понедельник, 19 июля 2010 г.

[prog] Так почему отладка без отладчика – это хорошо?

Данная заметка является логическим итогом предшествующей серии “Пути к отладчику, с отладчиком и от отладчика” (первая, вторая, третья, четвертая и пятая части).

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

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

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

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

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

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

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

Иногда это оказывается совсем просто. Иногда нет. Зачастую не хватает нужно глянуть значения переменных, на основе которых программа принимает решения. Нужен ли для этого отладчик? С точно таким же успехом можно обойтись и отладочными печатями. Главный вопрос здесь не в том “как смотреть”, а в том “что смотреть”. Прежде, чем вставлять отладочную печать в код нужно подумать о том, что я смогу увидеть, нужно ли мне это, достаточно ли мне этого. Нужно подумать. А проблема отладчика (как проблема шпаргалки) в том, что он провоцирует не думать. Добавим переменную x в окно просмотра – не вопрос! Что-то x мало оказалось, давай еще и y – давай, какие проблемы! А может еще и z – давай, делов-то! А еще можно по живому поправить код и посмотреть, получилось что-нибудь или нет. Не получилось? Тогда можно еще раз поправить и посмотреть. А потом еще и еще. Хотя можно было просто подумать :)

Так что коротко резюмирую главную свою претензию к отладчикам – отладчики провоцируют неосознанный поиск проблем. Тогда как, например, отладочные печати – осознанный поиск.

Далее, есть очень большой класс задач, в которых от отладчика вообще пользы мало. Например: многопоточность, многопроцессовость и распределенность, реальное время, обработка больших объемов данных, куски кода на конечных автоматах (да еще генерируемых автоматически, как в случаях с lex/yacc), работа с внешним оборудованием, встраиваемое ПО. Поэтому хочешь, не хочешь, а научиться обходиться без отладчика придется.

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

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

Для C/C++ разработчиков так же важным инструментом будет средство для обнаружения утечек и расстрелов памяти. Вроде valgrind-а. Причем такой инструмент заменить самодельным велосипедом намного сложнее, чем профайлер.

А вот отладчик к числу таких обязательных инструментов все-таки не относится. Я использую отладчик для обнаружения мест возникновения Access Violations в программах. Если отладочными печатями обнаружить их не удается. В этом качестве отладчик бывает полезен. Но далеко не всегда, особенно в многопоточном C++ном коде после проезда по чужой памяти.

Ну и еще один приятный бонус для тех, кто может отлаживать свои программы без отладчика. Вам будет проще осваивать новые, перспективные языки, которые еще не успели обзавестись собственным отладчиком :) Т.е. вы сможете сделать свой вывод о том, что “D/Scala/F#/Groovy++ (не) взлетит” гораздо раньше, чем те, кто будет ждать готовой интеграции со студией или эклипсом :)

Отправить комментарий