This is not an attempt to knock any particular program, professor, or course of study.  It's just some things that I think should be included in an undergrad CS program that I don't feel like I got.

  1. Serious study of data structures and algorithms.  While I know how to implement a linked list, structs, classes, vectors, and other data structures, not a whole lot was said about the best use cases for each.  That's something I've had to discover on my own.  And the most complex tree we discussed was the Binary tree.  We never talked about balanced binary trees, red-black trees, or generic n-ary trees.  Although I was taught the general idea behind Djikstra's algorithm, and can tell you the big-O runtime for about a half-dozen sorts, practice implementing them and discussion of their comparative strengths and weaknesses is not something I remember from my undergrad.  Also, there was NO discussion of time-memory tradeoffs involved in implementing some of the algorithms.  In fact, (and I'm embarassed to admit this) I only recently found out about the in-place implementation of quicksort!
  2. How to find your focus.  If there's ever been a real-world example of an NP-complete problem, it's finding your niche.  I'm still searching, and as I get into more things, I'm finding more interests than I am able to exclude.  IT/Computers/Technology is a massive field and even narrowing it a little is hard.  About the only things I've narrowed down are that I don't want to do end-user support, that I don't want to manage people, and that I want to work with/develop Open Source.  Oh, and that I like not doing the same thing every day.  (As it is, my current job is getting on the monotonous end of things.)  I hope I'll find my focus before its too late.
  3. How to develop with others.  This is a skill I've developed over the past few years of the "real world", but I'm not sure everyone I've worked with has gotten it down.  There were too few group projects in my undergrad, and those that I had were comparatively small.  We never had the big software engineering problems, and never really had to develop good APIs for others to depend on.  The division of work never seemed to be "you do the UI, I'll do the database components, and he'll do the business logic."  It was always "you do the UML diagram, I'll do all the code, and you do the final report."  That's not how it works in the real world (ok, well, sometimes it is, but it's not how its supposed to work).
  4. How to effectively use source code management.  Using SCM is critical to any serious development.  Not once in my entire undergrad career was that discussed.  No mention of any SCM.  While my experience in open source had led to me using and understanding SCM, I can say that I've seen how well prepared others are to use it -- and it's pretty scary.
  5. How to do requirements definitions and other software engineering tasks.  When I started my undergrad, there weren't really any dedicated software engineering programs -- everyone did CS or IS.  In the CS side of things, there was one software engineering class.  You can't learn to estimate time, do requirements definitions, manage deliverables, and all the other tasks that go into a software lifecycle in one class.  While I realize not every CS student will end up doing software engineering, the software engineering class should be early in the program (in my program, it was nearly at the end) and those concepts should be incorporated into every major project you do for the rest of your degree.  You've gotta do things more than once to really understand it.
  6. How to do dev/test/prod.  Much like #5, the words "unit testing" never came up in my undergrad program.  There also wasn't really any discussion of maintaining existing software, and of the different environments.  I knew about them, but not from my undergrad, and I've had to learn a lot about them "on my feet."  I'm still trying to get some of our practices at my job into this lifecycle in a sane manner, but it turns out: doing things the right way requires more work up front.  It'll save you in the long run, but it's hard to get that initial investment when it looks cheaper to "fix things later."  (It's not, by the way.  Doing it right the first time is always cheaper.)

I'm still learning a lot -- but if you're not learning, you're stagnant.  There are just some things that make you slap your forehead when you realize how nice it would have been to know those skills 5 years ago.