Being an effective software engineer requires a mix of different skills. In this article, I provide a framework for how to think about your skillset and guidelines for how to improve in each area.
At a high level, a software engineer needs to leverage four core types of skills:
I strongly believe that the impact of these core skills is multiplicative rather than additive. This means that having high skill levels across these areas has a compounding effect. Similarly, a big deficiency in any one of them can significantly hamper your ability to produce results. How skilled someone is in each area is usually a mix of background, career stage, and personal aptitudes. That said, all of us have plenty of room to grow in one or more of these, so let’s dive in!
Fundamentals
These are primarily your academic skills. Algorithms, data structures, programming languages, and other subjects you’ll typically learn in a university or from a textbook. Other related subjects such as math, logic, or statistics and specialized topics like cryptography fall into this category as well. A defining characteristic is that the knowledge in these areas tends to not change much over time.
Why they matter: It’s easy to dismiss these as purely theoretical and something you just had to go through in school. After all, not many people are implementing operating systems or compilers in their jobs. However, in many cases having this strong foundation enables you to tackle more interesting problems as they come up. For example, understanding the cost of a transition into kernel mode can inform your design of a performance-critical piece of code. Or a good understanding of probability can lead you to develop a randomized algorithm that is a lot more efficient than a deterministic one. This is something I experienced very closely when I worked in MSR. This type of software engineering (backed by fundamentals) can not only be incredibly impactful but also tends to be a lot of fun!
How to improve: Go back to (or stay) in school! These subjects can be hard and having access to professors and peers is very valuable. You can also use online courses or books, which have some advantages such as cost and convenience. The tradeoff is that you need more self-discipline and they may not provide the same depth.
Technology
Ah, the fun stuff! These are your bread and butter tools for developing software and fall into a few categories:
Area | Examples |
Programming languages | C++, JavaScript, C#, Python |
Frameworks and APIs | NodeJS, Angular, .Net, scikit |
Tools | Visual Studio, Eclipse, git |
Systems | Linux, AWS, Hive, SQL Server, Spark |
This is the easier category to learn. There are plenty of free resources, plus you get a short reward cycle, meaning that as soon as you learn a bit of, say NodeJS, you can get something working and play with it. Contrast that with understanding eigenvectors. The flip side is that this knowledge has a shorter shelf life (remember Silverlight?), so you need to be a bit strategic about what you learn.
Your learning plan
You will naturally learn many of these as part of your job. You just need to be mindful to keep a good balance between breadth, depth, and diversity. In terms of programming languages, my approach is to know one or two general-purpose languages like C++, C# or Java really well. Then add a couple of scripting (e.g. JavaScript, Python, Powershell, Perl) or application/niche-specific ones to the mix.
For all other areas, you basically want to stay up to date with technology. I spend the bulk of my time on technologies I’m currently using, reading up on improvements in the new versions, or finding tutorials or articles that teach you features you may not know well. I put extra focus on tools as I’ve found that being proficient with your IDE, source control and the command-line shell is a big productivity boost.
And in an industry such as ours, there’s always a new and shiny thing we feel we should learn. But if it doesn’t have a direct application to your work you need to be a little cautious. As much as it may feel like you must learn X or Y to not become obsolete, there’s also a very good chance that You aren’t gonna need it (YAGNI). What I typically do is I’ll spend a couple of hours understanding what this new thing is without going too deep. The goal is to be able to tell when I might need it but defer the in-depth learning until it’s necessary. An exception to this is if you are actively trying to make a career transition (e.g. go into Machine Learning), in which case you do want to build some depth.
Shipping (experience)
This is a bucket for the experience you accumulate by shipping software! Building software comes with many subtle pitfalls that are often hard to learn or appreciate until you’ve gone around the block a couple of times. For example:
- Importance of good logging
- Risk/value tradeoffs when adding dependencies
- Long term maintainability of a codebase
- Value of good API design and documentation
- Not over or under designing
- The value of simplicity
-
Etc …
The list goes on and there’s no denying that learning this takes time, but there are a couple of ways to accelerate the process:
Self-reflection: Take time to reflect on what worked well and what didn’t. Where and why did you end up spending a lot more time than you expected? What piece of code seems to never stop giving trouble and why?
Learn from others: Work closely with someone more senior than you. Observe what they focus on and what they worry about. Ask tons of questions and try to understand their decision-making process.
Read: There are some great books in this space, such as The Mythical Man Month, Joel on Software, Code Complete, and The Pragmatic Programmer (links in the Resources section).
Soft skills
In the beginning, you can advance your career mostly on your technical skills. You are quickly building your knowledge, getting better at design/implementation/debugging, and at delivering features independently. In other words, the focus is largely on your individual technical productivity. For this reason, it’s easy to neglect developing your soft skills at this stage. Don’t fall into that trap.
As you grow in experience and seniority, your ability to work with others and lead in various ways starts to become more and more important. This is where your soft (non-technical) skills will gain more importance, and if you’ve paid attention to them all along, you’ll be better positioned to continue your growth. Also, note that these skills are highly transferable across industries. They’ll help you even if you make a career change later on, so they are well worth the investment.
To make this a bit more concrete, these are some of the areas you should pay attention to:
-
Communication:
- Listening
- Presentation
- Writing
-
Leadership:
- Empathy
- Influence
- Integrity
-
Teamwork:
- Conflict resolution
- Collaboration
- Motivation
- Time management
These are huge subjects with entire bookstore sections devoted to each (I have some book suggestions here), so I primarily want to motivate you to give them the attention they deserve. Start by paying attention to who does these things well and who doesn’t. Seek feedback from your manager, your peers, or your mentors on areas for you to improve.
With some time and the right strategy, you can grow as a well-balanced engineer and more generally an effective professional. If there are skills I didn’t cover or any resources you’ve found valuable please share them in a comment so we can all learn!