题目：一个goroutine打印0-100，一个goroutine打印a-z，两个goroutine交替打印。考点：用channel通知另一个goroutine，并且不能出现goroutine阻塞。核心原理：channel 是同步阻塞的在没有缓冲的 channel（或容量已满的 channel）中：发送方（chan <- val）会阻塞，直到有接收方准备好读取。 接收方（<-chan）也会阻塞，直到有发送方发来数据。这种阻塞机制就可以天然地用于控制两个 goroutine 的执行顺序。方案一：两个channel，一个用来控制打印数字，一个用来控制打印字母，goroutine先接收channel再开始打印，如果没有接收到信号就会阻塞，打印完再作为发送方向对方的channel发送信号，并且第二个goroutine打印完就不要再向channel发送信号了，否则会死锁。因为第一个goroutine已经打印完，不会再接收channel，导致goroutine死锁。func Printnumandstring() { chNumber := make(chan struct{}) chStr := make(chan struct{}) wg := &sync.WaitGroup{} wg.Add(2) go func() { defer wg.Done() i := 0 for i <= 100 { <-chNumber for j := 0; j < 4 && i <= 100; j++ { println(i) i++ } chStr <- struct{}{} } }() go func() { defer wg.Done() for i := 'a'; i <= 'z'; i++ { <-chStr println(string(i)) if i != 'z' { chNumber <- struct{}{} } } }() chNumber <- struct{}{} wg.Wait() }