A DIY Computer Science Education

This short guide intends to answer the question: “what should I learn to learn computer science?” It is based on our experience teaching foundational computer science to 100s of mostly self-taught professional engineers.

Whether you’re a student, or a practicing engineer, this guide should help you chart a path toward sound computer science fundamentals. We encourage you to work through all of it, and have done our best not just to list books, but also project ideas and exercise sets. Of course the ultimate learning guide is an experienced and helpful human, so to make the most of this content we would encourage you to find a mentor, or enroll in Bradfield.

Programming

Most undergraduate CS programs start with an “introduction” to computer programming. The best versions of these courses cater not just to novices, but also to those who may benefit from concepts and models of programming that they may not have encountered through self-teaching.

Our standard recommendation for this content is the classic Structure and Interpretation of Computer Programs, which is available for free online both as a book, and as a set of video lectures.

We recommend working through at least the first three chapters, and doing the exercises. For additional practice, work through a set of small programming problems like those on exercism.

For those who find SICP too difficult, or are put off by some of by the domain specific aspects, we recommend How to Design Programs. For those who find it too easy, we recommend Concepts, Techniques, and Models of Computer Programming.

Computing Systems

Computing Systems—sometimes called “computer organization” or “computer architecture” is an important first look at computing from below the software surface. In our experience it is the most neglected area among self-taught software engineers.

The Elements of Computing Systems, also known as “Nand2Tetris” is an ambitious book attempting to give you a cohesive understanding of how everything in a computer works from boolean logic up to small applications. Each chapter involves building a small piece of the overall system, from writing elementary logic gates in HDL, through a CPU and assembler, all the way to an application the size of a Tetris game.

Our recommended way to start learning computing systems is to read through the first six chapters of the book and complete the projects (up to an including the assembler). Doing so will develop your understanding of the relationship between the architecture of the machine, and the software that runs on it.

This first half of the book, and all of the projects, are available for free from the Nand2Tetris website. It is also available as a Coursera course with accompanying videos.

In seeking simplicity and cohesiveness, Nand2Tetris trades off depth. In particular, two very important concepts in modern computer architectures are pipelining and memory hierarchy, but both are mostly absent from the text.

Once you feel comfortable with the content of Nand2Tetris, a good next step is Berkeley’s CS61C course “Great Ideas in Computer Architecture”. The lecture notes and labs are available online, and past lectures are on youtube. The suggested accompanying text is Patterson and Hennesy's Computer Organization and Design which is both excellent and commonly used.

Elements of Computing Systems

It’s hardware that makes a machine fast. It’s software that makes a fast machine slow.

– Craig Bruce

Problem Solving, Algorithms and Data Structures

We agree with decades of common wisdom that familiarity with common algorithms and data structures is one of the most empowering aspects of a computer science education. This is also a great place to train one’s general problem solving abilities, which will pay off in every other area of study.

There are hundreds of books available, but our favorite is The Algorithm Design Manual by Steven Skiena. He clearly loves this stuff and can’t wait to help you understand it well enough to use it to solve your problems. This is a refreshing change, in our opinion, from the more commonly recommend Cormen & Leiserson, or Sedgewick books.

For those who prefer video lectures, Skiena generously provides his online. We also really like Tim Roughgarden’s course (parts one and two) and suggest that you pick whichever of these best builds your intuition for the subject.

For practice, our preferred approach is for students to solve problems on Leetcode. These tend to be interesting problems with fairly good solutions and discussions. They are also a way to test your progress against questions that are commonly used in technical interviews at the more competitive software companies.

Finally we strongly recommend How to Solve It as an excellent and unique guide to general problem solving, just as applicable to computer science as it is to mathematics.

The Algorithm Design Manual How to Solve It

An algorithm must be seen to be believed

— Donald Knuth.

Operating Systems

Operating System Concepts (the “Dinosaur book”) and Modern Operating Systems are the “classic” books on operating systems. Both have attracted criticism for their writing style, and for being the 1000-page-long type of textbook that get bits bolted onto them every few years to encourage purchasing of the “latest edition”.

Operating Systems: Three Easy Pieces is a good alternative that’s free to read on the web. We particularly like the structure of the book, and feel that the exercises are well worth doing.

Then we encourage you to explore the design decisions of specific modern operating systems. The tradition is to name the book “{OS name} Internals” (e.g. “Android Internals”, “Solaris Internals” etc).

One of Marc Andreessen’s lesser known quips is “The Browser Will Be the Operating System”. It’s lesser known because it didn’t really happen. But it kinda happened. The browser did become a program that has to manage and share the machine’s resources between potentially hundreds of untrusted programs started by the user (just like an Operating System). So many techniques used to design and build modern browsers come from the OS world.

How browsers work is a good online book about the internals of a modern browser. And Matt Brubeck has a tutorial series on building a browser rendering engine.

Operating Systems: Three Easy Pieces

Unix is user-friendly. It’s just picky about who its friends are.

— Anon.

Networking

Given that so much of software engineering is on web servers and clients, one of the most immediately valuable areas of computer science is computer networking. Our self-taught students who methodically study networking find that they finally understand terms, concepts and protocols that they’d been surrounded by for years.

Our favorite book on the topic is Computer Networking: A Top-Down Approach. The small projects and exercises in the book are well worth doing, and we particularly like the “wireshark labs” which they have generously provided online.

For those who prefer video lectures, we suggest search for those from Stanford’s CS144 Introduction to Computer Networking course. At time of writing they had been removed from Coursera, but are still available on Youtube.

The study of networking benefits more from projects than it does from small exercises. Some possible projects are: an HTTP server, a UDP-based chat app, a mini TCP stack, a proxy or load balancer and a distributed hash table.

Computer Networking: A Top-Down Approach

I have a great joke about UDP, but I'm worried they won't get it

— Anon.

Databases

Many database books and courses are actually just guides on how to use the SQL language to manipulate one kind of database. And only at a very high level. This would be like buying a book on “nation building” and opening it up to find the US constitution (the authors might argue that they aren’t technically wrong).

Databases is relatively new (i.e. post 1970s) field of study in computing. And companies still pay enormous sums for databases that use novel techniques to help them solve their data storage and query problems. So many innovations and good ideas remain behind locked doors for long periods.

We suggest students of this topic split their study into two parts: transaction processing & data modeling.

For transaction processing a good book is Transaction Processing: Concepts and Techniques.

For data modeling, a good book is Data and Reality: A Timeless Perspective on Perceiving and Managing Information in Our Imprecise World.

Architecture of a Database System is a book-length paper that provides a good overview of how a modern RDBMs works.

We also think this is one area where a specific piece of software warrants a mention. Leveldb by Jeff Dean (of Jeff Dean fame) and Sanjay Ghemawat.

To our knowledge this is the only “pure” transaction processing DB system that doesn’t entangle itself with the data modeling/encoding/transport concerns that other DB software “bundles in”. Put another way, this is a database system designed for people to build bigger database systems on top of. The high quality source code is a good resource when studying transaction processing. And the program itself is a useful platform upon which to build your own query engine.

And then…?

We’ve listed only the areas of computer science that we believe every software engineer should be comfortable with. We hope you will continue beyond this content to pursue your particular interests, whether diving deeper into the above topics, or applying them to new fields. If we can help you at all with your journey, please let us know!

hello@bradfieldcs.com
San Francisco, California
© 2016 Bradfield School of Computer Science