Что такое netpoller в Linux
Что проверяют
Знаете ли вы, почему в Go сетевой код пишется синхронно, а масштабируется как асинхронный. Вопрос отделяет тех, кто представляет себе рантайм, от тех, кто просто пишет go перед вызовом функции.
Как отвечать
Сразу поправьте формулировку: netpoller это часть рантайма Go, а не подсистема Linux. Внутри он опирается на механизм опроса конкретной операционной системы: epoll на Linux, kqueue на BSD и macOS, порты завершения на Windows.
Схема такая. Сокет, созданный через пакет net, переводится в неблокирующий режим и регистрируется в опросчике. Горутина читает из него обычным синхронным вызовом; если данных нет, ядро отвечает признаком «пока нечего», рантайм паркует горутину и отцепляет её от системного потока, а поток уходит выполнять другие горутины. Когда опросчик сообщает о готовности дескриптора, планировщик возвращает горутину в очередь исполнения. Отсюда и картина: десятки тысяч соединений живут на нескольких потоках, а код читается как блокирующий. Таймауты через SetDeadline устроены на том же механизме.
Полезно очертить границу: обычные файлы на диске таким опросом не обслуживаются, поэтому файловый ввод-вывод и вызовы через cgo занимают поток целиком.
Где спотыкаются
Повторяют формулировку про механизм Linux и не могут объяснить, что тогда происходит на macOS. Netpoller это абстракция рантайма над несколькими реализациями, а в самом ядре Linux слово netpoll занято другой вещью, аварийной отправкой пакетов в обход сетевого стека.
Путают уровни и говорят, что каждая горутина это поток или что рантайм заводит поток на соединение. Потоков примерно столько, сколько ядер, плюс занятые в блокирующих вызовах.
Думают, что раз сеть не блокирует, не блокирует ничего. Чтение файла, вызов C-библиотеки через cgo и любой блокирующий системный вызов держат поток целиком; на сотнях таких вызовов рантайм плодит потоки, и выигрыш опросчика теряется.