Defending your solution: the follow-ups after the code runs
Working code is half the round. Then the interviewer asks: why is it correct, what's the complexity and why, can you do better, what if the input changes, and how would you test it? This page shows what each follow-up is testing, and the difference between a solution that works and one you can defend, with the same solution defended two ways.
- Sam My code passes the examples. Am I done?
- Priya Halfway. Then the interviewer asks: why is it correct, what's the complexity and why, can you do better, what if the input changes, and how would you test it? Those questions test what the code alone doesn't show.
- Priya Think of a bridge. Nobody hands one over with a photo of a single car crossing it. They hand over the load calculation. Passing the examples is the car crossing once. The follow-ups ask for the calculation.
- Sam Is that really what's scored?
- Priya Yes. The Tech Interview Handbook's rubric groups the signals into problem solving, technical competency, testing and communication. A strong candidate works out the complexity accurately, explains the trade-offs, finds and fixes their own bugs, and still has time for follow-ups.
- Sam What are the five follow-ups?
- Priya Why does it work: that's correctness, so name the invariant. What's the complexity: count it from what the code does. Can you do better: say whether a better bound is even possible. What if: say which part of your idea still holds. And how would you test it: pick inputs that would break a wrong version.
- Sam How do I know my answer is strong enough?
- Priya Use the proof ladder. Rung zero: "it passes the examples". Rung one: "it's a sliding window", just a label. Rung two: the invariant, "the window never holds a repeat". Rung three: the invariant, why each step keeps it, and what follows from it, like the complexity.
- Sam Show me.
- Priya Longest substring without repeating characters. Both candidates write the same correct code. Asked why it works, A says it passes the examples; B says the window never holds a repeat, because left jumps past the last copy. On complexity, A guesses; B says each index enters once and leaves once, so O of n. Can you do better? A says maybe dynamic programming; B says no, every character must be read. A stream? A would start over; B says it already works. And testing: B picks "abba", where an old repeat could pull the left edge backwards. A ends with one line of notes, B with six.
- Sam How do I practise?
- Priya The drill has five classic problems. Explain your solution, press next follow-up, and answer in under a minute. Then reveal a strong answer and compare.
- Priya Your turn. Your solution is O of n, and it has to read every character. "Can you do better?"
- Priya Not asymptotically, because every character must be read. Then offer the smaller trade-off, like a fixed array instead of a map.
- Sam The memory hook?
- Priya "Prove it, count it, beat it, bend it, break it." The invariant, the counted complexity, a better bound or a reason there isn't one, a changed input, and the tests that would break it.
- Sam Common mistakes?
- Priya Stopping at "it passes". Guessing the complexity. Jumping to a new approach with no reason. Rewriting for every "what if". Testing only the examples. And bluffing: "let me trace it" beats a confident wrong answer.
- Sam And the practice?
- Priya Pick a problem you've solved. Write one or two sentences for each of the five follow-ups. Drill them out loud, a minute each. Then check your invariant and tests against the pattern page.
1. Passing code isn't the whole score
Interviewers score more than whether the code runs. The rubric in the open-source Tech Interview Handbook groups the signals into four areas: problem solving, technical competency, testing and communication. A strong candidate, it says, "determined time and space complexity accurately", "explained trade-offs of each solution clearly and correctly", "identified and self-corrected bugs in code" and "had time to discuss follow up problems/extensions". Company rubrics use different labels, but they score much the same things.
That's why the follow-ups matter: each one tests a signal the code alone doesn't show. This page builds on the six-step problem-solving method: its last two steps, Review and Evaluate, are where these questions come.
2. The five follow-ups
| Follow-up | What it tests | Weak answer | Strong answer |
|---|---|---|---|
| "Why does it work?" | Correctness | "It passes the examples." | Names the invariant (what's always true) and why every step keeps it. |
| "What's the complexity?" | Analysis | "O(n), I think." | Counts it from the code: what moves, how many times, and what's stored. |
| "Can you do better?" | Optimisation and judgement | Starts a new idea without a reason. | Says whether a better bound is possible, and what any change would cost. |
| "What if…?" | Adaptability | Starts over. | Says which part of the idea still holds for sorted, streamed, huge or repeated input, and changes only the rest. |
| "How would you test it?" | Verification | "I think it works." | Picks inputs that would break a wrong version, traces one, and fixes what it finds. |
The proof ladder for a solution
Each thing you say about your solution sits on one of four rungs. Aim for rung 3 on every follow-up.
- 0Outcome. "It passes the examples." True, and proves very little.
- 1A label. "It's a sliding window." Names the idea without showing it applies.
- 2The invariant. "The window never contains a repeated character." Now there's something to check.
- 3The invariant, why each step keeps it, and what follows. "When a repeat enters, left jumps past its last position, so the window is valid again and no longer valid window is skipped; each index enters and leaves once, so O(n)."
3. One solution, defended twice
LeetCode 3, Longest substring without repeating characters. Both candidates write the same correct code. Then the interviewer asks the five follow-ups. Watch what reaches each set of notes.
def length_of_longest_substring(s: str) -> int:
last = {} # char -> last index seen
left = best = 0
for right, ch in enumerate(s):
if ch in last and last[ch] >= left:
left = last[ch] + 1 # jump past the repeat
last[ch] = right
best = max(best, right - left + 1)
return best
function lengthOfLongestSubstring(s: string): number {
const last = new Map<string, number>(); // char -> last index seen
let left = 0, best = 0;
for (let right = 0; right < s.length; right++) {
const seen = last.get(s[right]);
if (seen !== undefined && seen >= left) left = seen + 1; // jump past the repeat
last.set(s[right], right);
best = Math.max(best, right - left + 1);
}
return best;
}static int lengthOfLongestSubstring(String s) {
Map<Character, Integer> last = new HashMap<>(); // char -> last index seen
int left = 0, best = 0;
for (int right = 0; right < s.length(); right++) {
Integer seen = last.get(s.charAt(right));
if (seen != null && seen >= left) left = seen + 1; // jump past the repeat
last.put(s.charAt(right), right);
best = Math.max(best, right - left + 1);
}
return best;
}Candidate A · working code
Why"It passes all three examples."
Cost"O(n), it's one loop. Maybe O(n²) worst case?"
Better"Maybe with dynamic programming?"
What if"For a stream I'd have to rethink it."
Test"I'd run a few more strings."
Candidate B · defended code
Why"The window s[left..right] never holds a repeat. When a repeat enters, left jumps past its last position, so it's valid again, and no longer valid window is skipped."
Cost"O(n) time: each index enters the window once and left only moves forward. O(k) space for the map, k distinct characters."
Better"Not asymptotically: every character has to be read. For ASCII I'd swap the map for a 128-slot array."
What if"A stream works as is: I only keep last-seen positions and the best length."
Test"Empty string, one character, all the same, and “abba”: there an old 'a' could pull left backwards, which is why the check is last[ch] >= left."
4. Try it yourself
Follow-up drill
Pick a problem you know, explain your solution out loud in a minute, then press Next follow-up and answer in under 60 seconds. Then reveal a strong answer and compare.
5. What interviewers look for
Each follow-up adds a line to the interviewer's notes, or doesn't.
| Signal | Weak | Good | Strong |
|---|---|---|---|
| Correctness | "It passes the examples" | Names the pattern | States the invariant, and why every step keeps it |
| Complexity | A guess: "O(n), I think" | The right answer | Counted from the code: what moves, how many times, what's stored |
| Optimisation | Jumps to a new idea without a reason | Knows a faster or smaller version | Says whether a better bound is possible, and what any change would cost |
| Adaptability | Restarts from scratch | Patches the code | Says which part of the idea still holds and which part changes |
| Testing | "I think it works" | Runs the given examples | Picks cases that would catch a real bug, traces one, and fixes what it finds |
6. Remember it
How this hook works: what “Prove it, count it, beat it, bend it, break it” means
What the slogan means, phrase by phrase
- “Prove it”
- Why is it correct? Name the invariant and show each step keeps it.
- “count it”
- Time and space, counted from what the code actually does.
- “beat it”
- Can it be faster or smaller? Say if a lower bound stops you, and what a change would cost.
- “bend it”
- What if the input changes: sorted, streamed, huge, many queries?
- “break it”
- Which inputs would break a wrong version? Test those, out loud.
Why this picture fits: An engineer hands over a bridge with its load calculation, not just a photo of a car crossing it. The five follow-ups ask for that calculation.
The story → the concept
| The bridge | Defending a solution |
|---|---|
| A car crossing once | The code passing the examples |
| The load calculation | The invariant and the complexity |
| A lighter design | A better bound, or a trade-off |
| A new kind of traffic | A changed input |
| The stress test | Edge cases chosen to break it |
Watch it on an example
- "The window never holds a repeat" → prove it
- "Each index enters and leaves the window at most once: O(n)" → count it
- "Every character must be read, so O(n) is the floor" → beat it
- "A stream works too; I only keep last-seen positions" → bend it
- "abba: left must never move backwards" → break it
The trap it saves you from
Saying "done" the moment the examples pass, then guessing at every follow-up.
It still works when…
You can't prove it on the spot. Say what you believe the invariant is, then trace a tricky input to check it. Checking out loud is itself a signal.
7. Common mistakes
8. Practice exercise (25 minutes)
- Pick a problem you've solved (2 min). Any one from a pattern page, ideally one you could code from memory.
- Write the five answers (12 min). One or two sentences each: the invariant, the counted complexity, whether you can beat it, one "what if", and three test cases that would catch a bug.
- Drill it (8 min). Use the drill above: five random follow-ups, 60 seconds each, out loud.
- Check against the pattern page (3 min). Does your invariant match the one on the page? Did your tests include its edge cases?
9. Self-check quiz
Your code passes the examples. The interviewer asks "why does it work?" What's the strongest start?
How should you justify O(n) for the sliding window solution?
"Can you do better?" when your solution is already O(n) and must read every character. Best answer?
Which test is most likely to catch a real bug in this solution?
The interviewer asks "what if the string arrives as a stream?" What first?
10. Go deeper
| Resource | Time | Why |
|---|---|---|
| Coding interview rubrics (Tech Interview Handbook) | 10 min | What interviewers look for in each of the four areas, from weak to strong. |
| The problem-solving method | 5 min | The six steps that get you to working code; this page covers what comes after. |
| Sliding window | 45 min | The pattern behind the worked example, with its invariant and edge cases. |
| Behavioural 12a: Evidence quality | 20 min | The same idea in the behavioural round: structure isn't proof. |