Around the time that grades are posted at the end of the semester, I tend to get a few emails from my CS222 students, asking what they can do to get more practice with programming. The questions often come from students who got through the first two programming courses without really understanding some core concepts, and these deficiencies start rearing their heads during the nine-week project of CS222. This is a great awakening for the students, and I applaud them for the desire to invest personal time between semesters to improve their skills.
Also, I recently came across—though now cannot figure out where—the idea that we each have a limited number of keystrokes in us before we die. (The concept seems to be tied to keysleft.com, although I only found that today in trying to figure out who I saw writing about it.) From this perspective, all those emails I've sent to students over the years seem like a bad investment, not because it didn't help that one student, but because it could only have helped that one. This is related to the this semester's lack-of-blogging guilt, which I'm sure I will be able to write about in a few days.
Without further ado, let's get to advice for students (roughly sophomores) who want to get some practice.
First, if your main problem in CS222 was with Test-Driven Development, then the next step is easy: read Test-Driven Development: By Example. Then, read it again. The book is deceptively simple, but it contains the seeds for cognitive transformation. Then, the next time you want to write any kind of code, hold yourself accountable to TDD.
If you feel like your Java skills are just not up to snuff, spend some time with The Java Tutorials. The great thing about that site is that you can easily pick the area you want to learn about: the basic language, essential parts of the standard API, building a simple user interface in Swing, and so on. Another advantage of these official tutorials from Oracle is that they are precise and consistent in their use of language and terminology, and this can help you build your technical communication skills. Yes, you can do a random Web search for any of these, but Oracle's collection is well edited and presented.
A few sites have emerged in the last few years dedicated to helping programmers hone their skills with canned problems. Project Euler is one of the most famous, and I know students and alumni who really enjoy the challenges and the community. They make great training exercises if you are interested in programming competitions, such as the ones at the annual CCSC Midwest Conference or the ACM International Collegiate Programming Competition. Personally, I find them a bit too much like homework, but your mileage may vary.
A different take on this kind of exercise is the Code Kata. The idea behind this is that you get to be a better programmer through intentional exercises, exercises that both help you remember what you know and push you to extend your skills.
A talented alumnus recommended cyber-dojo.org, which includes a wide selection of exercises and a community of reviewers. A slightly more aggressive model comes up at codefights.com, which I have not tried but heard recommended by another alumnus.
There are myriad open source projects on the Web. Sometimes it can be difficult to see how to get involved, and I see that many people mistakenly think that "get involved" necessarily means writing production code. This article at SmartBear paints a more accurate picture of how these communities tend to work and how you can contribute, regardless of your programming skill level.
One of the best ways to motivate yourself is to build a thing you care about. Whatever your interest is, you can write programs for it. Games? Figure skating? Home security? Soccer? Whatever it is, think of what you can do at a very small scale, and build it. Keeping the scale small is important, because actually completing a project is much more difficult than just tinkering around with it. I do a lot of work with game programming, and many students come to Computer Science because of an interest in video games. Many of these same students fall into the trap of thinking that the first game they program should be their grand vision for a new strategic multiplayer role-playing 4x roguelike. Don't do it. Start by recreating the classics, like Asteroids, Space Invaders. Keep the scope small, so that you can get the learning that only comes from finishing.
No matter what you do, do it with reflective practice. Think about what you are doing and why you are doing it. Write about it and talk to people about it. Find a community where you can share your findings and ask questions. This will help you develop your metacognitive skills. If you find that you want to learn more about how to learn, I recommend Pragmatic Thinking and Learning.
I hope this list has been helpful. If you have more favorite links, books, and tricks, feel free to leave them in the comments.