Типичные ошибки начинающих программистов

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

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

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

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

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

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) Не отдыхать

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

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

Первая ошибка начинающего программиста заключается в отсутствии плана

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

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

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

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

Начинающий программист недооценивает кодстайл

При написании кода важно учитывать его читабельность. Новички пренебрегают пробелами, полноценными и понятными именами переменных, предпочитая не обращать на эти вещи внимания и называть первую переменную “a”, вторую – “b” и т. д. Никогда не недооценивайте важность чистоты кода. В интернете есть множество статей, посвящённых кодстайлу для каждого из ЯП. Наши материалы по общим рекомендациям:

  • 10 принципов хорошего программного кода, который устроит всех
  • 6 простых советов по написанию чистого кода

Всегда думайте, будто парень, который будет поддерживать ваш код, – это жестокий психопат, который знает, где вы живёте.” – Джон Вудс.

Выбирает первое попавшееся решение

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

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

Как сказал Энтони Ричард Хоар, существует два принципа написания ПО:

  1. Первый: написать код настолько просто, что в нём не будет недостатков.
  2. Второй: сделать код настолько сложным, чтобы в нём нельзя было найти недостатки.

Не может бросить код незаконченным

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

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

Пятая ошибка начинающего программиста в том, что он не гуглит

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

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

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

Шестая ошибка начинающего программиста – он использует не подходящие структуры данных

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

Вот два небольших примера:

Использование списков (массивов) вместо хешей (объектов) для управления записями.

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

Неприменение стеков.

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

“Недорефакторинг”

Обычно под словом “рефакторинг” подразумевается улучшение кода для более ясного понимания и оптимизации. Однако не все новички умеют улучшать читабельность своего кода.

Например, сделать проект более грязным может дублирующийся код. Вместо написания функции с необходимыми параметрами, новички обычно просто копипастят раздел кода, чтобы изменить одну-единственную строчку; объясняют они это “введением нового функционала”. Если вы выбираете стул, то согласитесь, что рациональнее купить один регулируемый по высоте, вместо десяти разной высоты.

Пишет комментарии об очевидных вещах

Есть один способ избежать комментариев и сделать код более понятным – заменять комментарии на очевидно заданные элементы.

Вместо следующего кода:

// 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 even
      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;
  }
);

Девятая ошибка начинающего программиста – отсутствие тестов

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

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

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

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

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

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

Начинающие разработчики не ставят себя на место пользователя

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

То, чем заставляют заниматься в школах/ВУЗах, – изобретение колеса

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

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

Отторжение code review

Один из признаков начинающего программиста – восприятие code review как осуждение, критику. Он недоволен этой критикой, не ценит её или даже боится. Это в корне неправильное отношение к ревью. Если вы так себя чувствуйте, убедительно рекомендуем пересмотреть и изменить своё отношение. Смотрите на каждое ревью как на обучение, возможность узнать что-то новое. Самое главное, благодарите своих рецензентов, когда они вас чему-то учат. Большинство из них поделится с вами опытом, который, возможно, упростит вашу деятельность и положительно скажется на продуктивности.

Оригинал

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

  1. Да зачем мне этот английский?
  2. Консервация проблем
  3. Гуглить — это долго: быстрее дёрнуть тимлида
  4. Тесты? Не, не слышал
  5. А давайте комментировать всё!
  6. Забивать на ревью и рефакторинг
  7. Минимум времени на общение с заказчиком
  8. Git — просто странное слово
  9. Игнорировать новые инструменты
  10. Высыпаться? Куда высыпаться?

1. Да зачем мне этот английский?

Начнём с того, что преобладающее большинство языков программирования основаны на английском (ну если только это не 1С). Например знание английского позволит быстро понять, что происходит в этом куске кода:

try:
    1 / 0
except:
    print("You cannot divide by zero!")

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

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

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

2. Консервация проблем

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

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

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

В обоих случаях поможет следующий подход:

  1. Перед выполнением таска всегда составляйте план решения: так, обращаясь с вопросом, вы заочно продемонстрируете человеку, что готовились, а не просто сидели, сложа руки.
  2. Пробегитесь по документации, потыкайте поиск и Stack Overflow.
  3. Не помогло? Тогда как можно скорее просите более опытного коллегу о помощи. Чем дольше тянете, тем больше вопросов к вашему тайм-менеджменту.

3. Гуглить — это долго: быстрее дёрнуть тимлида

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

Держите мастер-класс для программиста «Как правильно гуглить»:

4. Тесты? Не, не слышал

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

Освойте методологию разработки TDD (test-driven development) — разработка через тестирование, которая основывается на повторении коротких циклов: написание теста, покрывающего изменения, а затем написание самого кода, который это реализовывает. Хотя TDD подходит не любому проекту, понимание и практика лишними не будут.

5. А давайте комментировать всё!

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

Пример так себе названий:

// Эта функция суммирует только нечётные числа в массиве
const sum = (val) => {
  return val.reduce((a, b) => {
    if (b % 2 === 1) { // Если текущее число нечётное,
      a+=b;            // добавляем это число
    }
    return a;          // Возвращаем результат
  }, 0);
};

И вот что будет, если называть переменные нормально:

const sumOddValues = (array) => {
  return array.reduce((accumulator, currentNumber) => {
    if (isOdd(currentNumber)) {
      return accumulator + currentNumber;
    }
    return accumulator;
  }, 0);
};

6. Забивать на ревью и рефакторинг

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

Код должен быть вычищен от:

  • дублей;
  • временных переменных;
  • лишних условий;
  • избыточных комментариев.

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

7. Минимум времени на общение с заказчиком

Как же раздражает, когда менеджер проекта просит во всех подробностях расписать план действий по таску, правда? Ведь клиент тратит ваше драгоценное время: достаточно ответить «Yes, of course», и с места в карьер. Правильно?

А вот и нет: это очередная ошибка начинающего разработчика. Ненужные, на первый взгляд, детали сэкономят вам время в ближайшем будущем. Неверно интерпретированный таск заставит вас написать код, который после придётся переделывать. Расписывать заказчику вопросы и план действий — обязательное условие, даже если очень лень, даже если заказчика самого раздражает такая дотошность. Важно докопаться до истины и понять, что вы оба on the same page, а не каждый сам по себе.

8. Git — просто странное слово

Блокнот — вполне подходящая система контроля версий (VCS), пока вы учитесь. Но выход на профессиональный уровень, даже если это Trainee, потребует от вас умения работать в команде. И вот здесь начинается самое интересное.

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

VCS позволяет быстро отыскать баг, время его появления и главного виновника. В Git предусмотрен бинарный поиск bisect, который находит коммит, внёсший баг.

9. Игнорировать новые инструменты

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

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

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

  1. Не оставляйте всё на пятницу и выходные.
  2. Не игнорируйте болезни и берите больничный, даже если«просто простуда».
  3. Не отодвигайте отпуск, если чувствуете, что знатно устали.
  4. ВЫСЫПАЙТЕСЬ!

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

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

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

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

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

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

1) Программирование без планирования
2) Чрезмерное планирование
3) Недооценивание важности качества кода
4) Хвататься за первое решение
5) Не отступать
6) Не гуглить
7) Не использовать инкапсуляцию
Планирование неизвестного
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). Этот загадочный термин означает, что внутри класса должно быть максимально связей, а между классами – минимально зависимостей.

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

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

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

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

“Рост ради роста — это идеология раковой клетки”. (Эдвард Эбби)

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

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

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

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

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

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

Обычный массив:

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

Ассоциативный массив:

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

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

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

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

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

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

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

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

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

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

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

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

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

Любой 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) Не отдыхать

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

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

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

1. Выбор платформы и языка программирования

1

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

Что же делать? Все гораздо проще, чем кажется. Зайдите на любой сайт фриланса и посмотрите, какие специалисты требуются на данный момент. Скорее всего, вы сможете увидеть общую картину и понять, какие навыки вам нужно освоить. Если вы хотите сесть на красный трактор и уехать в другую страну, то попробуйте посмотреть на ситуацию на зарубежных сайтах фриланса.

Еще один более трудоемкий способ – это ходить на собеседования. Там вы не только сможете понять, нужны ли вы вообще хоть кому-нибудь с тем объемом знаний и навыков, которыми вы обладаете на данный момент. А еще вы поймете, какие требования есть у работодателей.

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

2. Слишком много сомнений

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

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

3. Слишком высокое самомнение

2

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

Конечно, никто не спорит с тем, что вы, возможно, являетесь вторым Биллом Гейтсом и перевернете мир в будущем. Но поверьте, дядюшка Билл не относился к остальным высокомерно.

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

4. Не знать английский

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

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

5. Слишком много комментариев

3

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

Но вот что вам не стоит делать, так это оставлять комментарии вроде этого: “score += 5; // добавляет 5”. Это очевидно, и нет нужды еще раз писать об этом в комментарии. Конечно, комментировать каждую линию – это отличное упражнение для вашей первой программы. Но это не то, к чему вы должны привыкать.

6. Не доучиваться до конца

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

7. Учить один язык за другим

4

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

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

8. Пренебрегать дебаггерами

Если вы работаете с такими языками как Java, C# или ActionScript3, то вам стоит пользоваться дебаггером. Он не только облегчит вашу работу, но и обнаружит то, что вы можете не заметить.

9. Не делать бэкапы своей работы

5

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

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

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

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

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

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

Читайте также: 9 полезнейших сайтов для изучения программирования

Читайте также: Уроки по JavaScript для начинающих

Читайте также: 16 полезных уроков по CSS3 для начинающих

За последние 30 лет в сети появилась уйма профильных книг, статей, туториалов, курсов, которые новички используют для погружения в IT-сферу. Однако это не спасает их от типичных ошибок. О них лучше помнить еще во время обучения, чтобы свести к минимуму на реальной практике.

Итак, ТОП ошибок начинающего разработчика

1. Невнимательное изучение технического задания

Новички часто хотят побыстрей приступить к задаче, не вникая в детали. Однако же программирование сродни точным наукам — каждая мелочь важна. Ситуация «упустил из виду одну функцию из ТЗ на приложение» стоит переработок, нервов, времени, если не денег.

Совет: читайте техническое задание вдумчиво и не спеша. Детали влияют на то, как программист оценит для себя задачу, ее объем, и как следствие —  сроки выполнения.

2. Реализация первого решения и поиск лучшего

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

Совет: иногда задачу стоит сделать «просто хорошо». Главное — чтобы код был чистый, понятный и адекватно решал задачу.

3. Боязнь ошибок

Программирование — это вообще чаще всего работа над ошибками. Если они выводят вас из равновесия, то вы либо новичок, либо сфера вовсе вам не подходит.

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

4. Недокументированный код

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

В разрезе этой ошибки наблюдаются такие явления:

  • • мало или нет комментариев в коде;
  • • имена методов и переменных не описывают сами себя;
  • • мало или нет документации о том, как код вписывается в систему или бизнес-процессы.

Совет: комментарии — полезные подсказки для себя и других разработчиков. Только не переусердствуйте с ними «в другую сторону».

5. Откладывание ошибок на «потом»

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

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

6. Игнорирование систем контроля версий

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

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

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

7. Боязнь обращаться за помощью

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

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

А еще хорошей «профилактикой» являются курсы, например, в ITEA. Обучение здесь построено на практике, так что вам придется спрашивать обо всем, если хотите чему-то научиться. Таким образом вырабатывается привычка быть любознательным, что, конечно, поощряется.

8. Нежелание юзать инет

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

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

9. Отсутствие регулярных перерывов

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

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

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

10. Отсутствие тестинга

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

Совет: напишите простенький тест и прогоняйте через него свой код. Хотя бы на момент разработки будьте уверены, что все работает, как надо.

Выводы

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

Разработчики занимаются программированием и внедрением приложений и веб страниц. Такой специалист отвечает не только за программное обеспечение, но и за безопасность интернет площадки. Обычно он обладает рядом навыков и знаний, которые помогают развиваться в своей сфере. Среди таких навыков: математические способности, владение языком программирования, навыки в тайм — менеджменте, внимательность и сосредоточенность на деталях.

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

Ошибки, которые допускает разработчик

1. Слабый уровень знаний английского языка

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

Инглекс

Инглекс

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

Skyeng

Skyeng

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

Lingualeo

Lingualeo

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

Cambly

Cambly

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

Englishdom

Englishdom

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

2. Метания в выборе сферы программирования

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

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

3. Игнорирование ревью

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

  • Дубля;
  • Временной переменной;
  • Лишних комментариев;
  • Излишних условий.

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

4. Написание кода без предварительного плана

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

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

5. Ограниченное время в обсуждении заказа

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

6. Игнорирование посторонней помощи

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

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

7. Игнорирование тестов

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

8. Игнорирование работы с новыми инструментами

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

9. Не документирование кода

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

  • Отсутствуют комментарии в коде;
  • Переменные не описывают друг друга;
  • Отсутствуют записи о внедрении кода в систему или проект.

Документированное сопровождение кода — это обязательное условие для успешной работы программиста. Так он сможет всегда возвращаться к прошлой работе и анализировать все свои действия.

10. Игнорирование качества созданного кода

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

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

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

https://gbcdn.mrgcdn.ru/uploads/post/2139/og_image/866e65cb285465ef3c663de8eb923817.png

Источник: м/ф «Симпсоны»

У каждого из нас имеется собственный компьютер на углеродной основе — головной мозг. Мощный, продуктивный и чрезвычайно сложный. Но, увы, подверженный сбоям и ошибкам. Баги заметили ещё в античности, а древние римляне запротоколировали их в краткой и ёмкой формуле: «Человеку свойственно ошибаться».

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

Мы составили шорт-лист самых популярных ошибок, которые делают новички.

Самоуверенность или чрезмерные сомнения в себе

Эти проблемы — две стороны одной медали, поэтому мы объединили их.

«Я уже знаю всё, что нужно!» — типичная ошибка самоуверенного юнца. Первые шаги оказались успешными, первая программа запустилась без ошибок (почти) — ура, я стал мастером! Многие из нас проходят эту стадию, и всем приходится рано или поздно убедиться: это не так. Никто из разработчиков, каким бы опытным он ни был, не знает всё, что может ему когда-либо понадобиться. Быть программистом — значит постоянно учиться, открывать для себя новые приёмы и возможности, заниматься исследованиями и экспериментировать. А порой даже мучительно вспоминать: «Чёрт возьми, я ведь уже делал что-то подобное, но не помню, как именно!»

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

Эта проблема известна с 1999 года как эффект Даннинга — Крюгера. В 2000 году  исследование авторов было отмечено Шнобелевской премией по психологии.

Но если у вас есть хорошая книга по программированию и/или грамотный наставник, вскоре вы заметите, что изучать язык программирования не сложнее (даже проще), чем какой-нибудь иностранный. Не слушайте тех, кто утверждает, что нужен особый талант, чтобы быть разработчиком. Склонность к логическому мышлению и математический склад ума могут помочь, но 99 % успеха — это труд, настойчивость и многочасовая учеба с чтением документации.

Изобретение велосипеда

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

Но программистам-новичкам лучше не пытаться прыгать выше головы, а сначала ознакомиться с теми «моделями велосипедов», которые  уже придуманы. Чаще всего готовое решение окажется и проще, и эффективнее.

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

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

И ещё — если вам нужна одна педаль, не стоит добавлять в проект весь велосипед. Импортируйте только те функции и классы из внешней библиотеки, которые вам необходимы. Не захламляйте проект!

Плохой стиль программирования и оформления кода

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

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

То же относится и к комментариям. Оставляя короткие и ясные примечания к коду, вы облегчаете труд себе и преемникам. 

Распространённая формула оценки кода — «What The F*ck’s»/minite — количество сомнительных мест в коде, которые можно за минуту отследить на код-ревью. Чем меньше это значение, тем лучше. 

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

Чрезмерное комментирование

Комментирование — это полезно и важно! Иногда (особенно работая с чужим кодом) вы будете остро нуждаться в подсказке: что делает этот кусок программы, зачем здесь цикл, для чего нужна эта переменная?

Некоторые программисты не комментируют код вовсе (и мы это не одобряем). Другие ударяются в противоположную крайность и пишут комментарии едва ли не к каждой строке.

К примеру:

int_Count += 1 // увеличиваем счетчик на 1

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

Оставляйте комментарии только там, где они действительно нужны. Комментируйте неочевидные решения, оставляйте пояснения о том, что делает класс или функция. Старайтесь формулировать комментарии кратко, чётко и только по делу. 

Плохие имена

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

Для компьютера это не проблема — переменные с именами типа f_ertw4d или j83lop0dpp будут работать не хуже, чем int_TryCount и str_UserName. Может быть, разработчику такие буквенно-цифровые аббревиатуры что-то говорят, но сторонний человек заработает головную боль, пытаясь удержать их в памяти. 

Таких проблем можно избежать, если давать объектам «говорящие» названия. Чем более внятное и содержательное имя, тем проще будущим поколениям программистов оценить ваш шедевр.

Правда, иногда в результате такого подхода рождаются неудобоваримые имена в духе AbstractSingletonProxyFactoryBean — настоящий Эйяфьядлайекюдль в IT. Но если бы создатели Java решили сократить имя этого класса до аббревиатуры «aspfb», было бы куда сложнее разобраться, что же это за класс и для чего он нужен.

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

Важнейшие общепринятые принципы именования объектов:

  • использовать осмысленные имена;
  • использовать CamelCase;
  • соблюдать регистр имени, даже если язык к нему нечувствителен; 
  • использовать префиксы для имён переменных разных типов или разного назначения (например, для переменных типа integer использовать префикс int_).

Отсутствие «защиты от дурака»

Мы можем работать над программой, которой будут пользоваться доктора наук, но не стоит чересчур полагаться на их регалии и звания. Если в программе предусмотрено поле с подписью «Введите число от 1 до 10» — не поленитесь, проверьте, что ввёл туда пользователь. Как показывает практика, там могут оказаться и значения из неправильного диапазона, и вообще ничего (если пользователь пропустил строку ввода). А иногда даже слово прописью: «десять». 

Попробуйте убедить пользователя, что такой ввод числа был неправильным!

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

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

Работа над кодом без общего плана

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

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

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

Чересчур большие функции

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

Ваша функция определённо слишком велика, если:

  • она занимает больше 50 строк;
  • вы не можете объяснить ее предназначение в одном предложении;
  • она содержит слишком много условных операторов или циклов.

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

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

Вместо этого создадим подфункции:

  • функцию, предлагающую пользователю выбрать файл (возвращающую дескриптор открытого файла);
  • функцию, считывающую матрицу в массив;
  • функцию для подсчёта арифметического среднего для заданной строки или столбца массива;
  • функцию для формирования графика.

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

Использование глобальных переменных не по назначению

Глобальные переменные удобны: достаточно один раз определить их в начале программы — и можно использовать в любом месте кода. До тех пор, пока не обнаружите, что одна из них содержит очевидно некорректное значение. И тогда придётся потратить полдня и кучу нервов, чтобы наконец выяснить, что значение изменилось после вызова какой-то функции, где она почему-то тоже используется (вот так неожиданность!). 

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

Выбор первого попавшегося решения

Перед вами поставили задачу. «О, я знаю, как это сделать!» — говорите вы и немедленно приступаете к выполнению.

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

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

Пренебрежение отладчиком

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

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

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

«Бэкапы для слабаков!» (на самом деле нет)

Фраз вроде «Я потерял целый день работы из-за сбоя!» вообще не должно быть в словаре программиста. Придумано множество средств, которые помогают автоматически сохранять бэкапы, выполнять резервное копирование и осуществлять контроль версий. Компьютер завис и пропали наработки? Следовало настроить автосохранение. Сгорел винчестер? Нужно было сохранять данные на сервере или в облаке. 

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

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

Google It First!

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

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

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

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

Все мы когда-то только начинали программировать и делали ошибки. Напоследок несколько конструктивных советов:

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

И всё у вас получится!

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

https://gbcdn.mrgcdn.ru/uploads/post/6/og_cover_image/3f6f8ab8d304f5a6ba3db89c837511ae

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

Неумение кататься на велосипедах

Неожиданно, да?) На самом деле я хотел сказать, что в эпоху дот-нетов, мак буков и web 2.0 всё (ну или почти всё) уже написано. На любой более-менее популярный язык программирования – по несколько фреймворков и сред разработки, в том числе множество бесплатного, но качественного софта и огромное количество CMS’ок и движков сайтов, для коих, в свою очередь, тысячи плагинов, расширяющих их функционал.
Но начинающие программисты часто либо забывают про этот факт, либо его игнорируют. Они, может быть, и понимают, что кто-то уже решил задачу, которая перед ними стоит, и предлагает решение абсолютно бесплатно, но это почему-то не останавливает их от изобретения велосипедов, которые в большинстве случаев оказываются менее качественными, чем уже изобретенные. А ведь вместо придумывания лучше найти хороший пример с открытым кодом и сосредоточиться на других задачах.

Использование неподходящих средств разработки

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

Вопросы, на которые уже 100 раз ответили

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

Костыли

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

«Этого точно никогда не будет»

 Любимая тема новичка – игнорировать обработку некорректных входных данных. Мотив – «этого точно никогда не будет» :) А ведь будет наверняка! Закон программистской подлости – случится именно то, чего ты  не предусмотрел. Надо быть готовым, что там, где должны ввести год рождения, будут вводить все, что угодно, кроме нужных четырех цифр. При этом еще нужно придумать правильные ограничивающие условия.

Некрасивый код

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

Не получилось с первого раза – ищем простой путь

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

Учимся на своих ошибках и не забываем: хорошо написанная программа – плюс один в карму!)

Тем, кто хочет стать программистом, рекомендуем профессию «Веб-разработчик».

  • Типичные ошибки начинающих поэтов
  • Типичные ошибки введения инсулина тест ответ нмо
  • Типичные ошибки введения инсулина выберите несколько правильных ответов
  • Типичные ошибки барьерного бега
  • Типичные ошибки аудиторских процедур