Bug Hunt — Course Map
"Here's a repo. You have an hour. What's wrong with it?" This section trains the answer.
Read this first. It takes five minutes.
The interview has changed
More and more technical rounds skip the algorithm puzzle. Instead you get a small codebase you've never seen, a few hundred to a few thousand lines, and a brief like:
- "Review this pull request as if you were the senior on the team."
- "Users report double charges. Find out why."
- "This service works in staging and falls over in production. Find the problems."
- "Find as many bugs as you can in 45 minutes, and rank them."
Often you're allowed to use an AI assistant. That makes the round harder, not easier: the interviewer has seen the assistant's answers, and they're watching whether you can tell a real bug from a plausible-sounding one, whether you find the bugs it misses, and whether you can explain why each one matters.
What gets scored:
| Skill | What the interviewer is looking for |
|---|---|
| Finding | Do you find the important bugs, not just the obvious ones? |
| Explaining | Can you say how it breaks: the input, the interleaving, the attacker? |
| Ranking | Do you fix the double charge before the typo? |
| Fixing | Is your fix the smallest correct change, and does it keep working behaviour working? |
| Improving | Can you say what design change would prevent this whole class of bug? |
| Method | Do you read systematically, or skim and guess? |
You don't need a 200,000-line codebase to practise this. You need a map of the kinds of bugs that exist, a method for reading that makes you look for each kind, and lots of short reps. That's this section.
The map: six levels
Bugs are graded by what you have to imagine to see them. Each level asks you to picture something more:
Three cross-cutting families sit alongside the levels: bugs in the tests, library and API traps, and smells that hide bugs.
Every bug in the catalogue is also marked with who should catch it:
| Mark | Meaning |
|---|---|
| J | A junior engineer should catch it |
| M | An engineer with about three years' experience should catch it |
| S | Expected of a senior engineer |
Most of L1–L3, the common L4 races, and the everyday L5 and L6 items are M. If you're interviewing at mid-level, that's the bar. If you're interviewing at senior level, the S items are where you stand out.
Reading order
| # | Chapter | You'll be able to… |
|---|---|---|
| 1 | The Bug Catalogue | Name about 170 kinds of bug, with the signal that gives each one away |
| 2 | Reading in Passes | Review an unfamiliar repo systematically in 60 minutes, and write findings up |
| 3 | L1–L2 · Logic and TypeScript | Catch slips, edge cases, error-handling and type-system holes |
| 4 | L3 · Data and SQL | Follow data through the API, the cache and the database |
| 5 | L4 · Concurrency and Time | Spot races and timing bugs from the code alone |
| 6 | L5 · Security | Read code the way an attacker would |
| 7 | L6 · Breaks in Production | See what fails at scale, on deploy, or after a month |
| 8 | Tests, Traps and Smells | Review the tests too, and know the library defaults that bite |
| 9 | Mock Reviews | Run full timed reviews on multi-file codebases |
Read 1 and 2 first. They're the map and the method. The level chapters can be read in any order.
Part 2: Eye Training (plain JavaScript)
Short snippets grouped by the kind of code you're looking at, with hidden bug counts and some clean snippets, to build the reflex of spotting a bug on sight.
| # | Chapter | You'll be able to… |
|---|---|---|
| 10 | Eye Training — Start Here | Use the drills, and see every surface planned |
| 11 | try / catch / finally | See which failures escape a try, and which ones a catch hides |
| 12 | Promises and async/await | Spot unawaited, unhandled and accidentally sequential promises |
| 13 | Timers | Spot timers that never stop, overlap, drift or don't survive a restart |
| 14 | Events, listeners and sockets | Spot leaked and duplicated listeners, reconnect bugs and unchecked rooms |
| 15 | Streams and streaming data | Spot split chunks, missing backpressure, unhandled stream errors and streams that outlive the client |
| 16 | fetch and the network | Spot unchecked statuses, missing timeouts, unsafe retries, SSRF and CORS holes |
| 17 | Caching and memoization | Spot wrong keys, stale and shared entries, cached failures, leaks and stampedes |
| 18 | Shared state and races | Spot lost updates, check-then-act gaps, double submits and out-of-order responses |
| 19 | Values, equality and numbers | Spot falsy defaults, string arithmetic, float money, NaN checks and unsafe integers |
| 20 | Objects and arrays | Spot mutating methods, shared references, lossy copies and prototype pollution |
| 21 | Loops and iteration | Spot off-by-ones, endless loops, skipped items, leftovers, N+1 and quadratic loops |
| 22 | Functions, this and closures | Spot lost this, missing returns, re-created helpers and closures that leak memory |
| 23 | Time and dates | Spot zero-based months, UTC date-only parsing, seconds-vs-milliseconds, month-end and clock-change bugs | | 24 | Resources and cleanup | Spot unreleased connections, stuck flags, open transactions, unbounded threads and shutdowns that drop requests |
Surfaces 25–27 (Node servers, AI app code and mixed rounds) are ideas for later.
How the drills work
Every chapter has bug-hunt drills: a small codebase, one or more files, with bugs planted in it.
- Read the code. Switch files with the tabs.
- Click every line you think is wrong. The timer starts with your first click.
- Check. Lines you got right turn green, false alarms turn yellow, and missed bugs turn red.
- Open each bug for why it's wrong and the fix.
Do each drill before reading the chapter's explanation of that bug type if you want an honest test, or after if you want practice applying it. Both work. Try every drill again a week later.
For the full repo experience, the repository has a bug-gym/ folder: two runnable TypeScript codebases (an orders API and a payment-webhook worker) with tickets, failing tests and ranked solutions. Run them with npm run test:01 or npm run test:02 from bug-gym/, with Node 22.18 or newer and nothing to install. The existing JS Gym focuses on async and races.
How this connects to the rest of the site
- JS Code Review: async JavaScript, race conditions and design critique in depth. L4 here is a summary of that section. Its Reviewing a Codebase chapter covers the first 15 minutes in a repo and how to present findings.
- Debugging: finding bugs from symptoms at runtime (logs, traces, the database). This section finds them from the code, before they happen.
- SD 6 · Break My Design: failure at the architecture level. L6 here is the same thinking at the code level.