面试题答案
一键面试优化思路
- 合理设置缓冲区大小:
- 过小的缓冲区可能导致频繁阻塞,影响性能;过大的缓冲区可能占用过多内存且掩盖潜在的性能问题。
- 根据实际数据量和处理速度估算缓冲区大小。例如,如果数据处理速度较快且数据量相对稳定,可以设置适中的缓冲区大小;若数据处理速度较慢,可适当减小缓冲区,尽早发现性能瓶颈。
- 避免死锁:
- 确保所有参与通信的goroutine都有机会发送和接收数据。
- 仔细设计goroutine之间的通信逻辑,避免出现循环依赖的阻塞情况。
- 可以使用
select
语句配合default
分支来防止阻塞,在无法立即发送或接收数据时执行其他逻辑。
示例代码
package main
import (
"fmt"
)
func producer(ch chan<- int, count int) {
for i := 0; i < count; i++ {
ch <- i
}
close(ch)
}
func consumer(ch <-chan int) {
for num := range ch {
fmt.Println("Received:", num)
}
}
func main() {
bufferSize := 10 // 合理设置缓冲区大小
ch := make(chan int, bufferSize)
go producer(ch, 20)
go consumer(ch)
// 防止主线程退出
select {}
}
在上述代码中:
producer
函数向通道ch
发送数据,consumer
函数从通道ch
接收数据。- 通过
make(chan int, bufferSize)
设置了缓冲区大小为10
。 consumer
函数使用for... range
循环读取通道数据,直到通道关闭,这有助于避免死锁。producer
函数在发送完数据后关闭通道,通知consumer
不再有数据发送。