Вопрос проверяет понимание конкурентности в Go и умение использовать горутины для параллельного выполнения HTTP-запросов.
В Go конкурентность реализуется через горутины — легковесные потоки, которые позволяют выполнять несколько задач одновременно. Для параллельного выполнения HTTP-запросов нужно запустить каждый запрос в отдельной горутине и дождаться их завершения.
package main
import (
"fmt"
"net/http"
"sync"
)
func fetchURL(url string, wg *sync.WaitGroup, results chan<string>) {
defer wg.Done()
resp, err := http.Get(url)
if err != nil {
results <- fmt.Sprintf("Error %s: %v", url, err)
return
}
defer resp.Body.Close()
results <- fmt.Sprintf("%s: %d", url, resp.StatusCode)
}
func main() {
urls := []string{"https://example.com", "https://google.com", "https://github.com"}
var wg sync.WaitGroup
results := make(chan string, len(urls))
for _, url := range urls {
wg.Add(1)
go fetchURL(url, &wg, results)
}
wg.Wait()
close(results)
for result := range results {
fmt.Println(result)
}
}В примере создается WaitGroup с количеством горутин, равным числу URL. Каждая горутина выполняет HTTP GET запрос и отправляет результат в буферизированный канал. После завершения всех горутин канал закрывается, и главная горутина выводит результаты.
Использование горутин с WaitGroup и каналами — стандартный и эффективный способ параллельной обработки HTTP-запросов в Go. Этот подход применяется в веб-скрапинге, микросервисах и любых задачах, где нужно ускорить выполнение множества независимых операций ввода-вывода.