GAP·MAP
← all breakdowns
GoConcurrencyGoroutinesRuntime Schedulingjunior level

Goroutines and Go's Runtime Scheduler

the question

What is a goroutine in Go, and how does it differ from an OS thread?

what they're testing: The interviewer is checking whether you can reason about Go's concurrency model without confusing concurrency, parallelism, and operating-system threads.

a strong answer

A goroutine lets a function run concurrently with the rest of a Go program. Start one by putting go before a function or method call, as in go serve(conn). The caller evaluates the function and its arguments, then continues without waiting. When that function returns, its goroutine ends and any return values are discarded.

A goroutine is not a dedicated OS thread. The Go runtime schedules many goroutines across a set of OS threads. Their stacks start small and grow when needed, so creating a goroutine is much cheaper than creating a thread. If one goroutine blocks, the runtime can keep other runnable goroutines moving. This gives you concurrency, but not a promise that two goroutines execute at the same instant. Parallel execution depends on available CPUs and runtime scheduling.

That convenience does not make shared state safe. Goroutines share an address space, so concurrent reads and writes still need channels, mutexes, or another synchronization primitive. Completion also needs to be explicit, commonly with a channel or sync.WaitGroup. The caller should decide how it will know the work has finished.

Where people slip

the tempting wrong answer, and what's actually true

  • The `go` keyword creates a new OS thread for the function.

    The Go runtime schedules goroutines across OS threads, and a goroutine is not tied to a dedicated thread.

  • Two goroutines always run in parallel.

    Goroutines are concurrent, while simultaneous execution depends on available CPUs and runtime scheduling.

  • Shared variables are safe because goroutines are managed by Go.

    A concurrent write paired with another read or write must be synchronized, for example with a channel, mutex, or atomic operation.

  • The main goroutine automatically waits for every goroutine it starts.

    Starting a goroutine does not make the caller wait, so completion must be coordinated explicitly.

If they push further

How do goroutines communicate and synchronize?

Explain that channels combine communication with synchronization, while mutexes are often simpler for protecting shared state; the choice depends on ownership and data flow.

How do you wait for or cancel a goroutine?

Use a channel or `sync.WaitGroup` to observe completion, and pass `context.Context` or another explicit signal for cooperative cancellation.

Can you create too many goroutines?

Yes; each goroutine consumes memory and scheduling work. Use fixed workers, or acquire a semaphore permit before starting a goroutine, when incoming work could otherwise create an unbounded number.

Sources

Now answer it yourself.

Reading a strong answer is easy. Producing one under pressure is the skill the interview tests. Gapmap grades your answer against the same bar an interviewer would.

was this useful?

beta

The interviewer part is in the works.

The diagnostic, personal maps, and AI mock interviews are being finished right now. The notes stay free either way. Leave an email and you'll get the first-cohort invite, plus a month of Pro when it opens.