golang面试题目整理

两个协程交叉顺序打印1~n的数字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
func main() {
//使用两个channel做两个协程的同步
//ch1使用缓冲信道,然后写入数据接触第一个协程阻塞
//ch2使用无缓冲信道,等到goroutine1运行向ch2写入数据后,ch2接触阻塞
var wg sync.WaitGroup
ch1, ch2 := make(chan int, 1), make(chan int)
wg.Add(2)
ch1 <- 1
go func() {
defer wg.Done()
for i := 0; i < 10; i = i + 2 {
<-ch1
fmt.Println(i)
ch2 <- 1
}
}()
go func() {
defer wg.Done()
for i := 1; i < 10; i = i + 2 {
<-ch2
fmt.Println(i)
ch1 <- 1
}
}()
wg.Wait()
// 代码实现修改版: 使用channel做事件通知+数据传输
// 使用close+ok-idom来做协程终止通知
var wg sync.WaitGroup
ch1, ch2 := make(chan int, 1), make(chan int)
wg.Add(2)
ch1 <- 1
max := 100
go func(id int, max int) {
defer wg.Done()
for i := 0; i < max; i = i + 2 {
cur := <-ch1
fmt.Println(id, cur)
ch2 <- cur + 1
}
close(ch2)
}(1, max)
go func(id int) {
defer wg.Done()
for {
cur, ok := <-ch2
if !ok {
return
}
fmt.Println(id, cur)
ch1 <- cur + 1
}
}(2)
wg.Wait()
}