Five great Computer Science courses on Coursera
Coursera is really fantastic. Like many other entrepreneurs, I dropped out of college to work. Before Coursera, I had never taken a real Computer Science course. I’ve read some of the Computer Science classics over the years out of general and practical interest, but I didn’t take the time to do the exercises. I’m not sure how sustainable it is for Coursera and the universities that participate to give away first-rate courses, but I’ll take it while I can get it!
I’m not taking these courses exactly as intended. I generally just read the slides and/or notes and do the assignments. I find that video is an inefficient method for me to learn. I also don’t spend much time in the forums except when I think there’s an issue with the material. I’d really wish Coursera would do something a bit more innovative with scheduling. I don’t see much reason why all students should have to start a course at the same time and take it at the same pace… but that’s a topic for another day.
Here are my favorite CS courses that I’ve taken on Coursera so far:
- Algorithms: Design and Analysis, Part 1 (Stanford)
- Algorithms, Part I & II (Princeton)
- Cryptography I (Stanford)
- The Hardware/Software Interface (UW)
- Programming Languages (UW)
Algorithms: Design and Analysis, Part 1 (Stanford)
This is an intro theory course. The suggested readings (which I didn’t do) are from four different algorithms books. I was already familiar with most of the algorithms in the course, with the exception of some graph algorithms such as Karger’s Minimum Cut Algorithm and Kosaraju’s Two-Pass Algorithm for computing Strongly Connected Components. I feel like I have a stronger mathematical understanding of algorithms after taking this course, learning the Master theorem was particularly enlightening.
Unlike many other CS courses, the programming assignments can be done in any language. For most of the assignments there will be a description of the problem and some data set to download, and you simply paste in correct output to a form to verify that your implementation is correct. Not as thorough as other courses, but the flexibility to use any language was nice. I did them all in Haskell for practice, although I didn’t go though all of the hoops to ensure I was getting exactly the right asymptotic performance for each algorithm (such as QuickSort, where you need to use a mutable array to get the right performance).
The slides are very high quality and easy to understand without the videos. He posts two versions, you’ll want to get the typed ones so you don’t have to decipher any handwriting. For some of the lectures, Tim also posts detailed and nicely rendered (LaTeX and GraphViz, probably) lecture notes that are about 3-5 pages each.
Algorithms, Part I & II (Princeton)
- Course URLs:
- coursera.org/course/algs4partI (6 weeks),
coursera.org/course/algs4partII (7 weeks),
Algorithms, 4th Edition (Amazon)
- Kevin Wayne, Robert Sedgewick
While these are technically two separate courses they have the same topic, instructors, and style so I have grouped them together. Their focus is more application than theory, although it has a good basis in theory as well. The course is based on the classic Algorithms, 4th Edition (Amazon) textbook, written by the instructors. In these courses I learned Java (yes, I managed to basically avoid it for this long) and implemented a number of interesting algorithms and data structures that I hadn’t done before such as Union Find, Graham Scan, Seam Carving, and the Burrows-Wheeler transform. After this course, I’m a lot better at reading Java code and its memory model, and I have some more algorithms in my tool belt.
The programming assignments for this course are all in Java. While Java isn’t my favorite, their grading system is excellent. Assignments are graded on correctness, memory, timing and style. They instrument the JVM such that they can determine whether your implementation has roughly the same (or better) time and space usage as their reference implementation. The assignments use a standard library written by the instructors for the textbook that make it straightforward to do things like IO without diving.into.java.namespace.hell. The second course only has five programming assignments, the last two weeks are mostly theory and only have review quizzes.
The slides for this course are wonderful. They’re very well prepared, and have some great historical anecdotes, and even a bit of humor. The videos for this course were not even remotely necessary because the slides are so good.
The Hardware/Software Interface (UW)
This course covers topics at the level of C and below. It starts off with pointer arithmetic and bit manipulation in C, and quickly goes down to reverse engineering x86-64 assembly code with GDB. I’m only six weeks in to this course so far, but I wanted to include it anyway because I’m really enjoying it. The course is not related to the classic textbook with a similar name, Computer Organization and Design: The Hardware/Software Interface.
The labs for this course are done in a 64-bit Linux VM. The first few labs are in C. Their grader checks correctness and ensures that the assignment is done within the given constraints. For example, in the bit manipulation lab it verifies that your implementation uses only the allowed operators for each function. The next lab is an x86-64 assembly lab where you are given a compiled executable “bomb” and you have to reverse engineer what the correct input to the executable is in order to “defuse” it. I learned quite a bit about x86-64 assembly and calling conventions in that lab.
The slides for this course are also great. Very easy to read with lots of diagrams. I was surprised at how up to date the material is, I didn’t expect to be learning x86-64.
Cryptography I (Stanford)
This course covers the theory and application of cryptography. Dan Boneh does a fantastic job covering how cryptography works in theory and practice, and does a great job touching on some of the history as well. I learned a lot more about the math behind cryptosystems from this course.
The programming assignments in this course are all optional, for a tiny bit of extra credit. They can be done in any language, although I’d highly recommend one with good big integer arithmetic like Python or Haskell. I used Haskell, with a bit of Python to verify solutions. Most of them were cryptanalysis related. Given some cipher text generated with some known weakness, your mission is to recover the original plain text. I didn’t expect to learn any code breaking in this course, but I had a ton of fun doing it!
The slides are excellent. The algorithms are clearly presented, and the historical anecdotes are often paired with photos. The cryptographer’s mantra of “do not even implement crypto primitives yourself…” is present in quite a few of the lectures alongside examples of improperly implemented crypto.
Programming Languages (UW)
The programming assignments for this course are done with whichever language language the lectures are about. The novel part about the labs here isn’t that they are automatically graded for correctness, but there’s a peer review component to assess the style of your assignments. After the due date for each assignment you have to review the work of three other students in the class. I think this is a great way to get students ready for code review, although it’s missing that critical feedback loop where you have an opportunity to fix the style of the code.
The course material for this class is available in both slides and summaries. I decided to just read the summaries, so I don’t have anything to say about the slides. The summaries are written in a narrative style and are 20-30 pages per week. The formatting is very nice, looks like LaTeX. I found the summaries to be quick and easy to read.