They just don’t make programmers like they used to

By | May 30, 2006

I’m trying to hire a senior software engineer for one of the teams I manage.  Apparently, my standards are a bit high…

I like to ask candidates a problem-solving question which one of my friends (thanks Andrew!) was once asked at an interview.  The question is, “Tell me how you would go about writing a function to convert an integer into a Roman numeral.”

I don’t expect candidates to be able to come up with a working algorithm on the spot (although that would be great!).  Instead, I want to see if they approach the problem and start working through it sensibly.

I asked a candidate this question recently, and he totally flubbed it.  His first problem was that he wasn’t even all that firm on what Roman numerals look like.  I corrected that by spelling out some of the rules of how they work.  Even with that information, he wasn’t able to make any headway at defining how he would approach the problem or figuring out what the solution might look like.  Well, he did pick up on one thing… He commented that recursion would not be useful, which is true; this is not the kind of problem that lends itself well to a recursive solution.

At the end of the interview, he said he’d think about it some more and send me email with an answer.  He sent me an answer written in C# a few days later (it was over a weekend, so the delay is understandable).  His 17-line conversion function had two bugs and two unnecessary (albeit harmless) syntax elements.  Now, as I said above, completely solving the problem during the interview isn’t really the point, but for heaven’s sake, if you’re going to take the trouble to send a solution after the fact, it had better be correct!

I told this story to my manager, and he told me about a much simpler question he asks candidates who claim to know C.  He gives them this code fragment:

char *p1, *p2;
...
p1 = p2;
...
*p1 = *p2;

and then asks them what the difference is between the second and third lines of code shown above.  When he showed me this, I said, “But that’s patently obvious, isn’t it?  How could anyone who claims to know C not know the difference between a pointer assignment and a pointer value assignment?”  He said that obvious as it may be, nine out of ten candidates get it wrong.

It was suddenly much clearer to me why it is so difficult to find good programmers.

 

Print Friendly, PDF & Email
Share

4 thoughts on “They just don’t make programmers like they used to

  1. jik Post author

    Here’s a function I had to work with today, written by someone at a firm from whom my employer contracted some Java work:

    public void EncryptFormValues(){
        crypto EncryptCipher;
        byte[] byteEncryptedSecretVal = new byte[256];
        Arrays.fill(byteEncryptedSecretVal,byteFillValue);
        byte[] bytePrivateIV = new byte[16];
        Arrays.fill(bytePrivateIV,byteFillValue);
        String strPrivateIVector = new sun.misc.BASE64Encoder().encode(bytePrivateIV);
        String B64EncodedVal = "";
        String pvtEncryptSession = "";
    		
        // Re-encrypt Session information with private key and IV		   
        EncryptCipher = new crypto( decryptedSessionID, strprivateAESKey, strPrivateIVector, byteDecryptSecretVal, B64EncodedVal);
        EncryptCipher.getssoEncrypted();  
        pvtEncryptSession = EncryptCipher._strB64Encoded;
        EncryptCipher = null;
        Arrays.fill(byteEncryptedSecretVal,byteFillValue);
        B64EncodedVal = "";
    		
        // "Double" encrypt session information with shared key for xmit to server
        // Regenerate an IV!
        strEncrVector = "";
        EncryptCipher = new crypto( pvtEncryptSession,  strpublicAESKey, strEncrVector, byteDecryptSecretVal, B64EncodedVal);
        EncryptCipher.getssoEncrypted();  
        strEncSAPSess = EncryptCipher._strB64Encoded;
        strEncrVector = EncryptCipher.getInitVector();
        EncryptCipher = null;
        Arrays.fill(byteEncryptedSecretVal,byteFillValue);
        B64EncodedVal = "";
    		
        // Encrypt the server User ID
        EncryptCipher = new crypto( decryptedUserID, strpublicAESKey, strEncrVector, byteDecryptSecretVal, B64EncodedVal);
        EncryptCipher.getssoEncrypted();  
        strEncUID = EncryptCipher._strB64Encoded;
        EncryptCipher = null;
        Arrays.fill(byteEncryptedSecretVal,byteFillValue);
        B64EncodedVal = "";
    		
        // Encrypt the server session ID
        EncryptCipher = new crypto( decryptedSession, strpublicAESKey, strEncrVector, byteDecryptSecretVal, B64EncodedVal);
        EncryptCipher.getssoEncrypted();  
        sessionID = EncryptCipher._strB64Encoded;
        EncryptCipher = null;
        Arrays.fill(byteEncryptedSecretVal,byteFillValue);
        B64EncodedVal = "";
    }	
    

    And here’s the 40% smaller function they should have written:

    public void EncryptFormValues(){
        crypto EncryptCipher;
        byte[] bytePrivateIV = new byte[16];
        Arrays.fill(bytePrivateIV,byteFillValue);
        String strPrivateIVector = new sun.misc.BASE64Encoder().encode(bytePrivateIV);
        String pvtEncryptSession;
    		
        // Re-encrypt Session information with private key and IV		   
        pvtEncryptSession = new crypto( decryptedSessionID, strprivateAESKey,
    				    strPrivateIVector, null, null).getssoEncrypted();
    		
        // "Double" encrypt session information with shared key for xmit to server
        // Regenerate an IV!
        strEncrVector = "";
        EncryptCipher = new crypto( pvtEncryptSession,  strpublicAESKey,
    				strEncrVector, null, null);
        strEncSAPSess = EncryptCipher.getssoEncrypted();  
        strEncrVector = EncryptCipher.getInitVector();
    		
        // Encrypt the server User ID
        strEncUID = new crypto( decryptedUserID, strpublicAESKey, strEncrVector,
    			    null, null).getssoEncrypted();
    		
        // Encrypt the server session ID
        sessionID = new crypto( decryptedSession, strpublicAESKey, strEncrVector,
    			    null, null).getssoEncrypted();
    }	
    

    *sigh*

    Reply
  2. jik Post author

    It wouldn’t be appropriate for me to get into specifics about salaries.

    Reply
  3. angwantibo

    Oy! That is sad.

    For problem solving, I usually ask how far you can see a plane at an altitude of 3000 feet on a perfectly clear day. It’s a pure geometry question, but I find that geometry skills and programming skills are linked. Not everyone has a good foundation in geometry, but it lets me see if they can visualize problems, how they attack a new problem and their resolve. The last is a personality trait that is required in debugging or systems integration.

    BTW, how much are you guys paying for a senior?

    Reply
  4. sethg

    To quote Joel Spolsky:

    “You used to start out in college with a course in data structures, with linked lists and hash tables and whatnot, with extensive use of pointers. Those courses were often used as weedout courses: they were so hard that anyone that couldn’t handle the mental challenge of a CS degree would give up, which was a good thing, because if you thought pointers are hard, wait until you try to prove things about fixed point theory.

    “All the kids who did great in high school writing pong games in BASIC for their Apple II would get to college, take CompSci 101, a data structures course, and when they hit the pointers business their brains would just totally explode, and the next thing you knew, they were majoring in Political Science because law school seemed like a better idea. I’ve seen all kinds of figures for drop-out rates in CS and they’re usually between 40% and 70%. The universities tend to see this as a waste; I think it’s just a necessary culling of the people who aren’t going to be happy or successful in programming careers.”

    These days, such kids get weeded out at the job interview. Or not.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *