Go语言面试题之select和channel的用法

目录
  • select
    • 先说switch...case...
    • 再说select...case..
    • select类比switch
    • 经典示例
    • 运行结果
  • channel
    • 1.从已经关闭并且没有值的通道中取值
    • 2.从已经关闭并且有值的通道中取值
    • 一图胜千言
  • 总结

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("写入数据")
   }
}

运行结果

channel

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

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

1.nil channel代表channel未初始化,向未初始化的channel读写数据会造成阻塞

2.关闭(close)未初始化的channel会引起panic。

3.从一个关闭的并且没有值的通道执行接收操作会得到对应类型的零值,并不会引起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")
   }
}

运行结果

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

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,而是会取到对应类型的零值。

一图胜千言

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

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

总结

本文解析了Go语言中select和channel在面试中可能遇到的进阶知识点。

到此这篇关于Go语言面试题之select和channel的用法的文章就介绍到这了,更多相关Go select channel内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Go语言中的通道channel详情

    目录 一.Go语言通道基础概念 1.channel产生背景 2.channel工作方式 二.通道使用语法 1.通道的声明与初始化 2.将数据放入通道内 3.从通道内取出数据 4.关闭通道close 三.单项通道及通道的状态分析 1.单项输出通道 2.单项输入通道 3.通道的状态 四.通道死锁原因分析 一.Go语言通道基础概念 1.channel产生背景 线程之间进行通信的时候,会因为资源的争夺而产生竟态问题,为了保证数据交换的正确性,必须使用互斥量给内存进行加锁,go语言并发的模型是CSP,提倡

  • Go语言select语句用法示例

    目录 用法 使用场景 实现收发功能 注意事项 用法 多个通道 Channel 中信息的发送和接受处理的专用的语句—select 语句.select 语句会阻塞,直到其中的一个发送/接收操作准备好.select 语句和 switch 语句有点相似,但 select 语句在被执行时会选择执行其中的一个分支,且选择分支的方法完全是不相同的. ch1 = make(chan string) ch2 = make(chan string) ch1 <- "server1" ch2 <

  • Golang的select多路复用及channel使用操作

    看到有个例子实现了一个类似于核弹发射装置,在发射之前还是需要随时能输入终止发射. 这里就可以用到cahnnel 配合select 实现多路复用. select的写法用法有点像switch.但是和switch不同的是,select的一个case代表一个通信操作(在某个channel上进行发送或者接收)并且会包含一些语句组成的一个语句块.现在让我们来实现一下这个核弹发射器 package main import ( "fmt" "time" "os"

  • go select的用法

    目录 1. select语句只能用于信道的读写操作 2. select中的case语句是随机执行的 3. 对于case条件语句中,如果存在通道值为nil的读写操作,则该分支将被忽略 4. 超时用法 5. 空select{} 6. for中的select 引起的CPU过高的问题 补充:7. 使用 select 切换协程 golang中的select语句格式如下 select {     case <-ch1:         // 如果从 ch1 信道成功接收数据,则执行该分支代码     cas

  • Go底层channel实现原理及示例详解

    目录 概念: 使用场景: 底层数据结构: 操作: 创建 发送 接收 关闭 案例分析: 概念: Go中的channel 是一个队列,遵循先进先出的原则,负责协程之间的通信(Go 语言提倡不要通过共享内存来通信,而要通过通信来实现内存共享,CSP(Communicating Sequential Process)并发模型,就是通过 goroutine 和 channel 来实现的) 使用场景: 停止信号监听 定时任务 生产方和消费方解耦 控制并发数 底层数据结构: 通过var声明或者make函数创建

  • Go语言面试题之select和channel的用法

    目录 select 先说switch...case... 再说select...case.. select类比switch 经典示例 运行结果 channel 1.从已经关闭并且没有值的通道中取值 2.从已经关闭并且有值的通道中取值 一图胜千言 总结 select 先说switch...case... switch...case... 很常用,且很好理解.其作用和if...else...一样. 区别是switch...case 相比于if...else...能让我们的代码看起来更清晰,更好理解.

  • go语言中如何使用select的实现示例

    目录 1.基本语法 2.select语句的实际应用 在golang语言中,select语句 就是用来监听和channel有关的IO操作,当IO操作发生时,触发相应的case动作. 有了 select语句,可以实现 main主线程 与 goroutine线程 之间的互动. 1.基本语法 select { case <-ch1 : // 检测有没有数据可读 // 一旦成功读取到数据,则进行该case处理语句 case ch2 <- 1 : // 检测有没有数据可写 // 一旦成功向ch2写入数据,

  • 详解Golang中Channel的用法

    如果说goroutine是Go语言程序的并发体的话,那么channels则是它们之间的通信机制.一个channel是一个通信机制,它可以让一个goroutine通过它给另一个goroutine发送值信息. 1 创建channel 每个channel都有一个特殊的类型,也就是channels可发送数据的类型.一个可以发送int类型数据 的channel一般写为chan int.使用内置的make函数,如果第二个参数大于0,则表示创建一个带缓存的channel. ch := make(chan in

  • jsp中select的onchange事件用法实例

    本文实例讲述了jsp中select的onchange事件用法.分享给大家供大家参考,具体如下: <script language = "JavaScript"> var onecount; onecount=0; subcat = new Array(); <% int count = 0; java.sql.ResultSet rs1 = DBManage.executeQuery("select hydm,zhydm,zhymc from zhy &qu

  • C语言中关于库函数 qsort 快排的用法

    目录 前言 一.库函数(qsort)的含义 二.(qsort)函数的实现方式,话不多说,请看. 1. 第一个参数 2. 第二个参数 3. 第三个参数 4. 第四个参数 1). 函数的参数 2). 这第四个参数的重点 三.函数实现 四.总结 前言 我也只是一个奋斗的程序猿,仅以此篇文章,作为我学习的见证,可能我的文采不好,有时候讲的词不达意,但我尽力去做好我想做的这些事情,如果此篇文章能够给各位读者带来一定的认识,那自然是最好的.若文章中有鄙人讲错了的,欢迎评论区指点.谢谢!!! 一.库函数(qs

  • C语言 while for do while循环体详解用法

    while循环 表达式: while(表达式) { 循环语句: } while 语句执行流程图: 例子: 打印1-10的数字 #include <stdio.h> int main() { int i = 1; while(i<=10) { printf("%d ", i); i +=1; } return 0; } 注意 ①在while中遇到break,终止整个循环 ②continue ,跳过本次循环continue后边的代码,直接去while循环的判断部分,进行下

  • C语言简明分析指针与引用的具体用法

    目录 1.指针 2.引用 1.指针 在计算机中,数据是存放在内存单元中的,一般把内存中的一个字节称为一个内存单元.为了更方便地访问这些内存单元,可预先给内存中的所有内存单元进行地址编号,根据地址编号,可准确找到其对应的内存单元.由于每一个地址编号均对应一个内存单元,因此可以形象地说一个地址编号就指向一个内存单元.C 语言中把地址形象地称作指针. 主要就是两个运算符:&和*. & 表示求地址,*表示求地址中的值,*也可以用来定义指针(int *p表示整型指针): int a=1; int *

  • C语言示例讲解do while循环语句的用法

    目录 1.do while()循环-先执行后判断 2.do while中的break以及continue 3.练习 4.猜数字游戏 1.do while()循环-先执行后判断 do语句的语法 do    循环语句;while(表达式); 此处的循环语句可能不是一条语句,而是一段代码. 示例:利用do while循环实现打印1-10 #include <stdio.h> int main() { int i = 1; do { printf("%d ",i); i++; }

  • C语言中回调函数和qsort函数的用法详解

    目录 回调函数 指向函数指针数组的指针 qsort(qulick sort)-库函数 回调函数 通过函数指针调用的函数,如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数. 回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应. 举例: #include<stdio.h> void menu() { printf("*************************

  • 详解java nio中的select和channel

    什么是NIO? 线程在处理数据时,如果线程还处于将数据从channel读到buffer的这段时间内,线程可以去做别的事情,等数据都读到buffer了,线程再回来处理读到的数据 channel是什么? 类比流的概念.与流的区别在于 1.channel是可读可写的,但是一个流要么写要么读 2.chanel可以异步的读和写 3.数据总是从channel中读到buffer,或者从buffer中写到channel 流的读取或写一般是一次性的操作,数据在读取过程中不会有缓存,这也就意味着没有办法自己随便移动

随机推荐