Code review interview questions
Answer code review questions with evidence.
A code review interview asks you to inspect an unfamiliar change, identify the issues that matter, and explain your judgment like a teammate. You may review a short pull request, a deliberately flawed function, or one change inside a larger repository. This guide gives you ten common questions, a repeatable 45-minute method, one worked TypeScript example, and answer language for evidence that is incomplete.
Review packet / 03 findings
- P1False success after failed writebehavior · line 08
- P1Missing input boundarycorrectness · line 03
- P2Inconsistent email normalizationdata contract · lines 04–06
Two blockers, one contract question, zero style-only comments.
What the format evaluates
The deliverable is a useful conversation.
In a code review interview, you may receive a short pull request, a deliberately flawed function, or a repository with a proposed change. You are usually asked to read it, leave comments, and discuss your reasoning. Some interviews are written and asynchronous. Others ask you to talk through the review with an interviewer. The exact format varies, but the strongest answers make the same moves: establish intent, trace behavior, test edge cases, rank findings, and communicate without overclaiming.
Interviewers can see whether you distinguish a blocker from a preference. They can also see whether you ask for missing context, connect feedback to a concrete outcome, and make the next change easier for the author. They are not only checking whether you can spot a bug. They are checking how you read, what you prioritize, how you handle uncertainty, and whether another engineer could act on your comments. A long list of generic best practices does not show that judgment.
A 45-minute preparation method
Make five passes, each with one job.
Re-reading the same file without a question burns time. These passes move from contract to evidence to communication, so your final comments reflect priorities rather than the order in which you noticed things.
- 01
0–5 min
Establish the contract
What must this code do?Read the prompt, tests, types, and call sites before judging style. Write down the expected inputs, outputs, failure behavior, and any constraints the interviewer gave you.
- 02
5–15 min
Trace one complete path
Where can behavior go wrong?Follow data from entry to return value. Mark unchecked assumptions, state changes, external calls, and branches that change the result. This is where correctness findings usually emerge.
- 03
15–25 min
Test the boundaries
Which case would disprove this?Check empty, missing, duplicate, oversized, concurrent, and failed-dependency cases that are relevant to the code. Prefer one concrete counterexample over a broad claim that the code is unsafe.
- 04
25–35 min
Rank the findings
What should change first?Separate behavior-changing issues from maintainability notes. Choose the two or three findings with the clearest impact, then keep optional polish in reserve.
- 05
35–45 min
Prepare the conversation
How would you say this to a teammate?State the observation, show the triggering case, explain the consequence, and propose a bounded change. Name what you would verify instead of pretending the snippet proves production impact.
Worked code review example
Turn lines of code into ranked feedback.
Assume this route should create one invite for an authenticated user and report whether the write succeeded. The snippet is intentionally small. The goal is to show how to move from observation to a review comment an author can act on.
01 export async function invite(request: Request) {
02 const user = await currentUser(request)
03 const email = user.email
04 const existing = await findInvite(email)
05 if (existing) return { status: 409 }
06 const normalized = email.toLowerCase()
07
08 saveInvite({ email: normalized })
09
10 return { status: 201 }
11 }Example review comments
State the evidence before the recommendation.
Each comment below contains four parts: the observed line, a plausible consequence, a question that checks the contract, and a bounded next step. That structure keeps feedback specific without pretending the snippet proves more than it does.
The input contract is not enforced
Line 02 accepts a missing user and line 03 reads `user.email` immediately.
"Could this path receive an unauthenticated request? If yes, I would return a clear client error before reading the email. A focused test for a missing user would protect that contract."
It begins with an observable failure path and asks a scope question before prescribing a fix.
A failed write can be reported as success
Line 08 does not await `saveInvite`, but line 10 returns a success response.
"Should the response confirm that the invite was persisted? If so, I would await this call and map its failure to the route’s error contract so callers do not receive a false success."
It connects one exact line to customer-visible behavior and a testable correction.
Normalization happens after the duplicate check
Line 04 checks the raw email while line 06 lowercases it.
"I would normalize once before the lookup and write. Otherwise `Dev@Example.com` and `dev@example.com` may take different paths depending on the store. Is email matching intended to be case-insensitive here?"
It explains the counterexample and leaves room for the system’s actual identity rules.
How to prioritize
Use impact and evidence, not confidence theater.
Severity labels vary between teams. Your reasoning matters more than the label. Put findings in the order you would want the author to address them.
Can it return the wrong result, lose data, or fail without recovery?
Lead with a concrete triggering case. If the consequence depends on deployment or traffic you cannot see, say what you would verify.
Does the change disagree with a type, test, caller, or documented rule?
A visible contract gives you stronger footing than a personal convention. Cite the file or test that establishes it.
Will this make the next correct change harder?
Explain the future edit that becomes risky or repetitive. Avoid asking for a refactor only because you prefer another shape.
Is this optional feedback that should not block the change?
Label minor naming, formatting, or local simplification as optional. A review is clearer when preference does not compete with correctness.
Code review interview questions and answers
Prepare to explain the review, not recite it.
The discussion often matters as much as the written comments. These example answers use the worked invite route above, so each claim has a visible source. Adapt the structure to your exercise: name what you observed, explain why it matters, state what you would verify, and choose the next action. Do not memorize the wording. Interviewers can change the code, but the reasoning pattern still holds.
What is a code review interview?
It is a structured exercise in reading, prioritization, and technical communication. You inspect a change, identify evidence-backed concerns, and explain what should happen next. The interviewer is evaluating your reasoning, not the number of comments you produce. A useful review distinguishes behavior-changing issues from questions, maintainability notes, and optional polish.
How do you review unfamiliar code under time pressure?
I begin with the prompt, types, tests, and call sites so I can write down the intended inputs, outputs, and failure behavior. Then I trace one complete path before exploring edge cases. That order keeps me from reviewing style before I understand the contract. I reserve the final minutes to rank findings and rewrite each comment so the author can act on it.
What did you look for first?
I established the behavior contract, then traced one complete path. In the example, the route should create one invite for an authenticated user and report whether the write succeeded. That contract led me to the missing-user path and the unawaited write before I considered naming or refactoring. Starting with observable outcomes gave me a basis for ranking the findings.
How did you decide severity?
I ranked findings by the strength of the evidence and the consequence in this code path. A missing user can cause a direct failure, and an unawaited write can return success before persistence succeeds. Those behavior-changing paths came before the normalization question. I would state that severity labels vary by team, then explain the ordering instead of defending a label as universal.
What kinds of issues should you look for?
I look first for incorrect results, lost data, unsafe state changes, missing authorization, and failures that are hidden from callers. Then I compare the change with visible contracts in types, tests, configuration, and call sites. After correctness, I consider maintainability and performance when the code provides direct evidence. Naming and formatting stay optional unless they make the behavior genuinely hard to understand.
How do you write a useful review comment?
I use four parts: the exact observation, a triggering case, the plausible consequence, and a bounded next step or question. For line 08, I would say that `saveInvite` is not awaited, ask whether the response should confirm persistence, and suggest awaiting the call plus testing the failure path. That gives the author evidence and a direction without pretending I know every system constraint.
What would you test?
I would add the smallest test that reproduces each disputed behavior: a missing user, a rejected persistence call, and differently cased versions of the same email. I would start with the two behavior-changing paths because they affect whether the route can return the correct result. The email case belongs after the identity rule is confirmed. These tests protect the fix and make the intended contract visible to the next reviewer.
Would you approve this change?
Not yet. I would ask for the missing-user path and persistence failure to be resolved or explicitly accepted because both can change the route's result. I would keep normalization as a contract question until the repository shows whether email identity is case-insensitive. That answer names the blocking evidence, separates it from uncertainty, and gives the author a clear path back to approval.
How do you handle disagreement with the author?
I return to the shared contract and the concrete case. If a test, type, caller, or documented rule supports the concern, I cite it. If the disagreement is about an unstated design choice, I ask what constraint I am missing and mark the comment as a question rather than a defect. The goal is to reach the correct change, not to win the review or defend my first reading.
What are you least certain about?
I cannot infer the authentication boundary, storage guarantees, or email identity rules from this function alone. The comments therefore describe plausible failure paths, not proven production incidents. I would inspect the route's caller, the persistence interface, nearby tests, and the repository's error conventions before widening the claim. Naming that uncertainty shows where the review should go next without weakening the evidence already present.
Practice with repository evidence
Bring a route, not a script.
Practice the method on a real repository by choosing one change boundary: an API route, command handler, persistence adapter, or pull request discussion. Identify the contract, trace one behavior, choose the two findings you would raise first, and note the files that support each claim.
RepoAtlas can turn a public GitHub repository or permitted ZIP into a Candidate Brief with a ranked reading path and file-backed talking points. Use the architecture, source-backed commands, test inventory, and structural risk signals to choose what to inspect first. RepoAtlas reads files as text and does not execute the code or call AI, so runtime behavior, author intent, and business impact still require verification. Inspect the public FastAPI Candidate Brief to see those evidence limits on an exact repository commit.
Continue with the method: learn how to trace an unfamiliar repository.
Compare preparation styles: choose between structured preparation and ad hoc browsing.