🗺 The Atlas
Learn Go, T-shaped
First the whole field, broad and shallow. Then deep stems drive down into one domain at a time — each climbing Bloom's six levels, ending in something you build.
The one idea
A type's behavior is the set of methods it has — interfaces are satisfied implicitly, so you compose small pieces instead of building hierarchies.
A Go type never declares which interfaces it implements; if it has the methods, it satisfies the interface. So programs are assembled from small, orthogonal parts — io.Reader, error, fmt.Stringer — wired by what they do, not what they are. Pair that with explicit values everywhere (errors are ordinary returns, the zero value is ready to use, no hidden control flow) and interfaces, embedding, testing with fakes, and the standard library's design all stop being surprises.
Orient first
The ladder every stem climbs
L1
Remember
recall
L2
Understand
explain
L3
Apply
use
L4
Analyze
compare
L5
Evaluate
judge
L6
Create
build
The 8 domains
The Type System & Values
Zero values, value vs. pointer semantics, structs, identity vs. equality — the layer everything else sits on.
Create: An immutable Money value type with value semantics and a correct Equals, gated by a table test.
Interfaces & Composition
Implicit satisfaction, small interfaces, embedding, and "accept interfaces, return structs."
Create: A Notifier interface with email and SMS implementations plus a no-op fake, selected at runtime.
Errors as Values
The error interface, wrapping with %w, errors.Is / errors.As, sentinel vs. typed — no exceptions, ever.
Create: A wrapped error chain with a sentinel and a typed error, navigable by errors.Is and errors.As, gated by tests.
Slices & Maps
The built-in containers, len vs. cap, aliasing and growth, and when each is the right reach.
Create: A word-frequency pipeline that picks slice vs. map correctly, with a benchmark justifying preallocation.
Goroutines & Channels
"Share memory by communicating" — goroutines, channels, select, and context cancellation.
Create: A concurrent URL fetcher with a worker pool and context cancellation, proven race-free with -race.
Synchronization & the Memory Model
sync.Mutex, WaitGroup, atomics, the happens-before rule, and when a mutex beats a channel.
Create: A concurrent-safe in-memory cache with sharded locks, validated under the race detector.
Generics & Constraints
Type parameters, constraints, type inference, and when generics beat any or code generation.
Create: A generic Map / Filter / Reduce over any slice, constrained by comparable and ordered, with tests.
Testing & Tooling
Table-driven tests, benchmarks, the race detector, pprof, go vet — the production concerns that keep code honest.
Create: A table-tested, benchmarked package with a pprof report that justifies one optimization.