In February, an engineer I’d managed for over a year moved to a new team. In one of our last 1:1s, I mentioned that he’d recently done some good project management. He replied that he’d had an epiphany about self-direction; he’d decided that he needed to own everything about his work, not just his code, to make sure his projects succeeded. I was impressed with him and, instantly, disappointed in myself — I’d long considered ownership the most important thing for young engineers to learn, but I’d somehow left this engineer to discover that for himself.

I decided then to write up the practices that I think lift a newly minted software engineer from amateur to professional: the path from fixing bugs as an “Engineer 1” to leading major projects as a “Senior Engineer.”

I firmly believe that those skills can be taught, but for my part, I learned the ideas you’ll read below The Hard Way over ten years in Silicon Valley. I’ve covered some ground in that decade; I hacked on the kernel at a well known fruit company in Cupertino for six years, threw away everything I knew to pursue an interest in distributed systems, spent a year at a startup that became a Unicorn and was subsequently acquired (AppDynamics), became a manager, ended up managing over 20 people at Uber, and eventually returned to my roots as an programmer. I hope that reading this list, however incomplete it may be, saves you some of the mistakes that educated me; I sure wish someone had sent it to me when I was 22.