Питер Сейбел - Кодеры за работой. Размышления о ремесле программиста
- Название:Кодеры за работой. Размышления о ремесле программиста
- Автор:
- Жанр:
- Издательство:Символ-Плюс
- Год:2011
- Город:Санкт-Петербург
- ISBN:978-5-93286-188-2
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Питер Сейбел - Кодеры за работой. Размышления о ремесле программиста краткое содержание
Программисты - люди не очень публичные, многие работают поодиночке или в небольших группах. Причем самая важная и интересная часть их работы никому не видна, потому что происходит у них в голове. Питер Сейбел, писатель-программист, снимает покров таинственности с этой профессии. Он взял интервью у 15 величайших профессионалов: Кена Томпсона, создателя UNIX, Верни Козелла, участника первой реализации сети ARPANET, Дональда Кнута, Гая Стила, Саймона Пейтон-Джонса, Питера Норвига, Джошуа Блоха, Брэда Фицпатрика, создателя Живого Журнала, и других. Все они “подсели” на программирование еще в школе. Тогда, на заре зарождения отрасли, лишь в немногих учебных заведениях читались курсы по компьютерным наукам. Поэтому будущим гуру приходилось покорять профессиональные вершины самостоятельно, но всех их отличает творческое горение и полная самоотдача любимому делу.
Вы узнаете, что они думают о будущем программирования и как сами научились программировать, как, по их мнению, нужно проектировать ПО, как выбор языка программирования влияет на продуктивность и можно ли облегчить выявление труднонаходимых ошибок.
Кодеры за работой. Размышления о ремесле программиста - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Например, сохраняем, а потом прогоняем тест занятости. А в некоторых участках теста занятости отсылался физический адрес вместо виртуального, и часть памяти в итоге затиралась числителем того, на что мы пытаемся поделить. А обнаруживалось это далеко не сразу, причем в самых разных местах. Безусловно, это самая сложная ошибка, которую мне пришлось искать.
Сейбел:Как же в итоге удалось ее отследить?
Томпсон:Я написал программу, которая должна была поставить мировой рекорд по нахождению знаков числа е. Предыдущие мировые рекорды были ограничены не вычислениями - количеством циклов в секунду, - а вводом/выводом. Я придумал новый алгоритм, узким местом которого были вычисления (ввод/вывод был тривиальным). Он был феерически тяжелым в отношении умножения и деления. И мы заметили, что машина каждый раз буквально обрушивалась, когда я запускал на ней эту свою программу. А потом и установили связь.
Сейбел:И это дало вам возможность понять, что проблема в умножителе. Вы сразу же нашли причину?
Томпсон:Сначала мы решили, что ошибка возникает, когда сохраняешь множитель в блоке умножения, потом обращаешься за ним, а его там нет. Мы обратились в компанию DEC, там ничего не нашли и не захотели связываться. Их слишком нормальным сотрудникам не хотелось иметь дело с гибридной машиной. В те дни у нас были принципиальные схемы машин, и мы, собственно, нашли ошибку по этой схеме. Потом мы позвонили в DEC и сказали им: “Соедините вот этот и вон тот проводки”.
Сейбел:К счастью, сейчас оборудование так не сыплется.
Томпсон:Да. Думаю, такие ошибки сейчас редки. К тому же сейчас компоненты гораздо более изолированы друг от друга: ошибку можно сделать, только если совсем уж безумствовать. Просто ошибиться на ассемблере: очень несложно что-то перепутать в каком-нибудь регистре при вызове подпрограммы. Но если вы имеете дело с высокоуровневым языком, где все аргументы должны подходить, такие ошибки становятся все более и более редкими.
Раньше в языках ассемблера их было множество. Если речь шла только о программах, а не о комбинации программ и оборудования, обычно они случались в одном месте и повреждалось только это место. Ошибка была с чем-то связана. Нужно было сидеть и мониторить операционную систему. И часто - или очень часто - мы видели, что случалась ошибка, как можно быстрее останавливали процесс и смотрели, что происходит в других местах, таким образом отслеживая ошибки. Их можно было так поймать.
Но вот ту, о которой я говорю, поймать было нельзя. Пока я не написал ту программу с тяжелым умножением/делением, благодаря которой стало видно, с какой частотой происходит ошибка. Вместо того чтобы падать раз в пару дней, теперь система рушилась раз в пару минут. И как только мы получили то, что обрушивает машину, у нас появился шанс это найти.
Сейбел:Сегодня некоторые говорят: “Да, конечно, у ассемблера больше всего шансов повредить память из-за программных ошибок, но и Си склонен к этому больше, чем некоторые другие языки”. Можно сделать так, что указатели будут указывать черт знает куда, и получится выход за границу массива. Вы не считаете, что это проблема?
Томпсон:Нет, ее можно обойти языковыми оборотами. Некоторые пишут хрупкий код, а некоторые - очень крепкий структурно, и тут все зависит от человека. Думаю, хрупкий код можно написать на любом языке. Я определяю хрупкий код так: допустим, требуется добавить функциональность, так вот в хорошем коде ее нужно добавить только в одно место, а в хрупком придется затронуть сразу десять мест.
Сейбел:Если появляется брешь в безопасности из-за переполнения буфера, то что вы можете ответить на критику Си и C++, где утверждается, что они частично за это ответственны, что многих проблем можно было бы избежать, если использовать язык, который проверяет границы массивов или в котором есть сборка мусора?
Томпсон:Ошибки есть ошибки. Вы пишете код с ошибками, просто потому что вы так пишете. Если язык безопасен в смысле безопасности времени выполнения, то операционная система упадет, а не переполнит буфер, став при этом уязвимой. Например, ping of death - атака на IP-стек операционной системы. Мне кажется, что будут еще атаки такого рода. Это будут не атаки типа “полностью захватить машину и стать суперпользователем”. Это будут ping of death.
Сейбел:Но ведь есть разница между отказом в обслуживании и уязвимостью, когда вы можете стать суперпользователем и делать, что захотите.
Томпсон:Есть две возможности стать суперпользователем: одна состоит в переполнении буфера, а другая - в том, чтобы указать программе сделать то, чего она делать не должна. В большинстве случаев реализуется вторая возможность, а не переполнение буфера. Вы можете стать суперпользователем без всяких переполнений. Так что ваш аргумент не работает. Все, что нужно сделать, - это уговорить su [73] Команда UNIX-подобных операционных систем, позволяющая пользователю войти в систему под другим именем. - Прим. науч. ред.
дать вам оболочку; все пути и так уже там есть, без каких-либо ошибок времени выполнения.
Сейбел:Ладно. Не будем говорить о том, что ведет к краху программы, уязвимости или чему-то подобному; есть такой класс ошибок, которые случаются в Си и C++, но почему-то не случаются, скажем, в Java. Есть ли для определенных типов приложений какие-то преимущества, весомые по сравнению с тем, что эти ошибки будут происходить и вызывать неприятности?
Томпсон:Думаю, этот класс ошибок доставляет не так уж много проблем. Разумеется, каждый раз когда я пишу один из вызовов функции, которая не проверяет длину строки, strcpy и тому подобное, я знаю, что фактически пишу ошибку. Но каким-то образом я принимаю решение о том, оправданна ли эта ошибка, нужно ли экономить аргументы. Сейчас обычно я их экономлю. Но имеется семантическая проблема: если вы обрезаете строку и используете обрезанную строку, то появляется новая проблема. Ошибка по-прежнему там, просто буфер еще не переполнен.
Сейбел:Какие инструменты вы используете при отладке?
Томпсон:В основном вывод на печать. При разработке программы я размещаю очень много операторов вывода на печать. И пока я их не убрал или не закомментировал, вывод на печать достаточно надежен. Мне редко приходится возвращаться к этому снова.
Сейбел:И что именно вы печатаете?
Томпсон:Все, что нужно, все, что удобно иметь под рукой. Инварианты. Но по большей части я печатаю во время разработки. Так я и выполняю отладку. Я не пишу программы счистого листа - я беру программу и изменяю ее. Даже в большой программе я вывожу: “main, left, right, print, hello”. Да, “hello” - это не то, что я ожидаю от этой программы. Я вывожу на печать то, что ожидаю увидеть, и отлаживаю эту часть. При разработке я запускаю программу двадцать раз в час.
Читать дальшеИнтервал:
Закладка: