Научитесь определять их, делать привычки, чтобы избежать их.
Позвольте мне сначала сделать одно. Если вы новичок-программист, эта статья не предназначена для того, чтобы вы плохо себя чувствовали в ошибках, которые вы могли бы совершить, а скорее, чтобы вы знали о них, учат вас видеть знаки их и напоминать вам об их избегании.
Я сделал эти ошибки в прошлом и узнал от каждого из них. Я рад сформировать привычки кодирования, чтобы помочь мне избежать их. Вы тоже должны это сделать.
Эти ошибки здесь не представлены в каком-либо конкретном порядке.
1) Написание кода без планирования
Высококачественный письменный контент, в общем, не может быть легко создан. Это требует тщательного мышления и исследований. Высококачественные программы не являются исключением.
Написание качественных программ - это процесс с потоком:
подумайте . Исследования . План . Напишите . Подтвердить . Изменить .
К сожалению, для этого нет хорошего акронима. Вам нужно создать привычку всегда выбирать правильное количество этих действий.
Одна из самых больших ошибок, которые я сделал в качестве начинающего программиста, заключалась в том, чтобы сразу же начать писать код, не задумываясь и не изучая. Хотя это может работать для небольшого автономного приложения, оно оказывает большое негативное влияние на более крупные приложения.
Так же, как вам нужно думать, прежде чем говорить что-либо, о чем вы можете пожалеть, вам нужно подумать, прежде чем писать что-нибудь, о чем вы можете пожалеть. Кодирование - это также способ сообщить свои мысли.
Когда вы разозлитесь, посчитайте до 10, прежде чем говорить. Если очень рассердился, сто.
- Томас Джеферсон.
Вот моя версия этой цитаты:
При просмотре кода считайте до 10, прежде чем реорганизовать линию. Если код не имеет тестов, то сто.
- Самер Буна
Программирование в основном связано с чтением предыдущего кода, изучением того, что необходимо и как он вписывается в текущую систему, и планированием написания функций с небольшими проверяемыми приращениями. Фактическое написание строк кода, вероятно, составляет всего 10% от всего процесса.
Не думайте о программировании как написании строк кода. Программирование - это основанный на логике творческий подход, требующий воспитания.
2) Планирование слишком много до написания кода
Да. Планирование перед тем, как перейти к написанию кода - это хорошо, но даже хорошие вещи могут повредить вам, когда вы делаете слишком много из них. Слишком много воды может отравить вас.
Не ищите идеальный план. Это не существует в мире программирования. Ищите достаточно хороший план, который вы можете использовать для начала. Истина заключается в том, что ваш план изменится, но то, что было хорошо, - это заставить вас превратиться в какую-то структуру, которая приведет к большей ясности в вашем коде. Слишком много планирования - просто пустая трата времени.
Я говорю только о планировании небольших возможностей. Планирование всех функций сразу должно быть объявлено вне закона! Это то, что мы называем « Водопадным подходом» , который представляет собой системный линейный план с отдельными шагами, которые должны быть завершены один за другим. Вы можете себе представить, сколько планирования требуется для этого подхода. Это не та планировка, о которой я говорю здесь. Подход водопада не работает. Все сложное может быть реализовано только с гибкой адаптацией к реальности.
Письменные программы должны реагировать. Вы добавите функции, о которых вы никогда бы не подумали в плане водопада. Вы удалите функции по причинам, которые вы никогда бы не рассмотрели в плане водопада. Вам нужно исправить ошибки и адаптироваться к изменениям. Вы должны быть проворными.
Однако всегда планируйте следующие несколько функций. Делайте это очень осторожно, потому что слишком мало планирования и слишком много планирования может как повредить качество вашего кода, так и качество вашего кода - это не то, что вы можете рискнуть.
3) Недооценка важности качества кода
Если вы можете сосредоточиться только на одном аспекте кода, который вы пишете, это должно быть его читабельность . Нечеткий код - это мусор. Он даже не подлежит вторичной переработке.
Никогда не недооценивайте важность качества кода. Посмотрите на кодирование как способ передачи реализаций. Ваша основная работа в качестве кодера - четко информировать о реализации любых решений, над которыми вы работаете.
Одна из моих любимых цитат о программировании:
Всегда указывайте, как будто парень, который заканчивает поддерживать ваш код, будет жестоким психопатом, который знает, где вы живете.
- Джон Вудс
Блестящий совет, Джон!
Даже мелочи имеют значение. Например, если вы не согласны с вашим отступом и капитализацией, вы должны просто потерять лицензию на код.
ТАЙНА
БОЛЬШЕ важна
чем
вы думаете
Еще одна простая вещь - использование длинных строк. Все, что превышает 80 символов, гораздо труднее прочитать. Возможно, у вас возникнет соблазн поставить какое-то длительное условие на одну строку, чтобы сохранить блок if-statement более заметным. Не делай этого. Просто никогда не выходите за пределы 80 символов, никогда.
Многие простые проблемы, подобные этим, могут быть легко устранены с помощью инструментов для литья и форматирования . В JavaScript, у нас есть две отличные инструменты , которые работают отлично вместе: ESLint и похорошела . Сделайте себе одолжение и всегда используйте их.
Вот еще несколько ошибок, связанных с качеством кода:
- Использование нескольких строк в функции или файле. Вы всегда должны ломать длинный код на более мелкие куски, которые можно протестировать и управлять отдельно.
Любая функция, имеющая более 10 строк, слишком длинная
- Использование двойных негативов. Пожалуйста, не делайте этого.
Использование двойных негативов просто не совсем не так.
- Использование коротких, общих или имен переменных типа. Дайте вашим переменным описательные и недвусмысленные имена.
В «Информатике» есть только две вещи: недействительность кеша и именование.
- Фил Карлтон
- Жестко кодирующие примитивные строки и числа без описания. Если вы хотите написать логику, которая зависит от фиксированной примитивной строки или числа, поместите это значение в константу и дайте ей хорошее имя.
const answerToLifeTheUniverseAndEverything = 42;
- Использование неаккуратных ярлыков и обходных решений, чтобы не тратить больше времени на простые проблемы. Не танцуйте вокруг проблем. Посмотрите на свои реалии.
- Думаю, что более длинный код лучше. В большинстве случаев более короткий код лучше. Только писать более длинные версии, если они делают код более читаемым. Например, не используйте умные однострочные и вложенные трехмерные выражения, чтобы сохранить код короче, но также не намеренно делать код длиннее, когда это не нужно. Удаление ненужного кода - лучшее, что вы можете сделать в любой программе.
Измерение прогресса программирования по линиям кода подобно измерению прогресса самолета по массе.
- Билл Гейтс
- чрезмерное использование условной логики. Большая часть того, что, по вашему мнению, требует условной логики, может быть достигнута без нее. Рассмотрите все альтернативы и выберите исключительно на основе удобочитаемости. Не оптимизируйте производительность, если вы не можете измерить ее. Связано: избегайте условий и назначений Yoda в условных выражениях.
4) Выбор первого решения
Когда я начинал программировать, я помню, что когда мне представилась проблема, я найду решение и сразу же займусь этим. Я бы сразу бросил реализацию, прежде чем думать о сложностях и потенциальных ошибках моего первого идентифицированного решения.
Хотя первое решение может быть заманчивым, хорошие решения обычно обнаруживаются после того, как вы начнете опросить все найденные вами решения. Если вы не можете думать о нескольких решениях проблемы, это, вероятно, признак того, что вы не полностью понимаете проблему.
Ваша работа в качестве профессионального программиста заключается не в том, чтобы найти решение проблемы. Это найти простейшеерешение проблемы. Под «простым» я подразумеваю, что решение должно работать правильно и выполнять адекватно, но все же быть достаточно простым, чтобы читать, понимать и поддерживать.
Существует два способа построения программного обеспечения. Один из способов - сделать его настолько простым, что, очевидно, нет недостатков, а наоборот - сделать его настолько сложным, что нет очевидных недостатков.
- Автомобильный хор
5) Не оставлять
Еще одна ошибка, которую я делал чаще, чем я хотел признать, придерживается первого решения даже после того, как я определяю, что это может быть не самый простой подход. Вероятно, это психологически связано с менталитетом « не уходящего ». Это хороший менталитет в большинстве видов деятельности, но он не должен применяться к программированию. На самом деле, когда дело доходит до написания программ, правильный менталитет терпит неудачу рано и часто случается .
В тот момент, когда вы начинаете сомневаться в решении, вы должны подумать о том, чтобы выбросить его и переосмыслить проблему. Это верно, независимо от того, сколько вы были инвестированы в это решение. Инструменты управления источниками, такие как GIT, могут помочь вам отлаживаться и экспериментировать со многими различными решениями. Используйте это.
Не привязывайтесь к коду из-за того, сколько усилий вы вложили в него. Плохой код нужно отбросить.
6) Не гуглинг
Было много случаев, когда я потратил драгоценное время на то, чтобы решить проблему, когда я должен был сначала исследовать ее.
Если вы не используете передовую технологию, когда вы сталкиваетесь с проблемой, есть вероятность, что кто-то другой столкнулся с одной проблемой и нашел для нее решение. Спасите себя некоторое время и Google It First .
Иногда Googling показывает, что то, что вы считаете проблемой, на самом деле не так, и что вам нужно сделать, это не исправление, а принятие этого. Не предполагайте, что вы знаете все, что необходимо для решения проблемы. Google удивит вас.
Однако будьте осторожны, для чего вы Google. Еще один признак новичка - это копирование и использование другого кода, поскольку оно не понимает его. Хотя этот код может правильно решить вашу проблему, вы никогда не должны использовать какую-либо строку кода, которую вы не полностью понимаете.
Если вы хотите быть креативным кодером, никогда не думайте, что знаете, что делаете.
Самая опасная мысль, которую вы можете иметь как творческую личность, - это думать, что вы знаете, что делаете.
- Брет Виктор
7) Не использование инкапсуляции
Речь идет не об использовании объектно-ориентированной парадигмы. Использование концепции инкапсуляции всегда полезно. Не использование инкапсуляции часто приводит к более сложным системам.
В приложении функция должна иметь только одно место, которое обрабатывает ее. Как правило, это ответственность одного объекта. Этот объект должен показывать только то, что абсолютно необходимо для использования другими объектами приложения. Речь идет не о секретности, а о концепции сокращения зависимостей между различными частями приложения. Придерживаясь этих правил, вы можете безопасно вносить изменения во внутренние части своих классов, объектов и функций, не беспокоясь о том, чтобы разбить вещи в большем масштабе.
Концептуальные единицы логики и состояния должны получать свои собственные классы . По классу я имею в виду шаблон шаблона. Это может быть фактический объект класса или объект Function . Вы также можете идентифицировать его как модуль или пакет .
В рамках класса логики самодостаточные части задач должны иметь свои собственные методы. Методы должны делать одно и делать это хорошо. Аналогичные классы должны использовать те же имена методов.
Будучи программистом-новичком, у меня не всегда был инстинкт, чтобы начать новый класс для концептуального подразделения, и я часто не мог определить, что может быть самодостаточным. Если вы видите Utilкласс « », который использовался как свалка для многих вещей, которые не принадлежат друг другу, это признак кода для новичков. Если вы сделаете простое изменение, а затем обнаружите, что изменение имеет каскадный эффект, и вам нужно сделать много изменений в другом месте, это еще один признак кода для новичков.
Прежде чем добавлять метод к классу или добавлять дополнительные функции к методу, подумайте и спросите свои инстинкты. Тебе нужно время. Не пропустите или не подумайте, что позже вы будете реорганизовывать . Просто сделайте это правильно в первый раз.
Большая идея здесь заключается в том, что вы хотите, чтобы ваш код имел High Cohesion и Low Coupling , что является просто причудливым термином, который означает совместное использование связанного кода (в классе) и уменьшение зависимостей между различными классами.
8) Планирование неизвестного
Часто возникает соблазн задуматься над тем, что вы пишете. Всевозможные «что-то» появятся в вашей голове с каждой строкой кода, которую вы пишете. Это хорошо для тестирования крайних случаев, но просто неправильно использовать его в качестве драйвера для потенциальных нужд .
Вам нужно определить, к какой из этих двух основных категорий принадлежит ваше. Не пишите код, который вам не нужен сегодня. Не планируйте на неизвестное будущее.
Написание функции, потому что вы думаете, что вам может понадобиться в будущем, просто неправильно. Не делай этого.
Всегда указывайте минимальный объем кода, который вам нужен сегодня для решения, которое вы используете. Обращайтесь с краями, конечно, но не добавляйте краевые функции .
Рост ради роста - это идеология раковой клетки.
- Эдуард Абби
9) Не использовать правильные структуры данных
При подготовке к собеседованию начинающие программисты обычно уделяют слишком много внимания алгоритмам. Хорошо идентифицировать хорошие алгоритмы и использовать их при необходимости, но запоминание их, вероятно, никогда не будет приписывать вашему программированию гению.
Тем не менее, запоминание сильных и слабых сторон различных структур данных, которые вы можете использовать на своем языке, безусловно, сделает вас лучшим разработчиком.
Использование неправильной структуры данных - это большой и сильно освещенный рекламный щит, который кричит здесь код новичка.
Эта статья не предназначена для того, чтобы научить вас структурам данных, но позвольте мне упомянуть пару быстрых примеров:
- Использование списков (массивов) вместо карт (объектов) для управления записями
Наиболее распространенной ошибкой структуры данных является, вероятно, использование списков вместо карт для управления списком записей. Да, для управления списком записей вы должны использовать MAP.
Обратите внимание, что я говорю о списке записей здесь, где каждая запись имеет идентификатор, который будет использоваться для поиска этой записи. Использование списков для скалярных значений в порядке и часто лучший выбор, особенно если фокус использования «подталкивает» значения к списку.
В JavaScript наиболее распространенной структурой списка является массив, а наиболее распространенная структура карты - это объект (в современном JavaScript также есть структура карты).
Использование списков по картам для управления записями часто неверно. Хотя этот момент действительно справедлив только для больших коллекций, я бы сказал, просто придерживайтесь его все время. Основная причина, по которой это важно, заключается в том, что при поиске записей с использованием их идентификаторов карты намного быстрее, чем списки.
- Не использовать стеки
При написании любого кода, требующего некоторой формы рекурсии, всегда возникает соблазн использовать простые рекурсивные функции. Однако, как правило, трудно оптимизировать рекурсивный код, особенно в однопоточных средах.
Оптимизация рекурсивного кода зависит от того, какие возвратные функции возвращаются. Например, оптимизация рекурсивной функции, которая возвращает два или более вызовов самому себе, намного сложнее, чем оптимизировать рекурсивную функцию, которая просто возвращает один вызов самому себе.
То, что мы склонны игнорировать как новички, заключается в том, что существует альтернатива использованию рекурсивных функций. Вы можете просто использовать структуру Stack . Нажимайте вызовы функций непосредственно на Stack и начинайте выскакивать их, когда вы готовы пройти обратные вызовы.
10) Сделать существующий код хуже
Представьте, что вам дали грязную комнату:
Затем вас попросили добавить предмет в эту комнату. Поскольку это уже большой беспорядок, у вас может возникнуть соблазн поставить этот предмет в любом месте. Через несколько секунд вы сможете выполнить свою задачу.
Не делайте этого с грязным кодом. Не делайте это хуже! Всегда оставляйте код немного чище, чем когда вы начали работать с ним.
Правильная вещь, которую нужно сделать в комнате выше, - это очистить то, что необходимо, чтобы разместить новый предмет в нужном месте. Например, если предмет представляет собой предмет одежды, который должен быть помещен в шкаф, вам необходимо очистить путь к этому шкафу. Это часть выполнения вашей задачи правильно.
Вот несколько неправильных практик, которые обычно делают код более сложным, чем то, чем он был (не полный список):
- Дублирующий код . Если вы копируете / вставляете раздел кода, чтобы только изменить строку после этого, вы просто дублируете код и делаете больший беспорядок. В контексте примера грязной комнаты, это было бы похоже на введение другого стула с нижней базой вместо того, чтобы инвестировать в новый стул, регулируемый по высоте. Всегда держите концепцию абстракции в своем уме и используйте ее, когда сможете.
- Не использовать файлы конфигурации . Если вам нужно использовать значение, которое потенциально может быть разным в разных средах или в разное время, это значение относится к файлу конфигурации. Если вам нужно использовать значение в нескольких местах в вашем коде, это значение принадлежит файлу конфигурации. Просто задайте себе этот вопрос все время, когда вы вводите новое значение для кода: это значение принадлежит файлу конфигурации? Ответ, скорее всего, будет да.
- Использование ненужных условных операторов и временных переменных . Каждый оператор if - это логическая ветвь, которая должна быть как минимум дважды проверена. Когда вы можете избежать условностей, не жертвуя удобочитаемостью, вы должны. Основная проблема заключается в расширении функции с логикой ветвления вместо введения другой функции. Каждый раз, когда вы думаете, что вам нужен оператор if или новая функциональная переменная, вы должны спросить себя: я меняю код на правильном уровне или должен ли я думать о проблеме на более высоком уровне?
На тему ненужных if-утверждений подумайте об этом коде:
function isOdd (число) {
if (number% 2 === 1) {
return true;
} else {
return false;
}
}
isOddВыше функция имеет несколько проблем , но вы можете увидеть самый очевидный?
Он использует ненужный if-statement. Вот эквивалентный код:
function isOdd (число) {
return (число% 2 === 1);
};
11) Написание комментариев об очевидных вещах
Я усвоил трудный способ избежать написания комментариев, когда смогу. Большинство комментариев могут быть заменены на более названные элементы в вашем коде.
Например, вместо следующего кода:
// Эта функция суммирует только нечетные числа в массиве
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;
}
обратный аккумулятор;
}, 0);
};
Просто использование лучших имен для функций и аргументов просто делает большинство комментариев ненужными. Имейте это в виду, прежде чем писать какие-либо комментарии.
Однако иногда вас принуждают к ситуациям, когда единственная ясность, которую вы можете добавить в код, - это комментарии. Это когда вы должны структурировать свои комментарии, чтобы ответить на вопрос ПОЧЕМУ этот код, а не вопрос ЧТО это делает этот код .
Если вы сильно соблазняетесь написать комментарий WHAT для уточнения кода, пожалуйста, не указывайте на очевидное. Вот пример некоторых бесполезных комментариев, которые только добавляют шум к коду:
// создаем переменную и инициализируем ее до 0,
пусть sum = 0;
// Loop over array
array.forEach (
// Для каждого числа в массиве
(число) => {
// Добавить текущий номер в сумму переменной
sum + = number;
}
);
Не будь этим программистом. Не принимайте этот код. Удалите эти комментарии, если вам приходится иметь дело с ними. Если вы, оказывается, нанимаете программистов, которые пишут комментарии, подобные приведенным выше, стреляйте в них прямо сейчас.
12) Не написание тестов
Я собираюсь сохранить эту точку просто. Если вы думаете, что являетесь экспертом-программистом, и это мышление дает вам уверенность в написании кода без тестов, вы новичок в моей книге.
Если вы не пишете тесты в коде, вы, скорее всего, проверите свою программу по-другому, вручную. Если вы создаете веб-приложение, вы будете обновлять и взаимодействовать с приложением после каждых нескольких строк кода. Я тоже это делаю. Нет ничего плохого в ручном тестировании вашего кода. Однако вы должны вручную протестировать свой код, чтобы выяснить, как его автоматически проверять. Если вы успешно протестируете взаимодействие с вашим приложением, вы должны вернуться к редактору кода и написать код, чтобы автоматически выполнять то же самое взаимодействие при следующем добавлении дополнительного кода в проект.
Вы человек. Вы не забудете протестировать все ранее успешные проверки после каждого изменения кода. Сделайте компьютер для этого!
Если вы можете, начните с угадывания или разработки ваших проверок даже до того, как вы напишете код для их удовлетворения. Тестируемое развитие (TDD) - это не просто причудливый ажиотаж. Это позитивно влияет на то, как вы думаете о своих функциях и как придумать лучший дизайн для них.
TDD не для всех, и он не работает хорошо для каждого проекта, но если вы можете его использовать (даже частично), вы должны это сделать полностью.
13) Предполагая, что если дела работают, все правильно
Взгляните на эту функцию, которая реализует эту sumOddValuesфункцию. Что-то не так с этим?
const sumOddValues = (array) => {
return array.reduce ((accumulator, currentNumber) => {
if (currentNumber% 2 === 1) {
return accumulator + currentNumber;
}
обратный аккумулятор;
});
};
console.assert (
sumOddValues ([1, 2, 3, 4, 5]) === 9
);
Утверждение проходит. Жизнь хороша. Верно-верно?
Проблема с приведенным выше кодом заключается в том, что он не завершен. Он правильно обрабатывает несколько случаев (и используемое утверждение является одним из таких случаев), но у него много других проблем. Позвольте мне пройти через несколько из них:
- Проблема № 1: для пустого ввода нет обработки. Что должно произойти, когда функция вызывается без каких-либо аргументов? Прямо сейчас вы получаете сообщение об ошибке реализации функции, когда это происходит:
TypeError: Невозможно прочитать свойство «уменьшить» неопределенного.
Это обычно является признаком плохого кода по двум основным причинам.
- Пользователи вашей функции не должны сталкиваться с деталями реализации.
- Ошибка не помогает пользователю. Ваша функция просто не работала для них. Однако, если ошибка была более понятной в проблеме использования, они знали бы, что они неправильно использовали эту функцию. Например, вы можете выбрать, чтобы функция выбрала пользовательское исключение, подобное этому:
TypeError: Невозможно выполнить функцию для пустого списка.
Возможно, вместо того, чтобы бросать ошибку, вам нужно создать свою функцию, чтобы просто игнорировать пустой ввод и вернуть сумму 0. Независимо от того, что-то должно быть сделано для этого случая.
- Проблема № 2: Обработка недопустимого ввода не выполняется. Что произойдет, если функция вызывается со строкой, целым числом или значением объекта вместо массива?
Вот что теперь будет бросать функция:
sumOddValues (42);
TypeError: array.reduce не является функцией
Ну, это несчастливо, потому что array.reduceэто определенно функция!
Поскольку мы назвали аргумент функции array, все, что вы вызываете с помощью функции ( 42в приведенном выше примере), помечено как arrayфункция. Ошибка в основном говорит, что 42.reduceэто не функция.
Вы видите, как эта ошибка запутывает, не так ли? Возможно, более полезная ошибка:
TypeError: 42 is not an array, dude.
Проблемы №1 и №2 иногда называют краевыми. Это некоторые общие краевые задачи для планирования, но обычно есть менее очевидные краевые случаи, о которых вам нужно думать. Например, что произойдет, если мы используем отрицательные числа?
sumOddValues ([1, 2, 3, 4, 5, -13]) // => еще 9
Ну, -13это странное число. Это поведение, которое вы хотите, чтобы эта функция имела? Должен ли он выкинуть ошибку? Должны ли они включать отрицательные числа в сумме? Или просто просто игнорировать отрицательные числа, как это происходит сейчас? Возможно, вы поймете, что функция должна была быть названа sumPositiveOddNumbers.
Принятие решения по этому делу легко. Более важным моментом является то, что если вы не напишете тестовый пример для документирования вашего решения, будущие сторонники вашей функции не будут иметь понятия, если ваше игнорирование отрицательных чисел было преднамеренным или ошибочным.
Это не ошибка. Это особенность.
- Кто-то, кто забыл тест
- Проблема №3: Не все проверенные случаи проверены. Забудьте о крайних случаях, эта функция имеет законный и очень простой случай, когда она не обрабатывается правильно:
sumOddValues ([2, 1, 3, 4, 5]) // => 11
2Выше , был включен в сумму , когда оно не должно быть.
Решение прост, reduceпринимает второй аргумент, который будет использоваться в качестве начального значения для accumulator. Если этот аргумент не предоставлен (как в приведенном выше коде), reduceон просто будет использовать первое значение в коллекции в качестве начального значения для accumulator. Вот почему первое значение в приведенном выше тестовом случае было включено в сумму.
Хотя вы, возможно, сразу заметили эту проблему или когда код был написан, этот тестовый пример, который показал его, должен был быть включен в тесты, в первую очередь, наряду со многими другими тестовыми примерами, такими как все четные числа, список который имеет 0в нем и пустой список.
Если вы видите минимальные тесты, которые не обрабатывают многие случаи или игнорируют краевые случаи, это еще один признак кода для новичков.
14) Не допросить существующий код
Если вы не суперкодер, который всегда работает соло, нет никаких сомнений в том, что вы столкнетесь с каким-то глупым кодом в своей жизни. Начинающие не узнают об этом, и они обычно считают, что это хороший код, поскольку он, кажется, работает, и он уже давно является частью кодовой базы.
Хуже всего то, что если плохой код использует плохую практику, у новичка может возникнуть соблазн повторить эту плохую практику в другом месте в кодовой базе, потому что они узнали ее из того, что они считали хорошим кодом.
Некоторый код выглядит плохо, но у него может быть особое условие, которое заставило разработчика написать его таким образом. Это хорошее место для подробного комментария, который учит начинающих об этом состоянии и почему код написан таким образом.
Как новичок, вы должны просто предположить, что любой недокументированный код, который вы не понимаете, является кандидатом на плохое. Вопрос. Спросите об этом. git blameЭто!
Если автор этого кода давно ушел или не может его запомнить, изучите этот код и попытайтесь понять все об этом. Только когда вы полностью понимаете код, который вы получаете, чтобы составить мнение о том, плохо это или хорошо. Не думай ничего перед этим.
15) Одержимость лучшей практики
Я думаю, что термин «лучшие практики» на самом деле вреден. Это означает, что дальнейшие исследования не требуются. Вот самая лучшая практика. Не спрашивайте об этом!
Нет лучших методов. Есть , вероятно , хорошие практики , сегодня и для этого языка программирования .
Некоторые из того, что мы ранее идентифицировали как лучшие практики в программировании, сегодня обозначены как плохие методы.
Вы всегда можете найти лучшие практики, если инвестируете достаточно времени. Остановите беспокоиться о лучших практиках и сосредоточьтесь на том, что вы можете сделать лучше всего.
Не делайте что-либо из-за цитаты, которую вы читали где-то, или потому, что вы видели, как кто-то это делает, или потому, что кто-то сказал, что это лучшая практика.
16) Одержимость о производительности
Преждевременная оптимизация - это корень всех злых (или, по крайней мере, большей части) в программировании
- Дональд Кнут (1974)
Хотя программирование значительно изменилось с тех пор, как Дональд Кнут написал вышеупомянутое заявление, я думаю, что он по-прежнему имеет ценный совет сегодня.
Хорошее правило помнить об этом: если вы не можете измерить предполагаемую эффективную проблему с кодом, не пытайтесь ее оптимизировать.
Если вы оптимизируете перед выполнением кода, скорее всего, вы делаете это преждевременно. Существует также большое изменение, что оптимизация, в которую вы вкладываете свое время, совершенно не нужна.
Конечно, есть некоторые очевидные оптимизации, которые вы должны всегда учитывать перед введением нового кода. Например, в Node.js крайне важно, чтобы вы не наводнили цикл событий или не блокировали стек вызовов. Это пример ранней оптимизации, которую вы всегда должны иметь в виду. Спросите себя: будет ли код, о котором я думаю, блокировать стек вызовов?
Любая неочевидная оптимизация, которая выполняется на любом существующем коде без измерений, считается вредной и ее следует избегать. То, что, по вашему мнению, может быть усилением производительности, если это возможно, может стать источником новых неожиданных ошибок.
Не тратьте время на то, чтобы оптимизировать неизмеримые проблемы с производительностью.
17) Не нацеливание на опыт конечного пользователя
Каков самый простой способ добавления функции в приложение? Посмотрите на это с точки зрения себя или как он вписывается в текущий пользовательский интерфейс. Правильно? Если функция предназначена для захвата какого-либо входа от пользователя, добавьте ее в ту форму, которую у вас уже есть. Если эта функция заключается в добавлении ссылки на страницу, добавьте ее в это вложенное меню ссылок, которые у вас уже есть.
Не будьте этим разработчиком. Будьте одним из профессионалов, которые ставят себя в обувь своих конечных пользователей. Они представляют себе, что нужно пользователям этой конкретной функции и как они могут себя вести. Они думают о том, как облегчить пользователям возможность находить и использовать эту функцию, а не простой способ сделать эту функцию в приложении каким-то образом без каких-либо мыслей об обнаружении и удобстве использования этой функции.
18) Не выбрал правильный инструмент для работы
У каждого есть свой список любимых инструментов, чтобы помочь им в их активациях, связанных с программированием. Некоторые инструменты велики, а некоторые - плохи, но большинство инструментов отлично подходят для одной конкретной вещи и не так хороши для многих других.
Молоток - отличный инструмент для приведения гвоздя в стену, но это худший инструмент для использования с винтом. Не используйте молоток на винте только потому, что вы «любите» этот молоток. Не используйте молоток на винте только потому, что это самый популярный молот на Amazon с 5.0 отзывов пользователей.
Опираясь на популярность инструмента, а не на то, насколько он соответствует этой проблеме, является признаком истинного новичка.
Одна проблема в этом вопросе заключается в том, что вы, вероятно, не знаете «лучших» инструментов для определенной работы. В ваших нынешних знаниях инструмент может быть лучшим инструментом, о котором вы знаете. Однако, по сравнению с другими вариантами, он не будет составлять верхний список. Вам необходимо ознакомиться с инструментами, доступными вам, и не забывать о новых инструментах, которые вы можете начать использовать.
Некоторые кодеры отказываются использовать новые инструменты. Они довольны своими существующими инструментами, и они, вероятно, не хотят изучать новые. Я понимаю это, и я могу относиться к нему, но это просто неправильно.
Вы можете построить дом с примитивными инструментами и взять свое сладкое время, или вы можете потратить некоторое время и деньги на хорошие инструменты и построить лучший дом намного быстрее. Инструменты постоянно совершенствуются, и вам нужно получить удобное знание о них и их использовании.
19) Не понимая, что проблемы с кодом вызовут проблемы с данными
Важным аспектом программы является управление некоторыми формами данных. Программа будет интерфейсом для добавления новых записей, удаления старых и изменения других.
Даже самые маленькие ошибки в коде программы приведут к непредсказуемому состоянию для данных, которыми он управляет. Это особенно верно, если все проверки данных выполняются полностью с помощью одной и той же багги.
Начинающие могут не сразу подключать точки, когда дело доходит до отношения кодовых данных. Они могут чувствовать себя хорошо, продолжая использовать какой-то багги-код в производстве, потому что функция X, которая не работает, не очень важна. Проблема в том, что кодовый код может постоянно вводить проблемы с целостностью данных, которые вначале не очевидны.
Хуже всего то, что код доставки, который исправлял ошибки, не устраняя тонкие проблемы с данными, вызванные этими ошибками, просто накапливает больше проблем с данными, которые относятся к метке «неустранимый уровень».
Как вы защищаете себя от таких проблем? Вы можете просто использовать несколько уровней проверки целостности данных. Не полагайтесь на один пользовательский интерфейс. Создавайте валидации на интерфейсах, интерфейсах, сетевых связях и базах данных. Если это не вариант, вы должны, как минимум, использовать ограничения на уровне базы данных.
Ознакомьтесь с ограничениями базы данных и используйте их все, когда вы добавляете столбцы и таблицы в свою базу данных:
- NOT NULL ограничение на колонке означает , что нулевые значения будут отклонены для этого столбца. Если ваше приложение предполагает существование значения для этого поля, его источник должен быть определен как null в вашей базе данных.
- UNIQUE ограничение на колонке означает , что столбец не может иметь одинаковые значения по всей таблице. Например, это отлично подходит для поля имени пользователя или электронной почты в таблице «Пользователи».
- ПРОВЕРКИ ограничение пользовательского выражение , которое должно вычисляться верно для данных , которые будут приняты. Например, если у вас есть нормальный процентный столбец, значения которого должны быть между 0 и 100, вы можете использовать контрольное ограничение для его принудительного применения.
- PRIMARY KEY ограничение означает , что значение столбца являются не-нуль и уникальным , а также. Вероятно, вы используете этот. Каждая таблица в базе данных должна иметь первичный ключ для идентификации своих записей.
- FOREIGN KEY ограничение означает , что значение столбца должны совпадать со значениями в другом столбце таблицы, которая обычно является первичным ключом.
Еще одна проблема новичков, связанная с целостностью данных, заключается в отсутствии мышления в отношении транзакций. Если для нескольких операций необходимо изменить один и тот же источник данных, и они зависят друг от друга, они должны быть завернуты в транзакцию, которая может быть отброшена, когда одна из этих операций завершится с ошибкой.
20) Переосмысление колеса
Это сложный момент. В программировании некоторые колеса просто стоит изобретать. Программирование не является четко определенной областью. Так много вещей так быстро меняется, и новые требования вводятся быстрее, чем любая команда может справиться.
Например, если вам нужно колесо, которое вращается с разной скоростью в зависимости от времени суток, вместо того, чтобы настраивать колесо, все мы знаем и любим, возможно, нам нужно переосмыслить его. Однако, если вам действительно не нужно колесо, которое не используется в его типичном дизайне, не изобретайте его повторно. Просто используйте проклятое колесо.
Не тратьте свое драгоценное время на исследование, которое является лучшим колесом. Просто сделайте быстрое исследование и используйте то, что найдете. Только заменяйте колеса, когда вы можете ясно видеть, что они не выполняют рекламу.
Самое интересное в программировании - то, что большинство колес свободны и открыты для вас, чтобы увидеть их внутренний дизайн. Вы можете легко судить колеса кодирования по их внутреннему качеству дизайна. Используйте колеса с открытым исходным кодом, если сможете. Пакеты с открытым исходным кодом можно легко отлаживать и исправлять. Их также можно легко заменить. Кроме того, им проще поддерживать их самостоятельно.
Однако, если вам нужно колесо, не покупайте совершенно новый автомобиль и не ставьте автомобиль, который вы поддерживаете на этом новом автомобиле. Не включайте целую библиотеку только для использования функции или двух из нее. Лучший пример - библиотека lodash в JavaScript. Если вам просто нужно перетасовать массив, просто импортируйте shuffleметод. Не импортируйте всю бесплатную библиотеку lodash.
21) Неправильное отношение к обзорам кодов
Одним из признаков кодирования новичков является то, что они часто рассматривают проверку кода как критику. Им они не нравятся. Они не ценят их. Они даже боятся их.
Это просто неправильно. Если вы так себя чувствуете, вам нужно сразу изменить это отношение. Посмотрите на каждый обзор кода как возможность обучения. Приглашайте их и оцените их. Учитесь у них. И самое главное, поблагодарите своих рецензентов, когда они вас чему-то учат.
Вы являетесь учеником навсегда. Вы должны это принять. Большинство обзоров кода научат вас тому, что вы не знали. Классифицируйте их как учебный ресурс.
Иногда рецензент ошибается, и ваша очередь будет учить их чему-то. Однако, если это что-то не было очевидным только из вашего кода, тогда, возможно, ваш код нуждается в модификации в этом случае. И если вам все равно нужно научить своего рецензента, просто знайте, что преподавание является одним из самых полезных действий, которые вы можете выполнять в качестве программиста.
22) Не использовать контроль источника
Новички иногда недооценивают силу хорошей системы контроля версий / ревизий, и, кстати, я имею в виду Git .
Исходный контроль - это не просто толкание ваших изменений, чтобы другие могли и дальше работать. Это намного больше. Контроль источника - это четкая история. Код будет поставлен под сомнение, и история прогресса этого кода поможет ответить на некоторые сложные вопросы. Вот почему мы заботимся о фиксации сообщений. Они являются еще одним каналом для передачи ваших реализаций и использования их с небольшими фиксациями, которые помогут будущим разработчикам вашего кода выяснить, как код достиг состояния, в котором он находится прямо сейчас.
Зачасть часто и совершать на ранней стадии, а для любви к последовательности использовать настоящие напряженные глаголы в строке темы фиксации. Расскажите о своих сообщениях, но имейте в виду, что они должны быть резюме. Если вам нужно больше нескольких строк, это, вероятно, признак того, что ваша фиксация слишком длинная. Rebase!
Не включайте ничего лишнего в сообщения о фиксации. Например, не перечислите файлы, которые были добавлены, изменены или удалены в сводках фиксации. Этот список существует в самом объекте commit и может быть легко отображен с помощью некоторых аргументов команды Git. Это просто шум в сводном сообщении. Некоторым командам нравится менять разные сводки на файл, и я вижу это как еще один признак слишком большого коммита.
Контроль источника также связан с возможностью обнаружения. Если вы сталкиваетесь с функцией, и вы начинаете расспрашивать о ее потребностях или дизайне, вы можете найти комманду, которая ее представила, и увидеть контекст этой функции. Commits может даже помочь вам определить, какой код ввел ошибку в программу. Git даже предлагает двоичный поиск внутри commits ( bisectкоманда), чтобы найти единственную виновную фиксацию, которая ввела ошибку.
Исходный контроль также можно использовать отличными способами еще до того, как изменения станут официальными. Использование таких функций, как изменение настроек, выборочное исправление, сброс, штамповка, изменение, применение, различие, реверсирование и многие другие, добавляют некоторые богатые инструменты для вашего потока кодирования. Поймите их, изучите их, используйте и оцените.
Чем меньше функций Git вы знаете, тем больше новичок вы в моей книге.
23) Переопределение общего состояния
Это, опять же, не будет вопросом о функциональном программировании и других парадигмах. Это тема для другой статьи.
Это связано с тем, что разделяемое государство является источником проблем, и его следует избегать, если это возможно. Если это невозможно, использование общего состояния должно быть сведено к абсолютному минимуму.
То, что я не понимал как программист-новичок, состоит в том, что каждая переменная, которую мы определяем, представляет собой общее состояние. Он содержит данные, которые могут быть изменены всеми элементами в той же области, что и эта переменная. Чем глобальнее объем, тем хуже диапазон этого общего состояния. Попытайтесь сохранить новые состояния, содержащиеся в небольших областях, и убедитесь, что они не просачиваются вверх.
Большая проблема с общим состоянием начинает происходить, когда несколько ресурсов должны изменять это состояние вместе в одном тике цикла события (в средах, основанных на циклах событий). Условия гонки будут происходить.
Вот что: у новичка может возникнуть соблазн использовать таймер в качестве обходного пути для этой проблемы состояния общего состояния штата, особенно если им приходится иметь дело с проблемой блокировки данных. Это большой красный флаг. Не делай этого. Следите за этим, укажите это в обзорах кода и никогда не принимайте его.
24) Неправильное отношение к ошибкам
Ошибки - это хорошо. Они означают, что вы добиваетесь прогресса. Они означают, что у вас есть легкое последующее изменение, чтобы добиться большего прогресса.
Экспертные программисты любят ошибки. Новички ненавидят их.
Если вы видите эти замечательные красные сообщения об ошибках, вам нужно изменить это отношение. Вам нужно посмотреть на них как на помощников. Вам нужно иметь дело с ними. Вы должны использовать их для достижения прогресса.
Некоторые ошибки необходимо обновить до исключения. Исключения - это определяемые пользователем ошибки, которые необходимо планировать. Некоторые ошибки необходимо оставить в покое. Им нужно свернуть приложение и заставить его выйти.
25) Не принимать перерывы
Вы человек, и ваш мозг нуждается в перерывах. Вашему организму нужны перерывы. Вы часто будете в зоне и забудьте взять перерывы. Я рассматриваю это как еще один признак новичков. Это не то, что вы можете скомпрометировать. Интегрируйте что-то в свой рабочий процесс, чтобы заставить вас делать перерывы. Возьмите много коротких перерывов. Оставьте свой стул и займите короткую прогулку и используйте его, чтобы подумать о том, что вам нужно сделать дальше. Вернитесь к коду со свежими глазами.
Это был длинный пост. Вы заслуживаете перерыва.
Спасибо за прочтение.