The Debugging Mindset

4.Ten Minutes That Lasted Ten Milliseconds

A

In this chapter

We'll learn to find logical errors like a detective: dry runs (playing the computer with pen and paper), tracing what happens step by step, the most common beginner mistakes, and a simple method for writing any algorithm.

14–16 min

The Problem in Real Life

Anna turns version 2 into code. In her first test, a fan holds a seat, waits two minutes, and pays. The system says: "Your hold has expired."

Two minutes, not ten. She reads the code five times. It looks right every time. "I don't understand," she says. "Every line makes sense."

John slides a blank sheet of paper across the desk. "Then stop reading it like a human. Read it like the computer — one line at a time, writing down every value."

J

Don't guess what the code does. Follow it, step by step, and watch where reality and your expectation split apart.

John

Staring at Code vs. Tracing It Step by Step

Your brain autocorrects

When you read your own code, you see what you meant to write, not what's actually there.

Play the computer

Following the code line by line on paper, writing every value, reveals what really happens.

Find where it splits

The bug is at the first step where the real value differs from the value you expected.

The Debugging Mindset

The detective analogy: a good detective doesn't guess who did it and then look for proof. They collect facts, follow the timeline step by step, and look for the exact moment the story doesn't add up. Debugging is the same. A bug is the gap between what you expected the code to do and what it actually did. Your job is to find the exact step where that gap appears.

The detective's most powerful tool is surprisingly simple: pen and paper.

  • Dry run — playing the computer: you run the code in your head, on paper, without a computer. Go line by line, exactly as the computer would, and never skip a line because "it's obviously fine." It's called "dry" because nothing actually runs — like a rehearsal before the real show.
  • Tracing — keeping a trace table: while you dry-run, write a small table: one column for each variable, one row for each step. After every line, write down the new values. This is called tracing the execution. The table makes the invisible visible.
  • Finding the logical error: compare each row with what you expected. The first row where they differ is where the bug is. You don't need to understand the whole program — just find the first step where reality splits from your expectation.
Table — Anna's trace table — hold at 10:00, pay at 10:02
StepLine of codeheldUntilExpectedMatch?
1now = 10:00:00.000——✓
2heldUntil = now + 1010:00:00.01010:10:00.000✗ — 10 ms, not 10 min!
3(fan pays) now = 10:02:00.00010:00:00.01010:10:00.000—
4IF now is before heldUntilfalse → "expired"true → take payment✗
This whole line is a row — one record

The first ✗ is the bug. Everything after it is just a consequence.

Table — Common beginner mistakes — check these first
MistakeExampleFix
Off-by-onecount > 5 instead of count >= 5Test the exact boundary values
Wrong units+ 10 (milliseconds) meant as 10 minutesName the unit: HOLD_DURATION_MS
= instead of ===if (state = "SOLD") puts a value inUse === to compare
Conditions in the wrong orderGroup discount checked before studentMost specific / best case first
Forgetting the empty caseAn empty cart crashes the totalAlways test zero items
Not updating a valueSeat stays HELD after paymentTrace every variable
Infinite loopA while condition that never becomes falseMake sure each loop moves toward its end
Mixing text and numbers"5" + 1 gives "51"Convert with Number() first
Table — Five steps for writing any algorithm
StepWhat you doFor the seat hold
1. UnderstandSay it in your own words; list input and outputSeat, fan, time in → held / taken out
2. ExamplesWork examples by hand, including edgesPay at minute 2, at minute 9, at minute 11
3. StepsBreak it down; pseudocode or flowchartVersions 1 and 2
4. Dry runTrace your steps on paperThe trace table above
5. Code and testWrite code; test the same examplesFix the units bug, test again
The bug and the fix
// Before: Date.now() counts in MILLISECONDS — this is 10 ms, not 10 minutes
seat.heldUntil = Date.now() + 10;
// After: say the unit out loud in the name
const HOLD_DURATION_MS = 10 * 60 * 1000; // 10 minutes × 60 seconds × 1000 ms
seat.heldUntil = Date.now() + HOLD_DURATION_MS;

Putting the unit in the name (MS for milliseconds) makes this whole family of bugs much harder to write.

Anna's trace: she writes a trace table for her test: the fan holds the seat at 10:00 and pays at 10:02. Line by line: now is 10:00. heldUntil = now + 10. She writes down the value... and stops. In JavaScript, time is counted in milliseconds — thousandths of a second. So + 10 added ten milliseconds, not ten minutes. The hold really did expire almost instantly; the payment page just loaded slowly enough that she didn't notice.

The fix is one line: heldUntil = now + 10 * 60 * 1000 (10 minutes × 60 seconds × 1000 milliseconds) — or better, a named constant HOLD_DURATION_MS. She runs the test again: hold at 10:00, pay at 10:02, and the seat is SOLD. The bug wasn't in a hard part at all. It was a hidden assumption about units — exactly the kind of thing your eyes skip and a trace table catches.

The beginner's mistake list: John shares a list he wishes he'd had on his first day. Almost every early bug is one of these: off-by-one (> vs >=, like BUG-142), wrong units (milliseconds vs. minutes), using = (put a value in) when you meant === (compare), conditions in the wrong order (the first true one wins — Act 07), forgetting the empty case (zero items, empty text), forgetting to reset or update a value, a loop that never ends, and mixing text and numbers ("5" + 1). When you're stuck, check this list first.

A simple method for writing any algorithm: John sums up the whole Act as five steps. 1. Understand: say the problem in your own words and write the input and output. 2. Examples: work a few examples by hand, including the edges. 3. Steps: break it down and write pseudocode or a flowchart. 4. Dry run: trace your steps with your examples on paper. 5. Code and test: only now write the code — and test it with the same examples, especially the edges.

Key Takeaway

A bug is the gap between what you expected and what actually happened. Don't stare and guess — dry-run the code like the computer, keep a trace table of every value, and find the first step where reality differs from your expectation. Then check the classic beginner mistakes, and plan every algorithm in five steps: understand, examples, steps, dry run, code and test.

Why This Matters

Every developer spends a large part of their time debugging, and the difference between a junior and a senior is often just method: guessing versus tracing. The habits from this chapter — dry runs, trace tables, the mistake checklist, the five-step method — will save Anna hours every week. In Act 17 she'll get real tools for this (debuggers and tests), but they all do what her pen and paper just did.

The seat hold works: picked, held for exactly ten minutes, sold or released, every "what if" answered. Samantha plans to turn it on for the next big sale. Before that, John wants to see Anna do the whole thing again on her own — understand, examples, steps and dry run.

Next