Опыт использования примитивов синхронизации потоков
Что проверяют
Работали ли вы с конкурентностью руками или только читали про горутины. Интервьюер слушает, подбираете ли вы инструмент под задачу и знаете ли, чем ловят гонки, а не пересказ списка из документации.
Как отвечать
Скажите сразу, что в Go два способа синхронизации, и выбор между ними и есть содержание ответа.
Разделяемое состояние закрывается sync.Mutex; если читателей много, а записи редки, берут sync.RWMutex. Счётчики и флаги дешевле через sync/atomic, вообще без блокировки. Дождаться группу горутин помогает sync.WaitGroup, инициализировать ровно один раз sync.Once, оборвать работу по таймауту или сигналу context.Context. sync.Cond в прикладном коде почти не встречается, его роль обычно берёт канал.
Второй способ это передача владения данными через каналы. Небуферизованный канал сам по себе точка встречи: отправитель ждёт получателя. Буферизованный работает как очередь с ограничением, и на нём собирают пул воркеров: горутины читают общий канал задач, пишут в канал результатов, а закрытие канала задач останавливает всех сразу.
var mu sync.Mutex
seen := map[string]int{}
mu.Lock()
seen[key]++
mu.Unlock()Закончите тем, чем гонки ловят: go test -race и стенд, собранный с -race. Гонка это не только две одновременные записи, но и чтение параллельно с записью, и без детектора она годами не проявляется.
Где спотыкаются
Копируют структуру, внутри которой лежит мьютекс: передали по значению, и блокировка досталась копии, а защищаемые данные остались общими. Такие структуры передают только указателем, а go vet про копирование предупреждает.
Захватывают мьютекс и не освобождают его на всех путях. Ранний return по ошибке оставляет блокировку навсегда, и следующий вызов виснет. Отсюда привычка писать defer mu.Unlock() сразу за Lock. Обратная крайность не лучше: держать блокировку на время сетевого запроса значит превратить её в узкое место.
Повторяют как заклинание, что каналы всегда лучше мьютексов. Канал дороже и труднее в отладке, а для защиты счётчика или карты мьютекс проще и быстрее. Каналы выигрывают там, где данные надо передать между этапами, а не там, где их надо просто защитить.