There is a huge disconnect today in the way we teach computer science to students who wish to become software engineers, and what the industry expects of them when they graduate. Ask a recent graduate what the algorithmic complexity for a binary search of a sorted list, and he'll (likely) give you the correct answer of O(log(n)), but many recent graduates struggle with designing any kind of complete system from the ground up.
I recently spoke to a friend of mine who graduated from the University of Maryland with a degree in computer science about the interviews he was going through, and he told me about one particular interview where the question asked was how he would design a system to keep track of the positions of all of the trains in the Washington D.C. subway system.
He also told me how he answered it. He spoke of the data structures one would use-- binary tree this; linked list that, but when I asked him how he said the data would get from the train to whatever computer his software was running on, he couldn't give me an answer. Should there be a computer at each station that communicates with a central computer over HTTP? Again, no answer.
This person is a straight-A student. He took some of the most demanding computer science courses that were offered, but he couldn't answer these questions (that I considered to be simple). This is what happens to an extremely bright person whose entire exposure to computer science and computer engineering was through school.
The takeaway from this observation is that something is wrong with the way we teach computer science. I certainly am not the first to bring this up. I've spoken to a lot of people who have recently graduated with CS degrees, and the gaps in their knowledge frequently surprise me. A CS education is great for those who wish to pursue it as a purely academic exercise, but a person with solely a formal CS education is woefully under prepared for employment as a software engineer.
When I was studying computer science at the University of Maryland, of the myriad projects we were assigned, not a single one involved working with other people, all of the projects required very little creativity, and only one had even a mention of source control. All three of these elements are vital to learning how to write software effectively.
There are very few times in a programmer's career that he'll be working alone in a vacuum. Whether interacting with coworkers in the office, other contributors to open-source software, or even reading code that someone else wrote. And yet, these vital skills are nowhere to be found in your average CS program.
Furthermore, all the projects I've ever had to do in class were of the pattern "implement this function", or "implement these functions". I understand why projects are assigned this way. If a student is assigned a set of functions to implement, it's easy to test that for some input you get the correct output. For any project where the developer has design freedom, it suddenly becomes necessary to customize tests for every student; which is not economical when you have class sizes of 200 or more.
The lack of a "version control" class (or even a unit!) is the worst of these offenses. People are graduating without any notion of how to use a version control system like Git! I've seen teachers advocate having multiple copies of code in different folders as "backups". Source control is a necessary part of a software developer's career.
It's easy to look at any system and point out the flaws, but how do we fix them? I have a few ideas.
The first, and most important in my mind, is to introduce the concept and the importance of version control concurrently with the basic concepts of programming. "Alright class, you've written your 'Hello World' program. Now we'll talk about how to commit it to git." Version control needs to be second nature to someone writing code, why not introduce it as early as possible?
The second, which perhaps doesn't scale as well as the first, is to assign more freeform, multi-person projects from the ground up. Students need to learn how to work on a project with other people, split up work and communicate with each other so that the software will work when its component pieces are assembled.
Version control is also a completely different beast when you're working in a team. Now you're dealing with pull requests, merge conflicts, and code reviews. These are all things that professional developers have to deal with.
It's easy to see why this isn't done in large universities: suddenly you can no longer write automated tests to assign every student a grade as soon as they submit their project; professors suddenly have to do the same thing that an English or math professor has to do when they grade a paper or proof: read the code and grade it according to what it's trying to do.
Lastly, it's important as a developer to be able to look at a code base you've never seen before and figure it out. In all of my CS classes, I almost never had to read code someone else had written. This is closely related to working with other people, but sometimes the author of the original code isn't available to walk you through it. Projects that give a student some code that say "This project currently does x. Change it so that it does y" may be helpful in helping students develop this skill.
The chances of my suggestions being universally incorporated into every university with a CS program are slim, so if a person can't rely on school to teach him how to be a good developer, what can he do? How does one become a good developer?
Ultimately, it's up to the student to find and participate in extracurricular programming activities. I highly suggest finding an apprenticeship. Whether it's an internship at a development firm or involvement in an open source community. Many open source communities have mentorship programs geared to getting new contributors up to speed with the community's development standards. This benefits them just as much as it benefits the new contributor. Developing a one-on-one relationship with a professional software engineer is also a great way to learn. I was lucky enough to have all these things in high school, and it helped me significantly in growing as a software engineer and in finding a job.
Alex is a Python/Django software developer with Fusionbox.