面试题答案
一键面试应用场景一:数据传递
在并发编程中,不同的goroutine之间常常需要传递数据,Channel提供了一种安全、高效的方式。
package main
import (
"fmt"
)
func main() {
ch := make(chan int)
go func() {
data := 42
ch <- data
}()
received := <-ch
fmt.Println("Received:", received)
}
在上述代码中,一个匿名的goroutine将数据42
发送到ch
这个channel中,主goroutine从ch
中接收数据并打印。
应用场景二:同步
Channel可用于同步goroutine的执行。例如,当一个goroutine完成某些任务后,通过Channel通知其他goroutine。
package main
import (
"fmt"
)
func main() {
done := make(chan struct{})
go func() {
// 模拟一些工作
fmt.Println("Working...")
close(done)
}()
<-done
fmt.Println("Work is done.")
}
这里,匿名goroutine在完成工作后关闭done
这个channel,主goroutine通过接收done
中的数据(这里使用struct{}
类型,因为不需要传递具体数据,仅用于同步)来得知工作已完成。
生产者 - 消费者模型实现
生产者 - 消费者模型是一种经典的并发设计模式。生产者将数据放入Channel,消费者从Channel中取出数据进行处理。
package main
import (
"fmt"
)
func producer(ch chan<- int) {
for i := 0; i < 5; i++ {
ch <- i
fmt.Printf("Produced: %d\n", i)
}
close(ch)
}
func consumer(ch <-chan int) {
for data := range ch {
fmt.Printf("Consumed: %d\n", data)
}
}
func main() {
ch := make(chan int)
go producer(ch)
go consumer(ch)
// 防止主程序退出
select {}
}
在上述代码中,producer
函数作为生产者,向ch
这个channel发送数据,并在发送完后关闭ch
。consumer
函数作为消费者,通过for... range
循环从ch
中接收数据,直到ch
被关闭。主函数中启动了生产者和消费者的goroutine,并使用select {}
来防止主程序过早退出。