Научитесь выявлять их. Выработайте привычки избегать их.


Цель этой статьи не загнобить новичков за типичные ошибки, а научить выявлять их и избегать. Порядок перечисления – случайный.

От переводчика


Иногда бывает трудно объяснить простыми словами казалось бы банальные вещи: зачем использовать гит, в чем фишка инкапсуляции, зачем писать тесты, как планировать свой код, рефакторить чужой и т.д. Мне показалось, что в этой статье компактно собраны важные «гуманитарные» аспекты программирования. Что-то вроде морального кодекса, ориентира и мотиватора в принятии решений, связанных с написанием кода.

Как бы это смешно не звучало, я работал над этим текстом с середины марта, стараясь подобрать подходящие формулировки и упростить для восприятия. Ещё пару дней воевал с хабра-редактором. Поэтому, если вы найдёте недочёты, прошу не винить меня в нерадении, а оповестить, я их сразу же исправлю. Я думал украсить статью картинками, но решил, что это только раздует её до совсем неприличных размеров. Приятного чтения.

1) Программирование без планирования
2) Чрезмерное планирование
3) Недооценивание важности качества кода
4) Хвататься за первое решение
5) Не отступать
6) Не гуглить
7) Не использовать инкапсуляцию
8) Планирование неизвестного
9) Использование неподходящих структур данных
10) Ухудшать код
11) Комментирование очевидных вещей
12) Не писать тесты
13) Думать, если что-то работает, то это правильно сделано
14) Не подвергать сомнению существующий код
15) Одержимость лучшими практиками
16) Одержимость производительностью
17) Не ориентироваться на конечного пользователя
18) Не подбирать правильные инструменты
19) Непонимание, что проблемы с кодом вызывают проблемы с данными
20) Изобретение колеса
21) Неправильное отношение к инспекции кода (code review)
22) Не использование систем контроля версий
23) Злоупотребление общим состоянием (shared state)
24) Неправильное отношение к ошибкам
25) Не отдыхать

1) Программирование без планирования


Качественный контент не создаётся “на коленке”, а требует основательной работы. Программный код – не исключение.

Хороший код должен проходить через следующие стадии:

Замысел. Исследование. Планирование. Написание. Проверка. Изменение.

Каждому из этих пунктов надо уделить достаточно усилий.

Новички склонны кодить без предварительных раздумий. Это может сработать на маленьких автономных приложениях. Но на крупных может обернуться трагедией.

Прежде чем сказать что-то, вы обдумываете слова, чтобы потом не было стыдно. Точно так же избегайте непродуманного кода, за который однажды будет стыдно. И слова и код – это отображение ваших мыслей.

“Если ты зол, сосчитай до 10, прежде чем говорить. Если очень зол — то до 100”. (Томас Джефферсон)

Для нашего случая это можно перефразировать так:
“Когда проверяешь код, сосчитай до 10 прежде чем переписать 1 строчку. Если для этого кода нет тестов — то до 100”.

Программирование – это на 90% изучение существующего кода и его изменение посредством маленьких, легко тестируемых порций, вписывающихся в общую систему. Само написание кода это всего лишь 10% работы программиста.

Программирование – это не просто написание строк кода, а творчество, основанное на логике, которое надо развивать в себе.

2) Чрезмерное планирование


Планировать прежде чем нырять в написание кода – хорошая вещь. Но даже хорошие вещи могут навредить вам, если переборщить с ними. Даже водой можно отравиться, если слишком много её выпить.

Не ищите идеальный план. Такого не существует в мире программирования. Ищите достаточно хороший план для старта. Любой план изменится, зато он заставит вас придерживаться структуры в коде, которая облегчит вашу дальнейшую работу.

Линейное планирование всей программы “от А до Я” (водопадным методом) – не годится для большинства программных продуктов. Разработка подразумевает обратную связь и вы постоянно будете удалять и добавлять функционал, что никак нельзя учесть в «водопадном планировании». Планировать следует несколько следующих элементов. И каждый новый надо включать в план лишь после гибкой адаптации к реальности (Agile).

К планированию надо подойти очень ответственно, потому что и его недостаток и избыток могут навредить качеству кода. А качеством кода ни в коем случае нельзя рисковать.

3) Недооценивание важности качества кода


Если при написании кода вы можете сосредоточиться только на одной вещи, то это должна быть читабельность. Непонятный нечитабельный код это не просто мусор, а мусор, не подлежащий переработке.

Смотрите на программу как на составные части, общающиеся посредством кода. Плохой код — это плохая коммуникация.
“Пишите свой код так, будто его будет сопровождать агрессивный психопат, знающий, где вы живете”. (Джон Вудс)

Важны даже “мелочи”. Если вы бессистемно используете заглавные буквы и отступы, то у вас нужно отобрать лицензию программиста.

tHIS is
  WAY MORE important
than
         you think

Не используйте длинные строки. Строку длиннее 80 символов очень трудно читать. Используйте специальные инструменты для приведения кода в порядок (ESLint, Prettier для js).

Следите за количеством строк в функциях и файлах. Разделяйте код на мелкие части, понятные и тестируемые. Функция больше 10 строк – слишком длинная.

Не используйте двойное отрицание. Не не не делайте так. Это очень не не плохо.

Давайте переменным осмысленные, информативные, однозначные названия. Не используйте короткие, общие, или опирающиеся на тип, названия.
“В компьютерных науках есть только две по настоящему сложные вещи: инвалидация кэша и именование переменных”. (Фил Карлтон)

Используйте константы с содержательным названием для хранения примитивов. Если вам где-то нужно использовать число 12, сделайте сначала так:

const monthsInYear = 12; 

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

Краткий код в большинстве случаев лучше длинного. Но стремление к краткости не должно вредить читабельности. Не используйте замудреные тернарные операторы, чтобы уложиться в одну строчку. Но и не удлиняйте код без особой надобности. Удаление ненужного кода – это лучшее, что вы можете сделать для улучшения любой программы.
“Измерять программирование строками кода, это то же самое, что измерять авиастроительство тоннажем произведенных самолетов”. (Билл Гейтс)

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

4) Хвататься за первое решение


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

Ваша задача как профессионального программиста, найти не первое попавшееся решение, а самое простое. То есть то, которое наиболее просто реализуется, эффективно работает и легко поддерживается.
“Есть два пути написания программы: 1) сделать её настолько простой, что в ней, очевидно, не будет недостатков; 2) сделать её настолько сложной, что в ней никакие недостатки не будут очевидными”. (Тони Хоар)

5) Не отступать


Другая частая ошибка новичков – не отступать. Даже когда они поняли, что выбранное решение не самое лучшее. Подход “не сдаваться” хорош во многих сферах, но не в программировании. Программистам полезно признавать ошибки раньше и чаще. Как только вы засомневались в решении – отбросьте его и переосмыслите проблему. Не важно, сколько вы уже вложили в этот путь. Системы контроля версий типа Git позволяют создавать ветки и экспериментировать с разными решениями, активно пользуйтесь этим.
Не цепляйтесь за код только потому, что вложили в него много времени и сил. Плохой код должен быть отброшен.

6) Не гуглить


Если вы не пионер на острие новейшей технологии, велика вероятность, что вашу задачу кто-то уже решил. Гуглите, чтобы сэкономить драгоценное время.

Поиск может показать вам проблему с неожиданной стороны. И то, что вы считали решением и хотели реализовать, может оказаться усугублением проблемы. Даже когда кажется, что вы всё знаете для решения, гугл наверняка удивит вас.

Обратная сторона медали – новички любят копировать из гугла всё подряд без особых раздумий. Но даже если код решает вашу проблему, используйте его только когда ясно понимаете каждую его строчку.

Не будьте креативным в понятиях Брета Виктора, который сказал:
“Думать, что ты знаешь, что делаешь – самая опасная мысль креативного человека”.

7) Не использовать инкапсуляцию


Инкапсуляция полезна в общем, не только как часть парадигмы ООП. Не использование инкапсуляции приводит к возникновению трудно поддерживаемых систем.

Каждый элемент приложения должен описываться в одном месте, обычно это один объект. И этот объект предоставляет другим объектам ровно столько из своих данных, сколько нужно. Не из соображений секретности, а чтобы снизить уровень зависимости отдельных частей друг от друга. Это позволяет вам редактировать каждую отдельную часть, не ломая целое.

Логические единицы программы должны быть разделены на классы. Под классами подразумевается любое разделение, будь то класс, функция, модуль или пакет.

У новичков всегда бывает проблема с выделением логических единиц в классы. Если вы видите класс со смутным названием и выполняющий разношерстные операции – перед вами код новичка. Если вы сделали небольшое изменение в коде, и это вызвало по цепочке много других изменений – это ещё один признак новичка.

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

Стремитесь к тому, чтобы ваш код имел высокое зацепление и низкую связанность (High Cohesion and Low Coupling). Этот загадочный термин означает, что внутри класса должно быть максимально связей, а между классами – минимально зависимостей.

8) Планирование неизвестного


Когда вы пишете новую строчку кода, порой в голову лезут мысли: “а что если…” И вы начинаете фантазировать о разных новых фичах, которыми можно украсить программу. В большинстве случаев такие мысли вредны и не стоит на них ориентироваться.

Пишите только тот код, который вам нужен сегодня. Не пишите код, который возможно пригодится когда-то потом.

Всегда пишите минимум кода, необходимого сегодня и для конкретной текущей задачи. Конечно, предугадывайте и обрабатывайте экстремальные случаи, но не создавайте экстремальный функционал.
“Рост ради роста — это идеология раковой клетки”. (Эдвард Эбби)

9) Использование неподходящих структур данных


Начинающие программисты обычно уделяют много внимания алгоритмам. Умение подобрать нужный алгоритм и уместно использовать его – это очень хорошо. Но простое их заучивание не много прибавляет к вашему гению программирования.

В то же время заучивание сильных и слабых сторон разных структур данных вашего языка программирования, несомненно, повысит ваше качество как разработчика.

Неуместно использованная структура данных это кричащее предупреждение: “код новичка!”. Вот несколько примеров.

Обычный массив или ассоциативный?


Самая распространённая ошибка – это использование обычных массивов вместо ассоциативных для хранения списка записей.

Обычный массив:
[{id: 1, title: "entry1"}, {id: 2, title:"entry2"}, .... ]

Ассоциативный массив:
{ 1: {id: 1, title: "entry1"}, 2: {id: 2, title:"entry2"}, ....}

Да, вы не ослышались, для хранения списка записей нужно использовать ассоциативные массивы. Под списком записей я подразумеваю такие записи, где присутствует идентификатор. Массивы оправданы для хранения скалярных величин и если планируется активное использование методов, вроде push, pop, shift, unshift, которые обращаются к записям не через ключ, а через порядок в списке.

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

Стек или рекурсия?


Оптимизировать рекурсии довольно сложная задача, особенно в однопоточной среде. Это усложняется, если рекурсивная функция вызывает себя 2 и более раз.

Но вместо рекурсии можно использовать такую структуру данных как стек. Помещайте вызовы функций в стек и затем извлекайте их, когда подойдёт очередь.

10) Ухудшать код




Представьте, что вам досталась такая бардачная комната. И теперь перед вами стоит задача поставить туда какую-то свою вещь. Многие склонны сразу же сделать это. Задача будет решена за секунды. Но так вы станете соучастниками этого бардака. Правильный подход — это упорядочить ту часть комнаты, куда вы добавляете что-то. Например, если это одежда, то приберитесь в шкафу для одежды, сложите туда всю одежду из комнаты, а потом уже положите свою вещь на отведенное ей место. Всегда улучшайте код хоть немного, но никогда не ухудшайте.

Вот несколько распространенных ошибок, приводящих к беспорядку в коде:

Дублирование


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

Не использование файла конфигурации


В файл конфигурации обязательно надо помещать те величины, которые:
могут меняться в зависимости от окружения
встречаются в разных местах кода
Каждый раз, когда вы вводите в код новую величину, спрашивайте себя: “может быть её поместить в файл конфигурации?” И ответ будет почти всегда “да”.

Лишние условные операторы и временные переменные


Любой if разветвляет логику вашей программы, поэтому их наличие должно быть сведено к минимуму, насколько это возможно без вреда для читабельности. Самое сложное – определить правильный уровень для изменений: будете вы расширять текущий код или вынесете его во внешнюю функцию и вызовете её?

Вот яркий пример ненужного if:

function isOdd(number) {
 if (number % 2 === 1) {
   return true;
 } else {
   return false;
 }
}

Его можно переписать без единого if:

function isOdd(number) {
 return (number % 2 === 1);
};

11) Комментирование очевидных вещей


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

Например, такой код:

// This function sums only odd numbers in an array
const sum = (val) => {
  return val.reduce((a, b) => {
    if (b % 2 === 1) { // If the current number is odd
      a+=b;            // Add current number to accumulator
    }
    return a;          // The accumulator
  }, 0);
};

Можно заменить таким:
const sumOddValues = (array) => {
  return array.reduce((accumulator, currentNumber) => {
    if (isOdd(currentNumber)) { 
      return accumulator + currentNumber;
    }
    return accumulator;
  }, 0);
};

Но иногда прояснить код можно только комментарием. В таком случае сосредоточьтесь на вопросе: “ЗАЧЕМ нужен этот код”, а не “ЧТО делает этот код”. Вот пример кода, где комментарии только засоряют код:

// create a variable and initialize it to 0
let sum = 0;
// Loop over array
array.forEach(
  // For each number in the array
  (number) => {
    // Add the current number to the sum variable
    sum += number;
  }
);

Не делайте так, если вы программист. А если вы работодатель таких программистов — увольте их прямо сейчас.

12) Не писать тесты


Если вы считаете себя экспертом в программировании, который не нуждается в написании тестов для своего кода, то вы – новичок.

Если вы не пишете тесты, вы всё равно так или иначе тестируете вашу программу вручную. Если это веб-приложение, то вы обновляете страницу и совершаете какие-то действия после каждых нескольких строк кода. Все так делают, в этом нет ничего зазорного. Так делают хотя бы, чтобы понять, как писать автоматический тест. Каждый раз, когда вы проделали что-то вручную, вернитесь в редактор кода и напишите тест, повторяющий эти же действия и ожидающий эти же ответы.

Вы человек и рано или поздно, по мере роста проекта, вы забудете проделать какой-то из прошлых успешных тестов. Пусть компьютер проделает их за вас.

Если можете, создавайте проверки даже прежде самого кода. Разработка через тестирование (test-driven development, TDD) создана не для прикола и хайпа. Она благотворно влияет на то, как вы продумываете, проектируете и реализуете программные элементы.

TDD подходит не каждому программисту, и не каждому проекту, но если вы можете хотя бы частично реализовать его, то обязательно делайте это.

13) Думать, если что-то работает, то это правильно сделано


Взгляните на эту функцию, которая суммирует нечетные числа. Всё ли там правильно?

const sumOddValues = (array) => {
  return array.reduce((accumulator, currentNumber) => {
    if (currentNumber % 2 === 1) { 
      return accumulator + currentNumber;
    }
    return accumulator;
  });
};
 
 
console.assert(
  sumOddValues([1, 2, 3, 4, 5]) === 9
);

Тест проходит. Жизнь прекрасна. Правда?
Проблема этого кода в том, что он не полный. Он корректно работает только для нескольких случаев и наш удачный тест проверяет как раз один из них.

Проблема 1


Нет проверки на пустой ввод. Что случится, если функцию вызвать без аргументов? Выведется ошибка.

TypeError: Cannot read property 'reduce' of undefined.

И это признак плохого кода по двум главным причинам:
Пользователи вашей функции не должны сталкиваться с деталями её реализации.
Сообщение об ошибке не информативно.

Для пользователя функция просто не работает и он не поймет, что делать для исправления ситуации. Было бы намного лучше, если бы ошибка выдавалась в таком виде:

TypeError: Cannot execute function for empty list.

А может вам следует изменить функцию, чтобы она игнорировала пустой ввод и выдавала ответ 0? В любом случае, надо что-то сделать, нельзя оставлять так как было.

Проблема 2


Нет валидации. Что если в функцию передадут вместо массива строку, число или объект? Вот что произойдет:

sumOddValues(42);
TypeError: array.reduce is not a function

Подвох в этой ситуации в том, что array.reduce — это как раз функция. Но так как вы назвали аргумент функции array (массив), то что бы вы не передали ей (в данном примере это 42), будет названо массивом внутри функции. На самом деле ошибка говорит о том, что 42.reduce — это не функция. Не лучше ли сделать вывод ошибки в виде:

ОшибкаТипа: 42 - это не массив, чувак. 

Проблемы 1 и 2 описывают стандартные исключения, которые легко предусмотреть. Но бывают и менее очевидные исключения, с которыми надо быть внимательнее. Например, что произойдёт, если в массиве будут отрицательные числа?

sumOddValues([1, 2, 3, 4, 5, -13]) // => still 9

Следует ли программе воспринимать -13 как нечётное число? Или игнорировать? Или выдать ошибку? Может следует переименовать функцию в “сумма положительных нечётных чисел”? Вы легко выберете нужный вам вариант. Но самое интересное здесь то, что если вы не пишите тесты, документирующие работу вашей функции, то те, кто будут их сопровождать, даже не смогут понять, баг ли это или преднамеренное допущение.

“Это не баг. Это задуманный функционал” — удобная отмазка тех, кто не пишет тестов.

Проблема 3


Не все валидные случаи правильно работают. Забудьте разные каверзные исключения. Эта функция неправильно работает и с вполне обыденным набором переменных.

sumOddValues([2, 1, 3, 4, 5]) // => 11

В данном примере 2 попадёт в сумму, хотя не должна. Это произойдёт потому, что в функцию reduce не передано initialValue, и поэтому в качестве исходного значения будет взят первый элемент массива. Поэтому важно написать тест и для такого случая. Если такого нет, то это ещё один признак кода новичка.

14) Не подвергать сомнению существующий код


Если вы не супер-пупер программист, который всегда работает в одиночку, то рано или поздно в своей жизни вы столкнетесь с тупым кодом. Новички склонны не замечать этого, тем более, если он исправно работает и давно написан.

Самое страшное в этой ситуации, что новичок может подумать, что это хороший код, и будет повторять существующие в нём неправильные подходы.

Иногда код может выглядеть плохо, потому что разработчик был вынужден написать его таким в силу объективных причин. В таком случае уместно оставить комментарии с описанием этих причин.

Новичкам можно посоветовать такое правило: любой недокументированный код, который вы не понимаете — возможно, плохой. Изучайте его. Спрашивайте о нём. Пользуйтесь командой git blame, выдающей автора каждой строки кода.

Если автор далеко или не может вспомнить свой код, изучайте его до тех пор, пока полностью не поймете. Только так вы сможете ответить на вопрос, плохой код перед вами или хороший. Никогда не решайте этого наугад без твёрдых знаний.

15) Одержимость лучшими практиками


Термин “лучшие практики” вредный, он ограничивает вас в исследовании, «ведь уже есть лучшая практика».

“Лучших практик” не бывает. Бывают хорошие практики на сегодняшний день и для этого языка программирования.

Довольно часто то, что вчера считалось “лучшей практикой” сегодня считается плохой практикой. Вы всегда можете найти более лучшую практику, если потратите достаточно времени для этого. Поэтому не парьтесь о “лучших практиках”, а сосредоточьтесь на том, что вы можете сделать хорошо.

Не делайте что-то, потому что где-то прочитали цитату об этом, или увидели как кто-то делает это, или кто-то сказал про это “лучшая практика”. Ставьте всё под сомнение, бросайте вызов всем теориям, знайте все возможные варианты, и принимайте только обоснованные решения.

16) Одержимость производительностью


“Преждевременная оптимизация – это корень всех зол в программировании (или почти всех)”. Дональд Кнут, 1974

Хотя программирование существенно изменилось со времен Дональда Кнута, его совет актуален и в наши дни.

Если не можете измерить предполагаемую “проблему производительности”, то не заморачивайтесь о ней. Если вы оптимизируете код до того, как начали исполнять его, то наверняка потратили это время и усилия зря.

Разумеется, есть очевидные правила оптимизации, которые всегда надо держать в уме при написании кода. Например, в Node.js нельзя заполнять цикл событий и блокировать стек вызовов.

В погоне за вымышленной производительностью вы можете наделать реальные баги в самых неожиданных местах.

17) Не ориентироваться на конечного пользователя


Когда вы добавляете новый функционал в приложение, вы думаете в первую очередь о себе или конечном пользователе? Допустим, надо добавить новый ввод. Проще его прикрепить к уже существующей форме? Или нужно добавить ссылку. Проще всего прикрепить её к уже существующему меню ссылок?

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

18) Не подбирать правильные инструменты


У каждого есть набор любимых инструментов. Каждый из них прекрасен для какой-то своей задачи, в то время как для другой он ужасен. Молоток хорош для забивания гвоздя и плох для закручивания самореза. Не используйте молоток потому, что вы любите его или потому, что он самый популярный на Амазоне с рейтингом голосов 5.0.

Ориентироваться на популярность инструмента, а не пригодность для конкретной задачи – признак новичка.

Если вы знаете мало инструментов, то даже “лучший” из вашего списка по факту не обязательно будет таковым. Поэтому надо всегда расширять свой кругозор и быть готовым браться за новые инструменты.

Есть кодеры, которые чувствуют себя комфортно с известным для них набором инструментов и не хотят изучать новые. Это неправильно.

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

19) Непонимание, что проблемы с кодом вызывают проблемы с данными


Один из важнейших аспектов программирования — это управление данными. Программа – это интерфейс для добавления, редактирования и удаления записей.

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

Что ещё хуже, так это то, что исправление кода без исправления уже созданных кодом данных, может увеличить ошибки в данных вплоть до степени невосстановления.

Как защитить себя от такого? Можно использовать несколько уровней валидации: на фронтенде, бекенде, при передаче и в базе данных (БД). Как минимум, используйте встроенные ограничения в БД.

Хорошо знайте все типы ограничений в БД и используйте их все при создании новых столбцов и таблиц.

NOT NULL накладывает ограничение на столбец, чтобы он не принимал пустые значения. Это обязательно делать, если ваше приложение предполагает существование этой величины.

UNIQUE отслеживает уникальность величины столбца в масштабах всей таблицы. Идеально подходит для хранения логина или почты пользователя.

CHECK проверяет произвольное выражение, например, для процентов нужно проверять вхождение в интервал от 0 до 100.

PRIMARY KEY подразумевает одновременно уникальность и не пустое значение. Каждая таблица базы данных должна иметь такое поле для идентификации записей.

FOREIGN KEY говорит о том, что величины этого столбца содержатся в другой таблице.

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

20) Изобретение колеса


В программировании зачастую полезно переизобретать колёса. Это довольно гибкая и стремительно меняющаяся сфера знаний. Никакая команда не может угнаться за всеми обновлениями и новыми требованиями.

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

Иногда бывает сложно выбрать нужное колесо из-за многообразия. Проводите исследование. Пробуйте перед покупкой. Большинство “программных колёс” бесплатны и с открытым кодом. По возможности используйте заготовки с открытым исходным кодом (open source), их легко отлаживать, улучшать, заменять и поддерживать.

В то же время, если вам нужно только колесо, не надо покупать целую машину и прикручивать эту машину к другой машине на место колеса. Не подключайте целую библиотеку ради одной-двух функций. Если вам нужна функция shuffle из библиотеки lodash, импортируйте только её, не надо подключать весь lodash.

21) Неправильное отношение к инспекции кода (code review)


Один из признаков новичков, это восприятие инспекций кода как критицизма. Они не любят их, не ценят и даже боятся.

Это в корне неправильное отношение надо как можно быстрее изменить. Смотрите на каждую инспекцию кода как на ценную возможность обучения. Любите и цените их. Учитесь посредством них. И благодарите делающих замечания.

Надо принять тот факт, что программист – это вечный ученик, а инспекция кода – это одна из форм обучения.

Иногда сам инспектор ошибается и тогда приходит ваш черёд научить его чему-нибудь. Его неправильное замечание могло возникнуть по причине неочевидности вашего кода, тогда, возможно, вам следует доработать его. В любом случае, взаимный обмен знаниями крайне ценен для программистов и окупается многократно.

22) Не использование систем контроля версий (Git)


Новички склонны недооценивать пользу хорошей системы контроля версий/кода, вроде Git.

Обычно её используют, чтобы опубликовать свои изменения кода для других. Но её главное предназначение — это ясность истории. Код будут изучать и история его развития ответит на многие вопросы. Маленькие коммиты с осмысленными заголовками помогут сопровождающим код людям понять, как шаг за шагом образовывалась программа, пока не достигла текущего состояния.

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

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

Ещё одно предназначение системы контроля версий – понятность предназначения той или иной вещи. Допустим, вы столкнулись с функцией и вам надо понять её назначение и устройство. Вы можете найти коммит, в котором она появилась, и перед вами возникнет контекст её создания, что прольёт свет на всё остальное, связанное с ней.

Система контроля версий может даже помочь обнаружить баг, а именно, ту строку кода, с добавления которой программа дала сбой. В Гите есть бинарный поиск bisect, обнаруживающий коммит, внёсший баг.

Систему контроля можно использовать в разных целях, даже до того, как изменения кода превратились в официальные коммиты:
  • отслеживание изменений (staging changes)
  • выборочный патч (patching selectively)
  • сброс (resetting)
  • прятание (stashing)
  • перезапись истории (amending)
  • применение (applying)
  • просмотр изменений (diffing)
  • отмена коммитов (reversing)

Изучите все эти возможности, поймите, используйте и цените их. Чем меньше возможностей Git вы знаете, тем больше вы новичок.

23) Злоупотребление общим состоянием (shared state)


И снова это не про сравнение парадигмы функционального программирования с остальными.

Общее состояние является источником многих проблем. По возможности следует избегать его использования или свести к минимуму. Новички зачастую не понимают, что когда они определили переменную, она превращается в общее состояние. Это состояние содержит данные, которые могут быть изменены любыми элементами программы, находящимися в этой же области видимости. И чем больше область видимости, тем шире общее состояние и тем хуже. Старайтесь сохранять состояния в маленьких областях видимости и не давать им вылезать наружу.

Большая проблема общего состояния начинается тогда, когда несколько ресурсов меняют его в рамках одной итерации цикла событий (в событийно ориентированных средах). Возникает состояние гонки (Race conditions). И новички склонны решать эту проблему посредством таймера, особенно при блокировке данных. Это большой красный флаг. Избегайте этого. Ни в коем случае нельзя писать такой код или принимать его.

24) Неправильное отношение к ошибкам


Ошибки – это хорошо. Они говорят вам, что вы на правильном пути и подсказывают как добиться ещё большего прогресса. Опытные программисты любят ошибки, новички – ненавидят.

Если вас раздражают эти маленькие прекрасные сообщения об ошибках – вам надо изменить отношение к ним. Смотрите на них как на помощников, сотрудничайте с ними, опирайтесь на них, поднимаясь к новым высотам.

Некоторые ошибки следует превратить в исключения – запланированные за пользователем ошибки. Некоторые следует оставить как есть и позволить им уронить приложение и закрыть его.

25) Не отдыхать


Ваше тело и мозг нуждаются в отдыхе. Новички склонны увлекаться работой и забывать о перерывах. Обязательно включите в ваш рабочий процесс что-то, напоминающее об отдыхе. Вставайте, прогуливайтесь, думайте о том, какая работа на очереди и как лучше её сделать. Возвращайтесь за компьютер со свежими глазами.

Комментарии (186)


  1. Alozar
    21.06.2018 13:30
    +1

    Функция больше 10 строк – слишком длинная.

    Почему именно 10? Заголовок и скобки тоже включать?
    Я правильно понимаю, что функцию такого вида нужно делить?
    void foo()
    {
        --7 строк кода
    }


    1. rustamaha Автор
      21.06.2018 14:03

      не обязательно так буквально воспринимать, это же не закон в госдуме, чувак цифру назвал просто для ориентира.


      1. a-tk
        21.06.2018 14:55
        +26

        0. Воспринимать буквально советы бывалых.


      1. saboteur_kiev
        22.06.2018 18:16

        Так а зачем тогда писать советы, если они взяты для ориентира, и каждый совет нужно тщательно додумывать с точки зрения опытного разработчика — как новичок может это сделать? Новичок поймет буквально — будет писать функции не более 10 строк.
        А потом, через 5 лет, будет еще и других учить, что так делать правильно?


    1. wormball
      21.06.2018 14:11
      +1

      Просто вы не программировали на форте. Там и в две строчки функция — уже слишком длинная.


      1. ainoneko
        22.06.2018 11:46
        +1

        Там и в две строчки функция — уже слишком длинная.
        Это смотря сколько в одну строчку писать:
        примеры из nnCron:wakeup.spf
        : SetWTimer ( pd h -- ior )
        >R
        >R
        TRUE 0 ['] APCWTimer 0
        R>
        R> SetWaitableTimer ERR
        ;

        : WakeAfter { ms \ ht -- }
        WaitableTimer THROW TO ht
        ms 10000 UM* DNEGATE SWAP SP@ ht SetWTimer THROW 2DROP
        TRUE ms 10000 + SleepEx DROP
        ht CloseHandle DROP
        ;


    1. red75prim
      21.06.2018 22:25

      Ерундовый совет. Если поток управления в функции прямой как палка и в ней нет каких-то кусков, имеющих потенциал переиспользования, то можно и функцию на 1000 строк написать без потери читаемости.


      1. GreedyIvan
        21.06.2018 22:51
        +1

        можно и функцию на 1000 строк написать без потери читаемости.

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


        1. Antervis
          22.06.2018 07:02

          чрезмерное биение тоже может усложнить код — появляется куча непонятно как взаимодействующих друг с другом функций с не говорящими названиями


          1. BigFlask
            23.06.2018 00:15
            +1

            Решается использованием говорящих названий.


            1. Antervis
              23.06.2018 19:39

              важно не только правильно именовать, но также чтобы атомарные функции были самостоятельными логическими единицами. Иначе, впрочем, говорящее название всё равно не выдумать


        1. Skerrigan
          22.06.2018 07:33

          Пардон за оффтоп, но прям к месту (на мой взгляд):
          Совсем на днях сменил тактику разработки моделей в KSP — догадался, что не стоит делать «монолитные» изделия в сохранениях. Перешел как раз к более промышленной тактике: делаю отдельно те же ускорители / ступени / сегменты / полезную нагрузку (те же зонды/спутники). А потом уже по мере надобности из готовых сегментов собираю конкретный экземпляр под конкретную задачу.

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

          Модульность — великое «изобретение» (на самом деле подход).


          1. eoffsock
            22.06.2018 11:33

            Там вроде есть мод, который позволяет сваривать такие модули в один. В итоге они вроде как считаются как один компонент, и игра тормозит меньше. Не пользовался, но видел что-то такое.


            1. Skerrigan
              22.06.2018 11:54

              Сейчас в игре (кажется из коробки… но не уверен на 100%) есть при загрузке модели доп.кнопка «вставить» — вот она и позволяет в итоге делать сборку из нескольких частей.
              Ирония в том, что я не сообразил изначально весь итоговый простор.

              UPD: пардон, перечел еще раз ваше сообщение… кажется вы несколько об ином, хм… пойду опять шерстить CKAN.


            1. Rsa97
              22.06.2018 13:30

              Есть, но с ним свои проблемы. Сваривать можно только простые однотипные детали. Несколько баков можно объединить в один, а вот двигатель к баку, ЕМНИП, приварить не получится.


    1. Mishootk
      22.06.2018 10:21

      Как только разработчик начинает покрывать свой код тестами, у него автоматически приходит понимание оптимального размера функции. Чем длиннее функция, тем сложнее для нее тест. Слишком короткие и тривиальные функции привносят накладные расходы по обмену параметрами между ними (именно организационные в коде, а не производительность). И та и другая крайность замедляет и усложняет разработку и сопровождение. У каждого свой баланс.


      1. Alozar
        22.06.2018 10:35

        Может тогда не надо указывать какие-то конкретные цифры, а говорить, что функция должна выполнять только одну неразрывную операцию.
        В моей практики была ситуация, когда в функции из 30 строк, при этом 20 из них занимало строки с переносом значений из распарсенного xml-файла в класс. Сами понимаете, что это делить не имеет смысла, т.к. нужно сделать всё или ничего.


        1. GreedyIvan
          22.06.2018 12:58

          Как раз-таки имеет. Написание теста на такую функцию сразу выявит, что конвертация XML в специальный класс — это одна задача, а манипуляция этим классом — другая. И проверять этот функционал проще, когда он разнесен по разным функциям, чем писать каскад тестов на всевозможные пересечения.


          1. Alozar
            22.06.2018 13:18

            Я же написал, что файл распарсенный. На вход функции подавался готовый xml-документ.


      1. red75prim
        23.06.2018 07:03
        +1

        Иногда можно обойтись минимумом тестов. Если все компоненты, используемые в функции, оттестированы, возможность описок минимизирована с использованием системы типов, в функции нет ветвлений, то достаточно проверить пару случаев с известным входом/выходом, чтобы убедиться, что все требуемые шаги выполнены.


        Это я про языки с развитой системой типов. В языках с динамической типизацией, тестировать естественно нужно всё.


  1. TonyLorencio
    21.06.2018 13:40

    Не используйте длинные строки. Строку длиннее 80 символов очень трудно читать. Используйте специальные инструменты для приведения кода в порядок (ESLint, Prettier для js).

    Ограничение в 80 символов лично мне кажется перебором


    1. KMiNT21
      21.06.2018 13:52

      Тоже считаю, что много кому лучше использовать, например, с 120. Я в Python, например, пишу документирующий сам себя код, потому имена там длинные, но понятные. И если ограничение в 80 символов, то уж слишком много строк будут некрасиво переноситься на вторую строку, лишь ухудшая читабельность.


    1. igruh
      21.06.2018 14:05

      EGA mode detected.


      1. wlr398
        21.06.2018 15:13
        +1

        Возможно перевёрнутый набок экран монитора detected. То есть в портретном режиме. Часто приходится видеть у программистов.


        1. LynXzp
          23.06.2018 23:38
          +1

          И в xcode.


      1. haoNoQ
        21.06.2018 23:15

        А я просто люблю видеть несколько колонок кода на экране одновременно. Это очень удобно.


    1. Akon32
      21.06.2018 14:59
      +1

      Действительно.
      Нет смысла тащить ограничение из времён DOS. Обычно выбирают так, чтобы строчка влезала на экраны у всей команды. И чаще это 110-130 символов, но не всегда.


      1. Areso
        21.06.2018 15:01
        +1

        Это еще что. Я тут на работе столкнулся в ограничение в 8 символов в одной дорогой и в общем-то современной системе управления базами данных. Вот где настоящий хардкор) Причем не то чтобы не рекомендуется — нельзя сделать больше.


        1. PolyAkaMorph
          21.06.2018 16:46

          Название системы — три буквы?) За два с лишним года так и не смог привыкнуть к именованию датасетов вида "птчк", " упрлс"...


          1. Alozar
            21.06.2018 17:23

            У неё ещё есть циферка 3 или потом 4 буквы :-)
            Менять больше всего поразило в ней, что в ней есть ограничение по длине ПРАКТИЧЕСКИ на все поля. И диагностика ошибок нулевая или на уровне, что документ не сохраняется с формулировкой «Нельзя сохранить документ», без всякого объяснения почему…


          1. Areso
            21.06.2018 20:27

            Не угадали) Но видимо такие проблемы не только у Oracle с SID


      1. KoCMoHaBT61
        21.06.2018 20:03

        Это ограничение не времён ДОС, а времён перфокарт.


        1. saboteur_kiev
          22.06.2018 18:18

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


          1. KoCMoHaBT61
            22.06.2018 19:18

            На единственном промышленном языке программирования FORTRAN писали на перфокартах. Первые терминалы имитировали перфораторы.


            1. saboteur_kiev
              22.06.2018 20:01

              Ну вы же не путайте.

              На перфокарту переносили готовую программу для выполнения.
              Саму разработку на перфокарте не вели.


              1. KoCMoHaBT61
                22.06.2018 21:44

                Саму разработку вели на бумажке, прикинь. Потом специально обученные девушки (ну или сам программист) набивали её в колоду. А потом был прогон. Единственный. Потому, что вас много, а ЭВМ один.


                1. saboteur_kiev
                  22.06.2018 23:48

                  Я пользовался перфокартами, прикинь?


      1. daiver19
        21.06.2018 22:21

        Дос-не дос, но надо не чтобы «строчка» влезла в экран, а «строчка 3 раза» (или в вашей практике 3-way merge не существует?). У меня от силы 3 по 100 влазит на 27 дюймов.


      1. KvanTTT
        22.06.2018 09:42

        Лучше чтобы влезала в полэкрана на широком мониторе.


    1. Alendorff
      23.06.2018 19:33

      Кому как. Мне кажется очень удобным. Я привык работать за одним монитором на 24'', обычно открыто две колонки кода в вебшторме и иногда структура и/или файлики. И всё влезает, читать удобно. При 100-120 такое не пройдет уже. Надо будет подскролливать что-то. Да и читать короткую строку проще, на самом деле, глазки меньше бегают вправо-влево.


    1. alix_ginger
      24.06.2018 12:01
      +1

      У меня есть плоховидящий коллега, у него масштаб выкручен на 200% на 24" мониторе, и длинные строки соответственно, в него не помещаются.


  1. jetcar
    21.06.2018 13:51
    +4

    26. ошибка читать такие статьи и считать что это эталон :D


    1. springimport
      21.06.2018 22:52

      «Читать» можно убрать потому что статью могут рассказать…


    1. KvanTTT
      22.06.2018 09:44

      27. считать что количество пунктов — всегда кратное или красивое число.


  1. tewak
    21.06.2018 14:08
    +1

    Ну и классика:

    The Zen of Python, by Tim Peters

    Beautiful is better than ugly.
    Explicit is better than implicit.
    Simple is better than complex.
    Complex is better than complicated.
    Flat is better than nested.
    Sparse is better than dense.
    Readability counts.
    Special cases aren't special enough to break the rules.
    Although practicality beats purity.
    Errors should never pass silently.
    Unless explicitly silenced.
    In the face of ambiguity, refuse the temptation to guess.
    There should be one-- and preferably only one --obvious way to do it.
    Although that way may not be obvious at first unless you're Dutch.
    Now is better than never.
    Although never is often better than *right* now.
    If the implementation is hard to explain, it's a bad idea.
    If the implementation is easy to explain, it may be a good idea.
    Namespaces are one honking great idea — let's do more of those!


    1. TerraV
      21.06.2018 16:01
      +2

      Один этот комментарий лучше чем целая статья.


  1. vedenin1980
    21.06.2018 14:12

    0 Ошибка — использовать бездумно любые патерны, правила или советы из подобных статьей как единственный и непреложный закон. Всегда должна быть золотая середина и любые правила можно при необходимости нарушить.

    Надо написать очевидный скрипт на 2 строчки — не пишите тесты, не используйте Dependency injection framework'и если у вас в проекте 3 простейших класса, не засовывайте паттерн проектирование только потому что можете.

    В общем, при использовании любых правил — думайте сами насколько они вам нужны. Это сложно, но очень полезно. Иначе так и останетесь начинающими с 20 лет годами опыта.


    1. rustamaha Автор
      21.06.2018 14:17

      В статье это пункт 15


      1. vedenin1980
        21.06.2018 14:31

        Это не только о лучших практиках, это вообще о любых советах. Если Линус Торвальдс говорит, что у него очень хорошо пишется код, стоя на голове, не стоит считать, что лично вам писать код, стоя на голове, как-то поможет


    1. vlreshet
      21.06.2018 14:29

      Надо написать очевидный скрипт на 2 строчки — не пишите тесты, не используйте Dependency injection framework'и если у вас в проекте 3 простейших класса, не засовывайте паттерн проектирование только потому что можете.
      Надо быть с этим осторожным. А то потом окажется что «очевидный скрипт» со временем должен делать ещё что-то небольшое. И ещё немного. И ещё. И вот уже сраный монстр, который как-то незаметно, маленькими шажками, вырос из говнокода. И в таких процессах очень сложно поймать момент мол «не, всё, надо сначала переписать, а потом дальше развивать». Ведь всего чуть-чуть надо добавить, как всегда.


      1. Suvitruf
        21.06.2018 14:30

        На микросервисы/модули распилить.


        1. vlreshet
          21.06.2018 14:31

          К чему это?


          1. Suvitruf
            21.06.2018 14:33
            +1

            Не надо выращивать монстра, разбивайте логику на небольшие модули, тогда такой проблемы не будет.

            Ну и да, вы описали пункт 1 — «Программирование без планирования».


            1. vlreshet
              21.06.2018 14:36
              +1

              Ещё раз — нужно будет поймать момент когда уже пора разбить логику на модули. И планирование тут не поможет потому что: «надо написать очевидный скрипт». Планируем — небольшой скрипт, не буду строить сложно. ОК. Проходит время — надо добавить буквально маленькую фичу в этот скрипт, чуть-чуть. Это ж не полный ребилд — нет. Значит дописываем в существующее. И так несколько итераций. В итоге большой говнокод, потому что в самом начале мы решили что «к чему тут сложности, маленький скрипт же». Не всё можно запланировать наперёд


    1. Suvitruf
      21.06.2018 14:30
      +1

      Про DI и фреймворки прям в точку. Пытаются даже в самый маленький проект запихать. Для простейшего http сервиса тащат Express =/


      1. vlreshet
        21.06.2018 14:33
        +1

        А почему бы и нет? «Проиграть» какие-нибудь 10% производительности, и сэкономить кучу времени, даже на маленьком скрипте. Это же не дикий хайлоад где каждый такт важен. И не embedded devices.


        1. Suvitruf
          21.06.2018 14:36
          +1

          Я разработкой игр занимаюсь в последнее время (в данный момент на Unity3d). Насмотрелся уже как люди бездумно тащат в проект DI github.com/modesttree/Zenject. Производительность проседает, использовать правильно не умеют.

          Помимо просадок по скорости такие громоздкие библиотеки требуют зачастую специфичных знаний, просто так бездумно использовать такие вещи не стоит.


          1. vlreshet
            21.06.2018 14:37

            Игра — это не «простейший сервис», не так ли? ;) Вполне логично что в случае игр (где важен перфоманс) задумываться о зависимостях действительно нужно, тут я не спорю.


            1. Areso
              21.06.2018 14:51

              Зависит от игры. Можно одну и ту же игровую функциональность сделать как с десятком мегабайт зависимостей, так и совсем без них.


            1. Suvitruf
              21.06.2018 14:51

              В случае с node.js не уверен, что написание простейшего http сервиса на Express будет быстрее, чем с использованием стандартной http библиотеки.

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


            1. Areso
              21.06.2018 15:16
              +1

              Дабы не быть голословным, две ссылки на две игры одного жанра (сити билдинг + походы, а-ля травиан):
              github.com/sizeofcat/civitas
              github.com/Areso/1255-burgomaster
              Первая, правда, более богата функционалом, но начинались они примерно в одно и то же время с диаметрально разным подходом по отношению к зависимостям, и у обоих игр решение было принято на начальном этапе.


          1. Zoolander
            21.06.2018 15:32

            в играх вообще перформанс часто вступает в яростную борьбу с паттернами и архитектурой, привычными и допустимыми в других типах приложений


  1. guai
    21.06.2018 15:13
    +4

    Строку длиннее 80 символов очень трудно читать

    Ну ё-маё! Сколько столетий должно пройти, чтоб мы перестали ориентироваться на CGA?


    1. rustamaha Автор
      21.06.2018 15:25

      ограничение же не только в экране, но и в глазе.
      по правде сказать я смирился. у меня prettier по умолчанию так настроен был и я не стал менять. Да, иногда раздражает автоперенос, но в общем терпимо


      1. saboteur_kiev
        22.06.2018 18:20
        +2

        "по правде сказать я смирился. у меня prettier по умолчанию так настроен был и я не стал менять. Да, "
        В этой строчке 101 символ. Что у вас с глазами?


        1. rustamaha Автор
          22.06.2018 18:27

          я не настаиваю что именно 80 надо. но как ориентир нормально.
          а с этой строчкой что? за один раз раз не получается её охватить взглядом и несколько раз надо фокусироваться.


    1. stardust_kid
      21.06.2018 16:57
      +3

      На него с 14 века ориентируются, какой живучий однако формат мониторов.


      1. guai
        21.06.2018 17:02

        а тогда на чём кодили? на сишке, наверное?


        1. stardust_kid
          21.06.2018 17:04
          +4

          На латыни. А за плохой код карала инквизиция.


          1. LynXzp
            24.06.2018 00:07
            +1

            Еще там код надо было оборачивать обильным количеством комм рисунков.


    1. RomanArzumanyan
      21.06.2018 17:35
      +3

      Позволяет держать открытыми 2-3 окна одновременно, что весьма удобно.


      1. pesh1983
        22.06.2018 20:16

        Более того, не у всех десктоп с большим монитором и экран ноутбука с высоким разрешением)


  1. Kwisatz
    21.06.2018 15:35
    +3

    UNIQUE отслеживает уникальность величины столбца в масштабах всей таблицы. Идеально подходит для хранения логина или почты пользователя.

    Нет не подходит. У таблице пользователей не может быть уникальных полей, за исключением id. Уникальным может быть только связка электропочта+valid range.
    А если есть сервисные записи без почты или сотрудники без логина то и эта связка тоже не может присутствовать.

    для процентов нужно проверять вхождение в интервал от 0 до 100

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

    Одержимость производительностью

    Спорный момент. Где грань, когда необходимость становицо одержимостью? Огромное количество проектов насилует сервера понапрасну, только из-за того, что лень было подумать над SQL запросами.

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

    ох не всегда это работает, ох не всегда)

    Ну и кроме всего прочего: KISS, YAGNI. Остальное от лукавого 8)


    1. Areso
      21.06.2018 15:39
      +1

      Если пользователи могут обмениваться логинами (искать друг друга по ним), то лучше сделать их уникальными.


      1. Kwisatz
        21.06.2018 17:11

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


        1. Areso
          21.06.2018 21:26
          +1

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


          1. Kwisatz
            21.06.2018 23:53
            +1

            Нет не помню. Изначально аккаунт был другой с моим традиционным ником. А почта у меня для всяких регистраций теперь одна.


    1. rustamaha Автор
      21.06.2018 15:43
      -1

      Это в какой бд так?
      заглянул в первую попавшуюся документацию, это было по SQL:
      you can have many UNIQUE constraints per table…
      для любого поля можно задать уникальность и оно будет соблюдаться в рамках всей таблицы


      1. Areso
        21.06.2018 15:48
        +1

        Оратор выше вел речь не про физическую невозможность, а про логическую целесообразность.
        Впрочем, я не согласен про логины, хотя соглашусь про почты (если они не выступают логинами). Я люблю регать на 1 почту несколько аккаунтов)


        1. Kwisatz
          21.06.2018 16:35
          +2

          Был сотрудник с почтой Вася Пупкин (vp@) мы его уволили, добавляем нового Виталий Пупкович (vp@) и начинается веселье. Причем чем больше сотрудников, тем веселее.


          1. Eldhenn
            21.06.2018 21:02
            +1

            А потом Вася Пупкин возращается обратно.


            1. Areso
              21.06.2018 21:29
              +2

              На этом месте обычно отдел кадров запарывает кадровый учет в 1С.


      1. Kwisatz
        21.06.2018 16:55

        У нас всем сотрудникам выдаются легко произносимые почты из двух букв, дабы легко можно было диктовать/запоминать/итд Естественно они наследуются


        1. terrier
          21.06.2018 17:19
          +3

          У нас всем сотрудникам выдаются легко произносимые почты из двух букв, дабы легко можно было диктовать/запоминать/итд

          Самая потрясающая корпоративная идея тысячелетия!
          Пишешь на почту vp@crazycompany.com и не знаешь к кому попадешь — к Василию Пупкину или он уже уволился и эту почту читает совсем другой человек.
          А если Василий Пупкин уже работает в компании, то новобранцу Виталию Пупковичу дадут очевидный и запоминающийся логин ip или vu — логично же!


          1. Kwisatz
            21.06.2018 18:26
            -2

            Ах какой приятный выпад.
            1. А вы желаете получить автоматический отлуп? Не нужно ничего знать, вам все расскажут.
            2. Я так понимаю у вас сотрудники знают фонетический альфавит и могут легко диктовать vasyapupkin@crazycompany.ru? действительно идея тысячилетия
            3. Вы явно не в продажах работаете да?) У второй компании адреса 01, 02, 03 У третьей m1, m2, m3. Это удобно и клиентам нра.


            1. terrier
              21.06.2018 18:58
              +1

              1. А вы желаете получить автоматический отлуп? Не нужно ничего знать, вам все расскажут.

              Естественно! Категорически не хочу, чтобы вместо юриста Пупкина наши договоры читал программист Пупкинович.
              2. Я так понимаю у вас сотрудники знают фонетический альфавит и могут легко диктовать vasyapupkin@crazycompany.ru?

              Собственно, все компании, кроме вашей, как-то справляются.
              У второй компании адреса 01, 02, 03 У третьей m1, m2, m3.

              Хм, да, очень удобно — клиент сразу понимает, что Василию Пупкину надо писать на vp07@crazycompany.com — логично и интуитивно!


              1. Kwisatz
                21.06.2018 19:49

                Естественно! Категорически не хочу, чтобы вместо юриста Пупкина наши договоры читал программист Пупкинович.

                Для этого есть специальные адреса.

                Собственно, все компании, кроме вашей, как-то справляются.

                У многих торговых компаний короткие мыльца сейсас. А у мосигры например прикольные. Кроме того слышал как они справляются, по 10 минут на почтовый адрес, ага.

                Хм, да, очень удобно — клиент сразу понимает, что Василию Пупкину надо писать на vp07@crazycompany.com — логично и интуитивно!

                У меня почта 02 уже на многих доменах. Никто не жаловался.

                ЗЫ А вообще в таком тоне мне общаться неприятно. Удачи вам с таким подходом.


                1. terrier
                  21.06.2018 20:12

                  Для этого есть специальные адреса.

                  Ну вот, в случае юристов и реальной ответственности, здравый смысл как-то быстренько возвращается.

                  У многих торговых компаний короткие мыльца сейсас. А у мосигры например прикольные.

                  Да, вот, хоть на примере мосигры: если мы связываемся не с человеком, а с функцией, то вполне логично писать на invest@ или ecommerce@. А если мы пишем на короткий адрес hi@, то мы ожидаем, что это прочитает собственно Сергей Абдульманов, а не рандомный Христофор Иванов.

                  У меня почта 02 уже на многих доменах. Никто не жаловался.

                  Ну, конечно, глупо жаловаться, если неизвестно кто прочтет — уборщица или вахтер.


        1. DarthVictor
          22.06.2018 14:56
          +1

          У нас всем сотрудникам выдаются легко произносимые почты из двух букв, дабы легко можно было диктовать/запоминать/итд Естественно они наследуются

          У нас писарь в уезде был, в пачпортах год рождения одной только циферкой обозначал.
          Чернила, шельмец, вишь, экономил. Потом дело прояснилось, его в острог, а пачпорта переделывать уж не стали. Документ все-таки. Ефимцев, купец, третьего года рождения
          записан, Куликов — второго… Культякин — первого. Да, много тут долгожителей.
          из к/ф Формула любви


          1. Kwisatz
            22.06.2018 15:59

            Я немножечко не въезжаю в местный сарказм видимо. Но раз вопросов никто не задает видимо все равно почему и зачем, ну ладно 8)


    1. pesh1983
      22.06.2018 20:28
      +1

      В статье имеется ввиду преждевременная оптимизация производительности. Это писать код сначала понятно и просто, не заморачиваясь на оптимизации, просто потому, что код ещё несколько раз может поменяться. И вот когда код уже написан, он работает, покрыт тестами и выполняет задачу, для который написан, профилирование показало, что этот код работает медленно, вот только тогда стоит браться за оптимизацию. Да и то, тут ещё стоит рассмотреть систему в целом, а то может у вас больше тормоза даёт I/O, недели ваш код, и даже его оптимизация не даст ощутимого прироста.


      1. Kwisatz
        22.06.2018 23:04

        Не соглашусь с вами. Писать запросы сразу надо нормально. Если у вас во всех местах, например, в условиях стоят всевозможные функции в запросах. То только все переделывать под ноль. Такое встречается постоянно


        1. pesh1983
          23.06.2018 09:12
          +1

          Я и не отрицаю. Нормально != Преждевременная оптимизация.
          В статье все же речь про языки программирования, а не языки выполнения запросов, потому что в последних свои нюансы, которые отличаются. И речь скорее всего про оптимизиции без предварительного профилирования, которые в большинстве не приносят существенной пользы, зато тратят время и даже могут ухудшать читабельность кода.
          В общем, посыл такой, что не нужно заморачиваться на производительности при написании кода на языке программирования (не запросов), если эффективность этого кода не определена эмпирически и не доказана целесообразность увеличения его производительности. Иначе — это, с большой вероятностью, пустая трата времени.


    1. Ckpyt
      23.06.2018 12:03

      >Огромное количество проектов насилует сервера понапрасну, только из-за того, что лень было подумать над SQL запросами.

      И не меньшее — потому что было НЕ лень. Работал в проекте, где ВСЯ серверная логика была вынесена в СУБД. Ну и 150 запросов в минуту и не больше. После разделения логики и упрощения запросов, получили около 10К запросов в минуту.


      1. Kwisatz
        23.06.2018 13:16
        +3

        И не меньшее

        Ну все таки меньше) Порок входа в это дело куда выше, чем в клепание простых запросов.

        Работал в проекте, где ВСЯ серверная логика была вынесена в СУБД. Ну и 150 запросов в минуту и не больше. После разделения логики и упрощения запросов, получили около 10К запросов в минуту.

        Странная корреляция. Я даже придумать не могу как можно было сделать так плохо.


  1. luch_kot
    21.06.2018 15:35
    +1

    Вспомнил свой код с многократными повторениями, по 500 строк в процедуре.
    Эх, детство у меня было замечательным.
    Изменение разрешения экрана ради демонстрации пиксель-сцены.
    Переменные а1, а1_0, аа, аа0.
    Полное отсутствие каких бы то ни было проверок на наличие тех файлов, которые я честно-честно положил.
    Карты местности в jpeg.

    Могу сказать, что данная статья действительно полезна, но уже не для новичка. Новичок может и половины не понять.


    1. cyberly
      22.06.2018 05:13

      Угмс, есть такое ощущение. Читаешь, и по значительному числу пунктов: «Да, помню, был у меня такой факап»…


  1. Zoolander
    21.06.2018 15:40
    +1

    В п.13 однозначо справедливым мне кажется только последнее замечание, с которого и надо было начинать — что reduce плох тем, что не обрабатывает массив, если он длиной в 1 элемент, а тупо возвращает этот элемент, если не указано initialValue

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

    проверять данные нужно в момент поступления их от пользователя и к пользователю — это да, это необходимо. Возможно, в ряде других случаев эта проверка тоже уместна — к примеру, при вращении катапульты в играх уместно ограничивать предельные значения углов поворота.

    А если программист передает объект в функцию, в документации которой описан четко тип передаваемых аргументов — это не создатель функции виноват.


    1. AngReload
      21.06.2018 22:01

      Категорически согласен, всего не предусмотришь. И, кажется, я знаю откуда у автора появилась эта паранойя — в Javascript'e, с его динамической и слабой типизацией, даже во вполне безобидном коде приходится писать проверки типов.


    1. pesh1983
      22.06.2018 20:39

      В языках с динамической типизацией одна и та же переменная может иметь разный тип, в результате ошибки или явно, но это факт и от наверного типа никто не застрахован. Более того, есть такое понятие, как duck typing, так что тут больше по интерфейсу матчинг, а не по типу объекта. Ну и Null, None, null, undefined и так далее никто не отменял, их как минимум нужно проверять.
      А ещё если вы пишете библиотечную функцию и есть внешний клиентский код, который может передать в нее все, что угодно, проверки входных параметров все же стоит делать)


      1. Zoolander
        23.06.2018 05:45
        -2

        Null, None, null, undefined — все эти варианты возникают не сами по себе, а потому, что какие-то другие функции их возвращают, что тоже является слабым и спорным приемом программирования

        Если использовать прием «не возвращать Null, None, null, undefined» — то и проверки не будут нужны так часто


      1. Zoolander
        23.06.2018 05:59

        // В языках с динамической типизацией одна и та же переменная может иметь разный тип

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

        в JavaScript использование одного типа является крайне желательной практикой — это позволяет движку V8 проводить дополнительные оптимизации после «разогрева», да и уменьшает вероятность ошибок в коде из-за того, что вы описываете )


  1. ArsenAbakarov
    21.06.2018 15:52
    +2

    «высокое зацепление» в моем понимании это означает что класс должен выполнять именно то, для чего он предназначался и делать это превосходно, а не «что внутри класса должно быть максимально связей»


  1. Tiendil
    21.06.2018 16:16
    +6

    У начинающего программиста всего две ошибки:

    1. Недостаточно делать что-то.
    2. Чрезмерно делать что-то.


    1. Artyomcool
      21.06.2018 23:41

      Боюсь, слово «начинающего» тут излишне)


      1. markmariner
        22.06.2018 11:27
        +1

        Тогда и слово «программиста» тоже лишнее.


    1. LynXzp
      24.06.2018 00:12
      +1

      1. Недостаточно делать что-то.
      2. Чрезмерно делать что-то.
      Напоминает выход за границы массива.


  1. cynovg
    21.06.2018 16:33
    +3

    Правильный подход — это упорядочить ту часть комнаты, куда вы добавляете что-то.

    Только в отдельной задаче. Иначе, в одном комите будет Ад и Израиль.


    1. Artyomcool
      21.06.2018 23:43

      Или в отдельном, предварительном коммите. Иначе банальная лень (заводить тысячи задач, обосновывать необходимость каждой перед всеми заинтересованными лицами и т.п.) может погубить хорошее начинание.


      1. cynovg
        21.06.2018 23:49

        Мы завели тип задач «улучшение кода» и доверили их дежурному. Иначе, при код-ревью задачу могут завернуть за правки, которые к ней не относятся и тогда будет не только обидно, но и проблемой для заказчика (грубо говоря, потеря денег).


  1. Barbaresk
    21.06.2018 16:33
    +1

    Не используйте длинные строки. Строку длиннее 80 символов очень трудно читать. Используйте специальные инструменты для приведения кода в порядок (ESLint, Prettier для js).

    Как оно там живётся в 90-х? Какие 80 символов? Кто еще пишет на калькуляторах код? Зачем это? 120 символов в строке можно смело писать. А если это какое-нибудь перечисление, то можно и больше символов.

    Следите за количеством строк в функциях и файлах. Разделяйте код на мелкие части, понятные и тестируемые. Функция больше 10 строк – слишком длинная.

    Тоже странный совет. Особенно в сочетании с предыдущим. А сотни функций с похожими именами, и содержащими по 7-9 строчек логики это лучше? 10 строк кода — это две объявленных переменных и два уровня цикла с одним if. Так себе перспективы.

    Массив или объект?
    Самая распространённая ошибка – это использование массивов вместо объектов для хранения списка записей. Да, вы не ослышались, для хранения списка записей нужно использовать объекты. Под списком записей я подразумеваю такие записи, где присутствует идентификатор. Массивы оправданы для хранения скалярных величин и если планируется активное добавление в массив.

    Автор сравнивает теплое с мягким. Вроде идея-то правильная — «нужно использовать правильную структуру данных», но пример такой, что запутает любого. Наверное, имелось ввиду, что для записей с некоторым ключом нужно использовать такие «объекты», которые позволяют искать не за линейное время (упорядоченные таблицы, деревья поиска, хеш-таблицы, списки с пропусками и т.д.). Но идея выражена максимально невнятно. Да и если искать, например, не нужно, то и список пойдёт. В общем странный совет.
    Не делайте так, если вы программист. А если вы работодатель таких программистов — увольте их прямо сейчас.

    Надеюсь, это была такая шутка, а не максимализм.

    А вообще, сама статья плоха именно потому, что постоянно мешает советы разного типа. Например совет проверять тип аргумента — бесполезен в строготипизированных языках. Не говоря уж о том, что во внутренних функций НЕ НУЖНО проверять аргументы методов и т.п. Нужно обеспечивать переход объекта из одного согласованного состояния в другое. И таких вещей в статье масса. Причём на каждое правило можно привести контрпример, когда так делать не надо. Удивлен, что не встретил такого заезженного и избитого правила, как «не использовать goto». Обычно в подобных списках советов он тоже встречается, хотя правило совсем неоднозначное.

    П.С. В какой-то момент понял, что это перевод. Поэтому про остальное писать нет смысла. Зачем это переводить? Таких списков советов — полно. Их никто не читает, они субъективны чуть больше чем наполовину.


    1. stardust_kid
      21.06.2018 16:56
      -1

      На широких мониторах можно и до тысячи. Только есть правила типографики, о которых вы не знаете.


      1. guai
        21.06.2018 17:25

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


        1. stardust_kid
          21.06.2018 18:04

          И все это не о том.


          1. guai
            21.06.2018 19:01

            аргументов не будет?


            1. stardust_kid
              22.06.2018 12:20

              Если вы ожидаете от меня развернутой аргументации, стоило бы ознакомиться с ссылками, которые я привел. В приведенных статьях, говорится о том, что длина строки обусловлена особенностями поля зрения человека. Строки длиннее 90 символов вынуждают глаз совершать дополнительные движения, что приводит к утомлению.
              При этом не имеет значения код это или стихи.


              1. guai
                22.06.2018 14:31

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


                1. AlexBin
                  22.06.2018 17:51

                  Да судя по тому, что вам хоть в глаза нассы, глаза у вас такие крепкие, что и широкий текст им не навредит. Однако, среднестатистический читатель утомляется от чтения широкого текста.

                  Последствия нарушения правил типографики не очевидны для читателя. Он чувствует, что устал читать, но не понимает из-за чего именно. Шрифты, отступы, интервалы, засечки, колонки, думаете это все только декораций ради? Если вы заметите, то на всех популярных ресурсах ширина основного контента ограничена, а не растянута на весь монитор.

                  И в коде я тоже всегда использую две колонки, иногда в них даже открыт один файл в разных местах.

                  Я вот знаю, что наоборот, к утомлению приводит статичный взгляд в одну точку

                  Совершенно верно, поэтому ширина колонки не должна быть в один символ. Не нужно приводить глупые примеры.

                  Работать за двумя широкими мониками менее напряжно, потому что чаще двигаешь глазами.

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

                  Короче не ту тему вы выбрали для спора.


                  1. guai
                    22.06.2018 19:21

                    хоть в глаза нассы

                    чо за быдлота на моем хабре?
                    попробуйте на два монитора растянуть сплошной текст

                    Не нужно приводить глупые примеры.


                    Шрифты, отступы, интервалы, засечки, колонки — где вы это всё увидели в программном коде?
                    Один шрифт, один интервал, никаких колонок. В программном коде свои способы организации текста — это отступы и подсветка синтаксиса. И читают программный код люди не подряд, они ориентируются на уровень вложенности в первую очередь, на цвет ключевых слов, на пустые строчки. Когда читаешь код, ты его не читаешь, как обычный текст, ты чаще что-то ищешь — нужный метод и возвращаемый тип, например. Вчитываешься намного реже.

                    Так что весь ваш дезигн головного мозга выплёскивайте в каментах к другим статьям


                    1. AlexBin
                      22.06.2018 22:26

                      Мой пример экспериментально доказывает, что у текста должна быть разумная ширина. А общепринятые стандарты типографики, которые не без причины используются во всем мире, намекают, какая именно ширина.

                      Товарищ выше прислал вам ссылки ознакомиться, но вы попросили ссылки на исследования. А от вас можно ссылки на исследования получить, что широкий код — благо глазу? Или даже без исследований, есть где-нибудь признанные в IT-сообществе стандарты или рекомендации в отношении ширины кода в 120 символов?

                      Шрифты, отступы, интервалы, засечки, колонки — где вы это всё увидели в программном коде?


                      Везде, например? В любой профессиональной IDE, на любом профессиональном ресурсе (типа гитхаба или стека, и даже хабра) код и вставки кода имеют строго определенную типографику. Да, везде шрифты без засечек, моноширенные, узкая колонка. Могу забросать примерами. А вы можете найти пример, где по умолчанию пропагандируется широкий код? А не моноширинный шрифт? А уплотненный интервал?

                      Вопреки аргументам, вы конечно же можете воскликнуть, что не смотря на статистику, они все дураки и быдло, а вы один такой умный с железными глазами. Но чтобы делать такие заявления, должна быть какая-то репутация. А вы пока производите впечатление не признанного гения с синдромом даннинга крюгера.

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

                      Верно, и это никак не исключает необходимость типографики, поэтому она везде и есть по умолчанию. Если вы у себя в IDE ее намеренно ломаете, это не говорит о том, что типографики там не было изначально.

                      Приведу пример:

                      Отступы есть? Есть.
                      Подсветка синтаксиса есть? Есть.
                      Одна проблема: типографики нет.

                      Глаза уже зачесались?


              1. Firz
                23.06.2018 18:56
                +1

                Дополню наглядным примером)
                habrastorage.org/webt/ga/8a/ha/ga8ahabgwzxzdbh96pwmjfmdgni.gif (6MB)


    1. mistergrim
      21.06.2018 17:36

      > 120 символов в строке можно смело писать. А если это какое-нибудь перечисление, то можно и больше символов.

      Тут есть один нюанс — эти символы потом кому-то, вполне возможно, придётся читать.


    1. reskator
      21.06.2018 23:34

      Я скажу так — никогда не следите за количеством символов в строке. Если вы вынуждены следить за этим самостоятельно (при помощи настроек в IDE, или вообще вручную) — это совсем плохо. Все правила форматирования кода должны проверяться на серверах сборки, и/или в pre-commit хуке. Только так вы не допустите нарушение этого правила, в противном случае — напрасная трата времени.


      1. Barbaresk
        22.06.2018 00:03

        Вот, пожалуй, самый правильный совет. Который можно обобщить до «автоматизируйте рутинные вещи».


      1. pesh1983
        22.06.2018 21:32

        Правильно пишете. Это должно быть привычкой и на уровне автоматизма. А ещё проверяться линтерами)


    1. hexploy
      22.06.2018 00:58

      120 символов в строке можно смело писать. А если это какое-нибудь перечисление, то можно и больше символов.
      А лучше вообще все элементы перечисления в одной строке — чтобы люди не пользовались слишком уж простым git blame и более глубоко прокачивали навыки работы с системой контроля версия и shell скриптами.

      Нет, я лично вообще за 140 символов (впрочем код у меня, в основном, на Java, а она многословна), но, по многолетним ощущениям, код лучше поддерживается если одна строка содержит не больше одной мысли или «семантического объекта»


      1. guai
        22.06.2018 14:48

        если VCS встаёт на пути к достижению красоты кода в HEAD, что-то вы делаете не так.
        Код читаешь явно чаще, чем блэймы, да и вообще, в историю лезешь только косяки разбирать, не было косяков — наплевать, что там в истории вообще было.


    1. Antervis
      22.06.2018 11:32
      +1

      Как оно там живётся в 90-х? Какие 80 символов? Кто еще пишет на калькуляторах код? Зачем это? 120 символов в строке можно смело писать. А если это какое-нибудь перечисление, то можно и больше символов.

      У тех, кто использует IDE в двухколоночном режиме, на среднем мониторе ширина колонки 85-100 символов. На ноутбуках и того меньше. А фича, между прочим, удобная


    1. pesh1983
      22.06.2018 21:19

      Коллеги с экранами ноутбуков 1280x800 (стандарт на ноутах старых моделей) скажут вам "спасибо" за 120 и более символов. Потому что 80 символов позволяют открыть два файла с кодом на таком экране и ничего не будет переноситься)


      1. Barbaresk
        22.06.2018 22:52
        +2

        Завтра кто-то захочет открыть этот код на калькуляторе каком-нибудь в 4 столбца. И что теперь? По 20 символов в строке писать? Да, я, конечно, смотрю со своей колокольни (17 дюймов ноут, а на работе два больших экрана). Но кто мешает сделать автоперенос лишних символов в вашей среде разработке? Как, например, в Notepad++. А всем, у кого большие экраны и 120 символов норм.


        1. pesh1983
          22.06.2018 23:32
          -2

          Ну с таким подходом непонятно, почему все должны под вас подстраиваться) А почему не взять тогда уж все 320 символов? И больше ж кода то влезет на экран и будет стимул всем мониторы обновить. Я вам так скажу. Есть рекомендации (например, pep8 в Python), которые не с потолка взяты, а следовать им или нет — ваше личное дело. В команде, как правило, code conventions принимают либо на базе общепринятых рекомендаций, либо на базе мнения большинства. Если в вашем случае большинству удобнее со 120 символами — ради бога. А в статье приводятся общепринятые рекомендации, а следовать им или нет — каждый сам решает


        1. pesh1983
          22.06.2018 23:38
          -1

          И калькуляторы тут не причем, я вам привел пример наиболее распространенного разрешения на ноутбуках. И большинство ноутов старых моделей именно с таким разрешением. И именно 80 символов позволяют на таком разрешении делать 2 колоночный просмотр кода без переноса строк. И это одна из причин такого выбора


          1. Barbaresk
            23.06.2018 01:38
            +1

            На число символов влияет всё-таки не разрешение, а диагональ, при условии, что работа с устройством идём с фиксированного расстояния. Я понимаю, что открыть две страницы кода на 13" мониторе со 120 символами сложно, но я вообще не могу на таких маленьких мониторах что-то продуктивное делать, мне банально тесно. Вообще этот спор в какой-то мере о вкусах и удобстве. Кому-то неудобны длинные строчки, кому-то переносы на пустом месте и куча свободного пространства справа. Но апелировать к «общепринятости» в статье я бы не стал — автора статьи явно js укусил (ничего не имею против js) и некоторые советы там вообще спорные или относятся только к js. Сode-style в питоне относятся всё-таки к питону, не знаю, может разработчики питона все сидят на 13". А то так можно вспомнить какой-нибудь археологический язык, где нужно оставлять 5 пробелов слева для названия метки. Тоже code-style. Но писать про 80 символов я бы не стал в общепринятых советах, нужно находить компромисс между удобством и обратной совместимостью с калькуляторами. А самый лучший совет уже писали — использовать автоматические средства для форматирования + автоматический перенос.


            1. altrus
              23.06.2018 04:24

              Прогресс не стоит на месте и профессиональная разработка сейчас идет на больших мониторах. А значит, ничего такого, чтобы поменять правило 80 символов под новое время нет, думаю.

              Кроме того, про все языки программирования не знаю, но если дело касается кода, то превышение 80-120 символов в строках происходит редко, и на удобство чтения кода на любом мониторе влияет не сильно.


  1. terrier
    21.06.2018 17:13

    Оригинал

    — Using lists (arrays) instead of maps (objects) to manage records
    The most common data structure mistake is probably the use of lists instead of maps to manage a list of records. Yes, to manage a LIST of records you should use a MAP.

    Перевод
    Массив или объект?
    Самая распространённая ошибка – это использование массивов вместо объектов для хранения списка записей. Да, вы не ослышались, для хранения списка записей нужно использовать объекты.

    Немножко настораживает, что так называемый «full-stack» девелопер не знает слова map.


    1. rustamaha Автор
      21.06.2018 17:41

      Я знаю слово map и дальше идет пояснение, что это структура «ключ-значение» (что в привычном мне js соответствует объекту). А как лучше было перевести по вашему?


      1. a-l-e-x
        21.06.2018 17:58

        структура «ключ-значение»

        может быть массив структур «ключ-значение»
        Хотя тоже коряво.
        Вроде есть одна структура «ключ-значение». А потом их становится много — массив из них. Array of structs — вроде такой термин, к примеру, в BigQuery используется. Правда там структура не обязательно «ключ-значение»…


      1. lgorSL
        21.06.2018 18:08
        +1

        Я бы перевёл как "хеш-таблицу" (немного вольный перевод, но зато сразу понятна идея) или "ассоциативный массив" (точный перевод, но не очень очевидный).


        1. cynovg
          21.06.2018 20:55
          +1

          Ассоциативный массив — это точное название типа данных.


          1. nightwolf_du
            22.06.2018 15:21

            Не совсем так.
            Ассоциативный массив — это тип «интерфейса» структуры данных. Реализации могут быть разными — «хеш-таблица», какое-либо дерево поиска и т.д.
            Хэштаблица — это конкретная структура данных (на самом деле, не совсем, там тоже есть разные стратегии разрешения коллизий.)
            А общая рекомендация проста — не используй для поиска элемента плоские структуры.


      1. terrier
        21.06.2018 18:24

        А как лучше было перевести по вашему?

        [Один из пример ошибочного использования структур данных — это ...]
        — Использование списков (массивов) вместо ассоциативных массивов(*) для обработки записей(**)
        Возможно, самая частая ошибка, связанная со структурами данных — это использование списков вместо ассоциативных массивов для обработки списков записей. Да, верно, для обработки СПИСКА записей нужно использовать АССОЦИАТИВНЫЙ МАССИВ(***).
        Заметьте, когда я говорю о списке записей, я имею в виду, что каждая запись должна иметь идентификатор, который будет использоваться для поиска. Использовать списки для скалярных значений — нормально и зачастую даже предпочтительно, особенно если мы в основном добавляем значения в список.(****)

        (*) — вот то, что в оригинале maps ( в скобочках objects ) — это какой-то джаваскриптизм, который не способствует пониманию, по-моему его можно опустить ( тем более, что дальнейшие упоминания джаваскрипта вы подрезали)
        (**) — «запись» — немножко устаревший термин, я бы потестировал на людях, не будет понятнее здесь везде вместо «запись» писать «объект». Смысл тот же, хотя и не дословно.
        (***) — автор КРИЧИТ, ну и мы тоже будет, нуачо?
        (****) — дабл неловкость, во-первых потому что что-то не придумывается благозвучный перевод этого «focus of usage», во-вторых потому что автор что-то по-моему загнался ( и почему «pushing» в кавычках?)

        Вот примерно такое я придумал за минутку.


        1. rustamaha Автор
          22.06.2018 12:57

          terrier, спасибо, исправил «объект» на «ассоциативный массив».
          Как я понял автор имеет ввиду когда используют обычный массив:

          [{id: 1, title: "entry1"}, {id: 2, title:"entry2"}, .... ]

          Хотя лучше использовать ассоциативный массив:
          { 1: {id: 1, title: "entry1"}, 2: {id: 2, title:"entry2"}, ....}

          И предлагает использовать обычный массив, только если нам нужно активно пользоваться Методами типа push, pop, shift, unshift (которые обращаются к записям не через ключ, а ориентируюсь на порядок в списке).


          1. terrier
            22.06.2018 14:19

            Ну, да, видимо так.


      1. cynovg
        21.06.2018 20:53

        Хэш ведь.


    1. Barbaresk
      21.06.2018 18:30
      +2

      Ваше замечание сильно объяснило тот бред, который был написан в этом пункте. Да, в исходном тексте было корректно написано, а вот в переводе уже ерунда какая-то.


  1. avraam_linkoln
    21.06.2018 17:42

    Хмм. Впервые вижу чтоб кто то советовал не использовать стиль Йоды.


    1. springimport
      21.06.2018 23:02
      +2

      Так воот как это казывается! Всегда ненавидел такой стиль и теперь даже знаю его название и зачем он нужен.

      Имхо, решать костылями то что должно (в идеале) проверяться другими методами — не верно.


  1. reskator
    21.06.2018 23:12
    +2

    const daysInYear = 365;


    Никогда не делайте так. Понимаю, что это просто пример, но, не дай бог, кто-то так в реальном коде напишет. По поводу заблуждений программистов о времени — была хорошая статья, здесь, на хабре. Начать читать можно здесь https://habr.com/post/313274/ — много удивительного можно узнать.

    P.S.: Для примера можно использовать безопасный аналог — const monthsInYear = 12; Месяцев в нашем календаре всегда 12.


    1. Areso
      22.06.2018 07:45

      Конкретно такое вполне может попасться в банковском коде для депозитов и кредитов.


    1. ainoneko
      22.06.2018 12:00
      +1

      const daysInYear = 365;
      Никогда не делайте так
      А так можно:
      const integerPartOfDaysInUsualYearInMostCalendarsInEurope = 365;
      ?
      Или лучше писать в коде 365?


      1. vedenin1980
        22.06.2018 12:15

        А можете привести ситуацию когда вам нужно значение «обычно в году 365 дней»? Если вы знаете год, можно посчитать кол-во дней точно.


        1. Areso
          22.06.2018 12:54

          В тех случаях, когда погрешностью можно пренебречь + облегчить код за счет отсутствия зависимостей, которые выясняют сколько дней в каком году.
          Плюс мы облегчаем интерфейс пользователю, когда не спрашиваем у него в обязательном порядке в каком году он хочет открыть депозит или кредит или whatever что он хочет там сделать или посчитать.


    1. rustamaha Автор
      22.06.2018 12:46

      reskator, спасибо, исправил.


    1. Makc_K
      22.06.2018 13:11
      +1

      const daysInYear = 365,25;
      )))


      1. rustamaha Автор
        22.06.2018 13:15

        уже на месяца исправил по совету одного человека )


      1. defuz
        22.06.2018 17:45

        И снова ошибка. Каждый 100-ый, но не 400-ый год не является високосным, так что:

        const daysInYear = 365.2425;


        1. ainoneko
          22.06.2018 18:27
          +1

          Это в современном календаре так (в одном из). А в реальности это число колеблется и изменяется (Земля медленнее вращается вокруг своей оси).


    1. nrsoft
      22.06.2018 14:27

      Ага, и это в пункте про важность качественного кода. Кстати в оригинале автор уже осознал и поменял на

      const answerToLifeTheUniverseAndEverything = 42;


  1. jcmvbkbc
    21.06.2018 23:24
    +1

    if (b % 2 === 1) { // If the current number is even

    Вот тоже зло в чистом виде: комментарий не соответствующий коду.


    1. rustamaha Автор
      22.06.2018 13:04

      да, жесть ) спасибо, исправил


  1. Daddy_Cool
    22.06.2018 01:28
    +2

    Восхитительно. (
    Если вкратце — «Пишите хорошие программы, а плохие — не пишите».
    К сожалению, у большей части указанных ошибок нет внятных численных критериев. А значит если я даже искренне хочу воспользоваться ценным материалом статьи — то… как? Любая написанная программа которая работает — это лучшее, что сделал программист в существующих условиях. Объяснить как и главное — почему можно сделать лучше — может только более умный/опытный программист в каждом конкретном случае.


  1. TheIncognito
    22.06.2018 01:46

    П. 20. Колесо?
    Обычно что-то такое говорят про велосипед.


    1. cyberly
      22.06.2018 05:20

      «Изобретать велосипед» по-английски будет «reinventing the wheel». Мелкий огрех литературной адаптации.


  1. decomeron
    22.06.2018 04:19

    Ошибка 26. А зачем я вообще влез в это программирование когда ничего не получается?
    Раз влез, терпи, упорство и труд все перетрут


  1. Namynnuz
    22.06.2018 04:49

    Что за js-дичь я только что прочитал?

    В то же время заучивание сильных и слабых сторон разных структур данных вашего языка программирования, несомненно, повысит ваше качество как разработчика.
    Самая распространённая ошибка – это использование массивов вместо объектов для хранения списка записей
    Ну и расскажите мне, как я в ванильном си, узнав самую распространённую ошибку в структурах данных среди новичков, буду ходить по объекту (ага), который представлен ассоциативным массивом/словарём (ага) со стринговыми (ага) ключами, чтобы интерпретатор (ага) в рантайме мне нашёл (ага) содержимое этого самого т.н. «объекта», да ещё и сделал это быстрее (ага) массивов. Код новичка, млин.
    Пользуйтесь командой git blame, выдающей автора каждой строки кода.
    Пользуйтесь им везде. В Subversion, в Mercurial, в Team Foundation, вместо вечерней молитвы и в качестве приветствия. Просто бездумно запомните git blame и не забывайте почаще отрабатывать джебы по груше. Потому что «Не использование систем контроля версий (Git)». Потому что исключительно front-end open source на github в vs code. Потому что иначе вы пользуетесь примитивными инструментами из старой кладовки и не любите снуды.
    И снова это не про сравнение парадигмы функционального программирования с остальными.
    С какими остальными? Неправильными и неверными, потому что не модными? Конкатенативными и Логическими? Какими? Или, типа, всё-таки в очередной раз пошёл срач про модность в противостоянии Императивной и Декларативной парадигм?


  1. Kanut79
    22.06.2018 09:06

    Советы не универсальные, местами противоречат друг-другу и требуют различной интерпретации в зависимости от ситуации. И следовательно на мой взгляд они для начинающего бесполезны. Потому что у него скорее всего нет ни умений, ни знаний чтобы их правильно интерпретировать. А если умения и знания есть, то он и без этих советов разберётся.


  1. halted
    22.06.2018 09:21

    Кажется новичку полезнее набраться знаний по матчасти и ориентироваться в ней, чтобы хоть один из этих пригодился.


    1. halted
      22.06.2018 09:30

      вот я новичок, как мне оценить качество кода, если альтернативы мне неизвестны?


      1. Areso
        22.06.2018 09:51

        Смотреть код, который тщательно поддерживается и курируется. Это если нужен чужой код для сравнения со своим.
        Есть обратный вариант. Пишите статью на Хабр, в ней приводите небольшие кусочки кода и ссылку на проект, впадаете в депрессию от комментариев и общей оценки ваших трудов и заканчиваете жизнь самоубийством.


      1. markmariner
        22.06.2018 11:33

        Если вы можете безболезненно поддерживать и расширять вашу программу — у вас хорошее качество кода.


        1. Areso
          22.06.2018 12:47

          Смотрите. Если автор не может расширять свою программу — это плохой код.
          А если автор может расширять свою программу, то это не признак отсутствия плохого кода.
          Потому что другой человек откроет, не поймет ничего и ужаснется — значит это плохой код, но автор в состоянии его поддерживать.


  1. SbWereWolf
    22.06.2018 13:00

    Очень спорная статья. Минимум к 6-10 пунктам можно нпписать замечаний.


  1. altrus
    22.06.2018 13:10
    +1

    Маленькие коммиты с осмысленными заголовками помогут сопровождающим код людям понять, как шаг за шагом образовывалась программа, пока не достигла текущего состояния.

    Представил ситуацию, когда мой код коммит за коммитом кто-то так сопровождает.
    Варианта два:
    1. Это библиограф, а я Билл Гейтс. Мертвый.
    2. Это ботаны из УИТ ЦИБ ФСБ. А я в Лефортово.


    1. o4kapuk
      23.06.2018 00:29

      Справедливости ради нужно сказать, что есть и третий кейс: прибегает клиент с выпученными глазами и говорит, что в таком-то флоу в таком-то кейсе баг. А на самом деле это не совсем баг (или совсем не баг), а результат несогласованных требований к данному флоу, выставленных в разное время (а спецификация, разумеется, отсутствует). И вот тогда действительно приходится брать лопату и послойно разбираться, читать комментарии к коммитам и ссылаться на таски, попутно поясняя, как именно их взаимодействие привело к текущему результату.


      1. altrus
        23.06.2018 04:15

        Мне кажется для таких «поломок» хватает анализа пары последних коммитов. А если послойно и скурпулезно с самого начала — это скорей первые два варианта.


  1. mrZizik
    22.06.2018 13:15
    +1

    Интересный список.


  1. emkh
    22.06.2018 13:15

    По поводу «Не гуглить» — по смыслу этот заголовок не подходит: я бы лучше написал, нет «тупому» копипасту. Замечание относится конечно же к первоисточнику, а не к переводчику.


  1. Igor_ku
    22.06.2018 13:16

    Насчет першого пункта. Пока сам что-то не закодишь в уме это совсем никак не работает, а вот когда что-то написано, то все сразу хорошего видно


  1. saboteur_kiev
    22.06.2018 18:15

    Не пишите статьи типа «ошибок программистов», если вы сами не программист и не имеете хорошего опыта.

    «Новичкам можно посоветовать такое правило: любой недокументированный код, который вы не понимаете — плохой.»
    С какой стати код плохой? Он недокументирован, это плохо. Но с чего ему быть плохим?

    Очень много из 25 примеров в статье даны с неправильным толкованием.


    1. rustamaha Автор
      22.06.2018 18:41

      Автор статьи с нормальным опытом, уже не первый человек переводит его статьи для хабра, они вызывают интерес как минимум, и с медиума в рассылке они не просто так приходят — а значит у них высокий рейтинг и одобрения и читаемости.

      А код плохой — это что-то типа презумпции невиновности, только наоборот. Если не понимаешь код — не говори, что он хороший, пока не поймешь. Говори что хороший, только когда полностью понял. То есть призыв сомневаться, понимать и проверять. А не клеймить.


      1. saboteur_kiev
        22.06.2018 18:49

        «Новичкам можно посоветовать такое правило: любой недокументированный код, который вы не понимаете — плохой.»


        А код плохой — это что-то типа презумпции невиновности, только наоборот. Если не понимаешь код — не говори, что он хороший, пока не поймешь. Говори что хороший, только когда полностью понял. То есть призыв сомневаться, понимать и проверять. А не клеймить.


        Взаимоисключающие параграфы. То вы говорите, что код плохой, то вы говорите, что не нужно клеймить.
        Так не нужно говорить что код плохой или код хороший, пока не понимаешь что он делает. Просто нужно либо ничего не говорить, либо говорить «я не знаю, не разобрал еще». особенно, если это новичок.


      1. saboteur_kiev
        22.06.2018 18:57
        +1

        А, я нашел в чем дело:

        «As a beginner, you should just assume that any undocumented code that you do not understand is a candidate for being bad.»
        «Новичкам можно посоветовать такое правило: любой недокументированный код, который вы не понимаете — плохой.»

        «candidate for being bad» и «плохой» — так переводить не нужно.


        1. rustamaha Автор
          22.06.2018 21:17

          Спасибо за замечание, пока думаю как исправить.
          Первое что пришло в голову, «потенциально плохой», «кандидат на звание плохого», кажется не звучит. Еще подумаю немного и исправлю.


          1. ainoneko
            23.06.2018 07:14
            +1

            "… может оказаться плохим"?


            1. rustamaha Автор
              24.06.2018 08:16

              «возможно, плохой», написал пока )


  1. nleschev
    23.06.2018 19:36
    +1

    Пункт №0 Не думать про экономику проекта
    17) Не ориентироваться на конечного пользователя — должен быть №1
    26) Не задавать себе вопрос «а зачем»?

    Про тесты не хочу холиварить, но это тоже про экономику. На этапе тестирования идей и поиска бизнес-модели тесты вредны.