Go

Channels or mutexes: how do you decide?

Question 208MediumGo 1.22 to 1.25

The Go proverb says "Don't communicate by sharing memory; share memory by communicating", but the practical rule is:

  • Channels are for passing ownership of data, coordinating goroutine lifecycles, distributing work, pipelines, signaling events and cancellation, and combining waits with select and timeouts.
  • Mutexes are for protecting shared state such as caches, counters, and maps, where the operation is "read or modify in place". They are simpler and usually faster, taking tens of nanoseconds uncontended, whereas a channel op needs a lock plus possible goroutine park and wake.
  • Atomics are for single-word counters and flags.
// Overkill: a channel-guarded counter
type ChanCounter struct{ inc chan struct{}; get chan int }

// Idiomatic
type Counter struct{ n atomic.Int64 }
func (c *Counter) Inc()        { c.n.Add(1) }
func (c *Counter) Load() int64 { return c.n.Load() }

What the interviewer wants is pragmatism, not dogma. Mention that the standard library itself (e.g. net/http, database/sql) mostly uses mutexes and atomics and saves channels for coordination. Channel-heavy designs have more ways to deadlock and leak.

More on Channels & select

All 38 Channels & select questions