avatar

Organizing Chaos

Thoughts on technical leadership and software engineering

A few fast solutions for Advent of Code 2023

The Advent of Code is an annual programming competition with a lot of interesting puzzles. While the competition is mostly about answering the questions as quickly as possible, I instead prefer to challenge myself to come up with low-latency solutions for each problem. Now that the 2023 edition of AOC is wrapped up, I thought it would be interesting to go into a bit of detail about some of the faster and more unique solutions that I came up with.

Minimize global process

Global consistency comes at the cost of autonomy; be careful not to stifle what could be your most effective teams Earlier this week, I was discussing Platform Engineering with some other technical leaders. Someone suggested that one of the main benefits of an effective Platform was “reducing duplicate effort for developers”, to which another replied: I have worked for a company that forced all engineers to use the same shitty CI/CD system.

Software engineering is about thinking, not typing

Weeks of coding can save you hours of planning Software engineering best practices emphasize and value the importance of iterative work. They encourage working in ways that give us opportunities to make decisions frequently and adapt to changing circumstances. These principles are nearly ubiquitous and seem necessary for successful engineering efforts at large scales, but the concept is sometimes taken to an extreme that can be unhelpful. While it’s almost always a good idea to maintain the ability to iterate quickly and change our minds, that doesn’t mean that one shouldn’t take time to think before they begin to act.

Simplicity isn't easy

Simple is the opposite of complex, easy is the opposite of difficult I spend a lot of time thinking about complexity. I read an essay recently about complexity and cognitive load in software engineering that touches on a specific point that I think is important to the professional development of software: the difference between simplicity and ease. Like many engineers, I don’t enjoy working within overly complex systems. The cognitive load required to get anything done within such code bases is far greater than it should be.

Cheat codes

Support your teams' decision making processes while giving them the space they need to function autonomously. Autonomy is an important element of highly effective teams. As a leader, there’s a difficult balance to be struck between helping your teams get things done and providing the space and freedom that they need to solve problems themselves and own their solutions. Concepts like go slow to move fast can be used to help with this, but even still the core problem remains: how can a leader help teams solve difficult problems without reducing their ability to function autonomously?

Flexible systems

Most decisions that you make are not nearly as important as your ability to change them in the future. When designing systems, it’s easy to get caught up in the minutia of each decision that has to be made along the way. Technical systems may raise concerns about choosing the appropriate logging framework or determining the most effective concurrency model. Human systems may instead be concerned with how many meetings to hold, with whom, and how often.

Go slow to move fast

Engineering teams can often improve their long-term development velocity by slowing down in the short term. A shared misunderstanding 🔗Technical debt is an often debated topic. Like most concepts in software, it isn’t particularly difficult to find arguments supporting opposite sides of the spectrum - in a single minute of searching I was able to find that some believe that technical debt doesn’t exist, while others feel that technical debt is the most important aspect of product development.

Striped development

Incremental progress on large projects can be achieved by developing functional stripes across the system's components. When planning the delivery of a software project, there are many different strategies for handling the design and implementation of the system. At the extremes, we could attempt to complete a fully-specified design before writing any code at all, or we could start writing code without putting any thought towards our design and architecture at all.