If code reviews take too long, do this first

Short feedback loops are one of the drivers of productivity according to the DevEx model. On my team at Trello, we had a goal of all reviews being done inside 24 hours. Having that goal drove behaviors that made most reviews complete in a few hours. So, to start, collect data and get on the same page.

If your reviews are taking too long, try these enabling steps first:

  1. Gather metrics: If you use GitHub, try this repository metrics script to get a baseline.
  2. Get consensus: Nothing will happen unless the whole team is on board with this being a problem and that it can be fixed.
  3. Set a goal: I know from experience that 100% of reviews in less than 24 (work) hours is possible. If that seems out of reach, set something that you could accomplish in a quarter.
  4. Inspect outliers: Treat outliers like you would treat an outage incident.
  5. Compare reviews that met the goal to ones that didn’t: Gather statistics about PR’s and see if you can find differences between the ones that did and didn’t. For example: number of lines changed, the author, the reviewer, the number of commits, the part of the codebase, etc.
  6. Put real-time monitoring in place: If you are the lead, just do this manually to start. At the beginning of the day, make sure all of yesterday’s PRs are going to be reviewed soon.

Tomorrow, I’ll write about some common problems and what to do about them.

Network with Alums Just Ahead of You

Yesterday, I wrote about using your alumni network to make you more lucky. In most of my stories, the alumni network that was most helpful were in my year or just a bit older. They are the ones that just got a job and know what works in the current job market. They are also the most like you, so their advice is relevant. And, they know you, and like you, and so they will want to help you.

When I talk to my mentees, I keep warning them that my information is way out of date. I got my first job by looking in the classified ads in a newspaper. That ad led to a recruiter that placed junior software developers. Those parts of my story are from olden times.

But, networking with your college classmates is evergreen. The easiest way to do this is to just be a good classmate, study partner, and extra diligent when working in groups.

Alumni Networks Increase Your Luck Surface Area

When I walked into the second interview at my first job, one of the developers said: “Hi, I think you know my husband.” It turned out that her husband was a college classmate of mine. I didn’t get the lead from him (that would have been smart of me), but at least he must have said nice things when she asked (or I’m guessing I wouldn’t have been hired). It was pure luck, but I’m a big believer that Randomness is the Great Creator.

The woman who would become my wife started at that same company two years later. She was smart enough to get a referral from her alumni network, who had also gotten the job through an alum connection from a third person who had worked her alumni network to get the job through the wife of one of our executives. It was a triple-bank shot, with absolutely no chance of working, but without it, I would never have met my wife.

My luck continued. At my next job, I helped find one of our early customers, who was a prominent alum I had met because he hired a few of my friends (fellow alums of both of us). The work we did for them eventually led to a patent and getting VC money to pivot to a startup. This was more than 25 years ago, and I am still on the board and participating in their successes. More than 90% of my 2024 income came from connections I made there.

From the outside, it looks like randomness, and it is, but there are things you can do to move the odds, and networking with alums is an easy one.

Four Ways to Augment Code Coverage

Code Coverage by itself is a hard metric to use because it can be gamed, and so it will suffer more from Goodhart’s Law, which is summarized as “When a measure becomes a target, it ceases to be a good measure.” Goodhart’s Law observes that if you put pressure on people to hit a target, they will, but maybe not in the way you wanted.

And this would happen with code coverage because we can always increase coverage with either useless tests, tests of trivial functions, or tests of less valuable code.

I use these metrics in combination with coverage to make it harder to game:

  • Code Complexity: The simplest way to do this is to count the branches in a function. I use extensions in my code editor to help bring complex code to my attention. If coverage of the function is also low, I know that I can make the code less risky to change if I test it (or refactor it).
  • Usage analytics: If you tag your user analytics with the folder that the code generating it is in, you can later build reports that you can tie back to your coverage reports. See Use Heatmaps for iOS Beta Test Coverage. In that post, I used it to direct manual testing, but it would work for code coverage as well.
  • Recency of the code: To make sure that my PRs have high coverage, I use diff_cover. This makes it more likely that my tests are finding bugs in code that is going to be QA’d soon and has already been deemed valuable to write. Very old code is more likely to be working fine, so adding tests to it might not be worth it. If you find a bug in old code worth fixing, it will generate a PR (and become recent code).
  • Mutations: I am still trying to find a good tool for this, but this lets you test the quality of your assertions in addition to your coverage. I do it manually now.

Generally, the way to make a metric harder to game is to combine it with a metric that would be worse if it was gamed in ways you can predict (or have seen).

Invaders game screenshot

Play Invaders on Glitch

My nephew and I are meeting once a week to make video games. We are using Phaser (and Javascript) as our game engine and Glitch as our coding IDE.

Here’s one of our game: Invaders. Since it’s on Glitch, you can see all of the code and “remix” it into another game. In the constructor of the Invaders class there are a lot of member variables that you can can to tweak the game to your taste.

I’m sharing this because I think that to learn programming, you should Start with a Working System, not use tutorials. This is more like what real programming jobs are anyway. Once you are comfortable with what the code does, then build a new game from scratch by copying over pieces a little at a time as you need them. That’s what I did to learn Phaser. The game I used is out of date, but I’ll share my fork and update soon.

In this game, we use

  • Sprites
  • Animations
  • Sounds
  • Keyboard controls
  • Collision detection
  • The physics engine: so that we can use velocity instead of updating the positions manually

You can make a lot of games with just those basic tools.

November 2024 Blog Roundup

Whenever I am near the end of a year, I start planning for the next one. This has made me blog more than I had been in the early fall.

I wrote about planning for 2025

I’m also going to start podcasting soon, and I’m trying to find a way to bring them to YouTube

One of my major activities this year was working on my book on tech debt. I am wrapping that up and starting to think about marketing.

My next draft of the book is due on December 4, and so I will be spending most of December finding things to do while waiting for it. I hope to have some new podcasts with my major lessons learned writing it.

Practicing Doodling

I want to add videos to each my podcast episodes, so that I can post them on YouTube. One option I’m exploring is trying to sketchnote them while listening to them. This is a lot harder than I thought.

I have two problems. The first one is that I can’t do it fast enough. That’s easy to solve: I can just do it at any pace and fix it in my editor. The second is that I don’t draw well. Slowing down helps, but I just need to get better at doodling and coming up with objects to draw that represent the concept I am talking about in the podcast.

To practice, I saw Quick, Draw! on the Verbal to Visual YouTube channel. Google is training a neural net to interpret doodles, and it’s already good enough for this simple game. It gives you an object to draw, and you have 20 seconds to draw something the net recognizes as that object. When you are done, if it didn’t get your drawing, you can explore other drawings that the neural net did recognize as that object. They even let you explore the dataset of simple doodles. If you see one you like, you can tap it to see it being drawn, stroke by stroke.

I try to do it without thinking first because I want to get better at doing it live. I’m especially bad at animals. One drawback is that every prompt is an object, but I want to get better at translating verbs and concepts to visuals. I’d also love to see what people would draw for words like confusion, hunger, defiant, or tired.

Even playing for a half hour, I got much better. Not at animals, though.

Apples and Oranges are (Relatively) Easy to Compare

I don’t like stack ranking because it’s hard to compare people into a rank ordering.

One of the most surprising things I learned in math was that complex numbers had no natural ordering. Meaning, less-than and greater-than are not defined for complex numbers. It makes sense when you think of it for a minute. The same applies to other multi-dimensional things like matrices and vectors.

So, why do we think we can rank order people? I’m specifically talking about companies that do this for their employees, but it comes up in other contexts (e.g. class rank).

People are hard to compare, but when we say that it’s like comparing apples and oranges, I disagree. Apples and oranges are both fruit, they both have around the same number of calories, they are about the same size, shape, and cost. They are easy to turn into snackable pieces (slices or segments). Even for me personally, I like them both about the same. On a lot of dimensions, they are about the same. When that’s true, the comparison might turn into just a single dimension where they vary more—maybe only in specific situations.

For me, the main way they are different is in how they travel. Eating an orange is more of a mess and harder to deal with outside of my kitchen. I’m much more likely to grab an apple to throw in my hiking bag or take to the beach. Another way is in recipes. I know a lot more apple desserts than orange ones. It stands up to baking better.

But, how about apples and raisins, or apples and candy, or apples and tempeh, or apples and bicycles. Those are harder to compare because they vary on more dimensions. In the bicycle case, they don’t even share dimensions except generic ones—they are both objects that have size and weight.

Getting back to stack ranking (which I still don’t like). Inside of a team it makes no sense to me. You would have a mix of levels and experience. That mix makes the team valuable, and arbitrarily favoring a dimension hurts the mix.

Like comparing apples and oranges (which is easy), it would work better if you could remove dimensions and only compare one or two. So, for example: compare just your backend senior developers with each other on just system design skill. You could reduce the set to just those with two years at this level. This might be useful when considering a promotion. In this situation, you might value mentoring and consensus building skills more than in-depth knowledge of TypeScript. So, it’s situational (like which fruit to use for a pie) and has reduced dimensions. Another advantage is that you don’t need a full ordering to complete the task.

Video Ideas for a Podcast

I started a podcast in 2021, which has 43 episodes with writing exercises in it. I’m thinking of turning it into a YouTube channel, but I don’t want to just post the audio.

Here are some of the ideas I’ve had for adding video

  • Rerecord the podcasts with a camera pointing at me: Each of my episodes is about 5-10 minutes long, so this isn’t as bad as it seems. I also have a transcript for each one, and with my janky teleprompter setup, I might be able to pull this off.
  • Record myself sketchnoting the episode: I am not currently good at sketchnoting, but this might be a way to get better. I tried it out and it’s very hard to do this live. But, I can do it slow and fix it in my video editor.
  • Make a presentation and record it: This is probably the easiest thing I could do. I’m guessing it would also be the least successful
  • Show drawings in a presentation: This would use the drawings from the sketchnote, but instead of you watching me draw them, you see them in a deck.
  • Stylized Transcript: Normally you see this as an overlay on TikToks or shorts. It can look nice—maybe someone has made a generator.
  • AI: Just putting this here as placeholder. I’ve seen some videos that feel like they have been made by auto-generating (or matching) stock video to the audio. I hate them, but they aren’t horrible.
  • Fiverr: There are people that can make nice looking videos from audio. There are also some that look like they use AI (see above)

Of all of these, the stylized transcript appeals to me the most because I think I can write a script to do it and then I can make it look like however I want.

Leet Code at Work

I prefer work simulation questions to leet code questions for tech interviews. I like to ask interviewees to write code that is similar to what we actually did was better than, for example, finding a successor node in a BST. At Trello, our tech interview would have you refactoring code in a way that is very common in iOS or implementing a UI from a spec. At Atalasoft, we had a lot of image processing algorithms in our code base, so I wanted to see you do something simple with pixels.

The other day I was thinking about my career and trying to remember if I ever did have to code a custom algorithm given a specification, and I did come up with a few examples. I’ve written before that my career happened to have a lot of math in it, and those same jobs sometimes also needed me to implement algorithms.

But more often, I chose algorithms (or knew that I needed to). I think that’s a more universally useful skill. It’s often the case that something just isn’t fast enough. A lot of published and common implementations of algorithms work well for the general case, but you may be able to make some assumptions in your specific application that allow you to do something better. Or your particular workloads might make a different set of trade-offs more appropriate.

To do this, it’s good to have broad knowledge of a bunch of choices, just so you know what techniques might be possible. These days, I think AI can help you a lot with this, but it helps to know what to ask for and when to ask for it.