Skip to main content

Interview questions

Golang engineer interview questions

Golang engineers build network services, platform tooling and cloud-native backends with a focus on simplicity and operational clarity. Strong candidates understand goroutines, channels, interfaces, context propagation, profiling and production service design.

Seniorities
juniormidseniorstaffprincipal

Most reported

Top golang engineer interview questions

6 questions

Sorted by reported frequency. Click any question for the sample outline, follow-ups, and reference implementation.

As asked

A Go service slowly grows from 200 goroutines to 50,000 during normal traffic. Walk me through how you would diagnose and fix the leak.

Sample answer outline

Start with evidence: runtime metrics, pprof goroutine dumps and stack traces grouped by blocked call site. Common causes are sends to channels nobody receives from, receives on channels nobody closes, missing context cancellation and background tickers that are never stopped. The fix should remove the lifecycle ambiguity, usually by passing context.Context through the call chain, closing owned channels exactly once, and stopping tickers or timers. The candidate should also discuss regression protection with load tests or a goroutine-count assertion around the failing path. Interviewers look for ownership of goroutine lifetimes, not just knowing pprof commands.

Expect these follow-ups

  • How do you decide which side owns closing a channel?
  • What does a goroutine blocked on select usually tell you?
  • How would you expose goroutine growth as an alert?
goroutinespprofdebugging

As asked

You are designing an orders topic with 50,000 events per second. How do you choose the partition key, and what can go wrong?

Sample answer outline

The partition key controls ordering, load distribution and consumer parallelism, so it should match the ordering requirement first. If all events for an order must be processed in sequence, orderId is a natural key; if customer-level ordering matters, customerId may be required but can create hot partitions. The number of partitions should allow enough consumer parallelism without creating unnecessary broker overhead. The answer should discuss skew, key cardinality, compaction needs and future repartitioning pain. Candidates often say random keys for balance while missing that this destroys per-entity ordering.

Expect these follow-ups

  • How would you detect a hot partition in production?
  • What happens to ordering when you increase partition count?
  • When would you split one logical stream across multiple topics?
partitioningorderingstreaming

As asked

Explain how context.WithCancel works internally. If I cancel a parent context, how does the signal propagate to child contexts, and what responsibility do goroutines have when they receive a cancellation?

Sample answer outline

A strong answer explains that WithCancel creates a child cancelCtx and registers it with the parent by walking up the tree to find the nearest cancelCtx ancestor and appending to its children map. When the parent is cancelled it iterates its children and calls their cancel functions. Goroutines are responsible for selecting on ctx.Done() and returning promptly when the channel is closed, releasing resources and avoiding leaks.

Expect these follow-ups

  • What is the difference between context.WithTimeout and context.WithDeadline?
  • What happens if you forget to call the cancel function returned by WithCancel?
contextcancellationgoroutinesleaksstdlib

As asked

Describe the fmt.Errorf with %w, errors.Is, and errors.As APIs introduced in Go 1.13. When would you use each, and what is the difference between wrapping and substituting an error?

Sample answer outline

A strong answer explains that %w wraps an error so that errors.Is can traverse the chain for sentinel comparison and errors.As can extract a concrete type from anywhere in the chain. Wrapping preserves the original error for callers who care about the cause; substituting loses it. The candidate should mention when to define sentinel errors versus error types, and note that errors.Is uses == by default but types can implement Is() for custom logic.

Expect these follow-ups

  • How do you test that a function returns a specific wrapped error type?
  • What is the problem with using panic for error propagation in a Go service?
error-handlingerrorsstdlibwrappingsentinel-errors

As asked

Describe how goroutine leaks occur in Go services. What tools would you use to detect them, and walk me through fixing a concrete example where a goroutine blocks on a channel that is never closed.

Sample answer outline

A strong answer identifies the most common causes: goroutines blocked on channels with no sender, blocked on a nil channel, or waiting for a response that never comes. Detection tools include runtime.NumGoroutine in metrics, pprof goroutine profiles (go tool pprof /debug/pprof/goroutine), and the goleak testing library. The fix usually involves passing a context or done channel so goroutines have an exit path, and ensuring the caller always closes the channel or cancels the context.

Expect these follow-ups

  • How would you expose goroutine count as a Prometheus metric?
  • What does the pprof goroutine endpoint show, and how do you read the stack traces?
goroutinesleakspprofdebuggingproduction

As asked

Describe what a slice header contains, what happens internally when you call append and the underlying array is full, and give me a concrete example of a subtle bug caused by multiple slices sharing the same backing array.

Sample answer outline

A strong answer explains that a slice header is three words: a pointer to the backing array, a length, and a capacity. When append exceeds capacity, a new array is allocated (roughly doubling for small slices), data is copied, and a new slice header is returned. The bug: slicing s2 := s1[0:3] creates a slice sharing the same array. Appending within capacity to s2 silently overwrites s1's elements. The fix is s2 := s1[0:3:3] to limit capacity, or a copy.

Expect these follow-ups

  • How does the runtime decide the new capacity when growing a slice?
  • What is the difference between make([]int, 5) and make([]int, 0, 5)?
slicesmemoryappendbacking-arraybugs

Also known as

Go engineer - Go developer - backend engineer