5 exercises — choose the best-structured answer to common Go Developer interview questions. Focus on precise vocabulary, correct use of technical terms, and demonstrating real experience.
Structure for Go interview answers
Name the concurrency primitive: goroutine, channel, select, WaitGroup, Mutex — be specific about which and why
Explain channel direction: describe buffered vs unbuffered trade-offs and the happens-before guarantee
Cite select patterns: fan-out/fan-in, semaphore, done channel broadcast — use the correct vocabulary
0 / 5 completed
1 / 5
The interviewer asks: "What is the difference between goroutines and OS threads, and why does Go use goroutines?" Which answer best explains Go's concurrency model?
Option B is strongest: it names the M:N scheduling model precisely, gives specific numbers (2 KB goroutine stack vs 1–8 MB OS thread), explains cooperative scheduling and the work-stealing algorithm, describes the runtime's syscall handling (moving blocked goroutines to separate threads), and honestly states the trade-off for CPU-bound work. Key structure: M:N model → stack size comparison → cooperative scheduler mechanics → syscall handling → trade-offs. Option C is accurate but misses the M:N terminology and syscall isolation mechanism. Option D covers the stack size difference but does not explain the scheduler or the M:N model.
2 / 5
The interviewer asks: "Can you explain buffered vs unbuffered channels, and when you would use each?" Which answer best demonstrates channel pattern knowledge?
Option B is strongest: it gives the formal happens-before guarantee for unbuffered channels, explains the decoupling property of buffered channels, lists specific patterns for each (handoff/fan-out vs semaphore/work-queue/bursty producer), names the critical pitfall (full buffer still blocks — back-pressure needed), and explains why closing a done channel is superior to sending cancellation signals (broadcast semantics). Key structure: unbuffered = synchronisation point → buffered = decoupling with capacity → use-case mapping → full-buffer pitfall → done channel broadcast semantics. Option C covers semaphore correctly but misses back-pressure and done channel. Option D names patterns without explaining when to choose each.
3 / 5
The interviewer asks: "How does the context package work, and what are the rules for using it correctly?" Which answer best explains Go's context conventions?
Option B is strongest: it covers all three constructors with the critical rule that cancel must always be called even on success (resource cleanup), lists all four usage rules (first param, no struct storage, defer cancel, check Done), gives concrete use cases (HTTP abandonment, DB timeout, goroutine tree shutdown), and explains the WithValue constraint with a specific valid use case (trace IDs) and an explicit antipattern (function parameters). Key structure: three constructors + cancel always → four rules → concrete use cases → WithValue constraint. Option C is accurate but misses the struct storage antipattern and WithValue guidance. Option D only covers the timeout use case and the first-parameter convention.
4 / 5
The interviewer asks: "How does Go's error handling work, and how do errors.Is and errors.As differ from simple equality checks?" Which answer best explains Go's error wrapping model?
Option B is strongest: it explains why errors.Is is needed (wrapping creates a new value, breaking ==), explains errors.As with a concrete example of when structured data matters (os.PathError with path/syscall info), gives the design decision rule for when to use each error style, and correctly scopes panic to unrecoverable programming errors rather than domain errors. Key structure: errors are values → %w creates chain → errors.Is for sentinel comparison through chain → errors.As for typed extraction → design rules for sentinel vs structured → panic only for programming errors. Option C explains the mechanics well but misses the design rule for when to choose sentinel vs structured errors. Option D is accurate but too brief — it does not explain the os.PathError use case or the panic scoping rule.
5 / 5
The interviewer asks: "How do Go modules work, and what is the purpose of the go.work file?" Which answer best explains Go's module system?
Option B is strongest: it explains MVS (minimum version selection) and why it produces reproducible builds without a lock file — a key Go design decision interviewers ask about — explains go.sum's purpose as tamper detection, precisely describes go.work's use case (simultaneous development across multiple modules without publish/replace cycles), compares go.work to the replace directive (noting both purpose and the scoping difference), and gives the practical rule that go.work should not be committed. Key structure: module = packages + go.mod → MVS for reproducible builds → go.sum for tamper detection → go.work for multi-module local development → replace directive comparison → go.work not for shared repos. Option C explains MVS correctly but does not explain go.work's advantage over replace. Option D is accurate but surface-level — it does not explain MVS or the go.work vs replace distinction.