Tuesday, September 4, 2007

An exceptional interview

My friend Alfred was in a job interview the other day, with a guy named Quincy. It was for a Java programming gig and they were apparently getting too many resumes, so they sat him down with a paper and a pen and asked various questions in order to determine his skills. I hear it is very trendy nowadays, all the cool kids are doing it. After a lot of rather boring, Java-for-dummies kind of stuff, he was given a paper with something more-or-like the following code printed on it:


public String getSomething(String one, Object two, Integer three) {
if (one != null) {
if (two != null) {
if (three != null) {
String result = reallyGetSomething(one, two, three);
doSomethingMore(one, two);
return result;
} else throw new ObjectNotDefinedException("three is undefined");
} else throw new IllegalArgumentException("two is not legal");
} else throw new NullPointerException("one is null");
}

After taking a few moments to read the code, Quincy started firing away:

Q: What is wrong with this method?
A: Lot's of things.

Q: You mean more than one?
A: Of course. The most obvious mistake is that the method does not declare that it can throw ObjectNotDefinedException.

Q: Yep, that's right. Is there anything else?
A: Sure. That's the easy part that the compiler can tell you right away. Furthermore, the method is needlessly complex and has a questionable API.

Q: Really?
A: Sure, the order the null checks are in, force the indentation to increase, making the code difficult to follow. Moreover, if doSomethingMore() and reallyGetSomething() do not modify their parameters and have no side-effects that require this particular ordering, they could be swapped, saving one line:



public String getSomething(String one, Object two, Integer three)
throws ObjectNotDefinedException {
// Validate.
if (one == null)
throw new NullPointerException("one is null");
if (two == null)
throw new IllegalArgumentException("two is not legal");
if (three == null)
throw new ObjectNotDefinedException("three is undefined");

// Do the actual work.
doSomethingMore(one, two);
return reallyGetSomething(one, two, three);
}



Q: OK, now what's wrong with the API?
A: Check out the exceptions the method throws back to the caller.

Q: What about them?
A: Only one of them, ObjectNotDefinedException, is a checked exception that would give the caller a chance to react to such an anomaly. The others are unchecked exceptions that will bubble up the call stack and probably blow up in the users face.

Q: Well, perhaps the API designer wanted to differentiate the handling of the three error cases.
A: Perhaps, that's why I said "questionable". But looking at the similarities in the way the method handles its parameters, that would be hard to believe, don't you think?

Q: I'll ask the questions.


Then, after a bit of fiddling with the internals of his briefcase, Quincy presented another sheet of paper with the following printed code listing:


public class ThrowNull {

public static void main(String[] args) {
System.out.println(getFluff(null));
System.out.println(getStuff(null));
}

public static String getFluff(String name) {
if (name == null)
throw new NullPointerException("BOOM!");
return "Fluff: "+name;
}

public static String getStuff(String name) {
if (name == null)
throw null;
return "Stuff: "+name;
}
}


Alfred was given a few moments to digest it and then Quincy went on:

Q: What does the program print?
A: That's easy. It prints nothing. At least, nothing useful. It throws a NullPointerException since the caller of getFluff() is null.

Q: Why does getFluff() throw an NPE if the name parameter is null?
A: I suppose the getFluff() API designer considered that it's the caller's job to make sure it is not called with a null argument. He should have put that in the javadoc, though. You do write javadoc comments don't you?

Q: I'll ask the questions. What will the program output if we change the first println() in main to
System.out.println(getFluff("bad"));

A: It's not much of a change. The line "Fluff: bad" will be printed, followed by a new NullPointerException.

Q: So the "throw null" syntax is legal?
A: Hell yeah! Even Neal Gafter is using it.

Q: Which way of throwing an NPE is better?
A: Better in what way?

Q: I'll ask the questions.
A: Well, each one has its merits. The first form is more explicit and traditional, but longer. The second is more succinct and closer to the natural language, but cryptic to newcomers.

Q: So what would you recommend that we use?
A: Does that mean I got the job?

Q: I'll ask the questions.
A: Well, I kinda like the short, concise form, but I don't feel particularly strong about it.

Q: Good answer, because we picked the other one after a three-hour long debate last week.
A: You mean you were debating about ways to throw a NullPointerException for three hours?

Q: Yeah, why?
A: Don't you have real work to do?

Q: I'll ask the questions.



I don't believe Alfred has heard back from them ever since.


I'm actually glad about it.

Creative Commons License Unless otherwise expressly stated, all original material in this weblog is licensed under a Creative Commons Attribution 3.0 License.