ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: чтение этого не означает, что у вас больше никогда не будет ошибок. К сожалению.

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

Решение распространенных ошибок

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

Вот некоторые распространенные ошибки:

  • Опечатки: случайная орфографическая ошибка в имени переменной случается с каждым, обычно это очень легко найти, так как сообщение об ошибке должно указать вам на нее. Если у вас не много переменных с похожими именами, в этом случае вы можете рассмотреть некоторые другие имена переменных.
  • Неправильные имена / функции: вы копировали код из Stack Overflow? Если это так, убедитесь, что вы переименовали все переменные в то, что вам нужно. Это также касается функций. Также убедитесь, что вы знаете, что именно делает библиотечная функция (например, parseBoolean и getBoolean в Java делают разные вещи).
  • Строки: анализ строк / входных данных может легко привести к неожиданному поведению, убедитесь, что вы дважды проверили, что ваши строки / входные данные анализируются правильно.
  • Циклы и условные выражения: убедитесь, что вы закрываете свои циклы и условные выражения, и что они не выполняют нежелательный код.
  • = ›, =‹, =: Иногда этот может пробраться. При написании условий убедитесь, что вы выполняете if (var <= value), if (var >= value) или if (var == value), а не if (var =< value), if (var => value) или if (var = value), чтобы вы сравнивали две переменные, а не присваивали одну другую.
  • Одноразовые ошибки: дважды проверьте свои циклы, чтобы убедиться, что вы повторяете нужное количество раз. Например, for (int i = 0; i <= 10; i++) будет повторяться 11 раз, а не 10, тогда как for (int i = 0; i < 10; i++) будет повторяться 10 раз.
  • Необоснованные переменные: причина номер один NullPointers. Убедитесь, что вы создали экземпляры переменных (присвоили им значение), прежде чем начать их использовать.

  • Приращение до и после (i ++, ++ i): эти два параметра могут вызвать неожиданное поведение, если вы не будете осторожны, особенно если вы пытаетесь быть компактным и писать что-то вроде array [i ++] или работать с указателями. Это также относится к уменьшению.
  • Пограничные случаи: это чаще всего происходит в циклах или при использовании структур данных. Убедитесь, что вы знаете, что происходит в начале цикла или с первым элементом в вашей структуре данных (связанный список, я смотрю на вас), и то же самое касается последнего элемента.
  • SQL-запросы: если вы понятия не имеете, что не так, начните разбивать запрос на части, начните с выбора, откуда, а затем добавляйте данные, пока что-то не сломается или не появится неправильное, и выясните, почему.

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

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

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

  • Избегайте множества print ("get's to here 1"), print ("get's to here 2")print ("get's to here 100"). Если вы пишете оператор печати, чтобы сделать его полезным, попробуйте распечатать значения некоторых важных переменных.
  • Сделайте его описательным, особенно если вы печатаете значения переменных. Этот print ("myFunction() key = " + key) лучше, чем print (key), потому что вы знаете, в какой функции вы работаете и какую переменную печатаете.
  • Убирайте за собой, удаляйте операторы печати после завершения отладки, за исключением тех, которые могут быть полезны для последующей отладки. Когда вы заканчиваете код, охотиться за неуместными операторами печати - никогда не бывает весело.
  • Печатайте в stderr вместо stdin, если можете.

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

Избегание

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

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

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

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

(Также, если вы компилируете код, обязательно перекомпилируйте его перед повторным запуском…)

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

Вы также можете связаться со мной в Twitter: