Beyond Code; What It Takes to be a Great Software Engineer
Being a good software engineer requires you to write good code. That is a given but there is more to it than that; being a good software engineer means being the right kind of person.
This isn’t about that much quoted line about greatness and how many hours are required to achieve it.
10,000 hours is the magic number of greatness - Malcolm Gladwell
It is entirely possible, and indeed plausible, to practice something for more than 10,000 hours and be perfectly rubbish at it. I could spend 50,000 hours sitting atop a horse; a master jockey I wouldn’t be.
Discounting easy metrics like hours spent doing something is a must; the very fact that it requires use of a magic number should send any good engineer running. Like relating the number of lines of code to the quality of said code, how long you spend doing something in no way guarantees anything about the quality of the work done.
A good software engineer must not simply be good at coding; for a good software engineer does not simply code. A software engineer must code, design, communicate, teach, learn, solve problems, manage people, manage teams, manage code bases, perform releases, configure builds and many other tasks. That a software engineer can produce good code is a given for the sake of this article.
Instead, I prefer to discuss what qualities a good software engineer should have. Of course, there will be exceptions abound, so good engineers exist who don’t have these qualities and bad engineers exist who do. The following isn’t about those outliers; the following describes a typical good software engineer.
A good software engineer should be lazy, empathetic and passionate. Let’s start with laziness.
As a characteristic, laziness is usually frowned upon. However, I class it as being a positive, so long as it is the right kind of lazy.
Since this article was partially inspired by Larry Wall’s 3 Virtues of a Great Programmer, and I agree with his classification of laziness as a positive virtue, it makes sense to start with his description of laziness.
The quality that makes you go to great effort to reduce overall energy expenditure. - Larry Wall
Laziness isn’t about a failure to exert any effort; laziness is being focussed as to where effort is spent. Laziness is about deciding exactly how and when to spend effort such that you can minimise your effort in the long term. In other words, being lazy is an investment; often requiring some upfront energy to be spent now that will save energy over the longer term.
Laziness motivates automation. Laziness means that you don’t want to be performing a repetitive task over and over again so you seek a better means of doing it. If something can be automated, it probably should be automated. Not only does automating reduce the chance of human error and increase reliability and scalability, the act of automating a task properly cements your knowledge of it. You never fully understand a task until you automate it.
A talented software engineer doesn’t want to spend their time performing the same repetitive task over and over; a talented software engineer should be spending their efforts on solving new problems.
Laziness motivates knowledge sharing. Laziness means that you don’t want to be answering the same questions over and over again. With a little upfront effort that answer that you keep providing to people can be shared across the team; you can document it, you can teach others etc… Again, you want to be spending your time solving new and exciting problems; not regurgitating old solutions.
Laziness motivates efficiency. Laziness means that you don’t want to keep navigating the menus of your applications with your mouse; you want to learn the keyboard shortcut instead. You don’t want to type the same 30 character command into a terminal; you want an alias instead. You are investing a little bit of upfront effort (in learning a new shortcut) and in exchange you will be granted a lifetime of small wins each time you invoke that shortcut.
The next desirable quality is passion. What would you do if money was of no concern to you, if you were wealthy enough to live comfortably for the rest of your days? Would you still write code? It is an interesting thought. I think I would still be writing code because it is truly something I love doing. It is easy to spot those you work with who have passion for their craft and those who are merely drifting by. Whilst there is nothing unusual or particularly wrong about not loving it, or just doing it for the money, in my experience it is the people with passion who truly help shape a product’s future.
One person with passion is better than forty people merely interested. - E. M. Forster
In even the smallest of companies you are likely to find people who are performing their job as required but are not particularly passionate about it. Scale that up to a large company and the number of passionless people will be disproportionately high; big companies breed people who don’t care. That’s not to say you can’t be passionate and work in a big company. Chances are, however, that your passion won’t be recognised at a bigger company as well as you might hope. This leads to less engagement from you as you realise there are diminishing returns for your increased efforts. This leads to less passion.
The reason passion is so important is without deeply caring about what you’re working on you are not emotionally invested. You don’t actually care whether the project succeeds or not, whether it lives or dies, as you collect your pay cheque regardless. This is part of the reason I think larger companies struggle with passion in their employees; if a project fails in a big company, there will be plenty of other projects that replace it to keep the team employed. If a project fails in a small company, that could mean the end of the company; the end of your job.
This notion of caring about what you are building and not merely building it on request is important for the success of the project and the company as a whole. Too many times a project is kicked off which is clearly a Dead Fish.
“A Dead Fish project is one of those where it is known from the moment of inception that it is doomed to failure, and yet no one on the project stands up to say that it is doomed, that it will hang around, smelling badly, long after it should have been thrown out with the other trash.” — Adrenaline Junkies and Template Zombies: Understanding Patterns of Project Behavior
Projects that are clearly bad ideas but yet are being developed march forward until they encounter people with real passion. Only then does the project’s value really get the scrutiny the company deserves to give it. Sadly, if your passion:employee ratio is too low, this will be so far down the line it is too late to change it without huge costs.
Often companies will look to objective setting and appraisals to instill a sense of ambition into their teams; pick some achievable targets and aim to reach those targets over the next period. The process has never struck a chord with me however. I already know what kind of things I’m going to be pushing to include in the project in the next 6 months; I already know what kinds of skills I’m going to be aiming to achieve.
You should not wait to be asked how you can make a project better; that is your exact job from day one. Nobody needs it written into their job requirements, nobody needs it listed as an objective. If your daily aim is not to make your current project better in all ways, you are doing it wrong.
If you are not driven by this innate feeling to want to make things better, that is ok. If you don’t love what you do for a living though, there is the very real chance that there is something better out there for you. Do you love what you do for a living? If you don’t love it, is it because your current role is a stepping stone to something you will love? If you don’t love what you do, and it isn’t a stepping stone… why are you doing it?
I spend a lot of mental energy thinking about these types of things, thinking about the people I work with or have worked with, wondering what drives them, why they care about the things they care about and why they don’t about the things they don’t. Which brings me nicely onto empathy.
Empathy means the ability to understand and share the feelings of others. Rather than limit it to the now though, I also include the past and future states.
Code is never written in a bubble; never written without context. There are always pressures and constraints which shape code and it isn’t solely down to the ability of the author. When analysing a piece of code which has a bug, for instance, it is easy to criticise the author’s abilities: look at that bug, it’s so obvious, how did they not see that? What you don’t know, however is the context in which that code was written. Was the code written at 2:30am because there was a critical, production incident needing resolved? Was this code written because of yet another last-minute change of requirements? The context in which the code was written disappears quicker than the code itself leaving what I call decontextualised code. Without empathy as to what caused that code, you have only part of the story.
It is important to contextualise everything, not just the code. The designs, the requirements, the bug reports, the user feedback all have their own stories to tell but might not be immediately obvious. Again, it is easy to criticise a business requirement without appreciating that there might be pressures you’re unaware of which made it happen. A particular design might not please your eyes but perhaps it scored head and shoulders above all others at user testing.
When encountering something you don’t understand or agree with your first action should be to ask why.
Bug reports are my favourite example of where empathy creates a greater understanding of the full story and can help you add context. Receiving a bug report consisting of “this app is shit, all it has to do is let me take a photo, how hard is it?” can be hard to receive. It is hard to receive because it can negatively affect your app ratings without meaningfully giving you any information required to fix the problem. Without empathy, it is easy to dismiss this user as unhelpful, hysterical and unreasonable and, therefore, not worth replying to.
With empathy, however, you can rebuild the narrative. Perhaps this person had a small child who was doing something for the first time; standing up, laughing, petting the dog, whatever. If your camera app crashes and causes someone to miss a precious moment, one so precious they wanted to save it forever, they have a right to be angry. They have a right to vent.
Of course you’ll likely never know what the real context is behind such events. However, in my experience if you default to giving the benefit of the doubt, this will lead you to being a better developer. Choose the context which best motivates you to take action; choose the context which best makes you fix the reported problem; choose the context which makes you a better person. I’m certainly more inclined to go fix a problem which affects real people than one which can be dismissed as coming from an unreasonable, hysterical user.
Instead of assuming negative reviews come from unreasonable people, which is easily done, I imagine why the review was created. Someone quite probably needed something from an app and it let them down. The app is so crucial in their lives that it failing can lead to such an emotional outpouring. The person uses your app. Furthermore, the person relies on it. If ever you need extra motivation to listen to your feedback that is it.
Empathy is crucial in software development and unfortunately it is a trait so many lack. Until you ask why, until you understand why, you are in no position to make a decision. Decisions, actions, events are rarely as binary as they first seem.
Whenever you can you should put yourself into the shoes of your users. Who are they? What are their goals? Why are they using your service? How can you make their lives better?
Whenever you can you should also put yourself into the shoes of your teammates, your peers, your managers and those you manage. What drives them? What do they expect from you? How can you make their lives better?
Empathy is the single greatest virtue of a highly efficient software engineer.
Maybe you agree, maybe you don’t. Either way, drop me a message and let me know.