Войти Регистрация
Конкурентность

6. Выписка по счетам: WaitGroup и канал

Средняя

Go · 46 строк

У клиента от 1 до 12 счетов: карты, вклады, брокерский. Collect грузит операции по каждому счёту в своей горутине и собирает общий список для экрана «Выписка».

Отметьте строки с ошибками.

В работе: Сборка единой выписки по всем продуктам клиента.

Как проверяем Нажмите на строку с ошибкой и коротко напишите, что не так. Баг засчитан, если отмечена хотя бы одна его строка. Зачёт — найдено не меньше 60 % багов с учётом серьёзности (критичный весит 3, обычный 2, мелкий 1), а лишних отметок не больше, чем багов в коде. Пустые строки, скобки и комментарии лишними не считаем. Плюс 1 вопрос про поведение программы — на зачёт не влияют. Ответ один на подход: после него показываем разбор.
WaitGroupканалfan-inобработка ошибок

Источник: Т‑Банк: секция Go, асинхронность и примитивы синхронизации. Условие пересказано своими словами.

Давали на собеседовании? Ответов пока мало — ваш поможет.
  1. package statement
  2. import (
  3. "context"
  4. "sync"
  5. )
  6. type Operation struct {
  7. AccountID string
  8. Amount int64 // копейки
  9. }
  10. type Loader interface {
  11. Load(ctx context.Context, accountID string) ([]Operation, error)
  12. }
  13. // Collect собирает выписку по всем счетам клиента параллельно.
  14. func Collect(ctx context.Context, l Loader, accounts []string) []Operation {
  15. var wg sync.WaitGroup
  16. out := make(chan []Operation)
  17. for _, id := range accounts {
  18. wg.Add(1)
  19. go load(ctx, l, id, out, wg)
  20. }
  21. go func() {
  22. wg.Wait()
  23. close(out)
  24. }()
  25. var all []Operation
  26. for ops := range out {
  27. all = append(all, ops...)
  28. }
  29. return all
  30. }
  31. func load(ctx context.Context, l Loader, id string, out chan<- []Operation, wg sync.WaitGroup) {
  32. defer wg.Done()
  33. ops, err := l.Load(ctx, id)
  34. if err != nil {
  35. return
  36. }
  37. out <- ops
  38. }