25 Go interview questions
Structure the Go interview loop around evidence, not recall. Start with a short screen on recent Go work, production responsibilities, and comfort with services, databases, and cloud tooling. Use a focused coding round to test readable Go, errors, table-driven tests, concurrency basics, and debugging under time pressure. Add a practical exercise or pair session using real tools such as Go 1.22+, modules, context, slog, pprof, the race detector, and govulncheck. For mid and senior candidates, include a design round on APIs, data flow, backpressure, observability, and deployment trade-offs. Finish with a collaboration round covering code review, incident response, ownership, and how they make technical decisions with product constraints.
Junior Go questions
Fundamentals, learning speed and how they debug.
01Tell me about a Go program you changed recently. What did you change, how did you test it, and what surprised you?
Listen for: A strong junior can describe a concrete change, not just a tutorial. Listen for use of go test, small commits, reading existing code before editing, and checking behavior manually or through logs. They should be honest about uncertainty and able to explain how they found answers without guessing.
Red flag: They describe only syntax learning and cannot explain how they verified the change worked.
02You call a third-party HTTP API from a handler and it sometimes hangs. What would you change first?
Listen for: Look for context timeouts, an http.Client with sensible Timeout or transport settings, checking response status, closing the body, and returning useful errors. A good answer mentions avoiding the default client for production dependencies and adding a test with httptest.Server or a fake RoundTripper.
Red flag: They suggest adding a goroutine or retry loop without a timeout or cancellation path.
03How would you write tests for a function that parses CSV rows into domain structs and reports bad rows?
Listen for: Good signals include table-driven tests, named cases, checking both valid output and error details, edge cases for empty fields and malformed input, and keeping parsing separate from file I/O. They may mention subtests, cmp-style comparisons, and testing error behavior without matching fragile full strings.
Red flag: They only test the happy path or say manual testing is enough for parsing logic.
04You see `fatal error: concurrent map writes` in logs. How do you approach the bug?
Listen for: They should recognize that ordinary maps are not safe for concurrent writes. Listen for reproducing with `go test -race`, identifying shared ownership, and fixing with a mutex, channel ownership, sync.Map when appropriate, or restructuring state. Good candidates discuss the smallest safe fix and adding a regression test.
Red flag: They think maps are safe because goroutines are lightweight or propose ignoring the panic.
05What makes a Go error useful to the caller? Give an example of a bad error and an improved one.
Listen for: Look for context in the message, preserving the original error with `%w`, avoiding log-and-return duplication, and using sentinel errors or typed errors only when callers need branching. A good junior understands that errors are part of the API and should help decide retry, user feedback, or debugging.
Red flag: They return `nil` on failure to keep the program running or rely only on logging.
06A code review points out that your function has too many responsibilities. How would you respond and refactor it?
Listen for: Strong answers show receptiveness and concrete decomposition: separate validation, transformation, I/O, and side effects. Listen for keeping behavior unchanged with tests first, choosing names that reflect domain intent, and avoiding over-engineering. They should treat review as improving maintainability, not as personal criticism.
Red flag: They argue that smaller functions are always unnecessary unless performance is affected.
Mid-level Go questions
Independent delivery, trade-offs and code quality.
07Design a Go package interface for sending notifications through email and SMS. What do you expose and what do you hide?
Listen for: A strong answer keeps interfaces small and owned by the consumer, separates domain commands from provider SDK details, and returns errors with actionable context. Listen for context.Context, dependency injection for tests, avoiding global clients, and choosing package boundaries that prevent transport concerns from leaking into business logic.
Red flag: They create one large interface mirroring a vendor SDK and require callers to know provider-specific details.
08A service has rising memory usage after a deployment. Walk me through your investigation in Go.
Listen for: Listen for checking dashboards and release diff first, then using pprof heap profiles, goroutine profiles, runtime metrics, and load reproduction. Strong candidates distinguish leaks from cache growth, mention unclosed response bodies, retained slices, timers, and goroutine leaks, and propose safe mitigation before a perfect root cause.
Red flag: They jump directly to increasing memory limits without profiling or forming a hypothesis.
09How do you decide between channels, mutexes, and atomics in production Go code?
Listen for: Good answers use channels for ownership transfer, cancellation, or pipelines; mutexes for protecting shared state; and atomics for simple counters or carefully documented lock-free paths. They should favor clarity, use the race detector, avoid cleverness, and discuss shutdown behavior and backpressure rather than treating channels as the default.
Red flag: They say idiomatic Go means using channels for all synchronization.
10You need to add retries around a database operation. What conditions must be true before you retry?
Listen for: Look for idempotency, transaction boundaries, classifying transient versus permanent errors, context deadlines, jittered backoff, maximum attempts, and observability. Strong candidates consider duplicate side effects, unique constraints, optimistic concurrency, and whether the caller should control the retry policy instead of hiding it deep in a package.
Red flag: They retry every error indefinitely because databases are sometimes flaky.
11How would you structure configuration for a Go service deployed to Kubernetes and run locally by developers?
Listen for: Strong candidates separate config loading from use, validate at startup, avoid package globals, and support environment variables, files, or flags with clear precedence. They mention secrets coming from the platform, safe defaults for local development, redacting logs, and tests for validation rather than relying on runtime surprises.
Red flag: They read environment variables throughout the codebase whenever a value is needed.
12A handler sometimes returns partial JSON and then an error is logged. What Go-specific issues would you check?
Listen for: Listen for understanding that once headers/body are written, status may be committed. Strong answers mention validating and preparing the response before writing, encoding into a buffer when needed, middleware ordering, panics during streaming, client disconnects via context, and not mixing multiple response-writing paths.
Red flag: They try to fix it by writing another status code after the body has started.
13What does a good migration from an older Go service to Go modules and current tooling look like?
Listen for: Look for incremental steps: pinning module versions, running tests under a supported Go toolchain, replacing GOPATH assumptions, updating CI, scanning with govulncheck, and handling deprecated dependencies. Strong candidates mention reproducible builds, module graph review, minimal behavior changes, and communication around deployment risk.
Red flag: They update every dependency at once and rely on the compiler to catch all issues.
Senior Go questions
Judgement, architecture and raising the team's bar.
14You inherit a Go monolith with slow delivery and uneven code quality. What do you assess in the first month?
Listen for: Strong answers balance technical and organizational discovery: build and test reliability, ownership boundaries, incident history, coupling hotspots, deployment process, data model risk, and team pain. Listen for measuring before rewriting, improving feedback loops, and choosing a small high-leverage slice rather than announcing a broad rewrite.
Red flag: They immediately propose splitting everything into microservices before understanding the domain.
15How do you set standards for errors, logging, and tracing across multiple Go services?
Listen for: Look for practical conventions: wrapping errors at boundaries, structured logs with slog or a similar library, correlation IDs, OpenTelemetry spans, and clear rules on where to log versus return. Senior candidates consider PII redaction, sampling, operational usefulness, and migration paths for existing services.
Red flag: They mandate a custom framework without explaining how teams will adopt or maintain it.
16A team overuses interfaces and mocks in Go tests. How would you guide them toward better design?
Listen for: Strong answers distinguish useful seams from premature abstraction. Listen for consumer-defined interfaces, fakes for external systems, integration tests with containers or local emulators where valuable, and testing behavior rather than implementation. They should coach through examples and reviews, not impose a blanket ban on mocks.
Red flag: They say all interfaces are bad or all dependencies must always be mocked.
17How would you evaluate whether to introduce generics into an existing Go codebase?
Listen for: A senior answer uses generics where they remove real duplication without obscuring domain behavior, such as typed collections, result helpers, or reusable algorithms. Listen for API stability, readability, compile-time clarity, constraints design, benchmark evidence when performance is claimed, and avoiding generic abstractions that hide simple business logic.
Red flag: They treat generics as either forbidden or automatically better than explicit code.
18Describe how you would make a Go service resilient to downstream latency without creating hidden failure modes.
Listen for: Look for context deadlines, bounded concurrency, circuit breaking where justified, bulkheads, backpressure, queues only with clear durability semantics, and fallbacks tied to product requirements. Strong candidates consider observability, load shedding, retry budgets, testing with injected latency, and avoiding retry storms.
Red flag: They add aggressive retries and goroutines around every slow call without limiting concurrency.
19How do you lead a production incident involving a suspected Go runtime or concurrency issue?
Listen for: Strong answers separate coordination from investigation: stabilize first, assign roles, capture profiles and logs before restarting when safe, use the race detector in reproduction, inspect goroutine dumps, and communicate impact clearly. They also plan follow-up actions such as regression tests, runbook updates, and code ownership fixes.
Red flag: They focus only on debugging code and ignore communication, mitigation, and follow-up.
20When reviewing a Go API client library for internal teams, what design issues do you look for?
Listen for: Listen for stable, small public surface area; context-aware methods; explicit timeouts; clear retry behavior; testable transports; semantic versioning; and error types only where callers need decisions. Strong candidates check docs, examples, compatibility, observability hooks, and whether the library hides or exposes protocol details appropriately.
Red flag: They judge the library mainly by whether it has many convenience methods.
System design Go questions
Designing real systems end to end.
21Design a Go service that ingests webhooks from several vendors, validates them, and delivers normalized events to internal consumers.
Listen for: Strong answers cover signature verification, idempotency keys, schema evolution, per-vendor adapters, queues for durability, bounded workers, retries with dead-letter handling, and observability. Go-specific signals include context-aware handlers, careful body reading limits, structured logging, table-driven validator tests, and avoiding shared mutable state in worker pools.
Red flag: They process every webhook synchronously in the HTTP request without idempotency or backpressure.
22Design a high-throughput Go worker system that processes image jobs from a queue and calls an external storage service.
Listen for: Look for bounded concurrency, cancellation, timeouts, job visibility or ack semantics, retry classification, resource limits for CPU and memory, and graceful shutdown. Strong Go answers discuss worker pools without unbounded goroutines, pprof for tuning, streaming large objects, avoiding retained buffers, and using metrics to find saturation points.
Red flag: They spawn one goroutine per job with no limit because goroutines are cheap.
23Design an internal Go SDK used by many services to call a payments platform.
Listen for: Strong answers prioritize API stability, context propagation, clear error contracts, configurable transports, observability hooks, retries that respect idempotency, and safe defaults without hiding critical behavior. Go-specific signals include small interfaces for tests, httptest coverage, module versioning, compatibility policy, and avoiding global singleton configuration.
Red flag: They expose raw HTTP details everywhere or hide everything behind an unconfigurable global client.
24Design a Go-based real-time notification service using WebSockets or server-sent events.
Listen for: Listen for connection lifecycle management, authentication refresh, heartbeats, write deadlines, backpressure for slow clients, fan-out strategy, and graceful deploys. Strong Go answers discuss per-connection goroutines with bounded channels, context cancellation, avoiding concurrent writes to the same connection, and measuring active connections and dropped messages.
Red flag: They broadcast directly to all connections without handling slow consumers or disconnects.
25Design a multi-tenant Go API service with PostgreSQL where tenants need strong data isolation.
Listen for: Strong candidates discuss tenant identification, authorization at every boundary, database constraints, row-level security or schema separation trade-offs, migration strategy, indexing, auditing, and test coverage for isolation. Go-specific signals include passing tenant context explicitly, avoiding package-level tenant state, transaction scoping, and preventing accidental cross-tenant cache keys.
Red flag: They rely only on a request header and trust developers to remember every WHERE clause.
Build and harden a small Go HTTP service
Create a Go service with two endpoints: POST /events to accept JSON events and GET /events/{id} to retrieve them. Store data in memory behind an interface so it can be replaced later. Validate input, return consistent errors, use context-aware handlers, and add structured logging. Include table-driven unit tests and at least one httptest-based handler test. Add a README explaining how to run tests, start the service, and what production changes you would make for persistence, observability, and graceful shutdown. Keep the solution small enough to review in one sitting.
How to evaluate it
- Readable package structure with clear separation between HTTP, validation, and storage
- Correct error handling, status codes, context use, and request body limits
- Useful tests covering success, validation failures, and storage errors
- Idiomatic Go: simple interfaces, no unnecessary globals, race-safe in-memory storage
- Practical README notes on production trade-offs rather than overbuilt code
Rather skip the interview loop?
Every Octogle Go engineer has already passed a technical assessment, system design and a live interview with an engineer who has shipped Go. Send a brief and get 3–5 scored profiles in 48 hours.