In fact, I think you can tell a competent software developer from an incompetent one with a single interview question:
What's the worst code you've seen recently?
If their answer isn't immediately and without any hesitation these two words:
My own.
Then you should end the interview immediately. Sorry, pal. You don't hate software enough yet. Maybe in a few more years. If you keep at it.
I have always enjoyed Jeff's columns and maybe I'm missing a subtle point (or just taking the bait), but this may be the worst "advice" I've ever read on hn.
If someone told me that the worst code they've seen recently was their own, I'd wonder why.
I feel confident in my own ability to usually write excellent code on the first try. Sure, it may need some refactoring, optimization, and flushing out of features, but it works, it generally works well, is very well documented, and can be easily enhanced by myself or someone else. If it's not right on the first try, I will fix it before I promote it. Shame on me (and anyone else for that matter) for leaving behind garbage for someone else to inherit. I've cleaned up far too many messes to allow myself to become like that.
I'm probably not alone when I say that I love developing new code and often hate maintaining someone else's mess.
Jeff is right about one thing though, almost everything I ever inherited was crap in one way or another, probably written by someone "less than senior".
I'd rephrase the whole interview question:
"What's the second worst code you've seen recently?"
The irony of you saying "almost everything I ever inherited was crap in one way or another" is that somebody probably said the exact same thing about your code. I bet you write amazing code, but when given a choice, programmers would rather have the joy of creating their own code than trying to interpret someone else's.
In the mid 80's I worked for a game company for about a year (Aackosoft, flightdeck, indy 500 on the Atari) and I inherited a project from another programmer. After reading the code for a couple of days I realized that he'd been planning his 'exit' for a considerable time. The could would assemble (the 68k part) and compile (the C part) but other than that you couldn't make heads or tails of it.
Every variable was named after a vegetable, a fruit or a plant and every subroutine after a famous person.
It took quite a while just to get things back to self documenting names, after that another month or so to restructure it to the point where it started to do what it was intended to do.
There would indeed have been much joy in writing it again, but there was just as much joy in figuring it out and getting it to work.
When it comes to maintaining code, I believe there are 2 kinds of crap: subjective (I don't like it) and objective (it's crap because of these 14 specific reasons).
You're probably right about people who inherit my code. I know, when they've whined about it, I confronted them. "Please show me exactly what's wrong with it. What are your specific complaints about violations?" I rarely got an objective answer. It was usually something about formatting, indenting, variable names too long, variable names too short, I'm use to it the way we did it (wrongly) at XYZ Co., something like that.
True crap can be objectively identified by a violation such as:
- variables named so that no one except King Tut could possibly figure out what they are
- the same variables used for different purpose at the same time, usually in nested recursions
- variables named with 1 or 2 characters
- unassigned variables
- variables initiated when they shouldn't be
- division by zero
- single entry, multiple exit (heavily maintained so that now outlying cases skip critical logic)
- the same code in multiple places (only some of it maintained so that outlying cases skip critical logic)
- data base tables with no definitions either in the schema or any code (my new favorite)
I could go on and on, but you kinda get the picture. I wonder how many readers here have posted crap like this on their "wall of shame" at one time or another. It's funny the first 2^n times. Not so much fun anymore.
Those are technical issues. The truly most nightmarish software to inherit is one that shouldn't have been writen to begin with: software made by people who either lack the programming skills, or the domain knowledge. Nothing worse than an accountant-turned-DBA's perl, or a system's programmer that just left you an steaming pile of MFC GUI. Worst of all, the person responsible for the mess is not long gone and forgotten, quite the contrary, he has been promoted through and he is now responsible for interviewing you to polish his brown magnum opus.
I breath a sigh of relief whenever Microsoft breaks and old DLL's compatibility: when you can't push through for an upgrade, pray for Redmond to force it.
[Update:
``The hardware-specific accounting package''
This one is truly the "winar": plain-jane boring software that for some goddamn reason depends on that old Hayes modem, or this matrix printer. I have been hired to do this shit so often it's not even funny; it tends to sneak past the initial discussions. You tick off "GUI" and "ODBC" and you're on your way to start hacking, making a mental note about "ability to print". What you don't know is that, not only do they want to convert the old Access package to an intranet web app, but they also want it to print receipts using the "receipt printer" -- a custom made piece of pain that uses the parallel port for data, the serial for control, and two RJ45s to whistle the Danish national anthem on error. FUCK!]
Now I can't sleep (why did we have to talk about bad code?)
``The Windows 3.1 Guru''
1) That guy who knew too much about Windows 3.1 internals and never thought this newfangled "Windows for Workgroups" or "95" would never take off. Thank you, sir. Treating obaque structures for the unsigned chars they are has never posed a problem for me. All the documentation I needed was in those 4 pages of macros you left me (completely unnecessary, given the clarity of their octal values, btw) Indeed, 10 years later, the low nibble of the AL register held an integer index into your very own "stash area" just below the PSP (task_struct for linux weenies) where you kept all the open file handles. Clever of you, reusing every bit of the process memory, specially the unused parts of the MS DOS header format. (long story about this destructive log-rotate elided)
Your share custody of this award with Mr. EE.
2) Mr. Electrical Engineer, how can I forget you? We all know it's all signals and gates down there, so, yeah, it was refreshing to see them again! I can't believe you rolled your own signal-driven layer on top of the Win32 message system. The ordering system couldn't have been done any other way. Looking at your code put a bar over my head, sir, you have asserted me. And to be honest, Visual C++ needed your linguistic extensions; we all know, code runs faster when it looks more and more like Fortran.
Some of these "violations" are good ideas in some contexts. Tom Duff has written a pretty good, clear case for "single entry, multiple exit" in the form of multiple conditional return statements in a function. And Rob Pike has made a pretty clear case that this:
for(i=0 to 100)
array[i]=0;
is better than this:
for(elementnumber=0 to 100)
array[elementnumber]=0;
But that involves variables named with 1 or 2 characters.
The rest I pretty much agree with, except in very unusual cases.
I have always enjoyed Jeff's columns and maybe I'm missing a subtle point (or just taking the bait), but this may be the worst "advice" I've ever read on hn.
Huh... I generally don't enjoy Jeff's column, but this is the first one where I was nodding my head the whole time. In fact, I had even copied the above quote from the article just to comment on it, but in affirmative agreement. To give some context, I'm on a team that is about to ship a very, very large project, and I have to say that I honestly believe my team's part to be the worst bit of it, and my own contribution to be the worst part of my team's code.
Well, maybe not really...but I can't shake this feeling every time I go in to work.
Here's why I think Jeff is right: Software, done well, is like magic. You don't see the arrays and pointers, you don't see that it was programed with objects and/or functions. You see an interface, you click some buttons, you type some words, and BAM! You get exactly what you want. At least, that's the user experience. If, however, you're the one writing the code that makes the magic work, then you know what's going on under the covers. You see the arrays and pointers and objects and functions. The magic is dead. The code is just a repulsive, heaping pile of bits with no special properties whatsoever.
If you tell me that your code is not the worst code you've seen recently for X, Y, and Z reasons-that-only-make-sense-to-a-programmer, then you've missed the point entirely.
I imagine the Wizard of Oz might have looked at his contraption and thought to himself "This is the worst hunk-a-junk illusion I've ever seen."
I don't understand your analogy. Is the Wizard of Oz repulsed because he thinks the illusion is bad, or because he knows how it's made? Would "This is the worst hunk-a-junk implementation of an illusion I've ever seen?" be an accurate interpretation of what he means?
Jeff's post and your comment both confuse me on this point - I can't figure out when either of you are talking about quality of implementation (when I read "code" I think implementation) and when you're talking about quality of user experience. I'm not even sure if you and Jeff are saying the same thing. Jeff spends most of his post talking about bad user experiences caused by programs written by people who are probably not experts, but then he ends by saying that all programmers should hate their own code. I, and most people on HN apparently, interpret this to mean that we should all hate the quality of our implementations. Not only is this weird on it's face (surely many people who read Jeff's blog, let alone HN, have seen worse code than what they usually write themselves), but it doesn't seem to follow from the rest of the post. My reading of your comment leads me to believe that you dislike all code/implementations on general principle, but I can't tell if you even refer to the user experience at all. The second to last sentence seems to, but I can't figure out how the rest of the comment relates to it because the rest of the comment seems to be purely about implementation (except for the reference to the Wizard of Oz, which is completely ambiguous in that regard as far as I can tell).
My experience seems to be different than yours. I might have thought of software as magic when I was exposed to computers for the very first time, but as soon as I learned a little bit about how they worked none of it was really "magic" any more. A good user experience might be smooth, or quick, or intuitive, or even delightful, but I don't see it as magic. Occasionally I see something and I don't know how it was done, and it that case I want to know. I want to look under the covers, just like I wanted to know how computers worked. The connotations of "magic" hardly arise, because I immediately move past the "I can't believe that works!" stage to the "how does it work?" stage. I assume (or in the case of computers, know) there is machinery under the covers even before I see it, and I want to see it. There is nothing necessarily repulsive about the machinery to me, and in fact the machinery has its own beauty that is largely independent of the user experience. My ideal piece of software delivers a fantastic user experience with beautiful machinery, but I understand that beauty in one part does not necessarily imply beauty in the other. The user experience is generally more important than the quality of the code, but there is no law that says code has to be repulsive. We seem to disagree about that.
I would not say that my own code was the worst I've ever seen, but I am always dissatisfied with it and with the user experience it delivers because I always think it could be better. I completely agree with Jeff's Parnas quote, and I also agree that Jeff is probably an incompetent programmer in the judgement of Parnas and others like him. So I maybe I agree with Jeff's intended point. On the other hand, I think Jeff has delivered some pretty good user experiences, and I think many programmers who really don't produce great code and/or create a net increase in programmer demand can and do deliver decent, or even fantastic, user experiences. (This is probably one of the reasons why we have so many incompetent programmers and don't live in Parnas's ideal world. Relatively incompetent programmers can still deliver good user experiences, so in the short term it's expedient to deliver software that way. In the long term, we have a shit ton of deeply stacked shit and all the really good programmers are spending their time making shit shoveling tools instead of advancing the state of the art, but hey. Just another tradeoff.)
Speaking for myself, I know I'm an incompetent programmer who would not have a job in my own ideal world, but my goal is to not be that guy, and I would prefer not to hire that guy, or the guy who has never seen worse code than his own, doesn't make a clear distinction between his own level of skill and the level of skill displayed by crapware developers, does not aspire to write anything terribly ambitious from a technical standpoint, and in fact has nightmares about it. I enjoy programing, and I am more suspicious of people who say they hate software than I am of people who say that their own code is not the worst they've ever seen.
Get out, see the world, look at other peoples' code (particularly the stuff they don't release publicly), and I can guarantee you will be surprised at what people can make run.
I believe there is a saying that there will always be [code] better than [yours]. The opposite is also true: There is always code out there which is worse than yours.
I think Jeff is exaggerating a bit with his phrasing, but I think there's an important point there: humility is always important, and it's the only way you ever improve. As soon as you start being really satisfied with your own work, you stop trying to improve it, and that's a dangerous point to be at. Most of the best programmers I know personally are all highly self-critical about their work.
I also think it's important for one's job satisfaction and enjoyment of life that you take pride in your work and can be proud of your accomplishments, and I think it's important to be able to juxtapose that level of satisfaction with a constant drive to improve (I actually blogged about that topic a couple of months ago http://guidewiredevelopment.wordpress.com/2009/05/07/it-can-...)
It's also far too easy to assume that everything written by everyone else is crap simply because it doesn't map to how you would solve the problem, and while some of it certainly is crap, it's important to be charitable in your analysis there. Becoming better means being open to learning from other people's ways of doing things, and being a good teammate means giving your coworkers the benefit of the doubt and assuming that if something doesn't make sense to you or seems ugly, perhaps it's because the problem is more complicated than you thought, or perhaps they had to inherit some ugly legacy code, or perhaps the problem domain just wasn't well understood at the time the code was first written.
"but it works, it generally works well, is very well documented, and can be easily enhanced by myself or someone else."
Yeah, but maybe for you "excellent, clean code" means you have moved everything into XML configuration files. I thought the general consensus was that real experts can never know that they are experts, therefore your claims would make me wary of your skills.
Isn't there always a way to write things even better, cleaner, more effective, more modular, whatever? In that sense I think all of my code sucks. I am sure some people out there write worse code than I do, but I am also sure there is much better code.
If you think you are so good, are you even still trying to improve yourself?
The only way I see to write "perfect" code is to adhere to some standard perfectly. Like J2EE development: you have strict rules for putting stuff into XML files and so on. So if you did all that, and raked in the money, you can call your code "perfect". It would still suck, though.
I completely agree that pretty much every proprietary software product that has come bundled with a device I purchased has been useless crap. There's probably one or two exceptions but I can't think of them.
I didn't find the rest of the article that interesting, but he definitely nailed his first point.
It's not so much bad programming, it's more a case of why? Why do I want to install something that by default will chew up memory by running in the background (and default to launch on startup), that I will never use, because I have so many better tools for the job.
I guess the argument is that it's useful for non power-users... Umm sure. How many of you have been asked to fix something on a relative or friends windows box only to find it grindingly slow because of all the run-time resident crap running on it? Like 10 things in the system tray? Update notifications launching one after another on boot? My first task is usually removing all of this stuff they NEVER use before even tackling the real problem they're having.
You should consider your code to suck over time, if you're "doing it right".
If you keep learning new and better techniques and practices, old code starts to look immature. If you code in the real world, you make compromises to get a project launched before you're living in an alleyway.
TicketStumbler may be a steaming pile of crap in some places and my deployment strategy may have devolved to "install random packages until it stops throwing internal errors", but it was not always this way. Not only have I managed to become an even more amazing programmer in the past year (against all odds), but I've had to cut so many corners the whole thing is beginning to look like a circle. These two factors, above all others, have caused me to rather loathe my code. But that doesn't mean I always do.
Maybe this was the point Jeff was attempting to make? If I am only good by hating all my code, I don't see how I could ever be good.
I'm a little bit nervous to say this, but this is another of Jeff's articles where I think "man, so many of this guy's problems would go away if he didn't hate Macs so much".
In my experience, Mac devs don't hate software, and Mac users don't have the instinctive "oh [App X I haven't heard of]? That's going to suck".
Gruber talked more about this in his Broken Windows essay -- http://daringfireball.net/2004/06/broken_windows -- and what he said about security is generally true for quality and polish as well. If I get a new app for the Mac, I know that it's going to have basic standards of fit and finish and will make a reasonable attempt at being a good Mac citizen, because otherwise the community will kill it.
When a new Mac app comes out, I'm usually fairly optimistic about what it will do. When a new Windows one appears, I'm sceptical.
This doesn't extend all the way to the quality of coding admittedly, but certainly at least until the iPhone came out Cocoa devs were a fairly select set of committed people, and the higher barrier to entry helped keep at least some of the crappiest C&P coders out of the platform.
Not even having a Mac saves you from the crapware hardware makers bundle with their crap. You have no idea how annoying it was for me to have to remove shitty Kodak photo management software from my parents' Mac (which had a perfectly good version of iPhoto) or the horrific, kernel-panic-causing HP All-In-One software. Or even the shitty Verison DSL setup CD I was supposed to use to set up my DSL modem.
Apple is it's own worse enemy here - while there is beautiful software on the Mac and the standard is in general above what I think you find on windows, the software that Apple itself makes for windows is generally awful and this drives the perceptions of a lot of windows users.
For example, iTunes is still the one piece of software that gets me into a flying rage - usually when I want to do something stupidly simple and it refuses to let me due to some preconceived user workflow that I would be violating. It freezes and hangs at weird moments, the UI lacks all kinds of normal Windows niceties like tooltips and hover highlighting, things that are vitally important to click on are rendered as if they are not clickable at all, and in general it looks completely out of place.
The message that Windows users get from this kind of thing is that Macs are foreign and hostile and incomprehensible and the idea of spending your whole life in that environment is repellent. Strangely when I use the same software on the Mac it all makes sense - I can't even really explain why.
In fact, I think you can tell a competent software developer from an incompetent one with a single interview question:
What's the worst code you've seen recently?
If their answer isn't immediately and without any hesitation these two words:
My own.
Then you should end the interview immediately. Sorry, pal.
It seems to me that few programmers would answer the question this way, competent or not. And it's probably not true for most competent programmers... I wonder if Jeff has actually received this answer from a interviewee.
I know I've said it in a number of interviews and have gotten offers from all but one of them. I don't know if I'd recommend it unless you can follow it up with a strong explanation of why it was the worst -- and how you fixed it -- but it isn't an interview killer, IMO.
I agree with Jeff on this one. Some of my worst experiences with code has been going back over stuff that I wrote 3-5 years ago. I'm pretty hard on crappy developers, so I'm doubly hard on myself when I look back at some of the boneheaded mistakes and decisions I've made.
I think this article makes some good points, and I found myself nodding a lot.
On the other hand, it (along with some of the HN comments) conflates a couple of unrelated issues: (1) how well software is written, and (2) whether software forces me to do things I don't want to do.
One of the parts I nodded along with, was his story of lunging for the computer when the camera software CD was inserted. But this doesn't have anything to do with whether the source of this software was readable, variable names, etc., nor is it related to the competence of the programmers or whether they are aware of their own failings. The issue is that such software is often written with a view toward taking over the way I do things.
I want to do things myway. That's the reason for my move from Windows to Linux, and it's why I use Firefox instead of IE when I do use Windows. It's why I avoid Flash when feasible, why I hate most children's educational software, and why I would not even glance at the software that came with a camera. Does this have anything to do with the quality of the code involved in these programs? I don't think so.
I remember that scene from "War of the Roses" where the Danny DeVito character tells the horror story of the Roses to talk a new client out of engaging in an ugly and bitter courtroom battle. I think his line was (paraphrasing here) "when a man who could charge you $250 an hour wants to tell you something for free, you should listen."
I often feel that way about software. Remember the stages of a software project?
1) wild enthusiasm
2) profound disillusionment
3) search for the guilty
4) punishment of the innocent
5) rewards and accolades for the non-participants
Can't remember exactly where I read that, but software developers have experienced them all, over and over.
I don't necessarily try to talk people out of a new development effort. After all, there are clearly times when we need to write software, and some projects are smashing successes. But I kind of feel like that breed of lawyer who tries to get clients to see litigation as a true last resort.
I say - is there anything already out there that could solve your problems without a new development effort? How far would a much simpler approach go toward solving your problems - could you live with it? Basically, I want clients to understand just how risky a full blown development effort truly is.
Of course, if you need business... well, nothing like an angry divorce to keep the billable hours up, and nothing like a flailing software project funded by deep pockets to keep the cash flow positive....
There is a lot of value in the comments on this article, but I am afraid that the idea that you can usefully hire someone based on the answer to one question is a bit oversimplified. In any project that I have done that spans any length of time, often the first code I wrote doesn't look up to snuff with what I wrote most recently. The later code looks better by virtue of a better feel for the environment and the tools and some obscure abbreviation-finder that seems to be at work in the background.
One concern that I would have if you think the worst code that you have seen is stuff you wrote, perhaps you are not reading enough of other people's code. I bet there is a lot of that amongst us all.
In the vein of simple questions that help in an interview, particularly for someone who purports to be an expert, is "Tell me five ways that it won't work". An expert ought to have some scars, and have learned from them, no?
Lisp is crack. Your eyes are rolling in with pleasure and you're the king of the world, but your expressed sense of delight is not commensurate with people's idea of what should be enjoyable and by how much, even your programmer peers (should programming really be that fun?) And to be honest, you're just getting off writing skeletal Idealized software; your toy apps lack the necessary cruft to face a stupid world, so no one ever sees it. As time passes, you're left huddled over your workstation firing dopamines like any other fiend, and the world moves on in its crisply pressed suits, doing hard work and getting social validation and recognition for it. You, on the other hand, are left flailing your arms, feeling the music, offering the Love and the Message to others as they avoid making eye contact.
As usual Atwood manages to destroy a valid perspective (be mindful of your code quality) with unnecessary hyperbole.
I wouldn't hire anyone who said their own code was the worst they'd seen recently. Whatever points they may win for perception and awareness are totally overshadowed by their lazy acceptance of the situation.
"Which areas of your coding could you most improve on?" - now that is a question worth asking,
Clearly the main issue of the post is the answer to the interview question. Although I think it's a very good answer and that to me it would probably mean I would be hiring a guy which is humble, which always views his knowledge has something that still could be better and has a view of his own code has something imperfect, and so he tries very hard to always know more and improve, and that would mean in the end he is just one of the best choices to hire, I think that in most companies that guy would never be hired.
Although it sucks, nobody gives any value to humility anymore. They want the confident, "I'm an expert" kind of guy, so giving as answer that the worst code you've seen lately is your own, without any kind of explanation of why you think that (that you view your knowledge has something which as always a long way to go) would probably be a instant KO to the poor humble interviewee.
What you'll end up with is hiring either incompetent programmers who know they're incompetent, or people with no self-esteem. Great.
It seems more like either Jeff is incompetent (which he admits to) or self-deprecating, and assumes everyone else is.
Besides the "my code is the worst code" part, I thought he did an excellent job of explaining a software developer's natural aversion to software. I had my wife read it, and it helped her understand more about why I refused to pollute the computer with that CD that came with her new camera.
Aside: I know it's a beloved HN meme to bash Atwood, but don't let that excuse us from being lazy about it.
Your comment did not point out anything other than the fact that you personally think Atwood's articles are useless. It did not contribute anything to the discussion, and it garnered knee-jerk upvotes from people who, like you, hate Atwood's articles. I don't often downvote, and I never downvote for disagreement. I downvote comments that either add nothing or take away from the discussion, and your comment was a perfect example of that.
If you have a particular problem with this article, then follow the example of edw519 and elaborate.
What's the worst code you've seen recently?
If their answer isn't immediately and without any hesitation these two words:
My own.
Then you should end the interview immediately. Sorry, pal. You don't hate software enough yet. Maybe in a few more years. If you keep at it.
I have always enjoyed Jeff's columns and maybe I'm missing a subtle point (or just taking the bait), but this may be the worst "advice" I've ever read on hn.
If someone told me that the worst code they've seen recently was their own, I'd wonder why.
I feel confident in my own ability to usually write excellent code on the first try. Sure, it may need some refactoring, optimization, and flushing out of features, but it works, it generally works well, is very well documented, and can be easily enhanced by myself or someone else. If it's not right on the first try, I will fix it before I promote it. Shame on me (and anyone else for that matter) for leaving behind garbage for someone else to inherit. I've cleaned up far too many messes to allow myself to become like that.
I'm probably not alone when I say that I love developing new code and often hate maintaining someone else's mess.
Jeff is right about one thing though, almost everything I ever inherited was crap in one way or another, probably written by someone "less than senior".
I'd rephrase the whole interview question:
"What's the second worst code you've seen recently?"
"My own."
"OK then, what's the worst?"
"Everyone else's."
That's the one I would hire.