Для последовательного варианта проверяйте URL в цикле, для конкурентного — передавайте задания workers, а результаты печатайте в вызывающей горутине. Нужны таймаут и закрытие тела ответа.
Есть набор урлов.
Для последовательного варианта проверяйте URL в цикле, для конкурентного — передавайте задания workers, а результаты печатайте в вызывающей горутине. Нужны таймаут и закрытие тела ответа.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Есть набор урлов.
Напишите программу, которая:
-
Поочередно выполнит http запросы по предложенному списку ссылок • в случае получения http-кода ответа на запрос "200 OK" печатаем на экране "адрес url - ok" • в случае получения http-кода ответа на запрос отличного от "200 OK" либо в случае ошибки печатаем на экране "адрес url - not ok"
-
Модифицируйте программу таким образом, чтобы использовались каналы для коммуникации основного потока с горутинами. Пример: Запросы по списку выполняются в горутинах. Печать результатов на экран происходит в основном потоке.
Ответ
Для последовательного варианта проверяйте URL в цикле, для конкурентного — передавайте задания workers, а результаты печатайте в вызывающей горутине. Нужны таймаут и закрытие тела ответа.
type Result struct { URL string; OK bool }
func check(client *http.Client, url string) Result {
resp, err := client.Get(url)
if err != nil { return Result{url, false} }
defer resp.Body.Close()
return Result{url, resp.StatusCode == http.StatusOK}
}
func printResult(r Result) {
status := "not ok"
if r.OK { status = "ok" }
fmt.Printf("%s - %s\n", r.URL, status)
}
func sequential(urls []string) {
client := &http.Client{Timeout: 10 * time.Second}
for _, url := range urls { printResult(check(client, url)) }
}
func parallel(urls []string) {
client := &http.Client{Timeout: 10 * time.Second}
jobs := make(chan string)
results := make(chan Result)
var wg sync.WaitGroup
for i := 0; i < 4; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for url := range jobs { results <- check(client, url) }
}()
}
go func() {
for _, url := range urls { jobs <- url }
close(jobs)
wg.Wait()
close(results)
}()
for result := range results { printResult(result) }
}
Импорты: fmt, net/http, sync, time. Конкуренция ограничена четырьмя запросами; порядок вывода второго варианта — порядок завершения. По умолчанию клиент следует редиректам, поэтому проверяется итоговый ответ. Полное чтение ограниченного тела может улучшить reuse соединений, но для проверки статуса здесь достаточно закрытия.