Golang 面試題3 兩個協程輪流列印字母和數字
阿新 • • 發佈:2022-04-13
Golang面試程式設計題3
實現兩個協程輪流輸出A 1 B 2 C 3 .... Z 26
方案1:有緩衝的chan
func ChannelFunc() { // 思想:兩個g,一個輸出數字,一個輸出字母,重點是如何控制兩個g的列印順序,讓其可以輪流列印 // 分別使用兩個快取為1的chan,來控制兩個g的列印順序 strChan := make(chan int, 1) numChan := make(chan int, 1) strChan <- 0 // 先往字元chan中塞入,此時strChan再塞入會堵塞 // 負責列印字母 go func() { for i := 65; i <= 90; i++ { <-strChan // strChan取出,因為之前先塞入了,所以此處不會堵塞,會直接列印字元A..Z fmt.Printf("%v ", string(rune(i))) // 列印字母 numChan <- i // numChan 塞入,塞入後,另一個g的numChan取出操作才能進行 } return }() // 負責列印數字 go func() { for i := 1; i <= 26; i++ { <-numChan // 一直阻塞,直到字母被列印,這樣每次數字都是在字母后面被列印的 fmt.Printf("%v ", i) /// 列印數字 strChan <- i // strChan塞入,此處塞入後,上面協程的strChan取出操作才能進行,才會列印字母,這樣保證了列印完數字後,緊接著列印字母 } return }() time.Sleep(1 * time.Second) fmt.Println() // A 1 B 2 C 3 D 4 E 5 F 6 G 7 H 8 I 9 J 10 K 11 L 12 M 13 N 14 O 15 P 16 Q 17 R 18 S 19 T 20 U 21 V 22 W 23 X 24 Y 25 Z 26 }
方案2:無緩衝的chan
func ChannelFunc() { strChan := make(chan int) numChan:= make(chan int) // 列印字母 go func() { for i := 65; i <= 90; i++ { // 保證字母先被列印 fmt.Printf("%v ", string(rune(i))) strChan <- i // strChan塞入,通知數字可以被列印了 <-numChan // numChan一直被阻塞,直到被g2通知可以列印字母了 } return }() // 列印數字 go func() { for i := 1; i <= 26; i++ { <-strChan // strChan拉取,一直被阻塞,直到被strChan被塞入,即被g1通知數字可以列印了之後才解除阻塞 fmt.Printf("%v ", i) numChan <- i // numChan塞入,通知g1可以列印字母 } return }() time.Sleep(1 * time.Second) fmt.Println() }
總結:
- 一個協程負責列印數字,一個協程負責列印字母,分開進行,我們只需要控制其輪流列印即可
- 採用有無緩衝的Chan都可實現輪流控制