Гонки данных в небезопасном счётчике

SafeCounter не является безопасным: ++ состоит из чтения и записи, а map одновременно меняют многие горутины. Нужны mutex и явное ожидание завершения.

Короткий ответ

Что ответить на собеседовании

SafeCounter не является безопасным: ++ состоит из чтения и записи, а map одновременно меняют многие горутины. Нужны mutex и явное ожидание завершения.

Подробный разбор

Ответ с пояснениями

Условие

В примере реализован простой счётчик, который предполагается использовать в многопоточной среде, однако доступ к общей структуре происходит без какой‑либо синхронизации. Нужно понять, какие ошибки возникают при одновременных вызовах методов и как правильно защитить внутреннее состояние от race‑condition.

type SafeCounter struct {
    values map[string]int
}

func (ctr *SafeCounter) Inc(key string) {
    ctr.values[key]++
}

func (ctr *SafeCounter) Value(key string) int {
    return ctr.values[key]
}

func main() {
    counter := SafeCounter{values: make(map[string]int)}
    for i := 0; i < 1000; i++ {
        go counter.Inc("somekey")
    }

    time.Sleep(time.Second)
    fmt.Println(counter.Value("somekey"))
}

Ответ

SafeCounter не является безопасным: ++ состоит из чтения и записи, а map одновременно меняют многие горутины. Нужны mutex и явное ожидание завершения.

Защита методов:

type SafeCounter struct {
    mu sync.RWMutex
    values map[string]int
}
func (c *SafeCounter) Inc(key string) {
    c.mu.Lock()
    defer c.mu.Unlock()
    if c.values == nil { c.values = make(map[string]int) }
    c.values[key]++
}
func (c *SafeCounter) Value(key string) int {
    c.mu.RLock()
    defer c.mu.RUnlock()
    return c.values[key]
}

Подключите sync. В main перед каждым go делайте wg.Add(1), внутри — defer wg.Done(), после цикла — wg.Wait() вместо Sleep. Тогда при тысяче успешных Inc значение будет 1000. Чтение тоже обязано брать блокировку; нельзя копировать счётчик с использованным mutex.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее