Goroutines
⭐ Interview Importance: HIGH
⏱️ Revision Time: 4 min
TL;DR
A Goroutine is a lightweight thread managed by the Go runtime, not the Operating System. You can spawn hundreds of thousands of goroutines simultaneously because they start with a tiny 2KB stack (compared to OS threads which consume 1-2MB).
Mental Model
How It Works
To start a new goroutine, you simply put the go keyword in front of a function call.
The function will instantly execute concurrently in the background, and the main thread will continue to the next line of code.
Crucial Rule: When the main() function finishes, the entire program exits immediately. It does not wait for background goroutines to finish!
Example
package main
import (
"fmt"
"time"
)
func printNumbers() {
for i := 1; i <= 3; i++ {
fmt.Printf("Number: %d\n", i)
time.Sleep(10 * time.Millisecond)
}
}
func main() {
// 1. Spawning a named function
go printNumbers()
// 2. Spawning an anonymous function (closure)
go func() {
fmt.Println("Running from anonymous goroutine!")
}()
fmt.Println("Main thread finished executing setup.")
// DANGER: If we don't sleep, main() exits instantly,
// killing the two goroutines before they even print anything!
// (In real code, use a WaitGroup instead of Sleep).
time.Sleep(50 * time.Millisecond)
}
Common Interview Questions
What is the difference between a Goroutine and an OS Thread?
- Creation Cost: Goroutines start with a 2KB stack that grows dynamically. OS threads start with a massive fixed 1MB+ stack.
- Context Switching: The Go Scheduler switches between goroutines in user space (very fast). OS thread context switching requires a kernel trap (very slow).
- Mapping: Go uses an M:N scheduling model. ‘M’ goroutines are multiplexed onto ‘N’ OS threads.
How do you gracefully wait for Goroutines to finish?
Never use time.Sleep()! You should use a sync.WaitGroup to wait for a known number of goroutines to finish, or use Channels to signal completion.