We need to talk about what it means to be a Software Engineer
There are varying interpretations of what it means to be a software engineer in 2024. Recruiters and companies looking to hire always tended to focus on the specifics of the skills, often with
outrageous entertaining laundry lists of arbitrary requirements. When was the last time a recruiter reached out to you with an opener similar to the following:
We'll get back to that shortly.
What skills should software engineers be hired for?
It depends who you ask. It also depends in which continent you live, and the type of company you work for. Given you're reading this blog, you probably want to know my answer: Software engineers should be hired for their problem solving skills. I acknowledge that "problem solving" is quite broad a term. Let me clarify further.
Some companies adopt a narrow definition of problem solving which confines the scope to implementation details. Other companies let engineers partake in identifying and solving business problems before code is even considered - the scope is much bigger, and engineers have a sense of ownership. I personally identify more with the latter approach. However, I have my own interpretation:
Problem solving is a pyramid of skills. A pyramid structure can only work if each layer is built on top of a strong foundation, else there is a risk of collapsing.
At the very bottom of the pyramid - the most foundational skill - is communication. The best engineers I've come across have all been, without exception, prolific communicators - both verbally and written. They articulate and convey technical concepts in an elegant fashion, possess emotional intelligence which helps them read and react to various situations, and write concise emails/memos/design documents.
Building on the communication layer, is the technical layer. I recognize there is more nuance when it comes to technical skills, but I maintain that here, too, there is a well defined baseline. You'd expect me to list data structures and algorithms here, and I'm not going to disappoint you. It's important to have a solid understanding of data structures and algorithms and knowing where to use them. Another technical skill which is overwhelmingly overlooked is understanding how computers work under the hood. Does the engineer understand modern computer architecture? Logic gates, for example, interpret varying voltage levels as ones and zeros - the very foundation of binary.
Are they familiar with modern Von-Neumann computer architecture, and understand the different components such as the ALU and Control Unit, which make up the CPU? Do they understand access time/storage space tradeoffs between registers, cache, RAM and disk? When they assign a literal string to a variable, do they understand where it's stored? Do they understand the call stack and heap memory? Do they understand how their high-level code get translated to machine instruction?
Most, if not all, modern systems today contain a substantial networking component. I argue it's important to know what TCP and UDP are, and when to use each one. Maybe even going a bit lower level, and looking at how packets are structured (extra points for messing around with Wireshark). Knowing those HTTP verbs will also come in handy when the REST API needs to be built. I could honestly go on, but I'm satisfied I made my point.
You could argue that understanding how computers work under the hood is extra curricular, and I would totally understand. Unless you work in embedded systems, it's highly unlikely you'll work at that level. But in my opinion, a good understanding of how computers work provides that additional context that makes a real difference when you're writing code, precisely because you can attribute operation costs to abstractions provided to you by modern interpreted or compiled languages.
At the top of the skill pyramid is experience. But here, too, just like problem solving, there are some nuances. When I say "experience", most people will think about years of experience, or "time served". I tend to look at experience as the cumulative hours logged doing the core job. Similar to how pilots are qualified based on their cumulative hours of flying. Engineers who write more code tend to be better engineers, and that should not come as a surprise to anyone. I also think there is immense value in variety of experience. I argue that a web developer will grow faster building a side project in a compiled language such as C, versus learning a new web development framework.
Now, what I wrote above is not to say that the time component of experience is not important - it absolutely is. There are elements of experience which extend beyond what an individual can do alone, or on small side projects. This type of experience typically has to do with differnt environments in which the engineer operates in, different tech stacks, different scale of operation and, of course, diversity of colleagues. It's just nearly impossible to get that kind of experience working as a lone-wolf on side projects, or by working with the same tech stack throughout one's career. The best heuristic for estimating this kind of experience is typically "years of experience", so I understand why employers look for that.
Combined, the two experience types, built on top of the other skills on the pyramid, elevate any software engineer to the status of Ship Mechanic.
But here is the problem
npm install something. They weren't familiar with the standard libraries of node, or how to run a JS file using node, but you know what they did know? Creating class-based components in React with JSX. I don't blame the candidate for this kerfuffle. They must have seen countless advertisements for similar roles with "React developer" in their title, and just made sure they hit that criteria.
Okay, we discussed the "React" part. Let's focus on the "front-end" requirement. It's absolutely not controversial to seek to hire engineers which are specialized, or have more experience with a particular part of the stack. But is it ideal? I argue it is not. Why not hire a competent engineer who is comfortable, or is keen on, working across the stack? This ties to my definition of problem solving. To truly be able to solve a business problem, the candiate engineer should have the breadth of expertise to ideate and execute on a particular solution - from start to finish. This is not to say that I think it's not useful to have teams of engineers working on a particular product or problem, there is immense value in having a team of engineers with complementing skills. But if it came to it, would the engineer be able to build a full, end-to-end solution, on their own? That's the litmus test. By shoe-boxing engineers into front-end or back-end categories, recruiters are causing aspiring engineers to narrow their focus and avert specific parts of the stack, and they rationalize it by stating that there will always be someone else who is in charge of the other part of the stack. I argue that this is, fundamentally, a mistake.
Wrapping it up
I know my little essay here won't change the hiring landscape, but it was important for me to share my feelings on this topic (emphasis on my feelings). I had a conversation with a close friend of mine (hello Friday frag-fest goers!) about this topic, and he sliced through it all, eloquently putting it as:
Aren't you simply making a case for the generalist software engineer?
He is right. This is a case for the generalist software engineer. I wish more of us existed, and for this kind of attitude to be more sought after by recruiters and companies. If job requirements will list more of these foundational skills as requirements, without sticking to the dry specifics, it would encourage aspiring engineers to spend their time on the right things and build solid foundations. Who knows, it may even pay off financially for those companies down the line as they could do more with less headcount.
I'll close this post on a personal note. The name of this domain is
polyglot, which is an evolution of a Greek word polyglōttos, which means "speaking many languages". I chose that domain name to remind myself that is the kind of engineer I aspire to be.