В сентябре 1985 года Джон Бентли опубликовал книгу Programming Pearls — сборник афоризмов об истинах в программной отрасли.

Прошло сорок лет. Наверняка спустя множество революций в нашей отрасли они потеряли актуальность? Эти советы относятся к той же категории, что и «всегда держи при себе пучок сена для лошадей» или «карманный калькулятор не всегда будет под рукой».

Ох, какая наивность! Ничто не ново под луной. Почти все приведённые афоризмы болезненно актуальны.

Прежде чем мы приступим, позволим Бентли рассказать о происхождении этого сборника:

Programming Pearls.

Хотя в каждом из высказываний отчасти есть истина, их следует воспринимать с долей скептицизма. После афоризмов обычно указаны фамилии тех, кто прислал их, даже если автором был дядя Ральф (прости, Ральф). Уверен, что обошёл вниманием многих, не указав истинное авторство; могу лишь утешить их тем, что плагиат — это самая искренняя форма лести.

Итак, поехали!

Gnarly monochrome scan of Programming Pearls.
Gnarly monochrome scan of Programming Pearls.

Кодинг

В случае сомнений применяй брутфорс. Кен Томпсон, Bell Labs

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

Избегайте функций арксинуса и арккосинуса; обычно лучше применять тригонометрическое тождество или вычислять скалярное произведение векторов. Джим Конингхем, Arvin/Calspan Advanced Technology Center

А теперь сразу нечто совершенно устаревшее. Подобные математические функции оптимизированы настолько, что, вероятно, уже не важно, как их вычислять.

Выделите в дате на год четыре разряда: грядёт новый миллениум. Дэвид Мартин, Норристаун, Пенсильвания.

Почему к тебе не прислушались, Дэвид? Хоть я и надеюсь, что весь код по эту сторону Y2K использует ISO8601, меня потрясает, что до сих можно встретить людей, желающих где-нибудь сэкономить пару байтов. В некоторых маленьких системах это удобно, но чаще всего приводит к катастрофе. Я намекаю на тебя, GPS!

Избегайте асимметрии. Энди Хьюбер, Data General Corporation

Честно говоря, не совсем понимаю, что имел в виду Энди. Предположу, что подразумевается возможность выполнить преобразование A->B без возможности преобразования B->A. Или же это о получении данных в одном формате и выводе в другом формате. На Hacker News эту тему обсуждали подробнее.

Чем раньше начинаешь писать код, тем дольше будешь разрабатывать программу. Рой Карлсон, Висконсинский университет

Бум! Ещё одна истина. По аналогии с дровосеком, который тратит время на заточку топора, мы знаем, что самый малоэффективный способ создания программы — это сразу браться за написание кода.

Если не можешь записать что-то на английском, то не сможешь закодировать это. Питер Халперн, Бруклин, Нью-Йорк

Слишком большое количество багов возникает из-за непонимания требований пользователя/заказчика.

Детали важны. Питер Вайнбергер, Bell Labs

Полностью согласен, Пит! При создании ПО легко увлечься «общей картиной». Но если не обработать напильником острые края, жизнь кода не будет счастливой.

Если код и комментарии расходятся, то, вероятно, ошибочны и тот, и другие. Норм Шайер, Belt Labs

Увы, мечта о самодокументирующемся коде так и не реализовалась. Здесь всё тоже сводится к (не)способности описания наших требований и к (не)адекватному превращению этих комментариев в код.

Процедура должна умещаться на странице. Дэвид Триббл, Арлингтон, Техас

У Amazon есть известное «правило двух пицц», определяющее максимальный размер команды. Чем больше или сложнее элемент, тем выше вероятность того, что что-то пойдёт не так. Да, у DRY и YAGNI есть свои пределы, но мы (вроде бы) чётко находимся в парадигме того, что большие процедуры/функции вредны для здоровья.

Если у тебя слишком много особых случаев, то ты делаешь что-то не так. Крейг Зеруни, Computer FX Ltd. Лондон, Англия

IF/ELSE и CASE/SWITCH продолжают испытывать наше терпение. Красивый и чистый код ломается из-за специальных подпрограмм, обрабатывающих редко возникающие ситуации. Но сложно сказать, что это «что-то не то». Иногда мир слишком сложен, а задача компьютеров — выполнять трудную работу за нас.

Сначала обеспечь корректность структур данных, и остальная часть программы напишется сама. Дэвид Джонс, Эссен, Нидерланды

Дейв прав. Правильно определённая структура данных по-прежнему остаётся сутью большинства CRUD-систем.

Пользовательские интерфейсы

[Принцип наименьшего удивления] Делай пользовательский интерфейс максимально согласованным и предсказуемым. Предложение множества читателей

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

Программа, спроектированная для ввода со стороны человека, обычно ломается от входных данных, сгенерированных компьютером. Дэннис Ритчи, Bell Labs

Думаю, по большей мере этот афоризм сегодня неактуален. Скорость человеческого ввода ограничена, но компьютеры могут мгновенно генерировать огромные объёмы данных. Однако выросли и способности машин в потреблении данных. Наверно, самое близкое к этому афоризму — это DDoS: ситуация, когда веб-сервер, предназначенный для небольшого количества посетителей, перегружается потоком автоматизированных злоумышленных запросов.

Двадцать процентов форм ввода, заполняемых людьми, содержат плохие данные. Виктор Высотский, Bell Labs

Ха! Виктор не знал, что в двадцать первом веке у нас будет валидация <input type...! Но да, люди вводят в формы всевозможный мусор.

Восемьдесят процентов форм ввода задают вопросы, которые их не касаются. Майк Гэри, Bell Labs

Майка отправили из будущего, чтобы он предупредил людей прошлого, но они игнорировали его.

Не заставляй пользователя предоставлять информацию, уже известную системе. Рик Лемонс, Cardinal Data Systems

Здесь я немного не соглашусь с Риком. Спрашивать информацию повторно разумно для того, чтобы дважды проверить её корректность. Также полезно валидировать, что пользователь именно тот, кем он представился.

В случае 80% датасетов 95% информации можно увидеть на хорошем графике. Уильям Кливленд, Bell Labs

Те, кто видел квартет Энскомба, знают, насколько это правда.

Отладка

Из всех моих багов программирования 80% были синтаксическими ошибками. Из оставшихся 20% тривиальными логическими ошибками были 80%. Из оставшихся 4% ошибками указателей были 80%. А вот оставшиеся 0,8% уже сложны. Марк Доннер, IBM T. J. Watson Research Center

Теперь, когда у нас есть IDE, синтаксические ошибки встречаются реже. Надеюсь, языки визуального программирования ещё больше снизят их количество. Ошибки логики по-прежнему одолевают нас. От ошибок указателей мы избавились (если, конечно, вы не работаете на очень низком уровне). И я бы сказал, что количество «сложных» багов стало выше из-за сложного взаимодействия множества библиотек и систем.

Нужно в три раза больше усилий для нахождения и устранения багов при тестировании системы, чем при тестировании разработчиком. Нужно в десять раз больше усилий для нахождения и устранения багов «в поле», чем при тестировании системы. Поэтому настаивай на том, чтобы разработчик выполнял юнит-тестирование. Ларри Бернштайн, Bell Communications Research

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

Не занимайся отладкой стоя, это вдвое снижает твоё терпение, а оно нужно тебе целиком. Дэвид Сторер, Седар-Рэпидс, Айова.

Лично я принадлежу к команде работающих стоя! Поэтому считаю, что Дейв ошибается.

Не увлекайся изучением комментариев, они могут сильно дезинформировать. Отлаживай только код. Дейв Сторер, Седар-Рэпидс, Айова

Хм... Да, вероятно, в этом есть истина. Я не могу сказать, что сегодня код стал самодокументируемым, но его определённо легче читать.

Тестирование может показать присутствие багов, но не их отсутствие. Эдсгер Дейкстра, Техасский университет

Осмелимся ли мы перечить Дейкстре?! Ну, только если немного. Благодаря современным инструментам фаззинга мы можем показать отсутствие определённых видов багов.

Каждый новый пользователь в новой системе обнаруживает новый класс багов. Брайан Керниган, Bell Labs

Ага! В нашем коде не было бы багов, если бы не эти противные пользователи!

Не чини то, что не поломано. Рональд Рейган, Санта-Барбара, Калифорния

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

[Девиз мейнтейнера] Если мы не можем починить что-то, то это не поломано. Подполковник Уолт Вейр, армия США

Я в вас верю. Самоуничижение — это нормально, но самоуверенность лучше.

Первый шаг к починке поломанной программы — обеспечение её стабильного вылетания. Том Дафф, Bell Labs

Да! Нерегулярные ошибки хуже всего! И они же оказываются самым крупным источником антипаттерна «на моей машине работает».

Производительность

[Первое правило оптимизации программ] Не делай этого. [Второе прави��о оптимизации программ — только для специалистов] Не делай этого пока. Майкл Джексон, Michael Jackson Systems Ltd.

Справедливо и тогда, и сегодня.

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

Здесь я почти полностью согласен. Многие баги безопасности, которые мы встречаем в современном коде, вызваны «хитрыми» трюками, у которых обнаруживаются неприятные побочные эффекты. Но на уровне микрокода производительность — это по-прежнему главное. И хорошо протестированный быстрый алгоритм может оказаться необходимостью.

На некоторых машинах косвенность медленнее, чем перемещение, поэтому самый часто используемый член структуры должен идти первым. Майк Мортон, Бостон, Массачусетс

Мы живём в эпоху чрезвычайно быстрых SSD и доступа к ОЗУ. Последовательное чтение по-прежнему немного быстрее, чем произвольные переходы, а структуры наподобие B-деревьев обеспечивают хороший баланс между тем и другим. Нам больше не приходится выравнивать данные по физическим дорожкам вращающегося диска.

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

Любопытно, насколько это актуально? Возможно, если мы заменим «ввод-вывод» на «Интернет-запросы», то утверждение останется точным?

Перед оптимизацией используй профилировщик, чтобы найти «горячие места» программы. Майк Мортон, Бостон, Массачусетс

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

[Сохранение размера кода] Если ты ради скорости превращаешь обычную страницу кода всего в несколько команд, то увеличь объём комментариев настолько, чтобы количество строк осталось постоянным. Майк Мортон, Бостон, Массачусетс

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

Если программист может симулировать конструкцию быстрее, чем сам компилятор может реализовать конструкцию, то автор компилятора совершил огромный промах. Гай Л. Стил, Tartan Laboratories

Думаю, тут всё понятно. Но компиляторы уже настолько оптимизированы, что такие ситуации случаются всё реже.

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

Думаю, этот совет можно ещё больше обобщить. Вспоминается проблема замедления полосы прогресса NPM. Во многих программах можно избавиться от большой доли избыточности.

Самый быстрый ввод-вывод — это отсутствие ввода-вывода. Нильс-Питер Нельсон, Bell Labs

Да уж! В те времена люди были одержимы вводом-выводом! В случае больших объёмов он по-прежнему остаётся проблемой. Но, возможно, теперь хотя бы в некоторых случаях можно расслабиться?

Самый дешёвый, быстрый и надёжный компонент компьютерной системы — это тот, которого нет. Гордон Белл, Encore Computer Corporation

Мне кажется, это немного несправедливо. С меньшим количеством ОЗУ ноутбук дешевле, но от этого он не становится быстрее.

[Девиз разработчика компиляторов для прохода оптимизации] Сделать плохую программу хуже — это не грех. Билл Маккиман, Институт Вона

Лично я считаю, что не компилятор должен говорить мне, что я делаю что-то не так.

Электричество движется со скоростью фут в наносекунду. Коммодор Грейс Мюррей Хоппер, ВМФ США

И на нановек за пи секунд! Это один из тех фактов для викторин, неактуальных в современных компьютерных системах.

Программисты на LISP знают ценность всего и стоимость ничего. Алан Перлис, Йельский университет

Сегодня программисты на LISP занесены в Красную книгу, и с ними нельзя обращаться столь строго.

[Формула Литтла] Среднее количество объектов в очереди равно произведению частоты ввода и среднего времени удержания. Ричард Фэйрли, Институт Вона

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

Документация

[Проверка отрицанием] Не включай в документацию предложение, отрицание которого очевидно ложно. Боб Мартин, AT&T Technologies

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

При объяснении команды, фичи языка или аппаратного виджета сначала опиши задачу, которую они должны решать. Дэвид Мартин, Норристаун, Пенсильвания

Согласен. Сочинение писать необязательно, но у документации должен быть контекст.

[Принцип одной страницы] (Спецификация, проект, процедура, план тестирования), которые не умещаются на одну страницу формата А4, невозможно понять. Марк Ардис, Институт Вона

Мне симпатичен этот принцип (см. выше «правило двух пицц»), но, наверно, он игнорирует реальность современных систем. Да, мы должны стремиться к простоте, но в то же время признавать, что сложности неизбежны.

Работа не закончена, пока не закончено оформление документов. Аноним

Аминь!

Управление программным обеспечением

Структура системы отражает структуру создавшей её организации. Ричард Фэйрли, Институт Вона

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

Не продолжай делать то, что не работает. Аноним

Это надо вытатуировать на самом видном месте.

[Правило доверия] На первые 90% кода тратится 90% времени разработки. На оставшиеся 10% кода тратится ещё 90% времени разработки. Том Кэргилл, Bell Labs

Методология Agile немного ослабила силу этого прогноза. Мне кажется, сегодня разработчики обычно лучше справляются с оценками затрат времени. Но избежать парадокса Зенона всё равно сложно.

Меньше 10% кода связано с предполагаемым предназначением системы; остальная часть занимается вводом-выводом, валидацией данных, поддержкой структур данных и другой побочной работой. Мэй Шоу, Университет Карнеги-Меллона

Как часто устанавливаемая вами простая программа подтягивала за собой кучу зависимостей? Чтобы дома не разваливались, нам нужны сегодня крепкие каркасы и леса.

Здравые суждения берутся из опыта, а опыт возникает из-за ошибочных суждений. Фред Брукс, Университет Северной Каролины

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

Не пиши новую программу, если уже существующая делает более-менее то, что тебе нужно. А если программу написать необходимо, то как можно больше работы должен выполнять уже имеющийся код. Ричард Хилл. Hewlett-Packard S.A., Женева, Швейцария

Это путь опенсорса. Гораздо проще создать форк, чем начинать с нуля. Но рано или поздно вы столкнётесь с нежелательным архитектурным решением, несущим важную нагрузку. Прежде чем использовать уже имеющийся код, тщательно подумайте.

Крадите код, когда это возможно. Том Дафф, Bell Labs

Я думаю, ты имел в виду «Соблюдайте условия опенсорсной лицензии, утверждённой OSI», не так ли, Том?

Хорошие отношения с заказчиком удваивают продуктивность. Ларри Бернштайн, Bell Communications Research

Этот урок усвоила Apple, но забыла Google.

Перенос работающей программы на новый язык или систему занимает 10% от исходного времени разработки, труда или денежных затрат. Дуглас Джонс, Айовский университет

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

Не выполняй при помощи компьютера те задачи, которые эффективно можно выполнять вручную. Ричард Хилл, Hewlett-Packard S.A., Женева, Швейцария

Редкий случай, когда я не соглашусь! Вручную можно выполнить задачу эффективно один-два раза, но потом можете пускаться во все тяжкие! Даже если задача проста, например, переименование десятка файлов в папке, то автоматизировав её, вы сможете научиться чему-то интересному.

Я лучше буду писать программы для написания программ, чем писать программы. Дик Сайтс, Digital Equipment Corporation

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

[Закон прототипов Брукса] Планируй выбросить прототип, тебе так или иначе придётся это сделать. Фред Брукс, Университет Северной Каролины

Скажу больше — советую выбрасывать несколько. Это сложно «продать» начальству, но необходимо.

Если планируешь выбросить один, то выбросишь два. Крейг Зеруни, Computer FX Ltd., Лондон, Англия

Лучше проверить дважды!

Прототипирование снижает объём работы по созданию системы на 40%. Ларри Бернштайн, Bell Communications Research

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

[Правило Томпсона для впервые собирающих телескоп] Быстрее изготовить четырёхдюймовое зеркало, а потом шестидюймовое, чем сразу шестидюймовое. Билл Маккиман. Институт Вона

Да, всегда хочется стремиться к большой победе. Но идти к ней нужно маленькими шагами!

Ожесточённая активность — не замена пониманию. Х. Уильямс, Окленд, Калифорния

Да, чёрт возьми! Всегда хочется сразу ринуться в атаку, но это неоптимальное использование времени.

Всегда начинай с самой сложной части. Если сложное реализовать невозможно, то зачем тратить время на простое? Закончив со сложной частью, ты уже почти победил. Всегда начинай с простой части. То, что ты поначалу считаешь простым, часто оказывается сложным. Закончив с простым, можно сосредоточить все усилия на сложном. Эл Шапира, Bell Labs

К счастью, в современных вычислительных системах осталось очень мало «простых» задач. Мы знаем большинство сложных задач. Возможно, если Agile учит нас всегда оставлять ПО в работающем состоянии, следует начинать с простых частей?

Если соврёшь компьютеру, тебе это аукнется. Перри Фэррер, Джермантаун, Мэриленд

Не нужно очеловечивать компьютеры, они этого не любят. На самом деле, сегодня мы часто «врём» компьютерам при помощи фиктивных данных и виртуализированных сред, так что это нормально.

Если система не обязана быть надёжной, то она может делать, что угодно. Х. Уильямс, Окленд, Калифорния

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

Константа для одного человека — это переменная для другого. Сьюзан Герхарт, Microelectronics and Computer Technology Corp.

Я много думал об этом афоризме. Возможно, ограничение области видимости переменных снижает актуальность этой проблемы в 21-м веке?

Данные одного человека — это программа другого. Гай Л. Стил, Tartan Laboratories

Не совсем понял, о чём это. Может кто-нибудь объяснить?

Избегай умных правил. Джон Кондон, Bell Labs

Этим перлом «Жемчужины» завершаются.

Чему мы сегодня научились?

В основном мои претензии оказались несущественными придирками. Хотя дисковый ввод-вывод теперь редко становится проблемой, его место в качестве основной причины задержек заняли сетевые задержки. Нам удалось кое-что исправить, но многие проблемы, похоже, безраздельно связаны с человеческим фактором.

Какая из жемчужин понравилась вам больше всего?

Комментарии (0)


  1. DustCn
    22.09.2025 13:28

    Самый дешёвый, быстрый и надёжный компонент компьютерной системы — это тот, которого нет. Гордон Белл, Encore Computer Corporation

    Тут скорее речь идет про софт. То чего нет не может сломаться.


    1. Octagon77
      22.09.2025 13:28

      То чего нет не может сломаться.

      Именно. Поэтому отсутствующий тормоз лучше сломанного.

      Чем лучше?

      Меньше шансов что заподозрят в принадлежности к тем трусам, которые тормоза придумали.


      1. DustCn
        22.09.2025 13:28

        Нет, это не так работает. Считается что при этом функционал системы - константа. И чем меньше в ней компонентов, чем меньше сложность - тем лучше.


    1. kaptnemo
      22.09.2025 13:28

      В ТРИЗ идеальная техническая подсистема — это подсистема, которая ликвидирована при полном сохранении её функциональности.


  1. Tetsuzin72
    22.09.2025 13:28

    Насчет акрксинуса и арккосинуса готов поспорить. Тут речь не об оптимизации, а о том, что при правильном использовании векторной геометии их можно вобще не вычислять.


    1. tenzink
      22.09.2025 13:28

      Вот именно. Совет живее всех живых. Погрешность вычислений с плавающей точой при использований арксинусов/арккосинусов может быть заметно выше