Felix Geisendorfer is taking an interesting approach to defining programming in this new post to the Debuggable blog - he's coming at it more from the level of the perception the programmer has about writing good code.
I believe understanding the patterns in your own thinking will by far make the biggest impact on how good you will get as a programmer. Forget design patterns, forget unit testing, forget all those functions you know. Important is to question why they exist and how they could be improved.
He illustrates through a few examples what he means. He describes one such thought method, the "return home early" process - basically, if something looks too complex for its own good, it probably is. He offers a different way of thinking about it too, a more visual way that can help simplify things even more by laying out the pieces and seeing where they all fit.