Goroutines
Concurrency is built into Go at the language level: you start a parallel task with the single keyword go. This is the intro topic: its goal is to understand what go does, why a goroutine is "lightweight," and how to wait for a group of goroutines cleanly, without diving into how the scheduler works.
Behind the apparent simplicity sit a few rules that interviews probe at the junior level. A goroutine is a lightweight thread managed by the Go runtime, not the operating system: you can launch tens of thousands of them because the starting stack is tiny and grows on demand. But when main returns, the program exits and all remaining goroutines are cut off — so you must wait for them explicitly. The canonical way is sync.WaitGroup: Add before starting, Done in each goroutine, Wait blocks until the counter reaches zero. Exchanging data between goroutines — through channels — is a separate topic, Channels; the scheduler design and concurrency patterns live in Concurrency.
Topic map
- The
gokeyword —go f()starts a goroutine — a lightweight runtime-managed thread; it runs concurrently, and returning frommaincuts off all goroutines at once. sync.WaitGroup—Add(n)before starting,Done()(usually viadefer) in each goroutine,Wait()blocks until the counter hits zero — the canonical way to wait for a group of goroutines.
Common mistakes and traps
| Mistake | Consequence |
|---|---|
Starting go f() and immediately returning from main | The program exits before the goroutine runs — there is no output |
| Treating a goroutine like an ordinary OS thread | You cannot spawn thousands of OS threads; a goroutine is cheap and managed by the runtime, not the kernel |
Calling wg.Add(1) inside an already-started goroutine | Wait() may see a zero counter and exit early — a race; do Add before go |
Forgetting wg.Done() in one of the goroutines | The counter never reaches zero and Wait() hangs forever |
Passing a WaitGroup by value instead of by pointer | Each goroutine sees its own copy of the counter — Wait never completes; pass *sync.WaitGroup |
Why it matters for interviews
Goroutines are an almost mandatory opening for a Go junior section: interviews start with them because this is the language's "feature." Deep scheduler knowledge is not expected at this level, but the basic mechanics of starting and waiting are asked every time.
What interviewers usually check:
- What
go f()does and why a goroutine is "lightweight" — it is managed by the Go runtime, not the OS. - Why a program with
go fmt.Println(...)inmainoften prints nothing (returning frommaincuts off goroutines). - How to wait for several goroutines with
sync.WaitGroupand whyAddgoes beforego. - What happens if you forget
Doneor pass aWaitGroupby value.