面试题答案
一键面试无缓冲通道(缓存大小为 0)
- 对程序性能影响:无缓冲通道会导致发送和接收操作同步进行,若没有对应的接收者,发送操作会阻塞,反之亦然。这在一定程度上会增加程序的等待时间,尤其在并发操作频繁时,可能降低整体性能。但它确保了数据传输的实时性和有序性。
- 对数据传输影响:数据直接从发送者传递到接收者,中间没有缓存空间。只有当接收者准备好接收时,发送者才能成功发送数据,这保证了数据的一致性和同步性。
示例:
package main
import (
"fmt"
)
func main() {
ch := make(chan int)
go func() {
num := 42
fmt.Println("准备发送数据:", num)
ch <- num
fmt.Println("数据已发送")
}()
received := <-ch
fmt.Println("接收到数据:", received)
}
在这个示例中,ch
是一个无缓冲通道。匿名 goroutine 尝试发送数据时会阻塞,直到主函数从通道接收数据。
有缓冲通道(缓存大小大于 0)
- 对程序性能影响:有缓冲通道允许在没有接收者的情况下,发送一定数量的数据到缓存中,减少了发送操作的阻塞频率,提高了并发性能。特别是在数据产生速度较快而处理速度相对较慢的场景下,能有效减少等待时间。
- 对数据传输影响:数据先进入通道的缓存,当缓存满时,后续的发送操作才会阻塞。接收者从缓存中获取数据,这使得数据传输具有一定的异步性。
示例:
package main
import (
"fmt"
)
func main() {
ch := make(chan int, 2)
go func() {
for i := 0; i < 3; i++ {
fmt.Println("准备发送数据:", i)
ch <- i
fmt.Println("数据", i, "已发送")
}
close(ch)
}()
for num := range ch {
fmt.Println("接收到数据:", num)
}
}
在这个示例中,ch
是一个有缓冲通道,缓存大小为 2。goroutine 可以先发送两个数据到缓存中而不阻塞,当发送第三个数据时,由于缓存已满,会阻塞直到有数据被接收。