Junior — Senior
62
Ускорение выполнения через параллельные запросы
Компании, где спрашивали:
Условие задачи
Необходимо доработать функцию Do так, чтобы её выполнение занимало около 10 мс независимо от количества переданных пользователей. Каждый вызов fetchByName имитирует задержку в 10 мс. Функции main и fetchByName менять нельзя – вся оптимизация должна быть реализована внутри Do.
package main
import (
"context"
"fmt"
"math/rand"
"sync"
"time"
)
type User struct {
Name string
}
func main() {
fmt.Println(Do(context.Background(), []User{{"aaa"}, {"bbb"}, {"ccc"}, {"ddd"}, {"eeee"}}))
}
// fetchByName изменять нельзя
func fetchByName(ctx context.Context, userName string) (int, error) {
time.Sleep(10 * time.Millisecond) // имитация сетевого похода
return rand.Int() % 100000, nil
}
// все изменения должны происходить в этой функции
func Do(ctx context.Context, users []User) (map[string]int, error) {
result := make(map[string]int)
var mu sync.Mutex
var wg sync.WaitGroup
errCh := make(chan error, 1)
for _, usr := range users {
wg.Add(1)
go func(u User) {
defer wg.Done()
id, err := fetchByName(ctx, u.Name)
if err != nil {
select {
case errCh <- err:
default:
}
return
}
mu.Lock()
result[u.Name] = id
mu.Unlock()
}(usr)
}
wg.Wait()
close(errCh)
if err, ok := <-errCh; ok {
return result, err
}
return result, nil
}