Решали задачу, суть которой сводилась к тому, чтобы дискретными отрезками достичь поверхности Земли, не выходя за пределы заранее заданного конуса. В качестве подзадач приходилось пересекать окружности, сравнивать углы между векторами и заниматься прочими трехмерно-геометрическими прелестями.
Всё готово, начинаем проверку. На одном тесте работает, на втором работает, на третьем — бац! — ошибка. В результате кропотливого дебаггинга обнаруживается проблемный кусок кода:
long double a1, a2; a1 = PI / 2 + alp; a2 = PI / 2 - alp;
После выполнения оказывается, что и a1, и a2 меньше, чем 1,57. Долго думали. Ещё думали. В итоге посмотрели в начало кода:
const int PI = 3.1415926535897932384626433832795;
Вот уж действительно: «Для простоты вычислений примем Пи равным трём»...
Дело было на первом курсе университета — тогда мы только-только начинали осваивать программирование на Паскале. Я зашёл к одногруппнику, который в это время бился с непростой программкой аж на 100 строк кода. В процесс отладки тут же был втянут и я — просмотрел код, сделал пару-тройку исправлений... Программа работает, компилится, но результаты выдаёт явно не те. Полчаса мы перечитывали код, подправляли, оптимизировали; абсолютно правильная «на бумаге» программа ни в какую не хотела выдавать верный результат.
Никогда не забуду выражение лица товарища, обнаружившего причину мучений. Оказалось, что я, в первый раз правя код, вместо переменной b в одном из операторов влепил d. С тех пор я стараюсь называть переменные осмысленно, а однобуквенных имён и вовсе избегать.
В последнее время я сконцентрировался на программировании микроконтроллеров на Си и ассемблере. Столь глубокое погружение в новую тему не могло не сказаться на психике.
Итак, раннее утро, часов шесть. Должна приехать родственница жены; я сквозь сон слышу звонок в дверь. Супруга просыпается, идёт встречать гостью. В сонный мозг приходит мысль: «Прерывание от звонка в дверь сработало». Мысленно представляю себе текст программы, понимаю, что до следующего прерывания еще куча тактов, и спокойно ухожу в sleep mode c пониженным энергопотреблением.
Через какое-то время просыпается мелкий, и не обнаружив рядом мамы, начинает пинать меня ногами в живот. Возвращаюсь к листингу — это не прерывание по звонку будильника. Если это не прерывание, значит, меня пинает главный цикл. А как он меня может пинать, если я в sleep mode? Он обязан подождать следующего прерывания!..
С мыслью о найденном баге я окончательно просыпаюсь.
SexPosition, говорите? Мне как-то довелось заниматься рефакторингом модуля, работавшего с системными таблицами нашего приложения, среди которых была и пресловутая «Sex».
То, что, разбираясь с этим делом, я осуществлял в проекте поиск по известному ключевому слову и чувствовал себя злобным, начинающим и неопытным др^H^H искателем порнухи — это полбеды. Гораздо интереснее было обнаружить сопутствующий класс SexManager — видимо, что-то вроде офис-менеджера по особым вопросам.
Cреди находок были переменные и функции animalSex, SexPanel и sexModel.getSex(). А что вы хотите — система медицинская, тут понятие пола порой к одному биту не свести. Вот и приходится работать... секс-менеджером.
Преподаватель: Еще задачка на динамику. Сейчас мы узнаем, как сгенерировать все последовательности длины N из нулей и единиц так, чтобы рядом не стояло трёх единиц. Голос с задней парты: А зачем все это нужно? Преподаватель: Нужно. Вот представь — гуляешь ты с девушкой, и вдруг она тебе говорит: «А сгенерируй-ка мне все последовательности длины N из нулей и единиц так, чтобы трех единиц не стояло рядом!» Голос с задней парты: ...и я покажу ей исходники решения, а она сама сгенерирует. Голос с первой парты:(мечтательно) Да-а, девушка-компилятор — это круто!..
В конце 11 класса мы с двумя друзьями из класса сдавали ЕГЭ по информатике. Один из них испытывал трудности в подготовке к экзамену и обратился ко мне за помощью. Дело происходило в июне, в школу мы уже не ходили, поэтому алгоритмы решения задач я объяснял ему по аське. Это было крайне неудобно: задачи были нетривиальными, поэтому печатать приходилось очень много.
Мы решили организовать видеоконференцию. То ли я нажал не туда, то ли мой друг воткнул микрофон не в ту дырку, но я не получал ни изображения, ни звука, а друг меня только слышал. Работали мы по такой схеме: он в письменном виде присылает мне задачу, а я устно объясняю решение.
Представьте: сижу я и вдумчиво излагаю, как определить, сколько чисел в двумерном массиве после выполнения алгоритма на Паскале примет отрицательные значения. Входит мать и видит картину: её сын сидит, смотрит на пустой рабочий стол (все окна я свернул для концентрации внимания) и о чём-то разговаривает со своим компом. Крику было!.. С трудом отговорил маму вызывать психиатра, объяснив, что я ещё не успел сойти с ума от многочасовых бдений за клавиатурой.
Некоторое время назад мне понадобилось написать класс, разбирающий структуру данных (строку, содержащую в себе в кодированном виде информацию о человеке) и дающий доступ к этой информации при помощи простых функций.
Буквально через день в процессе доработки этого класса появилось желание вынести позиции полей данных в этой строке в константы во избежание появления ошибок в дальнейшем. Был выбран простой синтаксис: *Position обозначало позицию поля данных в строке, а *Length — её длину. Например, birthDatePosition и birthDateLength — всё просто и понятно.
Только по прошествии получаса до меня наконец дошло, что речь-то идёт о разборе данных о человеке. Теперь невиннейшие константы sexPosition и sexLength в коде навевают определённые мысли о собственном моральном облике.
— Пятачок, нам прислали десять горшков меда, по восемь каждому! — Но как это, Винни, по восемь каждому?! — Не знаю как, но свои восемь я уже съел.
На пятый час написания кода на ассемблере под ATmega128 я осознал, что Винни-Пух на самом деле был очень справедливым медвежонком. Просто он был программистом и считал в шестнадцатиричной системе...