Lakshya

Software Engineering · Chapter 5 of 31

Debugging, and the coding round

What the coding interview actually measures, and the method that transfers to production.

5 min read0 diagramsAll 31 chapters

Coding rounds are frequently described as unrepresentative, and they partly are — but what they measure well is whether you can make progress on an unfamiliar problem while thinking out loud, which is most of the job.

How to run a coding round

  • Restate the problem and confirm. Cheap, and it catches the misunderstanding that would otherwise cost you the whole round.
  • Say your approach before writing. Silence is the most common way strong candidates fail — the interviewer cannot give credit for reasoning they cannot hear, or redirect you before you have spent fifteen minutes.
  • Start with something that works. Brute force, stated as such, beats an elegant thing that does not compile. Then improve it and say what you improved.
  • Test it yourself, out loud, on the empty case, the single-element case and one real case, before being asked.
  • If stuck, narrate the stuckness. ‘I think this needs a different data structure because lookup is O(n) here’ keeps you scored while you think.

Debugging as a method, which transfers everywhere

The habit that separates people is refusing to guess. Form a hypothesis, decide what observation would falsify it, and make that observation — rather than changing something and seeing if it helps, which is how you fix symptoms and introduce two new bugs.

Bisect aggressively: in time (when did this last work), in space (which layer), and in input (what is the smallest case that reproduces it). And when identical comparators exist — another host, another environment, another user — diff them mechanically rather than reasoning about what might differ. That single move resolves more incidents than any amount of insight.

The method, when the obvious approach has failed

Every engineer can debug a problem with a stack trace pointing at the line. The round exists to find out what you do when there is no stack trace, the failure is intermittent, and the system is one you did not write.

  • Establish what changed. Systems that worked and then did not almost always had something change: a deploy, a config flip, a dependency version, a data volume crossing a threshold, a certificate expiring, a leap in traffic. “It started at 14:20” plus a deployment log is often the entire investigation.
  • Make it reproducible before you make it fixed. A bug you cannot reproduce is a bug you cannot confirm you fixed — you can only observe that it stopped happening, which is not the same thing and is how bugs come back.
  • Bisect, do not stare. Halve the system: is it the client or the server? Before or after the proxy? In the write path or the read path? Each halving is worth an hour of reading code.
  • Read the error message completely. Genuinely — including the parts that look like boilerplate, and including the second exception in a chained trace, which is usually the real one.
  • Believe the machine. When the evidence contradicts your model of the system, the model is wrong. Time spent explaining away the evidence is time lost.

The failures that only look mysterious

SymptomUsually isHow to confirm quickly
Fails in production, not locallyConfig, data volume, or concurrency — the three things a laptop cannot reproduceDiff the config. Then check whether prod data is 1000× larger or has a shape yours does not
Intermittent, roughly 1 in NA race, or one bad instance out of NPin the request to one instance. If it becomes 100% or 0%, it is the instance, not the code
Slow, but only sometimesA cold cache, a lock, or the tail of a distribution you are averaging awayLook at p99 rather than the mean. An average hides exactly the thing you are chasing
Started overnight with no deployA certificate, a token, a scheduled job, a log or disk filling, or an upstream changeCheck expiries and disk first — they are cheap to rule out and are the cause surprisingly often
Works on retryAt-least-once delivery meeting non-idempotent code, or a timeout shorter than the operationCompare the client timeout to the actual server duration. They are frequently mismatched

What the coding round is really scoring

The visible test is whether the code runs. The actual scoring is mostly about how you behave when it does not.

State your approach before writing. Thirty seconds of ‘I am going to use a hash map keyed on X, iterate once, and handle the empty case separately’ makes everything you type afterwards legible. Silence forces the interviewer to reverse-engineer your intent from syntax.

Say the complexity out loud, unprompted, and say it in both time and space. If you are unsure, reason about it aloud — the reasoning scores, not the answer.

Name the edge cases before you are asked: empty input, one element, duplicates, the maximum size, and the type you were not expecting. Enumerating them is a two-line habit and it is one of the strongest available signals.

When stuck, narrate the stuck-ness. ‘I think the issue is my index is off by one at the boundary; let me trace a three-element case’ is a strong signal. Going quiet for four minutes is the weakest thing you can do, and it is what most people do.

And test with the smallest input that could fail, not the example from the prompt. The prompt's example is chosen to work.

Check yourself

What do you establish first on a production incident?What changed. Deploy, config, dependency, data volume, certificate, traffic. A timestamp plus a deploy log is often the whole investigation.
A bug is intermittent at roughly one in five. What is the first hypothesis?One bad instance out of five, before a race condition. Pin requests to a single instance — if the rate goes to 100% or 0%, it is the instance.
Why is reproducing before fixing important?Otherwise you cannot confirm you fixed it — only that it stopped occurring, which is how bugs return.
What is the weakest thing to do in a coding round?Go quiet while stuck. Narrating the stuck-ness scores; silence forces the interviewer to guess your intent from syntax.
← Code, review and the 9%What actually changes from mid to senior to staff →