0:00
/
Transcript

How to become a better engineer? (human)

Answer: Peel the onion…

This week’s Wednesday Wisdom features a competition of human against bot. I took the question of how to become a better engineer, wrote an article about it, but also asked Midweek Muse (a ChatGPT trained on Wednesday Wisdom content) to write an article about it. I am posting both of these articles and you choose which one you like best. This is the article written by the human.

I sometimes get messages from readers thanking me for all this content and asking me a question. Sometimes these questions are easy, such as how to prepare for interviews (answer: Buy Beyond Cracking the Coding Interview), but sometimes these questions are hard, such as how to become a better software engineer.

As if I know…

Note: This article will contain links to other Wednesday Wisdom articles where I have written more extensively about certain topics. These links will look like this: (ww).

Right, on to the topic then. How to become a better software engineer?

Let us start by realizing that an engineer is a person who solves practical problems using scientific knowledge. So there is a difference between being a software engineer and being a computer scientist. I went to an engineering school, where I learned how to code, whereas a friend of mine attended a more academic computer science program where he did not learn how to code, though he did learn how to prove that my code worked 🙂. Computer scientists know that you cannot prove that a program will ever stop, but software engineers know that all programs stop, typically when you don’t want them to…

The definition of engineering is instructive because it provides clues on how to become a better software engineer: Become better at solving practical problems and make sure that you have the scientific knowledge required to do so.

How to get there?

First of all: Do not be in a hurry (ww). Becoming a better software engineer is a lifelong pursuit and even I, after more than 37 years in the field and counting, am still becoming a better software engineer every day. Becoming a better engineer is a pursuit in which there is no finish line and time will give you all the opportunity you need to acquire knowledge and to deepen your experience. This is especially important in an industry where new things that promise to be game changers are released every day, but where only knowledge and experience can tell you if they do indeed change the game and for the better or not.

NSFW: I often (but not out loud in the office) liken many new developments in our field to particular types of very dirty sex. If you have never engaged in them you might think that you’d really want to try that and that you are going to like it. Those of us with more experience know that it most commonly devolves into a shit show, better not repeated. Of course, there are also people who actually like Javascript…

So you need to become better at solving practical problems. But what does it even mean “to be good at solving problems”? The proof here is in the track record. People who are good at solving problems have a history of solving problems. It is a somewhat intractable skill though, closely related to debugging. There might be a method to the madness, but it is hard to define exactly what the right method is.

Success at solving problems starts with being able to figure out which problems are worth solving and which ones are not. The fact that a problem is a problem does not automatically make it worth solving. It might not happen often enough. The impact when it happens might be negligible or easily addressed in other ways. The problem might be intractable or so expensive to solve that it is really not worth it. There might be bigger or more urgent problems to solve. Many people seem to be of the opinion that a problem is worth solving because it is a problem and it can theoretically be solved. That is a recipe for misspending your time and money on things that do not move the needle.

I was recently asked by a junior colleague what it took to be successful at our company. I had many things to say about this, but one particular piece of advice was to be mindful of what you are working on and if it was, all things considered, the most important thing that you could be working on. The simple fact that you are working on something that is on fire is not enough, because there might be bigger fires!

Solving problems requires tenacity. Or, as Thomas Edison reportedly said: “I have not failed, I have found 10,000 ways that do not work. If you give up too early, you will never solve any difficult problems, which means not getting better at solving problems and not building a track record. If you have solved a problem, you might want to give it some more thought to see if there is not a better, simpler, or easier way to solve it. When attacking a difficult problem, it is easy to be discouraged if success does not immediately materialize. Don’t be; few problems worth solving are easy to solve. Good software engineers have a method, but above all, stamina.

Being a software engineer (or, an engineer of any type, really) means working in groups. So to be a better software engineer, you need to be better at working with other people. That requires a whole array of interpersonal skills. First and foremost, you need to be able to communicate well, both in written form (ww) and verbally. You need to be able to communicate strategically (ww), have difficult conversations, and speak in public.

A lot of group work takes place in meetings, so you need to be effective at those too. You need to be able to make a plan and execute on it. Eventually, you will need to be able to direct the work of others and keep them on the straight and narrow.

None of these skills are easy to acquire, but all of them can be learned and practiced. There are books on these topics (most are crap), there are courses (most of these are crap too), there are coaches (most of them are …, you get the drift by now). But, if anything, the volume of material available to help you get better at this indicates how important it really is. We have all had ample experiences with people who were technically excellent, but who couldn’t work with people, making them less effective than they could have been. These people might be excellent coders, but they are bad software engineers because their leverage is typically very low (though exceptions do exist).

Example: Linus Torvalds is an excellent coder, but I would argue that his major achievement is that he got and keeps a community of people together that develops and maintains the single most widely used and complicated monolithic piece of software on the planet. That requires a ton of technical knowledge, but it also requires a ton of people skills. Not that Linus is the most suave interpersonal operator ever and I doubt he could be successful inside a bank or government, but the skills required are situational and his skill set apparently matches the kind of people he needs/wants to work with to get the job done. That said, even Linus had to work on his people skills…

So, how to become a better engineer, part one and two: Become better at solving problems and improve all the skills you need to work effectively and efficiently in groups. Like all things that you want to get better at, this requires study and practice.

Part three of the story is “technical knowledge”.

Long story short: You can never have enough technical knowledge and you need to be able to apply it in service of solving practical problems.

As behooves an old person, I am regularly shocked by how little younger engineers know about computers and about the basic software and protocols that make them work and work together. Obviously, that is somewhat unfair to the younger generation because if you get into the field today, your first steps are taken on top of a software stack that is a mile deep and working on hardware that is so complicated that it sometimes runs its own on-CPU operating system to keep it all going. This is in stark contrast to the first computers that I started working on, which could be understood completely by a sixteen your old, down to the circuits.

But, we all got to start somewhere and there is only one way to get better and that is to peel the onion.

I started programming in BASIC and then started wondering how that BASIC interpreter was implemented. This forced me to learn 6502 assembler, which in turn gave me access to the operating system. I then wondered how other programming languages worked and I spent a good chunk of the summer of 1985 disassembling and studying the rqForth interpreter, which gave me my first insights into programming languages that are partly implemented in themselves. A mind-blowing experience!

This experience led me to implement the run-time library for a Pascal compiler and runtime that we had to develop in the last year of college in Pascal itself. The teachers didn’t quite understand it :-)

When I moved on to other computers and other languages, the tactic of peeling the onion kept working for me. When I started coding C++ at a time that I didn’t understand C++ very well, I regularly compiled my C++ code with the “list” option to look at the assembler that the compiler had generated in order to figure out what the C++ compiler thought I had meant and how various C++ features, like virtual functions, were implemented.

Surely, that is something you can just ask ChatGPT these days, but imagine a world without the Internet, where copying software is easy, but copying books and manuals is hard and expensive. I literally spent days throwing quarters in the Xerox machine in my college while copying books and manuals; not cheap, but cheaper than buying all the books that I wanted to have.

Regardless of where you start your software engineering journey today, just peel the onion. If you are starting with Python, wonder how Python works. Branch out to C and study the CPython interpreter. Modify it to add a new Python feature or do something else similarly useless and inane. If you run on Linux or FreeBSD, build your own shell, including features to redirect standard I/O and running commands in the background. Whenever you work with something, do not satisfy yourself with understanding the outside of that thing, wonder about the inside and learn about it. Because of open source, we live in a golden age of being able to understand most essential software inside and out. You should use that opportunity.

“But Jos”, I hear you think, “that sounds like an incredible amount of work. Why is all of that necessary?”

Yes, you are right, it is an incredible amount of work. Fortunately, you have an equally incredible amount of time to do it in 🙂. Remember one of the first sentences in this article: “Do not be in a hurry. Becoming a better software engineer is a lifelong pursuit.”

All that technical knowledge is required for three things: To quickly ramp up on new technology, to debug, and to be able to make the right judgment calls.

New technology does not appear in a vacuum, but instead is grounded in existing technology. Having a good grasp on how that existing technology actually works under the hood is essential for getting up to speed with the new technology.

Time for an anecdote: At Google we had developed our own clustering technology: Borg, which offered features for what we now call container orchestration. In my days, almost every site reliability engineer (SRE) at Google needed to understand the ins and outs of Borg in order to run workloads reliably. Somewhere in 2008 or 2009, I was interviewing a candidate for an SRE role. On their resume they had claimed years of experience with Hewlett-Packard’s HA clustering solution: MC/ServiceGuard. As it happens, I used to teach MC/ServiceGuard courses at Hewlett-Packard and so I grilled the candidate on their in-depth understanding of this product: How it worked, how it locked disks, how it behaved when network interfaces went down, how it reached consensus, et cetera. After half an hour of this, the candidate asked me, in a somewhat exasperated tone of voice, why I was grilling them so much on this. Were we using MC/ServiceGuard internally? No, of course not, but if, after having worked for years with MC/ServiceGuard, you do not understand that product inside and out, what are the hopes of you learning Borg inside out?

Understanding Kubernetes is much easier if you understand containers and TCP/IP. Understanding containers is much easier if you understand Linux cgroups and chroot. Understanding chroot is much easier if you understand how the Linux kernel deals with file systems. The list goes on. Understanding Kubernetes in a vacuum is almost impossible. Being able to peel the onion is essential.

In-depth technical knowledge is also essential for debugging (ww). Debugging is a much-underrated skill for software engineers in the sense that we do not teach people how to do it and we do not interview for it either. But every software engineer I know spends more time debugging than coding. There is a method to debugging, and someone should write a book about it (oh hang on, they did), but having the method but no technical knowledge will not work.

Almost every day I am amazed how bad people are at debugging. If I have any career advice to give on how to become a better engineer, it is this: Learn how to debug! Debugging does not only require technical knowledge, it gives you new technical knowledge. More than half of the arcane things I know, I know because I debugged some problem where some technical tidbit proved to be the crucial insight.

Third aspect of technical knowledge: Judgment.

As a software engineer I make judgment calls each and every day. Is it worth fixing this bug? Should we use this component to help solve this problem? How to fix this oncall rotation? Use a better algorithm that is hard to understand or a worse one that is simpler? Buy this software product or implement our own solution? It is quite simply impossible to make the right judgment calls about technology without in-depth understanding of that technology.

This is also why you should never trust managers who are proud not to be technical (ww).

Becoming a better engineer means solving bigger and more complicated problems, using ever more advanced and more complicated technology, and in bigger and more diverse teams. It requires peeling the onion in everything you do to figure out the thing under the thing that makes it all work.

That amount of effort is not for everyone. But ask yourself this, if you are not doing this, what are you going to do in an age where AIs will do all the obvious technical work?

Support human labor! Subscribe to Wednesday Wisdom!

Discussion about this video

User's avatar

Ready for more?