Golang Select Statement Quiz

Golang
0 Passed
0% acceptance

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.

35 Questions
~70 minutes
1

Question 1

What is the select statement in Golang?

go
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")
}
A
Waits for multiple channel operations and executes the first ready one
B
Selects one channel to use exclusively
C
Creates new channels
D
Closes channels
2

Question 2

What happens when multiple cases are ready in select?

A
One case is chosen pseudo-randomly
B
First case in order wins
C
All cases execute
D
Compilation error
3

Question 3

How do you implement a timeout with select?

go
select {
case result := <-ch:
    fmt.Println("Result:", result)
case <-time.After(5 * time.Second):
    fmt.Println("Timeout")
}
A
Use time.After() in a case
B
Use time.Sleep()
C
Use context.WithTimeout()
D
Cannot implement timeout
4

Question 4

What is the default case in select?

go
select {
case x := <-ch:
    fmt.Println(x)
default:
    fmt.Println("No value ready")
}
A
Executes immediately if no case is ready
B
Executes after timeout
C
Required in all selects
D
Handles errors
5

Question 5

How do you handle closed channels in select?

go
select {
case v, ok := <-ch:
    if !ok {
        fmt.Println("Channel closed")
        return
    }
    fmt.Println("Received:", v)
}
A
Use comma ok idiom in receive operations
B
Check for panic
C
Use default case
D
Cannot detect in select
6

Question 6

What is multiplexing with select?

go
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
}
A
Handling multiple input sources in one goroutine
B
Sending to multiple channels
C
Closing multiple channels
D
No multiplexing in Go
7

Question 7

How do you implement fan-in pattern with select?

go
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
}
A
Merge multiple input channels into one output channel
B
Split one channel into multiple
C
Close channels
D
No fan-in pattern
8

Question 8

What is the fan-out pattern?

go
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)
        }
    }()
}
A
Distribute work from one channel to multiple worker channels
B
Combine multiple channels
C
Close all channels
D
No fan-out pattern
9

Question 9

How do you implement non-blocking receive?

go
select {
case v, ok := <-ch:
    if ok {
        fmt.Println("Received:", v)
    } else {
        fmt.Println("Channel closed")
    }
default:
    fmt.Println("No value available")
}
A
Use select with default case
B
Use buffered channel
C
Use goroutine
D
Cannot do non-blocking receive
10

Question 10

What happens with nil channels in select?

go
var ch chan int  // nil
select {
case <-ch:
    fmt.Println("Received")
default:
    fmt.Println("Default")
}
A
Nil channels are never ready, so default executes
B
Panics
C
Blocks forever
D
Same as closed channel
11

Question 11

How do you implement a quit channel pattern?

go
quit := make(chan struct{})
go func() {
    for {
        select {
        case <-quit:
            return
        default:
            // do work
        }
    }
}()

// To stop: close(quit)
A
Use quit channel in select to signal shutdown
B
Use context
C
Use sync.WaitGroup
D
Cannot implement quit
12

Question 12

What is the heartbeat pattern with select?

go
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
        }
    }
}
A
Periodic signal to show goroutine is alive
B
Error reporting
C
Work distribution
D
No heartbeat pattern
13

Question 13

How do you handle multiple timeouts in select?

go
select {
case result := <-ch:
    // handle result
case <-time.After(5 * time.Second):
    // short timeout
case <-time.After(30 * time.Second):
    // this never executes
}
A
Only first timeout case is effective
B
Both timeouts run
C
Compilation error
D
Random selection
14

Question 14

What is the convoy effect in select?

A
Slow operations delaying faster ones due to random selection
B
Channels backing up
C
Memory leaks
D
No convoy effect
15

Question 15

How do you implement priority in select?

go
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:
    }
}
A
Check high priority first, then low priority in nested select
B
Use random selection
C
Use timeouts
D
Cannot implement priority
16

Question 16

What is the done channel pattern with select?

go
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")
}
A
Signal completion of asynchronous work
B
Cancel work
C
Report errors
D
No done pattern
17

Question 17

How do you implement a rate limiter with select?

go
limiter := time.Tick(100 * time.Millisecond)
for req := range requests {
    <-limiter  // wait for tick
    go handle(req)
}
A
Use time.Tick channel to pace operations
B
Use buffered channels
C
Use sync.Mutex
D
Cannot rate limit
18

Question 18

What is the context cancellation pattern with select?

go
ctx, cancel := context.WithCancel(context.Background())
go func() {
    select {
    case <-ctx.Done():
        return
    case result := <-work:
        // process result
    }
}()

// Later: cancel()
A
Use context.Done() in select for cancellation
B
Use quit channel
C
Use timeout
D
Cannot cancel with select
19

Question 19

How do you handle multiple channels with different priorities?

go
for {
    select {
    case v := <-urgent:
        handleUrgent(v)
    default:
        select {
        case v := <-urgent:
            handleUrgent(v)
        case v := <-normal:
            handleNormal(v)
        }
    }
}
A
Use nested selects to check urgent first
B
Use timeouts
C
Use random selection
D
Cannot prioritize
20

Question 20

What is the problem with this select usage?

go
for {
    select {
    case v := <-ch:
        fmt.Println(v)
    }
}
A
Infinite loop consuming CPU when no cases ready
B
Blocks forever
C
Compilation error
D
No problem
21

Question 21

How do you implement a barrier with select?

go
barrier := make(chan struct{})
go func() {
    // do work
    close(barrier)
}()

go func() {
    // do other work
    close(barrier)
}()

// Wait for both
<-barrier
<-barrier
A
Use closed channels as completion signals
B
Use sync.WaitGroup
C
Use select directly
D
Cannot implement barrier
22

Question 22

What is the select loop pattern?

go
for {
    select {
    case v := <-input:
        process(v)
    case <-quit:
        return
    case <-time.After(heartbeat):
        sendHeartbeat()
    }
}
A
Main event loop using select for multiple operations
B
Error handling
C
Channel creation
D
No select loop pattern
23

Question 23

How do you implement a sliding window with select?

go
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)
}
A
Use buffered channel as sliding window semaphore
B
Use time windows
C
Use arrays
D
Cannot implement sliding window
24

Question 24

What is the tee channel pattern?

go
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
}
A
Duplicate input stream to multiple output channels
B
Merge channels
C
Close channels
D
No tee pattern
25

Question 25

How do you handle channel closure in select loops?

go
for {
    select {
    case v, ok := <-ch:
        if !ok {
            return  // channel closed
        }
        process(v)
    case <-timeout:
        return
    }
}
A
Check ok flag and exit loop when channel closes
B
Use panic recovery
C
Use default case
D
Cannot handle closure
26

Question 26

What is the or-done channel pattern?

go
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
}
A
Wrap channel with done channel for cancellation
B
Combine channels
C
Close channels
D
No or-done pattern
27

Question 27

How do you implement a bridge between channels?

go
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
}
A
Convert channel of channels to single channel of values
B
Close channels
C
Merge channels
D
No bridge pattern
28

Question 28

What is the bounded work pool pattern?

go
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
        }
    }
}
A
Limit concurrent workers with timeouts
B
Unlimited workers
C
Single worker
D
No bounded pool
29

Question 29

How do you implement a context-aware select?

go
select {
case <-ctx.Done():
    return ctx.Err()
case result := <-work:
    return process(result)
case <-time.After(deadline.Sub(time.Now())):
    return errors.New("timeout")
}
A
Include ctx.Done() as a case for cancellation
B
Use quit channel
C
Use sync.WaitGroup
D
Cannot use context
30

Question 30

What is the problem with empty select?

go
select {}  // deadlock
A
Deadlocks because no cases can ever be ready
B
Compiles but does nothing
C
Compilation error
D
No problem
31

Question 31

How do you implement a periodic task with select?

go
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()

for {
    select {
    case <-ticker.C:
        doPeriodicTask()
    case <-quit:
        return
    }
}
A
Use time.Ticker channel in select
B
Use time.Sleep in loop
C
Use goroutines
D
Cannot implement periodic tasks
32

Question 32

What is the drain channel pattern?

go
func drain(ch <-chan int) {
    for {
        select {
        case <-ch:
        default:
            return
        }
    }
}
A
Empty channel of pending values without blocking
B
Fill channel
C
Close channel
D
No drain pattern
33

Question 33

How do you implement a cascading timeout?

go
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")
    }
}
A
Use select with time.After for timeout
B
Use context
C
Use sync.WaitGroup
D
Cannot timeout
34

Question 34

What is the select with bias pattern?

go
for {
    select {
    case v := <-highPriority:
        handleHigh(v)
    default:
        select {
        case v := <-highPriority:
            handleHigh(v)
        case v := <-lowPriority:
            handleLow(v)
        }
    }
}
A
Prefer high priority cases over low priority
B
Random selection
C
Equal priority
D
No bias pattern
35

Question 35

What is the most important select best practice?

A
Include default case to avoid blocking, handle closed channels with comma ok, use for graceful cancellation
B
Always block in select
C
Never use default
D
Use select for all channel operations

QUIZZES IN Golang