Практическая задача: разбор кода go

Первый фрагмент делает пять вызовов для ID 42 и содержит data race на dbHits++. Второй при корректно объявленных once и user выполнит загрузку один раз.

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

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

Первый фрагмент делает пять вызовов для ID 42 и содержит data race на dbHits++. Второй при корректно объявленных once и user выполнит загрузку один раз.

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

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

Условие

type User struct {
    ID   int
    Name string
}

var (
    dbHits int
)

func getUserInfoFromDB(id int) User {
    time.Sleep(100 * time.Millisecond)
    dbHits++
    return User{ID: id, Name: fmt.Sprintf("User-%d", id)}
}

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)

        go func(i int) {
            defer wg.Done()
            fmt.Println(getUserInfoFromDB(i))
        }(42)
    }
    wg.Wait()
    fmt.Println("Обращений к базе данных:", dbHits)
}
func main() {
    var wg sync.WaitGroup

    j := 12345

    for i := 0; i < 5000; i++ {
        wg.Add(1)

        go func(i int) {
            defer wg.Done()
            once.Do(func() {
                user = getUserInfoFromDB(42)
            })

            fmt.Println(user)
        }(j)
    }
    wg.Wait()
    fmt.Println("Обращений к базе данных:", dbHits)
}

Ответ

Первый фрагмент делает пять вызовов для ID 42 и содержит data race на dbHits++. Второй при корректно объявленных once и user выполнит загрузку один раз.

В первом примере порядок печати не определён, а точное значение счётчика нельзя гарантировать из-за несинхронизированного инкремента. WaitGroup ждёт завершения, но не защищает конкурентные записи. Во втором нужны общие var once sync.Once и var user User; возврат once.Do гарантирует завершение единственной инициализации и безопасное чтение результата. Это решение подходит только одному пользователю: для разных ID нужен keyed-кэш, а для подавления одновременно повторяющихся загрузок — подходящий механизм координации.

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

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

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

Подробнее