Most of being a good programmer is conceptualization of large infrastructures and knowing enough language constructs to build that infrastructure in terms of code. The best way to get better at this is to build real, practical applications, server daemons, clients, games, injectors (modify existing software), etc. Also, don't forget about reverse engineering, because we all need to know the dark side if we are going to stake ourselves in the computer realm, there are far too many security-stupid programmers and they end up hurting us all. I was lucky I guess because as a kid I loved reverse engineering, making hacks for games n whatnot, I wasn't the nicest kid, lets just say that, I'm grown up now. I believe I am a great, not just good, programmer today because I made all this erratic, zany, cool, stupid, fun 'experimental' stuff along the way, while I learned, so I have a myriad of experience to build almost any kind of infrastructure. Actions like messing with Firefox and inspecting the %tempdata%/mozilla/user.profile, then looking at the code of extensions I had installed, modifying them, led all the way to me making an extension and it becoming highly acclaimed. I then used that extension as resume material for a job at a company fixing bugs on their Firefox addon. Not trying to brag here, I think this instance in my life shows just how important doing what you love is, because you never know when it will help you. Just make sure what you are doing has some value. If you are curious about the extension, it's ImageBot. I guess in summary, experiment by programming stuff for a reason. Learning through value is the best way to learn in my experience - don't just make arbitrary things, start making simple things that you will enjoy!