What Programmers Should Be Learning in College


 graduate_computer

I officially graduated last weekend ending an undergraduate effort that started at the University of Texas at Austin 20 years ago in 1989 and stalled in a hiatus that turned into a full-time career. 

With the help of my employer’s generous tuition reimbursement plan and the flexibility of the distance learning program at the UMass I finally managed to not only wrap things up and earn a BS in Information Systems, but in doing so earned the Chancellor’s Medal for Academic Achievement. Who knew I had it in me to graduate at the top of my class for my college?

 

The experience of going back to school so many years later has been eye opening and has provided a lot of context to my recruiting efforts for greenhorn programmers. That is, I’ve walked a mile in their shoes and seen what is currently being taught in college level Information Technology programs.

 

The Good News

Contrary to my expectations forged from my previous collegiate experience, the problem of professors teaching outdated technology and theory has been remedied to a considerable degree, at least in the UMASS program. Many of the classes were taught by adjunct professors that worked at least part time in the real world in addition to their academic duties.  This made the lessons much more relevant and practical. Also, I’m glad to see they have moved on from Turbo Pascal and 68000 Assembly, but then I am dating myself.

 

The Bad News

The curriculum is still very centered on learning specific technologies and was conspicuously weak on best practices or practical preparation for aspects of software engineering outside the scope of software construction.  Given the relatively small percentage of time that a working programmer spends on writing code versus other elements of the software construction process, this is not ideal.

 As a hiring manager, I’d greatly prefer graduates with a good grasp of basic software construction and project management skills than proficiency in a specific programming languages. Software platforms exhibit such a short half-life that I’d question the long term value of them anyway aside from the foundational ones like C++.

Concepts such as those described in the canons of programming literature like Code Complete  and The Mythical Man-Month, can provide more lasting value over the life of a programmer’s career.

 

Proposed Curriculum for Software Engineers

The following course of study is a recommendation based on the skills that I’d like to see when I interview entry level software developers. I am not saying that existing programs don’t include some or all of these elements, but I rarely see many of these skills when interviewing recent college graduates.  I’ve broken the topics out for clarity, but clearly some should be combined or split into multiple courses.

Freshman Year – The fundamentals

  • Overview of Operating Systems:  Working knowledge and exposure to at least 3 of the most commonly used operating systems, i.e.  Windows, Linux, OSX, etc. The ulterior motive is to derail platform bigotry before the mental cement dries.
  • Overview of Programming Languages:  Exposure to a variety of languages by writing very basic programs in each. (C#, C++, Ruby, VB.NET, Perl).
  • Scripting 101: Familiarity with the most basic programming concepts such as variables, methods, control structures, etc. without the overhead of more advanced programming concepts to provide a comfortable “wade-in” point for those new to programming.
  • Application Architecture: Become familiar with common application architectures, associated issues, and relevant technologies. (Desktop, Client-Server, N-Tier, Web, Embedded, AJAX, etc.)
  • Intro to Electrical Engineering: Hardware level programming as an analog for software development. Boolean algebra, basic circuit design, logic gates, etc.
  • Database Design Principles and Theory: Set Theory, Normalization, OLAP, ROLAP, etc.
  • Networking Basics: Topics including, networking hardware, topologies, the OSI model, basic signaling, and protocols.

 Sophomore Year – Filling the toolbox

  • Reporting Tools and BI: Crystal, Cognos, SQL Server Integration Services
  • Database Query Languages: Query language and  technique in ANSI-SQLsome coverage of PL/SQL and t-SQL.
  • Programming in <Student’s Choice>: In depth programming course in the language of the student’s choice.
  • Source Code Control Tools and Best Practices
  • Technical Writing: Best practices for creating of software documentation and help systems that are useful to real people.
  • The Build Process and Change Management

 Junior Year – Sharpening the tools

  • Programming for a Diverse world: I18N, L10N, Unicode, etc.
  • Writing Secure Code: Common application security vulnerabilities and how to avoid them (SQL Injection, XSS, Buffer Overflows, etc.)  Suggested Text – “Writing Secure Code
  • Programming Technique: OOP, Design Patterns, Refactoring, Coupling Cohesion.
  • Usability / User Experience: Suggested text – “About Face 2.0: The Essentials of Interaction Design

 Senior Year – From machinist to craftsman

  • Designing Software: Requirements Gathering, Use Cases, Prototyping.
  • Software Project Management and Estimation: Agile, Waterfall, etc.
  • Team Programming: Code review, pair programming.
  • Testing Software: Tools and technique (Unit, Automated, Load, Regression, Integration)
  • Profiling and optimizing code: Static/Dynamic code analysis, Big-O Notation.
  • Debugging/Troubleshooting:I am amazed at how impressively bad a lot of working programmers are at this. Suggested Textbook: “Debugging: The 9 Indispensable Rules for Finding Even the Most Elusive Software and Hardware Problems.”
  • Problem Solving in Code: Problem solving and more in-depth exposure to the programming language of the student’s choice.
Advertisements

16 Responses

  1. Nice one.
    I feel that debugging comes way too late in the curriculum (should fall in sophomore year) , it lacks things like language design/compilation theory and practice (probably senior year), as well as a real networking part on designing and implementing network protocols (probably junior year).

    • Writing this up gave me a new found respect for whoever it is at universities who have to come up with these things. There were a lot of things I wanted to put in there, but it would have turned it into an 8 year degree to fit them all in. I agree with several of your points, but think that the design/compilation theory probably more appropriately belongs in a Computer Science degree plan. I was trying to focus more on a practical programming curriculum.

  2. Great post. When I got my Comp. Sci. degree at University of Washington I though they did an excellent job, but somehow making CS people take Physics didn’t make any sense to me.

    I also think college is a place to learn things that your job is probably not going to teach you – OS design, some math theory etc.

    One last thing – it’s an absolute must for CS majors to take some writing and communication courses. We no longer live in a world where you just write code all day every day. Being connected to the rest of the team and to outside parties is important.

  3. 1. Appreciate the distinction between an Information Systems degree and a Computer Science one, but do you really think you won’t need any Math beyond the introduction to set theory you’re going to put into your freshman database course?

    2. I’m not sure there’s any point in teaching the OSI model (at this level) any more.

    3. Did you use “cannons” (big guns) when you meant “canon” (body of literature accepted as representing/defining a field)

    • 1. Originally I had a statistics and boolean algebra course in there, but ran out of slots. I assumed that they would have algebra from HS.
      2. Although I somewhat disagree, perhaps you are right for a course of study in programming. Maybe this would free up a spot for the math. I’ll rework a little.
      3. Thanks for pointing out the typo.

  4. My concern with a course of study like this would be that the students would never get their heads around basic programming concepts. It takes a long time to understand what is Object Oriented programming versus what functional programming is. It takes a while to get how computer memory works. Sure, as a Java developer I don’t routinely deal with memory manipulations, but when our huge program hits a java.lang.OutOfMemoryError, it is helpful to understand memory ideas.

    Sure, I don’t use a lot of the concepts that I learned in my undergraduate degree on a daily basis, but the theoretical foundations that I got are far better than learning a toolset that will change quickly.

    If I were to re-tool undergraduate curricula, it would be to make them more and not less theoretical.

  5. I would put your listing exactly in reverse order. You put testing, debugging for the last. But this is the entrance into software engineering! Your Freshman Year items like operating systems are just implementation details and would be better understood with some experience (e.g. microkernel).

  6. If Universities were to follow a curriculum like this they would be preparing students for your companies and not in engineering and life. Universities job is to prepare students for work but also for life. I prefer that they teach theory, math, and fine tune basic programming that the needs of web 2.0. It is the responsibility of a corporation to keep the education of the engineer going. Which is something you see less and less in corporate America.

    Now that you wrote this. Tell us about the curriculum you will put in place for engineer so they develop and grow?

    [Note: I fixed some typos in this comment, but did not alter the content otherwise.]

    • I appreciate your perspective, but also feel that the burden of growth and current skills should be on the engineer and not the University. Ultimately I think we agree more than disagree. I tried to build this curriculum to be heavy on theory with just enough technical content to allow the student to apply that theory in a practical context.

      Thanks for your feedback!

  7. I’d like to take these all over again ( :

    This would not be a CS degree. You called it a Software Engineering degree? Would you name it anything else? Something new perhaps?

    “From machinist to craftsman” – I don’t think you can call your self anything but a novice or apprentice until you get in to the real world and get a few years under your belt.

    A good writeup and a good read though. Thanks.

  8. Okay, this is good for, say, community college or something like that, but not for a university program. Here are some problems:

    1. Too few theory. Face it: you don’t go to university to be a coder, but a programmer, who understands, appreciates, and effectively use ALL technologies, past, now, or in the future. To do that, theory about computation, computer science, algorithms, etc. must be taught. You don’t think these are important or something?

    2. Yeah, talking about algorithm, you don’t include that. This is a HUGE mistake. Algorithms are EVERYTHING in programming! With a proper algorithm, you can program in ASM as well as in Javascript. Omit it, and you produce bad programmers.

    3. Too little coding. I learn something new every 500 lines of code. A good program should spend AT LEAST 1.5 years into coding and maintaining code, plus other code-related activities.

    4. Too little time allocated to liberal arts. Okay, I know, some people under-appreciate these things, but they broaden a person’s mind and afford creativity. Plus, they don’t need to be too heavy. Your program is too heavy to leave room for them.

    5. Wrong order. One should learn how to solve problems (algorithm, math background, etc.) first, then go on and apply these methods. You do the reverse. This is no good: the students will become too into coding, and don’t pay good attention to design matter.

    Otherwise, nice plan.

    Editor’s note: I fixed a small typo in this comment.

  9. Magice++

    Most of this is tools/techniques.

    The above plan is great until your boss ask you to “figure this out and build it.”

  10. Well this all what a programmer should learn, but not a computer science engineer

  11. […] What Programmers Should Be Learning in College « Software++ (tags: programming education) You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site. […]

  12. Not a bad start. (Aside: topics eerily similar to the 7 Habits of Highly Effective People, which is a strictly Modernist approach in a post-modern world, it might not apply too well for the future.)

    How about this suggested plan instead?

    Freshman Year – The fundamentals

    Overview of Operating Systems: Working knowledge and exposure to at least 3 of the most commonly used operating systems, i.e. Windows, Linux, OSX, etc. The ulterior motive is to derail platform bigotry before the mental cement dries.

    Overview of Programming Languages: Exposure to a variety of languages by writing very basic programs in each. (Excel VBA, C, C++, Java, C#, Perl, Matlab/Octave).

    Scripting 101: Familiarity with the most basic programming concepts such as variables, methods, control structures, etc. without the overhead of more advanced programming concepts to provide a comfortable “wade-in” point for those new to programming.

    The Hardware/Software Interface: Digital logic (boolean algebra, logic gates, KV maps, etc…), assembly language

    Source Code Control and the Build Process: CVS/SVN/git, committing code, assigning defects/features, creating a backend build process.

    Sophomore Year – Filling the toolbox

    Data Structures and Algorithms (2-semester interleaved course): big-O, lists, arrays, hash tables, binary trees, searching, sorting, …

    Programming in [Student’s Choice]: In depth programming course in the language of the student’s choice.

    Debugging/Troubleshooting:I am amazed at how impressively bad a lot of working programmers are at this. Suggested Textbook: “Debugging: The 9 Indispensable Rules for Finding Even the Most Elusive Software and Hardware Problems.”

    Debottlenecking Code: profiling, optimizing, Static/Dynamic code analysis. Focus on CPU-bound applications.

    Networking Basics: Topics including, networking hardware, topologies, basic signaling, and protocols.

    Junior Year – Sharpening the tools

    Application Architecture: Become familiar with common application architectures, associated issues, and relevant technologies. (Desktop, Client-Server, N-Tier, Web, Embedded, AJAX, etc.)

    CRUD Applications 1: Microsoft Access, data normalization, SQL, queries, frontend UI, reporting

    CRUD Applications 2: Migrate application developed in CRUD Applications 1 to 3-tier web/app server/SQL server

    Programming Technique: OOP, Design Patterns, Refactoring, Coupling Cohesion.

    Technical Writing: a general technical writing course from the English department

    Software Engineering Ethics: history of famous software mistakes, IP issues, the conflicts between making money and doing the right thing

    Senior Year – From machinist to craftsman

    Building A Non-Trivial Application: Each student (individually only) builds anything they want (2D/3D game, business app, …) using any programming language they wish. It must exceed 3000 LOC and be reasonably commented. In the final portion of the course, they must implement a new non-trivial feature in a classmate’s project.

    Testing Software: Tools and technique (Unit, Automated, Load, Regression, Integration)

    Usability / User Experience: Suggested text – “About Face 2.0: The Essentials of Interaction Design”

    Programming for a Diverse world: character sets (ASCII/CP437/Unicode etc.), string replacement (I18N/L10N/BiDi), issues in N-tier architecture

    Computer Security: crypto/SSL/PKI, worms/viruses (including writing them), exploits (buffer overflow, SQL injection, etc.)

    The Project Lifecycle: Requirements Gathering, Use Cases, Prototyping, Agile, Waterfall, etc.

    —-snip—-

    Very similar to your list, but a few additions and re-groupings.

  13. You can’t be serious. I’ve liked much of what you’ve written, but this is just bad.
    This is a program for teaching people to be drivers when you should be teaching them to be mechanics. Every mechanic can drive, but not many drivers can even change their own oil. This teaches how to use other people’s platforms to do basic business software, but it does not teach you how to do any of the hard stuff. It doesn’t even provide a foundation.

    No algorithms, as others have noted above? No operating system internals? Nothing about how to implement a database? No graphics? No programming language theory, especially compilers? Your “variety of programming languages” is a joke; it’s all from the menu of the same restaurant.

    If you never want to do anything fundamentally hard, if you only want to follow in the path of more knowledgeable pioneers years after they did, then this is the program for you. But you’ll never do anything new or exciting, and you’ll always be dependent on other people to do the truly hard things. A world of graduates of programs like this will have no Google, no Tivo, no Lucene, no Amazon, no Linux… Wait, it wouldn’t have anything, because the only things that these graduates would know how to build would depend on pieces that nobody would know how to build.

    Actually, wait… That’s great for me. I changed my mind. Every CS program should be shut down and replaced with this “Software Engineering” program.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: