面试题答案
一键面试- 死锁原因:
在Go语言中,向无缓冲通道发送数据(
ch <- 1
)时,会阻塞当前goroutine,直到有其他goroutine从该通道接收数据。在这段代码中,main
函数是一个单独的goroutine,当执行到ch <- 1
时,它会一直阻塞等待接收者,而后续的fmt.Println(<-ch)
也在等待通道有数据可接收,由于没有其他goroutine来协助,就形成了死锁。 - 避免死锁的方法及原理:
- 方法一:使用缓冲通道:
原理:有缓冲通道在发送数据时,如果缓冲区未满,不会阻塞发送者。这里创建的通道缓冲区大小为1,所以package main import ( "fmt" ) func main() { ch := make(chan int, 1) // 创建有缓冲通道,缓冲大小为1 ch <- 1 fmt.Println(<-ch) }
ch <- 1
不会阻塞,后续的接收操作也能正常获取到数据。 - 方法二:使用goroutine:
原理:通过启动一个新的goroutine来发送数据,package main import ( "fmt" ) func main() { ch := make(chan int) go func() { ch <- 1 close(ch) // 可以选择关闭通道,防止接收端一直阻塞等待新数据 }() fmt.Println(<-ch) }
main
函数所在的goroutine和新启动的goroutine并发执行。新的goroutine执行ch <- 1
,而main
函数执行fmt.Println(<-ch)
,它们之间的操作不会相互阻塞,从而避免了死锁。同时,关闭通道(close(ch)
)可以让接收者在没有更多数据时知道通道已关闭,避免一直阻塞。
- 方法一:使用缓冲通道: