The software engineering cheatsheet
This is a living document where I'm trying to keep track of my thoughts, advice and guidelines around building software and running software teams. Very little of this is original thought.
Resist complexity, especially the stuff that doesn't solve the problem.
Building simple software is hard. Valuable solutions are valuable because they solve hard problems and hard problems often defy simple solutions. The problem becomes knowing what complexity to admit and what to reject when building a system. In my experience this is one of the key things that sets teams that can move fast apart from teams that get trapped.
On the bright side lots of the crippling complexity I've witnessed (and contributed to) is extraneous to the value-providing function of the system. This means there's room for improvement. Using k8s when ECS will do? Building a fully responsive SSR'd frontend for your internal admin portal? CI/CD pipeline inspired by an Escher drawing? Figure out what really adds value and ditch the rest as it's much easier to add complexity than simplicity.
It's ok for senior engineers to appeal to experience but they need to make it clear when they're using it to overrule a junior
When teams need to make decisions it can be tricky when there's a difference of opinion, particularly between a more junior and more senior member of the team. When deciding what to do it's nice to think that the better argument should win every time but in low information situations slight differences in starting assumptions can have major implications for the conclusion.
One of the (most?) powerful features of senior engineers is that they've often seen analogous situations before and can detect something that doesn't smell right from a long way away. I think it's useful for senior engineers to be able to pull the experience card (even if they can't quite put it into words) but they have to make it clear that it's not because they think the junior is wrong or that their arguments are bad. Some things just don't feel right and on average there's value in the experience of a good senior.
Be fast to recognise when your argument hinges on personal preference
Everyone has their preferred tools, frameworks, patterns and methodologies. Some of them are better fits than others in certain situations but it's often a wash and people tend push for their preference.
Engineers that can recognise when their argument comes down to "I just prefer x" and engage accordingly (instead of engaging in lengthy efforts to retrofit an argument in favour of their preferred option onto the use-case) will accelerate the decision-making process and boost team harmony.
Demand concrete use cases when people propose new technology or new approaches
Shiny new tools can actually be a good thing. One of the keys to making sure that any new approach is worth the investment is to have a crystal clear focus on exactly how it's going to fix a problem. "Kafka is good for recording immutable commit logs, we should use it for our audit system" is much less good than "We're having peak throughput issues recording audit data, we should switch to Kafka to absorb the peaks while streaming the data into persistent storage using Kafka connect as we catch up".
Don't be afraid to ask the stupid sounding questions as it can be useful for the proposer to ensure they've got it fully clear in their own mind.
Reducing the duration of the build, test, deploy loop is an investment that pays back forever
Focusing on making tests run fast and taking seconds off of the deploy process saves engineering time forever. In microservice worlds where engineers can deploy multiple services many times a day, reducing the feedback loop is critical. Fast tests also encourage engineers to run tests more often which reduces the expected length of time between bugs getting written and bugs getting fixed.