Golang Concurrency Channels Quiz
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.
Question 1
What is a channel in Golang?
Question 2
How do you create an unbuffered channel?
ch := make(chan int)Question 3
What happens when sending to an unbuffered channel?
ch := make(chan int)
ch <- 42 // Blocks until receivedQuestion 4
How do you create a buffered channel?
ch := make(chan int, 10)Question 5
What is the difference between buffered and unbuffered channels?
Question 6
What are channel directions?
func sendOnly(ch chan<- int) {
ch <- 42
}
func receiveOnly(ch <-chan int) {
x := <-ch
}Question 7
How do you close a channel?
ch := make(chan int, 1)
ch <- 42
close(ch)Question 8
What happens when receiving from a closed channel?
ch := make(chan int)
close(ch)
x, ok := <-chQuestion 9
What happens when sending to a closed channel?
ch := make(chan int)
close(ch)
ch <- 42 // PanicQuestion 10
What is the range over channels pattern?
ch := make(chan int)
go func() {
for i := 0; i < 5; i++ {
ch <- i
}
close(ch)
}()
for value := range ch {
fmt.Println(value)
}Question 11
What is a deadlock in channel operations?
ch := make(chan int)
ch <- 42 // Deadlock - no receiverQuestion 12
How do you implement a worker pool with channels?
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
}
}Question 13
What is the select statement used for?
select {
case x := <-ch1:
fmt.Println("Received from ch1:", x)
case y := <-ch2:
fmt.Println("Received from ch2:", y)
}Question 14
What happens in a select with no ready cases?
select {
case <-ch1:
// ch1 not ready
case <-ch2:
// ch2 not ready
// Blocks here
}Question 15
How do you make select non-blocking?
select {
case x := <-ch:
fmt.Println(x)
default:
fmt.Println("No value ready")
}Question 16
What is the nil channel behavior?
var ch chan int // nil
select {
case <-ch:
// never selected
}Question 17
How do you implement a timeout with channels?
select {
case result := <-ch:
fmt.Println(result)
case <-time.After(5 * time.Second):
fmt.Println("Timeout")
}Question 18
What is the fan-in pattern?
func fanIn(ch1, ch2 <-chan int) <-chan int {
c := make(chan int)
go func() { for { c <- <-ch1 } }()
go func() { for { c <- <-ch2 } }()
return c
}Question 19
What is the fan-out pattern?
Question 20
How do you safely close a channel?
func producer(ch chan<- int) {
defer close(ch)
for i := 0; i < 10; i++ {
ch <- i
}
}Question 21
What is the comma ok idiom?
value, ok := <-ch
if !ok {
// channel closed
}Question 22
How do you implement a pipeline with channels?
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
}Question 23
What is channel capacity vs length?
ch := make(chan int, 10)
fmt.Println(cap(ch)) // 10
fmt.Println(len(ch)) // 0Question 24
How do you iterate over a channel until closed?
for value := range ch {
fmt.Println(value)
}
// Automatically stops when ch closesQuestion 25
What happens when buffer is full?
ch := make(chan int, 1)
ch <- 1 // ok
ch <- 2 // blocksQuestion 26
How do you implement a semaphore with channels?
semaphore := make(chan struct{}, maxConcurrent)
func worker() {
semaphore <- struct{}{} // acquire
defer func() { <-semaphore }() // release
// do work
}Question 27
What is the problem with multiple closers?
go func() { close(ch) }()
go func() { close(ch) }() // PanicQuestion 28
How do you handle closed channels in select?
select {
case v, ok := <-ch:
if !ok {
// channel closed
return
}
// use v
}Question 29
What is a channel of channels?
ch := make(chan chan int)
workerCh := make(chan int)
ch <- workerChQuestion 30
How do you implement a done channel pattern?
done := make(chan struct{})
go func() {
// do work
close(done)
}()
// Wait for completion
<-doneQuestion 31
What is the difference between len(ch) and cap(ch)?
Question 32
How do you implement non-blocking send?
select {
case ch <- value:
// sent successfully
default:
// would block
}Question 33
What is the producer-consumer pattern?
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)
}
}Question 34
How do you avoid channel leaks?
Question 35
What is the most important channel best practice?
