Почему в Go можно создать тысячи горутин
Что проверяют
Понимаете ли вы, за счёт чего горутина дешёвая, и знаете ли, что бесконечно их плодить всё же нельзя.
Как отвечать
Три причины.
Маленький стек. Горутина стартует примерно с 2 КБ и растёт по мере необходимости: рантайм выделяет новый стек больше и копирует содержимое. У потока операционной системы стек фиксирован, обычно 1 или 8 МБ, и резервируется сразу. Миллион горутин по 2 КБ это порядка двух гигабайт, миллион потоков не поместится никуда.
Дешёвое переключение. Горутины переключает планировщик Go в пользовательском пространстве, сохраняя лишь несколько регистров. Переход в ядро не нужен, поэтому переключение стоит десятки наносекунд против единиц микросекунд у потоков.
Мультиплексирование M:N. Горутины выполняются на небольшом пуле потоков (по числу ядер). Заблокировалась на сети, значит снимается с потока и передаётся сетевому опросчику, а поток идёт выполнять другую. Ждёт не поток, а epoll.
Обязательно добавьте ограничения, иначе ответ выглядит как реклама: горутины не бесплатны, каждая занимает память и попадает в очередь планировщика; неограниченный запуск на каждый входящий запрос это способ исчерпать память; горутина, застрявшая на канале, живёт до конца процесса, и это самая частая утечка в Go. Поэтому в проде их ограничивают семафором на канале, пулом воркеров или errgroup.SetLimit.
Где спотыкаются
Говорят «горутины лёгкие» без единой цифры.
Не знают про рост стека копированием.
Считают, что горутину можно убить снаружи.
Запускают горутину на каждый элемент большого списка без ограничения.