Bird
Raised Fist0
Goprogramming~10 mins

Buffered and unbuffered channels in Go - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Buffered and unbuffered channels
Create channel
↓
Send data
↓
Unbuffered?
↓
Wait receiver
↓
Receiver ready
↓
Data received
Shows how data is sent and received differently in unbuffered and buffered channels.
Execution Sample
Go
ch := make(chan int) // unbuffered

// goroutine to send
go func() {
	ch <- 42
}()

// main goroutine receives
val := <-ch
This code creates an unbuffered channel, sends a value, and receives it, showing synchronization.
Execution Table
StepActionChannel StateSender Blocked?Receiver Blocked?Output
1Create unbuffered channelemptyNoNo
2Send 42 to channelempty (waiting for receiver)YesNo
3Receive from channelemptyNoNo42
4Send completesemptyNoNo42
5Program endsemptyNoNo42
💡 Send blocks until receive happens; after receive, send completes and value is output.
Variable Tracker
VariableStartAfter Step 2After Step 3Final
ch (channel)emptywaiting for receiveremptyempty
val (received)undefinedundefined4242
Key Moments - 2 Insights
Why does the send operation block in an unbuffered channel?
Because unbuffered channels require a receiver to be ready before the send can complete, as shown in step 2 of the execution_table.
What happens to the channel state after the receiver reads the value?
The channel becomes empty again, allowing the send to complete, as seen in step 3 and 4 of the execution_table.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, at which step does the sender stop being blocked?
AStep 4
BStep 2
CStep 3
DStep 5
💡 Hint
Check the 'Sender Blocked?' column in execution_table rows for steps 2 to 4.
According to variable_tracker, what is the value of 'val' after step 3?
A42
B0
Cundefined
Dempty
💡 Hint
Look at the 'val (received)' row and 'After Step 3' column in variable_tracker.
If the channel was buffered with capacity 1, how would the sender behave at step 2?
ASender blocks until receiver reads
BSender does not block and stores value in buffer
CSender blocks forever
DSender skips sending
💡 Hint
Buffered channels allow one value to be stored without blocking; compare with unbuffered behavior in execution_table.
Concept Snapshot
Channels in Go can be unbuffered or buffered.
Unbuffered channels block the sender until the receiver is ready.
Buffered channels store values up to their capacity without blocking.
Use make(chan Type, capacity) to create buffered channels.
Send blocks if buffer is full; receive blocks if buffer is empty.
Full Transcript
This visual execution shows how unbuffered channels in Go synchronize sending and receiving. When a channel is unbuffered, sending a value blocks until another goroutine receives it. The channel state changes from empty to waiting for a receiver during send, then back to empty after receive. Variables track the channel state and received value. Key moments include understanding why send blocks and how the channel empties after receive. The quiz tests understanding of blocking behavior and variable values. Buffered channels differ by allowing sends without immediate receive if buffer space exists.

Practice

(1/5)
1. What is the main difference between a buffered and an unbuffered channel in Go?
easy
A. Buffered channels allow sending multiple values without waiting, unbuffered channels require receiver ready.
B. Unbuffered channels store values internally, buffered channels do not.
C. Buffered channels block the sender until the receiver reads, unbuffered channels never block.
D. Unbuffered channels can only send strings, buffered channels can send any type.

Solution

  1. Step 1: Understand unbuffered channel behavior

    Unbuffered channels require the sender to wait until the receiver is ready to receive the value.
  2. Step 2: Understand buffered channel behavior

    Buffered channels have a capacity to hold multiple values, so the sender can send without waiting until the buffer is full.
  3. Final Answer:

    Buffered channels allow sending multiple values without waiting, unbuffered channels require receiver ready. -> Option A
  4. Quick Check:

    Buffered vs unbuffered = sender wait or not [OK]
Hint: Buffered = sender can send without waiting until full [OK]
Common Mistakes:
  • Thinking unbuffered channels store values internally
  • Believing buffered channels never block sender
  • Confusing data types allowed in channels
2. Which of the following is the correct way to create a buffered channel of integers with capacity 3 in Go?
easy
A. ch := make(chan int)
B. ch := make(chan int[3])
C. ch := make(chan int, 3)
D. ch := new(chan int, 3)

Solution

  1. Step 1: Recall syntax for buffered channel creation

    Buffered channels are created with make(chan Type, capacity). Here, capacity is 3.
  2. Step 2: Check each option

    ch := make(chan int, 3) uses make(chan int, 3) which is correct. ch := make(chan int) creates unbuffered channel. ch := make(chan int[3]) has invalid syntax. ch := new(chan int, 3) uses new which is incorrect for channels.
  3. Final Answer:

    ch := make(chan int, 3) -> Option C
  4. Quick Check:

    Buffered channel syntax = make(chan Type, capacity) [OK]
Hint: Use make(chan Type, capacity) for buffered channels [OK]
Common Mistakes:
  • Omitting capacity creates unbuffered channel
  • Using new() instead of make()
  • Incorrect syntax with array notation
3. What will be the output of this Go program?
package main
import "fmt"
func main() {
  ch := make(chan int)
  go func() {
    ch <- 10
  }()
  fmt.Println(<-ch)
}
medium
A. Compilation error
B. 10
C. Deadlock error
D. 0

Solution

  1. Step 1: Analyze channel type and goroutine

    The channel ch is unbuffered. The goroutine sends 10 to ch, and main receives from ch.
  2. Step 2: Understand synchronization

    Because the send and receive happen in separate goroutines, the send blocks until receive is ready, so the program runs without deadlock and prints 10.
  3. Final Answer:

    10 -> Option B
  4. Quick Check:

    Unbuffered channel with goroutine send = prints sent value [OK]
Hint: Unbuffered channel blocks sender until receiver ready [OK]
Common Mistakes:
  • Expecting deadlock without goroutine
  • Thinking unbuffered channel stores default zero
  • Confusing compilation error with runtime behavior
4. Consider this Go code snippet:
ch := make(chan int, 2)
ch <- 1
ch <- 2
ch <- 3
fmt.Println(<-ch)
What is the problem with this code?
medium
A. It causes a compilation error due to wrong syntax.
B. It prints 3 because the last value overwrites the buffer.
C. It compiles but prints 0 because channel is empty.
D. It causes a deadlock because the buffered channel is full before the third send.

Solution

  1. Step 1: Check channel buffer capacity and sends

    The channel has capacity 2. Two sends fill the buffer. The third send blocks because buffer is full and no receiver yet.
  2. Step 2: Understand blocking behavior

    Since no goroutine is receiving before the third send, the program deadlocks at third send.
  3. Final Answer:

    It causes a deadlock because the buffered channel is full before the third send. -> Option D
  4. Quick Check:

    Buffered channel full + send without receive = deadlock [OK]
Hint: Buffered channel blocks sender when full without receiver [OK]
Common Mistakes:
  • Assuming buffer overwrites old values
  • Expecting zero printed from empty channel
  • Confusing syntax error with runtime deadlock
5. You want to send 5 integers to a channel without blocking the sender immediately. Which of these code snippets correctly achieves this using buffered channels?
Option A:
ch := make(chan int, 5)
for i := 1; i <= 5; i++ {
  ch <- i
}

Option B:
ch := make(chan int)
for i := 1; i <= 5; i++ {
  ch <- i
}

Option C:
ch := make(chan int, 3)
for i := 1; i <= 5; i++ {
  ch <- i
}

Option D:
ch := make(chan int, 0)
for i := 1; i <= 5; i++ {
  ch <- i
}
hard
A. Option A only
B. Option B only
C. Option C only
D. Option D only

Solution

  1. Step 1: Understand buffered channel capacity

    To send 5 integers without blocking immediately, the channel buffer must be at least 5.
  2. Step 2: Analyze each snippet's buffer size

    The first snippet creates a channel with capacity 5, allowing all 5 sends without blocking. The second creates an unbuffered channel, blocking the sender immediately on the first send. The third has capacity 3, blocking on the fourth send. The fourth has capacity 0 (unbuffered), blocking immediately.
  3. Final Answer:

    Option A only -> Option A
  4. Quick Check:

    Buffer size >= sends to avoid blocking [OK]
Hint: Buffer size must match sends to avoid blocking [OK]
Common Mistakes:
  • Using unbuffered channels expecting no blocking
  • Choosing smaller buffer than sends
  • Misunderstanding buffer size zero means unbuffered
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard