Bird
Raised Fist0
Goprogramming~5 mins

Buffered and unbuffered channels in Go

Choose your learning style10 modes available
Introduction

Channels let different parts of a Go program talk to each other safely. Buffered and unbuffered channels control how messages wait or pass instantly.

When you want to send data between two parts of a program without mixing them up.
When you want the sender to wait until the receiver is ready (unbuffered).
When you want the sender to send some messages and keep going without waiting (buffered).
When you want to control how many messages can wait before the receiver takes them.
When you want to avoid your program freezing because one part waits too long.
Syntax
Go
var ch chan int               // unbuffered channel
ch = make(chan int)           // create unbuffered channel

var chBuffered chan int
chBuffered = make(chan int, 3) // create buffered channel with capacity 3

An unbuffered channel has no space to hold messages; sender waits for receiver.

A buffered channel has space to hold some messages; sender waits only if buffer is full.

Examples
This example shows an unbuffered channel where send waits for receive.
Go
ch := make(chan int) // unbuffered channel
// Note: sending and receiving on unbuffered channels must be synchronized
// The following lines should be used with goroutines to avoid deadlock
// For example:
// go func() { ch <- 5 }()
// x := <-ch
This example shows a buffered channel where sends do not wait until buffer is full.
Go
ch := make(chan int, 2) // buffered channel with capacity 2
ch <- 1                 // send 1, does not wait
ch <- 2                 // send 2, does not wait
// ch <- 3 would wait here because buffer is full
x := <-ch               // receive first value
Sample Program

This program shows how unbuffered channels make the sender wait until the receiver gets the message, while buffered channels allow sending multiple messages without waiting until the buffer is full.

Go
package main

import (
	"fmt"
	"time"
)

func main() {
	// Unbuffered channel example
	unbuf := make(chan string)

	go func() {
		unbuf <- "hello"
		fmt.Println("Sent to unbuffered channel")
	}()

	time.Sleep(time.Second) // wait a bit
	msg := <-unbuf
	fmt.Println("Received from unbuffered channel:", msg)

	// Buffered channel example
	buf := make(chan string, 2)

	buf <- "hi"
	buf <- "there"
	fmt.Println("Sent two messages to buffered channel")

	fmt.Println("Received from buffered channel:", <-buf)
	fmt.Println("Received from buffered channel:", <-buf)
}
OutputSuccess
Important Notes

Unbuffered channels are good when you want strict synchronization between sender and receiver.

Buffered channels help improve performance by letting senders continue without waiting immediately.

Be careful: sending to a full buffered channel or receiving from an empty unbuffered channel blocks the program until the other side is ready.

Summary

Channels let parts of a Go program communicate safely.

Unbuffered channels make sender wait for receiver.

Buffered channels let sender send multiple messages without waiting until buffer is full.

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