Дедлок — ситуация когда горутины ждут друг друга и ни одна не может продолжить.
Типичные случаи:
// 1. Чтение из небуферизованного канала без отправителя
ch := make(chan int)
<-ch // deadlock!
// 2. Взаимная блокировка мьютексов
// Горутина 1: Lock(A) → Lock(B)
// Горутина 2: Lock(B) → Lock(A)
// 3. WaitGroup без Done
var wg sync.WaitGroup
wg.Add(1)
wg.Wait() // никто не вызовет Done
// 4. Полный буферизованный канал в одной горутине
ch := make(chan int, 1)
ch <- 1
ch <- 2 // deadlock — буфер полон, читатель нет
Go runtime обнаруживает глобальный дедлок (все горутины заблокированы) и паникует. Частичный дедлок не обнаруживается — используй go test -timeout.