Go

Implement a worker pool with result collection and proper shutdown.

Question 204HardGo 1.22 to 1.25
type Result struct {
	Job int
	Out string
	Err error
}

func Pool(ctx context.Context, jobs []int, workers int) []Result {
	jobCh := make(chan int)
	resCh := make(chan Result)

	var wg sync.WaitGroup
	for range workers {
		wg.Add(1)
		go func() {
			defer wg.Done()
			for j := range jobCh {
				out, err := work(ctx, j)
				select {
				case resCh <- Result{j, out, err}:
				case <-ctx.Done():
					return
				}
			}
		}()
	}

	go func() { // producer: sole owner/closer of jobCh
		defer close(jobCh)
		for _, j := range jobs {
			select {
			case jobCh <- j:
			case <-ctx.Done():
				return
			}
		}
	}()

	go func() { wg.Wait(); close(resCh) }() // closer of resCh

	var results []Result
	for r := range resCh {
		results = append(results, r)
	}
	return results
}

What the interviewer checks: (1) each channel has exactly one closer; (2) resCh is closed only after all workers finish, which needs the WaitGroup and a separate goroutine (calling wg.Wait() in the collector would deadlock on an unbuffered resCh); (3) every blocking send also watches ctx.Done(), so cancellation can't leak goroutines; (4) results arrive out of order, so include the job ID or index.

More on Channels & select

All 38 Channels & select questions