Go · 44 строк
Pick вызывается из каждой горутины HTTP-сервера, на пике — 20 тысяч раз в секунду. HealthLoop крутится в одной фоновой горутине и раз в 2 секунды пингует 12 бэкендов.
Отметьте строки с ошибками.
В работе: Внутренний L7-прокси перед пулом бэкендов сервиса.
Как проверяем
Нажмите на строку с ошибкой и коротко напишите, что не так. Баг засчитан, если отмечена хотя бы одна его строка. Зачёт — найдено не меньше 60 % багов с учётом серьёзности (критичный весит 3, обычный 2, мелкий 1), а лишних отметок не больше, чем багов в коде. Пустые строки, скобки и комментарии лишними не считаем. Плюс 1 вопрос про поведение программы — на зачёт не влияют. Ответ один на подход: после него показываем разбор.
Источник: обзор транскриптов интервью: Яндекс, балансировщик на Go. Условие пересказано своими словами.
Давали на собеседовании?
Ответов пока мало — ваш поможет.
package balancerimport ("errors""net/http""sync""time")type Balancer struct {mu sync.RWMutexbackends []stringalive []stringnext int}func New(backends []string) *Balancer {return &Balancer{backends: backends, alive: backends}}// Pick вызывается из тысяч горутин HTTP-сервера.func (b *Balancer) Pick() (string, error) {if len(b.alive) == 0 {return "", errors.New("no alive backends")}b.next++return b.alive[b.next%len(b.alive)], nil}// HealthLoop раз в 2 секунды обновляет список живых бэкендов.func (b *Balancer) HealthLoop(client *http.Client) {for range time.Tick(2 * time.Second) {var alive []stringfor _, addr := range b.backends {resp, err := client.Get("http://" + addr + "/ping")if err == nil && resp.StatusCode == http.StatusOK {alive = append(alive, addr)}}b.mu.Lock()b.alive = aliveb.mu.Unlock()}}