← Назад к вопросам

Сумма квадратов с горутинами

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) для хранения горутин и результатов в канале
Сумма квадратов с горутинами | PrepBro