A long, long time ago in a corporate universe far, far away... I was admitted to an elite group. A group where the members each had a manifesto. Chris was a founding member of the group, and has since published his manifesto on his blog. I don't quite know how I was deemed worthy for membership. My manifesto was unpublished, it was mostly unfinished, and it was unseen by all but me. Regardless, I was admitted. A fraud. Living a lie. For years I have lived with this shame.
At last all can be revealed, for here is my manifesto. Or as I originally called it, my List of Skills and Knowledge That All Developers Should Have. There are 9 items in no particular order, so I guess that makes it a set rather than a list for all you pedants in the audience (and I know you're there).
The idea is to document a set of skills that every developer should have. That's everyone who develops software professionally. Doesn't matter what type of position or company or industry; this is my stab at a body of knowledge that every serious developer should have. Essentials, essentially.
It's partly based on experience; specifically the experience of surprise I felt when a colleage, or random stranger on the internet, expressed ignorance at one of the items on this list. Other items on the list have come from an exacting process of posterior extraction. I'll leave it to you to guess which is which, and who is who. Or at least skim the headings. Read on.
Opening the list with a clearly endangered species, a bold step you might think. So maybe I'm just Old Skool but so much of software development falls to the task of managing dependencies between files. And although you may not have to explicitly set these dependencies, you almost certainly should know how these dependencies are created and used by your tools. The Youth of Today are lazy good-for-nothings who spend all day in their fancy IDEs and do a clean rebuild at the first sign of trouble.
By the way, Java developers who routinely, often unwittingly, introduce circular dependencies between source files and rely on the compiler to sort it all out may be feeling a bit smug at this point. Until they reflect on their own build tools, that is.
Java aside, the reality is that the principles of dependency-based build tools are core to software development in almost all languages. IDEs often encapsulate these principles. And even if you never physically write a Makefile yourself, the ability to diagnose a dependency problem is something that you will almost certainly have to do at some point.
Which is not to say that you should really be using the
make tool itself for serious software development, at least not while there are perfectly reasonable alternatives available. Or if you do insist on using make, at least be aware of its limitations and syntactical gotchas.
Even if you're an English speaker and you are writing for an English-speaking audience you'll quickly find that ASCII is très passé. But if you work outside that (increasingly) small set without Unicode, you're toast. You need more characters, and Unicode has 'em. So unless you are going to condemn yourself to writing software that never sees human-language text — and that is a very small niche indeed — my advice is to bite the bullet and start learning about Unicode. (Maybe start with BULLET POINT, U+2022).
In between running an application 'blind' and a up-to-the-elbows session with a debugger, there are tools I will call 'sniffers', because the packet sniffer is one important example. But really I'm talking about the general class of tools that monitor running applications by what they do under the covers. What files they have open, what network traffic they generate, how much memory and CPU they use, and even what system calls they make. Sometimes you need to use these tools on other people's applications to find out why (for example) it crashes on startup. Sometimes it's easier to use
lsof to see what files your application has open than try to work through it with the debugger. And sometimes it's just a learning experience to see at a high-level what your application is actually doing.
With the increasing importance of network communications in just about all software these days, packet sniffers are a particularly handy tool. If you know how to drive a packet sniffer like tcpdump or ethereal, including filtering the output for a specific exchange, you have a) sufficient IP networking knowledge to call yourself a developer, and b) some handy skills for debugging (even when it's not your code).
4. System Administration
In an enterprisey environment, the chances are that if you are developing something, someone else will be administering it on an ongoing basis in production. Of course your trusty systems engineer should document for you all of the unstated requirements that often accompany such deployments. But regardless there is no substitute for actually experiencing the pleasure and pain of installing, configuring, monitoring, backing up, and securing the software masterpiece you have just written. (Not to mention using it...)
This means learning about system administration. Finding out about how best to develop applications to best conform to local conventions, how to ensure that user data is clearly separated from the application itself and can be backed up, and getting your logs to be auto-rotated so they don't fill up the filesystem.
My advice is to get yourself a server and try to keep it functioning 24/7. When you fail, think about the lessons this implies for the software you write. And years down the track, thank me for my sage advice.
There's only one programming language in this list, and C is it. Not C++, or C#, but C.
C is the language which is the basis for all others, often quite literally. That fancy Java VM? Written in C. The Ruby interpreter? C code again. Fancy .NET CLR? Python reference implementation? Lisp runtime? All C. In fact, name me a general-purpose programming language which is not primarily implemented using compiled C code. I can't think of one.
Why is it so? Because C is the most portable language around. Can you name a single hardware platform produced in the last 30 years which did not have a C compiler? It's just unthinkable. From the most resource constrained to the most powerful computing systems in existence today, C is the lingua franca.
Not all programmers code to the bare metal, it's true. But even the most high-flying architecture astronaut would have to concede a knowledge of the fundamental architectural principles of modern computing equipment is prettymuch essential. And that's what experience with C gives you, an understanding of stacks and heaps and pointers and all of the other things that your high-level language tries to hide from you and, inevitably, doesn't.
If this list was ordered, C would be number 1. You have to know C, end of story. [Update: Apparently not]
Hey did you hear there's this amazing new thing called the Internet? Looks like it might catch on.
Instead of passing Microsoft Word documents around the place, the Netizens prefer to pass around text files containing a "markup language" called "HTML". It may look bizarre, with angle brackets and stuff everywhere, but the rules are really quite simple. There are only about a dozen tags that you have to know, so just learn them already. OK?
Oh, and in case you were wondering, the web is not WYSIWYG, and nor is it Sharepoint (and that is a rant for another day...).
7. Source Control
Shipping vast directory trees about the place is not source control. In any serious team development situation, you must be able to branch and merge, which in turn means that you must know how to drive a source code control system that supports this. Or one that comes close.
I'm not entirely sure how to be more precise here, but I suppose you should have some knowledge of the theory of source control systems, some common usage patterns (eg integration branches, release branches, etc) and detailed working knowledge of at least one implementation.
Besides code reviews, choice of source code control systems is the most reliable source of religious wars between developers, so I'll leave it at that. Just pick one and learn to use it.
8. Regular Expressions
Look, there's no doubt that they can be kinda tricky, the implementations are frustratingly divergent, and they are a bit ugly. But once you've got the hang of them, regular expressions will make your life as a developer so much easier. If nothing else, you'll at least be editing your source files a lot more effectively.
Like any tool though, you have to learn when not to use them. Otherwise, as the saying goes, you'll end up with two problems. Regexps should generally not be used to parse XML, for instance. They are great'n'all, but one day you will need a real parser.
9. A Scripting Language
Omissions, Deliberate and Otherwise
"What about <insert pet skill/knowledge here>? Surely you can't be considered a software developer without having some expertise with that!?"
Yes I acknowledge up-front — well, at the end really — that my list is incomplete.
Some things I have omitted deliberately, like any mention of Object-Oriented design for example. When considering this for inclusion, I imagined someone who might not have a lot of expertise with O-O design, but who is clearly a worthy developer. After coming up with an example, in this case Linus Torvalds — though apologies to Linus if he is an O-O expert unbeknownst to me — I rejected O-O as essential knowledge. It just is not applicable to many specialised domains of software development, and hence is not an "essential". Ditto XML - I can imagine Linus going through his entire career without knowing very much at all about that topic (except as required by HTML, see above).
At the other end of the scale, are the niche topics. How much assembly language does a software developer have to know these days? I'd argue not that much, really. You need to know basic systems architecture stuff like registers and addressing modes and such (see also C language above), but these days the need to drop to assembly is pretty uncommon. For this reason I tried to focus the above list on skills and knowledge that were of practical day-to-day benefit rather than topics that are learned in university and then forgotten.
Other items seemed too vague or overly-broad to warrant inclusion in this list. It's true that every developer should master their text editor of choice - but it's hard to define exactly what that means. Likewise algorithms; which are essential? And every developer should know, through practice, about testing; what types are available and applicable, how to assess results, etc. But how to nail it down further than that?
So there you have it, my manifesto, or what passes for such. Next time I'll be more wary about accepting admission to groups that would have me as a member.