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.
Dip your toes in many ponds.
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.
Do personal projects.
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
Don't settle on languages, approaches or technologies.
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 is important to stay nimble in regards to language, approach
and technology. All three of these things change, and they change
constantly. The most important skills are skills that are
transferable: application design above application design with Cocoa,
understanding the fundamental designs of web servers (threaded,
non-threaded, closure based) instead of understanding Apache.
Be deliberate about your career path.
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.
Make your talent and personality visible.
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
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
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.
Be wary of graduate school.
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.
Take responsibility for your own education.
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
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