面试题答案
一键面试无缓冲通道
- 发送操作阻塞情况:当无缓冲通道没有接收者时,发送操作会阻塞。例如:
package main
import (
"fmt"
)
func main() {
ch := make(chan int)
ch <- 1 // 这里会阻塞,因为没有接收者
fmt.Println("不会执行到这里")
}
原理:无缓冲通道要求发送和接收操作必须同时进行,它没有内部缓冲空间来暂存数据。发送方将数据发送到通道时,必须等待接收方准备好接收,否则发送操作就会阻塞在那里,直到有接收者从通道中取走数据。 2. 接收操作阻塞情况:当无缓冲通道没有数据发送进来时,接收操作会阻塞。例如:
package main
import (
"fmt"
)
func main() {
ch := make(chan int)
go func() {
ch <- 1
}()
value := <-ch // 这里如果没有上面的 goroutine 发送数据,会阻塞
fmt.Println("接收到的值:", value)
}
原理:接收方尝试从通道接收数据时,如果通道中没有数据,接收操作就会阻塞,直到有数据发送到通道中。
带缓冲通道
- 发送操作阻塞情况:当带缓冲通道已满时,发送操作会阻塞。例如:
package main
import (
"fmt"
)
func main() {
ch := make(chan int, 2)
ch <- 1
ch <- 2
ch <- 3 // 这里会阻塞,因为通道缓冲大小为2,已经满了
fmt.Println("不会执行到这里")
}
原理:带缓冲通道有一定大小的内部缓冲区,可以暂存一定数量的数据。当缓冲区被填满后,再进行发送操作,由于没有额外的空间存储新数据,发送操作就会阻塞,直到有接收者从通道中取走数据,腾出空间。 2. 接收操作阻塞情况:当带缓冲通道为空时,接收操作会阻塞。例如:
package main
import (
"fmt"
)
func main() {
ch := make(chan int, 2)
value := <-ch // 这里会阻塞,因为通道为空
fmt.Println("接收到的值:", value)
}
原理:接收方尝试从通道接收数据时,如果通道中没有数据(缓冲区为空),接收操作就会阻塞,直到有数据发送到通道中。