From my years of experience of recruiting computer science students, it seems that universities fail to train students who can build good software. When I hire freshly graduated students, I often need to rewrite their code (sometimes from scratch) before putting the code in production. Most graduates know what inheritance and interface are, but few of them can properly choose and defend which to use. Most graduates have taken classes in “Operating Systems” and thus can talk a lot about threads and scheduling, but few actually have read books like the one from Doug Lea. They cannot be entrusted to write multi-threaded code. Most graduates memorize the visited nodes when writing a function to detect cycle in a linked list, but few of them are aware of Floyd’s cycle-finding algorithm. The funnies thing is that a lot of them think that they are writing object-oriented code because they have replaced ‘struct’ in C with ‘class’ in C++. They are yet to read a book on design pattern.
In other words, these graduates cannot use the programming languages effectively (ineffective). They cannot communicate their ideas to colleagues in their code (incomprehensible). They do not evaluate the space and time complexities of their algorithms (inefficient). They produce spaghetti code that is so difficult to modify (unmaintainable) so we have this motto in the industry: if it ain’t broke, don’t fix it. It is next to impossible to add new requirements without rewriting it from scratch (inextensible). Often when I do code review, the code looks like scribble to me. I have no way to tell whether it is right or wrong (incorrect).
I would like to point out that computer programming is a real professional that requires more than merely reading “C++/Java/C# for Dummies”. We need the programmers to know more than just the programming constructs and some irrelevant theories they never use on the job. Given a project, a competent programmer should be able to understand the problem, design efficient algorithms in terms of space and time complexities, evaluate different implementations, type in legible code, and provide systematic evidences that the code work. It is very unfortunate that universities fail to deliver students that qualify.
Why don’t universities produce good programmers? The major problem lies in the curriculum. Speaking from personal experience, I managed to finished all B.S. computer science requirements, obtained a M.S. and a Ph.D. in this field without ever taking a course in software engineering. In fact, I have never seen a university course with the purpose to teach students how to write good programs, not at the top-tier “research” universities anyway. Somehow the schools assume everyone can read the book such as “C++/Java/C# for Dummies” on their own. Consequently, most fresh graduates write dummy code.
Yes, we do programming projects for courses like Data structure, Operating System, Artificial Intelligence and etc. But these assignments aim to enhance the students’ knowledge in the particular topics. The code is never graded based on how professional it is written. Take Operating System as an example, the assignments aim to enhance the students’ knowledge on the concepts of thread and the OS scheduling algorithms but they are never designed to train students on writing good multi-threaded programs. The textbooks used in class teach about mutex and semaphore but they do not teach how to use them effectively. How many students, after taking an OS class, can design a thread-safe stack? I bet that most of them know what threads are and what a stack is, but few can design an efficient and effective thread-safe stack class.
The second problem is faculty. As a university, most faculty members hold doctorate degrees. The undergraduate courses are usually taught by newly graduated doctorate students. These doctorate students are trained to publish journal papers. Many never deliver any industrial applications in their life time (not hands-on anyway). Not only do they not know how to write good code, but they cannot appreciate how important it is to produce good code. For instance, in a Data Structure course, a professor teaches about stack, but he is unlikely to implement a thread-safe stack class for professional use. Without ever working in the industries, it is very difficult for a professor to understand the details and issues associated with using a thread-safe stack. It would even be more difficult for him to appreciate how important it is to provide systematic evidences to show that his class works and is ready for a third-party to use.
One may argue that “Computer Science” is about science so we study Artificial Intelligence, Operating System, etc. Science is about research and innovation. It is not about programming. My dilemma is that if we cannot go to computer science schools to seek qualified programmers, where should we turn to? Also, what exactly is the use of these university trained computer science graduates if they cannot write good code? After all, not everyone becomes a scientist. Most of them are engineers that code the science ideas into real products that benefit our societies.