Disclaimer: All views expressed here are my own. Strong opinions, loosely held.
I’ve been in the software engineering industry for a while, and worked with a few hundred engineers from all walks of life (from freelancing, to startups of various sizes, to Google). I’ve seen some excellent engineers. I’ve also seen less-than-great engineers, and everything in between. Brilliant jerks, too.
As a result, I have some opinions on what a great software engineer looks like. Or at least, I’ve seen enough bad behaviours that tend to hinder a software engineer’s growth and career. I’ve summarised here a few “soft skills” that my favourite colleagues exhibit. Writing this down is also a great reminder for myself of the areas where I have room to grow.
I won’t talk about technical skills. While they’re definitely an important aspect of a great engineer’s competence, it’s relatively easy to identify that you need to learn a new technology, and then learn it. It’s harder to realise that you’re missing a particular soft skill, and people often won’t tell you. They will often assume that it’s just part of your personality. And if you don’t have a growth mindset, they’re probably right.
I should nuance the following with a note: not all organisations make it easy for software engineers to do their job well. All the advice below comes with a big caveat: if management doesn’t do their job right, or if the organisation doesn’t see the value of good software engineering practices, chances are you won’t be able to be a great software engineer. That’s a much deeper issue, and not necessarily something you can fix (aside from changing jobs, if that’s in the realm of possibility for you). Also, a lot of this advice doesn’t apply to solo developers.
Without further ado, here are a few critical soft skills I’d expect from a great software engineer.
If you don’t say hello to your colleagues and you’re not particularly approachable, chances are they won’t feel like involving you in critical discussions where your input would be valuable.
Great software engineers are friendly. They may not be your best friend or even someone you have a particular affinity with, but they make an effort to connect with their colleagues on a personal level, independently from the work being done.
The foundation of emotional trust they create with their colleagues helps them work more effectively. It helps them challenge ideas without making the other feel threatened. More generally, it contributes to creating a healthy working environment.
Great software engineers are helpful.
They’re not isolated in a bubble, only looking at their own work. They are actively looking out for their colleagues. If they learn something that could be relevant to a coworker or even just a friend, they reach out to let them know. They try to stay roughly aware of what their closest teammates are working on, to make sure they collaborate effectively and don’t step on each other’s toes unnecessarily.
Great software engineers put their hand up and offer help when a fellow engineer is stuck on a technical problem. They don’t “stay out of it” or say “not my problem”. They care about the team.
If you always do the same type of work day in and day out, and you don’t stimulate yourself intellectually outside of work, you may find yourself a bit stuck.
A great software engineer is forever curious. They’re always learning, wanting to expand their knowledge and challenge themselves.
They’re not necessarily always trying out the latest technologies. They might just read a lot of books or learn a new skill. It probably has nothing to do with software engineering.
The important thing is that they keep themselves on their toes.
Not afraid to get their hands dirty
I’ve seen a number of technically competent engineers who, when they run into an issue, will blame a third party (often another team) and not even try to address the underlying issue because it falls outside of their realm of responsibilities. They don’t try to understand the circumstances that led to the particular implementation that they’re having an issue with.
Great engineers on the other hand are pragmatic, understand that nobody can predict in advance all the ways a piece of code/infrastructure will be used, and they will propose solutions and refactors that help everyone get ahead. They’re not afraid of digging deep into something they’re unfamiliar with, even when it’s written in a different language, framework or for a different platform. Actually, that’s how they keep learning new technical skills on the job.
Not afraid to give and receive feedback
A great engineer likes feedback. They embrace their imperfection and strive to improve. They much prefer to be given uncomfortable feedback rather than be stuck with a blind spot. They don’t hold a grudge against another engineer from whom the feedback originated.
They also make an effort to help other engineers grow. They are supportive and encouraging when they notice great work being done. More importantly, they help others grow by noticing areas of personal improvement and highlighting them through constructive feedback. They follow up when appropriate, in particular when they notice a positive change.
Not afraid to change their mind
A great engineer doesn’t have to always be right.
They are humble enough to acknowledge that they don’t have the right answer to everything. They welcome criticism of their ideas, and they’re not afraid to say “Actually, you’re right.” even when it comes from a much more junior engineer.
When designing a system, a great engineer always considers alternatives to the obvious solution, or the “status quo”.
They are aware of their own biases, and make a point of exploring alternatives that they’re unfamiliar with. They document their reasoning and, per the point above, they invite others to critique their decisions in order to reach the best possible outcome.
Aware of other’s cognitive context
A great engineer strives to set the context for a technical discussion. They realise that each person has a different exposure to various aspects of the business, and they may not be aware of the particular circumstances that led to a technical decision. This is what Daniel Goleman calls “cognitive empathy”.
Therefore, a great engineer starts a technical discussion by looking around the room, and asking themselves “does this person have the required context already?”. They err on the side of caution and always remember to set up the stage before diving into the technical details. This has a number of benefits: other engineers can follow the conversation more easily, new teammates don’t feel left out, and subtle misunderstandings in the context become a lot more obvious.
This extends to non-engineers: a great engineer doesn’t feel disdain for the product manager in the room. They focus on building a shared understanding and help clarify any obscure aspects of the technical discussion.
This also extends to documentation: a great engineer not only documents their technical work, but also the necessary background, reasoning and decisions that led to this particular outcome. Their documents are easy to read even for someone who has just joined the team.
Respectful of others’ time
A great engineer is concise and articulate.
When discussing technical solutions, they focus on communicating effectively. They mentally prepare before making a point. They focus on articulating their ideas in a way that other engineers will be able to follow. They don’t repeat the same fact over and over again, although they may occasionally illustrate their point with simple, concrete examples.
They consider it a privilege to be granted the time to speak. Critically, they don’t ramble: they get to the point quickly, and they know when to stop talking. When in doubt, they stop talking earlier rather than later. They are deeply curious about what others have to say.
Actively listening to others
A great engineer is an active listener.
When another engineer is talking, they make a conscious effort of digesting what’s being said. They don’t use the time to daydream or think about a completely different point they want to bring up next. They don’t interrupt others constantly either. They wait for their turn.
Active listening works best when other engineers are also respectful of other’s time (per the previous point). It’s perfectly understandable to get tired of someone repeating the same thing five times in a row without letting anyone else talk. When that occurs, a great engineer stays courteous and takes the next available opportunity to give private, constructive feedback to the “offender”.
Aware of other’s emotional state
A great engineer keeps an eye out for signs of emotional distress in other engineers in technical discussions.
A relatively senior engineer will often be in the delicate situation of highlighting flaws in another’s work. Building software is a surprisingly personal endeavour. Realising that your design is flawed after spending weeks or months pouring your energy into solving a tricky problem can be very confronting.
A great engineer pays particular attention to “softening the blow” and strives to make constructive suggestions that make the other feel great about themselves (without making them complacent either).
This is critical for code reviews. It ultimately leads to much better outcomes in the overall quality of the codebase, as other engineers feel inspired to further improve the code without feeling personally attacked.
In case you haven’t noticed yet, most of the above can be summarised in a single sentence: a great software engineer shows strong emotional intelligence. Unlike raw intelligence, emotional intelligence can be learned. I’d recommend getting started with the book Emotional Intelligence 2.0, but there are lots of other great articles and books on the topic.
I hope a few of the points above gave you some pause. Maybe you won’t agree with them, and I’ll be glad to hear your feedback in the comments.
I certainly don’t check all the boxes yet, and I’m sure this list will keep growing as I progress in my own career. I’m glad I get to work with quite a few great engineers on a day-to-day basis at Airtasker, and I make a point of learning from them.