Go

Print odd and even numbers alternately from two goroutines (1..N) using channels. Then do the same with sync.Mutex and sync.Cond.

Question 516MediumGo 1.22 to 1.25

Channels: pass a "token" back and forth over two unbuffered channels. Only the goroutine holding the token may print, so the order is fixed. Each goroutine passes the token on only if more numbers are left. This matters: without the i < n check, the last send has no receiver and the program deadlocks.

func oddEvenChan(n int) {
	odd, even := make(chan struct{}), make(chan struct{})
	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
		defer wg.Done()
		for i := 1; i <= n; i += 2 {
			<-odd
			fmt.Println(i)
			if i < n {
				even <- struct{}{}
			}
		}
	}()
	go func() {
		defer wg.Done()
		for i := 2; i <= n; i += 2 {
			<-even
			fmt.Println(i)
			if i < n {
				odd <- struct{}{}
			}
		}
	}()
	odd <- struct{}{} // kick off
	wg.Wait()
}

Mutex + Cond: both goroutines share a counter next. Each one waits in a loop until it is its turn. You need the loop because of spurious wakeups and because Broadcast wakes everyone.

func oddEvenCond(n int) {
	var mu sync.Mutex
	cond := sync.NewCond(&mu)
	next := 1
	var wg sync.WaitGroup
	worker := func(parity int) {
		defer wg.Done()
		mu.Lock()
		defer mu.Unlock()
		for {
			for next <= n && next%2 != parity {
				cond.Wait() // atomically unlocks mu, sleeps, relocks
			}
			if next > n {
				cond.Broadcast() // let the other goroutine see the end
				return
			}
			fmt.Println(next)
			next++
			cond.Broadcast()
		}
	}
	wg.Add(2)
	go worker(1)
	go worker(0)
	wg.Wait()
}

What the interviewer is looking for: a clean exit with no leaked or deadlocked goroutine, Wait inside a for (never an if), and the explanation that Signal is enough with exactly two waiters but Broadcast is safer when there are more. Point out that the channel version is idiomatic, while the Cond version generalizes to "k goroutines printing in round-robin".

More on Classic Concurrency Coding Problems

All 16 Classic Concurrency Coding Problems questions