Что происходит при записи в небуферизированный канал дважды подряд: будет ли дедлок или паника
Что проверяют
Различаете ли вы блокировку, фатальную ошибку рантайма и панику. Это три разных исхода с разными последствиями, и вопрос ровно о том, какой из них тут.
Как отвечать
Небуферизированный канал это рандеву: отправка завершается только в тот момент, когда получатель забирает значение. Значит блокируется уже первая запись, а не вторая.
ch := make(chan int)
ch <- 1 // встаём здесь
ch <- 2 // сюда не дойдёмЕсли это единственная горутина и читателя нет, планировщик видит, что все горутины спят, и роняет программу с фатальной ошибкой о том, что все горутины уснули и это дедлок. Слово важно: именно фатальная ошибка, а не паника. recover её не перехватывает, отложенные функции не выполняются, процесс завершается с дампом стеков всех горутин. Паника у каналов бывает в других случаях: отправка в закрытый канал, повторное закрытие, закрытие нулевого канала.
Дальше стоит добавить оговорку, которая отличает сильный ответ. Детектор срабатывает только когда спят вообще все горутины. Достаточно одной, сидящей в time.Sleep, ждущей сокет или системный вызов, и рантайм тупиком это не считает: сообщения не будет, программа просто повиснет навсегда, и разбираться придётся по дампу горутин.
Если читатель есть в другой горутине, обе записи пройдут, каждая дождавшись своего приёма.
Где спотыкаются
Отвечают, что будет паника. Паники нет, и для обработки ошибок это принципиально: дедлок не превратится в аккуратно перехваченную ошибку ни в тесте, ни в сервисе, он убьёт процесс целиком.
Второе: считают, что программа просто подождёт и как-нибудь продолжится. Ждать нечего, состояние необратимо, и рантайм именно поэтому предпочитает упасть с понятным сообщением, а не висеть молча.
Третье: пробуют доказать обратное примером, где запись идёт в отдельной горутине, а главная читает один раз и завершается. Вторая отправка там действительно остаётся висеть, но программа выходит по завершении главной горутины, и это другой сценарий, а не отсутствие дедлока.