Role preparation

Go Developer interview questions and answers.

Go interfaces and typed nils, goroutines, channels, cancellation, and reliable services.

Questions

Technical questions to practise out loud

  1. 01

    How do Go slices work?

    A Go slice is a small descriptor containing a pointer to a backing array, a length, and a capacity. It is not the array itself, so two slices can share the same underlying storage and observe each other’s element changes.

    Read the full breakdown
  2. 02

    Why are concurrent map writes unsafe in Go?

    Regular Go maps are not safe for concurrent writes. Concurrent mutation can trigger a runtime panic; protect a map with sync.Mutex or sync.RWMutex, partition ownership, or use sync.Map only when its access pattern fits.

    Read the full breakdown
  3. 03

    Why can a Go interface be non-nil with a nil value?

    An interface value is nil only when both its dynamic type and dynamic value are nil. A typed nil pointer stored in an interface has a dynamic type, so the interface itself is non-nil.

    Read the full breakdown
  4. 04

    How do you prevent goroutine leaks?

    A goroutine leak happens when a goroutine blocks forever on I/O, a channel, a lock, or a timer. Give it cancellation, bounded work, and a clear owner that waits for shutdown.

    Read the full breakdown
  5. 05

    When do you use channels versus mutexes?

    Use channels to transfer ownership or coordinate a stream of values; use a mutex to protect shared mutable state. Channels are not automatically simpler when several operations must update one invariant atomically.

    Read the full breakdown
  6. 06

    How do you use context in Go services?

    context.Context carries deadlines, cancellation, and request-scoped values across API boundaries. It should be the first parameter, propagated rather than stored in a struct, and never replaced with context.Background inside request work.

    Read the full breakdown
  7. 07

    How do you design error handling in Go?

    In Go, errors are explicit return values. Add context with fmt.Errorf and %w, preserve the cause for errors.Is or errors.As, and decide at the boundary whether the caller can recover.

    Read the full breakdown
  8. 08

    How do you use interfaces idiomatically in Go?

    Keep Go interfaces small and define them at the consumer side. They describe the behaviour a caller needs, not a class hierarchy or every capability of a concrete type.

    Read the full breakdown
  9. 09

    How do you profile a Go service?

    Profile before optimising. Use pprof to compare CPU, heap, goroutine, mutex, or block profiles against a baseline, then validate the change with the same workload.

    Read the full breakdown
  10. 10

    What is your Go testing strategy?

    Go tests should cover behaviour at the smallest useful boundary: table-driven unit tests for pure logic, integration tests for real dependencies, and race detection for concurrent code.

    Read the full breakdown