面试题答案
一键面试在Go语言中,我们可以通过channel和goroutine来模拟生成器实现并发任务处理。以下是一个简单的示例代码及说明:
package main
import (
"fmt"
)
// 生成器函数,通过channel返回数据
func generator(nums...int) <-chan int {
out := make(chan int)
go func() {
for _, num := range nums {
out <- num
}
close(out)
}()
return out
}
// 处理任务的函数,从channel获取数据并处理
func worker(id int, in <-chan int, out chan<- int) {
for num := range in {
fmt.Printf("Worker %d processing %d\n", id, num)
result := num * num // 简单的处理,例如求平方
out <- result
}
}
// 汇总结果的函数
func collector(in <-chan int) []int {
var results []int
for result := range in {
results = append(results, result)
}
return results
}
func main() {
data := []int{1, 2, 3, 4, 5}
gen := generator(data...)
const numWorkers = 3
var workerOuts = make([]chan int, numWorkers)
for i := 0; i < numWorkers; i++ {
workerOuts[i] = make(chan int)
go worker(i, gen, workerOuts[i])
}
var finalOut = make(chan int)
go func() {
for _, out := range workerOuts {
for result := range out {
finalOut <- result
}
}
close(finalOut)
}()
results := collector(finalOut)
fmt.Println("Final results:", results)
}
代码说明
-
生成器函数(
generator
):- 接受可变参数
nums
,创建一个只写的channel
out
。 - 在一个新的
goroutine
中,将参数nums
中的数据逐个发送到out
channel
,发送完毕后关闭channel
。 - 最后返回这个只读的
channel
out
。
- 接受可变参数
-
工作函数(
worker
):- 接受
id
(标识工作者)、输入channel
in
和输出channel
out
。 - 从输入
channel
in
中读取数据,进行处理(这里简单地求平方),然后将结果发送到输出channel
out
。
- 接受
-
汇总函数(
collector
):- 接受一个只读
channel
in
,从该channel
中读取所有结果,并将其收集到一个切片results
中,最后返回这个切片。
- 接受一个只读
-
主函数(
main
):- 定义了一个数据切片
data
。 - 通过
generator
函数创建一个生成器gen
。 - 创建多个
worker
,每个worker
从生成器gen
获取数据并处理,将结果发送到各自的输出channel
workerOuts
。 - 再通过一个匿名
goroutine
将所有worker
的输出channel
中的结果汇总到finalOut
channel
。 - 最后通过
collector
函数收集finalOut
channel
中的所有结果并打印。
- 定义了一个数据切片