How to Grow as a Software Engineer
Software engineers will spend years looking at code, without thinking about their communication skills. However, software engineering is more than just programming. The reality is that technical ability can only take someone so far. Once you hit the technical ceiling, it becomes about communication.
In this post, I'm going to talk about communication and why it's important. I'll share with you the three domains of communication and decision-making. These domains will give you the tools to take your problem-solving skills and apply them to matters of communication.
Of course! An engineer can only get so far with technical ability alone. When we look at a job description from Google for a Software Engineer, we see the following:
- Degree or equivalent practical experience in computer science.
- Experience in working with the programming languages and frameworks we use.
- Working proficiency and communication skills.
These are the minimum skills required to become a software engineer. Technical ability is the basis for early career development. If you want to continue growing, you need to break past the technical ceiling. Let's look at the added requirements for a Staff Software Engineer position:
- Experience architecting and developing distributed systems design.
- Hands on technical leadership experience leading project teams and setting technical direction.
From these postings, we can see that technical ability can only get you halfway there. Communication skills are required for basic tasks like code reviews and collaboration. These are just the minimum skills required.
Beyond entry-level tasks, higher-level tasks require more strategic and tactical communication. Architecture requires strategizing a systems design through research, implementation, and working with others to oversee the process. Technical leadership requires essential communication skills to be able to direct and influence the group. Without developing these skills, an engineer can only go so far.
That's why we need communication: to grow. We need communication to take our technical abilities to new heights. These essential skills increase our ability to work with others and broaden our impact. To build these skills, we need to be more thoughtful, and we need to know which domains to think over.
Thoughtfulness and decisionmaking for software engineers can be broken down into three domains:
Engineers are already familiar with the technical domain. Many find their ceilings here because it's easy to be distracted by matters of code. However, to break past that ceiling, an engineer needs to exercise critical thinking in all three domains.
Writing code is easy, but figuring out which code to write is not. For any given feature, we could write it a hundred different ways. And while there is no "right" way to write it, we can strive towards writing code that is easier to read and maintain. Every line is a choice that makes tradeoffs to strive towards a healthier codebase.So what makes a healthy codebase?
A healthy codebase has a good balance of the following:
A healthy codebase has clarity, where new changes are easy to implement against a known path. Implementing new routes, creating new interfaces, and deploying new APIs; tasks like these are straightforward. Struggles in clarity happen when a codebase has too many layers of redirection, multiple mechanisms for the same task, or insufficient tooling and documentation. These together can help make the codebase more accessible to all contributors.
A healthy codebase has a path forward, called direction. When considering tech debt, the deferred cost of a short-term solution, a healthy codebase is well-documented and guarded by tooling that helps the developer to be productive. A good sense of direction is when tech debt is easy to silo so that it does not impact the rest of the codebase.
Lastly, a healthy codebase has consistency in its use of patterns. This means that what happens in one place of the codebase, is expected to happen elsewhere. Consistency is a spectrum where patterns align together. When there are many contributors over time, multiple patterns can emerge. Inconsistencies can also emerge when introducing new tooling or patterns. On the other hand, these are only problems when there is a lack of clarity or direction in the codebase.
A healthy codebase has a healthy balance of all three devices: clarity, direction, and consistency. When talking through the technical domain, these devices are useful tools for expressing the impact of technical decisions. However, engineers also need to think beyond the codebase. After all, the choices we make have an impact on the whole team.
An organization is a group of people or a company. In engineering, an organization could mean multiple groups of people: the whole company, a specific team, or a group of code owners. The decisions that engineers make affect more than the codebase — they affect these groups of people too. Being thoughtful about the organization is helpful for making better decisions to benefit these groups.
The organizational domain is where thoughtfulness and decisionmaking can impact these groups. An engineer exercises this domain when starting inward and reflecting outward on how decisions impact their peers and collaborators. Consider a codebase as a product of its own. Reflect on the users of this product, contributors to the code.
To reflect in this domain, we can ask the following questions:
- Who will maintain this decision in the short-term?
- How will this decision be adopted by external contributors?
- What impact does this decision have to make future decisions?
- When is the right time to make this decision?
The final question to ask, considering the inputs above, is: why? When we ask why we're considering the tradeoffs being made in the organizational domain. Finally, when we ask this question we also need to ask the inverse: why not?
Thinking through these problems is how engineers elevate their problem-solving skills to the organization. Reflecting on how decisions impact these groups of people, is how engineers become more effective. The organizational domain is how engineers apply their problem-solving skills to the needs of the group. This takes us into our next domain, where we apply problem-solving skills to operations.
The final domain we will cover is the operational domain. This domain is where problem-solving skills are applied to the impact on processes. The previous domains (technical and organizational) have so far focused on things and people. In this domain, we focus on the impact on things and people over time.
When working in product development, we often talk about how to build a minimum viable product. The first process is the one in which we brainstorm and plan before building. In this process, we talk about the scope of the development, meaning what's included. In this process, it's also helpful to ask: what's not included? Through this process, engineers collect a list of requirements, the needs of the development to fulfill the scope. Together, scope and requirements are useful tools for talking about the development process.
What about the processes that happen after the code is written? Writing the code is easy, however, engineers should be mindful of the following technical process that happen afterward:
- Code Review
- Building and Deployment
- Integration into the Mainline
In addition to these processes, our thoughtfulness and decisions can have latent effects that impact how we implement and integrate in the future. Moreover, there can be effects on the organizational and operational processes, such as:
- Who needs to be involved in the decision-making process?
- How does the scope today affect the requirements for tomorrow?
- What requirements can better prepare any incremental efforts?
- Are there opportunities to generalize the approach to scale for other initiatives?
- After the decision is settled, who needs to be informed?
Questions like these are effective tools for communication and reflection. When communicating in product development, asking these questions can help make an engineer more effective in the process. Reflecting on these answers will also make you a more critical thinker that can influence others at the table.
This framework of thinking is effective for software engineers to become more thoughtful and productive. Being thoughtful about the technical, organizational, and operational domains — will give you the tools to level up as a developer. Effective engineering is not writing the perfect code, but rather identifying how to apply problem-solving skills throughout the entire process. Harnessing communication in your career will help you become more impactful and influential beyond technical ability. The T.O.O framework reconciles these two areas to help you think through the domains and harness communication as a skill.