While not an exhaustive list, this is also not a list of requirements.
Many of the traits are contradictory. In fact, it is the balance of them that is most appealing.
You will rarely find them within one individual, which is what makes building teams so interesting.
It is hard for one person to encapsulate the following traits in perfect balance, but it is easier to hire or form a team that exhibits them in aggregate.
That is often superior as individual extremes can often collaborate to produce a product that is better than a group existing on the median.
Regardless, this whole post should be taken with a pinch of salt.
Like everything in software this is one individual’s opinion based upon their experiences which are likely different to your own.
Unwavering self confidence
Let’s be straight, as software developers we are crafting new worlds out of our own imaginations.
Just to embark on this effort without running away scared needs a modicum of self confidence.
To do this for a large part of a system that other people rely on requires significant cojones.
For this small part of the universe you are god, master of all you survey, and you will be subject to constant questioning as to why things are the way they are.
If you are a benevolent god, why can’t users store their favourite flavor of donut? Surely a wise and just god would allow for such things?!
Such confidence is usually hard earned from the journey from junior developer to lead developer (or whatever arbitrary name your company may apply).
Each step along the way someone more senior should challenge your every decision, not necessarily because they think it is wrong, but to help you understand why you believe it is right.
Only through your knowledge being hard won and battle tested should your self confidence become unwavering.
Unwavering self doubt
Equally as much as you need the confidence to declare that water is wine, you need to have a level of doubt that you implemented the water-to-wine algorithm correctly.
Confidence is a massively powerful thing, but untamed by doubt it can be misguided and cause more harm than it is worth.
Without self doubt, why would you ever write tests? Surely you would not need verification that your code works with complete self confidence?
Humility is the glue that brings self confidence and self doubt together.
It is what allows you to approach your peers from a position of “I’m 99% sure this is the best way forward, but I really want your thoughts on it”.
Starting a conversation from “I’m not really sure what to do” is a recipe for a long conversation.
Having the self confidence to start a conversation from a specific point of view helps shorten it.
Having the self doubt and humility to ask for the conversation helps improve your thinking.
Having the humility to readily admit when you are wrong during the conversation helps reach the best possible outcome.
Be it a junior developer that is learning the ropes, a customer that’s having trouble using the system you are responsible for, or a colleague that is wondering how something works, your default state should be to make someone’s day better.
So often all people outside of a development team hear is “no”.
Taking every opportunity to say “yes” and make things easier or better for someone is worthwhile. This also brings more weight to your “no” as you’ll be the one person that usually says “yes”!
If making the decision between being perhaps too helpful and refusing a request, always err on the side of being too helpful. You never know when you’ll need a favour to be repaid in kind.
This relates somewhat to being helpful, but if there was one trait I would highlight above all others it would be this.
The best developers I have known have always had a wider awareness of the system they are working on.
Sometimes they will be provided with the context they crave, otherwise they will ask “why is this important?” over and over and over until they understand the underlying motivation.
This is not because they disagree with the change, it is because they want to deeply understand why the change is being made. They understand that they are a catalyst for the company they work for and want to be as effective as they can be.
As a developer you are often uniquely positioned in understanding what a system is capable of.
Often you are approached with solutions to implement to an unarticulated problem.
Only empathy will help you surface the problem that is being solved, which can lead solution that is far superior.
A healthy level of paranoia
Effective developers know someone is always out to get you.
Even if you deeply understand a problem, have collaborated with your peers to implement the optimal solution, and have implemented it perfectly, someone is trying to find a way to poop on your parade.
This is why we protect against SQL injection, cross-site scripting, lock down everything possible, and so forth.
It is not primarily because we do not trust other people, it is because we do not trust anyone, even ourselves.
The worst part of this is that the parade pooper is likely to be yourself.
In six months you may be extremely motivated to change how something is implemented for the most well-meaning of reasons.
However, without sufficient safe guards put in place by your past self (tests, documentation, etc) you may inadvertently poop on your own parade by breaking existing functionality.
The best developers don’t just know how their own code works, they understand how the libraries and runtimes beneath it work.
This usually comes from a need to understand “how the sausage is made”. A good understanding of a couple of layers of abstraction below the level you are working at often helps you write better code at the level of abstraction you are working at.
Most common cases of this is understanding which calls will and won’t result in external calls, understanding what patterns result in excessive memory or object allocations which in turn lead to bloat or garbage collections.
I like the term I first heard from Martin Thompson for this: mechanical sympathy. Many approaches can work, many can be easy to maintain, but often there will be one that is particularly sympathetic to the library you are using, the runtime you’re executing within, or the hardware you are deploying to.
Only by understanding the wider picture can you pick an approach that is more sympathetic than others and reap the benefits.
Software development is intellectually challenging and can be an emotional rollercoaster.
There’s the highs of shipping a much needed feature, the lows of finding bugs, the lows of features that turn out to be unfeasible given the budget, the lows of spending hours looking into bugs, the lows of determining why something only works on your machine, the lows of the backlog growing faster than you can implement it, the lows of the mundane copy changes and other such trivial work that is only trivial after years of grinding, the lows of…
Actually, it’s a pretty crap rollercoaster.
And this is why perseverance is key.
You often have to wade through pits of despair or troughs of sorrow.
But occasionally there will be something, some change you need to make, some feature that you need to implement that will be so easy based upon the previous 6 months of hard work and discipline that you will be elated.
So much so that you’ll be able to face the next 6 months of slaying creeps until the next time.
Software development can be very serious.
It’s a binary world, zeroes and ones, black and white, right and wrong.
But so much of it is subjective that someone’s right can be another’s wrong and tensions can get high.
Simple mistakes can bring the world tumbling down, stable systems can spontaneously catch fire, ninja attacks can happen at any time and those ninjas might be on fire too.
Software development should be taken seriously, but it does need to be countered by a bit of humour; a bit of banter.
Otherwise it gets too serious, people get stressed, they stop enjoying themselves and then they won’t be able to focus as well on the task at hand.
It doesn’t take much to break the tension — a well chosen GIF, the perfect emoji, or sharing an amusing link.
That can be all it takes to stop things from boiling over.
It’s just a bunch of zeroes and ones at the end of the day.
Good memory for previous errors
Effective developers strive to not make the same mistake twice.
You’ll often find they have practices in their personal process that helps them avoid them.
For example, writing tests, documenting reasoning for particular things, use of code tools, and so forth.
The little mistakes can be easy to make but still take time to resolve.
If you can create a process or use a tool that helps you avoid making the small mistakes more of your attention is free for avoiding the larger, more costly ones.
An effective developer will often have these personality traits:
- Unwavering self confidence
- Unwavering self doubt
- Crushing humility
- Overly helpful
- Strongly empathetic
- A healthy level of paranoia
- Highly inquisitive
- Light heartedness
- Good memory for previous errors