Перед вами багованный сервис агрегации метрик. Метрики приходят через
AddMetric, буферизуются и периодически (по таймеру или при заполнении буфера)
сбрасываются батчем в хранилище ClickHouseClient.Save.
Код компилируется, но содержит ошибки: гонки данных, утечку горутины и
проблему с переиспользованием (aliasing) слайса-буфера, который передаётся в
фоновую горутину Save и одновременно перезаписывается агрегатором.
type Metric struct {
Name string
Value float64
}
type MetricsAggregator struct {
// ...
}
// NewMetricsAggregator запускает фоновую горутину агрегации.
func NewMetricsAggregator(db *ClickHouseClient) *MetricsAggregator
// AddMetric добавляет метрику в буфер (вызывается конкурентно).
func (ma *MetricsAggregator) AddMetric(m Metric)
// Stop корректно завершает агрегатор и сбрасывает остаток буфера.
func (ma *MetricsAggregator) Stop()
Ваша задача — найти и исправить ВСЕ ошибки так, чтобы поведение было
корректным: каждая добавленная метрика должна быть сохранена в ClickHouseClient
ровно один раз (без потерь и дублей), без гонок данных и без утечки горутин.
После Stop() все накопленные метрики обязаны оказаться сохранёнными.
Скрытый тест запускается под детектором гонок (-race) и проверяет суммарное
число сохранённых метрик. Если останется гонка данных, утечка или неверный счёт —
тест упадёт.
На что смотрит интервьюер:
- Гонка данных / aliasing слайса: буфер передаётся в горутину
Save и
одновременно мутируется агрегатором. Нужно копировать батч в свежий слайс перед
передачей либо сохранять синхронно.
- Конкурентный доступ к буферу:
AddMetric и фоновая агрегация трогают одно
состояние — доступ должен быть потокобезопасным (канал или мьютекс).
- Корректность счёта: ни одна метрика не потеряна и не сохранена дважды
(flush по таймеру и flush по размеру не должны дублировать данные).
- Graceful shutdown:
Stop() завершает фоновую горутину (нет утечки) и
досбрасывает остаток буфера.
- Чистота под
-race: отсутствие любых data race.