I get asked quite regularly what books I would suggest. So here’s a list.

Design Patterns

by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides

A lot of new programmers today say "Design patterns, that's from Java." Sorry, kids, it's from way before that. They say "It's not relevant to dynamic languages." Sorry, again, the ideas were formulated in a Smalltalk environment. They say "The example code is in Smalltalk and C++." Sorry, yet again, if you call yourself a programmer you should be at least able to read and understand both Smalltalk and certainly C++. But all this is completely irrelevant: Design Patterns is about a way of thinking about software design and construction. Furthermore it sets out a common vocabulary to talk about patterns in the arrangement and interaction of software components, regardless of language or context.

A Design Pattern, whether in Alexander's original context of architecture and city planning or software design, describes a common problem, presents the core of a solution to it (usually with some illustrative examples), and discusses results, consequences, and trade-offs. All that and gives it a name so you can succinctly reference it.

Refactoring

by Martin Fowler

Refactoring: Improving the internal design of a piece of software without changing it's external behavior.

Refactoring is a word that grossly overused these days. It doesn't mean "changing the design", "redesigning", "reworking", "redoing", etc. It means improving the internal design of a piece of software without changing it's external behavior.

Test Driven Development by Example

by Kent Beck

Kent's was the first book that focused squarely on test driven development (mine was the second). This book uses Python as it's implementation language, but even if you don't know it it's not a barrier to understanding the lessons.

If you are learning TDD for the first time, this is a great choice of book. The book is in three parts:

    a full worked example of a multi-currency arithmetic system in Java, building an xUint TDD framework from scratch in Python, and a selection of TDD patterns.

The book is written so that you can work along with the examples, and learn by doing.

Structure and Interpretation of Computer Programs

by Harold Abelson and Gerald Jay Sussman

Smalltalk Best Practices

by Kent Beck

Although Kent states that this is a book for Smalltalkers or those wanting to learn how to write good Smalltalk code, I hold forth that it has immense value for anyone in any object oriented language. While some patterns are Smalltalk specific (e.g. the formatting patterns) most can be applied to most OO languages: composing methods, constructors, naming methods, etc.

This relevance is hardly surprising given that Smalltalk was a strong influence on most OO languages. In fact, Kent once commented that he always knew Smalltalk would beat Java, he just didn't know it would be called Ruby when it did.

Compilers: Principles, Techniques, and Tools

aka The Dragon Book by Alfred V. Aho, Monica S. Lam, Ravi Sethi, and Jeffrey D. Ullman

This is a classic book on implementing programming languages. Affectionately known as The Dragon Book. There is a second edition, but the original is more focused on actual language processing.

xUnit Test Patterns

by Gerard Meszaros

The xUnit family of testing frameworks have fallen out of favor in some camps these days, to be replaced by rSpec and it's spawn. Even so, regardless what you use you're doing the same thing in the end. If this book Gerard takes you through how to use these tools in various situations.

Domain Driven Design

by Eric Evans

XP gave us the practice of Metaphor as a way to think about design and a place to get names for the various pieces. A lot of people found this idea confusing and difficult to use. Eric Evans set things right with this book. How you talk about design, how you get names for the pieces, all the while making it understandable to everyone with a interest in the project.

The Pragmatic Programmer

by Andrew Hunt and David Thomas

This is a classic "how to be a better programmer" books. Reading this was a cathartic moment in my career as a programmer.

Peopleware

by Tom DeMarco and Tim Lister

This is another great book on how to work better.

Software Craftsmanship

by Pete McBreen

The ideas of software craftsmanship have a significant following these days, and this was the first book that laid it out.

The Art of Computer Programming

by Donald Knuth

This is our Bible. I'm currently working though it slowly. It's dense, and math heavy, so be prepared for some serious work. Currently published in four volumes: Fundamental Algorithms, Seminumerical Algorithms, Sorting and Searching, and Combinatorial Algorithms (Part 1).

Fundamentals of Computer Algorithms

by Ellis Horowitz and Sartaj Sahni

A classic reference for algorithms. I still have the copy (of this as well as the next book) I got for my undergrad classes. After some introductory material it dives into Searching and sorting algorithms, moves on through dynamic programming and backtracking, before finishing off with a discussion of NP-hard and NP-complete. It's 30 years old but fundamental algorithms haven't changed in that time. You can probably pick this up pretty cheaply. It's definitely worth dropping a few bucks on. Code is in a pseudo-code language designed for the book.

Fundamentals of Data Structures

by Ellis Horowitz and Sartaj Sahni

This is the companion to the above algorithm book. Same authors, same value. It starts off with the basic data structure: the array. It then moves through stacks, queues, lists, graphs, before spending a couple chapters on sorting. It follows that with a chapter on symbol tables and hash tables, and finishing off with a discussion of file structures. Code is in a pseudo-code language designed for the book.