> Напиши функцию на Go, которая принимает слайс каналов int и возвращает канал с суммами чисел из каждого канала (Go)
Уровень: senior · Роль: backend · Категория: Технические вопросы
Компании: sferaplatform.ru
Стек: Go
> Пример ответа
Короткий ответ
Функция принимает []chan int, читает все значения из каждого канала, суммирует их и отправляет результат в выходной канал. Используем sync.WaitGroup для координации горутин и закрываем выходной канал после завершения всех чтений. Важно обработать закрытие входных каналов, чтобы избежать deadlock.
Подробное объяснение
Основная задача - конкурентно прочитать все каналы, просуммировать значения каждого канала отдельно и отправить сумму в общий выходной канал. Ключевые моменты:
- Для каждого входного канала запускаем отдельную горутину.
- Каждая горутина читает из своего канала до его закрытия, накапливая сумму.
- После завершения чтения горутина отправляет сумму в выходной канал.
sync.WaitGroupпозволяет дождаться завершения всех горутин перед закрытием выходного канала.- Выходной канал должен быть буферизированным или закрыт после завершения всех отправок, иначе потребитель может заблокироваться.
На практике
Типичный сценарий - агрегация результатов из нескольких источников данных. Например, сбор статистики с разных сервисов или обработка партиций. Важно помнить, что порядок сумм в выходном канале не гарантирован - он зависит от скорости чтения каждого входного канала. Если порядок важен, нужно передавать индекс канала вместе с суммой.
Пример кода
GOfunc SumChannels(chs []chan int) chan int {out := make(chan int, len(chs))var wg sync.WaitGroupfor _, ch := range chs {wg.Add(1)go func(c chan int) {defer wg.Done()sum := 0for v := range c {sum += v}out <- sum}(ch)}go func() {wg.Wait()close(out)}()return out}
Использование:
GOfunc main() {ch1 := make(chan int)ch2 := make(chan int)go func() {ch1 <- 1ch1 <- 2close(ch1)}()go func() {ch2 <- 10close(ch2)}()results := SumChannels([]chan int{ch1, ch2})for sum := range results {fmt.Println(sum) // 3 и 10 в произвольном порядке}}
Как отвечать на собеседовании
Начни с описания сигнатуры функции и подхода. Объясни, почему используешь sync.WaitGroup и зачем закрываешь выходной канал. Упомяни, что входные каналы должны быть закрыты отправителями - иначе горутины заблокируются. Если спросят про обработку паник или контекст отмены, предложи добавить context.Context для graceful shutdown.
Что проверяет интервьюер
- Понимание конкурентности в Go: горутины, каналы,
sync.WaitGroup. - Умение корректно закрывать каналы и избегать deadlock.
- Знание особенностей работы с каналами: чтение из закрытого канала, буферизация.
- Способность рассуждать о edge cases: пустой слайс, незакрытые каналы, порядок результатов.
Типичные ошибки
- Забыть закрыть выходной канал - потребитель заблокируется навсегда.
- Не использовать буфер для выходного канала - возможна блокировка при отправке, если потребитель медленный.
- Передавать канал в горутину без копирования переменной цикла (в старых версиях Go) - все горутины будут читать из последнего канала.
- Не обрабатывать случай пустого слайса - функция вернёт закрытый канал, что корректно, но может быть неожиданно.
- Предполагать, что входные каналы будут закрыты - в реальном коде это нужно явно документировать.
> Похожие задачи по backend
Как снять бронь товара при отмене заказа
Как гарантировать, что заказ не будет выполнен без исполнителя после резерва товара
Как реализовать эффективную пагинацию с курсорами и индексами
Как устроена пагинация в Go проектах
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью