← Назад к вопросам
Сумма квадратов с горутинами
2.0 Middle🔥 241 комментариев
#Конкурентность и горутины
Условие
Реализуйте функцию SumOfSquares, которая получает целое число c и возвращает сумму квадратов всех чисел от 1 до c, используя горутины и каналы.
Сигнатура
func SumOfSquares(c int) int
Требования
- Использовать горутины для параллельного вычисления квадратов
- Использовать каналы для передачи результатов
- Использовать select для получения результатов
Пример
Вход: c = 5
Вычисление: 1² + 2² + 3² + 4² + 5² = 1 + 4 + 9 + 16 + 25 = 55
Выход: 55
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Решение
Анализ задачи
Требования:
- Функция должна вычислить сумму квадратов чисел от 1 до c
- Необходимо использовать горутины для параллельного выполнения
- Нужны каналы для передачи результатов между горутинами
- Требуется select для получения результатов
Математика: 1² + 2² + 3² + 4² + 5² = 1 + 4 + 9 + 16 + 25 = 55
Решение
func SumOfSquares(c int) int {
// Канал для получения результатов
resultChan := make(chan int)
// Запускаем горутину для вычисления каждого квадрата
for i := 1; i <= c; i++ {
go func(num int) {
square := num * num
resultChan <- square
}(i)
}
// Собираем результаты
sum := 0
for j := 0; j < c; j++ {
// Используем select для получения результата из канала
select {
case result := <-resultChan:
sum += result
}
}
return sum
}
Пояснения реализации
1. Канал для результатов
resultChan := make(chan int)создаёт небуферизированный канал, по которому горутины отправляют свои результаты- Каждая горутина отправляет вычисленный квадрат в канал
2. Запуск горутин
- Для каждого числа от 1 до c запускаем отдельную горутину
- Важно: передаём параметр
iв замыкание через аргументfunc(num int), чтобы избежать проблемы с захватом переменной по ссылке
3. Сбор результатов через select
selectблокирует до тех пор, пока какая-то из операций не будет готова- В цикле из c итераций получаем все результаты и суммируем их
- Порядок получения результатов неопределён из-за параллелизма, но это не влияет на сумму
4. Возврат результата
- Функция возвращает окончательную сумму после обработки всех квадратов
Альтернативный вариант с WaitGroup
Для более управляемого кода можно использовать sync.WaitGroup:
func SumOfSquares(c int) int {
var wg sync.WaitGroup
resultChan := make(chan int, c) // Буферизированный канал
for i := 1; i <= c; i++ {
wg.Add(1)
go func(num int) {
defer wg.Done()
resultChan <- num * num
}(i)
}
go func() {
wg.Wait()
close(resultChan)
}()
sum := 0
for result := range resultChan {
sum += result
}
return sum
}
Эта версия более безопасна: использует WaitGroup для отслеживания горутин и закрывает канал после их завершения.
Сложность
- Временная сложность: O(1) в идеальном параллелизме (все n операций выполняются одновременно)
- Пространственная сложность: O(n) для хранения горутин и результатов в канале