Есть список ссылок (обычно около десяти). Нужно сходить по каждой GET-запросом
и вернуть результаты. Сначала напиши простую последовательную версию, потом
параллельную с тем же контрактом.
type Result struct {
URL string
Status int // HTTP-код ответа, 0 если запрос не удался
Body string // тело ответа целиком
Err error // ошибка сети / чтения тела, иначе nil
}
func FetchSequential(urls []string) []Result
func FetchParallel(urls []string) []Result
Требования
- Результатов столько же, сколько ссылок, и
result[i] относится к urls[i],
независимо от того, какой ответ пришёл раньше.
- Ошибка одного запроса (недоступный хост, битый URL) попадает в
Err этого
результата и не мешает остальным. Ответ 404 или 500 — не ошибка: это
Status и Body, Err == nil.
- Тело ответа читается целиком и закрывается.
FetchSequential делает запросы строго по одному.
FetchParallel отправляет все запросы одновременно и ждёт их все. Общее время —
примерно время самого медленного запроса, а не сумма.
- Пустой список — пустой результат. Код проходит
go test -race.
Пример
res := FetchParallel([]string{
"https://example.com/slow", // 300 мс
"https://example.com/fast", // 50 мс
"http://bad host/",
})
// ≈ 300 мс; res[0] — slow, res[1] — fast, res[2].Err != nil
Устно: что поменяется, если ссылок не 10, а 10 000? Как поставить таймаут на
весь обход и на отдельный запрос?
Разбор и эталонное решение — после своей попытки: на собеседовании подсказок не будет.
Сначала попробуй сам — подсказки не дают готовый ответ.