Last month we finished reading “The Effective Engineer” by Edmond Lau in the book club at work. It is a great book full of practical advice on how to get more done as a software developer. In fact, it is one of the three books I think all programmers would benefit from reading (the other two are Code Complete and The Pragmatic Programmer).
Code Complete is all about how to write good code, with advice on code layout, naming, if-statements, functions etc (Clean Code is almost as good in this respect). The Pragmatic Programmer zooms out a bit, and includes tips on the development environment, tools, testing and requirements (in addition to coding tips). The Effective Engineer zooms out even further – there is no code in it. But is still contains a lot of practical advice.
In the introduction, the author describes how he regularly worked 60 hours a week at the beginning of his career. After a while he started to question the wisdom of this, and looked for better ways of working. The whole book is an answer to how you can increase your impact without working longer and longer hours.
This is a short book, only about 200 pages (excluding appendix and notes), but the density of good content is very high. It is divided into three parts, each containing three or four short chapters, where each chapter ends with a good summary of the key points. The first part deals mostly with what to work on. The short answer is activities that give you the most bang for the buck. The second part is on how to work, and deals with iteration speed, measurements, fast feedback and project management. The third part is called Build Long-Term Value, and is mostly about team work and dev ops.
What I Liked The Most
High-leverage activities. A key concept in the book – focus your effort where the impact produced, divided by time invested, is the highest. There are numerous examples of this throughout the book. For example, creating a strong onboarding program for new engineers amplifies your efforts, since all new hires become productive faster, year after year.
Optimize for learning. Examples: master your programming language, work on a diversity of projects, jump into code you don’t know, read books, attend meetups and conferences, write to teach. If you improve just 1% every day, you will become 37 times better in a year.
Invest in time-saving tools. Learning editor/IDE shortcuts, configuring automatic reload on changes, writing scripts for repetitive tasks etc are small improvements that together can add up to large gains. Furthermore, when activities are faster and easier, they get done more often, and can sometimes enable new workflows that weren’t previously possible, such as continuous deployment.
Continuous deployment. The primary advantage is risk reduction. Instead of deploying a batch of changes every three weeks, you can deploy many times a day. That means that each change is small, so it is easier to pinpoint what change caused a problem. It is also easier to fix or roll back when each change is small. In addition, it makes it easier to experiment in order to learn more quickly.
Shorten the debugging loop. When debugging or testing code, we should use our abilities as developers to shortcut normal system behavior. For example, instead of clicking through a workflow, we could use an URL parameter, set a cookie, or modify some code in order to go straight to the buggy state. Having a tight feedback loop when debugging or testing changes makes a big difference.
Re-write project example from Ooyala. In the chapter on project estimation, there is an example of a project to re-write a video player. I always like reading case studies, and the video player re-write nicely illustrates many of the pitfalls in real software projects, such as inaccurate estimates, scope creep and competing priorities.
Don’t sprint in the middle of a marathon. When you are behind schedule and a deadline looms, it is tempting to start working more hours. But the author lists several reasons why this may not help, for example: hourly productivity decreases with additional hours, you are probably more behind schedule than you think, you incentivize technical debt, you risk burning out etc.
Recovery over prevention. Preventing bugs eventually produces diminishing returns. At that point, it makes more sense to invest time and energy in making sure you can recover quickly from failures, instead of doing more to prevent failures in the first place.
Automate mechanics, not decision making. In operations, relentlessly automate mechanical tasks, such as building and deploying software, restarting a service, capturing and restoring a database snapshot etc. However, tasks that require making a decision, such as when to failover to another server, are often better left to a human. This is because it can be hard to get this logic right, since it is hard to test and happens rarely, and it can often make matters worse (e.g. rebalancing to remaining servers overloads those servers).
Make batch processes idempotent. If a batch script fails, it should be possible to re-run it without causing problems. This is possible if it is without side-effects, such as holding onto a global lock, double-counting values or corrupting an output file. If it is idempotent, you can safely re-run it if it failed, which helps enormously when trying to find out why it crashed in the first place. Also, it should be possible to manually run periodic scripts (for example monthly jobs) more frequently for testing purposes, without causing problems.
What I listed above where the parts I liked the most. There were many more subjects covered, for example code reviews, A/B testing and onboarding of new engineers. I can’t recall anything that I actually disagreed with.
Throughout the book there are many quotes from people from various famous Silicon Valley companies. There are also references to several well-known books and concepts. For example, in the chapter on prioritizing, the following are mentioned: Getting Things Done, The 7 Habits of Highly Effective People, Maker’s Schedule Manager’s Schedule, limit work in progress. So many of the ideas aren’t new or unique, but they are summarized in a useful way, and the examples are relevant to programmers.
I really liked The Effective Engineer. It is full of practical advice that is relevant and useful to most programmers. It deserves to be better known than it is. If you haven’t read it, check it out!