We need to talk about what it means to be a Software Engineer

January 14th, 2024

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:

Hello Anonymous Squirrel, ACME Tech Valley is looking for an exceptional React front-end engineer with 10 years of JavaScript experience, and I thought your impressive background makes you a great fit. When would be a good time to chat?

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.

The skills pyramid

Communication

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.

Technical Foundation

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.

Experience

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

Let's get back to the recruiter email from the first paragraph. I could probably write an entire dissertation on the problems with recruitment in tech, but given that's not the focus of this post, I'll stick to the core topic. The recruiter looked for very specific skills. They wanted a "React front-end developer". I'd like to start with the "React" part. There are no "React developers", there are front-end engineers who have some exprience working with React. React is not, and should not, be a core skill. It is another tool in the toolbox of the engineer. It's much more important to have solid grasp of HTML, CSS, JavaScript and the DOM, over knowing React like the back of your hand. The problem with this super specific requirement, is that it incentivizes aspiring engineers to jump head first into frameworks such as React before they have any of the foundational skills I listed above. And the result?

Here is a relevant story. I once interviewed a candidate for a role in our team. They had to read a few files from the hard drive and do some processing. They chose to solve the problem with NodeJS, which is okay (I still think JavaScript on the server doesn't make sense, but I digress), but the first thing they did was attempting to install an npm package for reading and processing files. They didn't know what package to install, or why use npm at all, but it was an instinct of writing 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.

Now it's time to talk about the language requirement the recruiter had in their initial approach. They wanted an engineer with ten years of JavaScript experience. JavaScript is a language which was created by Brendan Eich in just ten days. JavaScript was designed for a particular purpose - to enable light scripting on websites. It is a tool. Just like C was designed for systems engineering, and Go is great for distributed computing backends. Engineers which are hired to solve problems should be able to use the right tool for the job, and that means being able to work with any language - not just JavaScript or Python. That's why hard language requirements often send the wrong (or right - depending how you look at it) signal if what we want to hire is an engineer with problem solving skills.

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.