Thursday, May 28, 2015

Training Versus Education for Software Developers

I have an interesting perspective on the issue of training versus education in software development. I have a master's degree from Stanford in computer engineering, I have written and taught college computer science courses, I have written and taught industrial training courses, and about 8 months ago I completed the Epicodus Web development boot camp class in an attempt to reinvent myself. I will state up front that I believe BOTH training AND education are necessary to become an excellent software developer.

Training is not enough

If you have to choose between the two, training may be the better way to go, since it will get you in the door much more quickly. But unfortunately training by itself is NOT enough to be an excellent programmer, just a money-earning one. It will be interesting to see how today's "Anybody can learn to code!" sales pitches will play out five to 10 years from now. The question is not whether anybody can learn to code, but whether just anybody can learn to code WELL. I suspect - and I fear - a lot of crummy code is being implemented these days by under-educated developers under the tutelage of under-educated software development managers. (I hope I'm wrong but it appears software development debacles continue unabated; the one that comes most quickly to mind is the CareOregon Web site that was implemented by Oracle. The fight over the many millions of dollars spent in vain will be fought in the courts for years.)

Recently I was assigned to work on the incomplete code of another code school graduate who had just achieved the ultimate goal - that I must confess I have NOT yet achieved - of a full-time, permanent job. The classmate had been working on a report for months that was supposedly rendering with sample data. I quickly discovered the report did NOT render with real-life data.  I ended up fixing a series of relatively small problems and got the report to render with real-life data after a day's work. But then I realized the code had some systemic problems. For example, it stored a couple of strings in a database table, one of which was 255 characters long(!), when the strings could have been represented by integer database record ID numbers instead. I left that problem, plus a couple more I found, to my now-former manager ABC to fix (since I discovered it one day before I was laid off.)

Had this co-worker taken a database class before writing that code, they would have been taught the database schema normal forms, during which they would have learned that you don't waste storage on strings when you can use anything else that is more storage-efficient. I suppose, in this day and age of cheap computing power and storage, those considerations aren't as important as when I studied them in the 1980s. But there is also the expense of querying on those long strings, which their code was also doing! The possibility of a mismatch in comparing two 255-character strings is much greater of a mismatch of two integers, which on its own merits contraindicates the design.

Education is not enough

This is a real-life example of how training without appropriate education can be a problem. But the opposite problem can also be true, since a bachelor's degree in computer science can be so theoretical that a graduate isn't qualified for any actual jobs. A quick Google search on "university courses software development lifecycle" did bring up a couple of interesting-looking offerings from DePaul University and Stony Brook University. But I know I didn't study anything practical with respect to software development at either Oregon State (where I took CS courses as a postbac) or Stanford. I studied algorithms and databases and operating systems and networks, but I couldn't study test design or comparative software development methodologies or bug reporting or version control/configuration management strategies or requirements management (which is the single-most important element of keeping software development on time and on budget) because those courses simply didn't exist.

Another problem for universities is which programming language(s) to teach. It's probably too difficult for them to keep their curricula current with courses in the "hottest" languages because 1) No one agrees on what the "hottest" languages are (For example, is Java or Python or Ruby the better backend language?), and 2) What is considered the "hottest" language is a rapidly and constantly moving target. Perhaps the only practical thing to do is educate a student WELL on one backend OOPL - Java, Python, or Ruby - and then give them a thorough education in JavaScript since, despite its many inherent flaws (and its' being totally misnamed since it has NO relationship to Java(!), it seems to be required for any reasonably performant Web frontend. The current quarter- or semester-long programming language survey course is still a good idea, but it should focus on the different types of languages (e.g. procedural, functional, and OO) and the advantages, disadvantages, and correct uses for each type rather than just being a sampler.

No substitute for real-life experience

What was most valuable to me by far was the internship portion of Epicodus. The chance to work on real-life code in a workplace setting was much more educational than writing phony, short (or in my case, not so short) programs to demonstrate various Web programming elements. I learned about Agile methodology by participating in defined code sprints that were reviewed and subsequently put into production. I learned about better UI design by suffering the embarrassment of watching a real-life user struggle to use code I had created, then worked with my former manager XYZ's UI redesign to help make it the application work much better. (I did point out to XYZ that my former co-worker and I could have implemented his greatly improved UI the first time around if he had given us the wireframes he eventually created.)

I learned automated Web testing by spending months writing a 300+ scenario/almost 2000 step Cucumber/Capybara regression test suite (and subsequently fixing the bugs it found). We were taught "git" (a popular freeware version control tool) at Epicodus, but I didn't really learn HOW to use it correctly until my ability (or lack thereof) meant the difference between a smoothly-running project or chaos. (As a side note: At Epicodus we were taught to never use "git rebase" because it could cause problems. In the real world, I ended up using "git rebase" on a regular basis as part of established software development processes. I also finally learned what "git stash" did and how to use it correctly after the second time I lost a full day's work!) We were also taught "bundler" (a popular freeware bill of materials/configuration management tool) at Epicodus, but only on the job did I learn the utter frustration of trying to reconcile conflicts when using literally dozens of different Ruby gems with complicated inter-dependencies.

Anti- and pro-education biases get in the way

Something I find truly disturbing in today's code school training environment is what I can only describe as an anti-education bias. Having a degree in computer science can sometimes, somehow be viewed as a negative with the epithet "credentialism". It IS possible to self-educate about the fundamentals of computer science because my aforementioned former manager ABC was able to educate himself amazingly well on his own, but it takes more motivation, discipline, curiosity, and time than most people possess. Since every action has an opposite reaction, educators may well dismiss those who have received only code school training or self-education as being "technicians" rather than developers or engineers, and that is also troubling and unfair. I am not sure how many of my Epicodus classmates had computer science backgrounds. I know one person had a master's degree in information security but I suspect we were greatly in the minority among the former teachers, social workers, and musicians in our cohort. And my former manager ABC is one of the most computer science knowledgeable people I know despite his lack of a formal computer science degree.

There are no easy answers, and I don't pretend to have a definitive answer to this conundrum. One partial solution may be for computer science programs to do what code schools do well in terms of arranging real-life internships for their graduates. (Hopefully some CS programs are doing this already?) Another partial solution may be for code schools to incorporate more educational elements in their trainings. It would go a long way to teach code school students about the tradeoffs of efficiency and ease of programming using the examples of interpreted languages, database joins, and automatic garbage collection.

Two interesting articles and further thoughts

In the week or so since I originally wrote the previous portion of this post, I found 2 interesting (and somewhat contradictory) articles that are somewhat related to this topic:

http://hechingerreport.org/can-we-really-prepare-kids-for-both-college-and-career/

http://qz.com/414542/why-programmers-should-get-a-masters-degree/

The first article, "Can we really prepare kids for both college and career?", answers its title question with a resounding "Yes" because California programs have been successful. The "linked learning" programs described in the article give high school students the chance to actually DO something concrete in a chosen area of study, and they have demonstrated a high success rate. The unfortunate part is that only 27 high schools have these programs in place for approximately 17K students, perhaps expanding to 19K students in the near future. I hope more states will look into and adopt some version of what California has done. Perhaps code schools could also take a look at what these high school programs are doing right and see what is applicable to add to their curricula.

I think the second article, "Why all programmers should earn their masters", is flawed in its reasoning. The author advocates that a programmer with a 1-year master's degree will have an average starting salary of $17K more than a BS graduate, and the author suggests that computer science graduates avoid the "fast-money trap". But while starting salary is important, it isn't everything:
  • An entry-level programmer will earn much more than $17K in their first year (even after taxes)!
  • I don't know anyone who completed a master's in computer science in a single year unless they did a co-terminal program to get a master's and bachelor's at the same time. It usually takes 2 years full-time. (It took me 4-1/2 years working full-time and attending Stanford part-time to get my master's.)
  • I think the author's assertion that a computer science BS graduate will "lack the in-depth knowledge and design experience necessary to take on challenging assignments that would lead to rapid advancement" is a failure of university computer science bachelor's degree programs.
  • I'm not sure what a master's graduate would learn would that would give them the practical knowledge and experience required for rapid advancement. A very useful program might be something along the lines of a master's degree in "software development practices". Hopefully something like this already exists and I just haven't found it yet!
  • The additional debt that the master's candidate would incur could be considerably more than $17K.
  • Most computer science BS graduates have gone to school for 16 to 18 years straight and NEED a break from academia and a chance to go into the "real world" for a while. (I'm all in favor of the US's adopting Britain's "gap year" idea for high school graduates, at least as an option. I think this would keep a lot of college students from flunking out as freshman because they haven't learned how to responsibly live on their own.)
  • Sometimes companies will pay for an employee to obtain a master's degree while I don't know of a company who will pay for a bachelor's degree (although they could exist without my knowing about them). I hereby thank Hewlett-Packard for paying for my master's degree.
But the most compelling reason for a computer science BS graduate to get a  job before they embark on a master's degree is that, after they have worked a while, they will have a better understanding of which area(s) of computer science are most interesting to them. If they decide later on to get an advanced degree, they will be more likely to choose a program more suited to their needs and wants and be more focused on their area of study. The only reason I can think of for a computer science BS graduate TO go immediately for a master's degree is if they have found something that deeply inspires them and they want nothing more than to pursue it. Even then I might advise them to try to find some sort of internship related to their passion before devoting time and money to an advanced degree.

The one issue on which I heartily agree with the second author is:

"Silicon Valley is paved with the myth of the software engineering wunderkind, a programming genius who reaches heights of success without a graduate degree or maybe even an undergrad degree. In reality, this wunderkind is rare."

Bill Gates and Steve Jobs are often held up as examples of why education is not necessary. (I think Steve Wozniak would probably be a better example than Steve Jobs since Woz did the technical work, but he never got the press that Jobs did.) People need to appreciate the utter rarity of the extraordinary success of these lucky individuals like Gates, Jobs and Wozniak. For the 99% (or 99.9999%) of us, THE MAGIC WILL NOT HAPPEN, and what success we achieve will be only through appropriate education, training and very hard work.