Go Programming Fundamentals · Concurrency & Idiomatic Go

Goroutines and Channels

Run concurrent work and communicate safely

Goroutines and Channels

A goroutine is a lightweight thread managed by the Go runtime. Starting one is as simple as prefixing a function call with the go keyword.

go processTask(taskID)

Channels

Channels let goroutines communicate and synchronize without shared-memory locking. Sending and receiving block until both sides are ready, which naturally coordinates work.

ch := make(chan string)
go func() {
    ch <- "done"
}()
msg := <-ch

Select

The select statement waits on multiple channel operations at once, enabling patterns like timeouts and fan-in/fan-out pipelines.

Practice questions

What is a goroutine, and how expensive is it compared to an OS thread?

Answer

Summary

A goroutine is a lightweight, runtime-managed unit of concurrent execution — far cheaper than an OS thread, so a program can comfortably run thousands of them at once.

Longer Answer

A goroutine is a lightweight, runtime-managed unit of concurrent execution — far cheaper than an OS thread, so a program can comfortably run thousands of them at once. This low overhead is exactly why goroutines are used so liberally in idiomatic Go code, unlike threads in many other languages. In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview.

Key Points

  • A goroutine is a lightweight, runtime-managed unit of concurrent execution — far cheaper than an OS thread, so a program can comfortably run thousands of them at once
  • This low overhead is exactly why goroutines are used so liberally in idiomatic Go code, unlike threads in many other languages
  • In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview
  • Use the answer to connect the concept back to a realistic production or interview scenario for 'What is a goroutine, and how expensive is it compared to an OS thread?'

Comparison / Tradeoffs

Aspect Notes
Core idea A goroutine is a lightweight, runtime-managed unit of concurrent execution — far cheaper than an OS thread, so a program can comfortably run thousands of them at once.
Practical tradeoff This low overhead is exactly why goroutines are used so liberally in idiomatic Go code, unlike threads in many other languages.

Why

Summary

This low overhead is exactly why goroutines are used so liberally in idiomatic Go code, unlike threads in many other languages.

Longer Answer

This low overhead is exactly why goroutines are used so liberally in idiomatic Go code, unlike threads in many other languages. In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview.

Key Points

  • This low overhead is exactly why goroutines are used so liberally in idiomatic Go code, unlike threads in many other languages
  • In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview
  • In an interview, relate 'What is a goroutine, and how expensive is it compared to an OS thread?' to implementation decisions, tradeoffs, and operational impact
  • Use the answer to connect the concept back to a realistic production or interview scenario for 'What is a goroutine, and how expensive is it compared to an OS thread?'

Comparison / Tradeoffs

Aspect Notes
Core idea This low overhead is exactly why goroutines are used so liberally in idiomatic Go code, unlike threads in many other languages.
Practical tradeoff In an interview, relate 'What is a goroutine, and how expensive is it compared to an OS thread?' to implementation decisions, tradeoffs, and operational impact.
Why do channel sends and receives block by default, and why is that useful?

Answer

Summary

An unbuffered channel blocks until both a sender and receiver are ready, which naturally synchronizes two goroutines without needing separate locks.

Longer Answer

An unbuffered channel blocks until both a sender and receiver are ready, which naturally synchronizes two goroutines without needing separate locks. This is Go's philosophy in practice: 'don't communicate by sharing memory; share memory by communicating' — channels replace explicit locks for many use cases. In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview.

Key Points

  • An unbuffered channel blocks until both a sender and receiver are ready, which naturally synchronizes two goroutines without needing separate locks
  • This is Go's philosophy in practice: 'don't communicate by sharing memory; share memory by communicating' — channels replace explicit locks for many use cases
  • In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview
  • Use the answer to connect the concept back to a realistic production or interview scenario for 'Why do channel sends and receives block by default, and why is that useful?'

Comparison / Tradeoffs

Aspect Notes
Core idea An unbuffered channel blocks until both a sender and receiver are ready, which naturally synchronizes two goroutines without needing separate locks.
Practical tradeoff This is Go's philosophy in practice: 'don't communicate by sharing memory; share memory by communicating' — channels replace explicit locks for many use cases.

Why

Summary

This is Go's philosophy in practice: 'don't communicate by sharing memory; share memory by communicating' — channels replace explicit locks for many use cases.

Longer Answer

This is Go's philosophy in practice: 'don't communicate by sharing memory; share memory by communicating' — channels replace explicit locks for many use cases. In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview.

Key Points

  • This is Go's philosophy in practice: 'don't communicate by sharing memory; share memory by communicating' — channels replace explicit locks for many use cases
  • In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview
  • In an interview, relate 'Why do channel sends and receives block by default, and why is that useful?' to implementation decisions, tradeoffs, and operational impact
  • Use the answer to connect the concept back to a realistic production or interview scenario for 'Why do channel sends and receives block by default, and why is that useful?'

Comparison / Tradeoffs

Aspect Notes
Core idea This is Go's philosophy in practice: 'don't communicate by sharing memory; share memory by communicating' — channels replace explicit locks for many use cases.
Practical tradeoff In an interview, relate 'Why do channel sends and receives block by default, and why is that useful?' to implementation decisions, tradeoffs, and operational impact.
What problem does the `select` statement solve?

Answer

Summary

It lets a goroutine wait on multiple channel operations at once and proceeds with whichever one becomes ready first, which is what you need for patterns like timeouts or merging multiple input streams.

Longer Answer

It lets a goroutine wait on multiple channel operations at once and proceeds with whichever one becomes ready first, which is what you need for patterns like timeouts or merging multiple input streams. select is essential for anything beyond the simplest single-channel handoff — timeouts, fan-in, and cancellation all rely on it. In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview.

Key Points

  • It lets a goroutine wait on multiple channel operations at once and proceeds with whichever one becomes ready first, which is what you need for patterns like timeouts or merging multiple input streams
  • select is essential for anything beyond the simplest single-channel handoff — timeouts, fan-in, and cancellation all rely on it
  • In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview
  • Use the answer to connect the concept back to a realistic production or interview scenario for 'What problem does the select statement solve?'

Comparison / Tradeoffs

Aspect Notes
Core idea It lets a goroutine wait on multiple channel operations at once and proceeds with whichever one becomes ready first, which is what you need for patterns like timeouts or merging multiple input streams.
Practical tradeoff select is essential for anything beyond the simplest single-channel handoff — timeouts, fan-in, and cancellation all rely on it.

Why

Summary

select is essential for anything beyond the simplest single-channel handoff — timeouts, fan-in, and cancellation all rely on it.

Longer Answer

select is essential for anything beyond the simplest single-channel handoff — timeouts, fan-in, and cancellation all rely on it. In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview.

Key Points

  • select is essential for anything beyond the simplest single-channel handoff — timeouts, fan-in, and cancellation all rely on it
  • In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview
  • In an interview, relate 'What problem does the select statement solve?' to implementation decisions, tradeoffs, and operational impact
  • Use the answer to connect the concept back to a realistic production or interview scenario for 'What problem does the select statement solve?'

Comparison / Tradeoffs

Aspect Notes
Core idea select is essential for anything beyond the simplest single-channel handoff — timeouts, fan-in, and cancellation all rely on it.
Practical tradeoff In an interview, relate 'What problem does the select statement solve?' to implementation decisions, tradeoffs, and operational impact.

Open in the app to mark lessons complete, take notes and track your progress.