UWaterloo CS Courses Tier List

I wrote my last exam exactly 3 weeks ago.

Published May 9, 2026in Brain Dump15 min read

Rankings of these sorts are highly highly subjective. My experience in a course is based on a variety of factors outside of the classroom: such as what else was going on in my life outside of school, having to take courses online, professor having to take 2 weeks to go to conference, etc. A few times I took courses that I wasn’t particularly interested in due to timing conflicts and course availability. A low rating is not reflective on a prof and to keep this more positive I will only shout out professors for courses that I really enjoyed!

Tiers:

  • S - must take (stuck with me)
  • A - great courses (useful but not memorable)
  • B - somewhat useful
  • C - felt like a drag
  • D - not for me

I’ll be going through the courses grouped by academic term. I won’t be revealing the ranking of each course until the very end but you can get a good idea based on my thoughts.


1A

CS 145: Designing Functional Programs (Advanced Level)

Unlike other universities, Uwaterloo teaches programming through a functional paradigm first. This is done through a language called Racket. I took this course online and that definitely made the course less engaging than in-person.

This course made me good with recursion! I used to be scared of recursion but doing it so much in this course especially for all types of tree traversals made it like second nature. I do think its difficulty is not much more than the base CS 135 and you do get taught some useful things not covered in CS 135.

1B

CS 146: Elementary Algorithm Design and Data Abstraction (Advanced Level)

One of the most memorable courses I have taken - in a mostly good way. The workload was quite heavy and the exams (esp midterm) were quite brutal. The final mark was good due to a generous curve. During the course, I had to juggle between the aforementioned Racket and C along with the occasional Haskell. On top of this, we were exposed to various toy languages to help us build an interpreter.

This course felt like 3 courses in one. Lots of smaller topics were expanded in upper year courses. To highlight the course intensity, this course had a weekly 1hr tutorial slot, which is basically treated as a 3rd lecture slot to overcome the universities limit on weekly lecture time :) Lectures were dense yet very engaging and clear due to lots of great analogies. Prof. Brad Lushman was great!

If you can manage it and are genuinely interested in CS, I highly highly recommend taking this over the regular CS 136. I was only taking 4 courses this semester and this course more than kept me busy. I had to go to office hours nearly every week for this course and shout out TA Hans Sun for basically doubling up as a second prof.

2A

245: Logic and Computation

I will preface my review by stating that most people I know really despised this course. They felt it was too dry and theoretical. Originally the content seemed mechanical and very dry in the section I was enrolled in, but, I started going to Prof. Lila Kari’s lecture made it come to life! Don’t get me wrong the content is only theory focused but I personally really enjoyed the philosophical slant to the course content!

246E: Object-Oriented Software Development (Enriched)

I decided to take the enriched version of CS 246 mainly since it was another course taught by Prof. Lushman, with whom I had a great experience in CS 146. The course content was interesting and the core content was very similar to the base version. The only extension topics were focused on C++ specific features like template meta programming. However, what made the course really interesting was the course structure where there was no final exam, and instead there was a final project. The structure made the course so much better as I had a lot of fun working on the project. The project was to design a terminal based game engine and 2 games that use the engine. Here is a demo of mine.

2B

240: Data Structures and Data Management

The course is very very useful from a job interviewing perspective. It introduces to essential data structures and the concepts of time and memory complexity analysis. To me, the content, especially a lot of the proofs, felt a bit dry though.

241: Foundations of Sequential Programs

I would call this compilers lite. I really enjoyed the iterative process of working up to a MIPS compilers. Each assignment is working on one component of it. Prof. Gregor Richards’s engaging lectures and his colourful outfits made the class pretty enjoyable overall

251: Computer Organization and Design

I took the course when it was still teaching MIPS. The new version in ARM would have been cool as its more applicable in today’s time. The course did a good job of teaching the basics of computer architecture (no physics involved for the CS course!).

I feel the content was very useful especially for someone who is curious about computer HW like me, but, assignments and exam just tested how well I could memorize the existing MIPS architecture and not about designing your own architecture.

3A

341: Algorithms

This was very much a follow on from CS 240. Similar to CS 240, it is known for being very very useful for technical job interviews. The course was less theoretical than CS 240. I liked that my prep for the midterm and final was just doing LeetCode problems!

350: Operating Systems

The content was super useful and foundational. I want to give a shout out to the reference textbook for this course: OS - 3 easy pieces! The textbook gave me a more intuitive understanding of many course concepts and the overall structure of course being broken down into 3 pillars was very clear and helpful.

However, studying for exam did feel like memorizing basically every word/concept covered on the slide, especially for the virtualization and persistence sections. Concurrency topics were tested by having us find bugs in code, etc which was tough but more stimulating than remember random facts about various OS components.

370: Numerical Computation

This was definitely the most forgettable technical course I took this term. To its credit, the content is very applicable to a lot of technical fields. The highlights for me were topics like Google’s page rank algorithm and image compression using Fourier series. However, each section in the course was very self contained and thus pretty surface level. I just copied down most of the proofs in my cheat sheet and more less repeated it on the exam.

3B

449: Human-Computer Interaction

I feel like this course is somewhat a fake CS course listing. It didn’t really connect with anything else I had learnt so far in my CS degree. It felt more like a humanities course. I felt like I didn’t really learn much and just did Figma designing which I relatively enjoy, but I had already done before. The writing and reflections component of the course were substantial but I felt like they were all pretty shallow. The end of term symposium and collaborative “lab” was cool.

454: Distributed Systems

I will say that most of the high level ideas covered in the course were very useful content for the kind of work I am interested in doing. The content I learned was also vital in helping me clear system design interviews, especially the one that landed me a internship as production engineering @ Meta. However as for the actual delivery of the course content, I felt it was a bit dry. I think using existing systems or analogies to motivate certain concepts and tradeoffs would have made the course more engaging. Also, studying for the final and midterm felt like memorizing certain algorithms and key terms instead of getting deep intuition on course concepts.

486: Introduction to Artificial Intelligence

I am quite intrigued by AI and this course provided a good high level overview. But, this course was very breadth focused so I didn’t develop good intuitions for many of the course concepts like back propagation and Q networks. Instead, I just ended up memorizing how a few key algorithms worked for the exams.

4A

I took no CS courses this term as I was working full-time for a startup and thus, took easy electives which wouldn’t take up too much of my time.

4B

343: Concurrent and Parallel Programming

Peter Buhr’s lectures in this course are the CS lecture equivalent of Pure Cinema. He incorporates all kinds of relatable analogies into his lectures to make abstract concepts easy to digest. On top of that, he makes his lecture notes public, making it easy to follow along.

The content of the course was very interesting as well and built off the concurrency unit in CS 350. It developed more high level abstractions/models for dealing with concurrency as opposed to just using POSIX pthreads library. The course is taught using a language called uC++ (micro C++) which takes C++ and adds a few keywords and a whole new runtime. Since uC++ is not really used anywhere outside of this course, it is often hated as being unpractical. However, I feel like the point of the course is to expose you to all kinds of concurrency models and how to think about your programs in concurrent setting.

The course load is decently demanding due to the lengthy assignments at a 2 week cadence. So, even if you do not want to do the assignments, I would recommend sitting in on the lectures! They are just that good.

450: Computer Architecture

I have always been fascinated by computer architecture and HW. So, I felt like this would be a perfect match. However, I feel like I leave this course disappointed in the course and partly in myself. On the surface, it feels like the “practical” extension of CS 251 where we examine modern computer architectures and design our own. The designing our own was done through a group project which was the highlight of the course. We really got to work on something state of the art. However, the lecture content in this course felt surface level and unorganized.

479: Neural Networks

The teaching style was great. We had a lecture, followed by a short quiz and then some time to work through some exercises questions. The quiz and exercises questions were a great way of check if we had understood the lecture content. I wish more courses adopted some aspects of this! I really enjoyed the first half of course (till around CNNs) and if it was only upto that, I would rate this course as A tier. However, the post midterm content felt more difficult and less intuitive and since we only covered topics at a high level, I sorely lacked important intuition on a lot of topics like RBMs and Transformers.

Must Take Electives

All of these are non-CS courses which are S-tier.

CO 250: Introduction to Optimization

This was pretty challenging course and I remember often going to Prof Vijay Bhattiprolu’s office hours multiple times week! I really loved Prof. Bhattiprolu’s teach style which roughly consisted of presenting a problem and then collaborating with students to try and solve the problem, which made the class very engaging. Learning about duality (duality almost felt philosophical) and convexity was great and surprisingly useful. Seeing how LPs and IPs are everywhere made me appreciate this area of mathematics a lot.

MUSIC 246: Soundtracks: Music in Film

This is everything a non-technical elective should be! Prof Simon Wood being a professional composer makes all the difference! Each class involved watching clips from a bunch of movies and analyzing the music in the film. We also covered the history of music in movies. This course opened my eyes to how new technology takes time to adapt to and is often as simple as trial and error.

CO 487: Applied Cryptography

A general rule of thumb is that if you see an article where I shout out course on my article then its at least an A tier. This course has inspired me to write a whole series of articles focused on cryptography primitives. The content of the course was just very interesting to me and I really enjoyed how some of the assignments were coding questions where each student got their own data that they had to process (e.g. decrypting cipher texts, authenticating messages, etc.). It gave me a feel for what it’s like to be a cryptographer.


The Glorious Tier List

Group 42 (1)


Some Closing Thoughts

Overall, the last 5 years at Waterloo has been a wild ride. With some great highs and some lows along the way. However, I will cherish my time at Waterloo as I learned a lot, got lots of different experiences like travelling abroad for a student design team and working at so many different companies in different cities. I also got to strengthen my friendships with many high school friends and build a ton of new ones too! I appreciate all the people - fellow students, faculty and friends - that have contributed to a memorable university experience! Onto the next chapter.