Перейти к основному содержимому

Практика: Горутины и каналы


Онлайн редактор кода для Go

Здесь вы можете попробовать свои силы в программировании на языке Go. Для этого мы предоставляем вам онлайн редактор кода, в котором вы можете написать свой код и запустить его.


❗️ При обновлении страницы код пропадёт, по этому, сохраните свой код куда-нибудь, если он важный.

Задание 1 — Параллельная загрузка аватаров

Задание 1: Параллельная загрузка аватаров

⏱️ Примерное время: 10-15 минут

Дан слайс имён пользователей. Запусти горутину для каждого — пусть она «загружает» аватар (имитация: time.Sleep + fmt.Printf). Дождись всех через WaitGroup.


Требования:

  • функция downloadAvatar(name string)
  • var wg sync.WaitGroup
  • wg.Add(1) перед go, defer wg.Done() внутри
  • wg.Wait() в конце main
  • выведи время начала и завершения каждой загрузки

Пример вывода:

14:35:22 alice: начало загрузки
14:35:22 bob: начало загрузки
14:35:23 alice: аватар загружен
14:35:24 bob: аватар загружен
Все аватары загружены

Задание 2 — Параллельный поиск слова в файлах (errgroup)

Задание 2: Параллельный grep с errgroup

⏱️ Примерное время: 20-25 минут

Дан слайс имён файлов и искомое слово. Запусти горутину для каждого файла — ищи слово построчно. Собери первую ошибку через errgroup.


Требования:

  • g := new(errgroup.Group)
  • g.Go(func() error { ... }) для каждого файла
  • внутри: os.Open, bufio.Scanner, поиск слова
  • если файл не найден — вернуть ошибку
  • в конце: if err := g.Wait(); err != nil { slog.Error("поиск прерван", "err", err) }

Пример вывода:

log1.txt:12: critical error occurred
log2.txt:45: connection timeout
Ошибка: open missing.log: no such file

Задание 3 — Безопасный счётчик посещений (Mutex)

Задание 3: Счётчик посещений сайта

⏱️ Примерное время: 15-20 минут

Создай структуру SiteStats с полем Visits int64. Запусти 1000 горутин — каждая увеличивает счётчик. Используй Mutex или atomic.


Требования:

  • два варианта: с sync.Mutex и с sync/atomic
  • сравни итоговое значение и время выполнения
  • выведи: "Ожидалось 1000, получили X за Y мс"

Пример вывода:

Mutex: ожидалось 1000, получили 1000 за 18 мс
Atomic: ожидалось 1000, получили 1000 за 4 мс

Задание 4 — Pipeline обработки логов

Задание 4: Конвейер обработки логов

⏱️ Примерное время: 25-30 минут

Создай конвейер: 1) генератор логов → 2) фильтр ошибок → 3) форматировщик → 4) вывод. Используй каналы между стадиями.


Требования:

  • 4 стадии — каждая в своей горутине
  • каналы: gen → filter → format → print
  • используй for line := range in и close(out) в конце стадии

Пример вывода:

[ERROR] 2026-01-07 14:35:22 connection refused
[ERROR] 2026-01-07 14:35:23 timeout after 5000ms

Задание 5 — Worker Pool с ограничением параллелизма

Задание 5: Worker Pool для парсинга URL

⏱️ Примерное время: 30-40 минут

Дан слайс URL. Ограничи параллелизм до N воркеров (буферизованный канал-семафор). Каждый воркер «скачивает» страницу (имитация). Собери результаты.


Требования:

  • канал-семафор: sem := make(chan struct{}, maxWorkers)
  • канал результатов: results := make(chan Result)
  • каждая горутина: sem <- struct{}{}; defer func(){ <-sem }()
  • используй WaitGroup + канал для сбора

Пример вывода:

worker-1: https://example.com → 200 OK (342 ms)
worker-3: https://google.com → 200 OK (189 ms)

Задание 6 — Итоговое: Параллельный скрейпер с таймаутом

Задание 6: Параллельный скрейпер страниц (итоговое)

⏱️ Примерное время: 40-60 минут

Дан слайс URL. Запусти воркеры (ограничь параллелизм), каждая горутина делает «запрос» (time.Sleep + случайный статус). Собери результаты через errgroup + контекст с таймаутом 5 секунд.


Требования:

  • g, ctx := errgroup.WithContext(context.Background())
  • ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
  • defer cancel()
  • семафор + errgroup.Go()
  • имитация запроса: случайный sleep 1–10s + статус 200/500/timeout

Пример вывода:

https://site1.com → 200 OK (2.3s)
https://site2.com → timeout (5.0s)
Обработка прервана по таймауту
подсказка

Горутины и каналы — это сердце Go.
Пиши просто, используй WaitGroup/errgroup, каналы вместо блокировок — и твой код будет быстрым, безопасным и понятным.