面试题答案
一键面试Go语言中通道(Channel)的主要特性
- 数据传递:通道是Go语言中用于在多个goroutine之间进行数据传递的核心机制。通过通道,一个goroutine可以发送数据,另一个goroutine可以接收数据,实现不同goroutine之间的通信。
- 同步:通道不仅可以传递数据,还能用于同步goroutine的执行。例如,当一个goroutine向通道发送数据时,如果没有其他goroutine在接收,该发送操作会阻塞,直到有接收者准备好接收数据。同样,接收操作也会阻塞,直到有数据发送到通道。
- 类型相关:通道是类型化的,创建通道时需要指定通道传递的数据类型,例如
chan int
表示该通道只能传递整数类型的数据。 - 缓冲与非缓冲通道:
- 非缓冲通道:也叫无缓冲通道,在创建时没有指定缓冲区大小,例如
make(chan int)
。这种通道的发送和接收操作是同步的,发送操作会阻塞直到有接收者准备好接收数据,接收操作也会阻塞直到有数据发送到通道。它常用于实现goroutine之间的精确同步。 - 缓冲通道:在创建时指定了缓冲区大小,例如
make(chan int, 5)
表示该通道的缓冲区大小为5。缓冲通道在缓冲区未满时,发送操作不会阻塞,直到缓冲区满;在缓冲区不为空时,接收操作不会阻塞,直到缓冲区为空。
- 非缓冲通道:也叫无缓冲通道,在创建时没有指定缓冲区大小,例如
利用通道实现两个goroutine之间的数据传递与同步示例
package main
import (
"fmt"
)
func main() {
// 创建一个非缓冲通道
ch := make(chan int)
// 启动第一个goroutine
go func() {
data := 42
fmt.Println("Sending data:", data)
ch <- data // 发送数据到通道
}()
// 启动第二个goroutine
go func() {
received := <-ch // 从通道接收数据
fmt.Println("Received data:", received)
}()
// 防止主goroutine提前退出
select {}
}
在上述示例中,第一个goroutine发送数据 42
到通道 ch
,第二个goroutine从通道 ch
接收数据,实现了两个goroutine之间的数据传递与同步。如果将通道改为缓冲通道 ch := make(chan int, 1)
,在发送数据时,只要缓冲区未满,发送操作不会阻塞。但这里为了展示同步效果,使用的是非缓冲通道。