One of the problems with computer science courses is that they are too academic; heavy on the theory while lacking in practical application. That’s not to say that theory is bad. Algorithms, data structures, run time analysis, discrete mathematics, and so on are the bread and butter of a solid developer. However, actually knowing how to write code is a key skill as well, and surprisingly, it is something that is not taught (adequately) enough in schools.
I attended the University of Washington computer science program. Aside from a few introductory programming classes, none of the courses really did a deep dive on the art of coding. Best practices regarding things such as good design, performance and scalability, testing strategies, naming conventions, formatting, debugging, defensive coding, etc, were things students had to pick up on their own. My software engineering course, which should presumably have covered some of these topics, was woefully inadequate. Part of the problem was that it was only a quarter long. In the real world, devs work in large teams and even larger code bases consisting of millions of lines of code. One short course can not possibly prepare the students for that kind of complexity.
One way to mitigate this problem is of course, to do actual work in the real world. However, that can be a crapshoot. You’d have to get lucky and find a good mentor who can show you the ropes. The other option is to teach yourself. Luckily, there are many books out there on how to write software well. Here is a simple list of books that I’ve read which I’ve found to be helpful. Obviously, this list is by no means complete.
- Code Complete – this is one of the most comprehensive books out there on how to actually write code well. It was written specifically to capture all the best practices regarding development. It is well written and well researched, citing sources from both the professional world and academia. The author is quite thorough as well. Because there is no “one size fits all” solution in software development, he presents multiple viewpoints for many of the topics, discussing the pros and cons of each. However, because the book is so thorough, it is also quite long (my copy is 914 pages long). Some of the information may be a bit too basic (such as the sections on conditionals and data types), however, there is something in here for everyone. As an added bonus, every chapter has a recommended reading list.
- Writing Solid Code – a lot of cynical people will point out that this book was published by Microsoft and make snide remarks about buggy Microsoft products and blue screens. However, this is a good defensive coding book. All the examples are in C and involve the joys of pointers and manual memory management in C, but a lot of the concepts still apply to today’s modern languages, such as the numerous examples of how to use assertions properly. One of the most insightful things that I took away from the book is that solid code is the result of a good mindset. Anytime you discover one of your own bugs, ask yourself how/why the bug happened, and what you can do in the future to automatically detect / prevent such bugs from happening in the future.
- The art of UNIX programming – this book covers the design philosophy of UNIX/LINUX systems. Because it discusses design philosophy, the information in this book is relevant to all developers, not just those working on a LINUX distro. The author discusses things such as transparency, modularity, simplicity, parsimony (writing programs as small as possible and no larger), composition (writing programs that can work well with one another), file formats, minilanguages, and a diverse set of other topics. In addition, the book contains quotes and thoughts from many computing legends such as Dennis Ritchie, Doug McIlroy and Brian Kernighan. There’s even a section at the beginning detailing the history of UNIX computing. As someone too young to have been a part of the computing revolution, its always a treat to learn about its past. Its difficult to sum up the book in a nutshell, but one of the key points is to write small, concise, simple programs that do one task well, and to write these programs in such a way that it can take input from other programs and output to other programs. By building upon this solid foundation of simplicity, one can elegantly combine these simple programs together in complex ways to achieve impressive results. This philosophy is what allows users to do stuff such as deleting all the html files containing the word “foobar”: “find /path/to/public_html -name ‘*.html’ -print0 | xargs -0 grep -lZ ‘foobar’ | xargs -0 rm -f”. The book does get a little too zealous at times, bashing windows and preaching the merits of open source, but that’s forgivable (some might even agree), considering the wealth of knowledge and experience contained within.
- The Mythical Man Month and other Essays – This is a collection of essays written by Fred Books. I actually had to read this book for my software engineering class at the UW, and didn’t like it. I only include this book in this list because it is considered a classic. My problem is that a lot of the information in these essays is just plain outdated and wrong. The author talks about microfiche, time sharing, treats memory like a rare and precious commodity, and ancient mainframes. His writing style is also quite dry. That’s not to say that there isn’t wisdom to be found in this book. Ideas such as no silver bullets, the mythical man month (adding more people to a late project makes it more late), and favoring data representation over algorithms (“Show me your flowcharts and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won’t usually need your flowcharts; they’ll be obvious.”) still ring true today. Fred Brooks is constantly quoted in other books and articles though, so all the wisdom can be found elsewhere in material that is more current and relevant. In my opinion, you don’t really need to read this book unless you are curious about what programming was like back then (which other books do a better job covering anyway).
- Joel on Software 1 & 2 – Joel on Software is a collection of essays from Joel Spolsky’s blog. Joel is the CEO of Fog Creek Software (which makes Fog Bugz, among other things). Joel’s writing style makes for easy reading. He has a sharp wit, a good sense of humor, and like all good bloggers, is controversial, purposefully ruffling feathers with essays such as “exceptions are no better than gotos”. His essays range cover a lot more than development best practices, and include topics such as high level articles on how to run your own business. As he explains, a good developer will understand the business and have a good grasp of microeconomics. And of course, it couldn’t hurt to have this knowledge if someday you want to start your own company. Granted, you can always read his blog instead of buying these books, but I enjoy the rustic feel of reading a good book on a lazy Sunday afternoon.
- Programming Pearls – This book is also considered a classic, and rightfully so. It reads like a computer science textbook, and that’s because its a collection of articles published by the ACM, written by John Bentley. It is deceptively short, but tackles lots of programming concepts and problems such as algorithms, testing, debugging, program verification, performance, searching, sorting, and string manipulation. I’m currently still working on this book. I say work, because this book provides an invaluable list of practice exercises at the end of every section. Anyone whose ever interviewed for a job before can surely recognize one variant or another of some of these difficult problems at the back of each chapter 🙂