Go · 49 строк
Рейтинг продавца показывается на каждой карточке объявления. У крупного продавца автомобилей 3 тысячи объявлений, и после рассылки на его карточки за секунду приходит до 300 запросов. Чтобы не класть базу, одновременные запросы по одному продавцу схлопываются: в базу идёт первый, остальные ждут его результат.
Запрос к базе обычно 15 мс, в час пик бывают таймауты. Отметьте строки с ошибками.
В работе: Сервис карточки объявления, блок «Рейтинг продавца».
Как проверяем
Нажмите на строку с ошибкой и коротко напишите, что не так. Баг засчитан, если отмечена хотя бы одна его строка. Зачёт — найдено не меньше 60 % багов с учётом серьёзности (критичный весит 3, обычный 2, мелкий 1), а лишних отметок не больше, чем багов в коде. Пустые строки, скобки и комментарии лишними не считаем. Плюс 2 вопроса про поведение программы — на зачёт не влияют. Ответ один на подход: после него показываем разбор.
Источник: наша задача на данных Авито: рейтинг продавца на карточке объявления. Условие пересказано своими словами.
Давали на собеседовании?
package ratingimport ("context""sync")type call struct {done chan struct{}val float64err error}type Loader struct {mu sync.RWMutexcalls map[int64]*callfetch func(ctx context.Context, sellerID int64) (float64, error)}// Rating схлопывает одновременные запросы по продавцу в один запрос к базе.func (l *Loader) Rating(ctx context.Context, sellerID int64) (float64, error) {l.mu.RLock()c, ok := l.calls[sellerID]l.mu.RUnlock()if ok {<-c.donereturn c.val, c.err}c = &call{done: make(chan struct{})}l.mu.Lock()l.calls[sellerID] = cl.mu.Unlock()defer func() {l.mu.Lock()delete(l.calls, sellerID)l.mu.Unlock()close(c.done)}()v, err := l.fetch(ctx, sellerID)if err != nil {c.err = errclose(c.done)return 0, err}c.val = vreturn v, nil}