What is the purpose of the select statement in Go?
The select statement lets a Go program wait on multiple channel operations. It blocks until one of the channels is ready to send or receive, then executes the corresponding case.
Click to reveal answer
intermediate
How does Go decide which select case to run if multiple channels are ready?
If multiple channels are ready, Go picks one case at random to run. This prevents starvation and ensures fairness.
Click to reveal answer
beginner
What happens if none of the channels in a select statement are ready?
The select statement blocks and waits until one of the channels becomes ready, unless there is a default case, which runs immediately if no channels are ready.
Click to reveal answer
beginner
Write a simple Go select statement that listens on two channels ch1 and ch2 and prints which channel received data.
select {
case msg1 := <-ch1:
fmt.Println("Received from ch1:", msg1)
case msg2 := <-ch2:
fmt.Println("Received from ch2:", msg2)
}
Click to reveal answer
intermediate
What is the role of the default case in a select statement?
The default case runs immediately if no other channel operations are ready. It prevents blocking and can be used to perform non-blocking checks.
Click to reveal answer
What does the select statement do in Go?
AWaits on multiple channel operations and executes one that is ready
BCreates a new goroutine
CDeclares a new channel
DLocks a mutex
✗ Incorrect
The select statement waits on multiple channels and runs the case for the first ready channel.
If multiple channels are ready in a select, how does Go choose which case to run?
ARuns the first case declared
BPicks one case at random
CRuns all ready cases simultaneously
DReturns an error
✗ Incorrect
Go picks one ready case at random to avoid starvation.
What happens if no channels are ready and there is no default case in a select?
AThe <code>select</code> blocks until a channel is ready
BThe program panics
CThe <code>select</code> skips all cases
DThe <code>select</code> runs the last case
✗ Incorrect
Without a default, select waits (blocks) until a channel is ready.
What is the purpose of the default case in a select?
ATo handle errors
BTo close all channels
CTo run code if no channels are ready, avoiding blocking
DTo create new channels
✗ Incorrect
The default case runs immediately if no channels are ready, preventing blocking.
Which of these is a valid use of select with multiple channels?
Aselect { for ch1: ... }
Bselect { ch1 <- 1; ch2 <- 2 }
Cselect { if ch1 == ch2: ... }
Dselect { case <-ch1: ... case <-ch2: ... }
✗ Incorrect
Option D shows correct syntax waiting to receive from multiple channels.
Explain how the select statement works with multiple channels in Go.
Think about how Go handles multiple channel operations at once.
You got /5 concepts.
Describe a real-life situation where using select with multiple channels would be helpful.
Imagine you are waiting for messages from different friends on separate phones.
You got /4 concepts.
Practice
(1/5)
1.
What does the select statement do when used with multiple channels in Go?
easy
A. It waits until one of the channels is ready to send or receive and executes that case.
B. It executes all channel operations simultaneously regardless of readiness.
C. It blocks forever until all channels are ready at the same time.
D. It randomly picks a channel to operate on without checking readiness.
Solution
Step 1: Understand select behavior
The select statement waits for one of its channel cases to be ready.
Step 2: Identify how select chooses a case
It picks one of the channels that is ready to send or receive and runs that case.
Final Answer:
It waits until one of the channels is ready to send or receive and executes that case. -> Option A
Quick Check:
Select waits for ready channel = A [OK]
Hint: Select picks the first ready channel to act on [OK]
Common Mistakes:
Thinking select runs all channels at once
Believing select waits for all channels simultaneously
Assuming select picks channels randomly without readiness check
2.
Which of the following is the correct syntax to use select with two channels ch1 and ch2 for receiving values?
?
easy
A. select {
case val = <-ch1:
fmt.Println(val)
case val = <-ch2:
fmt.Println(val)
}
B. select {
case <-ch1:
fmt.Println(val)
case <-ch2:
fmt.Println(val)
}
C. select {
case val := ch1:
fmt.Println(val)
case val := ch2:
fmt.Println(val)
}
D. select {
case val := <-ch1:
fmt.Println(val)
case val := <-ch2:
fmt.Println(val)
}
Solution
Step 1: Check channel receive syntax
Receiving from a channel uses val := <-ch to assign the received value.
Step 2: Verify select case syntax
Each case must have a receive operation with assignment like val := <-ch1.
Final Answer:
select {
case val := <-ch1:
fmt.Println(val)
case val := <-ch2:
fmt.Println(val)
} -> Option D
Quick Check:
Correct receive syntax uses := <-channel [OK]
Hint: Use := <-channel to receive inside select case [OK]
Common Mistakes:
Using = instead of := for assignment
Omitting the <- operator for receiving
Trying to assign channel itself instead of received value
3.
What will be the output of the following Go program?
The goroutine sending to ch2 sleeps 50ms, and ch1 sleeps 100ms.
Step 2: Determine which channel is ready first
Since ch2 sends first, the select will receive from ch2 and print "world".
Final Answer:
world -> Option B
Quick Check:
Channel with shorter sleep sends first = world [OK]
Hint: Select picks channel ready first (shorter sleep) [OK]
Common Mistakes:
Assuming ch1 sends first because it is listed first
Expecting both messages to print
Thinking select waits for all channels
4.
Identify the error in this Go code using select with multiple channels:
package main
import "fmt"
func main() {
ch1 := make(chan int)
ch2 := make(chan int)
select {
case val := <-ch1:
fmt.Println(val)
case val := <-ch2:
fmt.Println(val)
}
}
medium
A. Channels must be buffered to use select.
B. The select statement syntax is invalid without a loop.
C. The program will deadlock because channels are never written to.
D. The default case is not allowed in select statements.
Solution
Step 1: Analyze channel creation
Channels ch1 and ch2 are unbuffered with no goroutines to send values.
Step 2: Select behavior without senders
The select blocks forever since no channels become ready, causing a deadlock.
Final Answer:
The program will deadlock because channels are never written to. -> Option C
Quick Check:
No senders + no default = deadlock [OK]
Hint: No senders and no default causes deadlock [OK]
Common Mistakes:
Thinking channels must be buffered to use select
Believing select syntax is invalid without a loop
Assuming a default case is required or invalid
5.
You want to write a Go function that waits on two channels chA and chB and returns the first value received from either. If neither channel is ready immediately, it should return "timeout" after 100 milliseconds. Which select structure correctly implements this?
hard
A. select {
case val := <-chA:
return val
case val := <-chB:
return val
case <-time.After(100 * time.Millisecond):
return "timeout"
}
B. select {
case val := <-chA:
return val
case val := <-chB:
return val
default:
time.Sleep(100 * time.Millisecond)
return "timeout"
}
C. select {
case val := <-chA:
return val
case val := <-chB:
return val
case <-time.Tick(100 * time.Millisecond):
return "timeout"
}
D. select {
case val := <-chA:
return val
case val := <-chB:
return val
case <-time.After(100):
return "timeout"
}
Solution
Step 1: Use time.After for timeout
The time.After function returns a channel that sends a value after the specified duration, perfect for timeout.
Step 2: Check select cases
Cases for receiving from chA and chB return the first received value; the timeout case returns "timeout" after 100ms.
Step 3: Validate other options
select {
case val := <-chA:
return val
case val := <-chB:
return val
default:
time.Sleep(100 * time.Millisecond)
return "timeout"
} uses default with sleep which blocks select; select {
case val := <-chA:
return val
case val := <-chB:
return val
case <-time.Tick(100 * time.Millisecond):
return "timeout"
} uses time.Tick which repeats; select {
case val := <-chA:
return val
case val := <-chB:
return val
case <-time.After(100):
return "timeout"
} uses incorrect duration type.
Final Answer:
select {
case val := <-chA:
return val
case val := <-chB:
return val
case <-time.After(100 * time.Millisecond):
return "timeout"
} -> Option A
Quick Check:
Use time.After channel for timeout in select [OK]
Hint: Use time.After channel for timeout in select [OK]
Common Mistakes:
Using default with sleep instead of time.After
Using time.Tick which repeats instead of time.After
Passing wrong duration type to time.After
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.