A student emailed me, asking about what I do for a living. Not just my job title, but what specifically the job entails on a day-to-day basis. You know, that’s an interesting question, because I had the same question myself at that age. I loved programming. I knew I wanted to do it a lot, which suggested it might be a good career. But I didn’t have a clear picture of what a day at work would really be like. Certainly the job is more than just writing code, right?
The answer is, annoyingly, “it depends”.
The term “software engineer” is pretty loose, and ends up being applied to just about anyone who writes code. (Which is probably incorrect. Like calling a brick layer a “civil engineer”.) Rather than argue over definitions, we’ll just go with the broadest possible interpretation of the word.
I work for a small company, and like most small companies everyone has very broad responsibilities. If I worked at a big company, a lot of my duties would be split between senior and junior members. The size of your company will have a bigger impact on your job than just about anything else. Microsoft and Apple might have a very different corporate culture, but they’re very similar compared to (say) working for a company with seven employees. Having worked at both a large company (over 100 people) and small ones (less than 10 people) I have to say I like working in a small outfit far better. Maybe I’ll compare the two in another post, but for now we can just simplify it by saying your duties will become more diverse as the company size shrinks, and narrower as it grows.
Keeping this variable nature of the job in mind, here is a list of fundamental duties that will probably be a part of any Software Engineering career:
Estimating a task
Someone will come to you with a software problem.
Tiny problem: “The daily reports don’t print the full date, which is causing paperwork confusion”.
Small problem: “We need a program to scan a set of directories and delete files older than X days or larger than Y bytes”.
Large problem: “We need our software ported to run on Macs”.
Gargantuan problem: “Write a full-featured operating system”.
Your job will be to draw on your knowledge and think about how long it will take to solve this problem. How many programmers will be needed and how much time will they need? I do this on a regular basis, although it’s the part of the job I hate most. In a larger company this sort of thing is generally given to the senior programmers.
Once you give your estimate, someone else (probably not an engineer like you) will look at the problem and the cost to solve it, and decide if it’s worth it. If it is, you’ll end up doing…
This part of the job varies greatly. “Design” might mean, “sit in your cubicle and think for a few minutes before you get started”. Or it might mean, “attend meetings with other software engineers, design charts, and do extensive planning”. Generally, the bigger the problem gets and the more people you have involved, the more formal this process is going to be. You can’t begin building a bridge until everyone agrees precisely where it will be and what it will be made from. And you can’t write software until you understand how it will work once it’s complete. You need to decide what tools will be used (perhaps even decide on a particular programing language) who will do the work, and how all the parts will fit together. Alice will build the interface. Bob will write the server. Carl will write the client. Dave will port Carl’s work to Linux. Etc.
Maybe you’ll talk to people that have expertise relating to the problem. For example, I know just enough about databases to get myself into trouble. When you need to store data in a database, there are dozens of ways it can be done. Some will be ploddingly slow or consume lots of storage space, and others will be fast and lightweight. A clueless programmer can make a mess without realizing it. Whenever I do anything with databases I ask someone who knows more about databases than I do. I describe the solution I have in mind and ask if they see any obvious errors to my approach.
Note that nobody can be an expert on everything. User interfaces, databases, web applications, client / server stuff, 3D rendering, etc. You’ll probably end up specializing in a couple of them and leaning on colleagues for the others.
Once you know how the system will function, it’s time to…
The meat of the job. You sit at your desk and type arcane symbols and indecipherable nonsense. At least, that’s what it looks like to non-coders.
You’ll hear programmers talk about using an “IDE”, which stands for Integrated Development Environment. It’s basically a word processor for computer code. While not all programming jobs involve using an IDE, it’s certainly the most common sort. You’ll type code into it all day, occasionally running the your program to see how it works.
This is the part of the job I love. It’s solitary work, and the part of the job that requires the most intense levels of concentration.
Once you finish a feature or reach a major landmark, it’s time for…
In a big company with big software, this is done by a team of people. In a small company, it might just be a couple of people. In a really small project, you might do this yourself. The goal is to find bugs or design flaws. A bug is when the program does something that the programmer doesn’t intend, like always print January 1, 1970 for today’s date. Or crash. A design flaw is when the program is doing what you expected, but it’s still not satisfactory for some reason.
Tester: The program runs really, really slow on graphics cards with only 64MB of memory.
Programmer: I didn’t know you wanted it to run on graphics cards with only 64MB of memory.
In my experience, design flaws are usually the result of an oversight that happened during the “design” phase. You’ll end up going back to the drawing board and fixing problems you (or your boss) failed to anticipate. Sometimes this will be because you didn’t think the problem through. Sometimes it will be because you weren’t given clear objectives. Programmers and their managers blame each other a lot, and you can always find amusing or tragic anecdotes about friction between the two. This conflict is one of the ongoing themes in Dilbert. In truth, designing software is a big job and any decent-sized project is bound to have lots of misunderstandings like this.
And of course testing leads inexorably to…
The old axiom applies: “Programming is debugging.” Your program will fail in various ways that you never discovered, and you’ll have to fix these problems. This is the part of the job that requires the most intuition. Once your program goes through testing, you’ll be given a list of problems, errors, bugs, and crashes.
The trick here is that people will explain problems to you, and their description will often be confusing or misleading. They aren’t tying to annoy you, they simply don’t understand your job, which is fine.
Hey, when I select an option from the menu, nothing happens.
Hm. You try it yourself, and it seems to work fine. What’s going on here? You’ll spin your wheels for a while. Eventually you’ll go and try to duplicate the problem on the tester’s computer. You try it, and it still works just fine. You ask the tester to show you the problem while you’re looking. They do, and you notice that they’re using the keyboard to navigate menus instead of the mouse. Sure enough, highlighting an option and hitting the enter key doesn’t do anything. You forgot to set up the keyboard handler, because you always use the mouse for stuff like this.
This is where you’ll really get better with experience. A senior and junior programmer might both be equally smart, and (if they’re using a new language) they might both have the same amount of experience with the given language. But the senior programmer will be able to cut to the heart of a misunderstanding like this much faster. As in, the new kid will spend hours on a wild goose chase and the old-timer will perceive the root of the problem in a few seconds.
Do not scorn the older programmers. If you’re fresh out of college, you might be tempted to think of yourself as the New Hotness because you can work longer and faster than someone in their fifties. You might even have the hubris to imagine you’re “better” because you can output (say) twice as many lines of code. But I would urge you to keep your hubris in check. In college, they never teach you just how much you don’t know. You will spend the first few years of your career learning this the hard way, and it will help a great deal if you don’t make a fool of yourself in the process.
There are other duties that orbit these basics. Maybe you’ll dabble in hardware. Maybe (like me) you’ll end up writing a lot of documentation. Maybe (like me) you’ll be called on to take technical concepts and explain them to non-technical people. Maybe you’ll specialize in writing software for use by people in your company. Maybe you’ll write software that is sold to large clients. You might even end up working on software that gets put in a box and sits on the shelf at Wall-Mart. It all depends on where you end up and what they decide to do with you.
So that’s the job. After all these years, I’m still comfortable calling it “a good gig”. It’s not for everyone, but there are a number of people who can derive a lot of satisfaction from the work.
Quakecon 2011 Keynote Annotated
An interesting but technically dense talk about gaming technology. I translate it for the non-coders.
Spec Ops: The Line
A videogame that judges its audience, criticizes its genre, and hates its premise. How did this thing get made?
A video Let's Play series I collaborated on from 2009 to 2017.
Batman v. Superman Wasn't All Bad
It's not a good movie, but it was made with good intentions and if you look closely you can find a few interesting ideas.
Mass Effect Retrospective
A novel-sized analysis of the Mass Effect series that explains where it all went wrong. Spoiler: It was long before the ending.