Тратить слишком много времени на отладку

24

Вчера я выпустил веб-проект v1.0, над которым я потратил около 6 недель (то есть включен и выключен). Я не делал точных записей своего времени, но, исходя из своего опыта, я бы оценил, что из всего времени, которое я потратил на программирование, половина была потрачена на отладку. Я полагаю, что на отладку уйдет около 15-20 часов, что для меня драгоценное время, которое лучше было бы потратить на написание нового кода или на завершение проекта раньше. Также особенно не помогает то, что я буду новичком в колледже через 5 недель.

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

Как я могу предотвратить это в будущем? Я не хочу тратить 50% своего времени на отладку, я бы предпочел потратить 10% на отладку, а остальное на написание нового кода. Какие методы я могу попытаться помочь мне достичь этой цели?

Райан
источник
22
Когда я был новичком, я тоже был медленным программистом. Просто дайте ему 20 лет.
Работа
27
да, удачи в этом. «Если отладка - это процесс удаления ошибок. Тогда программирование должно быть процессом их исправления». -Edsger Dijkstra
Мэтт
7
Вы узнали что-нибудь из этих ошибок? Если вы это сделали, вы не сделаете их в следующий раз, и это сократит ваше время отладки.
Крейг Т
5
Это называется «опыт» и поможет вам в вашем следующем проекте.
4
Говоря о конце 1940-х годов, Морис Уилкс писал: «Как только мы начали программировать, мы обнаружили, к нашему удивлению, что не все так просто сделать программы правильно, как мы думали. Отладка должна была быть обнаружена. Во время моих путешествий между комнатой EDSAC и штамповочным оборудованием, которое «колебалось под углами лестницы», я понял, что со всей силой осознал, что значительная часть оставшейся части моей жизни будет потрачена на поиск ошибок в моих собственных программах ».
Тревор Пауэлл

Ответы:

35

Вы просите Святого Грааля разработки программного обеспечения, и пока никто не имеет «ответа» на этот вопрос.

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

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

Дефекты стадии проектирования

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

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

Ошибки кодирования

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

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

Если вы программируете на Perl, включите strictи warningsи внимайте , что он говорит.

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

Дефекты стадии интеграции

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

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

И так далее...

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

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

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

unpythonic
источник
1
Это отличный ответ, но ИМХО на чуть другой вопрос. ОП говорит, что я потратил 6 недель на то, чтобы что-то написать, и мне пришлось потратить много времени на отладку. Мы пока ничего не знаем, например, о качестве, ремонтопригодности, масштабируемости его продукта. Если мы предположим, что TDD, хороший дизайн, отслеживание ошибок, все еще остается вопрос о том, как написать код (включая тестовый код, который также должен быть отлажен) с меньшим количеством дефектов. Включение предупреждений, использование ворса и т. Д. Являются хорошими советами. Еще те из школы тяжелых ударов? :-)
Гай Сиртон,
1
@ Гай - Да ... Вопрос ОП был немного расплывчатым, поэтому я остановился на анализе первопричин. Вы не знаете, что случилось, пока не узнаете, что случилось. Причина, по которой я дал обзор проблемных областей, заключается в том, что я хотел, чтобы он знал о многих потенциальных подводных камнях, и что каждый этап процесса заслуживает отдельного рассмотрения. Насколько я знаю, он может быть следующим Тони Хоаром, но со способностью печатать слепого слона - разные исправления для разных причин.
unpythonic
37

Написать модульные тесты

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

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

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

Роберт Харви
источник
+1 для модульных тестов - чем раньше в процессе разработки обнаруживаются ошибки, тем дешевле и проще их исправить.
Пол Р
26

50% за отладку (в широком смысле) не так уж и плохо. Люди обычно тратят гораздо больше времени на разработку, тестирование, исправление ошибок, рефакторинг и написание модульных тестов, чем на написание реального кода. Это часть работы.

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

Есть несколько вещей, которые вы можете сделать, чтобы сократить время отладки:

  • Написать отлаживаемый код . Это означает: правильную обработку ошибок (с некоторой долей мысли), структурирование вашего кода, чтобы упростить отслеживание, использование утверждений, трассировок и всего, что может облегчить жизнь отладчику. Избегайте сложных линий; линия, которая делает больше чем одну вещь, должна быть разделена так, чтобы вы пошагово проходили их по отдельности.
  • Написать тестируемый код . Разделите ваш код на простые функции (или все, что поддерживает ваш язык); Избегайте побочных эффектов, так как их трудно уловить в модульных тестах. Разработайте свои функции так, чтобы они могли работать изолированно. Избегайте многоцелевых функций. Избегайте крайних случаев. Документируйте, что ваши функции должны делать.
  • Пишите тесты . Наличие модульных тестов означает, что вы знаете, что ваши функции работают, по крайней мере, на подмножестве их входных данных; это также означает, что у вас есть проверка работоспособности, чтобы убедиться, что ваши изменения ничего не нарушают. Убедитесь, что вы понимаете концепции покрытия кода и покрытия ввода, а также ограничения модульного тестирования.
  • Установите «верстак» . Как именно вы это делаете, зависит от языка. Некоторые языки, такие как Python или Haskell, поставляются с интерактивным интерпретатором, и вы можете загрузить в него существующий код, чтобы поиграть с ним. Это прекрасно, так как вы можете вызывать свои функции в любом удобном для вас контексте с минимальными усилиями - бесценный инструмент для поиска и локализации ошибок. На других языках такой роскоши нет, и вам придется прибегать к написанию небольших интерактивных тестовых программ.
  • Написать читабельный код . Сделайте привычкой писать свой код, чтобы выразить свои намерения настолько четко, насколько это возможно. Документируйте все, что не совсем очевидно.
  • Напишите простой код . Если ваш собственный мозг испытывает проблемы с пониманием всей кодовой базы, то это не просто, и очень маловероятно, что кто-то еще сможет полностью понять это. Вы не можете эффективно отлаживать код, если не понимаете, что он должен делать.
  • Будьте легко на кнопку «Удалить» . Любой код, который вам сейчас не нужен, находится в корзине. Если вам это понадобится позже, возродите его из системы контроля версий (опыт показывает, что это крайне редко). Чем больше кода вы утилизируете, тем меньше ваша поверхность отладки.
  • Рефакторинг рано и часто. Без рефакторинга вы не сможете поддерживать свой код в состоянии отладки при добавлении новых функций.
tdammers
источник
1
Также мир может вести себя иначе, чем вы ожидаете в случае проблем. Это может вызвать очень тонкие ошибки.
2
+1. Я бы сказал, что только 50% затрат на отладку довольно низки, особенно, но не только в установленной кодовой базе. Если мне приписывают ошибку, если только она не требует полного переписывания соответствующих частей кода (маловероятно), я мог бы потратить гораздо больше, чем эта доля общего времени, просто выясняя, что идет не так, а затем тестируя исправление. Само исправление часто быстрое, часто состоит из одной или нескольких строк измененного кода.
CVn
@ ThorbjørnRavnAndersen Черт, да, особенно с такими веб-проектами, как упоминается OP. Мы отлично
проводим
5

Больше планирования

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

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

Брайан Харрингтон
источник
1
+1, потому что это то, что я делаю, чтобы сократить время отладки. Когда я начинаю новый проект, я записываю все, что я собираюсь сделать в комментариях, затем возвращаюсь и заменяю комментарии кодом
CamelBlues
Я делаю то же самое с комментариями, тем более, чтобы я не забыл, где остановился. Но мне нравится рисовать диаграммы классов на бумаге и их зависимости. Это дает мне хорошее понимание того, что я думаю в то время.
Брайан Харрингтон
5

Работайте осторожнее

Это программный эквивалент выражения «Измерить дважды»:

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

Все это говорит о том, что ничто не собирается полностью устранять недостатки. Вы должны принять это как факт жизни. Учитывая этот факт план для дефектов, например, модульное тестирование. Также не принимайте это, чтобы означать «бери навсегда» (он же анализ-паралич). Речь идет о поиске баланса.

оборота Гай Сиртон
источник
4

Другие ответы уже охватили большую часть того, что я хочу сказать, но я все равно хочу высказать свое (жестоко честное) мнение в любом случае:

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

Очевидно, что различие между «обслуживанием» и «отладкой» немного субъективно. Считаете ли вы «ошибки» проблемами с кодом, который обнаруживается после его выпуска, и пользователи жалуются на них? Или это все мелочи, которые пошли не так с вашим кодом, когда вы что-то добавили (находились на ваших собственных этапах тестирования перед выпуском)? В нетривиальной программной системе (в зависимости от моделей использования) один может быть намного больше, чем другой. Но в любом случае, это то, что нужно для программирования чего-то большего, чем требуется игрушечной программе «Hello world» - много и много поддержки и отладки. Некоторые люди даже говорят что-то вроде « все, что после первой строки кода следует ожидать« режима обслуживания »,

TL; DR: Мне просто кажется, что у вас может быть немного нереалистичная картина того, что такое программирование нетривиальных программных систем. Подавляющее большинство усилий направлено на тонкую настройку, обслуживание, рефакторинг, исправление ошибок и в целом на выполнение работ, которые могут быть отнесены к «отладке» (обслуживанию) - по крайней мере, в самом общем смысле - в отличие от выполнения совершенно новой новой работы, написание свежего нового кода.

Бобби Столы
источник
2

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

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

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

НЕПРЕРЫВНАЯ ИНТЕГРАЦИЯ (CI) является ответом.

Непрерывная интеграция = система управления конфигурацией (а именно: Git, Mercurial, SVN и т. Д.) + Инструмент CI + модульные тесты + дымовые тесты

Эта формула должна побудить вас прочитать больше о непрерывной интеграции (CI). Ниже приведены некоторые ресурсы в этой области:

karthiks
источник
1

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

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

установка
источник
1

Разработка через тестирование может помочь сократить время отладки за счет:

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

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

Джейсон
источник
1

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

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

Кроме того, вы должны время от времени проводить рефакторинг своего кода. Я предлагаю вам прочитать книгу Мартина Фаулера « Рефакторинг: улучшение дизайна существующего кода»

ДРЕЗДЕН
источник
1

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

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

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

CPhelps
источник
0

Отличные ответы выше, но никто прямо не упомянул (хотя большинство намекало на это):

ЧИТАТЬ ЧИТАТЬ ЧИТАТЬ ЧИТАТЬ et в тошноте ...

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

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

Это был вопрос дизайнерского решения? Читайте о шаблонах проектирования.

Был ли это недостаток знания структуры или языка? Поддержите это!

так далее

Есть две вещи, которые (живой) разработчик никогда не сможет избежать: изменение (единственная константа в ИТ) и RTFMing ...

Мартин С. Столлер
источник
0

Модульные тесты и утверждения

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

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

dsimcha
источник
0

Когда вы начинаете проект, сколько альтернативных подходов вы определяете?

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

Тогда, самое главное, вы считаете простоту очень важной?

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

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

Майк Данлавей
источник
0

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

  • Запишите это в журнал регистрации дефектов , который включает в себя:

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

  • Интегрируйте правила безопасного кодирования в процесс проверки кода

  • Визуализируйте поток управления и данные

Ссылки

Пол Суатте
источник