Whats lacking in CS Degrees nowadays (Part 1)


I remember when I was a fresh grad, just joining Google. I was naive, starry eyed, and somehow scraped through the gauntlet of interviews thrown my way. Then came my first few weeks at work. I was given the task of writing this new testing framework for my product. In Java. Being the slinger that I am, I was in my zone. I worked for about three weeks, and churned out the code in no time. I had a working prototype which performed all that it needed to, and was customizable. I was pumped. And then came the point where I had to check this in. So of course, I sent it to one of the senior developers for review. And the first set of comments came back.

It almost seemed like there was a line of comment for each line of code I had sent. Suddenly, my starter project seemed like an insurmountable task. I ended up pairing with aforementioned developer, and refactoring the code till it was almost unrecognizable. But the end product after all that blood and tears and refactoring was something much more manageable and maintainable. We added unit tests for each component, and separated our concerns properly.

First, I thought maybe it was just me, I hadn’t learnt something in college. It was a humbling experience, and showed that I had much to learn. But then I saw this repeat. An intern I knew spent his entire internship developing a component for a bigger project, but he was unable to check it in till his internship finished. The code was simply horrible to maintain for anyone who had not written it, and there were no unit tests, so no additions could be done with confidence that nothing else was broken. This was code developed by a really smart guy, who was a pretty good programmer. And this was no isolated case, something along these lines happened again and again. So what happened ?

This was when I started questioning if what happened with me and this intern weren’t just isolated cases but part of something bigger? A conspiracy even? Well, I wouldn’t go so far, but simply put, why weren’t we taught in college how to actually develop software? Why doesn’t Software Engineering actually teach how to write maintainable, well tested applications? Why isn’t there a single CS course which taught us how to work with legacy systems?

I mean, the usual Computer Science degree consists of courses in Discrete Mathematics, Automata Theory, Data Structures and Algorithms, Object Oriented Analysis and Design, Software Engineering and many more. And sure, I learnt about how to define classes in my OOAD class, and how to write sorting algorithsm and graph algorithms in my Algorithms class, and what the different steps for a Software project are and what approaches are present in my Software Engineering class. But looking back at it, none of them really prepped me for the work I would do in real life.

For instance, the OOAD class had a great project of creating a Chess game with AI. And I am proud to say I did get it working with a pretty solid AI backing it. But it was not code that I am proud of, nor would I ever want to go back and add a feature or fix a bug in it. My Software Engineering class had a project which was mostly talk and design, and really not that much implementation. And Algorithms was mostly write a function or one or two classes to implement an algorithm.

These were some great professors. And I gained a solid theoretical base in Algorithms and OOAD which would have been impossible otherwise. But some of these professors had industry experience. And the assignments they gave and the problems they assigned reflected nothing of that. And that hasn’t been just my experience, restricted to my university. Talking to my colleagues and friends who graduated around the same time, it has been the norm, not the exception. Why is this the case?  Why couldn’t my CS degree have prepared me for what I would have to work with?

I will continue down this line of thought in my next post, where I try to articulate what I would have wanted to be taught in college, knowing what I do know now.

, , , , , , , ,

  1. #1 by Tejas on July 21st, 2009

    I agree with you completely. Somehow when I got done with engineering I thought I had been prepared to design a rocket. After all we had done some crazy calculations in Math, Probability etc etc But in the real world things were a lot different.

    Even getting a stupid computer working was a pain. Oh man…but those 4 years were still the best years of my life…lol

    Don’t you agree Shyam? haha

  2. #2 by Shyam on July 21st, 2009

    Indeed. Good times! What do you think about your current degree, gonna be the same?

  3. #3 by Mike on July 25th, 2009

    I completely agree with your post…I took a six month co-op during my college years, and learned more about good coding standards in those six months than I’d learned in four years of classes and teaching myself how to program.

    Now, when new co-ops/interns come in, one of the first things I do is to tell them to get their code reviewed early and often–and that the first couple of reviews are likely to be brutal. However, you tend to learn a lot more from your mistakes rather than your failures, so it all ends up okay in the end.

    One of the big things missing from colleges is how to review your own code for improvements–comments are nice, but ensuring your code is maintainable is even more important.

    And I also agree with you–it might have been nice to have a class where our job was to maintain and/or enhance a legacy system with some built-in flaws. I would bet there are some interesting learning experiences that would come out of a class like that.

  4. #4 by J on July 29th, 2009

    I strongly disagree with this article.

    I agree with the fact that a 4 year college degree does nothing to teach maintainable code development, but I disagree that it should be changed to do so.

    What you get in college is a strong background in theory. This background is necessary for doing what you need to do in the workplace.

    It’s clearly not sufficient, but that is true for all engineering fields.

    I think the things that can most easily be taught in a single semester classroom course are the things that are taught in a CS program.

    If we were to try and teach writing real, maintainable code, we would run into at least two problems:

    1) There is more than one way to write maintainable code, and different companies have different cultures, standards and ways of doing this.
    2) It’s fairly inefficient. In almost any company, the way this is taught is one-on-one. College is not optimized for a lot of one-on-one time. College is optimized for getting broad ideas, theories, etc. across, so let it play to its strengths, and let mentorship programs at either an internship or the first full-time job do the rest.

  5. #5 by LarsBerg on July 29th, 2009

    I think that’s part of the reason new full-time hires at MSFT (at least back when I got there…) get assigned an area and some very old or obscure bugs to fix. There’s nothing like needing to change just a line here or there to teach you the whole ins & outs of producing commercial software – without wasting weeks of “productive hacking” when you really don’t know what the heck you’re doing.

    I’m not convinced a university course can do this well. It’s stuff you learn over the course of weeks of 8-10 hour work days. That’s, what, two semesters of three hour-per-week labs?

    You know what’s really scary? How many people *never* learn this stuff. When I was interviewing 10 year veterans of startups, insurance industries, etc. I was frequently finding they had improved their knowledge but not their commercial development skills. No hire.

  6. #6 by Aaron on July 29th, 2009

    I do agree with J. This is exactly what an internship is for. If you want to be ready for the real world by the time you graduate, get at least a year of work experience in through internships, or some other form of part-time work in your field. And still get ready to be humbled by a senior engineer=)

  7. #7 by Nolan on July 29th, 2009

    Nice article, and I agree. My first job was the same frustrating experience. In college, programming was easy. As long as it compiled and spit out the right answers, all was well. The computer science program at UNC-Chapel Hill had one course when I was there titled ‘Software Engineering’, but being more interested in the theoretical aspects opted not to take it.

    On a tangential note, could you give an example of what kind of things you had to change? As in why you built it one way, but the the manager needed it another way. Could be a good blog post…

  8. #8 by Sharkey on July 29th, 2009

    I completely disagree, likely because I consider myself an academic egghead (and because I’m about to return to school to continue studying). You achieved a computer science degree, not a computer programming degree. You shouldn’t have been studying refactoring or unit tests, you should have learned the fundamentals of what you can express in code; classes like Discrete Math, Data Structures, Algorithms, etc. describe the potential and the limits inherent in computational abstractions, whether they are expressed Java, C, Lua or Haskell. Unfortunately, there is a conflation between a software developer and a computer scientist, and perhaps schools should change to reflect that distinction.

    In case it sounds like I’m implying that developer is a “lower class”: I consider it the difference between an architecture degree and a materials science degree. It isn’t the amount, difficulty or the general subject of the schooling, just the focus. Graduates of both programs may end up working on the same building with similar levels of expertise, but each with their own domain, and similarly with CS and Software Engineering.

  9. #9 by Shyam on July 29th, 2009

    So I’m going to be a little lazy and reply to a bunch of comments, all of which seem to echo a similar idea that the Comp Sci degree is meant for academia or theoretical backgrounds, and internships and co ops. First things first, I started off as a Software Engineer major in college. I stuck through it for 2 years, before switching to a Comp Sci. Degree. The major reason for that was the Software Engineering courses (which I assumed would be more towards engineering good software) turned out to focus on the theoretical aspects of Software Engineering, most of which aren’t applied in software development. Courses like requirements gathering and software testing are so out dated or out of touch that they end up talking generics which you end up chucking when you graduate, because “thats not how you do it in real life”. I have had so many people say that to me.

    So I switched to comp sci, and I enjoyed the heck out of it. I ended up taking some graduate level courses even as an undergraduate, and I loved it. I even did an internship in the Financial industry in New York. But that experience at software development just worsened my skills, not improved it. Code that probably will be thrown away the next time someone works on it, a focus more on get things done right now and don’t worry about who will work on this next, because you’ll be mostly gone.

    What I’m getting at, is even in the industry, its not taught. For every engineer who’s learnt through experience, there are 10 who just don’t get it. Writing maintainable code is not different from company to company. Follow a few basic tenets, and it works out the same. Sure, there might be style guides and naming conventions, but I am not talking about that. And why should it be that the theoretical and practical aspects of something be separate ? People pay a few thousand dollars for their education, can it not teach them just enough to land them a good job? People complain about the lack of good candidates from college, but when colleges go and teach pure theory and no practical knowledge, what do you expect? Why can’t there be a, say, special track for industry focussed graduates vs academia focussed students? Thats all I’m saying. There has been almost no attempt at this.

    I’ll probably do a follow up article to this with an example of what my first code attempt was vs what it should have been. But I love this discussion, thanks for your opinions.

  10. #10 by Clarence on July 30th, 2009

    One way for college students to learn quickly is to participate in open source projects. You get to learn how working developers code, have a chance to join in the discussion, and grow a thick skin when your submit get rejected repeatedly !

  11. #11 by Valeri Karpov on July 30th, 2009

    The answer is simple; you need to start with a solid background before building up your practical knowledge. In my mind, SWE is to CS as Physics is to Math – if you only study physics, you learn some bastardized math but learning new physics material is harder than it should be because you’ve never sat down and learned the underlying math. I know quite a few kids who wanted to be physics majors but didn’t like or understand math – they’ve either dropped out of physics or are struggling through it.

  12. #12 by Arun Srinivasan on August 3rd, 2009

    Computer science and engg in Colleges :

    1. theory – the backend layer
    2. application, projects – the middleware
    3. co-op and internship building you to be a better engineer – app layer.

    However beautiful the app layer is, if the backend like db design or interaction layers sucks, u r bound to be a failure. Thats why it’s easy (I am generalizing here) for an above avg engineer to become fully rounded prof than some above avg student (above avg, exceptions/anomalies are bound to be found everywhere) from community college learning applications :)

  13. #13 by Rezmason on August 21st, 2009

    I don’t think there is a place for theory without some practical grounding. Bam, there. Maybe that hurts to hear, but someone has to say it.

    Consider this. “Theory” may consist of anything one reasons about, but we choose to study the theoretical aspects of computing (instead of, say, the theoretical aspects of metallic floating sandwiches). Because of this, teachers who cover a theory are obligated to also eventually demonstrate how that theory can be applied. This is so sensible, it seems obvious.

    Now consider this. Every semester, hundreds of thousands of CS students sit in a course that teaches them about operating systems. They learn plenty, and although they themselves might never go on to create an OS, they hope to at least apply their knowledge to other, adjacent tasks.

    But in real life, a product as complicated as an operating system is usually created by a whole group of people. Using the reasoning above, isn’t it sensible that students expect from their teachers the practical knowledge that will allow them to contribute to such a group? Doesn’t this go without saying?

  14. #14 by Rezmason on August 21st, 2009

    I think my previous post skipped a beat. I meant to say, we study computer science theory (and not metallic floating sandwiches) because we intend to apply CS theory to real computing. There is an inherent intent to apply what we study when we study it.

  15. #15 by Shyam on August 21st, 2009

    Oh I completely agree that the intent is to apply what theoretical knowledge we have gained back out in the field. But my gripe is that 1.) You seldom have the knowledge to know what else is available, ending up reimplementing something that already exists
    2.) You are used to writing throwaway code or non maintainable code that becomes either your own or someone else’s headache. Most people eventually do learn to become Software Engineers (though I shudder when I remember the ones that didn’t make that leap), my argument is that it could very easily be alleviated by atleast some amount of coursework that is currently non existent.

(will not be published)