func (r *PayoutRepository) Payout(advertiserID, partnerID string, amount float32) error {

Выплата должна быть атомарной и идемпотентной: деньги нельзя хранить в float32, а независимые save допускают частичное обновление и гонки.

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

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

Выплата должна быть атомарной и идемпотентной: деньги нельзя хранить в float32, а независимые save допускают частичное обновление и гонки.

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

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

Условие

func (r *PayoutRepository) Payout(advertiserID, partnerID string, amount float32) error { advertiser, err := r.find(advertiserID) if err != nil { return err } partner, err := r.find(partnerID) if err != nil { return err }

advertiser.Balance -= amount
partner.Hold -= amount
partner.Balance += amount

if err := r.save(advertiser); err != nil {
    return err
}
if err := r.save(partner); err != nil {
    return err
}

r.totalPayouts++
return nil

}

Ответ

Выплата должна быть атомарной и идемпотентной: деньги нельзя хранить в float32, а независимые save допускают частичное обновление и гонки.

Используйте целые минимальные денежные единицы или точный decimal. Проверьте положительность суммы, доступный баланс и смысл списания Hold: текущий код может делать его отрицательным. Обновляйте счета в одной транзакции, блокируя их в стабильном порядке; случай совпадения advertiserID и partnerID обработайте отдельно. Уникальный ключ операции защищает от повторной выплаты. totalPayouts++ также гоняется между потоками и не является надёжным финансовым журналом; успешные выплаты лучше учитывать по зафиксированным операциям.

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

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

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

Подробнее