To explain your coding solution in an interview, narrate a fixed sequence: restate the problem, confirm constraints, walk one small example by hand, name the brute-force approach and its complexity, propose something better, get agreement, then code while explaining intent rather than syntax. Most candidates who fail a technical interview solved the problem. They just never let the interviewer watch them think.
This is a skill, not a personality trait, and it is separable from problem-solving ability. Strong engineers fail interviews by going silent for eleven minutes. Weaker candidates pass by making their reasoning legible. The good news is that the fix is mechanical: a structure you can rehearse until it runs without conscious effort, which is exactly what you want when adrenaline is eating your working memory.
What the interviewer is actually grading
Almost nobody is scoring you on whether the code compiles. They are filling out a rubric with categories like problem-solving, coding, testing, and communication, and they have to write evidence in each box within 45 minutes. Every sentence you say is either evidence or silence. Google’s own interview guidance for candidates makes the same point in plainer language: explain your thinking, because the reasoning is the answer they are assessing.
That reframes the whole session. You are not solving a puzzle while someone watches. You are producing a narrated demonstration that happens to contain a solution.
| What you do | What the interviewer is really assessing | What to actually say |
|---|---|---|
| Ask clarifying questions | Whether you build the wrong thing confidently. This is the closest proxy they have to how you handle a vague ticket. | “Can the array contain negatives? Are there duplicates? Is exactly one valid answer guaranteed?” |
| State assumptions | Whether you know the difference between a decision and a guess. | “I’ll assume the input fits in memory. If it does not, I’d stream it, and the approach changes.” |
| Name the brute force first | Whether you understand the problem before optimizing it, and whether you can reason about cost. | “The obvious approach is nested loops, O(n squared) time and O(1) space. Let me see if I can trade space for time.” |
| Justify the data structure | Depth. Anyone can say “use a hash map.” Fewer can say why it is the right cost model. | “A dictionary gives average O(1) lookup, which is what turns the inner loop into a constant-time check.” |
| Confirm before coding | Collaboration. Whether you check in with a teammate before spending 20 minutes. | “That’s my plan. Anything you’d want me to handle differently before I write it?” |
| Narrate while coding | Whether they can follow you, and whether your code matches your stated plan. | “Now the main loop. For each value I compute the complement and check the map before inserting.” |
| Trace your own code | Testing instinct. Whether you find your own bugs or wait to be told. | “Let me run this on my example. i equals 0, value 2, complement 7, not in the map, insert 2.” |
| Discuss trade-offs | Seniority. Junior candidates finish. Senior candidates finish and then critique. | “If the input were sorted I’d use two pointers and drop to O(1) extra space.” |
The ten steps, in order
Step 1: Restate the problem and confirm the constraints
Say it back in your own words in two sentences, then ask about input size, value ranges, duplicates, empty input, and what to return when there is no answer. This takes 90 seconds and prevents the single most expensive failure mode, which is solving a different problem well.
Step 2: State your assumptions out loud
Anything you cannot confirm becomes a stated assumption, not a silent one. “I’ll assume ASCII, not full Unicode” is a fine engineering decision. Quietly assuming it and getting caught later looks like a gap.
Step 3: Walk one small example by hand
Pick an input of three or four elements and work the expected output manually. This does three things at once: it proves you understood the problem, it surfaces ambiguity the interviewer had not mentioned, and it gives you a test case for step 8. Write it in the editor so it stays visible.
Step 4: Name the brute force and its complexity first
Do this even when you already know the optimal answer. It tells the interviewer you have a baseline and are optimizing deliberately rather than pattern-matching. It also buys you goodwill if you run out of time, because a working slow solution beats a broken fast one.
Step 5: Propose the better approach and justify the data structure
The justification is the part that earns points. “Hash map” is a noun. “A hash map, because I need membership testing inside the loop and I want that to be constant time instead of linear” is reasoning. The Python wiki’s complexity table is worth internalizing for exactly this: dict get and set average O(1), list membership O(n). Knowing those two lines lets you explain most optimizations in one sentence.
Step 6: Get agreement before you write code
Ask directly. “Does that approach sound reasonable to you?” Interviewers usually have a target solution, and many will nudge you if you are heading somewhere painful. Not asking is how candidates spend 25 minutes implementing an approach the interviewer knew would not work.
Step 7: Narrate at the altitude of intent, not syntax
This is where most people get the dosage wrong. Do not read your code aloud (“open paren, i, comma”). Do not go silent either. Speak in intentions, one sentence per logical block: “I’m initializing the map outside the loop so it persists across iterations.” Roughly one sentence every 15 to 20 seconds keeps the interviewer with you without turning into narration noise.
Step 8: Trace your code on the example
Use the example from step 3 and step through it out loud, tracking variable values. Do not skip this because you are confident. Tracing is where you catch off-by-one errors yourself, which is a much better look than having them pointed out.
Step 9: State time and space complexity precisely, and why
“O(n) time because I touch each element once, and O(n) space in the worst case because the map can hold every element before I find a match.” Attach the reason to the bound. A bare letter with no justification reads as memorized.
Step 10: Discuss trade-offs and what you would change
Close with one or two concrete alternatives tied to different constraints. Sorted input, streaming input, thread safety, a memory ceiling, a need for the actual values rather than the indices. Thirty seconds here is often what separates a “hire” from a “leaning hire.”
Weak versus strong narration, scripted
Take the classic problem: given an array of integers and a target, return the indices of the two numbers that add to the target. Here are two candidates who both arrive at the same code.
The weak version, which is more common than you think
Interviewer: Given an array and a target, return the indices of two numbers that sum to the target.
Candidate: Okay. Yeah, I think I’ve seen something like this. Let me think.
[Forty seconds of silence. Starts typing.]
Candidate: …so I’ll do a loop, and then another loop inside… actually wait. Hold on.
[Deletes two lines. Ninety seconds of silence. Types a dictionary.]
Candidate: Okay, so I’m using a hash map because it’s faster.
Interviewer: Faster in what sense?
Candidate: Like, lookups are O(1), so the whole thing is O(n) instead of O(n squared). I think. It should be O(n).
Candidate: Yeah, I think that works. Done.
Notice what is wrong here, because it is not the code. The code is correct. The candidate never confirmed constraints, never named the baseline before abandoning it, hedged on complexity with “I think,” never tested, and never mentioned a trade-off. The interviewer has a working solution and almost no evidence about how this person thinks.
The strong version, same code
Candidate: Let me make sure I have it: I get an array of integers and a target, and I return the two indices whose values sum to the target, not the values themselves. Right?
Interviewer: Correct.
Candidate: A few constraints. Can the array contain negative numbers or duplicates? Is exactly one valid pair guaranteed, or should I handle zero or multiple answers? And can I use the same element twice?
Interviewer: Negatives yes, duplicates yes, exactly one answer, and no reusing an element.
Candidate: Good. So with nums equal to 2, 7, 11, 15 and target 9, the answer is indices 0 and 1. Let me put that in the editor as my test case.
Candidate: The brute-force approach is two nested loops checking every pair. That’s O(n squared) time, O(1) extra space, and it definitely works. I’d like to do better by trading space for time.
Candidate: The insight is that for each value, I already know what its partner has to be: target minus the current value. So the question becomes “have I already seen that number?” That is a membership test, and I want it to be constant time, which is why I want a dictionary from value to index rather than scanning a list. One pass, checking the map before inserting, so I never pair an element with itself.
Candidate: That’s my plan: O(n) time, O(n) space. Want me to code it, or would you rather I handle the no-solution case differently first?
Interviewer: Go ahead.
def two_sum(nums, target):
seen = {} # value -> index
for i, value in enumerate(nums):
complement = target - value
if complement in seen: # check before inserting
return [seen[complement], i]
seen[value] = i
return [] # no pair foundCandidate: Let me trace it. i is 0, value 2, complement 7, not in seen, so seen becomes 2 mapped to 0. i is 1, value 7, complement 2, which is in seen at index 0, so I return 0 and 1. That matches.
Candidate: Complexity: O(n) time because I visit each element once and every dictionary operation is average constant time. O(n) space because in the worst case, where the pair is at the very end, the map holds nearly every element. Worth noting the average-case caveat on hashing, though with integer keys it is not a practical concern.
Candidate: Two things I’d revisit. If the array were sorted, two pointers from both ends would give O(1) extra space, which matters if memory is tight. And if the problem asked for all pairs rather than one, I’d store a list of indices per value and handle duplicates explicitly.
Same eight lines of code. Radically different interview. The strong version produced evidence in every rubric box, and it did so in maybe two extra minutes.
How to handle being stuck without panicking
Silence reads as panic. Structured thinking out loud reads as competence, even when you are lost. Say where you are: “I know I need to avoid the nested loop, and I’m trying to work out what to precompute. Let me look at the example again and see what information I’m recomputing.”
Then work the ladder deliberately:
- Solve a smaller or simpler version. If a k-element version is hard, do the two-element case first and generalize.
- Write the brute force and get it running. A working slow answer is a real answer, and looking at it often reveals the redundant work.
- Ask what a different data structure would buy you, out loud: sorting, a hash map, a heap, a set, two pointers, prefix sums.
- Ask for a hint, specifically. “I’m deciding between sorting first and precomputing a lookup. Is one of those closer to what you have in mind?” That is a collaboration signal, not a surrender. A vague “I’m stuck, can you help?” is the version that costs you.
Talking about a bug you just found in your own code
Finding your own bug is a positive signal, so do not apologize your way through it. Name it flatly, explain the cause, then fix it: “My loop misses the case where the complement equals the current value, because I insert before I check. I’ll move the insert after the check.” Two sentences, no self-deprecation, no “sorry, I’m so bad at this.”
What hurts is the opposite reflex: noticing something is wrong and silently editing until it works. From the outside that looks like guessing.
Explaining complexity when you are not sure of the exact bound
Say what you know and how you would pin it down. “The outer loop is n. The inner work is bounded by the number of divisors, which I believe is smaller than n but I would not want to state the exact bound without checking. So it is worse than linear and much better than quadratic.” That is a professionally honest answer, and interviewers accept it.
What they do not accept is a confidently wrong number. Reason from the loop structure out loud instead of naming a letter and hoping. If a language-level detail is doing the work, say so, the way you would when explaining that a case-insensitive string comparison in C++ costs a linear pass, or that a per-element push into a vector amortizes to constant time when you read a file into a vector. The interviewer is judging whether you know where the cost lives.
Remote and virtual interview specifics
Most technical interviews are now a shared editor and a video call, which changes the mechanics in ways worth preparing for.
- You have no whiteboard, so use the editor as one. Type your clarifying answers, your example, and a three-line plan as comments before you write code. It makes your structure visible and gives you something to point at.
- Say the section you are working in. Without a hand to gesture with, “I’m now filling in the helper function above” replaces pointing.
- Assume latency. Leave a beat before responding, and if you talk over each other, stop and let them finish. Interrupting reads worse on video than in person.
- You cannot read the room, so ask. “Does that make sense so far?” every few minutes replaces the nod you would normally see.
- Narrate more, not less. On video, ten seconds of typing without speech feels much longer to the interviewer than it does to you.
- Test your setup an hour early. Camera, mic, the specific coding platform, and a second device on a different network as a fallback.
Use the same structure for projects and system design
The framework generalizes, which is why it is worth drilling. For a past project, the sequence becomes: context and constraints, the options you considered, why you chose one, what it cost, and what you would do differently. That last part is not humility theater. It is the strongest seniority signal available in a behavioral answer.
For system design it becomes: clarify requirements and scale, state assumptions about traffic and data volume, sketch the simplest thing that works, name its bottleneck, then evolve it one bottleneck at a time while saying what each change costs. Same shape as the coding question: baseline, critique, improve, justify.
Language-level design questions follow the pattern too. If someone asks why you would overload an operator in C++ or how you would handle failed writes when you write to a file, the winning answer is not a recital. It is a trade-off stated in one sentence, then the reasoning behind it.
Common mistakes that sink strong candidates
- Coding first, clarifying later. Costs the whole interview when the assumption was wrong.
- Reading code aloud instead of explaining intent. Sounds like narration but conveys nothing.
- Jumping straight to the optimal answer you memorized. Interviewers hear pattern-matching, then probe, and the probe is where it falls apart.
- Never testing. Announcing “done” without tracing an example undercuts everything before it.
- Arguing instead of investigating. When the interviewer questions something, check it rather than defending it.
- Apologizing continuously. It converts a small stumble into a story about low confidence.
- Running out of time in silence. If you are at 40 minutes with no code, say so and write the brute force.
Frequently asked questions
Should I ask questions, or will that make me look like I do not know the answer?
Ask. Clarifying questions are scored positively in nearly every technical rubric, because ambiguous requirements are the normal condition of the job. Two or three targeted questions about input size, edge cases and expected output signal engineering maturity. Asking twelve questions to avoid starting is a different problem.
What if I have seen the problem before?
Say so, briefly, and then still show the reasoning. “I’ve seen this pattern, so let me explain why the approach works rather than just writing it.” Pretending to discover it is transparent and interviewers dislike it. Volunteering it and then demonstrating real understanding turns a recognition advantage into a credibility one.
How much should I talk during a coding interview?
Aim for a sentence every 15 to 20 seconds while coding, and full explanation during planning. If the interviewer has to ask what you are doing, you are too quiet. If they cannot get a word in or you are reading syntax aloud, you are too loud. Silence during a genuinely hard think is fine if you flag it: “Give me twenty seconds on this.”
Is pseudocode acceptable?
Yes for planning, no as a final answer unless the interviewer says otherwise. A three or four line plan in comments is the ideal use: it shows structure, keeps you oriented, and gives you something to check the finished code against. Then write real, running code in a real language.
What if I disagree with the interviewer?
Disagree with evidence, not with tone. “I think that case is handled, let me trace it and check” is the right move, and if you turn out to be right you have gained more than the point. If you are wrong, you found out in ten seconds. Flat refusal to reconsider is one of the fastest ways to fail an otherwise clean interview.
Wrapping up
Explaining your coding solution in an interview is a rehearsed sequence, not a talent: clarify, assume out loud, example, brute force with its cost, better approach with justification, confirm, narrate intent, trace, state complexity with reasons, then trade-offs. Run that same script on every practice problem until it is automatic, because under pressure you will only do what you have already made automatic.
If you have limited prep time, spend it unevenly. Ten problems solved out loud and recorded will move your outcomes more than fifty solved in your head. And if you are also studying a framework for the same job hunt, keep the two efforts separate. Reading a current Vue.js book teaches you the technology. Talking through problems out loud teaches you to pass the interview that gets you paid to use it.

