Wednesday, January 30, 2008

The Do-it-Yourself Degree in Software Engineering: Complementary Skills

The first three books on my list help you build great code, use and understand patterns, and even refactor the legacy code you got saddled with. What are the skills you need to be able to package that up and have a real impact?

You need to be able to write. You need to be able to write clearly and succinctly about technical issues. No interesting software is ever built by a team without real debate about the design, and those debates usually happen in written text, via email or design documents. If you want to see your ideas advance, you need to be able to write in a manner that is clear and persuasive.

Unfortunately I can’t point you to a text on how to write about technical matters. The best thing I can do is to point you to the archetype of clear, succinct technical writing, The C Programming Language, by Kernighan and Ritchie. This book provides the model every technical writer should use when trying to explain a new technology or concept to technical readers.

You need to be able to work on user interfaces. This is the hardest one for me, because I have no idea how to arrange pixels on a screen to convey meaning. It drives me nuts every time I try. Given a choice, I will hand off UI design to a trained professional every chance I get. But the fact is, skilled UI designers are exceptionally rare, and a service with a working UI is 100 times more meaningful than some script outputting text on a console. Most engineers will never be able to build beautiful interfaces, but User Interface Design for Programmers by Joel Spolsky is a great beginner’s guide.

You need to know how to think about hard problems in Computer Science. This is a fuzzy concept to describe, but what I really mean to say is, you must read Programming Pearls by Jon Bentley. And when you read it, do the freaking exercises. That’s what really matters. I always pose the same challenge about this book when I speak to undergrads: in the chapter on proving correctness of programs, find the bug in the program that is proven correct.

Coming up tomorrow: how to learn everything you need to know about software engineering management.

The Do-it-Yourself Degree in Software Engineering: Code Construction and Design

Picking up where I left off yesterday, what are the code construction and design books you need to read in order to become a practicing software engineer?

There's one absolutely critical task in building software, and that's creating the actual sequence of operations that comprise your software. If you can't get this right, you're nowhere.

Short tangent: think back with me for a moment to the first computer science class you ever took – that one in high school, with the hand-me-down PCs from the typing lab, and the part-time Math/part-time CS teacher. Ah, the heady days when making “hello world” appear on the screen seemed like magic, and HTML felt like a “programming language”.

I’m willing to bet that one of the first lessons you learned was about “routines” – nice, isolated bits of code that did one thing and did it well, bits that could be incorporated into other bits with a simple call. Boom, magic.

There’s always some smart student in the room who asks, “when do I use a routine and when should I just write the code in-line with everything else I’m doing?”

This question has one standard answer given in CS classes all over the world: “write a routine when you’re creating a piece of code that is going to get used frequently.” And for introductory CS classes, for the kind of code written by 16-year-olds, this is a fine enough answer. But for real software, with real users, and more than one developer, there are a lot more reasons to put a piece of code in its own routine. If you can’t name at least three, you need to read the beginning of chapter 7 of Code Complete. And that’s just three pages out of this 800+ page tome! (Aside: by a wide margin, Code Complete is the longest book on my list).

If you read nothing else on this list, please, for the sake of software, please read Code Complete. This book is jam-packed with hundreds of little tips that will make your code better, one line at a time

Code Complete will equip you with the skills to start thinking at a high-level about the organization and construction of code. There are two books I recommend here.

First, Design Patterns. A lot of developers like to write off Design Patterns as some pointy-haired fluff, but the fact is, in the 14 years since this book was first published, Design Patterns have become established as a useful shorthand for discussing high-order organization of code. If nothing else, you are likely to encounter other people using Design Patterns when they describe their code, and you need to understand the language in order to communicate with them.

There is a risk associated with reading Design Patterns - many people read this book and decide that patterns are the meaning of life itself. I am not advocating that you become a Design Patterns weenie, searching for ways to needlessly incorporate a Strategy or a Factory in your code, or, pure Design Pattern nerd-vana, a StrategyFactory. Nonetheless, there are a lot of fantastic ideas in this book, and your code will be easier to maintain, by yourself and others, if you apply the ideas espoused in Design Patterns.

Next, and finishing out the Code Construction and Design category, is Refactoring, by Martin Fowler. This book is fantastic for the genuine focus on a codebase as dynamic and evolving. For most computer science graduates, working on an existing codebase is completely foreign in academic settings, and one of the first experiences in the professional setting. The ability to think clearly about how to improve the design of existing code, while making strong assurances about the quality of the refactored product, makes an immense difference in your ability to work effectively with software.

Once you're through these three books, the raw quality of your code will be immensely better. Code Complete is the longest, but it's a fairly quick read. The other two should be easy to get through in free time.

Coming up tomorrow: now that you're writing great code, we'll talk about the skills you need to go along with that in order to round out your abilities.

The Do-it-Yourself Degree in Software Engineering: Intro

Depending on where you go to school, your degree in computer science can be useful for a lot of goals – becoming a professional developer, going into finance or biotech, getting a Ph.D. in computer science, becoming an IT project manager, or even something barely related to computer science. The one thing a CS degree is almost useless for is practical training in how to build production-quality software. The curriculum at most universities, especially the “top tier” universities, is (rightly) focused on an academic grounding in the field, not a practical guide to building great software.

I’ve been trying to teach undergrads about this gap between a Computer Science degree and professional software development in a talk that I’ve given twice now, once at Princeton and once at Carnegie Mellon. The kids seem to like it, and the number one question I get is for the reading list I mention.

My list is intentionally brief. Anyone with a degree and some spare time should be able to make it through the entire set in under six months. If you haven't read these books, and I mean all of these books, you are probably building bad software. When people talk about the 10:1 productivity difference between great developers and average developers, well, you're on the "1" side of that ratio. Take the time to read through these and everyone impacted by your software will benefit.

Just for the sake of your ease in reading, I’ve taken this list and broken it up over several posts. I’ll post the first portion of the list, code construction and design, tomorrow, followed by a few books on complementary skills, then books on software engineering management, and finish up with a short bonus of fun and engaging books that help fill the gap between a degree in computer science and professional software development.