If Benjamin Franklin could record how he did with his thirteen virtues every day, so can you and I.
#2: DebuggingWhen code doesn’t work as expected, we debug it, often as detailed as stepping through every statement.
“Debugging” is very powerful, but also very expensive.
We do it for the code because we need to get the code to work, but we often ignore it for our lives.
Debugging requires self-awareness, intentionality, and the desire to level up.
Next time when you make a mistake, or you wish that you could have done something better, try to sit down and carve out time to “debug” the process.
Go through what happened step by step, examine what you did and why, figure out the “bugs,” and take action to improve for the next time.
Debugging is useful for both personal life and professional events.
For example, at Medium, we run post-mortem meetings for site incidents, we write RCA (Root Cause Analysis) for major bugs, and we run project retro after a project has shipped.
In these settings, we first investigate the reality and list what happened, and then we ask ourselves a lot of “whys.
” Every time we’ve done this, we learned a ton.
#3: Design PatternsDesign patterns for software are tested and reusable solutions to commonly occurring problems.
Good design patterns not only speed up your work but also teach you how to think about software designs.
There are many types of design patterns in different contexts.
The classic example is the book Design Patterns: Elements of Reusable Object-Oriented Software.
We could apply similar ideas to life and work as well.
A lot of great books and articles summarize how authors repeatedly solved real-world problems and the lessons they learned.
We can collect these patterns and evolve them for our own use.
What is beautiful about these books and articles is that the authors spent years and years solving problems and writing about their patterns of solutions and lessons, and we can spend a relatively small amount of money and time and save ourselves years of trials and making the same mistakes.
I can’t think of a better investment than that.
The approach I found useful is to have a personal library of problem-solving patterns — a written collection of real problems you encountered and the patterns you learned, tried, and adjusted for yourself.
If you struggle to find a good solution for repeated problems, read relevant books and look for advice, then add them into your library.
#4: Open SourcingMost of us have used open source code; some of us have even open-sourced our own code.
Open source is great because it lets us learn from others, get feedback on our own work, and benefit from the work of others.
Many of the most influential software projects in the world wouldn’t have existed without the benefits of open source.
Wouldn’t it be wonderful if we could “open source” our thoughts as well?.Writing is a great way, and probably the only scalable way, to open source our thoughts.
Writing helps us clarify our thoughts, think better and more deeply, get feedback from others, and inspire others.
Open sourcing code enables us to build better software together.
Similarly, writing and sharing create a network of ideas that feed off each other, so we can move our thinking forward together.
#5: Using FrameworksWhen we code, we use a lot of frameworks.
Nobody would build a complex software system from scratch.
Good frameworks provide common foundations and suggest best practices, so we can focus on the unique business logic.
Great frameworks even make us rethink programming.
Frameworks for thinking are equally important.
They simplify our thought processes and help us focus on our unique goals, so we can make better decisions faster.
Thinking frameworks are often generic — they can apply to many different scenarios without losing value.
Take Stephen Covey’s four-quadrant framework of time management as an example.
It teaches us to focus on important but not necessarily urgent things, like planning, exercise, or self-improvement, which are often de-prioritized because they are not urgent.
If we apply this framework to software engineering, production bugs are urgent and important (Quadrant #1), whereas automated testing and tools are important but not urgent (Quadrant #2).
We should invest in better testing and tools, so we will have fewer bugs in the long run, and we can spend time on more important things.
Building frameworks for thinking is beneficial and fun.
If you observe patterns across different disciplines, try to abstract the similarities, peel off specifics, and build a framework.
This type of synergistic thinking helps you understand the world better and more deeply, and likely you will find the framework can apply to many other areas you hadn’t even thought about.
It inspires creativity.
#6: CommentingWe all try to write code that is easy to understand.
Good code should be readable and tell what it does.
Do we still need comments then?.Yes, we do, because comments tell us“why.
” No matter how good the code is, it cannot always explain why it is being written in certain ways, or be compared with alternative solutions.
Similarly, it’s very important to “comment” on the things we do with thoughtful communication.
People can observe what we do and how we do it, but they do not always understand why we do it or why we do it in certain ways.
Without knowing the why, people may get confused, defensive, or even misunderstand what we do; however, once they know the why, they become supportive, encouraging, and even get inspired.
Thinking about and articulating the why helps ourselves as well.
Maybe there are better alternative ways of doing it, or maybe we have other more important things to do first.
#7: LoggingLogging is a common practice to track important events or message exchanges when a software system runs, so we can go back to understand its execution or triage issues.
Without logging, troubleshooting production issues become extremely difficult if not impossible.
Just like logging in code, writing down the major events, decisions, successes, lessons, etc.
in your life and work could be tremendously useful.
It doesn’t mean you have to write a 500-word diary every day.
The life logs could be just a few sentences each time.
The key is to build a habit of writing them and looking back regularly.
I keep a personal log with the Day One App and a work log in Evernote.
I’m always amazed by how much I learn just by reflecting on my past self.
#8: TestingAfter you write some code, how do you know it works?.You may think that’s easy — you can test the code.
Testing has been widely adopted to improve code quality.
We invented tools and frameworks to make testing easier.
The Extreme Programming (XP) practices suggest writing test cases even before implementing the code, which is called TDD (testing-driven development).
It might not be always possible to live a “test-driven life.
” When we need to make a decision, how can we know we are making the right decisions?Rather than thinking, ‘I’m right,’ I started to ask myself, ‘How do I know I’m right?’” — Ray Dalio, the author of PrinciplesAlthough it is often difficult to fully test an idea or a decision before it is applied to real life, we could at least test it by the principles that reflect our fundamental beliefs, what we learned from the past, and what we learned from others.
We could also test it by asking for feedback from people who are believable.
If a decision passes this test, we should at least know it is good enough that we can live with the consequences.
If you want to get inspired by principles in life and work, I highly recommend Ray Dalio’s book, Principles.
#9: Style GuideIn coding, we often create opinionated style guides to make code looks consistent.
Sometimes style guides also suggest best practices, but most importantly, they save debates about how to format code, which are usually the most contentious but the least consequential topics.
In life, we also need to make decisions about many trivial topics.
Obviously different people trivialize different things—what to wear, what to eat, which path to take to commute, etc.
They are all small things, but mental energy spent on these topics adds up.
Making consistent decisions upfront on these topics helps us focus on more important things.
For example, Steve Jobs wearing the same clothes every day is akin to a programmer choosing tabs over spaces for every indent.
Life is a way more complex system than software.
It is easy to get caught up in the blizzard of things coming at us in life.
Take a step back and observe ourselves and surroundings objectively at a higher level.
This higher-level perspective allows us to use our engineering skills to figure how things fit together, identify and diagnose problems, improve the system, and finally achieve our goals.
Remember, we are also engineers to our lives.
Can you think of other things that we do with code but not with ourselves as often?.Write a response!P.
This post is a revised version of a post I wrote in 2015.
I want to thank Wanmin Wu for always patiently listening to me when I talk about random stuff and inspiring me with her thoughts.
Thank Dan Pupius, Jean Hsu, Evan Hansen, Herzog for letting me bounce ideas off them.
Thanks to many for their great responses to my original post, especially Ryan Huang and Buster Benson, from whom I borrowed some ideas.