TGStat
TGStat
Введите текст для поиска
Расширенный поиск каналов
  • flag Russian
    Язык сайта
    flag Russian flag English flag Uzbek
  • Вход на сайт
  • Каталог
    Каталог каналов и чатов Региональные подборки Тематические подборки Платные каналы Поиск каналов
    Добавить канал/чат
  • Рейтинги
    Рейтинг каналов Рейтинг чатов Рейтинг публикаций
    Рейтинги брендов и персон
  • Аналитика
  • Поиск по публикациям
  • Мониторинг Telegram
  • Продвижение
    Реклама через Яндекс Бизнес Реклама в каналах через TGStat Agency Реклама на сайте TGStat.ru
Максим Карась | Golang ментор

16 Feb, 17:03

Открыть в Telegram Поделиться Пожаловаться

Планировщик Go: все что нужно знать на собесе (ч.1)

Планировщик в Go спрашивают на каждом втором собеседовании на мидла+ и синьора. Я прошел десятки собесов включая Яндекс, Тинькофф, ВК, ВБ и могу сказать точно: кто не знает глубже GMP модели, тот фейлит техничку

Разберем что реально спрашивают

Начнем с базы: зачем вообще нужен планировщик?

Представь наивный подход:

1 горутина = 1 поток ОС.

Работает? Да. Масштабируется? Нет, потому что потоки это дорого: жирный стек, переключение контекста, давление на планировщик OC

Поэтому в Go используется модель M:N, где множество горутин мультиплексируются на маленькое число потоков ОС. И именно для этого существует планировщик в рантайме


Три буквы, которые надо знать наизусть: G, M, P

→ G (goroutine) это единица работы, та самая легковесная горутина
→ M (machine) это реальный поток ОС, worker thread
→ P (processor) это контекст планирования, без которого поток M не может выполнять Go-код. По сути квота на исполнение


Скажешь это на собесе, интервьюер уже понимает что ты ахуй умный ♟

Готовая формулировка:

Go мультиплексирует множество G на меньшее число M, а P это квота и контекст исполнения Go-кода. Связка M+P дает возможность исполнять Go, а число P ограничивает параллелизм


Где лежат горутины, готовые к выполнению?

У каждого P есть локальная очередь (per-P runq), быстрая, без глобального лока. Плюс есть глобальная очередь для балансировки


Тут часто ловят на собесе: «а как обеспечивается справедливость в нагрузке?»

Большинство кандидатов в этот момент начинают мычать что-то невнятное. А ответ простой: P основную часть времени ест из локальной очереди (скорость + локальность), но раз в 61 тик проверяет глобальную, чтобы горутины там не голодали

Work stealing: когда один P пустой, а другой забит

Если у P нет работы в локальной очереди, он пытается украсть половину у другого P. Это основа балансировки: распределенное состояние + stealing вместо центрального лок-бутылочного горлышка


Spinning threads: почему рантайм не будит поток на каждую готовую горутину?

Потому что если будить на каждый чих, получишь thrashing park/unpark и все ляжет нахуй. Рантайм аккуратно управляет этим: будит новый поток только если есть idle P И нет spinning worker threads. Сначала ищут работу, и только потом паркуются


НО ВСЕ ЭТО БЫЛА ТОЛЬКО БАЗА

Самые жесткие вопросы на собесе начинаются дальше. Именно на них валятся 80% кандидатов, потому что читали статьи 2019 года и не знают, что изменилось. А интервьюеры это прекрасно видят

Системные вызовы: любимый вопрос для синьоров

«Что происходит, когда горутина делает блокирующий syscall?»

Если горутина залипает в syscall, поток M блокируется вместе с ней. Чтобы не остановить весь Go-код, рантайм делает handoff P: отвязывает P от заблокированного M и переезжает на другой свободный M. Runnable горутины продолжают выполняться


Сколько OS threads может создать Go программа?

Тут надо отвечать двумя слоями, иначе выглядишь как человек, который прочитал одну статью на хабре и пришел на собес

Слой 1: есть лимит, по умолчанию 10 000 потоков, настраивается через runtime/debug.SetMaxThreads

Слой 2: Go создает новый поток НЕ потому что «надо больше параллелизма», а когда все существующие потоки заблокированы в syscalls, cgo или залочены через LockOSThread

Формулировка для собеса:

«GOMAXPROCS ограничивает число P и тем самым число потоков, одновременно выполняющих Go-код. Но общее число OS threads может вырасти из-за syscalls/cgo/LockOSThread и ограничено SetMaxThreads»


На этом тормозим

Во второй части разберем вытеснение (кооперативное vs асинхронное), что изменилось в Go 1.14, GOMAXPROCS в 2026 и контейнерах, а также топ-вопросы с собесов с готовыми ответами. Там будет самый сок

Вторая часть выйдет через несколько дней

2k 3 135 61
Каталог
Каталог каналов и чатов Подборки каналов Поиск каналов Добавить канал/чат
Рейтинги
Рейтинг каналов Telegram Рейтинг чатов Telegram Рейтинг публикаций Рейтинги брендов и персон
API
API статистики API поиска публикаций API Callback
Наши каналы
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Почитать
Академия TGStat Исследование Telegram 2019 Исследование Telegram 2021 Исследование Telegram 2023
Контакты
Справочный центр Поддержка Почта Вакансии
Всякая всячина
Пользовательское соглашение Политика конфиденциальности Публичная оферта
Наши боты
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot