Golang面试题精讲

Channel交替打印数字和字母

Preview
  • 交替打印数字和字母

交替打印数字和字母

问题描述

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

12AB34CD56EF78GH910IJ1112KL1314MN1516OP1718QR1920ST2122UV2324WX2526YZ2728

解题思路

为了实现交替打印数字和字母,我们可以使用两个 goroutine,一个负责打印数字,另一个负责打印字母。我们可以使用 channel 来进行两个 goroutine 的同步。

具体的解题思路如下:

  1. 创建一个 channel,用于数字 goroutine 和字母 goroutine 之间的通信。
  2. 创建一个 goroutine,用于打印数字。在该 goroutine 中,通过一个循环不断从 channel 中接收数字,并打印出来。每次打印完数字后,再向 channel 中发送一个信号,表示数字已经打印完毕。
  3. 创建一个 goroutine,用于打印字母。在该 goroutine 中,通过一个循环不断从 channel 中接收字母,并打印出来。每次打印完字母后,再向 channel 中发送一个信号,表示字母已经打印完毕。
  4. 在主 goroutine 中,先向 channel 中发送一个数字信号,表示可以开始打印数字了。然后进入一个循环,每次从 channel 中接收一个信号,表示数字已经打印完毕,然后向 channel 中发送一个字母信号,表示可以开始打印字母了。如此循环,直到打印完所有数字和字母。

下面是源码分析和实现:

package main

import (
	"fmt"
	"sync"
)

func printNumber(ch chan bool, wg *sync.WaitGroup) {
	defer wg.Done()
	for i := 1; i <= 28; i += 2 {
		<-ch // 等待信号,表示可以开始打印数字
		fmt.Print(i)
		fmt.Print(i + 1)
		ch <- true // 发送信号,表示数字已经打印完毕
	}
}

func printLetter(ch chan bool, wg *sync.WaitGroup) {
	defer wg.Done()
	for i := 'A'; i <= 'Z'; i += 2 {
		<-ch // 等待信号,表示可以开始打印字母
		fmt.Print(string(i))
		fmt.Print(string(i + 1))
		ch <- true // 发送信号,表示字母已经打印完毕
	}
}

func main() {
	ch := make(chan bool)
	var wg sync.WaitGroup
	wg.Add(2)

	go printNumber(ch, &wg)
	go printLetter(ch, &wg)

	ch <- true // 发送一个数字信号,表示可以开始打印数字

	wg.Wait()
	fmt.Println()
}

在上面的代码中,我们使用了 sync.WaitGroup 来等待两个 goroutine 完成任务。通过 WaitGroupAdd 方法增加计数器,然后在每个 goroutine 的最后使用 Done 方法减少计数器。在主 goroutine 中使用 Wait 方法等待计数器归零,以确保所有 goroutine 都已经完成任务。

最后,我们在主 goroutine 中打印一个换行符,使输出结果更加清晰。运行上述代码,即可得到交替打印数字和字母的结果:

12AB34CD56EF78GH910IJ1112KL1314MN1516OP1718QR1920ST2122UV2324WX2526YZ2728

以上就是一种解题思路和源码实现,通过使用 goroutinechannel 实现了交替打印数字和字母的效果。当然,还可以使用其他的方法来解决这个问题,比如使用互斥锁、条件变量等。具体实现方式可以根据实际情况进行选择。