October 22, 2008.
The intended audience for this advice is programmers in college. At lot of advice in this genre is labeled as advice for Computer Science majors, but is actually intended as advice for Software Engineering or Information Technology majors. Although the Platonic forms of these three programs differ in concrete and discernable ways, many colleges name their program based on the terms' relative popularity, so it's difficult to speak meaningfully about Computer Science programs, since many more closely resemble Software Engineer, but have been mislabeled.
Furthermore, the students in all three programs are generally taking different paths towards the same destination: careers as professional programmers. Some, particularly those in Computer Science programs, may aim to become academics instead, but even a PhD isn't insurance against becoming a programming professional (either in the workforce, or within the role of a professor or researcher).
With all that in mind, this advice is aimed towards programmers in college who will become professional programmers. There are other possible scenarios, some programmers in college probably become elementary school teachers, nurses or cocaine addicts, but I'll ask your forgiveness for focusing on the common case instead.
One of the most common sources of creativity, especially the kind of creativity that results in published academic papers, is transposing the solutions of one field onto the problems of another field. This is also how the best software gets written: it takes a domain expert to grok the nuanced details of their domain, but it also takes an expert developer to translate that nuanced knowledge into a usable application. When one person is both the domain expert and the programmer, then really amazing stuff can happen (this is why programmers create such great tools for programming, we're the programmer and the domain expert, so we can do it right).
Following that, those who take courses in a wide variety of subjects have a broader well of inspiration to draw from. Certainly, the deeper you go into a field, the more nuanced your understanding becomes, but I'm not recommending that you specialize in a second field (for example, pairing Computer Science with Chemistry and attempting two majors). Instead, I think you'll benefit most from gaining a moderate level of understanding of a broader range of topics.
If you gain a basic foundation in a topic, you're in a great position to continue studying on your own. Once you have the general concepts, you know where to look for the details later when you need them1, but if you don't have that foundation, you'll never know the right question to ask; you'll never even know that there is a question to ask.
The best way to become a better programmer is to write programs. You should always be working on a personal project. You'll certainly have programming projects assigned in your courses, but personal projects are a different beast: you pick the topic, you pick the size, you pick the language, you pick... well, you pick everything.
Here are my guidelines for picking good personal projects:
Do projects in a variety of different areas. Try doing some web development, some desktop development, some crossplatform development, some development that relies on awesome libraries, some development that doesn't use any libraries at all.
Game programming exposes some interesting problems, but so does designing a spreadsheet.
Focus on picking interesting projects first, and on making the project hard second. The important part of personal projects is to gain experience and exposure. As long as the project keeps your attention, you'll find difficult edge cases that you need to resolve: even easy problems have hard pieces. (Unless you skip them, which you won't, right?)
Try to work on personal projects with other people, at least part of the time. It's good to have personal projects that only you are work on, but learning to collaborate is important as well.
I had a number of different phases back in college. For a while I was certain that Java was the language for me, then I knew that Common Lisp was a persecuted prodigy to be rescued and applied to problems with undue haste. And so on.
It's easy to get caught up on a specific programming language, approach (big bang programming, not using version control, using regular expressions as the key to all locks), or technology (JVM, Ruby on Rails, Django), especially when your exposure is still limited.
It's fashionable, and very much encouraged, to go into college without even the slightest clue of what kind of profession you're interested in joining. Perhaps industrial concerns prefer it because they get a just-in-time workforce instead of having to predict their needs a decade in advance. Or perhaps the never-ending childhood crew prefer it because children--as we well know--are utterly free of concerns as long as we don't cruelly force responsible onto their fragile shoulders or limit their options by steering them towards one field or another2.
However, on the path towards becoming a professional programmer, being proactive will greatly improve your prospects of a happy ending. There are roughly four buckets of programming opportunities, and there are different ways to prepare for each:
Working for a large company is the path that most courses assume you'll be walking. This is a reasonable assumption, because the majority of programmers probably will end up working at a large company, but it is nonetheless important to be aware of the assumption.
Large companies, who indirectly dictate what material is taught in many programming related curriculums, are most concerned in the material you've learned in class. Specifically, they want to see a mastery of testable topics like algorithms, and also that you have excellent grades.
Some large companies may be interested in you having a specific set of skills (PHP, Java, etc), but more often they're interested in someone they can train and becomes a lifer.
Working for a medium sized company is similar to larger companies, but they tend to focus more on the specific skills you bring to the table. They don't have the same depth of resources as larger companies, so they are forced to take a more short term approach to productivity.
They'll want you to come equipped with a specific set of skills, and already be somewhat experienced. This can make starting out working at a medium sized company a bit challenging.
Working at a small company is rather different than working for a large or medium sized company. Small companies need especially productive people, who can handle a wide variety of tasks as necessary. Small companies are concerned that you can come in and be productive immediately, but they are usually not concerned about your specific set of skills (alternatively, there may be only one skill that they are interested in; Ruby on Rails, for example).
Small companies are concerned with personality and ability. I'l touch on these more in a moment, but having an impressive portfolio of projects and blogging can both be very helpful in that regard.
Working as a contractor or consultant is the fourth bucket of programming jobs. Like working at a small company, it is important to be productive, and it is even more important to be able to demonstrate your past productivity. (This makes having a portfolio or blog even more important.)
Often ignored--and equally important--is that contractors and consultants need to be good communicators and at least moderately likable people. Part of your job is that you need to get hired repeatedly. In the best case you'll be discussing new work every three to six months, but more likely you'll be talking to new clients several times a month (or more).
Once you have a client, again, you need to be friendly enough that they enjoy having you around, and also you need to communicate with them to make sure that you can do your job properly (and to make sure they know that you are doing your job).
I am certainly not saying you must decide which of the four buckets you are most interested in--you can be well prepared for all four--but you should keep in mind the different areas you need to invest energy into in order to be an effective applicant in the buckets in which you are interested in.
In particular, it is effectively impossible to get started as a contractor or in a small business without some public facing proof of your ability as a programmer3.
College is one giant grading mechanism, where you do numerous assignments and projects, and emerge with a GPA that theoretically describes your probable value as an employee. This seems like a great concept, but the problem is that--outside of large companies--no one gives a damn about your GPA.
Nope. Not even a little.
Your recourse against the grading scam is that you need to create public visibility for yourself that showcases your ability as a programmer. The best way to do this is to create a personal website that contains two crucial ingredients:
A blog where you write intelligently about programming, and write so that your personality comes through a bit. You don't have to write a tremendous amount, and you shouldn't worry about your pageviews or success on Reddit, just make sure that you write intelligently about technical topics. It helps to pick a handful of persistent themes in your blog and to integrate into their communities, but that'll likely happen over time without much concious effort.
My advice is to always write to help other people. Rants and hateful commentary are easy to do and attract attention, but are only only good for entertainment. Write quality content that can be helpful to your readers. Remember your priorities as you write: be proficient, have a visible personality, and be approachable4.
A portfolio of interesting projects. Start out by including absolutely anything you can think of, and as you create more projects gradually replace the less impressive projects with new ones. At minimum you should describe the project and the technologies it involves, but your portfolio will become increasingly effective as it becomes more tangible. To the extent possible, provide live demonstrations, source code for download, screenshots and links.
It has been my experience that making your personality and talent publicly visible is the most important thing you can do in terms of finding employment. Don't worry about starting late, or about making your site popular, just start slowly crafting pieces of your portfolio and grow something impressive5.
Elementary school leads to middle. Middle school to high. High school to college. College to graduate school. For many people, going to graduate school after undergraduate is the path of least resistance. I'm not telling you not to go to graduate school, but I'm going to tell you make sure you're going to graduate school for a good reason. Your job selection after working for two or three years will be at least as good as your job selection with a Masters degree. The same case with your salary.
The good reason to go to graduate school is to study something specific. Go in with a plan for exactly what you want to accomplish. If you don't have a specific plan, than you'll get a lot of rehash of your undergraduate program, a bit of new material, and not a whole lot more. Add to that the tuition, subtract the opportunity cost of not working, and graduate school isn't something to do on whim.
In particular, don't enter graduate school to avoid making important decisions about your future. If you think you might want to go to graduate school, then what's the harm in taking a few years off to work before going back? If you start working after undergraduate, you might never enter graduate school, but then you probably never had a strong motive for going to begin with.
Although your courses can teach you many things, a thoughtful teacher can assign engaging projects, and a well-written textbook can explain complex algorithms, you cannot surrender responsibility for your education to your teachers or to your courses. In order to become a proficient programmer, you must go beyond your coursework and direct your own learning.
The biggest part of that is the forementioned personal projects, which will guide you through a wide variety of topics to learn and discover. Some would argue that reading what others have written is equally important, but my experience is that you learn far more from creation than from consumption. Reading what others have written is valuable6, no doubt, but don't do it to exclusion of creating things yourself.
Most of all, I want you to take responsibility for yourself and your future. In our society, it is easy enough to drift through the first third of your life without ever really engaging in your own life. Please don't do that. I'm begging you. If you want to be alive, live deliberately.
We're cresting on an uncertain future. But the future was uncertain long before the newspapers began bemoaning the poor conditions for job seekers or enthusing about the latest tech bubble. That uncertainty is filled with places that glitter, and it is up to us to pursue them.
This is an attractive approach towards the details in our field as well. If you know the big O details for all the algorithms, do you necessarily have to be able to recreate the algorithm from memory?
I won't lie to you, I can't recreate all of the algorithms I have studied, but I think that just knowing their space and time complexities is insufficient. You should understand why the algorithm has those characteristics, which requires a understanding of how the algorithm is implemented, but not necessarily that you could quickly create the algorithm when prompted.↩
I'll posit Larson's Law: by utterly refusing to steer children into any career, we're steering them down the road with the fewest barriers to entry. In 2008, that road is law school.↩
Of course, if you have a connection in the right place, then you can get a job without following any of this advice. You cannot overestimate the impact of having connections in the right places.↩
This may feel like advice to whitewash your personality, and that I'm saying you should pretend to be something that you are not. No, no, not at all. What I really want is for you to be these things. I don't want you to pretend to be proficient, personable and friendly, I want you to be them. If that is "dishonest to your true self", then you should change.
But, yes, if you cannot be these things, I'd prefer if you just pretended.↩
Writing a blog and keeping a public portfolio is also a great way for developing contacts, and contacts open doors you don't even realize exist.↩
Especially reading code written by other people. That is a challenging and excellent way to learn about new topics and ideas.↩