В чем разница между потоками ОС и горутинами в Go?
Что проверяют
Понимаете ли вы, что горутина это не поток операционной системы, и можете ли объяснить, чем рантайм платит за дешёвую конкурентность. Дальше обычно спрашивают про планировщик и каналы.
Как отвечать
Горутина это функция, запущенная рантаймом Go на своём стеке. Запуск стоит одного слова go и около 2 КБ памяти: стек начинается маленьким и растёт по мере надобности, поэтому сотни тысяч горутин это рабочая ситуация, а сотни тысяч потоков нет.
go worker(ch) // не системный вызов, а запись в очередь планировщикаОтличия от потоков:
- кто планирует: потоки переключает ядро, горутины планировщик Go в пользовательском пространстве, без перехода в ядро;
- сколько стоит: стек потока фиксирован (обычно 1 или 8 МБ), стек горутины начинается с 2 КБ и растёт копированием;
- как соотносятся: модель M:N, горутины мультиплексируются на пул потоков размером GOMAXPROCS. Блокирующий системный вызов занимает поток целиком, и рантайм заводит новый;
- как общаются: каналами, а не общей памятью. «Не общайтесь, разделяя память, разделяйте память, общаясь».
Где спотыкаются
Говорят «лёгкий поток» и останавливаются. Интервьюер ждёт, кто именно её переключает.
Не знают, что горутину нельзя убить снаружи: остановка это только контекст или закрытый канал.
Забывают про утечку горутин. Горутина, навсегда вставшая на чтении канала, живёт до конца процесса, и это обычный продовый баг.
Путают конкурентность и параллелизм: при GOMAXPROCS=1 горутины выполняются конкурентно, но не одновременно.