5 exercises on Go concurrency primitives — goroutines, channels, and synchronization.
0 / 5 completed
1 / 5
What is a goroutine in Go?
A goroutine is a lightweight concurrent function execution managed by the Go runtime rather than the operating system. You start one by prefixing a call with the go keyword. Goroutines begin with a tiny stack (a few kilobytes) that grows and shrinks on demand, and the runtime's scheduler multiplexes thousands of them onto a small pool of OS threads. This makes massive concurrency cheap — far cheaper than spawning OS threads directly. The runtime handles parking and resuming goroutines around blocking operations transparently.
2 / 5
What is a channel in Go?
A channel is a typed conduit through which goroutines communicate and synchronize by passing values. You send with ch <- v and receive with v := <-ch. Channels embody Go's motto: "Do not communicate by sharing memory; share memory by communicating." An unbuffered channel blocks the sender until a receiver is ready, providing synchronization; a buffered channel holds a fixed number of values before blocking. Closing a channel with close() signals that no more values will arrive, which receivers can detect.
3 / 5
What does the select statement do in Go?
The select statement lets a goroutine wait on several channel operations simultaneously, executing the case whose channel becomes ready first. If multiple are ready it chooses one at random to avoid starvation. A default clause makes the select non-blocking, running immediately when no channel is ready. Combined with a time.After channel it implements timeouts, and with a done channel it implements cancellation. select is the central tool for coordinating multiple concurrent streams of communication in Go.
4 / 5
What is a mutex (sync.Mutex) used for in Go?
A mutex (mutual exclusion lock), provided by sync.Mutex, protects shared data from concurrent access. A goroutine calls Lock() before entering a critical section and Unlock() after, ensuring only one goroutine touches the guarded state at a time and preventing data races. While channels are idiomatic for communication, mutexes are preferred for simple shared-memory protection like a counter or cache. sync.RWMutex adds a shared read lock for read-heavy workloads. Forgetting to unlock — often guarded with defer — causes deadlocks.
5 / 5
How is a context used for cancellation in Go?
A context.Context carries cancellation signals, deadlines, and request-scoped values across API boundaries and goroutines. You derive a child context with WithCancel, WithTimeout, or WithDeadline; calling the returned cancel function closes the context's Done() channel. Goroutines select on ctx.Done() to stop work promptly when a request is cancelled or times out, releasing resources. Contexts propagate down the call tree, so cancelling a parent cancels all descendants — making it the standard mechanism for graceful shutdown and timeout control in Go servers.