Second the Pragmatic Programmer, however: I read it when I just started programming (like not much more experienced than basic hello world and some fiddling) and, looking back, didn't really get it. I mean, I got the principles, but couldn't apply it as there was just not enough experience for the higher level abstract stuff. I recently read it again and it makes complete sense now, but I ddn't learn much new from it. So I'd suggest that if you read it, do so after a couple of years of programming.
Indeed, the Pragmatic Programmer book's subtitle is "from Journeyman to Master", and that's exactly what journeyman is supposed to mean - someone who's a few years into it, not bad, but not great (yet?).