When we first start our careers as software engineers, we tend to focus on improving our coding skills, a.k.a. technical skills, including but not limited to: mastering a specific tech stack, adopting best practices, and studying architecture designs. But there is another side that is just as important: gaining the domain knowledge and forming a long-term vision for your team, product, and company.
I’m leading a multi-quarter project that requires collaboration among several engineering teams. My team has been the ultimate initiator and driver of the project. As more and more senior engineers from other teams joined, I started to wonder if I was still qualified to lead the project. After hearing my concerns, my manager pointed out something I neglected: the importance of domain knowledge and a long-term vision. I was not the most experienced engineer on the project, but I had the most context and domain knowledge. The project is most related to my team’s current domain, and I have been working in this area for a long time. The domain knowledge I gained over time leads to a long-term vision. Both the domain knowledge and long-term vision are critical to the success of the project.
The importance of gaining domain knowledge and forming a long-term vision is rarely discussed, especially compared with the level of emphasis we put on improving technical skills.
This post covers:
- what it means to have domain knowledge and long-term visions
- why domain knowledge and long-term visions are as important as technical skills
- how to gain domain knowledge and form long-term visions
What it means to have domain knowledge and long-term visions
Essentially, having domain knowledge and long-term visions means understanding 1) the status quo, 2) the history behinds it, and 3) the future you are moving towards.
First, understanding the status quo means having an overall understanding of the projects your team owns and maintains, technical debts your team carries, current limitations and fragile parts of the system, etc.
If you are dealing with a specific domain, it also means knowing the ins-and-outs of that domain. For example, if you are a payments engineer, you should be familiar with different payment routes and protocols. If you are building accounting software, you should know basic accounting concepts. This knowledge might have nothing to do with computer science or software engineering. But your job as a software engineer essentially is to translate this knowledge into code. The better you understand the domain, the easier it’s the build elegant systems.
Secondly, the history of the team and projects means why and how your team gets to this point. It includes the reasons certain responsibilities belong to your team, the tradeoffs and reasonings behind architecture design decisions made in the past, etc. It’s not necessary and impossible to know all the history and related details. But knowing the history of your team definitely helps you form a long-term vision with clarity and confidence.
Lastly, the future you are moving towards includes where you are going and when you plan to get there. This is the long-term vision of your team. It is ultimately determined by the status quo and future business needs. For example, if the business plans to reach 50% market share in three years but the current system doesn’t support the traffic coming from 50% of the market, then your vision might include upgrading the system to make sure it can meet the business needs by that time.
Essentially, domain knowledge and long-term visions are the contexts that surround your day-to-day work.
Why domain knowledge and long-term visions are as important as technical skills
First of all, domain knowledge and long-term visions give meaning to your everyday work. Which one of the following excites you more: “write this code to finish this three-point story” or “write this code to remove one of the limitations of the system which brings us one step closer to handling large traffics and serving more customers”?
Secondly, domain knowledge and long-term visions serve as your compass for making decisions, big and small. How many people does the team need to hire this year? Which projects need to be worked on this quarter? Which approach should we use to solve this problem? Engineering is about making tradeoffs. There’s no objective best solution. What you care about is the solution that works the best for your current context. Domain knowledge and long-term visions provide you the context to prioritize things and make decisions.
How to gain domain knowledge and form long-term visions
1. Getting your hands dirty: experience, experience, experience.
Nothing substitutes experience. The longer you work with the code, the more areas of code you touch, the more domain knowledge you gain. That’s why the person that has been on the team the longest typically knows the most about the system.
To make the most out of your experience, you should always pay attention to the surrounding context of your current project. Don’t just focus on that piece of code you are working with. Try to understand how it’s being used and how it fits in the overall system. Don’t just try to finish your project as fast as possible. Try to understand why it’s important and its relationships with past, current, and future projects. In other words, don’t just do what you are told. Be mindful about what you are doing, why you are doing that, and the downstream impacts.
2. Use the 5 Whys Technique
The 5 Why technique means asking: ‘why’ five times. It was originally developed by the Toyota Motor Corporation for troubleshooting root causes. But it’s also effective for understanding the context of our work.
Here is an example:
- Why do we want to refactor this code? So we can move the functionality out as a service class.
- Why do we want to move the functionality out as a service class? So we can decouple the use cases from the implementation details.
- Why do we want to decouple use cases from implementation? So we can gradually encapsulate all the implementation details behind an API.
- Why do we want to have an API? So we can move the service out to a different server if needed.
- Why do we want to move the service out to a different server? Because this service is the most CPU intense one and moving it out allows us to allocate more computing resource just to this service.
3. Pick senior engineers’ brains.
As we discussed above, normally, the longer an engineer has been on a team longer, the more they know about the domain and the more opinionated they are. Try to learn as much from them as you can.
- Pair programming with them more.
- Ask them lots of questions (why, what, how), especially when they hold strong opinions.
- Schedule casual 1on1s or walk-and-talks with them.
4. Building a solid technical foundation.
Having a solid technical foundation is still critical. A strong understanding in system design helps you see the pitfalls in the current system and helps you form a current vision of how the system should be. Having strong refactoring skills helps you find the best way to gradually and safely transform the system from its current form to the vision you have in mind.
Improving technical skills makes us good implementers. Gaining domain knowledge and forming long-term visions make us problem solvers and problem finders.
A man came upon a construction site where three people were working. He asked the first, “What are you doing?” and the man replied: “I am laying bricks.” He asked the second, “What are you doing?” and the man replied: “I am building a wall.” As he approached the third, he heard him humming a tune as he worked, and asked, “What are you doing?” The man stood, looked up at the sky, and smiled, “I am building a cathedral!”
Start focus on the other side of technical skill: gaining domain knowledge and forming long-term visions, so you can become the architect who designs cathedrals and leads teams that build them out.
My career plan for the year is to grow into a tech lead. I’m excited about all the learnings ahead and would love to share this journey with you in a brutally honest fashion. I will be sharing my weekly learning on the blog.
In the next few months, I will focus on growing in the following areas. You can expect to see posts related to them:
- focusing on the big picture of the project instead of near-term implementation details;
- balancing my efforts between leading projects and coding;
- work-life balance for long-term productivity;
- the human side of software development: making sure everyone riding with me enjoys the ride and feels fulfilled and inspired.