Golang Select Statement Quiz
35 comprehensive questions on Golang's select statement, covering multiplexing channels, timeouts, non-blocking operations, fan-in/fan-out patterns, and handling closed channels — with 18 code examples demonstrating advanced channel operations.
Question 1
What is the select statement in Golang?
select {
case x := <-ch1:
fmt.Println("Received from ch1:", x)
case y := <-ch2:
fmt.Println("Received from ch2:", y)
case ch3 <- 42:
fmt.Println("Sent to ch3")
}Question 2
What happens when multiple cases are ready in select?
Question 3
How do you implement a timeout with select?
select {
case result := <-ch:
fmt.Println("Result:", result)
case <-time.After(5 * time.Second):
fmt.Println("Timeout")
}Question 4
What is the default case in select?
select {
case x := <-ch:
fmt.Println(x)
default:
fmt.Println("No value ready")
}Question 5
How do you handle closed channels in select?
select {
case v, ok := <-ch:
if !ok {
fmt.Println("Channel closed")
return
}
fmt.Println("Received:", v)
}Question 6
What is multiplexing with select?
func multiplex(ch1, ch2 <-chan int) <-chan int {
c := make(chan int)
go func() {
for {
select {
case v := <-ch1:
c <- v
case v := <-ch2:
c <- v
}
}
}()
return c
}Question 7
How do you implement fan-in pattern with select?
func fanIn(ch1, ch2 <-chan int) <-chan int {
c := make(chan int)
go func() {
for {
select {
case v := <-ch1:
c <- v
case v := <-ch2:
c <- v
}
}
}()
return c
}Question 8
What is the fan-out pattern?
func fanOut(input <-chan int, outputs []chan<- int) {
go func() {
for v := range input {
for _, out := range outputs {
select {
case out <- v:
default:
// drop if full
}
}
}
for _, out := range outputs {
close(out)
}
}()
}Question 9
How do you implement non-blocking receive?
select {
case v, ok := <-ch:
if ok {
fmt.Println("Received:", v)
} else {
fmt.Println("Channel closed")
}
default:
fmt.Println("No value available")
}Question 10
What happens with nil channels in select?
var ch chan int // nil
select {
case <-ch:
fmt.Println("Received")
default:
fmt.Println("Default")
}Question 11
How do you implement a quit channel pattern?
quit := make(chan struct{})
go func() {
for {
select {
case <-quit:
return
default:
// do work
}
}
}()
// To stop: close(quit)Question 12
What is the heartbeat pattern with select?
func worker(heartbeat <-chan time.Time) {
for {
select {
case <-heartbeat:
fmt.Println("Heartbeat")
case <-time.After(30 * time.Second):
fmt.Println("No heartbeat - exiting")
return
}
}
}Question 13
How do you handle multiple timeouts in select?
select {
case result := <-ch:
// handle result
case <-time.After(5 * time.Second):
// short timeout
case <-time.After(30 * time.Second):
// this never executes
}Question 14
What is the convoy effect in select?
Question 15
How do you implement priority in select?
select {
case v := <-highPriority:
// handle high priority first
// then check low priority
select {
case v := <-lowPriority:
// handle low priority
default:
}
default:
select {
case v := <-lowPriority:
// handle low priority
default:
}
}Question 16
What is the done channel pattern with select?
done := make(chan struct{})
go func() {
defer close(done)
// do work
}()
select {
case <-done:
fmt.Println("Work completed")
case <-time.After(10 * time.Second):
fmt.Println("Timeout")
}Question 17
How do you implement a rate limiter with select?
limiter := time.Tick(100 * time.Millisecond)
for req := range requests {
<-limiter // wait for tick
go handle(req)
}Question 18
What is the context cancellation pattern with select?
ctx, cancel := context.WithCancel(context.Background())
go func() {
select {
case <-ctx.Done():
return
case result := <-work:
// process result
}
}()
// Later: cancel()Question 19
How do you handle multiple channels with different priorities?
for {
select {
case v := <-urgent:
handleUrgent(v)
default:
select {
case v := <-urgent:
handleUrgent(v)
case v := <-normal:
handleNormal(v)
}
}
}Question 20
What is the problem with this select usage?
for {
select {
case v := <-ch:
fmt.Println(v)
}
}Question 21
How do you implement a barrier with select?
barrier := make(chan struct{})
go func() {
// do work
close(barrier)
}()
go func() {
// do other work
close(barrier)
}()
// Wait for both
<-barrier
<-barrierQuestion 22
What is the select loop pattern?
for {
select {
case v := <-input:
process(v)
case <-quit:
return
case <-time.After(heartbeat):
sendHeartbeat()
}
}Question 23
How do you implement a sliding window with select?
window := make(chan struct{}, 3)
for i := 0; i < 10; i++ {
window <- struct{}{} // acquire slot
go func(i int) {
defer func() { <-window }() // release slot
process(i)
}(i)
}Question 24
What is the tee channel pattern?
func tee(input <-chan int) (<-chan int, <-chan int) {
out1 := make(chan int)
out2 := make(chan int)
go func() {
defer close(out1)
defer close(out2)
for v := range input {
out1 <- v
out2 <- v
}
}()
return out1, out2
}Question 25
How do you handle channel closure in select loops?
for {
select {
case v, ok := <-ch:
if !ok {
return // channel closed
}
process(v)
case <-timeout:
return
}
}Question 26
What is the or-done channel pattern?
func orDone(done <-chan struct{}, c <-chan int) <-chan int {
valStream := make(chan int)
go func() {
defer close(valStream)
for {
select {
case <-done:
return
case v, ok := <-c:
if !ok {
return
}
select {
case valStream <- v:
case <-done:
return
}
}
}
}()
return valStream
}Question 27
How do you implement a bridge between channels?
func bridge(done <-chan struct{}, chanStream <-chan <-chan int) <-chan int {
valStream := make(chan int)
go func() {
defer close(valStream)
for {
var stream <-chan int
select {
case <-done:
return
case maybeStream, ok := <-chanStream:
if !ok {
return
}
stream = maybeStream
}
for v := range orDone(done, stream) {
valStream <- v
}
}
}()
return valStream
}Question 28
What is the bounded work pool pattern?
jobs := make(chan Job, 100)
results := make(chan Result, 100)
for w := 0; w < 3; w++ {
go worker(jobs, results)
}
func worker(jobs <-chan Job, results chan<- Result) {
for j := range jobs {
select {
case results <- process(j):
case <-time.After(10 * time.Second):
// timeout
}
}
}Question 29
How do you implement a context-aware select?
select {
case <-ctx.Done():
return ctx.Err()
case result := <-work:
return process(result)
case <-time.After(deadline.Sub(time.Now())):
return errors.New("timeout")
}Question 30
What is the problem with empty select?
select {} // deadlockQuestion 31
How do you implement a periodic task with select?
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
doPeriodicTask()
case <-quit:
return
}
}Question 32
What is the drain channel pattern?
func drain(ch <-chan int) {
for {
select {
case <-ch:
default:
return
}
}
}Question 33
How do you implement a cascading timeout?
func cascadeTimeout(ch <-chan int, timeout time.Duration) (int, error) {
select {
case v := <-ch:
return v, nil
case <-time.After(timeout):
return 0, errors.New("timeout")
}
}Question 34
What is the select with bias pattern?
for {
select {
case v := <-highPriority:
handleHigh(v)
default:
select {
case v := <-highPriority:
handleHigh(v)
case v := <-lowPriority:
handleLow(v)
}
}
}Question 35
What is the most important select best practice?
