В представленном коде есть несколько ошибок и потенциальных проблем:
// Что выведет код?
В представленном коде есть несколько ошибок и потенциальных проблем:
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
// Что выведет код? func main() { var wg sync.WaitGroup for i := 0; i < 3; i++ { go func() { wg.Add(1) defer wg.Done() fmt.Print(i) }() } wg.Wait() fmt.Println("\ndone") }
Ответ
В представленном коде есть несколько ошибок и потенциальных проблем:
- Опечатка в параметре функции:
sync.WaitGropвместоsync.WaitGroup. - В цикле
for i := 0; i < 10; i++вызываетсяwg.Add(8), но запускается 10 горутин — это приведёт к дедлоку, так какwg.Done()будет вызвано 10 раз, а ожидание — только 8. - Передача переменной
iв замыкание корректная, так какiпередаётся как параметр, что предотвращает классическую ошибку с замыканиями в цикле.
Исправленный пример:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
wg.Add(10) // Количество горутин должно совпадать с Add
for i := 0; i < 10; i++ {
go func(wg *sync.WaitGroup, i int) {
defer wg.Done()
fmt.Println(i)
}(&wg, i)
}
wg.Wait()
fmt.Println("some text")
time.Sleep(1 * time.Minute)
fmt.Println("some text2")
}
Таким образом, код корректно создаёт 10 горутин, каждая из которых выводит своё значение i, затем основной поток ждёт завершения всех горутин, выводит "some text", ждёт минуту и выводит "some text2".