Чёртова дюжина ошибок начинающего программиста

Что не нужно делать при разработке ПО
12 минут60490

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

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

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

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

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

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

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

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

Эта проблема известна с 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 можно создавать инструкции по тому, как загуглить что бы то ни было

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

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

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

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

программированиеjava
Нашли ошибку в тексте? Напишите нам.
Спасибо,
что читаете наш блог!