I have been interviewing a lot of software engineers recently, as I am leading a new team and looking to expand it. That has led me to reflect a little on what I am actually looking for. The following five qualities have been shared by all of the really good, fun-to-work-with developers who I have had the pleasure to work with.
1. Technical mastery
Really good developers fully understand what they are doing. This might sound funny, but unfortunately, it is all too common for people to get things to work by cutting and pasting examples or fumbling through a quasi-random hacking process to arrive at code that "works" without actually understanding how or why (or in fact even if) it works. There is nothing wrong with experimentation and leveraging experience - and working code - of others. When really good developers do that, though, they always find their way to full understanding of the technologies and techniques that they are using. When I interview developers, I always ask them to explain exactly how the solutions that they developed work. I can usually tell very quickly if I am talking to an individual who masters the technology that they use. I would much rather have a developer with strong mastery of a small set of technologies than someone whose resume is full of advanced technologies that they don't understand.
2. Simple mindedness
In The Humble Programmer, Edsger W. Dijkstra said "The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague." Really good developers have a wonderful tendency to keep things as simple as possible, as long as possible. Fancy constructs, excessive OO complexity, needless external dependencies and exotic algorithms never find their way into their code. If there is a simple way to do something, that is what they do. Reading the code of a simple-minded developer is like reading a mathematical paper written by a great mathematician. If the content is straightforward, the progression is 100% predictable. You can stop in the middle and scribble out what should come next and then see that is what comes next. When you get to a difficult part where you have to think, you are happy to see that the author found something so simple that you should have thought of it.
3. Organizing
Another one of my favorite Dijkstra quotes is that the art of programming is the art of organizing complexity. Great developers are organizing forces. Note that this is not the same as "being organized." It means that they help define problems in a way that they can be solved with simple solutions and they help get contracts, interface boundaries and tests in place so that the teams they are part of can be organized. The scope of what developers can organize naturally grows as they progress in their careers; but they need to have the drive and ability to be "organizers" from the beginning. Developers that have to be told how to think about problems are net drags on the teams they are part of. Good ones are key contributors to their teams arrival at nicely organized approaches to problems.
4. Fast-learning
Technology changes so fast and business problems are spread across such a large surface that developers constantly need to learn new things. And these things are not just programming languages, frameworks or constructs. Developers need to learn business domain concepts, data science and AI concepts as needed, often in ridiculously short timeframes. This means that they have to be able to learn very fast. And they have to be able to do this and immediately exercise their knowledge with a high level of independence. Its great to be able to learn together and share knowledge with others, but sometimes developers need to figure things out for themselves and good ones have the ability and determination to learn what they need to learn - however hairy it gets - to solve the problems in front of them.
5. Situational awareness
Good developers ask about - and clearly understand - the execution context of the code they work on. If something needs to be thread-safe, they write it that way. They know what the performance and scalability bottlenecks in and around their code are. They know about its security context. They see enough of the larger system that their code is running in / interacting with to ensure that it will be operable, failing fast and loudly when it needs to fail, maintaining invariants that it needs to maintain, and providing sufficient logging / events / monitoring interfaces. And of course, all of this is validated in unit tests.
I know some people will say that some of what I have above - especially in 3. and 5. - can't really be expected of "SE's." These qualities, one might argue, are qualities of architects. Developers just need to be "feature machines" and architects can worry about how to organize the code and make sure the whole system is operable. My biggest learning in 30 years of software development is that that is the wrong way to think about it. Architecture influence and scope of vision naturally increases as developers progress in their careers; but it is part of what they do, every day, from day 1 and the better they do it, the more successful the teams they are part of can be. And the senior ones - those who might have "Architect" or "Principal" or "Staff" in their titles - need to encourage, cultivate, challenge and be influenced by the design thinking of SEs at all levels.