018 Project 18: Go Workout - 200 Ten-Minute Exercises

018 Go Workout: 200 Ten-Minute Exercises

This chapter uses a short-exercise format inspired by workout-style learning books: small tasks, tight scope, immediate practice.

How to Use

  • Spend 10 minutes per exercise.
  • Do not copy old answers.
  • Prefer standard library first.
  • After every 10 exercises, write a short reflection.
10-minute loop

read task -> code -> run -> test edge case -> note takeaway

Foundation Warmup (1-20)

  1. Parse two integers from CLI args and print sum.
  2. Parse -name flag and print greeting.
  3. Build a switch on day number (1-7).
  4. Convert Celsius to Fahrenheit with proper formatting.
  5. Reverse a string safely for ASCII.
  6. Count vowels in a string.
  7. Find min/max in an []int.
  8. Remove duplicates from a slice.
  9. Implement contains([]string, string) bool.
  10. Build a frequency map for words in a sentence.
  11. Sort a slice of ints ascending.
  12. Sort a slice of structs by one field.
  13. Write a function returning (value, error) for divide.
  14. Use defer to time function execution.
  15. Create a custom error type with context.
  16. Marshal struct to JSON with tags.
  17. Unmarshal JSON into struct and validate fields.
  18. Read env var with fallback default.
  19. Parse RFC3339 timestamp.
  20. Format duration nicely (1h2m3s).

Files and CLI Tools (21-40)

  1. Read file and print line count.
  2. Read file and print byte count.
  3. Read from stdin and uppercase output.
  4. Build tiny head -n clone.
  5. Build tiny tail -n clone.
  6. Filter lines containing a substring.
  7. Replace substring in each line and print.
  8. Walk directory and count files.
  9. Walk directory and sum file sizes.
  10. Print top 10 largest files in a directory tree.
  11. Build file extension counter (.go, .md, etc.).
  12. Skip hidden files while walking.
  13. Add -json output mode to a CLI tool.
  14. Add -quiet and -verbose log levels.
  15. Create a checksum (SHA-256) for one file.
  16. Compare two files by checksum.
  17. Build tiny wc (lines/words/bytes).
  18. Build tiny grep with regex input.
  19. Add case-insensitive flag to grep clone.
  20. Print first match index and line number.

Structs, Methods, Interfaces (41-60)

  1. Define User struct and constructor.
  2. Add String() method to struct.
  3. Add pointer receiver mutator method.
  4. Add value receiver read-only method.
  5. Implement small interface (Runner) with two types.
  6. Compose two structs via embedding.
  7. Resolve method name conflict in embedded structs.
  8. Implement io.Writer that counts bytes.
  9. Implement io.Reader over in-memory string.
  10. Build a decorator function for timing any function.
  11. Build Option pattern for server config.
  12. Validate config and return combined error.
  13. Compare two structs for equality constraints.
  14. Parse CSV into typed struct slice.
  15. Convert struct slice to map by key field.
  16. Implement generic Map helper for slices.
  17. Implement generic Filter helper.
  18. Implement generic Reduce helper.
  19. Create custom type alias with methods.
  20. Add unit tests for all methods.

Errors and Reliability (61-80)

  1. Wrap errors with %w across 3 layers.
  2. Detect sentinel error with errors.Is.
  3. Detect custom type with errors.As.
  4. Build retry helper with max attempts.
  5. Add exponential backoff to retry helper.
  6. Add jitter to retry backoff.
  7. Build circuit-breaker lite (open/close states).
  8. Add timeout via context.WithTimeout.
  9. Add cancellation via parent context.
  10. Build must helper for internal tooling only.
  11. Build panic recovery middleware for HTTP.
  12. Capture stack trace on panic and log.
  13. Return structured JSON error response.
  14. Add error codes enum for API errors.
  15. Validate all CLI input and fail fast.
  16. Add dead-letter file for failed jobs.
  17. Add graceful shutdown on SIGINT.
  18. Add idempotency key check for commands.
  19. Add bounded retries for network call.
  20. Add fallback path when primary call fails.

Concurrency Basics (81-100)

  1. Launch 5 goroutines and wait with WaitGroup.
  2. Fan-out tasks to worker pool.
  3. Fan-in results from workers.
  4. Add context cancellation to worker pool.
  5. Add timeout to a blocking goroutine.
  6. Use buffered channel to smooth bursts.
  7. Use unbuffered channel to enforce handoff.
  8. Prevent goroutine leak on early return.
  9. Build bounded semaphore using channel.
  10. Merge two channels into one output.
  11. Implement producer-consumer with backpressure.
  12. Add select with timeout case.
  13. Add select with default non-blocking case.
  14. Protect shared map with mutex.
  15. Replace mutex map with sync.Map and compare.
  16. Use sync.Once for singleton init.
  17. Use sync.Cond for queue notifications.
  18. Build rate limiter with ticker.
  19. Build token bucket limiter.
  20. Profile goroutine count during load.

Networking and HTTP (101-120)

  1. Build /health endpoint.
  2. Add /ready endpoint with dependency check.
  3. Parse query params safely.
  4. Parse JSON request body with size limit.
  5. Return JSON response helper function.
  6. Add middleware for request logging.
  7. Add middleware for panic recovery.
  8. Add middleware for request ID.
  9. Add middleware for timeout context.
  10. Add simple in-memory rate limit middleware.
  11. Build URL shortener POST /shorten.
  12. Build URL shortener GET /{code} redirect.
  13. Add TTL to short links.
  14. Add short-link collision handling.
  15. Add ETag support to one endpoint.
  16. Add graceful server shutdown with context.
  17. Build HTTP client with timeout + retries.
  18. Build HTTP client with custom transport.
  19. Add gzip compression middleware.
  20. Benchmark one endpoint with your load tester.

Data and Persistence (121-140)

  1. Use encoding/csv to read sample data.
  2. Use encoding/csv to write report file.
  3. Store key-value data in BoltDB (or bbolt).
  4. Build repository interface over in-memory store.
  5. Add file-backed repository implementation.
  6. Add migration version field to data model.
  7. Add optimistic locking field (version).
  8. Add simple cache with TTL map.
  9. Add cache invalidation on write.
  10. Serialize map to JSON snapshot file.
  11. Recover state from snapshot on startup.
  12. Add periodic snapshot goroutine.
  13. Add checksum to snapshot file.
  14. Add snapshot restore validation.
  15. Build append-only event log file.
  16. Replay event log to rebuild state.
  17. Add compaction command for old events.
  18. Add corruption detection for events.
  19. Add CLI export to CSV.
  20. Add CLI import from CSV.

Testing Workout (141-160)

  1. Write table-driven tests for parser.
  2. Add subtests by category.
  3. Add golden file test for CLI output.
  4. Add benchmark with b.Loop.
  5. Add benchmark with -benchmem analysis.
  6. Add fuzz test for JSON decode path.
  7. Add race test and fix discovered issue.
  8. Add test helper for temporary fixture files.
  9. Add t.Cleanup in all integration tests.
  10. Use httptest for handler test.
  11. Use httptest.Server for client test.
  12. Use testing/synctest for flaky timer logic.
  13. Add tests for retry backoff boundaries.
  14. Add tests for context timeout path.
  15. Add tests for panic recovery middleware.
  16. Add tests for rate limiter edge case.
  17. Add tests for short-link collision behavior.
  18. Add tests for file checksum mismatch path.
  19. Add integration test with build tag integration.
  20. Add CI test command matrix in README.

Linux Tooling Track (161-180)

  1. Extend ls clone with -R recursion.
  2. Extend ls clone with colorized output.
  3. Extend cat clone with -T tab markers.
  4. Extend grep clone with invert match -v.
  5. Extend grep clone with count-only -c.
  6. Extend tail clone to handle file rotation.
  7. Extend du clone with max depth flag.
  8. Extend find clone with regex match mode.
  9. Extend wc clone with rune count flag.
  10. Build mini xargs clone.
  11. Build mini cut clone.
  12. Build mini sort clone.
  13. Build mini uniq clone.
  14. Build mini tee clone.
  15. Build mini which clone.
  16. Build mini ps clone using /proc (Linux).
  17. Build mini free clone from /proc/meminfo.
  18. Build mini uptime clone from /proc/uptime.
  19. Build mini df clone using syscall.Statfs.
  20. Build mini watch clone for repeated commands.

Advanced TUI and Infra Track (181-200)

  1. Add CPU history sparkline to TUI monitor.
  2. Add memory history sparkline to TUI monitor.
  3. Add keybinding help modal in TUI.
  4. Add theme toggle (light/dark terminal palette).
  5. Add status bar with connection state.
  6. Add periodic refresh ticker with pause key.
  7. Add filtering by VM status in Proxmox TUI.
  8. Add node selector screen in Proxmox TUI.
  9. Add VM details pane in Proxmox TUI.
  10. Add confirmation dialog before VM stop.
  11. Add async action queue and progress states.
  12. Add retry-on-429 for Proxmox API calls.
  13. Add structured logs for every API request.
  14. Add audit log file for start/stop actions.
  15. Add SSH orchestrator output to JSON report.
  16. Add SSH orchestrator parallel limit per subnet.
  17. Add host reachability precheck before SSH.
  18. Add rollout mode: canary then full batch.
  19. Add rollback command set for failed rollout.
  20. Build capstone: TUI panel that triggers SSH jobs and shows live results.

Chapter References in This Book

Use these while solving workouts:

  • Foundations: /Users/king/Workspace/Repos/books/books/Go/content/01-foundations
  • Core: /Users/king/Workspace/Repos/books/books/Go/content/02-core
  • Concurrency: /Users/king/Workspace/Repos/books/books/Go/content/07-concurrency-parallelism
  • Testing: /Users/king/Workspace/Repos/books/books/Go/content/06-testing
  • Projects: /Users/king/Workspace/Repos/books/books/Go/content/99-projects

Step-by-Step Explanation

  1. Pick a small set of exercises by track.
  2. Timebox each attempt to ten minutes.
  3. Record one takeaway and one weakness after each exercise.
  4. Revisit chapter references when blocked.
  5. Re-solve selected problems from memory weekly.

Learning Goals

  • Build consistency, not one-time intensity.
  • Improve retrieval and transfer of Go patterns.
  • Progress from syntax fluency to engineering fluency.