a common mistake when using Channel Creation
Fast recall
Quick revision
Core answer
Practical understanding of Channel Creation.
Repeating a definition without saying when to use it.
Give one trade-off and say how you would test it.
Interview-ready guide
Interview answer
The zero value of a channel is nil, and using it for either direction blocks forever:
var ch chan int // nil
ch <- 1 // blocks forever
<-ch // also blocks foreverNot a panic — a silent, permanent block. If other goroutines can still make progress, the program runs on with the blocked goroutine leaked. If ALL goroutines block, the runtime's deadlock detector fires: fatal error: all goroutines are asleep - deadlock! — the one way this failure becomes visible.
The classic real-world bug: declaring a channel field or variable, intending to initialize it later, and a code path reaches the send before the make. The fix is structural: initialize at declaration (ch := make(...) or in a constructor) rather than 'later'.
One deliberate use exists: a nil channel in a select is a permanently-disabled case — select skips nil channels. That's the standard way to turn a case off (setting a channel variable to nil disables that branch) rather than building a state machine of separate selects. It's advanced but worth knowing: nil isn't always a bug — in select it's a switch.
a common mistake when using Channel Creation
Direct Answer
Blocks forever — a nil channel has no runtime structure, so the send parks permanently. If all goroutines end up blocked, the runtime reports a deadlock.
Deep Dive & Architecture
Why block forever instead of panicking like a nil map write? The operations differ mechanically. A map write must find a bucket and insert — there is no honest answer to 'where?' without a structure, and Go refuses to guess: panic. A channel send must enqueue the goroutine onto a wait queue — and 'wait indefinitely' IS expressible without a structure: park the goroutine and never wake it. The runtime treats nil as a wait-queue that never advances.
The asymmetry with nil maps is deliberate design: map-write failure is immediate and needs an error channel (panic); channel-send 'failure' is defined as waiting — the only question is for how long, and nil answers 'forever'.
The deadlock detector: the runtime periodically checks whether ANY goroutine can run. If every goroutine is parked (on channels, mutexes, or waiting for timers), no progress is possible — the program is deadlocked, and the runtime prints the state of every goroutine and exits. That dump is the diagnosis: the goroutine stacks show which channel operation each is stuck on, and a nil channel shows as a nil in the stack trace's argument. The detector only fires when ALL goroutines are blocked — one running goroutine (a timer, a network poller, a leaky loop) hides the deadlock forever, which is why nil-channel bugs in servers present as 'this request hangs' rather than 'the program died'.
Common Mistakes & Pitfalls
Repeating a definition without saying when to use it.
Check your understanding
Answer these without looking back at the article.
- What is Channel Creation, and when would you use it?
- When would you use Channel Creation in a real project?
- How would you compare Channel Creation with an alternative?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.