Pull to refresh
13
0
Nikita Bobko @Bobko

Software Developer

Send message
В большинстве случаев «магические числа» конечно же нужно выделять в отдельные константы, но этот пример:
StringBuilder builder= new StringBuilder();
for (int i = days; i > 0; i /= 10) {
    builder.insert(0, i % 10);
}

на мой взгляд, как раз наоборот является примером, где лучше использовать 10 вместо константы (банально сложно придумать адекватное название для 10 в данном контексте), а так в принципе понятно, что этот цикл откусывает от числа последнюю цифру на каждой итерации и вставляет ее в начало строки (в конченом итоге это просто:
String.valueOf(days)
).

На моменте с FunQL закатил глаза: "О боже, и тут без собственного языка не обошлись". То, что это собственный язык, к сожалению, тоже не сразу очевидно (ссылка с документацией на домен ozma.io намекает, но, кажется, лучше это явно проговорить). Как я понял собственный язык нужен в основном из-за атрибутов (кстати, пояснение, как аттрибут выглядит синтаксически, следует заметно позже нескольких примеров запросов).

Для такой тяжеловестной абстракции, как собственный язык, хочется сразу увидеть рационализацию необходимости такого решения. А точно ли нельзя было сделать на чем-то существующем? Нельзя ли было сделать какую-то мета-таблицу, где в специальной колонке указывался бы тип запроса? (который @type=’board’, @type=’form’)

Или чтобы это вообще был не SQL, а ЯП общего назначения? SQL это же про данные, а не логику. А то получается, что мы GUI пытаемся на SQL нарисовать. Короче, да, почему тут SQL я не очень понял. (не отрицаю что мое непонимание возможно исходит от слабого познания SQL. С SQL мне мало приходилось работать)

то есть варианты и получше

Был бы рад ссылкам

Я бы еще отметил, что наследование классов — впринципе очень опасная операция, с которой надо обращаться аккуратно. Когда вы наследуюте один класс от другого, то вы подразумеваете, что наследуете то, как там ваш родитель "работает под капотом". Иначе говоря вы наследуете не только семантику, но еще и реализацию этой семантики.


Выражать конструкции вида "квадрат это прямоугольник" путем наследования класса Square от класса Rectangle — опасно (это как раз то, что приводит к тому, что класс Square в реализации в статье работает не оптимально и требует в два раза больше памяти чем нужно).


Правильнее определить два интерфейса (я думаю не стоит упоминать, что интерфейсы еще и позволяют Square унаследовать дополнительно от Rhombus...):


interface Rectangle {
  int getHeight();
  int getWidth();
  int perimeter();
}
interface Square extends Rectangle {
  int getSideLength();
  default int getHeight() { return getSideLength(); }
  default int getWidth() { return getSideLength(); }
}

И после этого писать реализации RectangleIml и SquareImpl под каждый. Причем на практике допустимо реализовать SquareImpl путем наследования от RectangleIml, это обычный инженерный trade-off между "написать поменьше кода" и "покушать меньше памяти". Просто академически это неправильно.


Ну а про мутабельность Rectangle и Square сверху умные люди уже написали. В данном случае иммьютабельность — это не просто поклон моде, а вынужденная необходимость, чтобы Rectangle и Square оставались прямоугольником и квадратом в математическом определении соответственно. Если есть желание по существующему объекту интерфейса Rectangle получить другой Rectangle, с измененной высотой, то это можно делать имьютабельно путем добавления метода в интерфейс Rectangle:


  /**
   * Creates new Rectangle which inherits width from {@code this} Rectangle but has {@code newWidth}
   */
  Rectangle rectWithWidth(int newWidth);
и в отличии от арча — надёжности

За арч и двор стреляю в… А вообще кто это вам наговорил таких гадостей про арч? Очень надежная система. Стоит больше двух лет с более 1500 установленых пакетов, никак нареканий и проблем.

Если вы про обычную тетрадь, то да — можно использовать версию 2.1 для правшей, а версию 2.2 для левшей. И все будет работать даже в обычной тетради, только лист придется поддерживать в вертикальном положении.

Блочная тетрадь — потенциально бесконечный поток листов, у него нет конца. Вы не знаете в какой момент надо "развернуться" и писать в другом направлении (вы можете попытаться это угадать и, но если вы не угадаете, то у вас будет либо растрата ресурсов, либо вам не хватит листов). А если вы про обучную тетрадь, то в ней даже факт того, что вы пишете только на одной стороне листа не спасает (листья то закреплены)

Разве страницы «обычно» перелистываются не влево (справа налево=влево)?

Влево, вправо… Вот скажите свайп вправо это когда палец провели слева направо или наоборот? Я вот не знаю и каждый раз уточняю у говорящего, потому что каждый называет это по своему. Именно для этого я и ввел секцию с терминологией, чтобы исключить недопонимания.

Проблему мотания листка из стороны в сторону, когда идет переход между разворотами

Нелокальность больше, чем при обычном способе записи

Да, соглашусь, замечание по делу. Небольшой эффект нелокальности есть. Но можно заметить, что если мы хотим удовлетворять основному требованию, то нам непременно придется "скакать" по страницам, т.е. нельзя придумать такой способ, который бы удовлетворял и локальности, и основному требованию.

К сожалению, пока не придумали дисплеев, от которых бы не уставали глаза. Ну и к тому же математику проще от руки на бумаге, чем в том же LaTeX.
это плохо, потенциально можно словить nullptr dereference

Неа, nullptr dereference вы не словите, даже если если там null. sizeof() даже не пытается вычислять значение аргумента, а просто по честному подставляет его размер на эта преобразования в ассемблер. Именно по этому я пишу обращения в функции malloc и ей подобным в духе:
int *ptr = malloc(100 * sizeof(*ptr));

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Registered
Activity