使用两个channel(长度为1)和两个goroutine,分别是oddChannel/oddGoroutine和evenChannel和evenGoroutine;
oddGoroutine在从oddChannel接收到数据1后开始打印奇数;打印完毕后,向evenChannel写入数据1,通知evenGoroutine开始打印偶数;
evenGoroutine在从evenChannel接收到数据1后开始打印偶数;打印完毕后,向oddChannel写入数据1,通知oddGoroutine开始打印奇数;
为使奇数开始先打印,还需要一个startChannel,该channel从main goroutine接收数据1,在startChannel收到数据1后开始奇数的打印,奇数打印完后开始偶数的打印;
所有线程执行结束后,需要关闭各goroutine,子goroutine的管理使用sync.WaitGroup进行;
第一次用 Golang 出面试题小记
使用两个channel(长度为1)和两个goroutine,分别是numChan/numGoroutine和letterChan/letterGoroutine;
numGoroutine在从numChan接收到数据1后开始打印数字;打印完毕后,向letterChan写入数据1,通知letterGoroutine开始打印字母;
letterGoroutine在从letterChan接收到数据1后开始打印字母;打印完毕后,向numChan写入数据1,通知numGoroutine开始打印数字;
为使数字开始先打印,还需要一个startChannel,该channel从main goroutine接收数据1,在startChannel收到数据1后开始数字的打印,数字打印完后开始字母的打印;
所有线程执行结束后,需要关闭各goroutine,子goroutine的管理使用sync.WaitGroup进行;
Gopher面试中的Coding 交替打印数字和字母
有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推…现在有四个文件ABCD。初始都为空。现要让四个文件呈如下格式:
A:1 2 3 4 1 2…
B:2 3 4 1 2 3…
C:3 4 1 2 3 4…
D:4 1 2 3 4 1…
测试时记得先创建好a.txt、b.txt、c.txt、d.txt文件
go 面试题
intChan:存放输入数据的管道
primeChan:存放输出结果的管道
开启一个协程,专门负责向intChan中放入数据;
开启四个协程,专门负责从intChan中取出各个数据,并判断是否为素数,若是,则放入primeChan
尚硅谷_韩顺平_Go语言核心编程:16.8.6 应用实例3
尚硅谷_韩顺平_Go语言核心编程:16.8.6 应用实例1
func main() {
runtime.GOMAXPROCS(1)
int_chan := make(chan int, 1)
string_chan := make(chan string, 1)
int_chan <- 1
string_chan <- "hello"
select {
case value := <-int_chan:
fmt.Println(value)
case value := <-string_chan:
panic(value)
}
}
本题考察goroutine的select操作,代码本身没有问题,可以正常编译通过并执行。
但是,在select时,当case value := <-string_chan先满足条件可以执行,或者case value := <-int_chan和case value := <-string_chan两者都满足条件但在随机选择时选中case value := <-string_chan分支时,会触发panic()语句的执行,从而触发异常
Go面试题答案与解析 5、下面代码会触发异常吗?请详细说明
进程是操作系统层面支持的并发模型,同是也是开销最大的一种并发模型。进程是系统进行资源分配的最小单位。
线程也是操作系统层面支持的并发模型,开销比进程小,并且线程依赖于进程而存在。线程是系统调度的最小单位。
协程,也被成为轻量级线程,依托于线程而存在,开销比线程更小,同时能创建比进程和线程更多的数量。目前支持协程的语言包括:Golang、Python、Erlang
简单理解为基于事件的调度模型,在发生事件时,执行相应回调函数。目前在Node.js中有很好的实践。
并发,说到底难点在于对共享变量访问控制,通常有以下两种实现模式:
基于锁机制,线程在操作共享变量时,通过对共享变量加锁,实现对共享变量的独占式使用;在使用完毕后释放锁,以便其他线程使用
基于消息机制,线程在收到消息后开始操作共享变量,并在操作完毕后传出消息,通知其他线程对共享变量进行操作
concurrent_control_mode_test.go Test_Concurrent_Control_Mode_By_Channel
concurrent_control_mode_test.go Test_Concurrent_Control_Mode_By_WaitGroup
concurrent_control_mode_test.go Test_Concurrent_Control_Mode_By_Context
Golang中goroutine的调度依赖于M(work thread)、P(processor)、G(goroutine)三个基础组件,故又被称为MPG调度模式
Go全栈面试题(2) -Go进阶面试题 互斥锁,读写锁,死锁问题是怎么解决。
Golang中的三种锁包括:互斥锁,读写锁,sync.Map安全的锁
Go全栈面试题(2) -Go进阶面试题 说下Go中的锁有哪些?
在第一个()处作传入参数类型声明,在第二个()处出入实际参数
在不明确知道channel长度时, 需要线先进行channel的关闭, 然后才能进行channel的遍历
在明确知道channel长度时, 可以先使用普通的for循环进行channel的遍历, 在遍历后在进行channel的关闭
channel底层实现为一个队列,read & write可视为两个协程并发的操作这个队列
新建一个channel时,channel为空并且未关闭,readFlag=false & writeFlag=true,该channel等待goroutine写入数据;
当goroutine写入数据后,channel不为空并且未关闭,readFlag=true & writeFlag=false,该channel等待goroutine读取数据;
当goroutine读取完数据后,channel再次为空并且未关闭,readFlag=false & writeFlag = true, 等待goroutine写入数据;
如此,便实现两个goroutine对chan的读写操作
但是,当该channel为空并且未关闭时,readFlag=false & writeFlag=true,这个时候进行read操作便会因为并发修改channle而导致deadlock异常的出现
因此,在遍历channel之前,一定要确保channel已关闭,否则会出现deadlock问题
系统数据类型的默认值.
bool: false
int: 0
例如如上测试案例: Goroutine 1和Goroutine 2很可能无法得到执行, 因为main goroutine退出会导致子goroutine没有时间执行
sync.WaitGroup内部实现了一个计数器,用来记录未完成的操作个数,它提供了三个方法:
Go并发:利用sync.WaitGroup实现协程同步
Go全栈面试题(2) -Go进阶面试题 主协程如何等其余协程完再操作? & 如何等待所有goroutine的退出?
func TestBank(t *testing.T) {
// 如下代码段的含义是?
// Deposit [1..1000] concurrently.
var n sync.WaitGroup
for i := 1; i <= 1000; i++ {
n.Add(1)
go func(amount int) {
bank.Deposit(amount)
n.Done()
}(i)
}
n.Wait()
if got, want := bank.Balance(), (1000+1)*1000/2; got != want {
t.Errorf("Balance = %d, want %d", got, want)
}
}
done := make(chan struct{})
done <- struct{}{}
go获取协程(goroutine)号