MST

星途 面试题库

面试题:Go中Goroutine与通道结合的高效使用场景

假设你正在开发一个高并发的任务处理系统,需要使用Goroutine和通道(channel)进行数据交互与任务协作,请阐述至少两种高效的使用场景,并给出相应的代码示例及简要解释。
38.8万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

场景一:任务分发与结果收集

  • 场景描述:有多个相同类型的任务需要并发处理,将任务分发给多个Goroutine,每个Goroutine处理完任务后将结果返回,最后收集所有结果。
  • 代码示例
package main

import (
    "fmt"
)

func worker(id int, tasks <-chan int, results chan<- int) {
    for task := range tasks {
        result := task * task // 模拟任务处理,这里是计算平方
        fmt.Printf("Worker %d processed task %d and got result %d\n", id, task, result)
        results <- result
    }
}

func main() {
    numWorkers := 3
    tasks := make(chan int, 10)
    results := make(chan int, 10)

    for i := 0; i < numWorkers; i++ {
        go worker(i, tasks, results)
    }

    // 发送任务
    for i := 1; i <= 5; i++ {
        tasks <- i
    }
    close(tasks)

    // 收集结果
    var finalResults []int
    for i := 0; i < 5; i++ {
        finalResults = append(finalResults, <-results)
    }
    close(results)

    fmt.Println("Final results:", finalResults)
}
  • 解释worker函数从tasks通道接收任务,处理后将结果发送到results通道。main函数中创建多个worker Goroutine,然后向tasks通道发送任务,最后从results通道收集结果。

场景二:流水线处理

  • 场景描述:任务处理需要多个步骤,每个步骤由不同的Goroutine负责,数据像流水线一样依次经过各个步骤处理。
  • 代码示例
package main

import (
    "fmt"
)

func step1(input <-chan int, output chan<- int) {
    for data := range input {
        result := data + 1 // 模拟第一步处理
        output <- result
    }
    close(output)
}

func step2(input <-chan int, output chan<- int) {
    for data := range input {
        result := data * 2 // 模拟第二步处理
        output <- result
    }
    close(output)
}

func main() {
    data := make(chan int, 10)
    step1Output := make(chan int, 10)
    finalOutput := make(chan int, 10)

    go step1(data, step1Output)
    go step2(step1Output, finalOutput)

    // 发送初始数据
    for i := 1; i <= 3; i++ {
        data <- i
    }
    close(data)

    // 收集最终结果
    for result := range finalOutput {
        fmt.Println("Final result:", result)
    }
}
  • 解释step1函数从data通道接收数据,处理后发送到step1Output通道。step2函数从step1Output通道接收数据,再次处理后发送到finalOutput通道。main函数创建两个步骤的Goroutine,并发送初始数据,最后收集最终结果。