Один-единственный пропущенный дефис уничтожил ракету стоимостью в миллионы долларов через несколько секунд после запуска. Ошибка округления чуть не обрушила открытие биржи. Самые дорогостоящие баги в истории программного обеспечения почти никогда не бывают драматичными, сложными ошибками — это мелкие, легко упускаемые из виду ошибки, которые случайно оказались точно в неправильном месте.
Базовый уровень GCSE
Mariner 1: дефис, стоивший ракеты
В 1962 году зонд NASA Mariner 1 был уничтожен наземным управлением менее чем через пять минут после запуска, после того как его программное обеспечение наведения начало выдавать крайне неверные команды управления. Первопричина восходила к одному пропущенному символу в уравнении наведения, переписанном от руки, — формула сглаживания, которая должна была усреднять небольшие колебания датчиков, вместо этого обрабатывала каждое малейшее колебание как реальную и срочную коррекцию курса, отправив ракету с заданной траектории.
Пропущенный символ превратил формулу сглаживания в нечто, читающее каждое небольшое колебание датчика как настоящую команду управления — крошечная разница с катастрофическим результатом.
Почему маленькие баги вызывают самые большие катастрофы
Крупный, очевидный баг обычно быстро замечается — программа немедленно аварийно завершается или выдаёт явно неверный ответ, который кто-то замечает при тестировании. Баги, наносящие реальный вред, почти всегда достаточно тонкие, чтобы пережить тестирование и достичь продакшена: ошибка смещения на единицу в цикле, предположение об округлении, которое ломается только при необычном значении, условие, верное 99,9% времени и катастрофически неверное в остальное время. Чем меньше и незаметнее ошибка, тем больше мест, где она может спрятаться.
Вопрос в формате экзамена
Программист пишет цикл, предназначенный для обработки всех 10 элементов списка (с индексами от 0 до 9), но пишет «for i in range(1, 10)» вместо «for i in range(0, 10)». Объясните, к какому типу относится эта ошибка и каким будет её эффект. [3 баллов]
Показать образец ответа и разбивку баллов
- Это ошибка смещения на единицу (off-by-one) (1 балл)
- Поскольку индексация начинается с 0, написанный цикл начинается с 1 и никогда не обрабатывает элемент с индексом 0 — первый элемент списка незаметно пропускается (1 балл)
- Последний элемент (индекс 9) по-прежнему обрабатывается правильно, так как range(1, 10) действительно включает 9 — программа выполняется без сбоя, она просто незаметно выдаёт неполный результат (1 балл)
На что обращает внимание экзаменатор: точно определите, какой именно индекс пропущен, сравнив предполагаемый диапазон с написанным, а не давайте лишь общее определение «ошибки смещения на единицу».
Частая ошибка: предполагать, что программа завершится с ошибкой, или что пропускается последний элемент — эта конкретная версия пропускает первый элемент и работает без сбоя, что как раз и делает ошибки смещения на единицу опасными: они не всегда себя обнаруживают.
Что эти сбои на самом деле изменили
Провал Mariner 1 стал стандартным примером в преподавании программной инженерии и напрямую повлиял на то, как сегодня проверяется критически важный код — сама идея, что одна ошибка переписывания могла бы однажды достичь работающей системы наведения без повторной проверки, — это именно то, что современный код-ревью, автоматизированное тестирование и формальная верификация призваны предотвратить. Каждый знаменитый исторический баг в реальном смысле является причиной, по которой сегодня существует конкретная мера инженерной безопасности. Если отладка, тестирование или практика программной инженерии требуют объяснения как настоящий профессиональный навык, а не просто экзаменационный материал, именно для этого существует наше репетиторство по информатике GCSE — смотрите полный путь обучения здесь.
Часто задаваемые вопросы
Был ли баг с дефисом в Mariner 1 действительно одним символом?
Наиболее часто повторяемая версия этой истории — пропущенный дефис (или надчёркивание, в исходной нотации FORTRAN) в уравнении наведения, из-за чего программное обеспечение наведения ракеты неправильно интерпретировало формулу и выдало неверные команды управления — ракета была намеренно уничтожена менее чем через 5 минут после запуска, чтобы предотвратить её падение в населённую зону. Некоторые историки спорят о точной технической детали, но главный урок — крошечная, легко пропускаемая ошибка, вызвавшая катастрофический сбой, — хорошо задокументирован.
Почему ошибки «смещения на единицу» происходят так часто?
Потому что счёт в коде часто начинается с 0, а не с 1 — первый элемент списка обычно находится на позиции 0, а не на позиции 1, — и чрезвычайно легко написать цикл или условие, смещённое ровно на одну позицию в ту или иную сторону. Это одна из самых распространённых категорий багов во всём программировании именно потому, что ошибка настолько мала и легко допускается незаметно.
Что на самом деле мешает подобным багам достигать продакшена сегодня?
Автоматизированное тестирование (запуск кода против известных ожидаемых результатов перед его выпуском), код-ревью (второй человек проверяет логику перед слиянием) и более строго типизированные языки, которые улавливают некоторые категории ошибок ещё до запуска программы. Ничто из этого не гарантирует ноль багов, но они улавливают подавляющее большинство подобных мелких, легко пропускаемых ошибок, которые вызвали самые известные исторические сбои.
Оценки и отзывы читателей
Оцените эту статью по нескольким критериям — ваше мнение помогает другим читателям и помогает нам становиться лучше.
Была ли эта статья полезной?
Расскажите, что вы думаете — исправление, вопрос, оставшийся без ответа, или тема, которую вы хотели бы увидеть далее.
Хотите обсудить голосом? Запишитесь на бесплатный видеозвонок в удобное время: 15 минут для короткого вопроса, 30 — для всего остального. Время показывается в вашем часовом поясе.

Об авторе
Sudershan Soni
Основатель и главный преподаватель в Mostak Services — репетитор по математике, естественным наукам, информатике и STEM со степенью магистра и более чем 20-летним профессиональным опытом, преподаёт ученикам от уровня 11+ и GCSE до A-Level и выше, онлайн по всему миру.
Читать полный профиль