Explain the select statement in Go — how does it multiplex channels?
go-mid-005
Your answer
Answer as you would in a real interview — explain your thinking, not just the conclusion.
Model answer
select is like a switch for channel operations. It blocks until one of its cases can proceed. If multiple cases are ready simultaneously, Go picks one at random — this is a deliberate choice to avoid starving channels. A default clause makes select non-blocking — if no channel is ready, default runs immediately. Common patterns: implementing a timeout (case <-time.After(d)), cancellation (case <-ctx.Done()), and combining a producer channel with a done signal. select with a nil channel never fires for that case — useful to dynamically disable a case (set a channel variable to nil).
Code example
package main
import (
"context"
"fmt"
"time"
)
func fanIn(ctx context.Context, chs ...<-chan int) <-chan int {
out := make(chan int)
for _, ch := range chs {
go func(c <-chan int) {
for {
select {
case v, ok := <-c:
if !ok {
return
}
out <- v
case <-ctx.Done():
return
}
}
}(ch)
}
return out
}
func withTimeout(ch <-chan string, d time.Duration) (string, error) {
select {
case v := <-ch:
return v, nil
case <-time.After(d):
return "", fmt.Errorf("timeout after %v", d)
}
}
// Non-blocking send
func trySend(ch chan<- int, v int) bool {
select {
case ch <- v:
return true
default:
return false
}
}
Follow-up
How would you implement a priority select — always draining the high-priority channel before reading from a low-priority one?