DEV Community

Cover image for Turn a Pull Request Into a 10-Minute Technical Interview Drill
Karuha
Karuha

Posted on

Turn a Pull Request Into a 10-Minute Technical Interview Drill

The fastest way to make a technical answer sound generic is to rehearse it without a real change in front of you. Pick a pull request you can explain, spend 10 minutes turning its diff into a walkthrough, and you will have concrete decisions, risks, and verification steps to discuss instead of a memorized architecture speech.

This is not a trick for performing expertise you do not have. It is a way to surface work you already did: why the change exists, where it can fail, and what evidence would make you trust it.

Why use a PR instead of an interview prompt?

Interview prompts are intentionally underspecified. A real pull request is the opposite: it contains constraints. There are files, tests, callers, migrations, and review comments. That makes it a useful rehearsal artifact.

For a 45-minute technical interview, a strong answer usually needs four things:

Part What the interviewer can learn Evidence you can point to
Context Why the work mattered Issue, incident, or user path
Decision Why this approach won Constraints and rejected options
Safety How you controlled risk Tests, compatibility, rollout plan
Outcome What you checked afterward Metrics, logs, or manual verification

The mistake is reading the diff line by line. A reviewer can do that alone. Your job is to connect the changes to the system behavior.

A ten-minute rehearsal loop

Use this sequence once per PR. It is deliberately short enough to repeat.

  1. Minute 0–2 — name the before-and-after. Write one sentence: “Before, X happened when Y; now, Z.” If you cannot make that sentence concrete, you are not ready to explain the change.
  2. Minute 2–4 — choose the risk. Pick the one failure that would matter most: a stale write, an authorization bypass, a breaking API response, or a dropped background job. Do not list every theoretical risk.
  3. Minute 4–7 — narrate the control. Explain the code path that prevents or exposes that failure. Mention the test or observable signal that backs it up.
  4. Minute 7–10 — answer one follow-up. Ask yourself what you would change at 10× traffic, with an older client, or after a retry.

A PR walkthrough moves from changed files to a user-facing behavior, a risk, a control, and verification.

Generate the questions from a real diff

The script below is intentionally small. It reads the names of files changed against a base branch and produces follow-up prompts based on likely risk areas. It does not inspect source code or claim to understand your system. You supply the context; the script makes it harder to skip the important questions.

Save it as pr-walkthrough.mjs, then run:

git fetch origin main
node pr-walkthrough.mjs origin/main
Enter fullscreen mode Exit fullscreen mode
import { execFileSync } from "node:child_process";

const base = process.argv[2] ?? "origin/main";
let raw;
try {
  raw = execFileSync("git", ["diff", "--name-status", `${base}...HEAD`], {
    encoding: "utf8",
  });
} catch (err) {
  console.error(`Could not compare ${base} with HEAD.`);
  console.error("Fetch a base branch with shared history, then try again.");
  console.error("Example: git fetch --deepen=100 origin main");
  process.exit(err.status ?? 1);
}

const rules = [
  [/^(src|app|pages)\//, "Which user-facing behavior changes, and how would you verify it manually?"],
  [/(api|router|route|server)/i, "What is the request contract, and which old callers could break?"],
  [/(db|schema|migration|prisma|drizzle)/i, "Can old and new code run against this data shape at the same time?"],
  [/(auth|permission|role|token|session)/i, "Who is allowed to take this path, and how is that checked on the server?"],
  [/(test|spec)\./i, "Which failure would this test catch that a happy-path demo would miss?"],
  [/(queue|worker|job|cron)/i, "What happens on retry, duplicate delivery, or a partial failure?"],
];

const files = raw.trim().split("\n").filter(Boolean).map((line) => {
  const [status, path] = line.split("\t");
  return { status, path };
});

if (!files.length) {
  console.error(`No changes found against ${base}. Fetch the base branch or pass a different ref.`);
  process.exit(1);
}

const questions = new Map();
for (const file of files) {
  for (const [pattern, question] of rules) {
    if (pattern.test(file.path)) questions.set(question, (questions.get(question) ?? 0) + 1);
  }
}

console.log(`# PR walkthrough: ${files.length} changed file${files.length === 1 ? "" : "s"}`);
console.log("\n## Start with the change");
for (const { status, path } of files.slice(0, 12)) console.log(`- ${status}: ${path}`);
if (files.length > 12) console.log(`- …and ${files.length - 12} more`);

console.log("\n## Rehearse these follow-ups");
for (const [question, matches] of questions) console.log(`- (${matches} file${matches === 1 ? "" : "s"}) ${question}`);
console.log("- What did you deliberately leave unchanged, and why?");
console.log("- What observable signal would tell you the rollout is safe?");
Enter fullscreen mode Exit fullscreen mode

Here is what a useful result looks like for a change that touches an API route, a database migration, and tests:

# PR walkthrough: 4 changed files

## Rehearse these follow-ups
- (1 file) What is the request contract, and which old callers could break?
- (1 file) Can old and new code run against this data shape at the same time?
- (1 file) Which failure would this test catch that a happy-path demo would miss?
- What did you deliberately leave unchanged, and why?
- What observable signal would tell you the rollout is safe?
Enter fullscreen mode Exit fullscreen mode

That output is a prompt sheet, not a script you should recite. Answer every line with a detail visible in the PR. “We added a migration” is not enough; “the new column is nullable first, so the old worker can continue writing while the backfill runs” is an explanation a teammate can challenge productively.

Turn one change into a concise answer

Suppose the change adds an idempotency key to a payment endpoint. A vague answer sounds like this:

“I made the endpoint retry-safe and wrote tests.”

The rehearsal version has a shape:

“Retries from the client could create two charges when the response was lost. I stored a key plus a request fingerprint before calling the provider, so the same key and payload return the first result while a conflicting payload is rejected. The test starts two requests with the same key and asserts one provider call. In production, I would watch duplicate-charge support tickets and the rate of key conflicts; an unexpected rise in conflicts suggests a client bug rather than a successful retry.”

Notice the answer is still short. It establishes a cause, a control, a proof, and a signal. If the interviewer asks about multi-region writes or provider timeouts, you now have a real boundary to discuss instead of inventing one.

What to do when the PR is too large

Large diffs create bad rehearsal sessions because they invite a tour of unrelated files. Narrow the artifact before you practice:

  • Select one user journey, such as “checkout after a network retry.”
  • Select one invariant, such as “a completed order is charged exactly once.”
  • Select one proof: a test, a dashboard, or a manual reproduction.
  • Put the remaining changes in the “what I would cover next” bucket.

This is also a good way to answer “tell me about a challenging project” without wandering through three months of work. You can say which slice you are choosing and why it best demonstrates the trade-off.

Practice the follow-up, not just the opening

The best self-check is to ask a hostile-but-fair question after each answer:

If the interviewer asks… Do not say… Try explaining…
“Why not just retry?” “Retries are bad.” Which action is safe to repeat, which one is not, and where the deduplication record lives.
“How did you test that?” “I added unit tests.” The exact precondition, failure mode, and invariant the test asserted.
“What would you do differently?” “I would improve it.” The constraint that would justify a different design: scale, consistency, cost, or time to recover.

Record one run, then listen for two failure modes: unsupported claims (“it was more scalable”) and missing evidence (“we monitored it”). Replace either with a concrete number, test name, log field, or user behavior from the work.

If you want a structured place to repeat these sessions, aceround.app — an AI interview assistant can be useful for running a mock round. Bring the PR and your own evidence; treat any feedback as a prompt to sharpen the explanation, not as a substitute for understanding the change.

Sources and disclosure

  • The command interface used here follows the Git documentation for git diff.
  • AI assistance was used for copyediting. The workflow and code were reviewed and tested by the author.

Top comments (0)