Some Developers Just Can't Develop
richard-banks.org
richard-banks.org
This is a little bit of an aside, but how many people out there take this approach with a new hire? If you're a manager/team lead, do you start new developers out fixing bugs? If you're a developer, how do you feel when bug fixes are your first assignments?
Personally, I think that fixing someone else's bugs is one of the hardest tasks in programming. Depending on how the interview went, it can also be a very depressing and alarming task (autonomy? creativity, opportunity to influence the project? we've found that our recruitment success increased by 10% every time we used one of those words. now here's your task list, go fix some bugs).
I want to be sure that I emphasize that people have the right to pick their own management style, and I'm not questioning it. It also sounds like Richard was very reasonable about this - giving programmers adequate time to navigate the system (though "adequate" is a relative term... if "a few days" is enough for new devs to have their a-ha moments and fix several bugs, you probably have very high quality code and documentation).
But let's add this as reason #458 why young programmers prefer to start their own companies: their first "assignment" is creating a product, not fixing someone else's crap code.
1. It's a great way to learn a new codebase.
2. It's a good way to get some political capital so that you can get autonomy more easily.
You just don't usually start out with the plum assignments when you start a new job. If you do, you won't be given the autonomy to make them satisfying. So in my opinion, it's better to start off with jobs that you know will be drudgery to prove your worth than it will be to get a neat-sounding task where you'll be kept on a short leash.
For some people, the answer will always be "no". For others, it's complicated, and potentially impossible to answer without trying out the company for a while.
Suppose the code is well organized and understandable. The bugs are not the product of bad design, they're just the inevitable side effect of any real software project. The programmers who created these bugs are largely still with the organization, they are highly competent, and are more than willing to help a new dev get up to speed - and the documentation (and code quality) is so good that it usually isn't necessary. Lastly, the team and management is eager to give autonomy and flexibility to a talented, proven dev, so it's not a problem to build up that "political capital" you mentioned. Well in this case, what you said is reasonable and more than acceptable to many good devs, even if it isn't right for everyone.
Then there's the nightmare scenario - the team is not highly competent, and the reason you were hired is that the good programmers keep quitting and there's nobody to help you. The code base is a mess, and documentation doesn't exist or is useless. Even getting a build to work is difficult and painful. The reason the management is giving you bug fixes is that they don't really know what to do with a new hire, so they assign some bug fixes, that'll keep you busy for a while. Lastly, they're aren't interested in listening to new suggestions, so political capital won't get you anywhere. O course, in this case, I suppose it doesn't really matter what your assignments are.
By the way, there is another way to get political capital. In my first real programming job, I had an almost ludicrous amount of autonomy. Like, "find something that might be useful and write software for it" levels of autonomy. This was the dot com boom, and there was enough money to hire people for this kind of thing. Of course, they didn't give me high impact assignments, but they did give me broad flexibility in meeting (and even determining) my assignments. This can be an alternate way to build up the political capital you mentioned. Instead of having a limited role on a high impact project, you have a broad role on a low impact project. That can work well for some people - however, these jobs are very rare. Usually, you have to trade the stability of a paycheck for that kind of freedom, especially early in your career.
My current job had almost zero documentation anywhere, and nobody knew the entire system (or even the over-arching design, which I discovered was none). Which is starting to royally screw them over. And I started with a fairly highly integrated project. I learned it in spite of what I was doing in their system and lack of education for me (ie, zero), not because of it - they wanted things finished, I didn't want to finish them incorrectly.
Having someone take care of some of this stuff first to familiarize himself with the project and get used to the processes before jumping straight into a big task seems like a good idea to me.
Indeed!
Many developers view fixing bugs as a punishment. Perhaps that is part of the reason why so much software is riddled with bugs.
I really enjoy using various tools like static analysis programs and memory checkers to ferret out the offending bits of code, figuring out why they're broken, and fixing them.
It gives me a certain sense of satisfaction to finally conquer a bug. Particularly when it's a really tricky bug I've been bashing my head against for days.
Then again, when I've been after a given bug for days it can get really frustrating, and I don't enjoy the frustration.
And it's not like my dream job is doing nothing but fixing bugs. I also enjoy architecting new systems, learning new concepts, and applying them during the quest to complete a project.
I suppose a healthy mix of tasks, from architecture, to writing new code, to fixing bugs is ideal.
But what I really hate is writing documentation. I know it's necessary. And my (non-throwaway) code has quite a lot of comments in it because I know it's necessary and good practice. But it can get quite tedious.
I'd much rather bugfix than write documentation.
I actually treat bug fixing as a little treat. When I want a break from coding -- I'll go and find a few bugs to fix.
I started working on the bugs by choice, it was an easier way to familiarise myself with the source code and gave me some problems that the other developers hadn't been able to fix, or hadn't gotten to yet.
But I would be curious about the false negatives, the guys who were rejected (or almost rejected) but turned out to be truly good. Why they gave the impression they were bad in the first place? How did they proof the initial assumptions were wrong? What were they doing bad in the interview?
Does anyone have experience with these "false negatives"? How not to miss them in spite of a bad interview?
1. Poorly defined questions. One time, the interviewer kept referring to the browser as "the server" (in the context of a web app), despite my questioning him about it several times. After 5 or 10 minutes of trying to figure out what he even wanted, I told him I didn't want the job and ended it. From his perspective, he'd successfully weeded out an incompetent. From my perspective, I avoided working for someone with terrible communication skills.
2. Unclear objectives. One interviewer asked me to extend a small language by adding string support. No problem.
"OK, I'd start by modifying the parser."
"That's not what I had in mind."
"But that's clearly the first step. This isn't even a real language. What's the point here?"
"To get a feel for how you approach a problem in the real world."
"Well in the real world I'd modify the parser."
"Well just don't."
3. Pointless questions. "List some design patterns." Seriously? Sometimes my mind blanks on such questions. There's GoF over there on my bookshelf, and I could talk about the nuances of when and when not to use (almost) any particular pattern if they'd mention one, but from their perspective I know no design patterns at all. From my perspective, I'm glad I didn't end up working at a place whose screening process selects for rote memorization.
4. Insulting questions. "Write a for loop." I mean, I just told you I've been coding for 17 years. You're basically calling me a liar. I don't respond well to that. Enough of these and I might turn you down and walk out. A professional relationship (like any relationship) requires a certain amount of trust, so an interviewer this jaded/distrustful casts doubt on my ability to be accepted and productive there.
5. Trick questions. I hate them and I might have to count down from 10 if you ask me how many square manholes are in Beijing or whatever. You'll probably think I'm googling the answer.
6. The "figure out on the fly what I learned by reading a paper" question. Frequently I'll respond with a working but sub-optimal solution, then they'll prod me with hints until I come up with (or more often don't) the exact algorithm they had in mind. Sometimes they can't even explain what I need to improve about my answer, they just tell me to try something else. Sometimes this is the first question of the interview, and if I don't figure out the clever trick it becomes the only question, because they let me spend an hour banging my head against it without moving on. From their perspective, I answered zero questions and might not know anything at all. From my perspective... well I have no perspective by the end because I'm so tired and angry from being put through such a process.
I don't get offended by 4 (although I don't have 17 years of coding experience :); I understand the need for them to weed out the really incompetent ones. Think of this as a store clerk asking for your ID when you purchase cigarettes.
6 is, IMO, the biggest cause for false negatives. The interviewer feels that she gave ample hints, but really all she ascertained was that you did not have a crystal ball.
I also think that the interviewer anti-loop that Steve Yegge mentions (http://steve-yegge.blogspot.com/2008/03/get-that-job-at-goog...) contributes to the false negatives.
_Well, back when I was at Amazon, we did (and they undoubtedly still do) a LOT of soul-searching about this exact problem. We eventually concluded that every single employee E at Amazon has at least one "Interview Anti-Loop": a set of other employees S who would not hire E._
These days there's so much content around that some people in surprisingly senior positions can wing it, Googling some stuff then c'n'p, and slyly passing the rest to cow-orkers, at least for day-to-day tasks, and at least in the short term. Then one day everyone's busy and Jo(e) Faker has to do some real work.
But you've got to watch out. The very slyness that makes them do this will also get them promoted to management...
Asking "Define X" questions is a really bad proxy for assessing development skill. If you think developers are winging it by c'n'p--any interviewer who asks the candidate to produce a bunch of facts for an hour is the same, if not worse. You don't interview a classical pianist by asking him what notes are on the keyboard.
Before hearing her story, I was skeptical that anyone tried to pull this crap. She's now in a field (marketing) where she can put her slyness to more use.
The lesson is that interviewers must give coding questions even to "senior" developers. See, for example, the "FizzBuzz" interview question:
http://www.codinghorror.com/blog/2007/02/why-cant-programmer...
Oh there's plenty of quacks and shysters out there. I've met some of them.
I was very shocked because in Germany you actually have to a good part of the Chemistry studies at University to be allowed to teach it. I wonder if she forgot it all in the mean time, or if she had gamed the system somehow.
I think it would be interesting to work with someone like that, especially in software, you can mould them to anything. Would I enjoy it for the first couple of months? Probably not, but clearly not everyone you hire has to be excellent, sometimes you just need people that learn fast and are able to pick up new things easily.
I worked with a bunch, none of whom ever ventured outside of Visual C++ and SQL, and who would never have even heard of Ruby or Python or Clojure. Despite this, they could still knock out pretty decent real-World code.
In that case, it can be difficult to filter out the bad ones, just based on general conversations, without asking people to actually code on a blank board.
He didn't even recognise $ as a valid function name which rules out exposure to other libraries mapping it to different behaviours, and the use of an anonymous function (remember: this is someone who claimed to be "advanced" in Javascript) really blew his mind.
The professional incompetent part? She had had the same kind of two year stint for 10 years. I'm glad she wasnt y hire.
If they write something that compiles, give them a point. If it is well commented, give them another point. If the results are correct, give them another point. More than one language would get another point as would finishing early, etc.
It's pretty easy to weed-out people who cannot program by doing this and it doesn't take that long.
On another matter, I wouldn't be surprised if nobody worth their salt commented FizzBuzz; there's just not a level of complexity that you can better describe in English than in code.
eg:
#save the model and pass along a callback model.save(callback)
If you were writing code that was as simple as fizz buzz, would you really write any comments at all?
1) and keyword for c++ ? It has been a while since I used C++ but it used to be &&. Did it change (I'm actually asking, not being sarcastic).
2) on the 'else if' parts, you only need to do one evaluation (the == part) since the first if tests for both % 3 and % 5 so no need to do != on % 3 or % 5 as you know it will never be true.
3) honestly, I think the comments make it worst. If a programmer doesn't know by just looking at the code what it does, no amount of comments will help him.
# Outputs 'Fizz' when +arg+ is divisible by 3, 'Buzz' when
# it is divisible by 5 and 'FizzBuzz' when it is divisible
# by both 3 and 5.I'd rather see tests than comments.
###################################
import sys;map( sys.stdout.write,[#
''.join(map(chr,([0x46, 0x69,0x7A,#
0x7A,0x42,0x75,0x7A,0x7a] if not i#
%0x0F else[0x42,0x75,0x7A,0x7a] if#
not i%0x05 else[ 0x46, 0x69, 0x7A,#
0x7A] if not i%0x03 else[int(c)+#
0x30 for c in str(i) ])+ [0x0A]))#
for i in xrange( 0x01, 0x65)])#
###################################Here's my string reverse. Actually, it might be the first damn time I've ever reversed a string in code. Thoughts.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, const char * argv[]) {
/* alloc mem so we can reverse in-situ */
const char * s = "reverse me 123";
char * rev = malloc(strlen(s));
strcpy( rev,s );
/* reverse the string 'in' */
for( int i=0 ; i<strlen(rev)/2 ; ++i )
{
char tmp = *(rev+i);
*(rev+i) = *(rev+strlen(rev)-i-1);
*(rev+strlen(rev)-i-1) = tmp;
}
printf("string: %s reversed: %s",s,rev);
} char * rev = malloc(strlen(s));
... It should be malloc( strlen(s) + 1 ) to include the NULL terminator.Nitpick #1:
char tmp = *(rev+i);
should be char tmp( rev[i] );
Nitpick #2: i<strlen(rev)/2 ;
"strlen(rev)" is evaluated every iteration of the loop.Nitpick #3:
*(rev+i) = *(rev+strlen(rev)-i-1);
*(rev+strlen(rev)-i-1) = tmp;
Those two strlen(rev)'s are evaluated every iteration of the loop.Why not write it like this?
for ( int i(0), iLen( (int)strlen(rev) );
i < (iLen / 2);
++i )
{
Swap( rev[i], rev[iLen - 1 - i] );
}
}2. Your for() loop is still dividing `iLen/2` every iteration. Presumably the compiler would hoist the division out of the loop, but the code would still add some cognitive friction to future readers of this function. :)
Here's my attempt:
void strrev(char* s)
{
char* a = s;
char* z = s + strlen(s) - 1;
while (a < z)
{
const char c = *a;
*a = *z;
*z = c;
a++;
z--;
}
}I have interviewed people, but I gave up asking coding questions, since no one could ever do them. And if you keep thumbs-downing people, you don't really get invited to interview any more people.
Thanks again!
And yes, the compiler would optimize out "iLen / 2", computing it once rather than every iteration.
Not so sure about nitpick #1. I'll need to pull out K&R...
nitpick #2, sure.
nitpick #3, is that really what idiomatic C looks like? Yikes.
We started by designing a set of technical interview questions. A few simple ones, like reverse a string. A more complex ones, like reverse digits in an integer. And then even more complex and practical ones with algorithms, but still very trivial. At first another developer and I thought they were too easy.
When we started interviewing, we made a shocking discovery that around 90% of the candidates can answer even simple questions. Very few people can write a correct function to reverse a string. Just think about it. These are the people that will have to write complex production code.
Out of 50 people I think we had one guy who answered all the questions. A few times we allowed candidates to use their laptops (it was their choice), one candidate spent like 30 minutes writing the reverse function, didn't really help him.
Our success rate was pretty much 100%, we have not hired one bad developer.
TL/DR: always ask interviewees to write some code.
acc = "" ; "hello".size.downto(1) {|i| acc += "hello"[i-1]}
or the more rubyist way of doing it "hello".each_char.to_a.reverse.join
Or probably something more clever I can't think of at the moment. Was the language so crippled that they were worrying about UTF8 characters? It can't possibly be that 95% are that bad. How could they possibly do anything?The languages we interviewed for were Javascript and PHP (for different positions). There are lots of newbies out there who pick up the basics of these two languages (due to their popularity), and then try to get high paying jobs. Most of them are used to copy/pasting the code from the internet.
That's extremely prevalent among Drupal developers. Drupal has a ton of contributed modules, so you can get pretty far without writing a single line of code. It's really really hard to find a good Drupal developer.
I'm completely serious about 90% not being employable (by my standards).
And for the number reversal we ask not to fall back to strings.