CS in Review
A weekly roundup of my favorite papers/articles

The Software Ark: Issue 8

Mon 19 September 2022 / the-software-ark

Quote of the week

To work you have the right, but not to the fruits thereof - Gita

Articles

Understanding your code-base

Love the general approach, though I subscribe to a different set of mechanics. You start at the top at your typical RPC/HTTP endpoints. You spend a lot of time just understanding how everything is structured so that a request can be sent over the wire. Is there a custom protocol, or are they using Swagger for API definitions, or protobufs or thift for RPC. Is everything running in a container, is stuff spun up on demand, or is there allocated capacity? What happens when you go over your allocation - do you get throttled, or does everything come crashing down?

Once you get that, you traverse down the call graph from that entry point, one API at a time: what does a request look, what are the objects involved, how is the code-structured in layers or by feature? This builds your mental model for the domain. Then you wear your tin-foil-hat and assume all the documentation is wrong, and everything is poorly named. So you read through (top-down) the code for "key" classes. This is typically the ones that are massive, or with lots of dependencies. You make note of weird architectural patterns: two-writes, client instantiation in the constructor, muddled interfaces, duplicate dependencies, or serial network calls. This is where the fun stuff happens - no documentation will explain these decisions, and it makes for fun gossip with a more tenured dev: what circumstance led to this being shipped to prod. If you still don't get it maybe run some tests, use those break-points, inspect that state.

Once you have that, you take a second pass through and improve the documentation in the code. The stuff that you found weird - explain it and push that diff for review. PlantUML is great - get some block diagrams generated. Maybe use a UML plugin in your IDE to generate a skeleton if that helps you.

Also take a look at: Amber's take, and SWE Exchange which also has some good discussion around this

Design Thinking, and user needs

Design Thinking is this idea of working closely with the user to understand their pain-points, and then ideating a solution and validating market fit with said users. As trivial as it sounds, it works. In software, we hear about this often under the umbrella of Agile, but it's been a thing for while, even outside the world of software.

It works really well because it sets a robust framework in which to evaluate a solution, and reduces risk by validating market fit ahead-of-time. In a sense it applies the scientific method to the world of business - you come up with a hypothesis of a customer want, set up an experiment to validate it based on market dynamics, and repeat until you have a working view.

As simple as it sounds, it does run the risk of prioritizing customer wants over needs - and that's the slippery slope that I've seen really good PMs/engineers avoid. It's the 90s and a customer says they want to communicate better: do you build the Nokia 2200, or the first smart-phone with video calling to fundamentally change how they interact? Relying on your users to imagine the future gets you a better version of the present, and incremental improvement is good. But there are those big 10x gamechanging bets that you sometimes have to take. Design thinking doesn't hinder that, but empathising with a customer can easily become building what they ask for, same goes for the Engg-PM relationship - it can very quickly become building what a PM wants. That's autonomy that you shouldn't hand over. You're not there to build what they tell you to - you're there to solve their problem in the best way possible, and that might be building something better than they thought to ask for.

Growing as an engineer

There's this idea that growing as an engineer means getting better technically, and that's certainly a part of it. But tbh, I don't think there's a massive skill differential amongst talented experienced engineers. Once you know how to code, and can do it well, it sticks with you. Same goes for designing systems - you gotta put in the legwork to keep up to date, but it sticks around for a while. The differentiating factor is then just knowledge, that's why you've got to read a bunch. But if that's true, then what does it mean to grow as an engineer?

For me it's optimization. Optimizing the output of your team, and using all the levers at your disposal. Treat your team as a system - what changes can you make, what are you trading off, what do you get in return? Map this to the team, by introducing processes. A common one is code-reviews, but there are on-call handoffs, backlog grooming, monthly-business-reviews, user-feedback sessions, etc. Over time you build a toolbox of processes that have been tried and tested - that offer some potential to change the state space of your system. This is a valuable skill across teams, orgs, and companies. That's one way to grow.

But that doesn't absolve you of individual action. You have to wade through the dirty work sometimes. If on-call sucks, spend some time on fixing it so you have more time developing features. Weird bugs keep showing up, refactor your app so those bugs can't exist and replace them with new bugs. Find the problems that noone else is solving and get started. That's extremely fruitful as well.

A large part of that is foresight, which again requires information. Get better at predicting what could go wrong and preventing them. It's thankless, noone will care that you made sure the site didn't go down this year, because it didn't go down. It's the problem with building resilient systems - when they're resilient their robustness is taken for granted, and all the legwork to get there is often discounted. Do it anyway.

A specific element of that is the bus-risk, and speaks to the risks of not sharing context. So invest in your peers, and as you get more experienced, invest in those more junior. It pays out. You'll learn a lot from them, and hopefully they'll learn a lot from you too. But it also makes you someone that people want to work with, which is important. If it helps, an interesting thought is that seniority is just better exposure to the future, which has a ring of truth to it. So don't take your experience or seniority too seriously.

Beyond that, just have fun. I've seen a lot of engineers be performance driven, worrying about if they'll get promoted in a couple of years. It's tough to lose that mindset, and I've certainly got a tinge of that myself (maybe more), but at some point you've got to stop eating frogs.

  1. Do that dirty work: https://staysaasy.com/career/2022/09/11/Dirty-Work.html
  2. Live in the future https://www.zerobanana.com/essays/living-in-the-future/
  3. draw lots and lots of diagrams: https://engineering.atspotify.com/2022/07/software-visualization-challenge-accepted/
  4. Look at your team like a system: https://vickiboykis.com/2022/09/10/on-the-team-as-a-system/
  5. Stop eating frogs: https://experimentalhistory.substack.com/p/excuse-me-but-why-are-you-eating

Links

Your moment of Zen

Purple tomatoes with twice the shelf-life