面试题答案
一键面试通道(channel)的作用
在Go语言中,通道(channel)是一种用于在多个goroutine之间进行通信和同步的重要机制。它提供了一种类型安全的方式来传递数据,实现不同goroutine之间的同步与协作,避免了传统共享内存并发编程中的许多问题,如竞态条件等。通过通道,goroutine可以安全地发送和接收数据,就像在不同的执行路径之间建立了一条管道。
非缓冲通道示例代码
package main
import (
"fmt"
)
func main() {
ch := make(chan int)
go func() {
num := 42
fmt.Println("发送数据:", num)
ch <- num
}()
received := <-ch
fmt.Println("接收数据:", received)
}
在这个示例中,创建了一个非缓冲通道 ch
。在匿名goroutine中,将数字 42
发送到通道 ch
。主goroutine从通道 ch
接收数据。非缓冲通道要求发送操作(ch <- num
)和接收操作(<-ch
)必须同时准备好,否则发送或接收操作会阻塞,直到另一方准备好。这种特性使得非缓冲通道天然地起到了同步作用,确保数据发送和接收的操作严格按照顺序进行。
缓冲通道示例代码
package main
import (
"fmt"
)
func main() {
ch := make(chan int, 2)
ch <- 1
ch <- 2
fmt.Println("已发送两个数据到缓冲通道")
received1 := <-ch
fmt.Println("接收数据1:", received1)
received2 := <-ch
fmt.Println("接收数据2:", received2)
}
这里创建了一个缓冲容量为2的通道 ch
。首先向通道发送两个数据,由于通道有缓冲,发送操作不会立即阻塞。之后从通道接收数据。缓冲通道在缓冲区未满时,发送操作不会阻塞;在缓冲区不为空时,接收操作不会阻塞。只有当缓冲区满了再进行发送,或者缓冲区空了再进行接收时,才会发生阻塞。
区别总结
- 数据传递:
- 非缓冲通道必须在发送和接收方都准备好时才能传递数据,它确保了数据的同步传递。
- 缓冲通道允许在缓冲区未满时,发送方先将数据发送到缓冲区中,而不需要接收方立即准备好接收。
- 同步:
- 非缓冲通道更强调同步,因为发送和接收操作必须配对出现,这可以用于精确控制goroutine的执行顺序。
- 缓冲通道在一定程度上减少了同步性,它允许发送和接收操作在一定范围内独立执行,更适合解耦发送和接收的节奏。