一图胜千言,帮你搞懂Go面试中常问的channel问题!

简介: 一图胜千言,帮你搞懂Go面试中常问的channel问题!

一图胜千言

下面的表格中总结了对不同状态下的通道执行相应操作的结果。

image.png

注意: 对已经关闭的通道再执行 close 也会引发 panic。

之前整理了一篇:# GO面试必知必会面试题,收到了小伙伴们的好评。

这篇文章将重点讲解Go面试进阶知识点:select和channel。

select

先说switch...case...

switch...case... 很常用,且很好理解。其作用和if...else...一样。

区别是switch...case 相比于if...else...能让我们的代码看起来更清晰,更好理解。

再说select...case..

golang 的 select 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作。

所说的IO操作就是对channle的操作:向通道发送数据,或者从通道中读取数据。

在执行select语句的时候,运行时系统会自上而下地判断每个case中的发送或接收操作是否可以被立即执行。

什么是立即执行呢?

立即执行:意思是当前Goroutine不会因当前操作而被阻塞

select类比switch

select的用法与switch非常类似,由select开始一个新的选择块,每个选择条件由case语句来描述。

与switch语句可以选择任何可使用相等比较的条件相比,select有比较多的限制,其中最大的一条限制就是每个case语句里必须是一个IO操作。

确切的说,应该是一个面向channel的IO操作。

经典示例

package main
import "fmt"
func main() {
   ch1 := make(chan int, 1)
   ch1 <- 2
   select {
   case v := <-ch1:
      fmt.Println("取到的数据:", v)
   case ch1 <- 1:
      fmt.Println("写入数据")
   }
}

运行结果

image.png

channel

goroutine和channel作为go语言中最重要的两个知识点,一定要搞清楚。

大家容易出错的知识点是以下3点,尤其是最后一点:

  • nil channel代表channel未初始化,向未初始化的channel读写数据会造成阻塞
  • 关闭(close)未初始化的channel会引起panic。
  • 从一个关闭的并且没有值的通道执行接收操作会得到对应类型的零值,并不会引起panic。

1.从已经关闭并且没有值的通道中取值

package main
import "fmt"
//从关闭的通道中取值示例:
func main() {
   //声明实例化通道ch1
   ch1 := make(chan int, 1)
   //关闭通道
   close(ch1)
   select {
   //通通道ch1中取值
   case v := <-ch1:
      fmt.Printf("从ch1中取值:%d\n", v)
   default:
      fmt.Println("默认case")
   }
}

运行结果

和我们预想中的一样,取到了对应的零值:

image.png

2.从已经关闭并且有值的通道中取值

我们稍微修改一下上面的代码

package main
import "fmt"
//从关闭的通道中取值示例:
func main() {
   //声明实例化通道ch1
   ch1 := make(chan int, 1)
   //向通道中赋值
   ch1 <- 1
   //关闭通道
   close(ch1)
   //关闭之后取值
   after_close_value := <-ch1
   fmt.Printf("关闭之后取值:%d\n", after_close_value) //打印结果:关闭之后取值:1
   select {
   //通通道ch1中取值
   case v := <-ch1:
      fmt.Printf("从ch1中取值:%d\n", v) //打印结果:从ch1中取值:0
   default:
      fmt.Println("默认case")
   }
}

运行结果

运行结果和我们预想中的一样:

  • 通道关闭后,如果通道中仍然有值,还是可以正常取到通道中的值的。
  • 通道关闭后,如果通道中已经没有值了,再从通道中取值,并不会引起panic,而是会取到对应类型的零值。

image.png

一图胜千言

下面的表格中总结了对不同状态下的通道执行相应操作的结果。

image.png

注意: 对已经关闭的通道再执行 close 也会引发 panic。

相关文章
[go 面试] 雪花算法与分布式ID生成
[go 面试] 雪花算法与分布式ID生成
|
Go 开发者
Go语言实战案例:使用select监听多个channel
本文为《Go语言100个实战案例 · 网络与并发篇》第5篇,详解Go并发核心工具`select`的使用。通过实际案例讲解如何监听多个Channel、实现多任务处理、超时控制和非阻塞通信,帮助开发者掌握Go并发编程中的多路异步事件处理技巧。
|
数据采集 编解码 监控
Go语言实战案例:使用channel实现生产者消费者模型
本文是「Go语言100个实战案例 · 网络与并发篇」第4篇,通过实战案例详解使用 Channel 实现生产者-消费者模型,涵盖并发控制、任务调度及Go语言并发哲学,助你掌握优雅的并发编程技巧。
|
存储 Go 开发者
Go语言中的并发编程与通道(Channel)的深度探索
本文旨在深入探讨Go语言中并发编程的核心概念和实践,特别是通道(Channel)的使用。通过分析Goroutines和Channels的基本工作原理,我们将了解如何在Go语言中高效地实现并行任务处理。本文不仅介绍了基础语法和用法,还深入讨论了高级特性如缓冲通道、选择性接收以及超时控制等,旨在为读者提供一个全面的并发编程视角。
530 50
|
安全 Go 数据处理
Go语言中的并发编程:掌握goroutine和channel的艺术####
本文深入探讨了Go语言在并发编程领域的核心概念——goroutine与channel。不同于传统的单线程执行模式,Go通过轻量级的goroutine实现了高效的并发处理,而channel作为goroutines之间通信的桥梁,确保了数据传递的安全性与高效性。文章首先简述了goroutine的基本特性及其创建方法,随后详细解析了channel的类型、操作以及它们如何协同工作以构建健壮的并发应用。此外,还介绍了select语句在多路复用中的应用,以及如何利用WaitGroup等待一组goroutine完成。最后,通过一个实际案例展示了如何在Go中设计并实现一个简单的并发程序,旨在帮助读者理解并掌
|
安全 Go 调度
探索Go语言的并发模型:goroutine与channel
在这个快节奏的技术世界中,Go语言以其简洁的并发模型脱颖而出。本文将带你深入了解Go语言的goroutine和channel,这两个核心特性如何协同工作,以实现高效、简洁的并发编程。
|
Go 调度 开发者
探索Go语言中的并发模式:goroutine与channel
在本文中,我们将深入探讨Go语言中的核心并发特性——goroutine和channel。不同于传统的并发模型,Go语言的并发机制以其简洁性和高效性著称。本文将通过实际代码示例,展示如何利用goroutine实现轻量级的并发执行,以及如何通过channel安全地在goroutine之间传递数据。摘要部分将概述这些概念,并提示读者本文将提供哪些具体的技术洞见。
|
安全 Go 调度
探索Go语言的并发之美:goroutine与channel
在这个快节奏的技术时代,Go语言以其简洁的语法和强大的并发能力脱颖而出。本文将带你深入Go语言的并发机制,探索goroutine的轻量级特性和channel的同步通信能力,让你在高并发场景下也能游刃有余。
|
存储 安全 Go
探索Go语言的并发模型:Goroutine与Channel
在Go语言的多核处理器时代,传统并发模型已无法满足高效、低延迟的需求。本文深入探讨Go语言的并发处理机制,包括Goroutine的轻量级线程模型和Channel的通信机制,揭示它们如何共同构建出高效、简洁的并发程序。