12.13 — Code Review & Pair Programming

Opening scenario

Your onsite includes a “code review exercise”: the interviewer hands you a 200-line Swift PR and asks you to review it out loud in 30 minutes. They’re not testing whether you can find bugs — they’re testing how you communicate technical feedback to a teammate.

Context — what reviews really evaluate

Surface signalDeeper signal
Number of issues foundPrioritization (critical vs nit)
Technical depthCommunication tone
ConfidenceHumility — “I might be wrong, but…”
SpeedCare — did you read it twice?

The interviewer is a future teammate imagining you reviewing their PR. Be the reviewer you’d want.

The reviewer mindset

  1. Read the PR description first — even in interviews, ask if there is one. Context matters.
  2. Pass 1: skim the diff structure. Are file changes scoped? Naming sensible? Tests included?
  3. Pass 2: read line-by-line top to bottom. Note issues without typing immediately.
  4. Pass 3: prioritize. Group your notes into Blocking / Important / Nit.
  5. Verbalize in the order Blocking → Important → Nit, with rationale.

The comment categories

Every comment should self-tag:

  • blocking: must be fixed before merge (bug, security, breaks production).
  • important: should be fixed before merge (architectural concern, missing test).
  • nit: optional, style preference, won’t block merge.
  • question: I don’t understand; explain the intent.
  • praise: positive note — surface what’s good.

The labels make priority unambiguous. Junior reviewers leave 20 nit-level comments without tagging; the author can’t tell which to fix first.

What good reviews look like

// ❌ Bad comment:
// Why are you using force-unwrap here??

// ✅ Good comment:
// [blocking] Force-unwrap on line 42 will crash if `URL(string:)` returns nil.
// Suggest: `guard let url = URL(string: rawURL) else { throw URLError(.badURL) }`.
// Even if we control the input today, a future caller might not.
// ❌ Bad:
// This is wrong, use SwiftData instead.

// ✅ Good:
// [question] Is there a reason we're rolling our own caching here vs SwiftData?
// I might be missing context — happy to chat if there's a constraint I don't see.
// ❌ Bad: (silently approves without comment)

// ✅ Good:
// [praise] Love the protocol abstraction here — the test impl made the review easy.

Tone rules

  • Use “we” or “the code” — never “you”. “You forgot…” lands as accusation; “this missed…” or “we’d want…” lands as collaboration.
  • Frame suggestions as questions when you’re not sure: “Would it work to…?” beats “Do this”.
  • When you spot something serious, lead with the impact, then the fix.
  • Match formality to the team. Reviewer comments at FAANG are often more clipped; small teams can be more conversational. Read the existing PR culture.

What to review in iOS Swift code

A mental checklist while reading:

Correctness

  • Force-unwraps without invariant
  • Force-cast (as!) without runtime check
  • Threading: UIKit mutation off main thread
  • Retain cycles: closures capturing self strongly
  • Optional chaining producing silent nil instead of error

Concurrency

  • Task started without storage (can’t cancel)
  • Missing [weak self] in long-lived Tasks
  • Sendable violations under Swift 6 strict mode
  • @MainActor annotations missing on UIKit-touching code

Architecture

  • View doing data fetching (should be in VM/service)
  • Service knowing about UI types
  • Hardcoded dependencies (singletons referenced directly)
  • New class added to a feature module that doesn’t belong there

Testing

  • New logic has tests
  • Tests cover error paths, not just happy path
  • Mocks are reusable, not duplicated

Performance

  • Synchronous I/O on main thread
  • N+1 queries in Core Data / SwiftData
  • Image loading without downsampling
  • New view in a scroll list without Equatable

Style (low priority)

  • Naming follows team convention
  • File length / function length within team norms
  • Comment hygiene

If reviewing in an interview, voice the framework: “I’ll first scan for correctness issues, then concurrency, then architecture…”

PR hygiene (as the author)

When you open PRs, make them reviewable:

  • Title + description that explain the why, not just the what.
  • Scope: one logical change. Don’t bundle refactors with features.
  • Size: < 400 lines preferred; > 800 lines almost always means split it.
  • Self-review first: leave inline comments on tricky parts before requesting review.
  • Tests included in the same PR (not “tests in a follow-up”).
  • Screenshots/video for UI changes.

The single biggest reviewer time-saver is a PR description that lets the reviewer skip 80 % of the diff and focus on the 20 % that needs attention.

Pair programming in interviews

Pair sessions are similar to live coding but with a collaborator. Differences:

  • Talk to the partner, not at them. Pause for input.
  • Type at moderate speed — too fast feels like showing off, too slow loses momentum.
  • Ask before going down a rabbit hole: “Want me to add error handling now or keep moving on the happy path?”
  • Take suggestions gracefully: if the partner proposes a different approach, try it for 2 minutes before defending yours.
  • Switch driver/navigator if the format allows. Be a good navigator: ask before suggesting, point at lines not just describe them.

The interviewer is asking: would I want to pair with this person on a hard production bug at 9 PM on a Friday? Be that person.

Recovering from a wrong review

You confidently said “this is a memory leak” and the author replies “no, I added [weak self] on line 18 which you missed.” Recovery:

  • Acknowledge directly: “You’re right, I missed that — apologies.” No defensive softening.
  • Course-correct: “Disregard the memory point; the rest of my comments stand.”
  • Move on: don’t dwell or over-apologize. Two seconds, then next comment.

Senior reviewers are wrong all the time. The grace of being wrong well is itself a signal of seniority.

Common misconceptions

  1. “More comments = better review.” Inverted. Three high-quality blocking comments beat 30 nits.
  2. “Reviewers should never suggest code.” Suggest code freely for non-trivial changes — saves the author guessing what you mean. Use GitHub’s suggestion blocks.
  3. “You should approve only if you’d write the code that way.” No — approve if the code is correct, safe, and on-team-convention. Personal preference isn’t blocking.
  4. “Reviews are about gatekeeping.” Reviews are about collaboration + knowledge sharing. A good review teaches both author and reviewer.
  5. “Senior engineers leave fewer comments.” They leave more impactful comments, often fewer in count but with higher per-comment value.

Seasoned engineer’s take

Code review is the highest-leverage activity in a senior engineer’s day. A great review prevents one bug from shipping AND teaches the author a pattern they’ll apply for years. Treat every review as both quality gate and mentoring opportunity. The cost of a careful 30-min review is far less than the cost of fixing a bad merge.

TIP: Adopt the “two-pass minimum” rule personally. Never approve on first read of a non-trivial PR. The bugs hide on the second pass.

WARNING: Don’t review-block out of personal style preferences. Distinguish “this is incorrect” from “I’d write it differently” — only the first blocks. The second is a discussion, not a block.

Interview corner

Junior: “What do you look for first in a code review?” Correctness — force-unwraps, threading, error handling — then test coverage. Style comments come last and are usually optional.

Mid: “How do you handle disagreement during a code review?” I tag my own confidence: “I’m not certain, but…” for opinions, firm phrasing for facts. If the author pushes back with a reason I missed, I update. If we still disagree, we resolve over a quick call or escalate to a third reviewer — but I never block over a tie.

Senior: “What does a great code reviewer do that an average one doesn’t?” A great reviewer prioritizes ruthlessly — blocking comments come first, nits come last and tagged as such. They write comments that teach, not just correct: ‘this would crash if X happens; consider Y’ beats ‘don’t do this’. They surface what’s good, not just what’s wrong, so the author learns the pattern to replicate. They read the PR twice before commenting. And they recover gracefully when they’re wrong — acknowledging directly, no defensiveness. The result is a team where reviews are anticipated, not dreaded.

Red-flag answer: “I leave detailed comments on every line.” This is exhausting for the author and signals inability to prioritize.

Lab preview

Open the latest PR in a public Swift open-source project (Apple’s swift-package-manager, Alamofire, Vapor). Write a hypothetical review without submitting it. Self-grade against the categories above. Repeat weekly.


Next: 12.14 — Portfolio, GitHub & LinkedIn