Читаем Кодеры за работой. Размышления о ремесле программиста полностью

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

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

Вот один из самых интересных случаев в моей практике. Меня попросили написать отзыв на статью Дэвида Гриса для «САСМ». Грис писал о доказательстве правильности параллельного алгоритма сборки мусора. Сьюзен Овицки была студенткой Гриса и разработала кое-какие инструменты для доказательства корректности параллельных программ. А Грис решил применить их к параллельному сборщику мусора, разработанному Дейкстрой. Код занимал где-то полстраницы. А остальная часть статьи содержала доказательство его корректности.

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

Сейбел: Итак, алгоритм содержал ошибки, и доказательство их пропустило.

Стил: Да, получилось, что доказательство некорректно. Что-то где-то было упущено. Какие-то детали работы с формулой — формула была почти правильна, но именно «почти». Дело было лишь в том, чтобы поменять местами, например, две строки кода.

Сейбел: Итак, 25 часов ушло на то, чтобы проанализировать доказательство. Вы бы смогли найти ошибку в коде за 25 часов, имея перед собой только код и больше ничего?

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

Сейбел: И все выявилось в процессе доказательства, то есть вам не надо было рассматривать различные сценарии типа «что, если» для обнаружения проблемы.

Стил: Верно. Доказательства позволяют представить глобальную точку зрения и предусмотреть все возможности, резюмируя их при помощи очень сложной формулы. И чтобы это получить, приходится проработать кучу формул. Автор переработал статью, она снова вернулась ко мне на рецензию — и хотя я уже проделал это упражнение, пришлось опять потратить 25 часов на проверку доказательства. На этот раз, кажется, все было нормально.

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

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

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

Сейбел: И программа автоматической проверки, проверенная вручную, может сэкономить 25 часов, потраченные вами на изучение доказательства фрагмента кода?

Стил: Да. Точно.

Сейбел: О чем еще вы бы хотели поговорить?

Стил: Мы не коснулись такой темы, как красота программ. А мне хочется сказать об этом пару слов. Некоторые программы буквально поражали меня своей красотой. Например, ТеХ, то есть исходный код ТеХ. METAFONT — в меньшей степени, но не знаю, почему: то ли потому, что я работал с ним меньше, то ли потому, что мне и вправду меньше нравятся структура кода и архитектура программы.

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

Перейти на страницу:

Похожие книги

Адмирал Советского Союза
Адмирал Советского Союза

Николай Герасимович Кузнецов – адмирал Флота Советского Союза, один из тех, кому мы обязаны победой в Великой Отечественной войне. В 1939 г., по личному указанию Сталина, 34-летний Кузнецов был назначен народным комиссаром ВМФ СССР. Во время войны он входил в Ставку Верховного Главнокомандования, оперативно и энергично руководил флотом. За свои выдающиеся заслуги Н.Г. Кузнецов получил высшее воинское звание на флоте и стал Героем Советского Союза.В своей книге Н.Г. Кузнецов рассказывает о своем боевом пути начиная от Гражданской войны в Испании до окончательного разгрома гитлеровской Германии и поражения милитаристской Японии. Оборона Ханко, Либавы, Таллина, Одессы, Севастополя, Москвы, Ленинграда, Сталинграда, крупнейшие операции флотов на Севере, Балтике и Черном море – все это есть в книге легендарного советского адмирала. Кроме того, он вспоминает о своих встречах с высшими государственными, партийными и военными руководителями СССР, рассказывает о методах и стиле работы И.В. Сталина, Г.К. Жукова и многих других известных деятелей своего времени.Воспоминания впервые выходят в полном виде, ранее они никогда не издавались под одной обложкой.

Николай Герасимович Кузнецов

Биографии и Мемуары
100 великих гениев
100 великих гениев

Существует много определений гениальности. Например, Ньютон полагал, что гениальность – это терпение мысли, сосредоточенной в известном направлении. Гёте считал, что отличительная черта гениальности – умение духа распознать, что ему на пользу. Кант говорил, что гениальность – это талант изобретения того, чему нельзя научиться. То есть гению дано открыть нечто неведомое. Автор книги Р.К. Баландин попытался дать свое определение гениальности и составить свой рассказ о наиболее прославленных гениях человечества.Принцип классификации в книге простой – персоналии располагаются по роду занятий (особо выделены универсальные гении). Автор рассматривает достижения великих созидателей, прежде всего, в сфере религии, философии, искусства, литературы и науки, то есть в тех областях духа, где наиболее полно проявились их творческие способности. Раздел «Неведомый гений» призван показать, как много замечательных творцов остаются безымянными и как мало нам известно о них.

Рудольф Константинович Баландин

Биографии и Мемуары
100 великих интриг
100 великих интриг

Нередко политические интриги становятся главными двигателями истории. Заговоры, покушения, провокации, аресты, казни, бунты и военные перевороты – все эти события могут составлять только часть одной, хитро спланированной, интриги, начинавшейся с короткой записки, вовремя произнесенной фразы или многозначительного молчания во время важной беседы царствующих особ и закончившейся грандиозным сломом целой эпохи.Суд над Сократом, заговор Катилины, Цезарь и Клеопатра, интриги Мессалины, мрачная слава Старца Горы, заговор Пацци, Варфоломеевская ночь, убийство Валленштейна, таинственная смерть Людвига Баварского, загадки Нюрнбергского процесса… Об этом и многом другом рассказывает очередная книга серии.

Виктор Николаевич Еремин

Биографии и Мемуары / История / Энциклопедии / Образование и наука / Словари и Энциклопедии