We live in times when virtually every company is a software company from the perspective of software systems being essential for their core business. A bank is a software company, a car manufacturer is a software company, an airliner is a software company. Software engineers are the professionals who create the backbone of these firms – a well designed, perfectly written, easily maintainable, quickly scalable, quality software systems. At least that’s where we should be aiming for. This leads to the question – what are the three key qualities of a great software engineer? In my opinion those would be the will to learn, thinking in abstractions and the ability to “see the larger picture”.
The first key quality of a great software engineer is something all of us can easily achieve. That is the constant will and openness to learn both in-depth and in-breadth. To learn new technologies, new abstractions, new patterns, new algorithms, new methodologies, new frameworks. Most people, let alone software engineers are unwilling and even scared to leave their comfort zone. As a result we end up with software developers so accustomed to a specific language paradigm and so unwilling to have a look at something else that it becomes a religion to them. It’s OK to have a favorite technology, but being religious about it is where I put the first line between a coder and a software engineer. So if you are looking to become a great software engineer have a critical look at a programming language you are less familiar with. This means writing a non-trivial piece of software using a new approach you have just learned.
Thinking in abstractions is considered one of the key traits in modern human behavior. Abstractions are also a key underlying principle that made the rapid software industrialization possible. As software engineers we rarely have to think in terms of bytecode, assembly language or binary sequences of 0s and 1s. Coders typically think in terms of classes and methods, loops and conditionals, variables and their types. These are concepts that we teach first year students in universities for a brief period of 6-8 weeks. As opposed to mere coding, software engineers should be able to clearly grasp higher-order concepts, such as inheritance, encapsulation, polymorphism. Great software engineers should be able to think in terms of well-defined components and design patterns. Unfortunately, in my opinion there is no clearly defined “algorithm” of how to get from coder to a software engineer. The ability to think in abstractions is nearly constant around the age of 18.
Finally the last and perhaps the most essential skill to discern a great software engineer is his ability and his will to see the larger picture and zoom in when necessary. Thinking in abstractions is a necessary, but not a sufficient quality. De Saint-Exupery once said “If you want to build a ship, don’t drum up the men to gather wood, divide the work, and give orders. Instead, teach them to yearn for the vast and endless sea”. Most of the modern developers are literally “stuck” in code. There is a conscious, intentional and substantial gap towards the customer. It is not their job to be talking to the customer, yet if they understood what the customer really needs the results would far outreach the current state-of-practice. The second issue is that the separation of concerns principle led us to job descriptions such as a front-end developer, a back-end developer, a database specialist, a data scientist and what else not. Clearly, the organizational structure that produces the job description is not an issue, but the knowledge scope of a modern software engineer has reduced to a level where a mid-level software engineer thinks that a data scientist is someone who can manage his way through an ELK stack.