Apprenticeship Retro
Reflecting on my 8th Light apprenticeship journey - books read, blogs written, projects completed, and lessons learned.
Reflecting on my 8th Light apprenticeship journey - books read, blogs written, projects completed, and lessons learned.
Demystifying Cross-Origin Resource Sharing (CORS) and the Same-origin Policy that protects web browsers from malicious sites.
Understanding Cross-site Tracing (XST) attacks and how the HTTP TRACE method can bypass HttpOnly cookie protection.
Social and behavioral patterns observed during intensive pair programming - checking ego, pulling out information, and stepping up.
Why learning testing tools before diving into a new language or framework can accelerate learning and improve TDD practice.
A comprehensive guide to Vim registers - unnamed, numbered, named, and read-only registers for storing and retrieving text.
Implementing the Circuit Breaker stability pattern to protect against failures from unavailable services or resources.
Realizing the importance of text editing fluency outside your favorite editor - being a generalist with tools too.
Learning why overriding built-in function names can cause confusion and how to make better naming decisions.
Exploring Ward Cunningham's original debt metaphor - it's about incomplete understanding, not sloppy code.
Using Vim's built-in exrc setting to enable project-specific configurations without plugins.
Understanding the Acyclic-Dependencies, Stable-Dependencies, and Stable-Abstractions principles for reducing package coupling.
Exploring the three principles of package cohesion - REP, CRP, and CCP - for allocating classes to packages effectively.
Using Clojure's thread macro to create readable data transformations that clearly describe the flow of operations.
The Visitor pattern - extending object structure behavior without modifying classes through double dispatch.
Understanding the Observer pattern spectrum - comparing push and pull models for notifying observers of changes.
Creating an ad-hoc test runner in Vim using tmux send-keys to eliminate workflow friction when running tests.
Using tmux send-keys to emulate keyboard input and automate workflows across panes and windows.
Exploring Vim's Command-line mode - one of the lesser-known modes that enables powerful command history features.
Applying the expand-contract refactoring pattern in Clojure using multimethods to safely migrate function interfaces.
Using auto-test runners more deliberately with Vim settings to improve TDD workflow and avoid programming by coincidence.
A deeper look at the Dependency Inversion Principle - understanding that clients should own the interfaces they depend on.
Understanding hygienic macro systems and why they matter - preventing unintended variable capture and binding issues.
A cool pattern in Elixir - using list comprehensions to generate multiple named function definitions at compile time.
Creating test doubles for Java Socket objects in Clojure using proxy and closures for testing socket-based applications.
Exploring homoiconicity in programming languages - when code structure matches its internal representation, enabling "code as data".
Understanding referential transparency - when expressions can be replaced with their evaluated values without changing program behavior.
Explaining closures and free variables - how functions capture and retain access to variables from their enclosing scope.
Understanding the difference between lexical and dynamic scoping - how variable resolution differs based on code structure versus call stack.
Clarifying the difference between statements and expressions in programming languages - actions versus values.
Understanding how implicit "this" references can escape inner classes and cause thread safety issues in Java.
Demystifying event listeners in Java by building a custom event system for publishing notifications.
Exploring the relationship between the Liskov Substitution Principle and Dependency Inversion Principle - both encourage flexibility in dependencies.
Why Vim's find and till motions are hard to adopt, and how rethinking their use can make them more practical and less about precision.
Introduction to the Liskov Substitution Principle - subtypes must be substitutable for their base types to maintain expected behavior.
Exploring the relationship between the Single Responsibility Principle and small classes - they may actually be the same thing.
Three key benefits of the Single Responsibility Principle - reduced coupling, increased testability, and reduced mental energy.
Two patterns for introducing interfaces - replacing subclasses with injection and creating dependencies that don't exist yet.
Understanding Android's Java compilation process and debugging a NoClassDefFoundError caused by missing runtime dependencies.
How the Interface Segregation Principle applies SRP to dependencies - limiting coupling and improving cohesion.
Exploring how the Interface Segregation Principle applies SRP to interfaces - making them smaller and more cohesive.
Useful Vim features for writing prose - sentence motions, spell checking, and display line navigation.
Techniques for identifying Single Responsibility Principle violations - summaries, method prefixes, and abstraction levels.
Introduction to the Single Responsibility Principle - a class should have only one reason to change.
Understanding the difference between Uncle Bob's Three Rules of TDD and the red/green/refactor cycle - they're not the same thing.
Exploring when to use single versus multiple assertions in tests - being pragmatic about testing stateful behavior.
Why wildcard imports are problematic - they hide design flaws and obfuscate module dependencies that could reveal code smells.
Breaking down the minimax algorithm for creating an unbeatable Tic-Tac-Toe computer player by minimizing maximum loss.
Using triangulation to drive out behavior by adding more assertions to tests, preventing naive implementations from passing.
Exploring the Child Test pattern from Kent Beck - knowing when to back out of a test and write supporting tests first.
Understanding the distinction between rehearsing and practicing katas, and the benefits of preparing for a kata performance.
Learning the difference between doing a kata once and truly practicing through repetition - the key to unlocking the potential of code katas.
Starting my first apprenticeship project: building an unbeatable Tic-Tac-Toe game using TDD and the minimax algorithm.
Beginning my apprenticeship journey at 8th Light, documenting the ideas, principles, and techniques I encounter along the way.