Friday, December 07, 2007

Preparing Students for Jobs

In a recent "discussion" on another blog, I repeatedly heard the refrain that we ivory-tower pie-in-the-sky university computer science professor types just aren't preparing students suitably for "real-world" employment. Personally, I think that's just BS. However, I realize I may have a fairly biased viewpoint. I teach at Harvard, and, if I may say so, our students are generally quite good and do well in the job market. Having spent some time in industry, and, if I may so so, being perhaps more interested than the average theorist about practical issues, I attempt to add "real-world" aspects to my classes, like programming assignments in my undergraduate theory course.

Now occasionally I catch students who admit to reading this blog. I mean all students, from whatever school, undergraduates and graduate students, not just students from my classes or Harvard students. I hope some of you are reading now. Because I'd like to ask you to enlighten me. (That means, for instance, I'll keep quiet on the comments.) Please tell me, in your experience, did your education prepare you for your life after in the real world. (For current students, you can comment on how you feel your education is preparing you.)

While I'd expect you to comment anonymously, I'd ask that you provide salient information where possible. (Harvard student or not, current undergraduate or long-time real-world person, CS or EE or other major, etc.) I'd also greatly enjoy hearing specific comments and criticism regarding my own classes, from any ex-students out there.

And in advance of some annoying anonymous commenter who might feel the need to say how out of touch I must be that I need to find out how students are doing by asking on my blog, please rest assured I have other sources of information (both personal and data-driven) on the subject, but this is, hopefully, an interesting opportunity for me and others to gain more insight.

25 comments:

Daniel Lemire said...

I haven't been a student in over ten years, but I guess we are all students, in some way.

I wrote something about this very issue some time ago:

http://www.daniel-lemire.com/blog/archives/2004/09/19/does-your-university-think-that-jobs-are-for-the-little-people/

Basically, my stance is that you should not assume that your students (at Harvard or elsewhere) come for the joy of learning alone. That's an idealistic point of view which simply does not match reality. Even TCS professors have to check whether their theories are good models, sometimes, no?

Does this mean you should be teaching your CS students how to setup a router? Gosh! No!!!

But maybe, you know, you ought to talk about the real world, and give some practical advice, and explain why you think that some of what you are teaching can be used by engineers on the field.

It is not *that* difficult. I mean, proving that sort requires O(n log n) time *is* very practical. You just have to go the extra mile and tell your students why this matters for an engineer.

And frankly, if one cannot be bothered to do that, one should maybe let other folks teach undergraduate classes.

Anonymous said...

i did my undergrad at cornell in cs and i never had to learn c or c++. i think i wrote one program in those languages since high school. wasn't very reflective on what industry expected.

Anonymous said...

While in university I was constantly made to believe by professors and colleagues that to get the really good jobs you only need to be smart, and specific skills don't matter because you can learn them on the job. The atmosphere was that you don't want the job if they have the nerve to ask you about programming in the interview (because you are supposedly too good to be asked about programming skills).

This is BS. For the best jobs you are competing with people who are just as smart and know how to program. And, if you are not a very good computer scientist (in the practical sense), they might as well hire a physicist or a mathematician (who actually *know* math).

Your employer will give you time to learn what is specific to the company or the job, not to fill the gaps in your basic education.

Anonymous said...

A PhD spoils students in the sense that they would no longer want a software engineering job.

There are a few exceptions perhaps (e.g., at Google) and in graphics companies.

Anonymous said...

A university is not a vocational school. The point of any university program is to teach students how to think. I have many friends who complain that whatever particular language/methodology/software library/etc. is used at their current job, they weren't taught in school. What I try to convince them (and usually fail) is that they know how to learn those ideas because of their training, and they would have been unable to learn them straight out of high school. That is, the point of their degree wasn't to teach them how to do their current job, but to teach them how to learn how to do their current job.

Note that this doesn't mean on-the-job training is the answer. As a previous poster pointed out, many companies don't want someone who doesn't know specific languages already. But whoever said that either your school or your employer is required to teach you those languages? Don't have the programming experience that your dream job wants you to have at the time you apply? Buy a book and learn it on your own before you apply. Spend a month or two developing small projects to learn the skills. If you can't do that, then I would agree that your undergrad program did not work for you (whether it is your fault or theirs is another matter).

But don't demand that all of your useful experience must come from your classes. What if your classmate's dream job requires different skills than your dream job? How is it fair to that person that the class is tailored to your particular future job? Internships are a great way to get some of this experience if you aren't sure what sorts of things you ought to have experience with. Sure they don't pay as well, but guess what? They shouldn't! Not if you don't have the experience yet. Just because the average amount salary a CS person makes is large doesn't mean you are entitled to a slice of it because you have a CS degree. The average salary is that large because there are lots of motivated CS people who do so much learning on their own that the skills they consequently develop means they command those high salaries.

Anonymous said...

At CMU we're forced to take 3 classes with heavy programming assignments (as undergrads)

1) Fundamental Data Structures and Algorithms (not to be confused with our Algorithms course). Assignments are due every two weeks (in Java) and usually require us to implement some kind of data structure that already exists in the Java library. The final lab, "the chess lab," was fun because we could run our code online against other students to see how we did.

2) Introduction to Computer Systems - entirely taught in C. The first few assignments have to do with assembly, GDB and code optimization. The last two assignments include implementing malloc and creating a web proxy.

3) A systems course - people usually take either Operating Systems (taught in C), where you create your own kernel, etc. or Networks, where you create a bit torrent client/server protocol. You also have the option of taking a parallel computation course.

There are many electives which have more of an "industrial" setting, but being biased towards theory has prevented me from taking those courses. They include system-level programming, distributed systems, large-scale complex systems, etc.

My understanding is that after the first two courses, most are prepared for industry jobs. The third course is acherry on top for the more serious software engineering positions.

My opinion is that without creating projects on your own, you will never truly be ready for a job in the industry.

Anonymous said...

At my undergrad school, I started out as a CS engineering major, but switched math after the first year because there was TOO MUCH emphasis on software development. This was at a public school with a large college of engineering.

Anonymous said...

I think there's been some complaints in the recent years from industry about this issue, because a lot of schools seem to have added a (essentially) a coding course in their curriculum.

I think perhaps at the undergrad level, some universities can do a better job of exposing students to intermediate level coding so they experience it for at least a semester or two. This is usually done through a special course or a senior project.

On the other hand, i disagree with mixing the "algorithms" course with this. In my opinion they should be kept nearly disjoint. If in fact schools X pumps out grads who are uncomfortable coding, they perhaps the curriculum should be beefed with some project courses. For the more advanced student who wants to go beyond, it is always nice to offer a course such as this (http://www.cs.nyu.edu/courses/fall07/G22.2965-001/index.html).

In addition, for phd students.. i think it is absurd for a school to 'prepare' them for real world jobs. The willing student can pursue such endeavors on his own without having the school/department/faculty to guide him/her.

As for masters students.. i have no opinion.

Anonymous said...

I'm a master's student at Harvard in CS, sponsored by one of the "Big 5" defense contractors, which I work for as a systems engineer. You can probably figure out who I am. I can only speak to my own experiences, which might be very different if I worked somewhere like Akamai or ITA. I'm interpreting your "preparing students suitably for 'real-world' employment" narrowly to mean something like "provide training that will allow an individual graduate to quickly make valuable contributions to the technical side of a typical employer's computing project."

For me, there's almost no intersection between work and school. A huge portion (probably the bulk) of my work deals with resolving linker errors, version control management, deciding which features are needed in which builds, constructing "make files," fixing platform dependency issues, designing schedules to ensure people aren't stuck waiting on necessary sub-components, getting (e.g.) the new debugger to work properly, defining message formats, writing and addressing bug reports, describing progress to lay-persons, and so on. If there's ever a need to compute an MST or solve a linear programming problem, well, there are libraries for that. I suspect my experience is typical for the industry.

Some of my co-workers are graduates of programs that emphasize such skills. They've taken courses on shell scripting and writing make files, or using Rational Rose in compliance with UML standards, or technical writing. For the most part, I think they're better employees for having learned these skills in school rather than having picked them up ad hoc the way I did. (Although it's still unsettling when someone with a degree in CS tells me the halting problem is NP-complete.)

Basically though, I think graduates of top-25 CS programs who succeed in typical engineering positions do so in spite of their training. Still, I consider myself extremely fortunate to be in school, if only for the huge pleasure I've gotten from much (though not all!) of the academic work I've done.

Anonymous said...

I have done around 10-15 theory/algorithm courses and I have interned in 2 small software companies and full timed 9 months in Microsoft. Frankly, I never needed anything from my algorithm classes (not even anything from the first course in algorithm). I did a parser for XML and I knew the parser should be in linear time. That’s the nearest thing I can recall that I used some skills learned from algorithm classes.
I truly believe understanding only two books, “the C++ programming language” and “introduction to algorithm”, and practice coding for 5k lines already suffice to find any entry-level developer jobs, in Microsoft or Google.
Although my working experience is not significant, I have been wondering how many software engineering jobs indeed need any algorithm skills. At least I confirmed this question with a few colleagues outside my group within Msft: we had been joking that Microsoft only asks the algorithm questions in interview; but never needs it in any products. Maybe my opinion is biased because I was in the office division and I did not have chance to touch any performance critical tasks in server or search engine.
Now here comes the question: do you want to prepare the students for the interviews or for the jobs? Preparing for the interview seems too short-sighted while preparing for the jobs, unfortunately, does not really need rigorous algorithm training component. My opinion is that, algorithm lecturers should not be too serious about the job preparation issues. Just like the kids are likely to forget about the Green’s theorem in Calculus, Plato, or Shakespeare after their graduation, they will also be likely to forget about most things taught in the algorithm course.
Concerning on the white-board coding issues, I was a little surprised I writes code in whiteboard even better than seasoned engineers when I was interviewing. I spent 3 hours a day to write code in C++ in the summer I graduated from high school. That’s nearly all the programming trainings I had. Well, I also admit that a typical good university in Hong Kong requires around 8 to 10 intensive programming courses. I am not sure how much my programming skill have improved over these courses, but the “intensiveness” usually means at least 30 hours of programming for a single assignment. The algorithm coding assignment at Harvard would indeed looks like toys compared to ours. This is the only component I found missing in Harvard’s CS undergrad program. But my whole point is, if one writes his/her first 5000 lines of code. Writing 50000 lines more would not be a big problem.
Even one knows coding and coding over the whiteboards (they are different skills), I think for fresh graduates they still needs significant trainings after joining the product teams. When one is writing a real product, he/she need to consider how to hook a dll into the program, how to deal with all sorts of strange exceptions and input, how to make the programming style be absolutely consistent with another 10000 developers within the organization, and how object-oriented programming is wrong. All these are not taught in colleges. And if some course teaches them, it must be a horribly boring course.
Now I still have the habit of writing codes as the way I did in Microsoft. You can take a look on the programs I sent to you recently to see how much difference between code in CS50 or CS124 and the product code. Just take a look how we use goto statement and how we deal with exceptions, you can feel that the way we learn coding is a lot different from the way we code in “real world”.

Zhenming

Anonymous said...

I think you can teach ANYTHING in undergrad that requires intelligence and it will be a predictor of success in a typical software engineering position provided that interviews test you on what you have learned.

In other words, it's a special kind of IQ test agreed upon by universities and people doing the interviews.

In short, what matters is not so much what you learn but rather that you are smart.

Anonymous said...

Frankly, I never needed anything from my algorithm classes (not even anything from the first course in algorithm).

I tell my students that 95% of the coding they'll do in a job does not require algorithms and that any code monkey can do that. What separates highly sought after programmers from the rest is the ability to implement the remaining 5% efficiently. When tasks are assigned the good ones get the interesting and challenging bits while the code monkeys get more of the easy tasks. Ironically the latter use this as reinforcement that they really didn't need to learn any algorithms since they've never used any.

Anonymous said...

For undergrad curriculum at U. of Waterloo you don't get your degree until you have taken some fairly heavy programming courses in compilers, software abstraction (project oriented), and operating systems with NachOS. Then in upper year you can take specialized courses in your area of interest whether be real-time programming (where it is known you'll never sleep) or quantum computing.

Anonymous said...

I am the interviewer who started this discussion on the other blog.

I think you are too focused on the issue of programming. What I see in candidates, in particular phds, is the lack of basic skills in all areas of CS that are relevant for the job I am interviewing for, most notably algorithms. A whiz coder will not get the jobs I interview for if she doesn't know algorithms or math to a minimum level. One candidate didn't know how to maintain a set of integers under {insert, delete, find-second-largest} without spending less than linear time for at least one operation. Some phds don't know anything about anything outside of their thesis project.

Anonymous said...

To Anonymous #14:

What you see is probably because most PhDs have forgotten all about their basic algorithms/data structure courses by the time they are done with their PhD, and only recall stuff about their areas of specialization. Common sense dictates that if such a PhD wants industry jobs, he/she should prepare, at least by going over some of the basics. However, this simple fact is not well-known: grad-school teaches you to focus on depth and not on breadth, and to believe that smartness, not skills, is everything. In this sense, grad-school actually diminishes the employability of students.

Of course, research _is _ all about focusing on one topic in depth. To ensure grad-school prepares students for jobs better, my suggestion would be a fair number of breadth courses. My experience is also that professors are usually clueless about non-academic jobs : options available to PhDs and what these jobs demand. My other suggestion would be for schools/departments to have resources for career-counseling, specifically for graduate students.

Anonymous said...

As a member of the engineering staff of a large telecomm company (and a former student of Mitz), there is often a wide gap between the skills taught in undergrad programs and the skills needed in industry.

One particular problem isn't necessarily connected to the languages used for development but familiarity with the commercial offerings that are used by large corporations to speed development. Essentially, students show up with little or no industry awareness in their chosen field.

I've had networking students from a local university show up for internships in my company. We ask a basic set of qualifying questions. You'd be suprised what percentage of networking students can't name CISCO as a manufacturer of routers.

I find that without exposure to industry, students have little perspective on how to apply the theory they learn to the real-world problems that need to be solved in the field.

Anonymous said...

I see a clear distinction between those who are CS savvy and those who are not at my mid-sized telecom equip. manufacturer. The CS savvy folks find themselves much more in the middle of the fray, dealing with low level features where the difference between inserting to the beginning of an array and inserting to the beginning of a linked list is palpable. The other folks tend to spend their days swimming in business logic repeatedly trying to answer the question "do the 'if' statements appropriately reflect the outrageously monotonous requirements?"

Anonymous said...

"My other suggestion would be for schools/departments to have resources for career-counseling, specifically for graduate students."

This is very important. I've been at four schools and seen enormous variation in the career resources at the schools. A smaller school might have one or two events for graduate students all year, and if you are traveling then you missed it. Bigger schools, like Harvard presumably, have much better contact with employers.

Noel said...

[I]n your experience, did your education prepare you for your life after in the real world[?]

My education failed to prepare me for the mind-numbing boredom of my first job. It did, however, prepare me for my return to academia, and my imminent return to the 'real world' as an entrepreneur.

Your job isn't to prepare students for entry level code monkey jobs. It's to prepare them to change the world via the application of technology. For this you need fundamentals, as they drive innovation. Ephemera, like the intricacies of linker errors or make files as discussed above, can be picked up by any competent person.

My education/career: Graduate 1997 w/ Engineering and Business degrees. Worked a year. Did a MSc. Worked 3 years. Currently finishing PhD and have started own company.

appughar said...
This comment has been removed by the author.
appughar said...

Most of the undergraduate system courses (eg: Intro/Intermediate to Database, Networks, Graphics etc.) in my uni have a course project component to it. Usually course project constitutes 30% of the grades. So expect a student to spend somewhere between 40 hours per course on each project. Also a major part of the last semester is dedicated for a single project (35 hrs/week). At an average an undergraduate student does around 8 course projects plus the final project.

Usually students are allowed not only to select their project (with a restriction that the topic must fall inside a fairly decent top-level domain covered in the course), but also allowed to use his/her programming tools and packages. This gives ample room to develop and attune their programming and working skills.

I personally believe University courses adapting to the tide of industry will introduce unnecessary overhead. The trends in the latter are in most cases found to be transient and useless after a few year (months?), conversely most of the stuff you learn in school must have stood the test of time with a significant higher probability . One ideally must (and should) expect their University to tutor them about programming concepts and good practise, however not about some "currently popular" industrial application or tool.

Anonymous said...

I am an EE grad student at a big school in the midwest, close to finishing my PhD.

I think my PhD training has equipped me to pick up new things in related areas pretty fast.

When I interviewed last summer for an internship with Qualcomm, I was asked- in a phone interview- a) a lot of tricky puzzle-type questions in probability and b)Some fairly involved questions in physical layer wireless comm.

My research being in info/coding theory, I found the latter category quite hard to answer. I also thought asking tricky and long puzzles in a phone interview was weird.

I was offered the internship, but insteadI ended up going to a research lab where I got to work with a very smart host. All he asked in the interview was if I was interested in working on the problem they were addressing and gave me the resources to learn the programming language they were using. He also asked my advisor for a reference. It worked out fabulously and I think I would not have had such a great time at QualComm.

rgrig said...

did your education prepare you for your life after in the real world

YES.

A commenter mentioned makefiles. Here are two extreme ways of using them in a lecture.

(1) Today we will learn about a tool — make — that is used a lot in industry to manage the build process. When you deal with a huge codebase it is impossible to run the compiler by hand in the correct order. Instead, we record the dependencies in a specialized language and the tool will figure out how the compiler and the linker should be invoked. Here are the most relevant parts of the manual. Here is an example of a complete makefile; it is taken from a real project. The project uses a code generator that gets invoked during the build. The problem with this makefile is that it invokes that code generation every time, and therefore also compiles the generated code every time. Your homework is to find a fix to this problem, thereby speeding up the build-time. In fact, if you can find other ways to avoid redundant work that would speed up the build significantly you will get bonus points.

(2) Today we'll look at graph cycles. Whenever you need to solve a problem that deals with graphs you must ask yourself "can it have cycles?". The problem is generally easier if the answer is "no". This sounds trivial but it is a theme that keeps appearing. An example is the topological sort problem: find an ordering of the nodes such that all edges go from left to right. This can't be solved if there are cycles. The tool make, which I encourage you to play with, is used for building large software systems and its basic function is to do a topological sort. When there are cycles it prints an error message. Let's look today at the following simple problem: Determine whether a graph given has cycles. Here is how we solve it for dense graphs. Here is how do we solve it for sparse graphs. Your homework is to find an algorithm that topologically sorts nodes in a graph and detects if there are cycles (not in a preliminary check!).

Some people prefer the first method and others prefer the second. I conjecture that their preference is strongly correlated with how they evaluate the usefulness of education:
1. Did the school improve certain thinking skills?
2. Did I learn to do this in school?

There is also a strong correlation between how people interpret the question and how they respond. The yes/no answer you give says more about whether you think that school should teach you to think or to do; it says close to nothing on whether the school 'helped'. In fact, a proper experiment to see if school helps is to compare a group of people that go to college with a group of people that do not. We probably all guess the same result for such an experiment.

Perhaps it's better to figure out in high-school whether you like to be taught how to do or how to think and then choose an appropriate school.

Personally, I would hate a school that teaches me how to do instead of how to think. I've been lucky to take mostly theoretical courses. After college I worked for 30 months developing translators in teams from 1 to 10 people. All went smoothly. Now I'm doing a PhD, because I wanted to see what research is like, so I can make a better long-term decision.

It's beyond me how can some people prefer to be taught how to create a project in Visual Studio and how to fetch web-pages in some scripting language rather than how Dijkstra's algorithm works or how generating functions can be used to solve recurrences. But such people exist and there should be schools where they can have fun. It annoys me, though, when such people fail to acknowledge my existence and attack all CS schools for being not in touch with the "real world" (am I not real?) and preach for changing all CS programs.

AstralEye said...

I think that how we behave in the real world/tackle real life problems are a direct consequence of what we learn in school. Many ppl for e.g. say that "I wanna be a lawyer, what use is math/calculus etc to me?" Well may be not the formulae but the approach developed is certainly too useful-- How do you learn to break a complex problem into a smaller one (differentiation?) and combine various small results into a proper larger scenario (integration)... Mostly ppl think this way of thinking just comes by... I think its just an extrapolation of how you have learnt to tackle problems in school. As a corollary if ur teaching in school had really been faulty, you wouldn't have survived in this real world-- so perhaps its this 'way of thinking' (as mentioned in the previous comment) than problem solving that is useful. For e.g. how did the interviewer decide on his course/flow of questions; selecting say 10 questions out of the 100 probable? I think the logic he used then (analyzing the candidate; seeing his C.V.(and not the recos :P);weighing ideas/ questions; selecting the best course etc etc), was the same as he applied while solving some of his problem he worked on for his PhD(analyzing the problem; seeing available data and maybe past literature; weighing ideas ; selecting the best)-- and which he then used in his job. The parameters, their effective weights and balancing them-- which is what you use in all the above things-- is what educations teaches/must teach you, the rest follows.

Anonymous said...

"Please tell me, in your experience, did your education prepare you for your life after in the real world. "

I am a 4th year CS undergrad student and so far I have had five internships (four months each) at various different companies as a software developer (large IT, startups, finance, you name it).

So to answer your question, what we learned in school is absolutely worthless and does not at all prepare you for the real world. I don't have a good explanation, but that's how I feel personally. Everything in school is pretty much outdated and totally uninteresting. The courses do nothing more than digging a few thousand bucks from your pocket in exchange for a few basic concepts. I am in excellent academic standing, yet I don't even remember 90% of the materials just after four months.. The courses themselves are bad too -- some profs just doesn't know how to present materials properly.

I read some of the comments briefly, and I totally agree with "The point of any university program is to teach students how to think. "

Well, I should be going back to studying my exam, which is due in 5/2 hours..