go面试题--使用两个goroutine交替打印数字与字母

使用两个goroutine交替打印数字与字母

题目如下:

使用两个goroutine交替打印序列,一个goroutine打印数字,另外一个goroutine打印字母,最终效果如下:

12AB34CD56EF78GH910IZ1112KL1314MN1516OP1718QR1920ST2122UV2324WX2526YZ2728

解题思路:

使⽤ channel 来控制打印的进度。使⽤两个 channel ,来分别控制数字和

字⺟的打印序列, 数字打印完成后通过 channel 通知字⺟打印, 字⺟打印完成后通知数字打印,然后周⽽复始的⼯作

go 复制代码
package main

import (
	"fmt"
	"time"
)

var number, letter = make(chan bool), make(chan bool)

func numberPrint() {
	i := 1
	for {
		<-number
		fmt.Printf("%d%d", i, i+1)
		i += 2
		letter <- true
	}
}
func letterPrint() {
	i := 0
	str := "ABCDEFGHIZKLMNOPQRSTUVWXYZ"
	for {
		if i >= len(str) {
			return
		}
		<-letter
		fmt.Print(str[i : i+2])
		i += 2
		number <- true
	}
}
func main() {
	go numberPrint()
	go letterPrint()
	number <- true
	time.Sleep(5 * time.Second)
}

注意main routine中的number<-true要写在两个go协程下面,因为定义的channel是无缓冲通道,所以当对这个缓冲通道写的时候,会一直阻塞等到某个协程对这个缓冲通道读

如果写在两个go协程上面会发生阻塞,报错
all goroutines are asleep - deadlock

关于无缓冲通道:
一次只能传输一个数据
同一时刻,同时有 读、写两端把持 channel
如果只有读端,没有写端,那么 "读端"阻塞
如果只有写端,没有读端,那么 "写端"阻塞

那么有缓冲通道即为一方可以写入很多数据,不用等对方的操作,而另外一方也可以直接拿出数据,不需要等对方写,但是注意一点:如果写入的一方把channel写满了,那么如果要继续写就要等对方取数据后才能继续写入,这也是一种阻塞,读出数据也是一样,如果里面没有数据则不能取,就要等对方写入

相关推荐
2601_9498177222 分钟前
Spring Boot3.3.X整合Mybatis-Plus
spring boot·后端·mybatis
oy_mail36 分钟前
QoS质量配置
开发语言·智能路由器·php
oyzz12039 分钟前
PHP操作redis
开发语言·redis·php
uNke DEPH1 小时前
Spring Boot的项目结构
java·spring boot·后端
nashane1 小时前
HarmonyOS 6学习:网络能力变化监听与智能提示——告别流量偷跑,打造贴心网络感知应用
开发语言·php·harmony app
zhenxin01221 小时前
Spring Boot 3.x 系列【3】Spring Initializr快速创建Spring Boot项目
spring boot·后端·spring
凌波粒2 小时前
Java 8 “新”特性详解:Lambda、函数式接口、Stream、Optional 与方法引用
java·开发语言·idea
前端一小卒2 小时前
前端工程师的全栈焦虑,我用 60 天治好了
前端·javascript·后端
不停喝水2 小时前
【AI+Cursor】 告别切图仔,拥抱Vibe Coding: AI + Cursor 开启多模态全栈新纪元 (1)
前端·人工智能·后端·ai·ai编程·cursor
oyzz1202 小时前
Spring EL 表达式的简单介绍和使用
java·后端·spring