A TLDR of The Effective Engineer by Edmond Lau
Before starting my internship this summer at Bluecore, I was given this book to read by the team. Instead of just reading through it and probably forgetting most of it within a month, I wanted to do a type of book report. Writing down the key ideas and condensing the information into my own words helps with retaining information. We learned about this strategy in my overview of Learning How to Learn on how chunking helps make things stick.
Part 1 - Adopt the Right Mindsets
In the first part of the book, Lau focuses on how you, the individual, can increase your value creation.
Focus on High-Leverage Activities
Here Lau debunks the myth of the startup or company where engineers work 70-90 hours a week in order to be successful. Instead of pure hours worked, Lau explains how you should instead focus only on high leverage activities
Use Leverage as Your Yardstick for Effectiveness
Leverage = Impact Produced / Time Invested
80-20 Rule: 80% of your impact will come from 20% of your time. Find what that 20% is! Hint: It’s not going through your emails or sitting in meetings.
1 hour each day for 20 days is only 1% of an engineer’s yearly hours worked. Yet, 1 hour each day for the first 20 days of an engineer’s job can snowball tha learning into massive leverage gains later on.
Three ways to Increase Leverage
- Reduce the time it takes to complete an activity
- Increase the output of an activity
- Shift focus to a higher leverage activity
Here are a few tips to accomplish the above:
- Condense meetings into 30 minutes instead of a half hour
- Prepare an agenda for meetings to streamline them
- Replace non-important meetings with emails
- Automate parts of your development or testing workflow
- Focus on launch critical tasks
- Use profiling tools to instantly know where bottlenecks are versus using time finding them
Focus on Leverage Points, not Just Easy Wins
People think the Leverage equation can be gained by just focusing on a ton of ‘low-hanging’ fruit. This is wrong as a bunch of small wins will still be eclipsed by large, critical, high impact tasks.
Tims is like money. You want to invest it in what will give the biggest return. You wouldn’t use your days going around collecting quarters off the street. Instead, invest into things with high payouts.
Optimize for Learning
Learning is the single most important investment you can make in yourself (except maybe health and fitness but there are other books on that). Figure out how to optimize your time so you are learning as quickly and early as possible as knowledge is like money: it has compound interest.
A big factor in deciding to work somehwere is if you think you will be challenged enough to always be learning.
Adopt a Growth Mindset
Be a Yes Man to learning opportunities. I actually did this with my life a few years ago (say yes to everything) and it really does change your life.
Force yourself to believe that you can always learn new things and skills and that belief will actually get you to to partake in activities that foster growth.
Invest in Your Rate of Learning
Learning is like money: it is affected by compound interst.
Invest early and invest in high return knowledge (things that will make more future learning easier). For me, this is math as many of the things I want to do require a solid foundation in Mathematics.
Seek Work Conducive to Learning
We spend most of our waking hours as work. You should find ways to learn while at work.
Below are criteria you should be measuring when deciding where to work:
- Fast Growth: is the company growing fast or just kinda floating along?
- Training: the company should offer extensive training opportunities (not just for new hires!)
- Openness: Different teams should not be isolated and closed off
- Pace: you should be able to get things done quickly and not get bogged down by miles of red tape
- People: never be the smartest person in the room
- Autonomy: you should have some freedom and say in what you really want to work on
Dedicate Work Time for Learning
Google’s 20% Time: Engineers get one day a week to work on whatever side project they think will help the company in the long run.
Ten suggestions on how to learn on the job:
- Study other’s code
- Write more code
- Go through internal technical documentation
- Master your most used programming language
- Ask for code reviews from the harshest critics
- Enroll in classes (even in nearby University)
- Participate in design meetings
- Work on diverse projects (Interleaving from Learning How to Learn anyone??)
- Make sure your team has at least one engineer more senior than you so you can learn
- Jump into new code bases without fear
Always be Learning
You should also be learning outside of work. Even learning in other disciplines can trickle over to better work performance.
Here are ten ways to learn:
- Learn new programming languages and frameworks
- Invest in high demand skills (future proofing)
- Read books (checkout Books2Rec for recommendations!)
- Join discussion groups or book clubs
- Attend meetups, talks, and conferences or even just watch them online
- Network and maintain relationships
- Follow bloggers that share great knowledge
- Write to teach. Trying to teach others is by far the best way to learn material yourself. This is my inspiration for this blog!
- Work on side projects
- Pursue what you love. Don’t waste time on TV, web surfing, or social media
Success of your company or yourself requires prioritizing the things that actually matter. Prioritizing is a skill like all others. You can get better at figuring out what is important and also estimating how long things will take.
I use Google Calendar and Google Tasks to track everyting I have to and want to do every day and week. There are thousands of apps that do this or even just keep a journal.
Learning How to Learn also showed us the importance of writing down To-Dos. Our working memory is a very limited cache so writing things down helps us clear out our cache for more in the moment things and doesn’t let us forget future things to do.
You should also learn to assign priority and estimated time to your to-do items. Don’t just brain dump them. Tomorrow you will have to use time to sort through it all!
Focus on what Directly Produces Value
There are an infinite amount of things you can do at this moment. However, you should do that things that produce the most value.
A good example Lau provided is saving money. Many people say you should skip the Starbucks $4 coffee every morning as this will save X amount of money a year. However, there are other, shorter (not easier) ways that will save MORE money.
- Spending an hour or two researching cheaper high expense items like hotel rooms or tickets can save hundreds of dollars.
- Optimizing your stock and savings into higher return accounts will generate more money than saving on coffee every morning.
- Negotiating a higher salary can net you tens of thousands of dollars a year for a day’s worth of extra effort.
Of course, saving $4 a day on coffee is still helpful but always look for bigger value items first to tackle!
Focus on the Important and Non-Urgent
This is the famous Qudrant chart.
The lesson is that Important and Non-Urgent is JUST AS HIGH PRIORITY as Urgent and Important.
Protect Your Maker’s Schedule
Engineers need long, uninterupted blocks of time to get things done. Limit your interuptions and make it known you need blocks of ‘do not disturb’ time. This is why working from home can be very helpful.
Limit Amount of Work in Progress
Our working memory can store 7 +/- 2 chunks. If you have 20 ‘In Progress’ tickets in JIRA, something is wrong. Limit this to 2 or 3.
My Learning How to Learn post has valuable information on this topic, much of which is repeated in this chapter of the book.
One new piece of advice is to form a plan of when you will do things in the future. The simple fact of planning our future blocks of time to work on something will actually make you 2-3x more likely to do it.
Make a Routine
Use the Pomodoro Technique to split up your day into 25 minute productive chunks. Aim to maximize how many Pomodoro blocks you complete each day for high leverage work (25 minutes of answering emails does not count).
Split up your To-Do list into a ‘Doing’, ‘Today’, and ‘This Week’ sections and shuffle things from one to the next each day. Only assign as many things as can realistically get done per day.
Part 2 - Execute, Execute, Execute
Part 2 explains how an engineer can actually get stuff done.
Invest in Iteration Speed
Companies are starting to realize that pushing dozens of code changes every day is better than a few large code changes every week or month. Setting up a workflow that allows for this constant iteration is crucial to surviving in today’s fast paced tech scene.
Move Fast to Learn Fast
‘Move Fast and Break Things’ - Facebook mantra. It’s better to move fast and learn from failures quickly than taking it too slow and not taking enough risks. It’s easier to roll back changes and new features than to push dozens of them instantly.
Invest in Time Saving Tools
One way to save time is to create tools that automate of speed up repetetive processes. Even though this slows you down at first, over the long run, it will save more time.
Another technique to save time is to prototype in high level languages like Python. Only use low level languages once you have the prototypes done and approved.
Shorten Your Debugging and Validation Loops
Create code that drops you right into the buggy pieces of code so you can work on debugging them rather than wasting time repeatedly getting back to the bugged code. This example is highlighted with working with CSS styling for specific web pages. Code up a shortcut to take you right to the page you are styling rather than clicking from the login page everytime.
Master Your Programming Environment
- Get proficient with your favorite text editor or IDE
- Learn at least one high-level language that can be used to prototype ideas (Python)
- Get familiar with shell commands (Unix shell). This is VERY important.
- Prefer keyboard shortcuts over the mouse
- Automate your manual workflows. If you’ve done something the same way twice, automate it for the third time.
- Test ideas in an interpretable language and not in one that requires code compilation (C, C++, Java)
- Make running unit tests insanely easy and fast by making Make files.
Don’t Ignore Non-Engineering Bottlenecks
Here are a few bottlenecks that can occur and slow down engineering:
- Waiting on other people to get things you need (ie Photoshop images from Design Team). Solve this with constant communication with your PM and updating them with what you need.
- Obtaining approval from higher-ups. This is hard to solve and should be avoided in the engineering culture.
- Review processes (QA). Do not wait to QA all your work at the last minute. QA should happen in real time alongside development.
Measure What You Want to Improve
You need to convert certain goals into numeric values in order to measure them. It’s hard finding what to measure. For example, Google figured out that clicks was not a good thing to measure but the time a user spent in a result page offered by search before returning to research was a great metric.
Use Metrics to Drive Progress
Metrics provide the following pros:
- They help you stay focused on the right things
- When visualized over time, they help prevent future regressions by pinpointing what changes caused them.
- Good metrics drive progress forward at all times (assuming they the metrics are increasing).
- Metrics let you measure effectiveness of what you are spending time on and allow you to compare the value of doing other things.
Pick the Right Metric
Metrics need to satisfy the folliwing 3 properties:
- Metrics need to maximize impact
- Metrics need to be actionable. They should provide info that you can make changes on to respond to. They should not be vague.
- Metrics need to be responsive. You need to pick a metric that will respond to a change made today so you can measure it.
Instrument Everything to Understand What’s Going On
You should be measuring EVERYTHING in your company. Not doing this will result in scrambling to figure out why some crucial service died. Large companies can afford to build custom in house software to do this, but there are many third-party measuring software that any tech company can purchase.
Internalize Useful Numbers
Know your numbers! This applies to finance as it does to the technology companies. Knowing your numbers is like knowing your health vitals. Here are a few numbers to always know:
- Number of registered users and number of active users
- Amount and total data capacity
- Amount of data read/written every day
- Number of servers a single service takes up
- Throughput of services or endpoints
- Growth rate of traffic
- Page load time (average, per browser, etc)
- Traffic distribution accross different pages or services
- Distribution accross devices and OS’s
Be Skeptical of Data Integrity
Statistics can lie and liars use statistics. Never blindly trust data. Here are a few ways to increase the trustworthiness of your data:
- Log as much data as you can
- Build tools that assist data accuracy earlier rather than later
- Write integration tests to ensure data quality has not worsened
- Examine data soon after it’s collected rather than next week when its needed
- Use cross validation (compute the same metric using different pieces of the data)
- If your gut tells you a number looks off, it usually is. Investigate!
Validate Your Ideas Early and Often
Optimize for feeback earlier. Don’t spend a year working on a product only to have the end users hate it.
Find Low Effort Ways to Validate Your Work
Create a MVP (Minimum Viable Product) and use this to gather feedback and make changes. Spend the first 10% of your time creating it. This will save massive amounts of time compared to changing features of the final product that took 50% of your time to create.
Validate Product Changes with A/B Testing
A/B testing is when you show a percentage of users one version of the product and the other percentage a control version. You only make changes if the changed version responded with better metrics. A/B testing is a critical part of all of the largest tech companies and it not going anywhere soon. It essentially allows you to use statistics on subjective feedback, something that is traditionally not possible.
Beware the One Person Team
Try to avoid having a single person be responsible for an entire feature or product. However, this is sometimes not possible to avoid. Here are some tips to help this not blow up your company if that person gets run over by a bus:
- Be open to feedback
- Commit code early and often
- Request code reviews from the toughest reviewers
- Bounce ideas off diverse range of teammates
- Have people review design docs before wasting time coding things up
- Structure projects so different teammates have responsibility for different pieces
- Get end-user buy in before implementing features
Build Feedback Loops for Your Decisions
Rather than making an important decision and moving on, set up a feedback loop that enables you to collect data and measure how valuable your work has been up to this point.
Improve Your Project Estimation Skills
44% of projects are delivered late, overbudget, or without key requirements. 24% never complete at all 79% is the average time a overrun project exceeds its initial estimation
Use Accurate Estimations to Drive Project Planning
- Decompose the project into granular tasks (not one mega ticket)
- Estimate on how long a task will take, not how long you desire it to be done in
- Estimates are probability distributions. The actual time to complete will be under or over the mean time you have picked (assuming you perfectly picked the mean to begin with!)
- Always have the person responsible for the task actually make the estimate
- Beware the mythical man-month. Adding an engineer to a one person team does not double the speed of the project. Adding bodies does not follow a linear curve.
- Use historical data to fine tune your estimates for future projects. If you always underestimate, add time to this projects estimates.
- Don’t let features keep growing in time
- Allow others to challenge estimates and don’t make them afraid to speak up
Budget for the Unknown
There will always be things you can’t predict that will eat up at your time. Always budget extra time for these unknowns and budget more ‘unknown’ time for longer projects.
Define Specific Goals and Milestones
As with using metrics to measure the value of a product, you can use goals and milestones to measure the growth and value of a development project. Goals and milestones also help with not feeling burnt out.
Reduce Risk Early
Always tackle the hardest and riskiest features first. You don’t want to complete 9/10 easy features and then realize the 10th is not doable and have to scrap the project.
Beware Project Rewrites
Engineers are always thinking a rewrite will be easy, quick, and much much better than what already exists. 99% of the time they are wrong.
Don’t Sprint in the Middle of a Marathon
Only do a spring or crunch if the end is actually near. If you sprint in the middle of a project, you are dooming your team and will not be able to finish. Here are a few facts to keep in mind:
- Productiviy of a single hour decreases as you work more hours
- You are more behing schedule than you think you are. This is especially true in the early stages
- More hours can leas to burn out
- Working more hours can lead to team members resenting each other
- Communication will ramp up as deadlines approach and this can lead to bottlenecks and overhead
- Sprinting and crunch times increase technical debt
Part 3 - Build Long-Term Value
Companies are trying to maximize profit and revenue in the long run, not just for this year. There are many tips and tricks to maximize value in the long-term.
Build Quality with Pragmatism
Software quality is always a trade off between actually getting things done and having solid, bug free code. Large companies like Google can get away with insanely difficult code standards to achieve while this level of confinement would cripple any start up that needs to get a product up and running.
Establish Sustainable Code Review Process
Code reviews should be present in any tech company. Here are a few reasons why:
- Code reviews catch bugs and design flaws early
- Knowing you have to be reviewed makes you less likely to commit quick and dirty code
- Allows others to see what the company’s code standards are
- Distributes the knowledge of the code base to others
- Increases long term agility because the code base won’t be riddled with bugs
Manage Complexity Through Abstraction
Eventually, you will want to do things that are so advanced, you can’t expect single engineers to recreate the entire code needed. Just as we don’t all code in Assembly, we want to abstract as many things as possible. A great example is the Google File System (that turned into Hadoop). This abstraction of running algorithms on distributed data allowed engineers to focus on writing algorithms rather than managing the insanely complex intracacies of distributed data.
Automating testing allows you to keep developing without the fear that your changes are breaking existing features. Spend time setting up large scale and comprehensive testing scripts that cover most of your code and features.
Repay Technical Debt
Eventually techincal debt needs to be dealt with. However, you can pick and choose which debts to pay off. LinkedIn for example spent months after going public freezing all code changes and only fixing technical debt in the code base.
Minimize Operational Burden
Avoid tech or tools that will create headaches later on. Use stable and trusted software to build your products with. Keep it simple stupid!
Embrace Operational Simplicity
Always keep things simple. Here are a few things that happen if you don’t:
- Engineering expertise gets splintered accross multiple systems
- More complex pieces of the puzzle introduce more points of failure
- New engineers will take longer to get up to speed
- Complexity takes time away from testing, abstraction, etc
Build Systems to Fail Fast
Failing fast is actually preferable to staying alive after a problem has occured. This doesn’t seem to make sense but this actually lets you solve the real issues as they occur rather than after they have corrupter other parts of the product. Always deal with critical errors as they occur and don’t let them slip by undercover for weeks or months.
Relentlessly Automate Mechanical Tasks
Here are a few things that should be automated (versus doing manually):
- Validating code or running tests
- ETL of data
- Detecting error rate spikes
- Deploying software to new machines
- Restoring database snapshots
- Running batch computations
- Restarting a web service
- Checking code styles (use a linter)
- Training machine learning models
- Managing user accounts and data
- Removing or adding servers to services
Make Batch Process Idempotent
Idempotent: running the same script over and over, no matter how many times, gives back the same results. This is the same idea as non-mutable code. You shouldn’t have your state affected by running something. This makes it harder to track down errors.
Be Able to Respond and Recover Quickly
Create a Chaos Monkey: a piece of software the creates havoc in your systems, brining services down and other pieces of infrastructure. This allows you to know how to support your products even with individual pieces going down. All of the major tech companies now use Chaos Monkeys to test their products. It’s better to fail in a test environment than in the real world.
Invest in Your Team’s Growth
Your individual success comes from how successful your company is and your company’s success stems from how successful all of the individual workers are. This creates a nice Game Theory environment where it’s in everyone’s interest to help each other and the company.
Make Hiriing Everyone’s Responsibility
Hiring might be one of the most critical parts of your company’s long term health. Hiring is responsible for who is working on and developing all the things that need to be done. Also, hiriing is responsible for who your teammates will be so hiring should be everyone’s priority.
Design a Good Onboarding Process
Onboarding is critical to getting new hires up to speed and productive. Every hour they aren’t onboarded is a loss to the company’s bottom line. Here are 4 goals all onboarding processes should accomplish:
- Ramp up new engineers as quickly as possible
- Impart the team’s culture and values so everyone is on the same page
- Get new engineers to master the fundementals critical to this company’s products and tools
- Get new engineers socially integrated with exisiting team members
Mentorship is also a widely used and effective onboarding technique.
Share Ownership of Code
Sharing ownership of code helps team moral and also prevents projects from being derailed if an employee leaves or is hit by a bus. Here are some ways to increase code ownership:
- Avoid one person teams
- Do code reviews
- Rotate tasks around the team
- Keep code quality high. It’s easy to own code if you can know what it does quickly
- Do tech talks and show and tells
- DOCUMENT CODE!!
- Document workflows and non-obvious things to do to get things working
- Have mentors
Build Collective Wisdom Through Post-Mortems
It’s easy to pat yourself on the back after a successful launch and to glow in the praise, but you actually learn more from dissecting what went wrong on a failed project. Set aside your ego and talk about it.
Build a Great Engineering Culture
People want to work at places with good culture. Here are what the best of the best are looking for in a company:
- High iteration speed companies. Engineers don’t want to wait a month to push one feature
- High value for automation
- Great abstractions for complicated services
- High code quality
- Respectful work environment
- Shared ownership of code
- Automated testing and solid QA
- Allow for expirimentation time (hackathons or 20% time)
- Foster a high learning environment
- Tough hiring standards. People will want to work with others they know got through the gauntlet.