Golang Concurrency Channels Quiz

Golang
0 Passed
0% acceptance

35 comprehensive questions on Golang channels, covering unbuffered and buffered channels, directions, closing, and patterns — with 18 code examples demonstrating channel usage in concurrent programming.

35 Questions
~70 minutes
1

Question 1

What is a channel in Golang?

A
A typed conduit for sending and receiving values between goroutines
B
A type of goroutine
C
A shared memory location
D
A synchronization primitive
2

Question 2

How do you create an unbuffered channel?

go
ch := make(chan int)
A
make(chan Type)
B
make(chan Type, 0)
C
chan Type{}
D
new(chan Type)
3

Question 3

What happens when sending to an unbuffered channel?

go
ch := make(chan int)
ch <- 42  // Blocks until received
A
Blocks until another goroutine receives the value
B
Sends immediately without blocking
C
Compilation error
D
Runtime panic
4

Question 4

How do you create a buffered channel?

go
ch := make(chan int, 10)
A
make(chan Type, capacity)
B
make(chan Type)
C
chan Type[capacity]
D
buffered chan Type
5

Question 5

What is the difference between buffered and unbuffered channels?

A
Buffered channels don't block until buffer is full; unbuffered always block
B
Buffered are faster
C
Unbuffered can hold more values
D
No difference
6

Question 6

What are channel directions?

go
func sendOnly(ch chan<- int) {
    ch <- 42
}

func receiveOnly(ch <-chan int) {
    x := <-ch
}
A
chan<- Type for send-only, <-chan Type for receive-only
B
->chan Type for send, chan<- Type for receive
C
No direction restrictions
D
Directions are runtime only
7

Question 7

How do you close a channel?

go
ch := make(chan int, 1)
ch <- 42
close(ch)
A
close(channel)
B
channel.close()
C
delete(channel)
D
Cannot close channels
8

Question 8

What happens when receiving from a closed channel?

go
ch := make(chan int)
close(ch)
x, ok := <-ch
A
Receives zero value and ok=false
B
Panics
C
Blocks forever
D
Compilation error
9

Question 9

What happens when sending to a closed channel?

go
ch := make(chan int)
close(ch)
ch <- 42  // Panic
A
Runtime panic
B
Blocks
C
Ignores the send
D
Compilation error
10

Question 10

What is the range over channels pattern?

go
ch := make(chan int)
go func() {
    for i := 0; i < 5; i++ {
        ch <- i
    }
    close(ch)
}()

for value := range ch {
    fmt.Println(value)
}
A
Iterates over channel until closed
B
Iterates fixed number of times
C
Requires buffered channel
D
Cannot range over channels
11

Question 11

What is a deadlock in channel operations?

go
ch := make(chan int)
ch <- 42  // Deadlock - no receiver
A
Goroutine blocks forever waiting for impossible operation
B
Channel buffer overflows
C
Channel is closed
D
Race condition
12

Question 12

How do you implement a worker pool with channels?

go
func worker(id int, jobs <-chan int, results chan<- int) {
    for j := range jobs {
        results <- j * 2
    }
}

func main() {
    jobs := make(chan int, 100)
    results := make(chan int, 100)
    
    for w := 1; w <= 3; w++ {
        go worker(w, jobs, results)
    }
    
    for j := 1; j <= 9; j++ {
        jobs <- j
    }
    close(jobs)
    
    for a := 1; a <= 9; a++ {
        <-results
    }
}
A
Multiple goroutines reading jobs channel and writing results channel
B
Single goroutine doing all work
C
Use global variables
D
Use sync.Mutex
13

Question 13

What is the select statement used for?

go
select {
case x := <-ch1:
    fmt.Println("Received from ch1:", x)
case y := <-ch2:
    fmt.Println("Received from ch2:", y)
}
A
Waits on multiple channel operations
B
Selects one channel to use
C
Creates new channels
D
Closes channels
14

Question 14

What happens in a select with no ready cases?

go
select {
case <-ch1:
    // ch1 not ready
case <-ch2:
    // ch2 not ready
// Blocks here
}
A
Blocks until one case becomes ready
B
Panics
C
Executes default case
D
Compilation error
15

Question 15

How do you make select non-blocking?

go
select {
case x := <-ch:
    fmt.Println(x)
default:
    fmt.Println("No value ready")
}
A
Add default case
B
Use timeout
C
Use buffered channels
D
Cannot make non-blocking
16

Question 16

What is the nil channel behavior?

go
var ch chan int  // nil
select {
case <-ch:
    // never selected
}
A
Nil channels never become ready in select
B
Panics
C
Blocks forever
D
Same as closed channel
17

Question 17

How do you implement a timeout with channels?

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

Question 18

What is the fan-in pattern?

go
func fanIn(ch1, ch2 <-chan int) <-chan int {
    c := make(chan int)
    go func() { for { c <- <-ch1 } }()
    go func() { for { c <- <-ch2 } }()
    return c
}
A
Multiple input channels merged into one output channel
B
One channel split into multiple
C
Channels fanning out
D
No such pattern
19

Question 19

What is the fan-out pattern?

A
One input channel distributed to multiple goroutines
B
Multiple channels merged
C
Channels closing
D
No such pattern
20

Question 20

How do you safely close a channel?

go
func producer(ch chan<- int) {
    defer close(ch)
    for i := 0; i < 10; i++ {
        ch <- i
    }
}
A
Only the sender should close the channel
B
Any goroutine can close
C
Receiver closes
D
Never close channels
21

Question 21

What is the comma ok idiom?

go
value, ok := <-ch
if !ok {
    // channel closed
}
A
Checks if channel receive succeeded or channel is closed
B
Checks if send succeeded
C
Checks channel capacity
D
Checks if channel is nil
22

Question 22

How do you implement a pipeline with channels?

go
func generator() <-chan int {
    ch := make(chan int)
    go func() {
        for i := 0; i < 10; i++ {
            ch <- i
        }
        close(ch)
    }()
    return ch
}

func square(in <-chan int) <-chan int {
    out := make(chan int)
    go func() {
        for n := range in {
            out <- n * n
        }
        close(out)
    }()
    return out
}
A
Chain goroutines where each reads from previous stage's output channel
B
Use single goroutine
C
Use shared memory
D
Cannot implement pipelines
23

Question 23

What is channel capacity vs length?

go
ch := make(chan int, 10)
fmt.Println(cap(ch))  // 10
fmt.Println(len(ch))  // 0
A
cap() returns buffer size, len() returns queued items
B
Both return same value
C
cap() for length, len() for capacity
D
No difference
24

Question 24

How do you iterate over a channel until closed?

go
for value := range ch {
    fmt.Println(value)
}
// Automatically stops when ch closes
A
Use for range loop
B
Use while loop
C
Use for i := 0; i < n; i++
D
Cannot iterate over channels
25

Question 25

What happens when buffer is full?

go
ch := make(chan int, 1)
ch <- 1  // ok
ch <- 2  // blocks
A
Send blocks until space available
B
Panics
C
Drops oldest value
D
Compilation error
26

Question 26

How do you implement a semaphore with channels?

go
semaphore := make(chan struct{}, maxConcurrent)
func worker() {
    semaphore <- struct{}{}  // acquire
    defer func() { <-semaphore }()  // release
    // do work
}
A
Use buffered channel as counting semaphore
B
Use unbuffered channel
C
Use sync.Mutex
D
Cannot implement semaphore
27

Question 27

What is the problem with multiple closers?

go
go func() { close(ch) }()
go func() { close(ch) }()  // Panic
A
Closing closed channel panics
B
Blocks forever
C
Ignores second close
D
Compilation error
28

Question 28

How do you handle closed channels in select?

go
select {
case v, ok := <-ch:
    if !ok {
        // channel closed
        return
    }
    // use v
}
A
Check ok value in receive operation
B
Use default case
C
Cannot detect in select
D
Use panic recovery
29

Question 29

What is a channel of channels?

go
ch := make(chan chan int)
workerCh := make(chan int)
ch <- workerCh
A
Channel that carries other channels as values
B
Invalid syntax
C
Channel that multiplexes
D
No such thing
30

Question 30

How do you implement a done channel pattern?

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

// Wait for completion
<-done
A
Use empty struct channel to signal completion
B
Use bool channel
C
Use int channel
D
Use sync.WaitGroup
31

Question 31

What is the difference between len(ch) and cap(ch)?

A
len is current items, cap is maximum capacity
B
Both same for unbuffered
C
cap is current items, len is maximum
D
No difference
32

Question 32

How do you implement non-blocking send?

go
select {
case ch <- value:
    // sent successfully
default:
    // would block
}
A
Use select with default case
B
Use buffered channel
C
Use goroutine
D
Cannot do non-blocking send
33

Question 33

What is the producer-consumer pattern?

go
func producer(ch chan<- int) {
    for i := 0; i < 10; i++ {
        ch <- i
    }
    close(ch)
}

func consumer(ch <-chan int) {
    for value := range ch {
        fmt.Println(value)
    }
}
A
Producer sends to channel, consumer receives from channel
B
Both produce and consume
C
No channel involved
D
Use shared memory
34

Question 34

How do you avoid channel leaks?

A
Always close channels when done, ensure receivers exist
B
Never close channels
C
Use buffered channels
D
Use global channels
35

Question 35

What is the most important channel best practice?

A
Sender closes channel, use comma ok to detect closure, prefer unbuffered for synchronization
B
Use buffered channels everywhere
C
Never close channels
D
Use channels for all communication

QUIZZES IN Golang