Коррекция замыкания и взаимодействие с планировщиком

Для Go 1.21 передайте idx аргументом горутины и дождитесь всех через WaitGroup. Исходник не гарантирует ни полный вывод, ни правильный захват индексов.

Короткий ответ

Что ответить на собеседовании

Для Go 1.21 передайте idx аргументом горутины и дождитесь всех через WaitGroup. Исходник не гарантирует ни полный вывод, ни правильный захват индексов.

Подробный разбор

Ответ с пояснениями

Условие

Необходимо поправить программу, чтобы она надёжно выводила числа от 0 до 9. После исправления следует объяснить, как внутри планировщика Go происходит распределение работы. Какие результаты выдаст приведённый фрагмент при запуске на Go 1.21? Как гарантировать, что на экран появятся все числа от 0 до 9? Охарактеризуйте, каким образом планировщик распределяет горутины и почему это связано с тем, как захватывается переменная цикла.

func main() {
    for idx := 0; idx < 10; idx++ {
        go func() {
            fmt.Println(idx)
        }()
    }
}

Ответ

Для Go 1.21 передайте idx аргументом горутины и дождитесь всех через WaitGroup. Исходник не гарантирует ни полный вывод, ни правильный захват индексов.

Исправление:

func main() {
    var wg sync.WaitGroup
    for idx := 0; idx < 10; idx++ {
        wg.Add(1)
        go func(idx int) {
            defer wg.Done()
            fmt.Println(idx)
        }(idx)
    }
    wg.Wait()
}

Нужны fmt и sync. Печатаются все числа 0–9, но не обязательно по порядку. Планировщик распределяет горутины G по потокам M через ресурсы P; GOMAXPROCS ограничивает одновременное выполнение Go-кода. Захват общей переменной определяется семантикой языка, а планирование лишь делает гонку наблюдаемой. В Go 1.21 без локальной копии цикл переиспользует idx.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее