Базовый CS с нуля
Когда программа падает: охота на два бага рассуждением
Читать про сбои — не то же, что выследить один. Собери маленькую программу, заложи в неё два сбоя противоположного характера — громкое падение и тихий неверный ответ — затем используй метод юнита, чтобы найти причину каждого рассуждением, а не угадыванием, и докажи фикс доказательствами.
Преврати ментальную модель юнита в повторяемый инженерный цикл: отличай громкий defined error от тихого сбоя в собственном коде, читай реальный stack trace сверху вниз до throw site, отделяй, где error всплыл, от того, где живёт причина, и находи каждый баг записанной гипотезой, подтверждённой против реального состояния.
Собери маленькую программу с двумя умышленно заложенными багами — один поднимает exception (громкий, defined error), другой даёт неверный ответ вообще без ошибки (тихий сбой) — затем найди и почини каждый рассуждением, документируя гипотезу и доказательство на каждом шаге.
- Короткое описание, которое для каждого бага указывает гипотезу, проверенное состояние, наблюдение и однострочный фикс — доказывая, что причина найдена рассуждением, а не сменой строк до исчезновения симптома.
- Для бага A: аннотированный stack trace с чётко отмеченными throw site и точкой входа, и фраза о том, был ли throw site причиной или реальная причина была выше по цепочке вызовов.
- Для бага B: ясное заявление, почему exception не поднялся — что сделало сбой тихим — и вывод до/после, показывающий неверный ответ, ставший верным.
- Однострочная классификация каждого бага как defined error или тихий сбой, с причиной.
- Добавь третий баг — чтение за границей массива — и опиши, как тот же баг вёл бы себя как defined error в языке с проверкой границ против undefined behaviour в низкоуровневом языке без проверки.
- Оберни бросающий вызов бага A в обработчик (блок catch) на фрейм выше, изящно восстановись и покажи, что программа теперь продолжает вместо падения — демонстрируя, что exception не равен поломке программы.
- Преврати тихий сбой в громкий, добавив проверку валидации, которая бросает на плохом значении, и обоснуй в двух предложениях, почему превращение тихого сбоя в громкий, defined error — обычно улучшение.
- Напиши однастраничный runbook по debugging для новичка: три приёма (сузить диапазон, прочитать trace, проверить состояние), как читать trace сверху вниз и правило, что throw site — где error всплыл, не всегда где живёт причина.
Это цикл, который ты будешь гонять на каждом реальном сбое: классифицируй его — громкий defined error или тихий неверный ответ — прочитай trace сверху вниз до throw site, затем отдели, где он всплыл, от того, где живёт причина. Найди причину рассуждением над детерминированной машиной: запиши проверяемую гипотезу, сузь диапазон, проверь реальное состояние и меняй строку только когда доказал виновный шаг. Сделав это однажды на игрушечной программе с двумя заложенными багами, ты превращаешь продакшен-версию в мышечную память.