Goroutines and Channels

Go's primary selling point is its built-in support for high-performance concurrency. Instead of the complex, memory-heavy threads found in other languages, Go uses Goroutines and Channels based on the Communicating Sequential Processes (CSP) model.

The core philosophy is: "Do not communicate by sharing memory; instead, share memory by communicating."


1. Goroutines: Multiplexed Threads

A Goroutine is a lightweight thread managed by the Go Runtime, not the Operating System.

go doWork() // Starts a new goroutine

2. Channels: The Pipe for Data

Channels are the pipes that connect goroutines. They provide a synchronized way for goroutines to send and receive values, effectively handling synchronization and locking for you.

ch := make(chan int)    // Unbuffered
ch := make(chan int, 10) // Buffered (Capacity 10)

3. Directional Channels and Selection

Go allows you to define channels that can only send or only receive, which improves type safety in your API.

The select statement is used to wait on multiple channel operations. It blocks until one of its cases can run.

select {
case msg := <-ch1:
    fmt.Println("Received", msg)
case ch2 <- "hi":
    fmt.Println("Sent hi")
default:
    fmt.Println("No communication")
}

Interview Pro-Tips: Channel Closedness

If an interviewer asks what happens when a channel is closed:

  1. Sending to a closed channel: Causes a Panic.
  2. Receiving from a closed channel: Returns the zero-value of the type (e.g., 0 for int) and a second boolean false (e.g., val, ok := <-ch).
  3. Closing a closed channel: Causes a Panic.
  4. Conclusion: Always ensure only one goroutine (the sender) is responsible for closing a channel.

Technical Summary

  1. Concurrency: Handling multiple tasks (not necessarily at the same time).
  2. Parallelism: Executing multiple tasks simultaneously (on multi-core CPUs).
  3. CSP: A mathematical approach to concurrency that avoids the need for manual Mutexes and Locks in most cases.