Вход/Регистрация
Кодеры за работой. Размышления о ремесле программиста
вернуться

Сейбел Питер

Шрифт:

Программирование — глубоко неестественный вид деятельности, и ему надо как следует учиться. Люди привыкли, что их слушатели сами восстанавливают лакуны в речи. И с компиляторами мы обращаемся в какой-то мере так же. Говоря: «Мне нужна переменная с именем foo», — вы не заботитесь о регистре имени. Люди неточны, часто неряшливы в своей речи. Но когда мы даем команды машине, детали важны, потому что мелкая погрешность может изменить ход всего процесса.

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

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

Стил: Да. И, кроме того, люди сосредоточены на главном, они не думают о пограничных случаях, о сложных случаях, о маловероятных случаях. А именно в таких случаях начинаются разногласия — как сделать правильно.

Иногда я спрашиваю студента: «Что будет в таком-то случае?» — «То-то и то-то». И тут же кто-нибудь вскакивает: «Нет, должно быть вот так!» Вот такие вещи и надо отражать в программной спецификации.

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

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

Сейбел: Возьмем «Fantasia» — она в том числе об опасности рекурсии.

Стил: «Fantasia» и рекурсия, да. Или «Я хочу быть самым богатым человеком в стране», — в итоге все становятся бедняками, а он остается при своем. Такое в волшебных сказках случается, потому что люди забывают о разных путях, ведущих к цели. Если думать только о главном желании, пренебрегая деталями, много чего не стыкуется.

Сейбел: Каков же урок волшебных сказок? Гэндальфы становятся великими магами путем тяжких трудов и зубрежки заклинаний, а легкого пути нет?

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

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

Стил: Я уже говорил: нельзя пренебрегать точностью. В то же время мы можем создавать инструменты для повышения точности. Мы не можем сделать эту процедуру тривиальной, но можем помочь избежать некоторых ошибок. Вместо того чтобы допускать циклическое переполнение 32-битных целых, можно сделать обнаружение арифметического переполнения или предоставить возможность работы с большими числами. Сейчас реализация всего этого обходится дороже, но я считаю, что работа с настоящими большими числами дает немного меньше ошибок для некоторых видов программирования. Программисты и создатели алгоритмов для операционных систем все время попадают в одну и ту же ловушку. Они говорят: «Нам нужно синхронизировать фазы, так что будем брать по одному числу. При начале новой фазы вычисления будем увеличивать на единицу какую-нибудь переменную, получать новое число — и тогда все участники будут уверены, что работают в одной и той же фазе, пока не начнется какая-нибудь операция». Это работает на практике, но с 32-битными числами вы досчитаете до 4 миллиардов довольно быстро. Что будет в случае циклического переполнения? Все будет в порядке? Или нет? Многие подобные алгоритмы в компьютерной литературе содержат эту небольшую ошибку. Что если какой-нибудь поток застопорится со 2-й по 32-ю итерацию? Маловероятно, но все-таки возможно. Надо или как-то смягчить эту проблему в смысле корректности, или все просчитать и показать, что такой вариант настолько маловероятен, что беспокоиться не о чем. Или, возможно, для вас приемлем один компьютерный сбой в день. Суть в том, что надо проанализировать проблему, а не игнорировать ее. Тот факт, что счетчик может переполниться, — проблема еле заметная, большинство программистов она не затронет. Но для остальных это ловушка в их алгоритмах.

Сейбел: Кстати о сбоях. Какова худшая ошибка, с которой вы имели дело?

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

Когда я был зеленым программистом и работал на IBM 1130, решение, как исправить ошибку, однажды явилось мне во сне. Или сразу после пробуждения. Я бился над ней пару дней, ничего не получалось. И вот посреди ночи — озарение. Оказалось, я кое-что пропустил в спецификации интерфейса.

Это было связано с параллельными процессами. Я писал декомпилятор, чтобы декомпилировать и изучить дисковую оперативную систему машин IBM. Для этого надо было взять с диска данные в двоичном виде и распечатать их в разных форматах — как инструкции, как коды символов, как числа и так далее. Для преобразования символов я скармливал их разным функциям преобразования, одна из которых была предназначена для работы с кодом, считанным через устройство для чтения перфокарт. И я пропустил крохотное примечание в спецификации: «Прежде чем вызвать эту функцию, необходимо очистить младшие биты в буфере, в который будут считываться данные с перфокарты». Или, наоборот, их надо было установить.

  • Читать дальше
  • 1
  • ...
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: