Главная страница
Навигация по странице:

  • Различия в эффективности отладки

  • ЧАСТЬ V

  • Дефекты как возможности обучения

  • Перекрестная ссылка

  • Изучить программу, над которой работаете

  • Изучить собственные ошибки

  • Изучить качество своего кода с точки зрения когото, кому придется чи

  • Изучить используемые способы решения проблем

  • Изучить используемые способы исправления дефектов

  • Руководство Дьявола по отладке

  • Поиск дефектов, основанный на гадании

  • Тщательный анализ проблемы — пустая трата времени

  • Исправление ошибок самым очевидным образом

  • Совершенный код. Совершенный код. Мастер-класс. Стив Макконнелл. Руководство по стилю программирования и конструированию по


    Скачать 5.88 Mb.
    НазваниеРуководство по стилю программирования и конструированию по
    АнкорСовершенный код
    Дата31.03.2023
    Размер5.88 Mb.
    Формат файлаpdf
    Имя файлаСовершенный код. Мастер-класс. Стив Макконнелл.pdf
    ТипРуководство
    #1028502
    страница66 из 106
    1   ...   62   63   64   65   66   67   68   69   ...   106
    ГЛАВА 23 Отладка
    525
    терные проблемы стали сваливать на насекомых. Вне программирования слово
    «bug» уходит корнями по крайней мере во времена Томаса Эдисона, который ис#
    пользовал его уже в 1878 году (Tenner, 1997).
    Забавное слово «bug» вызывает в воображении подобные образы:
    Однако на самом деле программные дефекты — не организмы, проникающие в код, если его забыли обработать пестицидами. Это ошибки, допущенные програм#
    мистами, а результаты ошибок обычно больше похожи не на предыдущий рису#
    нок, а на подобную записку:
    Отладка и качество ПО
    Как и тестирование, сама по себе отладка не служит для повышения качества ПО
    — это способ диагностики дефектов. О качестве нужно заботиться с самого нача#
    ла работы над программой. Лучший способ создания качественной программы заключается в тщательной выработке требований, грамотном проектировании и применении высококачественных методик кодирования. Отладка — это средство для крайних случаев
    Различия в эффективности отладки
    Зачем вообще обсуждать отладку? Разве не все программисты умеют отлаживать программы?
    Увы, не все. Исследования показали, что опытным программистам для на#
    хождения тех же ошибок требовалось примерно в 20 раз меньше време#
    ни, чем неопытным. Более того, некоторые программисты находят больше дефектов и исправляют их грамотнее. Вот результаты классического исследова#
    ния, в котором профессиональных программистов, обладающих минимум 4#лет#
    ним опытом, попросили отладить программу с 12 дефектами:

    526
    ЧАСТЬ V Усовершенствование кода
    Три самых
    Три самых
    быстрых
    медленных
    программиста
    программиста
    Среднее время отладки (в минутах)
    5,0 14,1
    Среднее число необнаруженных дефектов 0,7 1,7
    Среднее число новых дефектов,
    3,0 7,7
    внесенных в код при исправлении имеющихся дефектов
    Источник: «Some Psychological Evidence on How People Debug Computer
    Programs» (Gould, 1975)
    Три самых лучших в отладке программиста смогли найти дефекты при#
    мерно в 3 раза быстрее и внесли в код примерно в 2,5 раза меньше де#
    фектов, чем три худших. Самый лучший программист обнаружил все дефекты и не внес во время их исправления новых. Самый худший не нашел 4 из
    12 дефектов, а при исправлении 8 обнаруженных дефектов внес в код 11 новых.
    Но ставить точку рано. После первого раунда отладки в коде самых быстрых про#
    граммистов все еще остались 3,7 дефекта, а в коде самых медленных — 9,4 дефек#
    та. Ни одна из групп не довела отладку до конца. У меня возник вопрос, что слу#
    чится, если экстраполировать данные этого исследования на дополнительные циклы отладки. Мои результаты не являются статистически надежными, но они все же интересны. Применив те же показатели обнаружения и некорректного исправления дефектов к дополнительным циклам, я выяснил, что для снижения показателя необнаруженных дефектов до уровня 0,5 дефекта самой быстрой группе понадобились бы в общей сложности 3 цикла отладки, а самой медленной — 14.
    Если далее учесть, что время выполнения одного цикла отладки этими группами различается почти в 3 раза, мы получим, что самой медленной группе для пол#
    ной отладки своих программ потребовалось бы в 13 раз больше времени, чем самой быстрой. Аналогичные крупные различия в эффективности отладки показали и другие исследования (Gilb, 1977; Curtis, 1981).
    Эти данные не только сообщают нам кое#что об отладке, но и подтверждают Главный Закон Контроля Качества ПО: по#
    вышение качества программы снижает затраты на ее разра#
    ботку. Лучшие программисты обнаружили больше дефектов за меньшее время и исправили их более корректно. Нет нужды выбирать между качеством, стоимостью и быстротой — они идут рука об руку.
    Дефекты как возможности обучения
    О чем говорит наличие дефекта? Ну, если исходить из того, что наличие дефек#
    тов в программе нежелательно, это говорит о том, что вы не полностью понима#
    ете программу. Это тревожит. Все#таки, если вы написали программу, она должна делать то, что вам нужно. Если вы не до конца понимаете свои указания компиля#
    тору, еще чуть#чуть, и вы просто начнете пробовать все, что придет в голову, пока что#то не сработает, т. е. начнете программировать методом проб и ошибок. А раз так, дефекты неизбежны. Вам не нужно учиться исправлять дефекты — вам нуж#
    но знать, как их избегать.
    Перекрестная ссылка О связи между качеством ПО и стоимо- стью его разработки см. раздел
    20.5.

    ГЛАВА 23 Отладка
    527
    Однако люди несовершенны, и даже прекрасные программисты иногда допуска#
    ют промахи. В таких случаях ошибки предоставляют отличные возможности уз#
    нать много нового. Например, вы можете сделать все, что описано ниже.
    Изучить программу, над которой работаете Наличие дефекта указывает на то, что вы должны лучше изучить программу, потому что, если б вы уже отлич#
    но ее знали, в ней не было бы дефектов. Вы уже исправили бы их.
    Изучить собственные ошибки Все дефекты вашей про#
    граммы лежат на вашей совести. Не каждый день у вас по#
    является такая прекрасная возможность лучше узнать соб#
    ственные недостатки, и грех ее не использовать. Обнаружив ошибку, спросите себя, как и почему вы допустили ее. Как вы могли найти ее быстрее? Как ее можно было предотвра#
    тить? Содержит ли код другие подобные ошибки? Можно ли исправить их до того, как они приведут к проблемам?
    Изучить качество своего кода с точки зрения кого'то, кому придется чи'
    тать его Чтобы найти дефект, вы должны прочитать свой код. Это дает вам пре#
    красную возможность критически оценить его качество. Легко ли его читать? Как его можно улучшить? Используйте полученные знания для рефакторинга имею#
    щегося кода или для улучшения кода, который вы будете писать позднее.
    Изучить используемые способы решения проблем Чувствуете ли вы уверен#
    ность, обдумывая свой подход к отладке? Работает ли он? Быстро ли вы находите дефекты? Может, ваш подход к отладке неэффективен? Чувствуете ли вы тоску и огорчение? Не отлаживаете ли вы программу, опираясь на случайные предположе#
    ния? Нужно ли как#то улучшить процесс отладки? Если учесть объем времени, ухо#
    дящего на отладку во многих проектах, анализ вашего способа отладки определенно не будет пустой тратой времени. Трата некоторого времени на анализ и измене#
    ние процесса отладки может оказаться самым эффективным способом сокращения общего времени разработки программы.
    Изучить используемые способы исправления дефектов Кроме способа по#
    иска дефектов, вы можете изучить и свой способ их исправления. Вносите ли вы максимально простые исправления, используя операторы
    goto и частные случаи,
    устраняющие симптомы, но не проблему? Или вы вносите системные исправле#
    ния, точно определяя и устраняя причины проблем?
    Вышесказанное позволяет сделать вывод, что отладка обеспечивает программис#
    там крайне благоприятные возможности для самосовершенствования. Именно отладка является перекрестком всех дорог конструирования: удобочитаемости,
    качества проекта и кода и т. д. Именно на этапе отладки окупается создание хо#
    рошего кода, особенно если его качество редко заставляет прибегать к отладке.
    Неэффективный подход
    К сожалению, в вузах почти никогда не рассматриваются принципы отладки.
    Возможно, вы прослушали пару специальных лекций, но скорее всего на этом все и кончилось. Я никак не могу пожаловаться на качество полученного образова#
    ния, но и в моем случае рассмотрение отладки ограничилось советом «для нахож#
    дения дефектов включайте в код команды печати». Это неадекватный уровень. Если
    Дополнительные сведения Ме- тодики, помогающие узнать, ка- кие ошибки чаще всего допус- каете лично вы, рассматриваются в книге «A Discipline for Software
    Engineering» (Humphrey, 1995).

    528
    ЧАСТЬ V Усовершенствование кода образовательный опыт других программистов похож на мой, им приходится изоб#
    ретать концепции отладки заново. Какая трата времени и сил!
    Руководство Дьявола по отладке
    В свое время Данте отвел нижний круг ада самому Сатане.
    Но с тех пор кое#что изменилось, и сейчас Сатана охотно делит нижний круг с программистами, не умеющими эффек#
    тивно отлаживать программы. Он мучает программистов, за#
    ставляя их отлаживать программы с использованием попу#
    лярных принципов из следующего списка.
    Поиск дефектов, основанный на гадании Для нахож#
    дения дефекта разбросайте по программе случайным обра#
    зом команды печати и изучите выходные данные. Если при помощи команд пе#
    чати найти дефект не получается, попробуйте изменить тот или иной фрагмент
    — может, что и сработает. Не сохраняйте первоначальный вариант программы и не регистрируйте внесенные изменения. Если вы точно не знаете, что делает про#
    грамма, программирование становится более увлекательным. Запаситесь колой и леденцами, потому что вам придется провести перед монитором всю ночь.
    Тщательный анализ проблемы — пустая трата времени Скорее всего про#
    блема тривиальна, и ее не нужно полностью понимать, чтобы исправить. Доста#
    точно ее просто найти.
    Исправление ошибок самым очевидным образом Обычно можно просто устранить специфические симптомы проблемы, а не тратить время на внесение крупного амбициозного исправления, которое может затронуть всю программу.
    Вот прекрасный пример:
    x = Compute( y )
    if ( y = 17 )
    x = $25.15 — если y = 17, метод Compute() не работает; мы это исправляем
    Зачем анализировать метод
    Compute() в поисках причин непонятной проблемы со значением
    17, если можно просто написать частный случай в очевидном месте?
    Суеверная отладка
    Сатана выделил часть ада программистам, которые отлаживают программы, опи#
    раясь на суеверия. В каждой группе есть хоть один программист, бесконечно сра#
    жающийся с демоническими компьютерами, таинственными дефектами компи#
    лятора, скрытыми дефектами языка, которые проявляются только в полнолуние,
    плохими данными, утратой важных изменений, заколдованным текстовым редак#
    тором, который неправильно сохраняет программы… дополните этот список сами.
    Это и есть «суеверное программирование».
    Если написанная вами программа не работает, ошибка лежит на вашей совести.
    Компьютер и компилятор ни в чем не виноваты. Программа не делает каждый раз что#то иное. Она не писала сама себя — ее написали вы, так что не уходите от ответственности.
    Программисты не всегда ис- пользуют доступные данные для ограничения своих рассужде- ний. Они вносят в код неболь- шие и иррациональные исправ- ления и часто не отменяют не-
    корректные исправления.
    Айрис Весси (Iris Vessey)

    ГЛАВА 23 Отладка
    529
    Даже если ошибка поначалу кажется не вашей, в ваших интересах пола#
    гать, что справедливо обратное. Это предположение помогает в отладке.
    Ожидаемый дефект обнаружить в коде трудно; если вы полагаете, что ошибок в вашем коде нет, найти их еще труднее. Допуская вероятность того, что ошибка является вашей, вы будете вызывать большее доверие. Если вы утвержда#
    ете, что ошибся кто#то другой, ваши коллеги подумают, что вы тщательно прове#
    рили свой код. Предполагая, что виновником проблемы являетесь вы сами, вы сможете избежать неловких ситуаций, связанных с публичным признанием вины,
    которую вы первоначально отвергали.
    23.2. Поиск дефекта
    Отладка включает поиск дефекта и его исправление. Поиск дефекта и его пони#
    мание обычно составляют 90% работы.
    К счастью, существуют более эффективный подход к отладке, чем гадание, и, чтобы его применить, совсем не нужно заключать договор с Дьяволом. Отладка програм#
    мы, основанная на размышлении о проблеме, гораздо эффективнее и интереснее,
    чем отладка с использованием глаз тритона и помета летучей мыши.
    Допустим, вам нужно раскрыть тайну убийства. Что оказалось бы интереснее:
    обойти дома всех жителей района, проверяя их алиби, или найти несколько улик и, опираясь на них, установить убийцу? Большинство людей предпочло бы вто#
    рой вариант, поэтому вполне логично, что и у программистов большей популяр#
    ностью пользуется интеллектуальный подход к отладке. Лучшие программисты,
    отлаживающие программы в двадцать раз быстрее, чем их менее квалифициро#
    ванные коллеги, не гадают, как исправить дефекты. Они используют научный метод
    — основательный процесс анализа и доказательства.
    Научный метод отладки
    Классический научный метод включает следующие этапы.
    1. Сбор данных при помощи повторяющихся экспериментов.
    2. Формулирование гипотезы, объясняющей релевантные данные.
    3. Разработка эксперимента, призванного подтвердить или опровергнуть гипотезу.
    4. Подтверждение или опровержение гипотезы.
    5. Повторение процесса в случае надобности.
    Научный метод имеет много аналогов, используемых при отладке. Ниже описан эффективный метод поиска дефекта.
    1. Стабилизация ошибки.
    2. Определение источника ошибки.
    a. Сбор данных, приводящих к дефекту.
    b. Анализ собранных данных и формулирование гипотезы, объясняющей дефект.
    c. Определение способа подтверждения или опровержения гипотезы, осно#
    ванного или на тестировании программы, или на изучении кода.

    530
    ЧАСТЬ V Усовершенствование кода d. Подтверждение или опровержение гипотезы при помощи процедуры,
    определенной в п. 2(c).
    3. Исправление дефекта.
    4. Тестирование исправления.
    5. Поиск похожих ошибок.
    Первый этап этого процесса аналогичен первому этапу научного метода в том смысле, что оба они основаны на повторяемости. Диагностика дефекта облегча#
    ется, если его стабилизировать, т. е. обеспечить его надежное возникновение.
    Второй этап основан на этапах научного метода. Вы собираете тестовые данные,
    приводящие к проявлению дефекта, анализируете эти данные и формулируете гипотезу об источнике ошибки. Затем вы проектируете тест или инспекцию и оцениваете гипотезу, после чего празднуете успех (если гипотеза подтверждает#
    ся) или начинаете поиск источника ошибки сначала. Подтвердив гипотезу, вы исправляете дефект, тестируете исправление и ищете в коде похожие ошибки.
    Рассмотрим все эти этапы на примере. Допустим, вы столкнулись с несистемати#
    ческой ошибкой в программе, которая работает с базой данных о сотрудниках.
    Программа должна печатать список сотрудников в алфавитном порядке и суммы подоходного налога, вычитаемые из зарплаты каждого сотрудника, но при запус#
    ке программы выводится:
    Formatting, Fred Freeform $5,877
    Global, Gary $1,666
    Modula, Mildred $10,788
    ManyLoop, Mavis $8,889
    Statement, Sue Switch $4,000
    Whileloop, Wendy $7,860
    Как видите, список содержит ошибку: записи сотрудников
    Many%Loop, Mavis и
    Modula, Mildred выведены в неверном порядке.
    Стабилизация ошибки
    Если дефект проявляется не всегда, его почти невозможно диагностировать. Пе#
    ревод несистематического дефекта в разряд предсказуемых — один из самых слож#
    ных аспектов отладки.
    Непредсказуемые ошибки обычно связаны с инициализаци#
    ей, расчетом времени или зависшими указателями. Если сумма иногда вычисляется правильно, а иногда неправиль#
    но, это, вероятно, объясняется тем, что одна из переменных не инициализируется и просто получает в большинстве случаев нулевое значе#
    ние. Если вы столкнулись со странной непредсказуемой проблемой при работе с указателями, почти наверняка ее причина — неинициализированный указатель или использование указателя после освобождения соответствующей ему области памяти.
    Стабилизация ошибки обычно не ограничивается нахождением теста, приводя#
    щего к ошибке. Она предполагает упрощение теста до тех пор, пока не будет по#
    лучен самый простой тест, все еще приводящий к ошибке. Иначе говоря, тест следует сделать таким простым, чтобы изменение любого его аспекта изменяло
    Перекрестная ссылка О безо- пасном использовании указате- лей см. раздел 13.2.

    ГЛАВА 23 Отладка
    531
    поведение ошибки. Затем, тщательно изменяя тест и наблюдая за поведением программы в контролируемых условиях, вы можете диагностировать проблему.
    Если в вашей организации есть независимая группа тестирования, упрощение тестов иногда можно поручить ей, но в большинстве случаев это ваша работа.
    Для упрощения теста также следует использовать научный метод. Допустим, вы определили 10 факторов, комбинация которых приводит к ошибке. Сформулируйте гипотезу о том, какие факторы нерелевантны для возникновения ошибки. Измените эти факторы и выполните тест еще раз. Если ошибка никуда не исчезает, вы може#
    те упростить тест, исключив эти факторы. Затем вы можете попробовать сделать тест еще проще. Если ошибка больше не возникает, значит, вы опровергли кон#
    кретную гипотезу и получили дополнительные сведения о проблеме. Возможно,
    другие изменения все еще будут приводить к ошибке, но теперь вы хотя бы знаете одно конкретное изменение, после внесения которого ошибка исчезает.
    В нашем случае при первом запуске программы запись
    Many%Loop, Mavis выводится в списке после
    Modula, Mildred. Однако при втором запуске записи выводятся в правильном порядке:
    Formatting, Fred Freeform $5,877
    Global, Gary $1,666
    ManyLoop, Mavis $8,889
    Modula, Mildred $10,788
    Statement, Sue Switch $4,000
    Whileloop, Wendy $7,860
    После ввода записи
    Fruit%Loop, Frita, которая появляется в неверной позиции, вы вспоминаете, что запись
    Modula, Mildred также была введена непосредственно перед отображением некорректного списка. Что необычно в этих случаях, так это то,
    что записи были введены по отдельности. Как правило, данные вводятся сразу для нескольких сотрудников.
    Итак, можно предположить, что проблема как#то связана с вводом одной новой записи. Если это так, то при следующем запуске программы запись
    Fruit%Loop, Frita
    должна занять правильное место. Ну#ка, проверим:
    Formatting, Fred Freeform $5,877
    FruitLoop, Frita $5,771
    Global, Gary $1,666
    ManyLoop, Mavis $8,889
    Modula, Mildred $10,788
    Statement, Sue Switch $4,000
    Whileloop, Wendy $7,860
    Правильная сортировка списка соответствует выдвинутой гипотезе. И все же для ее окончательного подтверждения следует добавить несколько новых записей по одной за раз и посмотреть, выводятся ли они в неверном порядке при первом запуске программы и изменяется ли их порядок при втором.

    532
    ЧАСТЬ V Усовершенствование кода
    Определение источника ошибки
    Определение источника ошибки также призывает к использованию научного метода. Так, вы могли бы заподозрить, что дефект является результатом конкрет#
    ной проблемы, такой как ошибка занижения или завышения на 1. Для проверки этой гипотезы вы могли бы присвоить параметру, который предположительно вызывает проблему, значение, равное граничному условию, а также два значения,
    отличающихся от граничного условия на 1.
    В нашем примере причиной проблемы может быть занижение или завышение на
    1 при добавлении одной новой записи, но не двух или более. Однако изучение кода не приводит к нахождению очевидной ошибки занижения или завышения на 1. Тогда вы обращаетесь к плану Б и добавляете в БД одну новую запись, чтобы увидеть, вызовет ли это проблему. Вы добавляете запись
    Hardcase, Henry и пред#
    полагаете, что она займет неправильное место. При запуске программы выводит#
    ся:
    Formatting, Fred Freeform $5,877
    FruitLoop, Frita $5,771
    Global, Gary $1,666
    Hardcase, Henry $493
    ManyLoop, Mavis $8,889
    Modula, Mildred $10,788
    Statement, Sue Switch $4,000
    Whileloop, Wendy $7,860
    Список отсортирован правильно, а значит, первая гипотеза ошибочна. Добавле#
    ние одного нового сотрудника не является причиной проблемы. Проблема имеет или более сложную, или совсем другую природу.
    При более внимательном изучении выходных данных теста можно заметить, что только записи
    Fruit%Loop, Frita и Many%Loop, Mavis включают дефисы. Сразу же после ввода запись
    Fruit%Loop занимала неверное положение, но с записью Many%Loop
    все было в порядке, ведь так? Хотя распечатки результатов самого первого запус#
    ка программы у вас нет, вы помните, что вас смутило место записи
    Modula, Mildred,
    но она располагалась по соседству с
    Many%Loop. Возможно, ошибочным было положение записи
    Many%Loop, а не Modula.
    Вы выдвигаете новую гипотезу: причина проблемы связана с фамилиями, содер#
    жащими дефисы, а не с фамилиями, которые вводятся по одной.
    Но как это объясняет тот факт, что проблема возникает только при вводе записи?
    Вы изучаете код и замечаете, что в программе используются два разных метода сортировки: один вызывается при вводе записи, а второй — при ее сохранении.
    Более тщательный анализ первого метода показывает, что он и не должен сорти#
    ровать список полностью. Вставляя новую запись, он лишь приблизительно определяет ее положение для ускорения сортировки, которую выполняет второй метод. Так что проблема в том, что данные печатаются до их сортировки. Фами#
    лии, содержащие дефисы, располагаются в неправильном порядке из#за того, что метод примерной сортировки не обрабатывает подобные тонкости. Теперь вы можете выдвинуть еще более точную гипотезу: фамилии, содержащие знаки пун#
    ктуации, правильно сортируются только во время сохранения.

    1   ...   62   63   64   65   66   67   68   69   ...   106


    написать администратору сайта