Что такое гонка данных в Go и как её найти?
- Что делает флаг -race?
Гонка данных — две горутины обращаются к одной переменной одновременно, и хотя бы одна пишет, без синхронизации. Результат непредсказуем, а для мап и срезов возможна порча структуры. go test -race / go run -race включает детектор: он отслеживает обращения и печатает стеки обеих сторон гонки.
- Детектор находит только гонки, которые произошли при запуске — нужны тесты с конкурентностью
- Замедление в 2–20 раз и больше памяти — включают в CI, а не в проде
- Исправление: мьютекс, канал, atomic или отказ от общего состояния
А ещё Переменная цикла в горутине — классическая гонка до Go 1.22
Подробно
var counter int
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() { defer wg.Done(); counter++ }() // гонка
}
wg.Wait()
go run -race main.go выведет «WARNING: DATA RACE» со стеками записи и чтения.
Модель памяти Go: без синхронизации (каналы, мьютексы, атомики, WaitGroup) нет гарантии, что одна горутина увидит запись другой. Гонка — это не только потеря обновлений, но и чтение «разорванных» значений: интерфейсы и срезы состоят из нескольких слов.
Практика: -race во всех тестах в CI; конкурентные тесты, которые реально запускают код параллельно; при сообщении детектора — не глушить, а исправлять.
Что хотят услышать
- Определение гонки данных.
- Флаг -race и его ограничения.
- Способы исправления.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Детектор находит все гонки статическим анализом исходников, без запуска программы
- ✓Несинхронный доступ к переменной с записью; ловит go test -race
- ✗Гонка данных невозможна в Go благодаря горутинам
- ✗Детектор гонок стоит включать только в продакшене
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.