Реализуйте два потокобезопасных счётчика, которые корректно работают при
инкременте из тысяч горутин одновременно.
Первый счётчик защищён мьютексом, второй построен на пакете sync/atomic.
type MutexCounter struct {
// ...
}
func (c *MutexCounter) Inc()
func (c *MutexCounter) Value() int64
type AtomicCounter struct {
// ...
}
func (c *AtomicCounter) Inc()
func (c *AtomicCounter) Value() int64
Тест запускает 1000 горутин, каждая делает 1000 вызовов Inc() на каждом
счётчике. После завершения Value() обязан вернуть ровно 1 000 000.
Проверка идёт под детектором гонок (-race).
На что смотрит интервьюер:
MutexCounter корректно сериализует доступ через sync.Mutex
(lock/unlock вокруг чтения и записи), нет гонок под -race.
AtomicCounter использует atomic.AddInt64 / atomic.LoadInt64
(или atomic.Int64) — без мьютекса.
- Кандидат может объяснить, какой счётчик быстрее под высокой конкуренцией
и почему: atomic обычно быстрее, так как одна аппаратная
CAS/FAA-инструкция дешевле, чем блокировка мьютекса с возможной парковкой
горутины и переключением контекста.