A few weeks ago I returned from a six month trip around Asia. I didn’t have a computer while abroad, but I was able to catch up on several tech books I never had time for previously. Reading about programming without actually programming was an interesting and rewarding circumstance. It provided a unique mental model: it was no longer about “how you do this” but about “why would you do this”. Accomplishment of a task via implementation was not an end goal. The end goal was simply absorbing information; once read, it didn’t need to be applied. It only needed to be reasoned about and hypothetically applied under a specific situation (which I usually did on a trek or on a beach). Before I would have been eager to try it out, hacking away, but without a computer, I couldn’t. It was liberating. Given a problem, and a set of constraints, what’s the ideal solution? I realize this is somewhat of an ivory-tower mentality, however, I also realized some of the best software has emerged from an idealism to solve problems in an opinionated way. Sometimes we are too consumed by the here-and-now we fail to step back for the bigger picture. Conversely, we hold onto our ideals and fail to adapt to changing circumstances.
My favorite aspect of learning technology while traveling abroad did not come from any book or video. A large part of computer science is about optimizing systems under the pressure of constraints. Efficient algorithms, clean code, improving performance. The world is full of sub-optimal processes. Burmese hotels, the Lao transportation system, and Nepalese immigration to name a few. On a larger scale sun-optimal problems are created by geographic, socio-economic, or political constraints. People try the best they can to improve their way of life, and unfortunately, the processes are often “implemented” with a “naïve” solution. Some are also inspiring. It was powerful to see these systems up close, with cultural and historical factors so foreign. One thing is certain: when you optimize for efficiency, everyone wins.
Below are a selection of books and resources I found particularly interesting. I encourage you to check them out, hopefully away from a computer in a foreign land:
97 Things Every Programmer Should Know : A great selection of tidbits from a variety of sources. Nothing new for the experienced programmer, but reading through the sections is a great refresher to keep core principles fresh. Worthwhile to randomly select a chapter now and again for those “oh yeah” moments.
Beautiful Code by Andy Oram and Greg Wilson: My favorite book. Not so much about code, but the insight about solving problems makes it a great read. I appreciate the intelligent thought process which went into some of the chapters. Python’s hashtable implementation and debugging prioritization in the Linux kernel are two highlights.
Exploring Everyday Things with R and Ruby by Sau Sheong Chang: This is a short book with great content. You only need an elementary knowledge of programming and mathematics to appreciate the concepts. It’s also a great way to get a taste of R. The book covers a variety of topics from statistics, machine learning, and simulations. My favorite aspect is how to use modeling to verify a hypothesis or create a simulation. The chapters involving emergent behavior are particularly interesting.
Machine Learning for Hackers by Drew Conway and John Myles White: I’ve been interested in machine learning for a while, and I was very happy with this read. Far more technical and mathematical than Exploring Everyday Things, this book digs into supervised and unsupervised learning and several aspects of statistics. If you’re interested in data science and are comfortable with programming, this book is for you.
Scala in Action by Nilanjan Raychaudhuri: Scala and Go have been on my radar for a while as new languages to learn. It’s funny to learn a new programming language without being able to test-drive it, but I appreciated the separation. My career has largely been focused on OOP: leveraging design patterns, class composition, SOLID principles, enterprise architecture. After reading this book I realize I was missing out on great functional programming paradigms I was only unconsciously using. Languages like Clojure and Haskell are gaining steam for a radically different approach to OOP, and Scala provides a nice balance between the two. It’s also wonderfully expressive: traits, the type system, and for-comprehension are beautiful building blocks to managing complex behavior. Since returning I’ve been doing Scala full-time and couldn’t be happier. It’s everything you need with a statically typed language with everything you want from a dynamic one (well, there’s still no method-missing, at least not yet). I looked at a few Scala books and this is easily on the top of the list. Nilanjan does an excellent job balancing language fundamentals with applied patterns.
HBase: The Definitive Guide by Lars George: I’ve been deeply interested in distributed databases and performance for some time. I purchased this book a few years ago when first exploring NoSQL databases. Since then, Cassandra has eclipsed the distributed hashtable family of databases (Riak, Hbase, Voldemort) but I found this book a great read. No matter what implementation you go with, this book will help you think in a column-orientated way, offering great tidbits into architectural tradeoffs which went into HBase’s design. At the very least, this book will give you a solid foundation to compare against other BigTable/Dynamo clones.
The Architecture of Open Source Applications: I was excited when I stumbled upon this website. It offers a plethora of information from elite contributors. The applied-practices and deep architectural insight are valuable lessons to learn from. Andrew Alexeev on Nginx, Kate Matsudaira on Scalable Web Architecture and Martin Sústrik on ZeroMQ are highlights.
I was also able to check out some courses on iTunes U while traveling. The MIT OCW Performance Engineering of Software Systems was my favorite. Prof. Saman Amarasinghe and Prof. Charles Leiserson were both entertaining lecturers, and the course provided great insight into memory management, parallel programming, hardware architecture, and bit hacking. I also watched several lectures on algorithms giving me a new found appreciation for Big-O notation (I wish I remembered more while on the job interview circuit). I’ve been gradually neglecting the importance of algorithmic design since graduating ten years ago, but found revisiting sorting algorithms, dynamic programming, and graph algorithms refreshing. Focusing on how well code runs is as important as how well it’s written. Like most things, there’s a naïve brute-force solution and an elegant, efficient other solution. You may not know what the other solution is, but knowing there’s one lurking behind the curtain will make you a better engineer.
So, if you can (and you definitely can!) take a break, grab a book, read it distraction free, gaze out in space and think. You’ll like what you’ll find!