As per usual another excellent article by Joel Spolsky:

Instead what I'd like to claim is that Java is not, generally, a hard enough programming language that it can be used to discriminate between great programmers and mediocre programmers. It may be a fine language to work in, but that's not today's topic. I would even go so far as to say that the fact that Java is not hard enough is a feature, not a bug, but it does have this one problem.

If I may be so brash, it has been my humble experience that there are two things traditionally taught in universities as a part of a computer science curriculum which many people just never really fully comprehend: pointers and recursion.

When I went to University, we were never taught a language. We were expected to already know it or learn it overnight to do an assignment. Depending on what theories they were teaching we'd use any number of languages like Cobol (maybe one assignment), Fortran, Pascal, Lisp, Prolog, Ada, and "C" (I'm probably missing a few). Of course anything serious in later years was programmed in "C" (with Assembler where required).

This next paragraph from Joel brings back just way too many memories. I wouldn't want to try and figure out how many hours in my University life were spent chasing down the all too familiar "segmentation fault":

The lucky kids of JavaSchools are never going to get weird segfaults trying to implement pointer-based hash tables. They're never going to go stark, raving mad trying to pack things into bits. They'll never have to get their head around how, in a purely functional program, the value of a variable never changes, and yet, it changes all the time! A paradox!