面试题答案
一键面试Goroutine与Channel协作实现并发编程阐述
- Goroutine:
- Goroutine是Go语言中实现并发的轻量级线程。它由Go运行时(runtime)管理,与操作系统线程相比,创建和销毁的开销极小。一个程序可以轻松创建成千上万的goroutine。例如,
go func() { /* 这里是goroutine执行的代码 */ }()
这样就启动了一个匿名函数作为goroutine运行。
- Goroutine是Go语言中实现并发的轻量级线程。它由Go运行时(runtime)管理,与操作系统线程相比,创建和销毁的开销极小。一个程序可以轻松创建成千上万的goroutine。例如,
- Channel:
- Channel是Go语言中用于在goroutine之间进行通信和同步的机制。它可以看作是一个类型化的管道,数据可以通过它在不同的goroutine之间传递。例如,
ch := make(chan int)
创建了一个可以传递int
类型数据的channel。
- Channel是Go语言中用于在goroutine之间进行通信和同步的机制。它可以看作是一个类型化的管道,数据可以通过它在不同的goroutine之间传递。例如,
- 协作方式:
- 发送和接收操作:goroutine通过channel进行数据的发送(
ch <- value
)和接收(value := <- ch
)操作。发送操作会阻塞当前goroutine,直到有其他goroutine从该channel接收数据;接收操作也会阻塞,直到有数据被发送到该channel。这种阻塞特性实现了goroutine之间的同步。 - 关闭Channel:可以使用
close(ch)
关闭一个channel。接收方可以通过v, ok := <- ch
这种形式判断channel是否关闭,当ok
为false
时,表示channel已关闭且没有更多数据。 - 单向Channel:还可以创建单向的channel,如
sendCh := make(chan <- int)
表示只能发送数据的channel,recvCh := make(<- chan int)
表示只能接收数据的channel,这有助于明确数据流向,增强代码的可读性和安全性。
- 发送和接收操作:goroutine通过channel进行数据的发送(
使用场景及代码示例
- 场景:计算多个数字的平方,并将结果收集起来。假设我们有一组数字,希望并发地计算它们的平方,最后收集所有结果。
- 代码如下:
package main
import (
"fmt"
)
func square(nums []int, result chan int) {
for _, num := range nums {
result <- num * num
}
close(result)
}
func main() {
nums := []int{1, 2, 3, 4, 5}
result := make(chan int)
go square(nums, result)
for sq := range result {
fmt.Println(sq)
}
}
在上述代码中:
square
函数是一个在goroutine中运行的函数,它计算传入数字切片中每个数字的平方,并将结果发送到result
channel。计算完成后,关闭result
channel。- 在
main
函数中,创建了nums
切片和result
channel,并启动了一个goroutine来执行square
函数。 - 通过
for... range
循环从result
channel接收数据,当channel关闭时,循环自动结束,这样就收集到了所有数字的平方结果并打印出来。