# Go, One Small Lesson at a Time

## Course blueprint

**444 planned micro-lessons, organized into 31 chapters. Each lesson targets 5-10 minutes.**

This is the complete chapter-and-lesson syllabus. The companion course implements Chapters 01-10 (150 lessons) as a desktop offline copy and an installable PWA when served over HTTPS; Chapters 11-31 remain planned rather than implemented. This document defines what each lesson teaches, how the learner practices it, and how concepts return over time. See `START-HERE.md` for installation, offline-download status, manual completion, and progress backups.

The delivery format is an offline-friendly browser app and downloadable ZIP. This Markdown document remains the content blueprint for expanding the available chapters into the full course.

| Design choice | Plan |
|---|---|
| Starting point | No programming or Go knowledge required. A refresher route is available for returning developers. |
| Lesson size | One narrow learning goal, a small example, and approximately 3-4 short interactions. |
| Chapter size | Usually 12 lessons; Chapters 06, 09, 10, and 15-17 have 18 each, Chapter 08 has 24, and Chapter 31 has 36. Every five focused lessons are followed by a review or checkpoint. |
| Total inventory | 370 focused learning/practice lessons and 74 scheduled review/checkpoint lessons. |
| Practice style | Predict output, choose an explanation, fill a blank, fix a small bug, order steps, or write a few lines. |
| Projects | No required large projects, capstone, long setup exercise, or application that must be maintained between chapters. |
| Continuity | Saved progress, concept-based reviews, optional chapter diagnostics, and freely accessible reference cards. |
| Outcome | Practical Go reading, editing, problem-solving, development-tool fluency, and an applied introduction to Kubernetes controllers, built through small tasks. |
| Version baseline | `go 1.27.0` module baseline; use a current supported patch release. Version-sensitive material is labeled. |

As of the reference date, 2026-09-11, the release history consulted for this blueprint lists Go 1.27.1 as the current Go 1.27 patch release. The baseline is explicit because an installed toolchain and a module's `go` directive are not the same thing. The course should not depend on experimental features.

## Pacing and expectations

At 5-10 minutes per lesson, the 444-lesson syllabus represents approximately **37-74 hours**. A 12-lesson chapter takes approximately **1-2 hours**; 18, 24, and 36 lessons take approximately **1.5-3**, **2-4**, and **3-6 hours**, respectively. Spread each chapter across as many days as desired.

| Scheduled syllabus lessons per study day | Daily time | Study days to cover 444 lessons |
|---|---|---|
| 1 | 5-10 minutes | 444 |
| 2 | 10-20 minutes | 222 |
| 3 | 15-30 minutes | 148 |
| 5 | 25-50 minutes | 89 |

Study-day counts round up when the final day has fewer lessons. These counts already include the 74 scheduled chapter reviews. Optional diagnostics, repeated attempts, and additional spaced reviews add time. If reviews replace new lessons on some days, three daily sessions might spread the course over roughly 5-7 months rather than exactly 148 calendar days.

Installing Go or an editor is a separate, optional setup activity; installation time is not disguised as a five-minute lesson. Reading and question-based practice must work without installing a compiler, database, container runtime, or Kubernetes cluster, or obtaining a cloud account.

The time budgets are authoring targets, not promises about every learner. An advanced lesson should narrow its task until it fits ten minutes, rather than silently becoming a half-hour assignment.

Micro-lessons can develop substantial fluency. They do not, by themselves, establish experience operating a large production system. The course should describe its outcomes honestly: completing a code-recognition question is not the same as independently implementing and running a program.

## The lesson pattern

| Part | Typical budget | What happens |
|---|---|---|
| Recall | 30-60 seconds | One quick question about a relevant earlier concept. |
| Learn | 1-2 minutes | A plain-language explanation of one idea, with unfamiliar terms defined. |
| See | About 1 minute | One small, annotated Go example. Imports or previously explained scaffolding can be collapsed. |
| Practice | 2-4 minutes | Approximately three short interactions with immediate, explained feedback. |
| Finish | 30-60 seconds | A takeaway, a common mistake, and a clear indication of what to revisit. |

Some activities overlap these parts, so the interface should not turn this into a rigid timer. There is no countdown or penalty for taking longer.

### Activity vocabulary

| Activity | Typical task | Feedback requirement |
|---|---|---|
| Choose | Select the correct explanation or code fragment from a small set. | Explain why the alternatives do not fit. Clearly label questions with multiple correct answers. |
| Predict | Work out an output, returned value, blocking state, or compilation outcome. | Show the relevant reasoning. Never imply that unspecified ordering is deterministic. |
| Fill | Supply one expression, argument, condition, or missing line. | Accept the explicitly supported equivalent answers; explain the missing concept. |
| Fix | Repair one deliberate defect in a short snippet. | Explain the defect, its consequence, and why the correction addresses it. |
| Order | Put three or four execution or cleanup steps in order. | Explain the dependency between steps. |
| Write | Write a small function body or a few lines inside supplied scaffolding. | Provide hints, examples, and a reference answer; do not pretend string comparison proves arbitrary Go code correct. |
| Review | Answer a small mixed set without a new lecture. | Explain missed concepts and point to the relevant lesson. |

Early writing tasks should generally need 1-5 lines. Later tasks may need 5-15 lines, occasionally up to about 20. A full HTTP service, heap implementation, database environment, or protocol-code generation pipeline must not be a prerequisite for a single activity.

### Repetition without busywork

1. Every sixth lesson reviews the preceding five focused lessons: `.06`, `.12`, and, in longer chapters, `.18`, `.24`, `.30`, and `.36`.
2. Later reviews mix their block's ideas with earlier material; the last review in each chapter is its chapter checkpoint.
3. New lessons begin with a brief recall question when an older concept is needed.
4. Additional reviews can revisit concepts after approximately 1, 3, 7, and 21 days. These are adjustable reminders, not scientifically exact forgetting deadlines.
5. Repeated questions should change names, values, edge cases, and activity types. Memorizing one answer string is not the goal.
6. A missed question should produce useful feedback and a near-term retry, not remove a life or block the rest of the course.

Three daily sessions can mean two new lessons and one due review. A scheduled chapter review can occupy that review slot; it should not automatically become extra homework.

### Progress and refresher behavior

Keep "viewed," "practiced," and "needs review" distinct. A concept becomes a stronger mastery candidate after a correct first attempt on a later, different question, rather than immediately after revealing an answer.

At the learner's request, **Skip lesson** marks a lesson complete manually while preserving the unfinished attempt. Manual completions count toward navigation/progress, are labeled separately from quiz results, and never generate a quiz score. Reopening a lesson allows the saved attempt to resume.

Returning developers can use an optional 5-10 minute chapter diagnostic. It should include a prediction or repair task, not just terminology recognition. Suggested skips are recommendations; all lessons remain available.

No streak penalty, required leaderboard, energy system, or mandatory daily minimum is needed. An optional goal and an understandable next-lesson button are sufficient.

## Chapter map

Follow the numbered order for the full beginner path. The prerequisites on individual chapters also make selective refreshers possible. Existing lesson IDs remain unchanged when a chapter is extended.

| Chapter | Theme | Lessons | Practical outcome |
|---|---|---|---|
| [01](#chapter-01-your-first-go-programs) | Your first Go programs | 12 | Read, run, and make a small change to a program. |
| [02](#chapter-02-values-variables-and-expressions) | Values, variables, and expressions | 12 | Represent data and evaluate basic expressions. |
| [03](#chapter-03-decisions-loops-and-control-flow) | Decisions, loops, and control flow | 12 | Trace and write small decisions and repetitions. |
| [04](#chapter-04-functions-scope-and-small-units-of-behavior) | Functions, scope, and behavior | 12 | Turn a small task into a clear function. |
| [05](#chapter-05-first-tests-and-debugging-habits) | First tests and debugging | 12 | Use expected behavior to find and repair defects. |
| [06](#chapter-06-arrays-slices-and-shared-storage) | Arrays, slices, and shared storage | 18 | Work with lists without common length, iteration, or aliasing mistakes. |
| [07](#chapter-07-maps-sets-and-grouping) | Maps, sets, and grouping | 12 | Look up, count, deduplicate, and group values. |
| [08](#chapter-08-strings-bytes-runes-and-text-tools) | Strings, bytes, runes, and text tools | 24 | Parse values and process text with the right standard-library helper. |
| [09](#chapter-09-structs-pointers-and-data-models) | Structs, pointers, and data models | 18 | Model related data and understand mutation and ownership. |
| [10](#chapter-10-methods-interfaces-and-composition) | Methods, interfaces, and composition | 18 | Read and design small behavioral contracts and adapters. |
| [11](#chapter-11-errors-defer-and-resource-ownership) | Errors, defer, and ownership | 12 | Handle failures without losing causes or cleanup. |
| [12](#chapter-12-packages-modules-and-go-tools) | Packages, modules, and tools | 12 | Navigate and maintain an ordinary Go module. |
| [13](#chapter-13-files-streams-and-command-line-basics) | Files, streams, and CLI basics | 12 | Read and write bounded data through standard interfaces. |
| [14](#chapter-14-json-time-configuration-and-logs) | JSON, time, configuration, and logs | 12 | Handle common application data and settings. |
| [15](#chapter-15-generics-collection-helpers-and-iterators) | Generics, collection helpers, and iterators | 18 | Use reusable APIs to sort, search, compare, collect, and deduplicate. |
| [16](#chapter-16-complexity-searching-sorting-and-numeric-helpers) | Complexity, searching, sorting, and numeric helpers | 18 | Reason about algorithm costs and choose appropriate numeric/bit operations. |
| [17](#chapter-17-stacks-queues-trees-graphs-and-heaps) | Stacks, queues, trees, graphs, and heaps | 18 | Choose structures and use heap/list helpers in small algorithm tasks. |
| [18](#chapter-18-small-steps-through-advanced-algorithms) | Advanced algorithm patterns | 12 | Recognize and repair small pieces of more complex solutions. |
| [19](#chapter-19-goroutines-channels-and-select) | Goroutines, channels, and select | 12 | Reason about communication and concurrent execution. |
| [20](#chapter-20-shared-state-and-synchronization) | Shared state and synchronization | 12 | Protect shared invariants and coordinate completion. |
| [21](#chapter-21-context-cancellation-and-bounded-work) | Context, cancellation, and bounded work | 12 | Give concurrent work a clear lifetime and limit. |
| [22](#chapter-22-http-clients-and-reliable-requests) | HTTP clients and reliable requests | 12 | Make requests without common timeout or resource mistakes. |
| [23](#chapter-23-http-handlers-routing-and-middleware) | HTTP handlers, routing, and middleware | 12 | Read, edit, and exercise a small HTTP endpoint. |
| [24](#chapter-24-sql-database-access-and-transactions) | SQL access and transactions | 12 | Use Go's database APIs with correct error and lifetime handling. |
| [25](#chapter-25-safer-api-boundaries-and-input-handling) | Safer API boundaries and inputs | 12 | Recognize and correct common trust-boundary mistakes. |
| [26](#chapter-26-stronger-tests-fuzzing-and-reliable-fixtures) | Stronger tests, fuzzing, and fixtures | 12 | Build focused confidence without brittle test machinery. |
| [27](#chapter-27-benchmarks-profiling-and-runtime-costs) | Benchmarks, profiling, and runtime costs | 12 | Investigate performance before changing code. |
| [28](#chapter-28-reading-production-libraries-and-protocols) | Production libraries and protocols | 12 | Navigate representative ecosystem tools and their roles. |
| [29](#chapter-29-building-shipping-and-maintaining-go-software) | Building, shipping, and maintenance | 12 | Understand the path from source changes to operable software. |
| [30](#chapter-30-everyday-go-fluency-in-small-tasks) | Everyday Go fluency | 12 | Combine skills through independent, short maintenance tasks. |
| [31](#chapter-31-kubernetes-concepts-and-practical-go-controllers) | Kubernetes concepts and practical Go controllers | 36 | Read and repair reconciles, watches, filters, lifecycle handling, and controller fixtures. |

## Chapter 01: Your first Go programs

**Goal:** Make code feel readable rather than mysterious.

**Prerequisites:** None.

All tool-output activities have supplied examples. Installing tools is optional at this stage.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 01.01 | **What a program does.** Recognize instructions, inputs, values, and outputs. | Choose which short instruction sequence produces a described result. |
| 01.02 | **The shape of a Go file.** Recognize `package`, `import`, `func main`, braces, and statements. | Fill a missing part of an annotated five-line program. |
| 01.03 | **Printing a result.** Use `fmt.Println` and distinguish source text from printed output. | Predict the two lines printed by a tiny program. |
| 01.04 | **Source, execution, and binaries.** Distinguish writing code, compiling it, and running the result. | Order the steps from source edit to program output. |
| 01.05 | **Comments and formatting.** Read comments and recognize Go's standard formatting style. | Choose the program with the intended behavior despite different whitespace. |
| 01.06 | **Review: read a whole tiny program.** Retrieve the first five ideas without new syntax. | Identify the entry point, ignore a comment, and predict a printed result. |
| 01.07 | **Terminal and working directory.** Understand where commands run and why file paths matter. | Match a PowerShell prompt and file listing to the correct command location. |
| 01.08 | **The Go toolchain.** Distinguish `go version`, `go run`, and `go build`. | Choose the command for a supplied run/build scenario. |
| 01.09 | **A first module.** Recognize a module folder and `go.mod`; distinguish toolchain version from language baseline. | Fill the intended `go` directive in a supplied module file. |
| 01.10 | **Reading a compiler message.** Find the file, line, and useful first complaint. | Fix a missing brace or misspelled identifier in a short example. |
| 01.11 | **A tiny edit-run cycle.** Change one value and compare intended with observed output. | Make one edit to a greeting and choose the resulting output. |
| 01.12 | **Checkpoint: orient yourself.** Read a program and its surrounding tool output. | Complete a small mixed set about source, commands, and one compiler error. |

## Chapter 02: Values, variables, and expressions

**Goal:** Know what basic expressions mean and where their values live.

**Prerequisites:** Chapter 01.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 02.01 | **Basic values and types.** Distinguish integers, floating-point values, strings, and booleans. | Match literals to their types without relying on another language's rules. |
| 02.02 | **Names and assignment.** Understand a variable as a named place holding a value. | Predict a value after two assignments. |
| 02.03 | **Short declarations.** Introduce local variables with `:=`. | Fill the declaration rather than an assignment to an undeclared name. |
| 02.04 | **Typed declarations and zero values.** Recognize what `var` initializes when no value is supplied. | Predict the initial values of a few basic variables. |
| 02.05 | **Declaration versus reassignment.** Apply the same-block rule for `:=` introducing at least one new variable. | Fix a `no new variables` error without creating a different scope. |
| 02.06 | **Review: follow changing values.** Revisit types, zero values, and declaration rules. | Trace a short sequence and repair one declaration. |
| 02.07 | **Constants and small enumerations.** Use `const` and understand a simple `iota` sequence. | Predict a three-value constant group and identify an illegal reassignment. |
| 02.08 | **Numeric types and conversions.** Recognize when explicit conversion is required. | Fill a conversion in an expression combining different numeric types. |
| 02.09 | **Arithmetic and integer division.** Apply arithmetic operators and recognize that `++` is a statement. | Predict integer division and fix an increment used as an expression. |
| 02.10 | **Booleans and short-circuiting.** Evaluate comparisons and logical conditions in order. | Predict whether the right-hand side of a condition is evaluated. |
| 02.11 | **Numeric limits.** Recognize integer range limits and inexact floating-point arithmetic. | Choose a safe type or comparison strategy for a small numeric scenario. |
| 02.12 | **Checkpoint: expressions without surprises.** Combine assignment, conversion, and boolean reasoning. | Repair a tiny calculation and explain its original result. |

## Chapter 03: Decisions, loops, and control flow

**Goal:** Trace the path a program takes and make it repeat safely.

**Prerequisites:** Chapters 01-02.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 03.01 | **An `if` decision.** Select behavior using a boolean condition. | Fill the condition that accepts a value inside a stated bound. |
| 03.02 | **`else` and chained decisions.** Understand which branch executes and which are skipped. | Predict a result for boundary inputs. |
| 03.03 | **An `if` initializer.** Read a short initializer and its limited scope. | Fix a reference to an initializer variable outside its scope. |
| 03.04 | **Value switches.** Recognize matching cases, `default`, and the absence of implicit fallthrough. | Predict which case bodies run. |
| 03.05 | **Condition switches.** Use an expressionless switch to make ordered conditions readable. | Choose the first matching condition for overlapping cases. |
| 03.06 | **Review: take the correct branch.** Revisit scope, ordering, and boundaries. | Trace three tiny decisions with different input values. |
| 03.07 | **A counted `for` loop.** Follow initialization, condition, body, and update. | Predict the visited counter values. |
| 03.08 | **Condition-only and infinite loops.** Recognize the forms Go uses instead of a separate `while` keyword. | Fill the condition that makes a loop terminate correctly. |
| 03.09 | **`break` and `continue`.** Distinguish ending a loop from skipping an iteration. | Repair the wrong control statement in a short search. |
| 03.10 | **Integer ranges.** Use `range` over an integer in modern Go and identify the visited values. | Predict the iterations of `for i := range n`. |
| 03.11 | **Off-by-one and nested-loop tracing.** Reason about a small loop boundary before changing code. | Fix one bound in a two-loop example with a supplied expected count. |
| 03.12 | **Checkpoint: a tiny loop repair.** Combine condition and repetition reasoning. | Correct a short counting function and identify a boundary input. |

## Chapter 04: Functions, scope, and small units of behavior

**Goal:** Express one task as a small, understandable function.

**Prerequisites:** Chapters 01-03.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 04.01 | **Declaring and calling functions.** Read parameters, a return type, and a call. | Fill a short function signature and call it with a value. |
| 04.02 | **Parameter values.** Understand that a function receives copies of argument values. | Predict whether changing an integer parameter changes the caller's variable. |
| 04.03 | **Multiple results.** Return and receive more than one value; use `_` deliberately. | Fill the assignments receiving a quotient and remainder. |
| 04.04 | **Early returns.** Make an invalid or finished case leave a function clearly. | Replace unnecessary nesting with one guard return. |
| 04.05 | **Named results.** Read named return variables and prefer explicit returns when clarity benefits. | Predict which value is returned after a named result changes. |
| 04.06 | **Review: follow a call.** Revisit parameter copies, return paths, and multiple results. | Trace a two-function example with a boundary input. |
| 04.07 | **Scope and shadowing.** Distinguish a changed outer variable from a newly declared inner one. | Fix an accidental shadow that prevents an update. |
| 04.08 | **Functions as values.** Recognize function types and small anonymous functions. | Pass a supplied function value to a simple caller. |
| 04.09 | **Closures.** Understand a function using variables from its enclosing scope. | Predict a small counter closure across two calls. |
| 04.10 | **Pure versus stateful behavior.** Recognize hidden inputs and side effects. | Choose the function whose result depends only on its arguments. |
| 04.11 | **A first failure result.** Read the basic `(value, error)` convention, `nil` success, and a simple `errors.New`. | Fill an error check before using a returned value. |
| 04.12 | **Checkpoint: one useful little function.** Write a bounded, clearly specified behavior. | Complete a 3-5 line function with a guard and a result. |

The `error` type is introduced here as a standard failure value. Its interface mechanics and richer handling belong to Chapters 10-11; learners do not need to implement it yet.

## Chapter 05: First tests and debugging habits

**Goal:** Use evidence rather than guesswork when a small function is wrong.

**Prerequisites:** Chapters 01-04.

The test function's `t *testing.T` signature is supplied and annotated as a test handle. Pointer syntax is revisited fully in Chapter 09.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 05.01 | **Expected versus actual.** Turn a function requirement into an observable example. | Choose an input and expected output that exercise a stated rule. |
| 05.02 | **A first Go test.** Recognize `_test.go` and `Test...`, then use `go test` with a supplied scaffold. | Fill the call to the function being tested. |
| 05.03 | **A useful failure message.** Compare `got` and `want` and report enough context. | Complete a small `t.Fatalf` assertion using the supplied format pattern. |
| 05.04 | **Boundary cases.** Look beyond the happy path to zero, negatives, and limits. | Select the input that exposes an off-by-one defect. |
| 05.05 | **Repair from a failing example.** Change the rule that is wrong, not the expected answer. | Fix a tiny function while preserving its stated behavior. |
| 05.06 | **Review: let the evidence guide you.** Revisit examples, assertions, and boundaries. | Match a failure report to the responsible line. |
| 05.07 | **Kinds of failure.** Distinguish a compiler error, runtime panic, and incorrect result. | Classify three short failure examples. |
| 05.08 | **Reading test output.** Find the failed test, location, and useful difference. | Choose the next source location to inspect from a supplied report. |
| 05.09 | **A minimal reproduction.** Remove unrelated steps while keeping the failure. | Select the smallest input and snippet that still demonstrate a bug. |
| 05.10 | **Stepping through state.** Understand breakpoints, stepping, and inspecting variables. | Read supplied debugger snapshots and identify the first wrong value. |
| 05.11 | **Temporary diagnostic output.** Place a useful observation without changing the behavior under study. | Choose a helpful print location and remove it after the repair. |
| 05.12 | **Checkpoint: repair and demonstrate.** Make a small fix and select a case that would catch a regression. | Complete one function repair and one focused assertion. |

## Chapter 06: Arrays, slices, and shared storage

**Goal:** Work confidently with lists and the difference between a slice and its storage.

**Prerequisites:** Chapters 02-04.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 06.01 | **Arrays.** Recognize fixed length, array types, and value-copy behavior. | Predict whether changing a copied array changes the original. |
| 06.02 | **Slices and indexing.** Read a slice literal, use `len`, and respect index bounds. | Fill an index condition that avoids a panic. |
| 06.03 | **Slice expressions.** Apply inclusive lower and exclusive upper bounds. | Predict the elements in several short subslices. |
| 06.04 | **Iterating a slice.** Use index/value range variables and recognize zero iterations for nil or empty slices. | Fill a range loop that uses element values rather than indices. |
| 06.05 | **Keeping the result of `append`.** Understand that append returns the updated slice value. | Fill the assignment that grows a slice correctly. |
| 06.06 | **Review: lengths and elements.** Revisit arrays, bounds, empty values, and append. | Trace a short sequence of slice operations. |
| 06.07 | **Length versus capacity.** Use `make` without confusing reserved space with existing elements. | Fix a slice accidentally created with unwanted zero-valued elements. |
| 06.08 | **Shared backing storage.** Understand how copied slice values can refer to the same elements. | Predict a mutation through two overlapping slices. |
| 06.09 | **Append and storage reuse.** Reason from available capacity without assuming an exact growth factor. | Choose which mutation is guaranteed, possible, or not implied by a snippet. |
| 06.10 | **Copying elements.** Use `copy` to separate storage and recognize a shallow copy. | Complete a small independent-copy operation. |
| 06.11 | **Variadic functions.** Read `...T` parameters and expand a slice with `...`. | Fix a variadic call that passes a slice incorrectly. |
| 06.12 | **Checkpoint: a list bug.** Combine length, capacity, and ownership reasoning. | Repair one aliasing or append mistake in a supplied 8-line function. |
| 06.13 | **Range values are copies.** Distinguish changing a range variable from changing the indexed slice element. | Repair an increment loop whose changes never reach the slice. |
| 06.14 | **Slices passed to functions.** Separate shared element mutations from changes to the callee's slice length. | Keep a returned appended slice while predicting an existing-element update. |
| 06.15 | **Full slice expressions.** Use the third index to limit capacity without claiming it copies elements. | Prevent an append from reusing a protected tail while recognizing remaining element aliasing. |
| 06.16 | **Removing an element.** Use a bounded index and overlapping slice operations to shorten a list deliberately. | Remove one item and retain the returned length rather than write a full collection library. |
| 06.17 | **Slices of slices.** Build a tiny matrix and distinguish shared rows from independently allocated rows. | Fix a two-row matrix whose rows unexpectedly change together. |
| 06.18 | **Checkpoint: small mutation decisions.** Revisit iteration copies, function boundaries, capacity limits, and nested storage. | Make one local repair while preserving the caller's stated ownership contract. |

## Chapter 07: Maps, sets, and grouping

**Goal:** Use keyed collections deliberately, including their zero-value and ordering behavior.

**Prerequisites:** Chapters 03-04 and 06.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 07.01 | **Creating a map.** Read key/value types, map literals, and `make`. | Fill a map declaration for a small lookup table. |
| 07.02 | **Lookup and presence.** Distinguish a missing key from a present zero value using comma-ok. | Fix a presence check that treats a stored zero as absent. |
| 07.03 | **Updating and removing entries.** Use assignment, `delete`, and `clear` for their intended effects. | Predict a map's contents after a short sequence, without relying on print order. |
| 07.04 | **Iteration is unordered.** Recognize that map iteration order is unspecified. | Reject a test that expects one particular iteration sequence. |
| 07.05 | **Valid keys.** Recognize comparability requirements and why slices cannot be map keys. | Choose a valid key type for a supplied example. |
| 07.06 | **Review: lookups without assumptions.** Revisit presence, updates, key rules, and ordering. | Repair two small map misconceptions. |
| 07.07 | **Nil versus initialized maps.** Distinguish safe reads from writes requiring initialized storage. | Fix the initialization of a map used for accumulation. |
| 07.08 | **Map assignment and aliasing.** Understand that assignment does not clone the contents. | Predict whether an update is visible through another map variable. |
| 07.09 | **A small set.** Use `map[string]bool` for straightforward membership. | Complete a deduplication step. |
| 07.10 | **Frequency counting.** Use missing-key zero values intentionally. | Fill the update in a short word-counting loop. |
| 07.11 | **Grouping values.** Combine maps and slices without separate state for every group. | Complete one `map[string][]int` append operation. |
| 07.12 | **Checkpoint: count, group, or deduplicate.** Choose the right collection operation. | Repair a short grouping function and identify an absent-key edge case. |

## Chapter 08: Strings, bytes, runes, and text tools

**Goal:** Read and manipulate text without silently assuming every character is one byte.

**Prerequisites:** Chapters 03-04 and 06-07.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 08.01 | **String and rune literals.** Distinguish interpreted strings, raw strings, and rune literals. | Choose the literal that preserves a supplied path or escape sequence. |
| 08.02 | **UTF-8 and byte length.** Recognize that string length and indexing operate on bytes. | Predict the byte length of a supplied string containing `\u00e9`. |
| 08.03 | **Ranging over text.** Interpret byte offsets and decoded runes from a string range. | Match the iteration results to a short non-ASCII example. |
| 08.04 | **Text conversions.** Convert between strings, byte slices, and rune slices for the intended operation. | Fix a character-editing operation that cuts a UTF-8 encoding in half. |
| 08.05 | **Simple string helpers.** Use `strings.TrimSpace`, `Contains`, `HasPrefix`, or `Index` instead of a matching hand-written scan. | Choose the helper and handle the not-found result for a stated input rule. |
| 08.06 | **Review: bytes are not characters.** Revisit literals, lengths, iteration, and conversion. | Repair one byte/rune misconception and predict one output. |
| 08.07 | **Splitting and joining.** Distinguish `Fields`, `Split`, and `Join`, including empty input behavior. | Choose the result of processing repeated whitespace. |
| 08.08 | **`strconv`: decimal integers.** Use `Atoi` and `Itoa`; distinguish decimal formatting from the rune conversion performed by `string(n)`. | Fix a number-to-text conversion and preserve an invalid-input error. |
| 08.09 | **Formatting values.** Use common `fmt` verbs such as `%v`, `%q`, and `%T` deliberately. | Match a formatting expression to its intended diagnostic output. |
| 08.10 | **Building text.** Read a small `strings.Builder` example and avoid unnecessary repeated concatenation. | Complete a short multi-part message builder. |
| 08.11 | **A first regular expression.** Recognize when a small pattern helps and when plain string helpers are clearer. | Choose an anchored numeric pattern or a simpler non-regex alternative. |
| 08.12 | **Checkpoint: a text-processing repair.** Combine normalization, conversion, and Unicode awareness. | Fix one small parser and choose an input that previously broke it. |
| 08.13 | **`strconv`: binary and hexadecimal.** Read the base arguments of `ParseInt` and `FormatInt`, including explicit bases versus prefix inference. | Convert a small binary or hexadecimal representation using the intended base. |
| 08.14 | **`strconv`: signedness and range.** Choose `ParseInt` or `ParseUint`, an appropriate bit size, and the matching formatter. | Reject an overflowing or negative unsigned input instead of silently accepting a partial result. |
| 08.15 | **`strconv`: booleans.** Use `ParseBool` and `FormatBool` rather than treating every nonempty string as true. | Distinguish accepted Boolean spellings from an invalid value. |
| 08.16 | **`strconv`: floating-point text.** Use `ParseFloat` and `FormatFloat` with a stated bit size and output format. | Fill a small parse/format operation without assuming exact decimal arithmetic. |
| 08.17 | **`strconv`: append into a byte buffer.** Use `AppendInt` or `AppendUint` when the destination is already a byte slice. | Keep the returned buffer while adding a numeric field to a small encoded result. |
| 08.18 | **Review: match the conversion contract.** Revisit bases, widths, errors, Boolean values, and formatting. | Choose the conversion matching a stated input rule and repair one ignored error. |
| 08.19 | **Unicode-aware classification.** Use `unicode.IsLetter`, `IsDigit`, and `IsSpace` when the problem actually permits Unicode. | Choose an ASCII range check or a Unicode predicate for a supplied character policy. |
| 08.20 | **Case-insensitive text rules.** Distinguish rune case conversion, `strings.ToLower`, and `strings.EqualFold`. | Replace a manual case comparison without assuming case folding performs Unicode normalization. |
| 08.21 | **UTF-8 helpers.** Read `utf8.RuneCountInString`, `DecodeRuneInString`, and `ValidString` for their distinct contracts. | Advance by a decoded rune's byte width or reject a supplied invalid encoding. |
| 08.22 | **Custom tokenization.** Use `strings.FieldsFunc` with a small separator predicate. | Split on multiple delimiters while recognizing that empty fields are discarded. |
| 08.23 | **Byte-slice helpers.** Use `bytes.Equal`, `Index`, or `Contains` when the input is already bytes. | Replace a short byte-search loop without pretending byte matching is rune-aware. |
| 08.24 | **Checkpoint: choose the text shortcut.** Combine parsing, tokenization, byte/rune choices, and standard helpers. | Repair one small coding-challenge-style text operation using an appropriate library call. |

Rune counts are not necessarily counts of user-perceived characters. A brief reference note should explain combining characters without turning this chapter into a full Unicode text-segmentation course.

Challenge contracts still govern the solution. For example, `strconv.Atoi` is not automatically an implementation of a problem's custom "atoi" rules for leading whitespace, trailing characters, or 32-bit clamping. Unicode classification also does not imply that numeric parsers accept every Unicode digit.

## Chapter 09: Structs, pointers, and data models

**Goal:** Group related data and reason about copying, identity, and mutation.

**Prerequisites:** Chapters 04 and 06-08.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 09.01 | **A struct type.** Define fields and recognize their zero values. | Fill a small record type for a described item. |
| 09.02 | **Literals and field access.** Prefer readable keyed literals and use selectors. | Repair a field initialization after a struct changes. |
| 09.03 | **Nested data.** Read a struct containing another struct or collection. | Fill the selector reaching one nested value. |
| 09.04 | **Struct comparability.** Recognize how field types affect equality and map-key eligibility. | Choose which record type can be compared with `==`. |
| 09.05 | **Shallow copies.** Distinguish copying the outer struct from cloning referenced slice or map data. | Predict a mutation after a struct assignment. |
| 09.06 | **Review: understand the data shape.** Revisit fields, nesting, equality, and copies. | Trace a tiny record update and identify shared storage. |
| 09.07 | **Addresses and pointers.** Read `&` and `*` as address-taking and dereferencing. | Fill a pointer update and predict the resulting value. |
| 09.08 | **Nil pointers.** Recognize an absent pointer and guard before dereferencing. | Fix a nil dereference without inventing a success value. |
| 09.09 | **Choosing value or pointer parameters.** Remember that Go always passes values, including pointer values. | Choose the signature that permits an intended caller-visible mutation. |
| 09.10 | **Allocating an initialized value.** Read `new(T)` and Go 1.26+'s `new(expression)`. | Choose the pointer expression matching a desired initial value. |
| 09.11 | **Defined types versus aliases.** Distinguish a new named type from another name for an existing type. | Predict an assignment or required conversion involving a domain identifier. |
| 09.12 | **Checkpoint: model and mutate carefully.** Combine records, pointers, and collection ownership. | Repair a small update function while preserving an unrelated original value. |
| 09.13 | **Records stored in maps.** Understand why a map's struct value needs a read-modify-write step. | Fix a field update that tries to mutate a non-addressable map value directly. |
| 09.14 | **Records stored in slices.** Apply range-copy reasoning to a slice of structs. | Update the real element by index instead of changing a temporary struct copy. |
| 09.15 | **Optional values.** Use a pointer when absence must differ from a real zero value. | Distinguish an unknown count from a known count of zero. |
| 09.16 | **Returning a local address safely.** Recognize Go-managed lifetime without assuming a pointer necessarily lives on the stack or heap. | Read a small constructor returning a pointer to an initialized local value. |
| 09.17 | **An independent snapshot.** Copy the specific nested mutable fields that a snapshot must own. | Complete a short copy helper without claiming that a shallow struct assignment is a deep copy. |
| 09.18 | **Checkpoint: where does the mutation land?** Combine pointers, maps, slices, optional data, and independent copies. | Repair one unintended update using a tiny supplied data model. |

## Chapter 10: Methods, interfaces, and composition

**Goal:** Understand Go's approach to behavior without importing class-inheritance assumptions.

**Prerequisites:** Chapters 04-05 and 09.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 10.01 | **Methods and receivers.** Read a method declaration and call it on a value. | Turn a supplied operation into a tiny value-receiver method. |
| 10.02 | **Pointer receivers.** Choose a receiver when mutation or avoiding a large copy matters. | Fix a method whose update is lost on a copied receiver. |
| 10.03 | **Method sets.** Distinguish convenient method calls from satisfying an interface with `T` or `*T`. | Choose which assignment compiles from a supplied method-set table. |
| 10.04 | **An interface contract.** Recognize implicit implementation of a small method set. | Select the type that satisfies a one-method interface. |
| 10.05 | **Calling through an interface.** Use behavior without knowing the concrete implementation. | Fill the operation in a function accepting a small interface. |
| 10.06 | **Review: receivers and contracts.** Revisit method calls, mutation, and interface satisfaction. | Repair a receiver/interface mismatch. |
| 10.07 | **Interface values and typed nil.** Distinguish a nil interface from one holding a typed nil pointer; recognize `any`. | Predict an interface comparison with `nil`. |
| 10.08 | **Type assertions.** Use comma-ok when the dynamic type is not guaranteed. | Fix an assertion that can panic on an ordinary input. |
| 10.09 | **Type switches.** Handle a small set of dynamic types explicitly. | Fill one branch and an appropriate default. |
| 10.10 | **Embedding and promotion.** Recognize composition and promoted methods without assuming inheritance. | Explain which method is selected in a small embedded type. |
| 10.11 | **Small consumer-side interfaces.** Introduce a seam around behavior the caller actually needs. | Choose a one-method contract instead of a large implementation-shaped interface. |
| 10.12 | **Checkpoint: a clear behavioral boundary.** Combine receiver choice and interface use. | Repair a short caller/provider example without adding an unnecessary abstraction. |
| 10.13 | **Methods on nil receivers.** Distinguish a method that deliberately handles nil from one that dereferences it. | Add a small receiver guard while keeping ordinary failure behavior explicit. |
| 10.14 | **Composing interfaces.** Embed small interfaces to express a combined contract. | Choose the type that satisfies both supplied method sets. |
| 10.15 | **Method values as callbacks.** Understand what a saved method value captures for a value or pointer receiver. | Predict a callback's result after the original receiver variable changes. |
| 10.16 | **Function adapters.** Give a named function type a method so it satisfies a small interface. | Complete one adapter call instead of adding a large implementation type. |
| 10.17 | **Slices of interface values.** Distinguish converting one element from assigning an entire concrete slice to an interface slice. | Fill a short element-by-element conversion for a supplied interface-based API. |
| 10.18 | **Checkpoint: choose the smallest useful boundary.** Revisit nil handling, composition, callbacks, adapters, and conversions. | Fix one small interface interaction without changing unrelated concrete behavior. |

## Chapter 11: Errors, defer, and resource ownership

**Goal:** Preserve useful failure information and make cleanup predictable.

**Prerequisites:** Chapters 04 and 09-10.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 11.01 | **Errors as values.** Read the `error` interface and return failures deliberately. | Complete an error return rather than a silent zero-value success. |
| 11.02 | **Useful error context.** Add an operation or relevant identifier without leaking sensitive data. | Choose a clear `fmt.Errorf` message for a supplied failure. |
| 11.03 | **Propagating failures.** Handle an error at the layer that can make the decision. | Fix a swallowed error or unnecessary log-and-return duplication. |
| 11.04 | **Wrapping and `errors.Is`.** Preserve a cause with `%w` and match it without string comparison. | Repair a wrapped-error check. |
| 11.05 | **Typed errors and `errors.As`.** Retrieve structured error information safely. | Fill the target and check for a small custom error type. |
| 11.06 | **Review: keep the cause.** Revisit creation, context, propagation, and inspection. | Choose which error path preserves the information a caller needs. |
| 11.07 | **When deferred calls run.** Understand argument evaluation time and last-in-first-out execution. | Predict a three-line deferred-output example. |
| 11.08 | **Cleanup ownership and scope.** Place cleanup where a resource lifetime actually ends. | Repair a defer-inside-a-loop pattern that retains resources too long. |
| 11.09 | **Panic versus ordinary failure.** Distinguish broken assumptions from expected input or I/O failures. | Choose an error return instead of panic for an ordinary bad input. |
| 11.10 | **Recovery boundaries.** Read a narrow deferred recovery boundary and its same-goroutine limitation. | Reject a recovery pattern that cannot catch the indicated panic. |
| 11.11 | **Multiple failures.** Use `errors.Join` when independent failures both matter. | Choose a result that preserves two supplied cleanup/operation failures. |
| 11.12 | **Checkpoint: fail and clean up honestly.** Combine propagation, inspection, and ownership. | Repair one short failure path without hiding the original problem. |

## Chapter 12: Packages, modules, and Go tools

**Goal:** Be comfortable inside an existing Go repository.

**Prerequisites:** Chapters 01, 04-05, and 10-11.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 12.01 | **Package boundaries and exported names.** Distinguish local implementation details from a package's public surface. | Fix an access to an unexported name across a package boundary. |
| 12.02 | **Imports and aliases.** Read import paths, package names, and deliberate aliases. | Resolve a name collision without a dot import. |
| 12.03 | **Import cycles.** Recognize a dependency cycle and a small way to move the shared boundary. | Choose a package diagram that has no cycle. |
| 12.04 | **What `go.mod` means.** Distinguish module path, minimum Go version, and dependency requirements. | Identify the field responsible for a supplied compatibility issue. |
| 12.05 | **Adding dependencies versus installing tools.** Distinguish `go get` from versioned `go install`. | Choose the command for a library dependency or standalone developer tool. |
| 12.06 | **Review: navigate a module.** Revisit exports, imports, version baseline, and tool roles. | Match a small repository problem to the relevant file or command. |
| 12.07 | **Tidying and checksums.** Understand `go mod tidy` and why `go.sum` is not a conventional full dependency lockfile. | Read a small module diff after an import is removed. |
| 12.08 | **Versions and major paths.** Read semantic versions and recognize `/v2` import-path rules. | Choose a compatible import after a major-version change. |
| 12.09 | **Finding an API.** Read `go doc` or a package documentation excerpt efficiently. | Locate a function's parameters, result, and relevant usage caveat. |
| 12.10 | **Formatting and static diagnostics.** Distinguish the jobs of `gofmt` and `go vet`. | Match a formatting change or diagnostic to the appropriate tool. |
| 12.11 | **Multi-module workspaces.** Recognize what `go.work` connects and when one module is sufficient. | Choose whether a supplied local development scenario needs a workspace. |
| 12.12 | **Checkpoint: one repository maintenance task.** Combine package and module reasoning. | Repair a small import/version mismatch using supplied files and output. |

## Chapter 13: Files, streams, and command-line basics

**Goal:** Read and write data with clear bounds and ownership.

**Prerequisites:** Chapters 08 and 10-12.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 13.01 | **`io.Reader` and `io.Writer`.** Recognize small interfaces that decouple data sources and destinations. | Choose the parameter type for an operation that only reads bytes. |
| 13.02 | **In-memory streams.** Use `strings.NewReader` or `bytes.Buffer` to supply a small stream. | Fill a fixture without opening a real file. |
| 13.03 | **The read contract.** Handle returned bytes before a simultaneous error, including `io.EOF`. | Fix a loop that discards the last bytes of a stream. |
| 13.04 | **Copying streams.** Use `io.Copy` instead of rewriting a correct general-purpose copy loop. | Complete a source-to-destination copy and preserve its error. |
| 13.05 | **Scanning records.** Read `bufio.Scanner`, check `Err`, and recognize its token-size limit. | Repair a scanner loop that silently treats a scanning error as success. |
| 13.06 | **Review: streams and failures.** Revisit contracts, helpers, and final error checks. | Identify a partial-read mistake and choose the simpler correct helper. |
| 13.07 | **Whole-file operations.** Use `os.ReadFile` and `os.WriteFile` when bounded data makes them appropriate. | Choose between whole-file and streaming access for a stated input size. |
| 13.08 | **Open-file lifetime.** Close owned files and recognize when write/close failures matter. | Repair a short file-writing cleanup path. |
| 13.09 | **Portable path construction.** Use `filepath` rather than hand-built operating-system separators. | Fix a path join while recognizing that joining alone does not enforce containment. |
| 13.10 | **Arguments and flags.** Distinguish positional arguments from flags using `os.Args` and `flag`. | Fill one flag declaration and select its parsed result. |
| 13.11 | **Output and exit status.** Separate normal output, diagnostics, and exit codes; remember `os.Exit` skips defers. | Move an exit decision so owned resources can be cleaned up. |
| 13.12 | **Checkpoint: a small CLI behavior.** Combine input, output, and failure handling. | Repair a supplied short command operation, not build a whole CLI application. |

## Chapter 14: JSON, time, configuration, and logs

**Goal:** Handle everyday application data using the standard library.

**Prerequisites:** Chapters 08-09 and 11-13.

This chapter initially uses the supported `encoding/json` API, which remains common in existing code. Lesson 28.10 explicitly covers the Go 1.27 `encoding/json/v2` migration boundary.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 14.01 | **Encoding JSON.** Relate a small Go value to JSON objects, arrays, and scalar values. | Predict a simple marshaled representation with no map-order dependency. |
| 14.02 | **Decoding JSON.** Supply a destination and handle decoding failures before using it. | Fix an incorrect destination argument to `json.Unmarshal`. |
| 14.03 | **JSON fields and optional data.** Read tags, exported fields, and the difference between absent and zero-valued data. | Choose a small struct representation that preserves a required distinction. |
| 14.04 | **Streaming JSON.** Recognize the role of `json.Decoder` when input is a reader. | Complete a decoding call and return its error. |
| 14.05 | **CSV as structured text.** Use `encoding/csv` rather than splitting blindly on commas. | Choose the correctly parsed record containing a quoted comma. |
| 14.06 | **Review: representation and decoding.** Revisit field visibility, destinations, and structured-text boundaries. | Repair a small decode path and identify a lossy representation. |
| 14.07 | **Durations and units.** Treat `time.Duration` as a typed duration, not an unexplained integer. | Fix a milliseconds/nanoseconds mix-up. |
| 14.08 | **Timestamps and layouts.** Parse and format using a clear layout such as `time.RFC3339`. | Fill the layout and handle a parse error rather than using a zero time silently. |
| 14.09 | **Environment settings.** Distinguish unset from empty values with `os.LookupEnv`. | Repair a setting that incorrectly treats an explicit empty value as absent. |
| 14.10 | **Structured logging.** Use `log/slog` attributes and appropriate levels. | Replace an ambiguous concatenated message with structured fields. |
| 14.11 | **Configuration precedence.** Apply an explicit order among defaults, files, environment, and flags. | Predict the winning value from a small supplied configuration table. |
| 14.12 | **Checkpoint: load and describe a setting.** Combine parsing, failure handling, and useful diagnostics. | Repair one configuration path without silently accepting invalid data. |

## Chapter 15: Generics, collection helpers, and iterators

**Goal:** Read modern Go APIs and reuse logic where the abstraction is justified.

**Prerequisites:** Chapters 04, 06-07, 09-10, and 12.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 15.01 | **Why a type parameter exists.** Read a generic function and basic type inference. | Fill a call to a function that works over more than one element type. |
| 15.02 | **Constraints.** Distinguish `any` from `comparable` when an operation requires equality or map keys. | Choose the smallest constraint supporting a supplied operation. |
| 15.03 | **Type sets and underlying types.** Read a small union constraint and the purpose of `~`. | Decide whether a defined numeric type satisfies a supplied constraint. |
| 15.04 | **Generic types and their receivers.** Read a small parameterized container and a method using its type parameter. | Fill a receiver's type-parameter use in a tiny container method. |
| 15.05 | **Generic methods in Go 1.27.** Recognize a method's own type parameters and the restriction on interface methods. | Choose the valid declaration from version-labeled examples. |
| 15.06 | **Review: only the operations promised.** Revisit constraints, inference, and generic type/method forms. | Fix one operation unsupported by its constraint. |
| 15.07 | **Slice copying and equality helpers.** Use `slices.Clone` and `slices.Equal` while preserving shallow-copy awareness. | Replace a small copy/comparison loop without assuming nested data was cloned. |
| 15.08 | **Map copying and equality helpers.** Use `maps.Clone` and `maps.Equal` with comparable values and no ordering assumption. | Compare two frequency maps and identify what a clone does not isolate. |
| 15.09 | **Consuming an iterator.** Read `iter.Seq` and range-over-function usage. | Trace the values produced by a supplied small iterator. |
| 15.10 | **Producing an iterator.** Respect the boolean result from `yield` when a consumer stops. | Repair an iterator that keeps producing after early termination. |
| 15.11 | **Choosing an abstraction.** Distinguish concrete types, interfaces, and type parameters by their purpose. | Choose the least complex useful signature for a small requirement. |
| 15.12 | **Checkpoint: reuse without overengineering.** Combine modern helpers and appropriate abstraction. | Simplify one short collection operation and explain its remaining ownership limits. |
| 15.13 | **Sorting simple values.** Use in-place `slices.Sort`; recognize `sort.Ints` and `sort.Strings` as older-toolchain alternatives. | Sort a copy when the original order must remain unchanged. |
| 15.14 | **Custom ordering with `cmp`.** Use `slices.SortFunc` and `cmp.Compare` for a small record ordering. | Replace a subtraction-based comparator that can overflow and add a stated tie-breaker. |
| 15.15 | **Choosing a search helper.** Distinguish `slices.Contains`, `Index`, and sorted-input `BinarySearch`. | Interpret the insertion position and found flag without reading past the slice. |
| 15.16 | **Collecting deterministic map keys.** Combine `maps.Keys`, `slices.Collect`, and sorting on Go 1.23+. | Turn a frequency map into a sorted key list; recognize a range-and-append fallback. |
| 15.17 | **Compacting duplicates.** Use `slices.Compact` for adjacent duplicates and keep its returned slice. | Explain why unsorted nonadjacent duplicates remain and preserve input order when required. |
| 15.18 | **Checkpoint: collection helpers and their preconditions.** Revisit mutation, ordering, equality, and search requirements. | Select a short helper-based solution that satisfies the input contract, not just one that compiles. |

## Chapter 16: Complexity, searching, sorting, and numeric helpers

**Goal:** Reason about common algorithms and numeric operations without turning lessons into long interview problems.

**Prerequisites:** Chapters 03-04, 06-07, 09, and 15.

Algorithm lessons use tiny inputs, provided scaffolding, and one invariant or operation at a time. Production guidance favors standard-library implementations unless there is a concrete reason not to.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 16.01 | **Growth and Big O.** Recognize complexity as growth with input size, not an exact stopwatch prediction. | Match a short operation-count table to a growth class. |
| 16.02 | **Counting work in loops.** Distinguish constant, linear, and quadratic loop behavior. | Count visits for a tiny example before generalizing its growth. |
| 16.03 | **Space cost.** Recognize extra storage separately from running time. | Choose which implementation allocates space proportional to the input. |
| 16.04 | **Linear search.** Handle a match and absence explicitly. | Complete a short search and choose its empty-input result. |
| 16.05 | **Binary search.** Preserve the sorted-input requirement and shrinking interval. | Fix one bound in a supplied binary-search step. |
| 16.06 | **Review: cost and search invariants.** Revisit growth, storage, and boundaries. | Select a valid search strategy and identify a non-shrinking interval. |
| 16.07 | **Lower and upper bounds.** Use `sort.Search` with a monotonic predicate for the first value greater than or equal to, or strictly greater than, a target. | Fill the predicate and handle the no-match index without indexing past the end. |
| 16.08 | **Insertion sort, one pass.** Trace how one value moves into a sorted prefix. | Order the shifts for a four-element example. |
| 16.09 | **Merge sort, one merge.** Maintain a sorted output while combining two sorted inputs. | Fill one comparison or pointer advance in a supplied merge loop. |
| 16.10 | **Quicksort, one partition.** Understand the partition invariant without implementing the full algorithm. | Identify the element that belongs on the other side of a pivot. |
| 16.11 | **Stable ordering and ties.** Use `slices.SortStableFunc` or older `sort.SliceStable` when equal-key order matters. | Choose stable sorting or an explicit tie-breaker for a stated record-ordering contract. |
| 16.12 | **Checkpoint: select and repair.** Combine input assumptions, complexity, and one local algorithm correction. | Repair a small search/sort fragment and choose a boundary case. |
| 16.13 | **Type-appropriate numeric helpers.** Use built-in `min`/`max` for integer bounds and `math` helpers for genuinely floating-point work. | Remove an unnecessary float conversion without using `math.Pow` for exact integer arithmetic. |
| 16.14 | **Small bit masks.** Use shifts, bit tests, and XOR with an explicit unsigned width. | Set or test one flag in a supplied bounded mask rather than convert the number to a string. |
| 16.15 | **Counting set bits.** Use width-specific helpers such as `bits.OnesCount32` and `bits.OnesCount64`. | Replace a manual population-count loop while preserving the problem's bit width. |
| 16.16 | **Bit positions and zero.** Read `bits.Len64`, `LeadingZeros64`, and `TrailingZeros64`, including their zero-input behavior. | Fix an off-by-one bit-position result and handle a zero value explicitly. |
| 16.17 | **Exact large integers.** Read a small `math/big.Int` operation and its mutable receiver semantics. | Compute one supplied out-of-range result without overflowing `int64` or overwriting an input. |
| 16.18 | **Checkpoint: numeric shortcuts without changed semantics.** Revisit precision, widths, bit operations, and large-value ownership. | Choose the appropriate helper for a small constrained numeric task. |

## Chapter 17: Stacks, queues, trees, graphs, and heaps

**Goal:** Recognize common structures and make small, correct state transitions.

**Prerequisites:** Chapters 03-04, 06-07, 09-10, and 16.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 17.01 | **A stack with a slice.** Use last-in-first-out behavior and guard an empty pop. | Fill the push or pop step in a short snippet. |
| 17.02 | **A queue.** Use first-in-first-out behavior and understand a simple head index. | Predict the next item after a few enqueue/dequeue operations. |
| 17.03 | **Linked nodes.** Read pointer links and preserve access when rewiring a node. | Order two assignments for a small insertion. |
| 17.04 | **Tree structure.** Recognize root, child, leaf, and an absent child. | Trace a path through a supplied three-node tree. |
| 17.05 | **Recursion and a base case.** Follow a small recursive call and identify its stopping condition. | Fix a recursive function that fails on the empty case. |
| 17.06 | **Review: state and stopping.** Revisit stack/queue order, pointers, and recursive termination. | Trace one small structure and repair one missing guard. |
| 17.07 | **Depth-first traversal.** Use the recursive call stack to visit a tree. | Predict one stated traversal order for a tiny tree. |
| 17.08 | **Breadth-first traversal.** Use a queue to visit nodes by distance from the root. | Fill the queue update and choose the next visited node. |
| 17.09 | **Graph representation.** Read an adjacency list using slices and maps. | Add one directed edge to a supplied graph representation. |
| 17.10 | **Visited sets and cycles.** Avoid revisiting nodes indefinitely. | Place a visited check in the correct part of a traversal. |
| 17.11 | **A priority queue.** Read a provided `container/heap` implementation and use its public operations. | Choose the next minimum item; do not write the entire heap boilerplate. |
| 17.12 | **Checkpoint: choose the structure.** Match required behavior to a stack, queue, map, tree, or heap. | Repair one structure transition using a tiny supplied fixture. |
| 17.13 | **Initializing and ordering a heap.** Use `heap.Init` and a supplied `Less` method to establish a min-heap or max-heap. | Fix a comparator or missing initialization; do not assume the backing slice is fully sorted. |
| 17.14 | **Top-k with a bounded heap.** Use package-level `heap.Push` and `heap.Pop` to retain the required k values. | Fill one keep/remove decision in supplied scaffolding instead of sorting the entire input repeatedly. |
| 17.15 | **Changing a priority.** Use `heap.Fix` with a current element index and maintain index bookkeeping when swapping. | Repair one priority update without rebuilding the whole heap. |
| 17.16 | **A standard doubly linked list.** Read `container/list` element handles, insertion, movement, and removal. | Move an existing element with `MoveToFront` instead of searching for and recreating it. |
| 17.17 | **One LRU-cache operation.** Combine a map of element handles with `container/list` for recency tracking. | Complete a single cache-hit or eviction step; the rest of the cache is supplied. |
| 17.18 | **Checkpoint: heap, list, or simple slice?** Choose the structure that fits the required operation. | Repair one top-k or recency operation without introducing an unnecessary linked list for an ordinary FIFO queue. |

`container/heap` still requires a type implementing its interface. The package-level `heap.Pop` restores heap ordering before invoking that type's `Pop` method; calling the method directly is not an interchangeable shortcut. A slice with a head index remains a useful simple queue when linked-element operations are unnecessary.

## Chapter 18: Small steps through advanced algorithms

**Goal:** Build pattern recognition for more involved problems through bounded local tasks.

**Prerequisites:** Chapters 08 and 16-17.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 18.01 | **Two pointers.** Move two indices according to a stated invariant. | Fill one pointer movement in a short sorted-pair search. |
| 18.02 | **Sliding windows.** Update a fixed-size window without recomputing its entire sum. | Add the entering value and remove the leaving value correctly. |
| 18.03 | **Prefix sums.** Answer a range-total query from accumulated values. | Fix the two indices used for an exclusive-upper-bound range. |
| 18.04 | **Memoization.** Cache repeated subproblem results while preserving a base case. | Fill the cache lookup or store in a small recursive example. |
| 18.05 | **Bottom-up dynamic programming.** Compute states in dependency order. | Complete two cells of a tiny ways-to-climb table. |
| 18.06 | **Review: preserve the invariant.** Revisit pointer movement, window updates, and subproblem dependencies. | Repair one local update and explain what it maintains. |
| 18.07 | **Backtracking.** Apply choose, explore, and undo on a very small search space. | Restore one piece of state before exploring the next branch. |
| 18.08 | **Topological ordering.** Use indegrees and a queue to order a tiny dependency graph. | Choose the next available node and recognize when a cycle blocks completion. |
| 18.09 | **Dijkstra's relaxation step.** Improve a tentative distance using nonnegative edge weights. | Fill one distance comparison/update in supplied heap-based scaffolding. |
| 18.10 | **Greedy choices versus global results.** Recognize that a locally attractive choice needs justification. | Find a counterexample to a supplied coin-choice rule. |
| 18.11 | **Algorithm edge cases in Go.** Apply empty-input, overflow, and representation awareness to one algorithm. | Repair one supplied edge case rather than solve a new large problem. |
| 18.12 | **Checkpoint: name the pattern, fix the step.** Select an appropriate pattern and make one local correction. | Complete a short algorithm fragment using a tiny input trace. |

This is an introduction to advanced patterns, not a claim to cover algorithm proofs, every data structure, or competitive programming in full.

## Chapter 19: Goroutines, channels, and select

**Goal:** Reason about communication, blocking, and unspecified execution order.

**Prerequisites:** Chapters 03-04, 06-07, and 10-11.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 19.01 | **Concurrency versus parallelism.** Distinguish overlapping tasks from simultaneous execution. | Match a small execution timeline to the correct description. |
| 19.02 | **Starting a goroutine.** Recognize that launching work does not wait for it. | Fix an assumption that `main` waits for launched goroutines automatically. |
| 19.03 | **Creating a channel.** Read channel types and `make`; recognize that sends and receives on a nil channel block. | Fill a channel creation before a supplied communication step. |
| 19.04 | **Unbuffered rendezvous.** Understand a send/receive pair coordinating progress. | Identify which goroutine is blocked in a supplied state. |
| 19.05 | **Buffered channels.** Reason about available capacity and backpressure. | Predict which send blocks after a short sequence. |
| 19.06 | **Review: what can proceed?** Revisit launch, initialization, and channel blocking. | Choose the possible next execution steps, not an invented fixed print order. |
| 19.07 | **Directional channel types.** Restrict an API to sending or receiving. | Choose the narrow channel parameter for a consumer. |
| 19.08 | **Who closes a channel.** Give closing ownership to the party that knows no more sends will occur. | Repair a close-from-the-wrong-side bug. |
| 19.09 | **Receiving after close.** Read draining, comma-ok, and `range` termination behavior. | Distinguish a real zero value from the end of a closed channel. |
| 19.10 | **Selecting ready operations.** Use `select` without assuming priority among ready cases. | Identify all allowed outcomes of a small ready-case example. |
| 19.11 | **Nonblocking selection.** Distinguish a deliberate `default` from an accidental polling loop. | Fix one supplied loop that consumes CPU while waiting. |
| 19.12 | **Checkpoint: communication without a deadlock.** Combine blocking, closure, and termination reasoning. | Repair one small producer/consumer snippet using supplied scaffolding. |

Recall cards connect nil channels to disabled `select` cases. They also distinguish modern per-iteration variables declared with `:=` from assignment to an existing shared variable. Do not reuse pre-Go-1.22 loop-capture questions with their old answers.

## Chapter 20: Shared state and synchronization

**Goal:** Protect shared state and coordinate completion without guessing about timing.

**Prerequisites:** Chapters 09-11 and 19.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 20.01 | **A data race.** Recognize unsynchronized conflicting accesses and distinguish them from broader logical race conditions. | Identify the two accesses that race in a short example. |
| 20.02 | **The race detector.** Read a supplied `go test -race` report and understand its execution-based limits. | Match reported goroutine accesses to the responsible state. |
| 20.03 | **Protecting an invariant with a mutex.** Put all relevant accesses under the same synchronization rule. | Repair a partially locked update. |
| 20.04 | **Read/write locking.** Distinguish a read lock from permission to mutate. | Fix a write performed while holding only an `RLock`. |
| 20.05 | **Waiting for tasks with `WaitGroup.Go`.** Use the Go 1.25+ completion helper and `Wait`. | Fill the wait in a small launch-and-collect example. |
| 20.06 | **Review: protection and completion differ.** Revisit races, locking, and waiting. | Reject a WaitGroup-only "fix" for shared-state mutation. |
| 20.07 | **Reading older WaitGroup code.** Apply `Add` before launch and exactly one matching `Done`. | Fix a legacy completion-counting bug. |
| 20.08 | **Typed atomic operations.** Use a typed atomic counter for one appropriate independent value. | Choose an atomic update without claiming it protects a multi-field invariant. |
| 20.09 | **One-time initialization.** Read `sync.Once` and its one-time execution guarantee. | Predict how many times a supplied initializer runs. |
| 20.10 | **Do not copy used synchronization values.** Recognize why copying a struct containing a used lock is unsafe. | Change a receiver or parameter that copies a mutex-bearing value. |
| 20.11 | **Choosing a coordination primitive.** Match ownership, messaging, counters, and completion to appropriate tools. | Choose the simplest primitive for a small stated invariant. |
| 20.12 | **Checkpoint: a bounded race repair.** Combine state ownership and completion reasoning. | Fix one shared-state defect without serializing unrelated work unnecessarily. |

Actual race-detector execution depends on supported platform/toolchain requirements, including a C compiler on some setups. Supplied reports keep the browser lesson self-contained.

## Chapter 21: Context, cancellation, and bounded work

**Goal:** Make concurrent work stop, finish, and remain bounded deliberately.

**Prerequisites:** Chapters 11-12, 14, and 19-20.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 21.01 | **A cancellable context.** Recognize a work lifetime and the owner of its cancel function. | Fill a `WithCancel` creation and matching cleanup. |
| 21.02 | **Cooperative cancellation.** Understand that cancellation signals work to stop; it does not kill a goroutine. | Add a `ctx.Done()` case to a supplied waiting loop. |
| 21.03 | **Timeouts and deadlines.** Give work a time budget and release associated resources. | Fix a missing cancel call in a timeout-scoped operation. |
| 21.04 | **Propagating a caller's context.** Preserve cancellation across function boundaries. | Replace an inappropriate new background context inside request-scoped work. |
| 21.05 | **Timer and ticker lifetimes.** Choose the appropriate time source and stop a ticker when its work ends. | Repair one periodic-work cleanup path. |
| 21.06 | **Review: who stops the work?** Revisit ownership, deadlines, propagation, and timing. | Trace cancellation through a short call chain. |
| 21.07 | **Related tasks with `errgroup`.** Read first-error propagation and shared cancellation. | Fill a task's error return in supplied `errgroup.WithContext` scaffolding. |
| 21.08 | **Limiting concurrency.** Use a bound such as `errgroup.SetLimit` rather than launching unlimited work. | Choose a change that limits active tasks without dropping work. |
| 21.09 | **A small worker pool.** Read a fixed set of workers receiving jobs from a channel. | Fill one worker's job/cancellation selection; the pool setup is supplied. |
| 21.10 | **Stopping a pipeline.** Make a send cancellable when a downstream consumer may leave. | Repair one blocked-send goroutine leak. |
| 21.11 | **Shutdown as an ordered sequence.** Stop accepting work, signal cancellation as appropriate, and wait for owned tasks. | Order the steps for a supplied worker service with a stated drain policy. |
| 21.12 | **Checkpoint: finite work with a lifetime.** Combine bounded launch, cancellation, and waiting. | Repair one short orchestration fragment rather than build a full worker system. |

`errgroup` comes from the separately versioned `golang.org/x/sync` module, not the standard library. Its examples should identify that dependency and supply the setup rather than hide it inside a lesson.

## Chapter 22: HTTP clients and reliable requests

**Goal:** Read and repair ordinary Go HTTP client code.

**Prerequisites:** Chapters 11, 13-14, and 21.

Networking vocabulary is introduced as needed. Activities use supplied responses or local fixtures, not a required external API account.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 22.01 | **The request/response model.** Identify URL, method, headers, status, and body; recognize HTTPS as the secure transport default. | Label a short request and response pair. |
| 22.02 | **Building URLs safely.** Use `net/url` and encoded query parameters. | Fix a query string broken by a value containing reserved characters. |
| 22.03 | **A request with a context.** Read `http.NewRequestWithContext` and an explicit client. | Fill the caller's context in a supplied request creation. |
| 22.04 | **Transport errors versus HTTP status.** Understand that a non-success HTTP status is not automatically a `Do` error. | Repair a client that treats every received response as success. |
| 22.05 | **Response-body ownership.** Close bodies and bound reads when input size is not trusted. | Fix one missing cleanup or unlimited-read operation. |
| 22.06 | **Review: a response is not automatically success.** Revisit construction, status, errors, and cleanup. | Trace a supplied 404 response and its handling path. |
| 22.07 | **Sending JSON.** Supply an encoded body and the intended content type. | Complete a small JSON request without ignoring encoding failure. |
| 22.08 | **Client and transport reuse.** Recognize why a long-lived client is normally preferable to repeated new transports. | Choose which object belongs outside a per-request loop. |
| 22.09 | **Timeout layers.** Distinguish a whole-operation budget from an individual transport-phase timeout. | Choose the setting relevant to a supplied stall scenario. |
| 22.10 | **Bounded retries.** Read limited attempts, backoff, and cancellation-aware waiting. | Repair a supplied retry loop that never stops or ignores cancellation. |
| 22.11 | **Safe retry decisions.** Distinguish retryable operations from requests that may duplicate side effects. | Choose a retry policy for a read versus a payment-like mutation. |
| 22.12 | **Checkpoint: repair a reliable request.** Combine a status check, body lifetime, and a time budget. | Fix one client defect in a short, otherwise complete snippet. |

## Chapter 23: HTTP handlers, routing, and middleware

**Goal:** Understand an endpoint one small behavior at a time.

**Prerequisites:** Chapters 10-11, 14, 20-22.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 23.01 | **A handler's contract.** Read `http.ResponseWriter`, `*http.Request`, and a handler function. | Fill a small response in supplied handler scaffolding. |
| 23.02 | **Modern standard-library routing.** Use `ServeMux` method/path patterns and path values. | Choose the route that matches a supplied method and path. |
| 23.03 | **Parsing request values.** Convert a path or query value and reject an invalid input. | Add a missing parse-error response. |
| 23.04 | **Response ordering.** Set headers and status before writing a response body. | Fix a status change attempted after writing begins. |
| 23.05 | **A JSON response.** Encode a small response value with the intended content type. | Fill one field or encoding call in a small handler. |
| 23.06 | **Review: route, parse, respond.** Revisit matching, bad inputs, and response ordering. | Repair one short endpoint behavior. |
| 23.07 | **Middleware as a wrapper.** Read a function that wraps an `http.Handler` and invokes the next handler. | Fix middleware that forgets to call or incorrectly calls the next handler. |
| 23.08 | **Request-scoped cancellation.** Pass the request context to work done for the request. | Replace an inappropriate background context in a handler. |
| 23.09 | **Testing a handler.** Use `httptest.NewRequest` and `ResponseRecorder` without a deployed server. | Complete an assertion for a supplied handler response. |
| 23.10 | **Server-side time bounds.** Recognize the role and limits of settings such as `ReadHeaderTimeout`. | Choose the relevant server setting without assuming it caps all handler work. |
| 23.11 | **Graceful HTTP shutdown.** Read `Server.Shutdown` with a deadline and wait for the shutdown operation. | Fix a `main` path that exits before graceful shutdown completes. |
| 23.12 | **Checkpoint: one endpoint correction.** Combine routing, validation, response, and lifetime rules. | Repair one defect in a supplied handler or shutdown fragment. |

## Chapter 24: SQL database access and transactions

**Goal:** Use Go database APIs correctly without requiring a full database course first.

**Prerequisites:** Chapters 09-12, 15, and 21.

Minimal SQL concepts are introduced with supplied tables and queries. PostgreSQL-style placeholders are used consistently in examples, with a note that placeholder syntax depends on the driver. Database installation is not part of a five-minute lesson.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 24.01 | **Rows, columns, and a query.** Read a small table and a simple `SELECT ... WHERE ...` statement. | Predict the rows selected from a supplied three-row fixture. |
| 24.02 | **A database handle is a pool.** Distinguish `database/sql`, a driver, opening a handle, and testing connectivity. | Reject the assumption that `sql.Open` alone proves a connection works. |
| 24.03 | **Parameterized writes.** Pass values separately to a supplied `ExecContext` statement. | Fix unsafe value concatenation without inventing driver-independent placeholder syntax. |
| 24.04 | **One-row queries.** Read `QueryRowContext`, `Scan`, and `sql.ErrNoRows`. | Handle absence separately from other query failures. |
| 24.05 | **Multiple-row queries.** Scan projected columns, close rows, and inspect `Rows.Err`. | Repair a loop that silently loses an iteration error. |
| 24.06 | **Review: execute, scan, and finish.** Revisit handles, parameters, absence, and result lifetime. | Match a query outcome to the correct error-handling branch. |
| 24.07 | **Nullable columns.** Preserve the difference between SQL NULL and a real zero value, using a type such as `sql.Null[T]`. | Choose a destination that retains a missing-value distinction. |
| 24.08 | **Transaction lifetime.** Read `BeginTx`, transaction-scoped operations, commit, and rollback. | Fix an operation accidentally performed through the pool instead of the transaction. |
| 24.09 | **Concurrent updates.** Recognize a lost-update pattern and the role of atomic SQL updates or appropriate isolation. | Replace a read-modify-write sequence with a supplied atomic update. |
| 24.10 | **Pool limits and waiting.** Understand connection limits, returned resources, and context-bounded waits. | Diagnose a tiny supplied example that exhausts its pool through unclosed results. |
| 24.11 | **Schema changes.** Read a small migration and recognize compatibility with old and new application versions. | Choose a safe ordering for adding and using a new column. |
| 24.12 | **Checkpoint: one data-access repair.** Combine parameters, context, errors, and ownership. | Fix a short database operation using supplied SQL and fixtures. |

## Chapter 25: Safer API boundaries and input handling

**Goal:** Recognize what an application must not trust and make small defensive corrections.

**Prerequisites:** Chapters 08, 11, 13-14, and 22-24.

These are defensive development lessons, not a substitute for a full security review or specialist authentication design.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 25.01 | **Bounded, deliberate request decoding.** Limit body size and recognize unknown or trailing input according to a stated API contract. | Add one missing boundary check to supplied JSON-decoding scaffolding. |
| 25.02 | **Validation and public errors.** Separate malformed input, invalid domain values, and internal failures. | Choose an appropriate public response without exposing internal details. |
| 25.03 | **Authentication versus authorization.** Distinguish knowing an identity from allowing access to a particular object. | Add a missing ownership check in a tiny supplied handler. |
| 25.04 | **Trusted credential verification.** Recognize why decoding a token is not verifying it and why maintained verification libraries matter. | Reject an unverified-claims path; do not implement an authentication system. |
| 25.05 | **Randomness for secrets.** Distinguish cryptographic randomness from simulation/testing randomness. | Choose `crypto/rand` rather than `math/rand/v2` for a security-sensitive token. |
| 25.06 | **Review: locate the trust boundary.** Revisit input limits, identity, authorization, and secret generation. | Identify the one missing check in a supplied request flow. |
| 25.07 | **Filesystem containment.** Recognize why `filepath.Join` is not a sandbox and read a constrained `os.Root` access pattern. | Choose the operation that keeps file access within the intended root. |
| 25.08 | **Untrusted outbound destinations.** Recognize SSRF risks, including redirects, and the need for a deliberate destination policy. | Reject a redirect that violates a supplied allowlist policy. |
| 25.09 | **Browser boundaries.** Distinguish CORS from authorization and recognize cookie-based CSRF concerns. | Choose which protection actually addresses a described browser request. |
| 25.10 | **Sensitive data in diagnostics.** Redact credentials and avoid recording full untrusted inputs unnecessarily. | Remove a secret-bearing log attribute while preserving useful operation context. |
| 25.11 | **Limits serve different purposes.** Distinguish request rate limits, concurrency bounds, and operation deadlines. | Select the relevant control for a supplied overload scenario. |
| 25.12 | **Checkpoint: one defensive patch.** Combine validation, access control, and safe diagnostics. | Repair one small boundary failure and select a focused regression case. |

## Chapter 26: Stronger tests, fuzzing, and reliable fixtures

**Goal:** Exercise behavior systematically without turning every test into an infrastructure project.

**Prerequisites:** Chapters 05, 09-11, and 19-24.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 26.01 | **Table-driven tests.** Represent related input/output cases with a slice of small records. | Add one boundary case to a supplied table. |
| 26.02 | **Named subtests.** Use `t.Run` to make cases individually identifiable. | Fill the name and assertion inside a short subtest loop. |
| 26.03 | **Fixture ownership.** Use temporary directories and cleanup helpers to keep tests independent. | Replace a shared fixed path with a test-owned temporary location. |
| 26.04 | **Small test doubles.** Substitute a narrow dependency through an interface rather than mocking an entire implementation. | Fill a tiny fake's one required method. |
| 26.05 | **An HTTP client fixture.** Read `httptest.Server` to exercise actual client behavior locally. | Complete a status/body fixture for a supplied client test. |
| 26.06 | **Review: clear cases, isolated state.** Revisit tables, subtests, cleanup, and dependency seams. | Repair one brittle test setup. |
| 26.07 | **Test boundaries and coverage.** Distinguish unit and integration evidence; recognize that executed lines do not prove correct assertions. | Choose the smallest test boundary that can expose a described defect. |
| 26.08 | **A fuzz target.** Seed inputs and express a useful invariant for Go's fuzzing engine. | Complete one invariant in a supplied fuzz-test scaffold. |
| 26.09 | **Properties and transformations.** Test a relation such as a round trip or idempotent normalization. | Choose a valid property and identify its domain assumptions. |
| 26.10 | **Deterministic concurrent tests.** Read a small Go 1.25+ `testing/synctest` fixture instead of relying on arbitrary sleeps. | Replace one timing guess in supplied compatible scaffolding. |
| 26.11 | **Parallel-test isolation.** Recognize shared environment/global-state hazards and restrictions around `t.Parallel`. | Fix a test that mutates process-wide state while running in parallel. |
| 26.12 | **Checkpoint: a focused regression test.** Combine a clear failure case with a suitable test boundary. | Add one small case or assertion for a previously repaired defect. |

## Chapter 27: Benchmarks, profiling, and runtime costs

**Goal:** Make performance changes based on a measured cause, not a language myth.

**Prerequisites:** Chapters 06, 09, 16, 19-21, and 26.

Profile and benchmark activities use supplied reports. The browser must not present simulated output as a measurement made on the learner's machine.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 27.01 | **A benchmark's job.** Read a Go 1.24+ `B.Loop` scaffold and recognize older `b.N` loops when encountered. | Fill the operation being measured in a small benchmark. |
| 27.02 | **Measuring the right work.** Keep unrelated setup out of the measurement and preserve meaningful results. | Repair one misleading benchmark arrangement. |
| 27.03 | **Allocation results.** Read `ns/op`, `B/op`, and `allocs/op` without confusing their units. | Choose what improved and what did not from a tiny report. |
| 27.04 | **CPU profiles.** Distinguish frequently sampled work from a guess based on source appearance. | Identify the relevant hot path in a supplied profile excerpt. |
| 27.05 | **Heap profiles.** Distinguish total allocation activity from memory still retained. | Select the profile view relevant to a stated memory question. |
| 27.06 | **Review: evidence before edits.** Revisit benchmark boundaries, units, and profile purpose. | Reject an optimization claim unsupported by its report. |
| 27.07 | **Reachability and retention.** Understand why a small slice can keep a much larger backing allocation alive. | Repair a small retention problem with an appropriate copy. |
| 27.08 | **Escape analysis.** Read a supplied compiler diagnostic without assuming every pointer lives on the heap. | Identify which conclusion the diagnostic actually supports. |
| 27.09 | **A measured small optimization.** Apply appropriate preallocation or text building to one demonstrated hotspot. | Choose a change that reduces a shown allocation without changing behavior. |
| 27.10 | **Blocked and leaked goroutines.** Read a small goroutine/leak-profile excerpt and recognize detection limits. | Find the missing completion or cancellation path in supplied code. |
| 27.11 | **Profile-guided optimization.** Understand the role of a representative workload profile in a PGO build. | Choose a representative profile instead of a misleading one-off benchmark. |
| 27.12 | **Checkpoint: make the evidence-based change.** Combine correctness, costs, and a local improvement. | Select one justified patch from a supplied before/after scenario. |

## Chapter 28: Reading production libraries and protocols

**Goal:** Understand what representative ecosystem tools do and how to read their usage.

**Prerequisites:** Chapters 12, 15, 21-24, and 26.

Library lessons use pinned-version snippets and supplied generated code or fixtures. Installing every named tool is not required. The aim is transferable library-reading skill, not memorizing a catalogue of APIs.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 28.01 | **Choosing a dependency deliberately.** Compare standard-library capability, maintenance, compatibility, license, and added complexity. | Decide whether a small requirement needs another dependency at all. |
| 28.02 | **Cobra and command structure.** Read a supplied command definition, flag, and error-returning action. | Fill one `RunE` behavior; do not scaffold a CLI tree. |
| 28.03 | **Chi and routing composition.** Recognize what a router library adds beyond `net/http` and `ServeMux`. | Follow middleware and route selection in a tiny supplied example. |
| 28.04 | **pgx and database integration choices.** Distinguish pgx's native pool from its `database/sql` integration. | Choose one coherent pooling/API path rather than stacking incompatible abstractions. |
| 28.05 | **sqlc and generated queries.** Relate named SQL to a generated typed Go operation. | Call a supplied generated method with the correct parameter shape. |
| 28.06 | **Review: know the library's role.** Revisit dependency choice, routing, commands, and data-access layers. | Match a task to an appropriate existing layer rather than add another library. |
| 28.07 | **Protocol Buffers.** Read a tiny schema and preserve field-number compatibility. | Choose a safe schema change without reusing a removed field number. |
| 28.08 | **gRPC calls.** Read a generated unary client call with context and an appropriate status check. | Complete one call/error-handling step using supplied generated types. |
| 28.09 | **OpenTelemetry tracing.** Read a parent/child span relationship and propagate the returned context. | Repair a trace-context break in a small operation. |
| 28.10 | **JSON v1 to v2 in Go 1.27.** Recognize stricter defaults and use the migration guide instead of assuming a drop-in import rename. | Identify a behavior change using a supplied duplicate-name or invalid-UTF-8 fixture. |
| 28.11 | **Reflection literacy.** Read a small `reflect` example and recognize when ordinary types, interfaces, or generics are clearer. | Replace unnecessary runtime inspection with a supplied simpler alternative. |
| 28.12 | **Checkpoint: read an unfamiliar API.** Use a short documentation excerpt and a pinned snippet to make one correct call. | Complete a small library interaction without memorizing its whole API surface. |

## Chapter 29: Building, shipping, and maintaining Go software

**Goal:** Understand the mechanics around a Go program without requiring a deployment project.

**Prerequisites:** Chapters 12-14 and 22-28.

Git, CI, container, and build activities use small files or supplied output. Running a public service, installing Docker, or paying for infrastructure is not required.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 29.01 | **A focused source change.** Read a Git diff and distinguish intended edits from unrelated churn. | Choose the smallest coherent change set for a stated fix. |
| 29.02 | **Building for a target.** Read `GOOS`/`GOARCH` settings and recognize cgo-related cross-compilation constraints. | Match an output binary to its target operating system and architecture. |
| 29.03 | **Embedding assets.** Use `go:embed` to include a small file behind a supplied declaration. | Fix an asset path or missing embed import in a short example. |
| 29.04 | **Platform-specific source.** Recognize filename suffixes and `go:build` constraints. | Choose which implementation participates in a given target build. |
| 29.05 | **A container's runtime needs.** Read a minimal build/runtime image separation without assuming every Go binary is dependency-free. | Identify a missing runtime requirement or inappropriate root-user default. |
| 29.06 | **Review: source to runnable artifact.** Revisit targets, embedded data, selected files, and runtime assumptions. | Diagnose one mismatch using a supplied build scenario. |
| 29.07 | **Continuous integration.** Place formatting, analysis, tests, and builds into a clear automated sequence. | Fill one command in a small supplied pipeline fragment. |
| 29.08 | **Dependency vulnerability awareness.** Read `govulncheck` output and its limits. | Identify the dependency/call path requiring attention without treating a clean report as a security guarantee. |
| 29.09 | **Readiness versus liveness.** Distinguish accepting work from needing a process restart. | Choose the appropriate health signal for a supplied dependency failure. |
| 29.10 | **Updating Go deliberately.** Read release notes, review `go fix` changes, and preserve compatibility expectations. | Evaluate a small version/modernization diff against a stated module baseline. |
| 29.11 | **Useful operational metrics.** Recognize latency, errors, and saturation; avoid unbounded label cardinality. | Replace a per-user metric label with a bounded dimension. |
| 29.12 | **Checkpoint: one release-readiness decision.** Combine a source change, automation, and an operational constraint. | Fix one missing step in a supplied small release scenario. |

## Chapter 30: Everyday Go fluency in small tasks

**Goal:** Retrieve and combine skills without a large final project.

**Prerequisites:** Chapters 01-29, or equivalent diagnostic coverage.

Each lesson starts from a fresh, small fixture. There is no accumulating codebase to keep in sync. These are practice lessons, not ten new unrelated frameworks.

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 30.01 | **A misleading nil error.** Apply interface-value reasoning to a real-looking failure path. | Repair a typed-nil return in a small function. |
| 30.02 | **An unexpectedly shared list.** Apply slice and struct ownership rules to an independent-copy requirement. | Fix a short helper that changes its caller's data accidentally. |
| 30.03 | **An endpoint's bad-input path.** Apply parsing, validation, response ordering, and focused assertions. | Repair one small request-handling branch. |
| 30.04 | **A cancelled database request.** Keep context, transaction scope, and returned errors connected. | Fix one discarded-context or wrong-handle line in supplied data-access code. |
| 30.05 | **A goroutine that never finishes.** Apply cancellation and send/receive ownership rules. | Repair a blocked send after its consumer leaves. |
| 30.06 | **Review: find the responsible concept.** Retrieve the right mental model before choosing a patch. | Match several tiny symptoms to interfaces, ownership, cancellation, or validation. |
| 30.07 | **An unfamiliar package.** Find a relevant API contract from a bundled documentation excerpt. | Complete one new call and explain its cleanup or error responsibility. |
| 30.08 | **A dependency update.** Combine version paths, release notes, and behavior expectations. | Choose the necessary small code change from a supplied upgrade scenario. |
| 30.09 | **A Unicode input bug.** Apply byte/rune distinctions to a previously ASCII-only function. | Repair one text operation and choose a non-ASCII regression input. |
| 30.10 | **A slow local algorithm step.** Apply complexity and measurement evidence without changing the contract. | Replace one repeated operation using a supplied appropriate helper or structure. |
| 30.11 | **A maintainable small change.** Keep a behavior correction, an error path, and a focused regression case aligned. | Complete a short patch from a precise requirement, not a broad feature request. |
| 30.12 | **Core-course micro-checkpoint.** Demonstrate mixed retrieval with a small, bounded set rather than a marathon exam. | Answer a prediction, fix one short defect, and explain one development decision. |

## Chapter 31: Kubernetes concepts and practical Go controllers

**Goal:** Understand the Kubernetes object model and read, complete, and repair real Go controller patterns, particularly watches and filters.

**Prerequisites:** Chapters 09-12, 15, 19-26, and 28-29. No prior Kubernetes knowledge is assumed.

This longer chapter contains **36 micro-lessons**, not a six-hour operator-building assignment. Each activity supplies its own small objects, event trace, or Go scaffold. A recurring `Widget` custom resource, owned Deployment, and referenced ConfigMap provide familiar names without requiring an accumulating project.

The main implementation vocabulary is `client-go`, `controller-runtime`, and Kubebuilder. Their roles are distinguished rather than treated as interchangeable libraries. Code-authoring must pin a compatible set of `controller-runtime`, `k8s.io/api`, `k8s.io/apimachinery`, and `k8s.io/client-go` versions.

### Block 1: Kubernetes objects and desired state

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 31.01 | **Pods, Deployments, and Services.** Recognize the workload, replica-management, and network-access roles in one small application. | Match supplied `corev1` and `appsv1` objects to their responsibilities. |
| 31.02 | **Object identity and scope.** Read kind, API group/version, namespace, name, and UID; distinguish a namespaced key from an incarnation's identity. | Construct the right `types.NamespacedName` and distinguish a recreated object with a new UID. |
| 31.03 | **Labels, selectors, and annotations.** Distinguish selecting objects from attaching non-selection metadata. | Complete a `client.MatchingLabels` query for a supplied namespace and label set. |
| 31.04 | **Desired spec and observed status.** Read the fields a user requests versus those a controller reports. | Put a requested replica count and observed readiness into the correct Go fields. |
| 31.05 | **A CRD and its custom resources.** Distinguish a resource-type definition from instances and relate a small schema to a Go API type. | Match one validated CRD field to the corresponding supplied `WidgetSpec` field. |
| 31.06 | **Review: read a Kubernetes object.** Revisit roles, identity, labels, desired state, and custom types. | Interpret a tiny object fixture and choose the correct lookup or field. |

### Block 2: Talking to the API from Go

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 31.07 | **Go client layers and configuration.** Distinguish `client-go` clients, `controller-runtime` abstractions, and Kubebuilder scaffolding. | Choose the appropriate layer and identify supplied kubeconfig versus in-cluster configuration, without accessing a cluster. |
| 31.08 | **Registering types in a scheme.** Connect Go types to their Kubernetes group/version/kind using `AddToScheme`. | Add the missing custom-resource registration to a supplied manager/client setup. |
| 31.09 | **Reading objects and handling absence.** Use `client.Get` or `List` with context, keys, and an explicit not-found decision. | Handle a deleted primary object normally without suppressing permission or transport errors. |
| 31.10 | **Changing only the intended fields.** Read `Create`, `Update`, and a small `Patch` using a pre-change `DeepCopy` baseline. | Repair a `client.MergeFrom` patch whose baseline was captured after mutation. |
| 31.11 | **Permissions for the actual operation.** Read namespace-scoped RBAC verbs and subresources. | Add the missing `list`/`watch` or status-update permission instead of granting wildcard access. |
| 31.12 | **Review: client, type, key, permission.** Revisit the prerequisites for a successful API operation. | Diagnose one supplied scheme, namespace, error-handling, or RBAC mismatch. |

### Block 3: Reconciliation and watch routing

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 31.13 | **Manager and controller setup.** Read `SetupWithManager`, controller registration, and context-driven manager lifetime. | Complete one `ctrl.NewControllerManagedBy(mgr)` registration rather than scaffold an operator. |
| 31.14 | **Level-driven, idempotent reconciliation.** Treat a request as a key to current state, not a command to replay a particular event. | Repair a reconcile that creates a duplicate child on every call. |
| 31.15 | **Completion, errors, and future work.** Distinguish successful completion, retryable errors, and `RequeueAfter`. | Choose a return path without sleeping inside `Reconcile` or assuming result fields apply when an error is returned. |
| 31.16 | **Primary and owned-resource watches.** Connect `For`, `Owns`, and a controller owner reference to the primary reconcile key. | Add an owned Deployment watch or a missing `controllerutil.SetControllerReference` call. |
| 31.17 | **Watching a resource you do not own.** Use `Watches` and `handler.EnqueueRequestsFromMapFunc` to map a referenced ConfigMap to affected Widgets. | Return the correct namespaced reconcile requests, rather than enqueue the ConfigMap as though it were a Widget. |
| 31.18 | **Review: what gets reconciled?** Revisit manager setup, repeated execution, return values, and event-to-key mapping. | Trace a primary, owned-child, and external-dependency event to their intended requests. |

### Block 4: Watch streams, caches, and filters

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 31.19 | **List/watch and informers.** Read how an initial list and subsequent watch updates populate an informer cache; recognize relisting after a watch gap. | Interpret a supplied reconnect trace without treating watch events as an exactly-once audit log. |
| 31.20 | **The manager's cached client.** Distinguish normally cached reads, direct API writes, and an explicit API reader. | Repair an assumption that a cached `Get` immediately reflects a just-completed write. |
| 31.21 | **Event predicates.** Read create, update, delete, and generic callbacks in `predicate.Funcs` or the pinned typed equivalent. | Fill one old/new field comparison while preserving the other required event types. |
| 31.22 | **Generation, labels, and annotations.** Compose `GenerationChangedPredicate`, `LabelChangedPredicate`, or `AnnotationChangedPredicate` for a stated trigger policy. | Fix an AND/OR mistake and identify an update that generation-only filtering intentionally drops. |
| 31.23 | **Filters belong to the right watch.** Distinguish per-watch `builder.WithPredicates` from builder-wide `WithEventFilter`. | Stop a primary-resource filter from suppressing an owned Deployment's readiness-status updates. |
| 31.24 | **Review: keep necessary triggers.** Revisit watch continuity, cached reads, predicate decisions, and filter scope. | Explain why one relevant update failed to enqueue the expected primary key. |

### Block 5: Status, deletion, conflicts, and scale

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 31.25 | **Status conditions and observed generation.** Use `Status().Patch` and a condition helper to report the spec version actually processed. | Avoid an unnecessary status-write loop or a Ready condition that describes an older spec. |
| 31.26 | **Finalizers and deletion.** Read deletion timestamps and repeatable cleanup before removing a finalizer. | Fix a generation-only update filter that prevents deletion cleanup from ever starting. |
| 31.27 | **Optimistic concurrency and field ownership.** Treat `resourceVersion` as opaque and re-read before retrying an optimistic conflict. | Repair a stale-write retry without overwriting unrelated fields or blindly retrying every error. |
| 31.28 | **Field indexes for dependency lookups.** Register `IndexField` and use `MatchingFields` on the cache for a referenced ConfigMap name. | Replace a scan of every Widget with a scoped indexed lookup, without assuming the index creates a server-side selectable field. |
| 31.29 | **Workqueues and bounded controller work.** Recognize key deduplication, retry backoff, and `MaxConcurrentReconciles`. | Trace coalesced updates or repair an unsafe shared variable used by different concurrent reconcile keys. |
| 31.30 | **Review: preserve lifecycle and progress.** Revisit status, finalizers, conflicts, indexed mapping, and queued work. | Repair one small controller fragment that stalls or writes repeatedly. |

### Block 6: Controller fixtures and debugging

| Lesson | Focus and outcome | Representative activity |
|---|---|---|
| 31.31 | **Fake-client reconcile tests.** Use `fake.NewClientBuilder`, the correct scheme, and explicit status-subresource configuration for a logic-level fixture. | Complete an idempotence assertion while recognizing behavior the fake client does not emulate. |
| 31.32 | **Predicate and mapper test tables.** Exercise old/new objects and expected request keys without a running API server. | Add a case for a label change, status-only update, or deletion timestamp that catches an over-restrictive filter. |
| 31.33 | **When to use `envtest`.** Distinguish real API-server/etcd behavior from a fake client and from a complete cluster. | Choose the appropriate fixture for CRD validation or status-subresource behavior without expecting Pods to run. |
| 31.34 | **Exercising the watch pipeline.** Start a supplied manager fixture, wait for cache synchronization, and await a bounded observable outcome. | Replace a fixed sleep with a deadline-bounded observation and ensure manager/test-environment cleanup. |
| 31.35 | **Debugging a missed reconcile.** Follow API event, cache, predicate, handler, queue, and reconcile execution as separate stages. | Locate a filter, scope, mapping, or permission defect from a supplied short trace. |
| 31.36 | **Checkpoint: one practical controller patch.** Combine a precise watch contract with a small code correction and regression case. | Repair a supplied `SetupWithManager` or `Reconcile` fragment; do not build or deploy a whole operator. |

### Controller pitfalls that the lessons must make explicit

| Distinction | Required teaching point |
|---|---|
| Events versus state | Reconcile toward current desired state. Events can be coalesced and reconcile can run repeatedly; neither watches nor queues promise exactly-once side effects. |
| Generation versus resource version | Generation behavior depends on the resource and its subresources. `resourceVersion` is an opaque concurrency/watch token, not an application counter to parse or order. |
| Primary updates versus dependent status | Generation-only filtering may suit part of a primary-resource policy but can hide child readiness changes or prevent status repair. |
| Deletion versus the final delete event | With a finalizer, setting a deletion timestamp is an update before final deletion. The controller must still receive a trigger to perform cleanup. |
| Predicates versus cache scope | Predicates filter events before keys are enqueued; they do not reduce what the informer cache stores. Cache namespace/selector configuration has a different effect. |
| A query versus a subscription | `MatchingLabels` or `MatchingFields` on one `List` call does not, by itself, reconfigure the controller's watches. |
| Cached reads versus direct reads | The manager's default client does not generally promise read-your-writes through its cache. Bypassing the cache should be an explicit decision, not a blanket workaround. |
| Per-watch versus global predicates | Scope filters to the resource types and changes they understand. Do not assume a builder-wide filter is correct for every watched kind. `WatchesRawSource` has its own documented predicate behavior. |
| Indexes versus API-server selectors | A controller-runtime cache index accelerates local lookups; it does not automatically add field-selector support to the Kubernetes API server. |
| Owner references versus arbitrary dependencies | `Owns` routes using owner references, not matching labels alone. A referenced non-owned resource needs deliberate mapping to the primary keys. |
| Fake client versus API semantics | A fake client is useful for logic fixtures but is not evidence of real RBAC, admission, cache/watch, or complete resource-version behavior. |
| `envtest` versus a full cluster | `envtest` starts an API server and etcd; it does not automatically run kubelet or built-in controllers such as garbage collection. Start the controller under test explicitly. |
| Local queues versus multiple replicas | Queue deduplication in one controller is not a distributed lock. Understand manager leader-election configuration or an intentional multi-replica design; keep reconciliation idempotent either way. |

Browser activities use supplied objects, traces, and code excerpts. Optional executable controller fixtures need compatible dependencies; optional `envtest` execution also needs supported API-server/etcd binaries. Those downloads and any platform-specific setup are outside the lesson timer, and no activity should silently use an existing kubeconfig or cluster.

This is controller-development literacy, not a complete Kubernetes administration course. Cluster installation, networking internals, admission-webhook implementation, Helm, and fleet operations are separate deeper subjects.

## What one authored lesson could look like

This illustrative lesson is included to show the intended size and interaction style. The other lesson rows above are specifications, not already-written question banks.

### Example: 06.05 - Keep the result of append

**Goal:** Add elements to a slice and retain the updated slice value.

**Recall:** What does `len(scores)` tell you?

**Teach:** `append` returns the updated slice. Assign that result to the variable you want to use afterward. The storage details come later; today's goal is simply to keep the returned value.

```go
scores := []int{2, 4}
scores = append(scores, 6)
fmt.Println(scores)
```

**Predict:** Which values are printed?

**Fill:** Complete the line that adds `8` to `scores`.

```go
scores = ______
```

**Fix:** This standalone call does not compile because its result is unused:

```go
append(scores, 10)
```

Change that line so `scores` includes the new value.

**Hint 1:** The function returns the slice you want to keep.

**Hint 2:** Put that result back into `scores`.

**Answer explanations, revealed after an attempt:**

- The first example prints `[2 4 6]`.
- The blank is `append(scores, 8)`.
- The repair is `scores = append(scores, 10)`.

**Takeaway:** Keep the slice returned by `append`; do not confuse calling it with updating the caller's slice variable automatically.

Later reviews change the values, put the operation inside a function, or combine it with a nil slice. Capacity and backing-array questions do not appear until those concepts have been taught.

## Coding-challenge helper map

These additions are standard-library packages or built-ins, not third-party algorithm dependencies. The problem's contract and permitted techniques come first: do not substitute a helper when the exercise explicitly asks you to implement that operation yourself.

| Common task | Useful Go helper | Lessons | Important limit |
|---|---|---|---|
| Decimal text to/from an integer | `strconv.Atoi`, `Itoa` | 08.08 | Strict parsing and Go `int` range do not automatically match a problem's custom atoi/clamping rules. |
| Binary/hex text and explicit widths | `strconv.ParseInt`, `ParseUint`, `FormatInt`, `FormatUint` | 08.13-08.14 | Select base, signedness, and bit size deliberately; handle errors. |
| Boolean or floating-point conversion | `strconv.ParseBool`, `FormatBool`, `ParseFloat`, `FormatFloat` | 08.15-08.16 | A supported spelling or float format is a contract, not a general-purpose parser. |
| Append numeric text to bytes | `strconv.AppendInt`, `AppendUint` | 08.17 | Retain the returned buffer, just as with ordinary append. |
| Split, search, and build text | `strings.Fields`, `Split`, `Join`, `Index`, `Contains`, `Builder`, `FieldsFunc` | 08.05, 08.07, 08.10, 08.22 | Empty-field behavior and byte offsets matter; avoid a regex when a simpler helper fits. |
| Classify and compare character data | `unicode` predicates, `strings.EqualFold`, `unicode/utf8` | 08.19-08.21 | ASCII, Unicode code points, and user-perceived characters are different contracts. |
| Match byte slices | `bytes.Equal`, `Index`, `Contains` | 08.23 | Byte matching does not decode or normalize Unicode. |
| Copy or compare collections | `slices.Clone`, `Equal`; `maps.Clone`, `Equal` | 15.07-15.08 | Clones are shallow; equality helpers have type constraints. |
| Sort numbers, words, or records | `slices.Sort`, `SortFunc`; `cmp.Compare`; older `sort` helpers | 15.13-15.14 | Sorting mutates; subtraction is not an overflow-safe comparator. |
| Search a sorted sequence | `slices.BinarySearch`, `sort.Search` | 15.15, 16.07 | Sortedness or a monotonic predicate is required; the insertion index can equal the length. |
| Produce sorted map keys | `maps.Keys`, `slices.Collect`, then sorting | 15.16 | Iteration alone is not deterministic; iterator helpers need a suitable Go version. |
| Deduplicate or preserve equal-key order | `slices.Compact`, `SortStableFunc` | 15.17, 16.11 | Compact removes adjacent duplicates, not all duplicates in arbitrary order. |
| Select integer bounds or use floating math | Built-in `min`/`max`; `math` | 16.13 | Float conversion can lose integer precision; floating `Pow` is not exact integer exponentiation. |
| Count or locate bits | `math/bits` width-specific helpers | 16.14-16.16 | Width, signedness, and zero-input results must match the problem. |
| Calculate beyond machine integer ranges | `math/big.Int` | 16.17 | Respect mutable receivers and any problem rule forbidding arbitrary-precision shortcuts. |
| Keep top-k values or schedule by priority | `container/heap` | 17.11, 17.13-17.15 | Supply the required interface; call package-level heap operations to preserve invariants. |
| Move/remove a known entry or update LRU order | `container/list` plus a map | 17.16-17.17 | A linked list is not automatically preferable to a simple slice-based stack or queue. |

### Judge compatibility

The course's Go 1.27 baseline is not a claim about LeetCode's current execution environment. Check the selected judge's documented Go version and allowed imports before using a snippet. The following are focused helper alternatives, not a promise that the entire course can be compiled unchanged on an older toolchain.

| Helper | Minimum Go version for this helper | Older-toolchain alternative |
|---|---|---|
| Built-in `min` and `max` | Go 1.21 | A short typed comparison helper. |
| `slices.Sort`, `SortFunc`, `BinarySearch`, `Clone`, `Equal`, and `Compact` | Go 1.21 | `sort` functions, `copy`, or a small explicit loop as appropriate. |
| `maps.Clone`, `maps.Equal`, and `cmp.Compare` | Go 1.21 | Explicit copy/equality loops and comparisons, respecting the original type and nil-value contract. |
| Iterator-returning `maps.Keys` and `slices.Collect` | Go 1.23 | Range over the map, append keys to a slice, then sort when order matters. |

Reference cards can also point to related APIs such as `strings.Cut`, `strings.Count`, `strings.ReplaceAll`, `bits.Reverse32`, and `bits.RotateLeft32`. These are supporting lookups, not extra numbered lessons or permission to ignore overlapping-match and fixed-width requirements.

## Authoring rules for the eventual course

| Rule | Required behavior |
|---|---|
| Self-contained activities | Supply the relevant input, code, assumptions, and expected contract. Do not depend on a half-finished project from yesterday. |
| One central idea | A lesson can have supporting syntax, but should not require several new mental models at once. |
| Explained scaffolding | If a framework signature appears before its detailed chapter, annotate its immediate role and keep the unfamiliar part out of the exercise. |
| Short code | Keep the meaningful example small; collapse imports, fixtures, and generated boilerplate rather than forcing the learner to type them. |
| No hidden ordering assumptions | Map iteration, goroutine scheduling, and simultaneously ready `select` cases must not have fabricated single outcomes. |
| Explicit versioning | Label language/API changes and use the stated module baseline, not just whatever compiler happens to be installed. |
| Stable example behavior | Prefer specified behavior; mark compiler/runtime implementation observations as observations, not universal language guarantees. |
| No success-shaped failure | Incorrect answers, invalid input, failed parsing, unavailable storage, and unsupported grading must be surfaced clearly. |
| Meaningful distractors | Wrong options should reflect plausible misconceptions, not obscure trivia or intentionally confusing wording. |
| No spoiler-first design | Offer a nudge, then a stronger hint, then a solution; do not place the answer directly above the exercise. |
| Practice variety | Revisit a concept through different activities rather than repeat only multiple-choice recognition. |
| Honest completion evidence | Distinguish choosing an answer, self-checking written code, and executing that code. |
| No setup surprises | Database, compiler, race detector, code generator, and container installation are not hidden prerequisites for a browser lesson. |
| Challenge shortcuts | Teach helper contracts, mutation, complexity, and judge-version requirements, not simply the shortest-looking library call. |
| Controller examples | Use a compatible, pinned Kubernetes library set; distinguish predicates, cache scope, and request mapping, and include lifecycle-trigger cases. |
| Original teaching material | Explain concepts in original wording; link to authoritative documentation for deeper reference. |

### Modern Go guardrails

| Version-sensitive concept | Teaching rule |
|---|---|
| Go 1.21 collection and comparison helpers | Distinguish built-ins from packages and provide `sort`/loop alternatives when discussing an older coding-challenge judge. |
| Go 1.22 loop variables | Variables declared by a loop have per-iteration semantics. Assignment to an existing variable is different; captured referenced data can still be shared. |
| Go 1.22 integer ranges and HTTP routing | Label the newer syntax and `ServeMux` features when comparing with older code. |
| Go 1.23 iterators | Range-over-function is stable, not an experiment required by this course. Do not present iterator-returning collection APIs as returning slices. |
| Go 1.24+ benchmark and filesystem APIs | Label `B.Loop` and `os.Root`; do not equate string-based path joining with constrained filesystem access. |
| Go 1.25+ task and test helpers | Prefer clear current examples while teaching enough legacy WaitGroup syntax to read existing repositories. |
| Go 1.26 initialized allocation | Teach `new(expression)` as distinct from the older type-only form, with a version badge. |
| Go 1.27 generic methods | A method may have its own type parameters, but interface methods cannot declare type parameters or be implemented by generic methods. |
| Go 1.27 JSON APIs | The supported v1 API and the newer v2 API have different default behavior. Use an explicit migration lesson instead of a blind import rewrite. |

### Per-lesson content record

The eventual app should be able to represent each lesson with a stable record containing:

- Lesson ID, chapter ID, title, objective, prerequisites, and estimated duration.
- Concept tags and earlier concepts to retrieve.
- A short explanation and a runnable reference example, with expected behavior and a version baseline.
- Approximately 3-4 interactions, each with its type, prompt, supported answer format, hints, explanation, and grading mode.
- Any supplied fixture or optional local-run instructions.
- Review variants that test the same concept with different details.
- A concise takeaway and links to the relevant reference cards.

Chapter records must list their actual lesson IDs and review positions. Navigation and completion must not assume every chapter ends at lesson `.12`.

Arbitrary free-form Go answers need real execution or honest self-checking; an exact-text match is not a general Go compiler or semantic grader.

## Delivery requirements for the later web app

These describe the planned build, not features implemented by this syllabus.

| Area | Expected experience |
|---|---|
| Opening the course | Unzip and open the browser entry point; no account or hosted service required for lesson reading. |
| Navigation | Chapter map, resume button, previous/next lesson, search, and direct navigation to a lesson. |
| Readability | Short screens, legible code, keyboard controls, accessible labels, and a layout usable on smaller displays. |
| Feedback | Immediate explained feedback for supported question types; progressive hints; clear handling of ambiguous/free-form answers. |
| Progress | Local progress with JSON export/import so moving computers or clearing browser data does not have to erase the record. |
| Storage limitations | Surface unavailable or failed browser storage and keep the current lesson usable; do not silently claim persistence. Local-file browser behavior must be accounted for. |
| Reviews | A small optional due-review queue, with review work fitting inside the daily goal. |
| Code execution | No false claim that an offline question engine executes Go. Optional local commands can be provided separately. |
| Offline behavior | Bundle required lesson text, styles, scripts, questions, and illustrations; external documentation links are supplemental. |
| Privacy | No analytics, upload of answers, remote code execution, or public publishing required. |
| Portability | Keep editable lesson source and stable IDs; support a readable Markdown export alongside the app. |

## Reference cards and deliberately deferred depth

Reference cards are searchable supporting material, not additional numbered lessons. They should cover common syntax, basic type names and conversions, built-ins such as `min` and `max`, bitwise operators, common `fmt` verbs, collection zero values, receiver/method-set rules, error-inspection patterns, everyday `go` commands, the coding-challenge helper map, and standard-library package roles. Kubernetes cards should summarize object metadata, API verbs, watch-to-request routing, predicate scope, finalizer transitions, and fake-client versus `envtest` capabilities.

More specialized subjects can be acknowledged without pretending to teach them fully in a five-minute lesson: complex-number computation, detailed Unicode grapheme segmentation, advanced SQL/query planning, lock-free algorithms, distributed consensus, custom cryptography, extensive reflection, `unsafe`, cgo implementation, assembly, compiler internals, and experimental SIMD.

Reading a deployment fragment is not the same as operational experience; reading a Dijkstra step is not a complete algorithms education. The goal is a broad, practical Go foundation with enough repetition to retain it.

## Source and currency notes

The teaching text and exercises should be original. The following sources anchor language behavior, library contracts, version labels, and further reading.

| Source | Use |
|---|---|
| [Go documentation index](https://go.dev/doc/) | Official tutorials, diagnostics, database guidance, and module documentation. |
| [A Tour of Go](https://go.dev/tour/) | A useful reference for core syntax and conceptual progression. |
| [The Go language specification](https://go.dev/ref/spec) | Exact language rules; do not ask beginners to read it cover to cover. |
| [Go standard-library documentation](https://pkg.go.dev/std) | Current API contracts, examples, and version information. |
| [`strconv`](https://pkg.go.dev/strconv) | Parsing, bases, widths, formatting, and append-to-buffer contracts. |
| [`strings`](https://pkg.go.dev/strings) and [`bytes`](https://pkg.go.dev/bytes) | Text versus byte operations, tokenization, and result construction. |
| [`unicode`](https://pkg.go.dev/unicode) and [`unicode/utf8`](https://pkg.go.dev/unicode/utf8) | Character classification, case operations, and UTF-8 decoding/validation. |
| [`slices`](https://pkg.go.dev/slices), [`maps`](https://pkg.go.dev/maps), and [`cmp`](https://pkg.go.dev/cmp) | Modern collection helpers, contracts, and introduction versions. |
| [`sort`](https://pkg.go.dev/sort) | Search predicates, stable ordering, and older-toolchain alternatives. |
| [`math`](https://pkg.go.dev/math), [`math/bits`](https://pkg.go.dev/math/bits), and [`math/big`](https://pkg.go.dev/math/big) | Numeric types, fixed-width bit operations, and exact large-number arithmetic. |
| [`container/heap`](https://pkg.go.dev/container/heap) and [`container/list`](https://pkg.go.dev/container/list) | Priority-queue invariants and linked-element operations. |
| [Go release history](https://go.dev/doc/devel/release) | Supported release policy and patch-version selection. |
| [Go 1.27 release notes](https://go.dev/doc/go1.27) | Generic methods, JSON v2 availability, and current version-sensitive material. |
| [Go 1.26 release notes](https://go.dev/doc/go1.26) | `new(expression)`, modernized `go fix`, and module-initialization baseline behavior. |
| [Go 1.25 release notes](https://go.dev/doc/go1.25) | `WaitGroup.Go` and stable `testing/synctest`. |
| [Go 1.24 release notes](https://go.dev/doc/go1.24) | `B.Loop`, constrained filesystem access, and other labeled APIs. |
| [Go 1.23 release notes](https://go.dev/doc/go1.23) | Stable range-over-function iterators. |
| [Go 1.22 release notes](https://go.dev/doc/go1.22) | Per-iteration loop variables, integer ranges, and newer HTTP routing. |
| [Go 1.21 release notes](https://go.dev/doc/go1.21) | `min`/`max`, `slices`, `maps`, and `cmp`. |
| [Go modules reference](https://go.dev/ref/mod) | Modules, dependency resolution, versions, and workspaces. |
| [Go memory model](https://go.dev/ref/mem) | The basis for synchronization and race reasoning. |
| [Diagnostics](https://go.dev/doc/diagnostics) | Profiling, tracing, and investigation tool selection. |
| [Data race detector](https://go.dev/doc/articles/race_detector) | Execution-based race detection and platform requirements. |
| [Go fuzzing](https://go.dev/security/fuzz/) | Fuzz-test structure and usage. |
| [Go garbage collector guide](https://go.dev/doc/gc-guide) | Reachability, allocation, and runtime cost models. |
| [Database access guidance](https://go.dev/doc/database/index) | Handles, result lifetimes, contexts, transactions, and safe parameters. |
| [JSON v2 migration guide](https://go.dev/doc/jsonv2-migration) | Explicit behavior differences and migration decisions. |
| [Go vulnerability management](https://go.dev/doc/security/vuln/) | `govulncheck` and dependency vulnerability workflows. |
| [Effective Go](https://go.dev/doc/effective_go) | Selected idiom explanations, with its age and missing modern coverage explicitly acknowledged. |
| [Go extended libraries](https://pkg.go.dev/golang.org/x/sync/errgroup) | The `errgroup` API and its actual limits/semantics. |
| [Cobra](https://github.com/spf13/cobra) | Maintained command-library reference. |
| [Chi](https://github.com/go-chi/chi) | Router and middleware reference. |
| [pgx](https://github.com/jackc/pgx) | PostgreSQL driver and pooling reference. |
| [sqlc](https://docs.sqlc.dev/) | Generated query API and workflow reference. |
| [Protocol Buffers](https://protobuf.dev/) | Schema and compatibility guidance. |
| [gRPC for Go](https://grpc.io/docs/languages/go/) | Generated RPC API usage and concepts. |
| [OpenTelemetry for Go](https://opentelemetry.io/docs/languages/go/) | Instrumentation and context propagation. |
| [Kubernetes controllers](https://kubernetes.io/docs/concepts/architecture/controller/) | Desired-state reconciliation and the role of controllers. |
| [Kubernetes API concepts](https://kubernetes.io/docs/reference/using-api/api-concepts/) | Object versions, list/watch behavior, and API concurrency rules. |
| [`client-go`](https://pkg.go.dev/k8s.io/client-go) | Kubernetes Go clients and lower-level API/informer building blocks. |
| [Controller-runtime builder](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/builder) | `For`, `Owns`, `Watches`, mapping, and filter scope. |
| [Controller-runtime predicates](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/predicate) | Event filtering, generation caveats, and predicate composition. |
| [Controller-runtime client](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client) | Read/write operations, patches, indexes, and subresource access. |
| [Kubebuilder watch predicates](https://book.kubebuilder.io/reference/watching-resources/predicates-with-watch) | Focused watch-filter examples; adapt them to the complete lifecycle contract. |
| [Kubebuilder finalizers](https://book.kubebuilder.io/reference/using-finalizers.html) | Deletion timestamps and controller-owned cleanup. |
| [Controller-runtime fake client](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client/fake) | Logic-fixture setup and limitations. |
| [Kubebuilder `envtest`](https://book.kubebuilder.io/reference/envtest.html) | API-server/etcd fixtures, required binaries, and differences from a full cluster. |

Effective Go explicitly says it is not actively updated and does not cover significant later language, module, or library changes. It must not be the sole authority for the modern parts of this course.

Before authoring a version-sensitive lesson, consult the matching current official documentation and pin any external-library snippet to an actual release. Do not infer stable behavior from an experimental or proposal-only API.

The controller-runtime builder and predicate references consulted for this update identify v0.25.0. Use the selected release's compatibility guidance and dependency versions when the executable lesson fixtures are authored; do not mix a current generated scaffold with arbitrary older watch-handler signatures.
