Friday, May 30, 2008

What would you like to know about your candidate?

 (Or - how can you know that he is Smart and Gets things done?)

After my session at JavaDay I had a conversation with a colleague from Sun on technical interviews. We started with the question whether a Java candidate should be in the details of Generics (e.g. know the term "erasure" and what it means). I'll touch this in a moment but let's begin in an ordered manner.

What do you need to achieve in an interview?

The famous answer comes from Joel Spolky's "Smart & Gets Things Done" known article (it has an updated version, but I like better the original one. And it got out by now also as a book carrying the same title!) Sorry for the massive PR for Joel (he is NOT my cousin), but this is really a great source to begin with.

Following Joel, let's just mark out that you need to achieve two things in an interview:

  1. Attract the candidate: sell yourself, your company and the offered position. Make sure that if you want this person you will get him.
    -- This is highly important and sometimes neglected (e.g. making the candidate wait for his interview for 30 minutes), but we will keep this for another post.

  2. Make a Hire / No Hire decision (is the candidate Smart and Gets things done?)

__________________

What do you need to know about your candidate?

  • Communication skills - can he explain himself well. Ask him about his previous job or big project at college, see if he can well explain what he did.
  • Does he see the big picture? - continuing with his big project, make him explain what other did in the same project, ask about other alternatives that were there to implement the same thing and why the one taken was selected.
  • Technologies - ask about the technologies used in his big project and what can he tell about each of them.
  • Design - you can learn about the candidate's design abilities by talking about the design of his big project, but it would be better here to tackle him with something he haven't thought about or at least didn't talk about in his previous interviews. It can be a pretty simple design, like some kind of LRU Cache, or Copy on Write mechanism, or anything else you have in mind. But make sure to listen - ask shortly, give enough time to think and then listen. This is a good opportunity to see how the guy thinks.
  • Implementation - if the candidate is going to write code, let him do it in the interview. You will be amazed how many fail at this stage. There is a debate whether the code phase should be on paper, on a PC but only with a Text Editor (and Help?), or with a full-blown IDE. Each of the alternatives may shed light on a different interesting angle. The super-candidate should excel in all of the environments, he may be using all of them in his day-to-day life simultaneously. What would we say about a candidate that gets the IDE but when lag-behind gives the excuse that he is not used to this IDE? I believe paper exam for short implementation is good, as long as you tell the candidate that it's OK if he makes small syntax mistakes. The code should be considered as pseud-code, but all important aspects should be included (e.g. resource management and exceptions). Then of course he has to explain what he did.
  • Reading other people code - many developers are really good in writing their own new code but do miserably when it comes to working with other people's code. During the implementation phase you should check this with your candidate, give him some strange API that he has to use, suggest your implementation to one of the methods and ask for his opinion (it might be a good thing to throw into your implementation some obvious bug).
  • Effectiveness, Tidiness, Laziness - do not ignore the tidiness you see during the interview. Usually this is what you will get later. Pressure is not an excuse for a mess. Watch the way the code is placed, either on the paper or in the IDE. Laziness is OK as long as it does not effect the essence. In fact laziness is something you want to find in your candidate. You want to see that he gets things done and for that he should not finish some of the assignment you gave him, but it should be the trivial part. A candidate that cannot live with an unfinished task in a way that prevents him from even doing the parts that he could have finish, is someone that does not get things done. Effectiveness means starting with the tricky stuff leaving the trivial for the end. Identifying what is tricky and what is trivial is being smart.
  • How does he fit the position? - this is the place, after presenting the position and the assignments he would have to handle, to ask the candidate how does he see himself in this position, what he likes and what he doesn't, what he is strong at and what he still has to learn. This is the place to see that the candidate is attached to reality. You saw him already, you got some feelings and impression about him. Does your impression fits what he says about himself?

----------------------------------
Addition, 12/6/2008:
----------------------------------
Asking for the candidate's grades, maybe even his SAT score (Psychometric exam called in some countries) - can also be a smart thing, assisting you to pinpoint the smart guys. It doesn't necessarily help, this is why you are having the interview, but it may shed some more light. And in my experience, even if there isn't a complete correlation with performance, high grades do say something and poor grades also have their say. Usually, not a surprise, a guy with high grades would do better than his fellow with poor grades. But do not let the grades confuse you, I saw some promising candidates with marvelous grades who may barely complete an if-else.
----------------------------------

How much time should it all take?

Including the first part of attracting the candidate (speaking about the position, the organization, and yourself) - not less than 90 minutes. 2 hours may be reasonable.

__________________

Is it a true / false question?

Joel says it is. There is only Hire / No Hire, nothing in between.

I agree, if we have the budget and attraction to get all the MacGyvers that we need, then yes. I do not mean that all employees should be superheros. They should, however, be superheros in their field. If we need someone to handle XML configuration files we need someone who is a master in this domain, whistles XPaths in his sleep and grains XMLs with XSLs daily. He will not find his duty boring because he will deal with making it more efficient by inventing new utilities. Same thing would be with a secretary, we will want someone who knows how to create table of content in documents and use sophisticated attributes of the spreadsheet.

But what if we cannot attract superheros in the domain? Suppose the budget we have for developers doesn't bring us the most brilliant ones and we have to compromise.

Building your compromises

  • The candidate should have a positive marginal output. Writing bugs gives negative output, writing bugs half of the time may also. When saying positive marginal output, it means that you have to take into account the effort and investment to be made in this candidate if recruited.
  • Marginal output is related to the current mix of your team. If you have "good thinkers" but lack "coders", head for those who can code fast, even if not considered design superheros.
  • Remember that there are qualities that can be gained (e.g. experience), while some other qualities are inherent. Prefer smart over experienced and capable over well trained. A smart novice can quickly become smart and experienced.

Now back to the question we begun with. Suppose we recruit a Java developer. Does the candidate need to know what is "earsure" for Java Generics?

Answer is simple: if you already have in your team someone who read the Generices literature and can serve as the team knowledge base, it's not the end of the world if the candidate does not know it. The team will have the knowledge. BUT - if you are now seeking for this "curious developer", make sure he proves his curiosity!

Summary

Hiring decisions are of the most important decisions made by managers. The damage that can be made by an unfit employee are huge. Investing time in an organized recruitment process and in each of the relevant candidates is a must. At the end, the employee selected must have a positive marginal output that justifies his salary. Marginal output is related to the current mix of your team, so recruitment decisions should be made with the set of people that you have in mind, and with understanding of the qualities that you miss in your team and want to focus on.

----------------------------------
Addition, 12/6/2008:
----------------------------------

Is Smart and Gets things done the all thing? What about motivated, doesn't get bored too quickly, having a good temper?
You may want to read these comments on Joel as well.

----------------------------------

Monday, May 26, 2008

Java Generics, Erasure, Reification

I gave today a talk in Sun's Java Day 2008, Israel, on Java Generics, Erasure, Subtyping, Super Type, Wildcards and a few words on Reification.

Though it's a bit of an old, Java 5, topic, and though the use of Generics is straight forward, the deeper understanding of why one gets type unsafe warnings, how to generify your own utility classes etc. - this needs some more attention. So I still find it relevant to talk about and it seems that it was relevant for most of the audience (I hope! ... well, in fact this is the feedback I got after the talk).

The presentation itself is available in pdf format here.

I want just to post here a small piece of code from the presentation. The main point of this code is how you can cast an object to T when T was actually erased and you don't have it in run-time.
The important lines are emphasized.


public <T> T getContent(Column<T> column) {
Object colContent;
String colName = column.getName();
if(colName != null) {
colContent = getContent(colName);
}
else {
Integer index = column.getIndex();
// TODO: if null throw something of your own
// (for now it will be NullPointerException)
colContent = getContent(index);
}
if(colContent == null) {
return null;
}

// now we need to cast the returned type and that's not trivial

// need raw type as a bypass
// usually use Class<?> when the type of the Class is unknown
// but it won't work here!
@SuppressWarnings("unchecked")
Class colClass = colContent.getClass();

// we know that we hold the correct type
@SuppressWarnings("unchecked")
Class<T> colClassT = colClass;

// now we can use the cast method of Class<T>
// If we were wrong regarding the type ClassCastException
// will be thrown (we can wrap with catch and replace with
// some application exception if necessary)
return colClassT.cast(colContent);
}

--------------------------------------
Addition, 27/05/2008:
--------------------------------------
A day after posting this, I got a very innocent question on the code: why not just use simple casting to T: return (T)colContent;
Well, I remembered that it's Not OK. But checking it again I recalled that Not OK means here that you get 'Type Safety: Unchecked Cast' warning, yet it does compile. What the compiler tells you is that it cannot check that the casting is fine at compile time, which is OK with us.
(Isn't it always the case that the compiler cannot check down casting at compile time? raises the question why Java decided to give a warning on this...).
So, a simpler version of the code would be of course:

// ...
// now we need to cast the returned type
// we prefer to use a local var so we can put
// the SuppressWarning here and not on the method
// (you cannot put it on a return statement)
@SuppressWarnings("unchecked")
T retval = (T)colContent;
return retval;
}

Now, one can just ask: so what's all this thing with the Class<T>.cast() method if we can directly use the "plain old" casting way of (T).
Well, in cases where Class<T>.cast() saves the 'type safety' warning, it worth using it. In our example above we get the warning anyhow (for the implementation using Class<T>.cast() we even get two), so in such a case it would be a better choice to go back to the "plain old" casting way of (T).
For an example where Class<T>.cast() indeed omits the 'type safety' warning, see item 29 in "Effective Java", details below.
Of course, if you do need the Class<T> instance itself, e.g. for reflection purposes, the original way presented above would be relevant.

------------------------------------------------------
End of Addition, 27/05/2008.
------------------------------------------------------

The idea behind the code is based on Josh Bloch's "Effective Java" 2nd Edition, item 29.


(The code example is not in the book, it's my example based on item 29. So in case of any error please find me responsible...)