20,000 hours as a Software Engineer
Malcolm Gladwell said that to master anything, you need to spend at least 10000 hours doing it. As I look back to my career, I have in theory clocked more than double. And although it’s easy to multiply 250 days of work per year by 12 years, I have in the past said that this is a fallacy. There were years that were a repetition of previous ones. But this begs the question, what have I learned since 2010? What could I possibly recommend to people new to the field?
- Spend time reading technical documents. I have wasted many hours trying to bang something together, until I found that what I was doing didn’t make any sense. It’s not a surprise this has a dedicated wikipedia page.
- Theory only takes you so far. You can read as much as you want about swimming. Its history, the faster swimmers, technique and what not. But until you actually do it, you won’t know how to swim. Documents will only take you so far. You need to build things to get an intuition on how they work.
- The best way to get better at coding is to code. The same way the best way to get better at reading, is by reading. There are some shortcuts and mentorship makes a huge difference, but nothing replaces hard work.
- Be tidy. Keep variable names meaningful, the same with functions and classes. Don’t be afraid of leaving a comment. So the next time you go to that piece of code, you immediately understand what’s going on. Keep things separate by modules, or packages. Try to reuse things when it makes sense. These will save you time.
- Surround yourself with people better than you. This seems obvious, but people that lack confidence are resistant to this idea. In previous jobs, I was concerned about hiring someone better than me. That they could replace me. Guess what happened? I learned a lot from them and continued doing my job. “A players hire A players. B players hire C players”.
- At some point, you will look at the shape of code and see if it makes sense or not. This is a weird thing to explain, but with Swift I am able to have a glimpse about a method shape - with ifs, fors, switches, closures - and know if something is out of place or not. After thousands of hours, your brain will expect a particular shape.
- We spend more time reading than writing code. This happens with others’ code, but also with your own after a couple of weeks without touching it. Don’t try to be fancy, just because you read about it. An example could be recursion, when you are used to for loops. The next time you look at that piece of code, you might take longer to understand what it does. The flip side is that to learn new things you need to try them out.
- Simple is not the same as easy. Easy can lead to a long term maintenance nightmare. This was obvious to me when chaining tasks. For example, you want to make multiple requests, parse the response, cache them and wait until all these requests are done. In the past, doing this in iOS with Swift was a nightmare. The best way to go about it was to use RxSwift or ReactiveSwift to achieve it. It was trivial to do this with one of those frameworks. But for the untrained engineer, this was quite hard, but the benefits were tremendous. It was simple, but not easy.
- The DRY principle can sometimes lead you to bad places. I found myself over generalising a function, so that it could be used from multiple places. This leads to a bloated, unmaintainable, unreadable piece of code.
- 10x engineers exist. But they don’t always operate at 10x. Environment, team and goals play a massive role in this ratio. Because these influence drive and motivation. Rarely I found an engineer that I thought: this person shouldn’t be in this industry. So the same factors that influence a 10x engineer will also affect a 1x engineer. There’s definitely natural born talent and there’s little that one can do, besides putting more effort.
- Avoid external dependencies. These usually bring stuff that it’s irrelevant to you, so it bloats your app. You can always either build it yourself, or use only a slice of a dependency. If you do the latter, make sure you respect the license.
- Pull Requests are the opportunity for you to show off your work to the team. Don’t treat it like an afterthought. Explain why you did those changes, rather than the what. The “what” are your code changes - people can just read them. The why provides the necessary context. Pull Requests without any comment, or description, rarely have a reason to exist. Be respectful of your teammates’ time. The same applies to the size. Keep things small, the longer it is, the longer it will take to review and to merge. Again, be respectful of your teammates’ time.
- Expose yourself to every part of the stack. Try to do some frontend, backend, mobile, devops. It’s difficult to do all this in a professional context. Most companies value specialists over generalists. As a fronted engineer, you should know a bit of the backend, so you can empathize with their challenges and vice-versa. I have seen a lot of disdain by backend engineers towards frontend and mobile. I think about this quote, when I read people saying that it’s not real engineering: “You can’t understand someone until you’ve walked a mile in their shoes”.
- “Snacking” is something you should be aware of. It happens when you are avoiding a harder or boring tasks, so you just spend time on short, easy tasks. It tends to happen when you reach more senior roles and your manager doesn’t oversee you as much. Which leads to…
- … at higher levels, you are supposed to find your own work. You are supposed to look for opportunities, prioritise them and either execute them by yourself, or champion them. Senior engineers when promoted to Staff or Principle struggle with this. Because they are used to work being dropped in their laps. If you have been promoted to Staff Engineer and you are doing the same job as a Senior, but with a bigger paycheck, you are still a Senior.
- After a while, you understand that engineering is about people and less about code. Translating requirements into actual code is a skill. Reading between the lines is a skill. Dealing with an inexperienced Product Manager and delivering a working feature is a skill. These are more valuable than being good at producing code. “Hardcore” engineers will scorn at this, but let the market be the judge of that.
- Writing a good CV and being good at interviews has no correlation with your ability as a software engineer. It’s the same as comparing the freestyle football champion with Messi. These are completely different sports, they just so happen to use a ball. The good thing is that you can get good at interviewing.
- The above is also true about startups versus big tech. Being successful in one, doesn’t mean you will be in the other. The dynamics are completely different.
- Don’t feel bad if you use something like Source Tree, or VSCode, instead of CLI Git or Vim. Use whatever makes you productive. Get good with the stuff you are comfortable with. Being judged by the tools you use says more about the other person than of you.
- Improving your writing is one of the best things you can do. Any person interacting with you, whatever their role, will appreciate clean, concise writing. Beyond that, writing is thinking. When you put into paper your thoughts, you see hidden things. A good example is when you start writing a question on Stackoverflow and before you post it, you know the answer. If you don’t know what to write about, keep a weekly work diary. Write every week about what you did, your high and low points.