Назад к вопросам
OZON
Senior
3
//Что будет выведено при запуске программы: func main() { counter := make([]int, 0, 1000) var wg sync.WaitGroup for i := 0; i < 1000; i++ { wg.Add(1) go func() { defer wg.Done() counter = append(counter, i) time.Sleep(10 * time.Millisecond) // Имитация работы }() } wg.Wait() fmt.Println(len(counter)) }
Компании, где спрашивали
Ответ от нейросети
sobes.tech AI
В этом коде есть проблема с конкурентным доступом к срезу counter из нескольких горутин без синхронизации.
Каждая горутина пытается выполнить counter = append(counter, i), но:
appendне является атомарной операцией и может изменить underlying array,- одновременный доступ без блокировок приводит к гонкам данных (data race),
- переменная
iв замыкании не захватывается корректно (все горутины используют одно и то же значениеiпосле цикла).
Что будет выведено:
- Скорее всего, программа упадёт с паникой из-за одновременного изменения среза без защиты,
- Если паника не произойдёт, длина
counterбудет меньше 1000 или непредсказуемой, из-за гонок.
Правильный вариант — захватить i в аргумент функции и использовать мьютекс для защиты среза:
func main() {
counter := make([]int, 0, 1000)
var mu sync.Mutex
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
wg.Add(1)
go func(val int) {
defer wg.Done()
mu.Lock()
counter = append(counter, val)
mu.Unlock()
time.Sleep(10 * time.Millisecond)
}(i)
}
wg.Wait()
fmt.Println(len(counter)) // 1000
}
Итог: исходный код содержит гонки данных и неправильное захватывание переменной i, что приведёт к ошибкам и непредсказуемому результату.