awesome-everything RU
↑ Back to the climb

Base CS from zero

When a program fails: hunt two bugs by reasoning

Crux Hands-on project: build a small buggy program, drive it into one loud crash and one silent wrong answer, then locate each cause by reasoning and prove the fix.
Your altitude — climbing toward senior
ZeroJuniorMiddleSenior
You are at middle altitude — in the sky
◷ 200 min

Reading about failures is not the same as hunting one down. Build a small program, plant two failures of opposite character — a loud crash and a silent wrong answer — then use the unit’s method to locate each cause by reasoning, not guessing, and prove the fix with evidence.

Goal

Turn the unit’s mental model into a repeatable engineering loop: distinguish a loud defined error from a silent failure in your own code, read a real stack trace top-down to the throw site, separate where an error surfaced from where its cause lives, and locate each bug by a written hypothesis confirmed against actual state.

Project
0 of 7
Objective

Build a small program with two deliberately planted bugs — one that raises an exception (a loud, defined error) and one that produces a wrong answer with no error at all (a silent failure) — then locate and fix each by reasoning, documenting the hypothesis and the evidence at every step.

Requirements
Acceptance criteria
  • A short write-up that, for each bug, states the hypothesis, the state you checked, the observation, and the one-line fix — proving you located the cause by reasoning, not by changing lines until the symptom vanished.
  • For bug A: the annotated stack trace with the throw site and entry clearly marked, and a sentence on whether the throw site was the cause or whether the real cause was upstream in the call chain.
  • For bug B: a clear statement of why no exception was raised — what made the failure silent — and the before/after output showing the wrong answer becoming the right one.
  • A one-line classification of each bug as a defined error or a silent failure, with the reason.
Senior stretch
  • Add a third bug that is an out-of-bounds read, and describe how the same bug would behave as a defined error in a bounds-checked language versus undefined behaviour in a low-level unchecked one.
  • Wrap bug A's throwing call in a handler (a catch block) one frame up, recover gracefully, and show the program now continues instead of crashing — demonstrating that an exception is not the same as the program being broken.
  • Convert the silent failure into a loud one by adding a validation check that throws on the bad value, and argue in two sentences why turning a silent failure into a loud, defined error is usually an improvement.
  • Write a one-page debugging runbook for a beginner: the three moves (narrow the range, read the trace, check state), how to read a trace top-down, and the rule that the throw site is where the error surfaced, not always where the cause lives.
Recap

This is the loop you will run on every real failure: classify it — loud defined error or silent wrong answer — read the trace top-down to the throw site, then separate where it surfaced from where the cause lives. Locate the cause by reasoning over a deterministic machine: write a testable hypothesis, narrow the range, check the actual state, and change a line only once you have proven the guilty step. Doing it once on a toy program with two planted bugs makes the production version muscle memory.

Continue the climb ↑Why async exists
shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.