My Ultimate UBC CS Course Ranking

May 16, 2026 · 17 min read

At first I wanted to do something a bit more... academic. I was really inspired by this post. The author describes the state of UBC's CS curriculum better than I ever could. He proposes some solutions to the systemic issues with UBC CS, and I would definitely recommend giving it a read.

But I've done enough academic pondering over my five years at UBC! So instead, I've decided it would be much more fun to entirely subjectively rank each of the 18 CS courses I've taken, along with my thoughts on each.



#18. CPSC 121 - Models of Computation

This course is trying to do too much. If you asked 100 CS majors what the primary focus of CPSC 121 was, you would get 100 different answers. For example, here's a non-exhaustive list of the topics we covered:

My issue with the course isn't that it's inherently a lot of material. My issue is that the course doesn't go into enough depth with any of the material to truly build an understanding of it. I couldn't tell you how to form an inductive proof from scratch because the course never challenged us to do so.

The disconnect between the lab content and the lecture content made this problem even worse. I didn't feel like I could practice or apply what I learned in lecture in the labs because the lab felt like an entirely different course.

I didn't retain much from this course because my time and attention was spread so thinly across too many topics. I didn't enjoy this course and I think it needs a rework.

#17. CPSC 418 - Parallel Computation

For some reason, I thought parallel computation was going to be a lot more applicable than it was. If I could describe the course in one word, it would be "esoteric". I guess in hindsight it's what is advertised, but wow my expectations were off going into it. This course is niche.

Beyond my failed assumptions, this course had a number of issues. The biggest one being the generative AI policy. Exams were 100% open book, including the use of generative AI. As long as we "cited" (that term is being used loosely here) our usage of AI, all was fair game. While I can see the intended point of allowing AI use (something something "real world"), this seemed to backfire.

Many people I knew in the course would simply take the entire PDF of the exam, put it into their favourite chatbot, and get an almost perfectly answered exam out of it. And honestly, who can blame them? In a 400-level course, a lot of students are just trying to pass to get to graduation. Unless you're passionate about the maximum congestion of a network with a hypercube topology, not using AI when it's explicitly allowed feels like taking a gamble on graduating.

On top of the AI misuse, the course was logistically a nightmare. Assignments were consistently released late, with errors, missing questions, or just not released at all. Grading for the midterm was quick, but our assignments took forever. They took so long in fact, that we never ended up getting marks for the latter 50% of our submitted assignments.

#16. CPSC 310 - Introduction to Software Engineering

This course is notoriously a boring one. It's intended to be the "real world software engineering" course which gives UBC CS grads the ability to function in the workplace, but when you've already worked numerous internships, this course feels like a waste of time.

The majority of the content felt like common sense, and lectures were dry as a bone. On top of that, any of the content that was somewhat interesting was taken almost verbatim from Refactoring Guru. Why am I paying for this course?

The project was somewhat okay, but was a huge timesink and only worth 25% of our grade. Quiz questions were subjective and had room for interpretation, without any way to explain said interpretation. The final exam being entirely true/false really shows the depth of thinking this course required (not much).

Overall, a frustrating course which felt like a waste of time given my internship background.

#15. CPSC 416 - Distributed Systems

Wow. This course should have been really cool.

Distributed systems is my area of interest and I was so excited to take this course. Just look up "CPSC 416" and you'll see the conversation surrounding this course. It's supposed to be one of the most difficult but satisfying CS courses UBC has to offer. But the instructor absolutely ruined it.

I'm not kidding when I say 90% of the lecture content, assignments, and evaluation was created with an LLM. At first glance, the slides look detailed and useful, but after taking about five seconds to read them, you realize they're using a lot of words to say nothing of importance. When you'd ask the instructor to clarify, they'd take a minute to try and understand what the slides were trying to say and then dismiss it, saying the slides are bad. I thought you made the slides?

The rubrics were the same. They were verifiably created by an LLM and you could tell. They're incredibly vague and again, while they sound sophisticated, they mean absolutely nothing. Our assignments were marked with LLMs and we got LLM-generated feedback. The instructor even did a "self-evaluation" of their teaching style using an LLM. Why am I paying $800 in tuition to talk to an LLM? I can do that for free.

While I didn't get much from this course, I at least got an intro to some of the topics I should look into if I want to further my knowledge in distributed systems.

Overall, not the course's fault at all and would definitely recommend taking the course if possible, but just not with this instructor.

#14. CPSC 330 - Applied Machine Learning

Meh. The least "computer-sciencey" computer science course I've taken.

Definitely not a bad course by any means, but not a course designed for CS majors. A lot of business and other non-CS majors take the course. I think it's a good introduction to real-world ML applications and some key ML concepts, but, especially after taking CPSC 340, this course didn't stretch my brain at all.

If you're looking for a theory-based machine learning course, this is definitely NOT the course for you. However, CPSC 330 definitely has its place for students just looking for an intro to ML and ML-based tasks.

#13. CPSC 210 - Software Construction

I think CPSC 210 is the most forgettable CPSC course I've taken.

It's the first introduction to "real world" programming for a lot of students, and it does teach you the fundamentals of object oriented programming, but I don't know, something about this course just falls flat. I don't know how to put into words the feeling this course has. There's nothing inherently bad about it, it's just bland.

The project, while has potential to be interesting, is graded too leniently to really encourage critical thinking. It's too easy to build a simple CRUD app in Java, with almost no thought put towards its design, and get 100. I get it's only a 200-level course, but I think we could've gone deeper and been evaluated more critically.

Overall, not a bad course, but definitely lacking anything that makes it particularly memorable.

#12. CPSC 221 - Basic Algorithms and Data Structures

I struggled with figuring out what to write about this course. It has a similar feeling to CPSC 210. Nothing bad about it, but I can't tell you anything great about it.

This course has more of a focus on data structures, while CPSC 320 has a focus on algorithms. You learn about core CS data structures like trees, graphs, and heaps, while also some C++ specific concepts like vector resizing and pointers. I think the C++ programming assignments were the best part of the course. They were pretty difficult but easy to make consistent progress on. I remember spending 8 hours straight in the library working on assignment 3, without ever moving. Probably not the best thing for my health.

My big issue with the course was the evaluation. It felt too easy to game. The final exam was a collection of previous quiz questions; questions which we had access to when studying. This issue was evident in the final marks: the final average was in the high 80s. The high average didn't come from an innate understanding of the material, rather, from the overfitting when studying quiz questions.

While I liked the programming assignments, the fact they it was the only time I used C++ in our degree felt like a bit of a waste. I think C++ was a great choice, but I don't think I learned enough about C++ to feel any bit proficient in using it. It would be good if other courses changed to also using C++ to give us more exposure. I implore you to read the article I linked at the beginning if you're interested in the lack of C/C++ in UBC CS.

#11. CPSC 311 - Definition of Programming Languages

Talk about a mind-bending course. Definitely one of the hardest courses I've taken at UBC.

CPSC 311 introduces you to the fundamentals of programming languages. We built parsers and evaluators from scratch using Racket. It was the theoretical introduction to CPSC 411 where you actually build a compiler. The content was more cool than applicable. I think knowing the theory behind how programming languages work can be relevant to other areas of CS, but I think it's one of the most niche courses I've taken.

The exams were interesting. A lot of filling in starters, which made me feel like I was getting marks without fully understanding the material. But the course was so hard that if we had to build an evaluator from scratch, we would never finish the exam. The assignments, on the other hand, were HARD. They definitely made my brain hurt and I don't know how I got through some of them in one piece.

All that being said, I enjoyed the challenge of this course. I wasn't very good at it, which I think made me like it less. I think if I liked PL more it would be one of my top options, but it's not my area of interest.

#10. CPSC 304 - Introduction to Relational Databases

Tell me why this was my lowest CS grade.

CPSC 304 isn't supposed to be a hard course. My friends found it pretty easy, but for some reason, my grade didn't agree. I think this course is a good theoretical intro to its bigger sibling CPSC 404. It teaches you how to use SQL and the theory behind designing and using relational databases.

I think this course is important for designing good databases, but it doesn't teach you the "why" behind relational databases and how they work the way they do. Maybe it's because I couldn't see why the theory was relevant, but I found a lot of the content forgettable and quite boring. I know that not every course needs to be applicable to the real world (trust me, I love theory), but the theory in this course felt particularly bland. In other theoretical courses, I can see why the theory is being taught or where it can be applied, yet this course always left me asking "why?"

I still think this course is important to take. It's the only time we use SQL and use a database in the degree and I argue that it should be mandatory for all CS majors to take.

#9. CPSC 410 - Advanced Software Engineering

Why is this a software engineering course?

CPSC 410 is a programming languages course in disguise. The course is split between two main topics: domain specific languages and program analysis. While it was a lot less theoretical than something like CPSC 311, it definitely wasn't what I expected going into a software engineering course. I found the lectures hard to pay attention to. Not necessarily a fault of the professor, rather a fault of the content. I can only sit through so many lectures talking about how to implement program checking before I check out (pun intended).

The redeeming part of the course is definitely the projects. These projects are where the "software engineering" part of this course shines. They are the first time I've had to work with a large-ish group to work on a project at UBC. I worked in a group of five and, while they were based on the boring course content, they were so much fun to work on. We built a music creation DSL for our first project and a test coverage visualization tool for our second. I would say these were the best group project experiences of my time at UBC.

#8. CPSC 313 - Computer Hardware and Operating Systems

Despite this course being more applicable to the "real world" than CPSC 213 is, I've ranked it worse. This doesn't really follow my reasoning for other courses, yet for some reason CPSC 313 didn't sit as well with me in comparison to 213.

I enjoyed the second half of the course a lot more than the first. The first half of the course was CPU pipelining and instruction level parallelism, which is a) tedious and b) pretty boring. The second half, however, was all about memory and file systems, which felt a lot more applicable and important to know. Personally, I'd rather learn how caching and memory accesses work than learn about the steps in a CPU pipeline.

The assignments were the weakest part of this course. For a 300-level operating systems course, the assignments were small and quite trivial. I found them easier than the 213 assignments, which is saying something. I wish we were given more open-ended programming exercises. Nothing we did in this course prepared me for writing systems code at all, despite this being our one and only OS course. You could argue that the point of a university course is the theory behind concepts, not applying the concepts, but for our only OS course, it would've been nice to get a bit more systems programming under my belt.

I think the issues with this course are symptoms of the systemic issue UBC has with their systems track. Another call-back to the article I linked earlier, go read it for more on UBC's systems track.

#7. CPSC 320 - Intermediate Algorithm Design and Analysis

This course is considered the "LeetCode" class for a reason, yet I don't fully agree.

CPSC 320 teaches you the fundamental techniques for solving algorithmic questions. I really liked the organization of the course. Each unit felt like its own distinct thing which allowed you to focus on each one at once. We learned key classes of algorithms like greedy, divide-and-conquer, and dynamic programming, while touching more on the mathematical side of boolean satisfiability and NP-completeness.

The assignments were hard, but manageable. I liked that they were written assignments rather than coding assignments because it makes the course feel less like a LeetCode prep class and more like a university course. We weren't coding DFS to find cycles in a graph like you would in a technical interview. Instead, we were explaining the "why" behind the algorithms and applying existing algorithms in new ways. Exams were fair, and also written on paper (as they should be). I find it regrettable that they have now moved exams to PrairieLearn.

I think the course could use a bit more mathematical rigour. While yes, we did cover proofs, these proofs felt very hand-wavy. While we would explain why our algorithms worked, it always felt a bit like I was BSing my way through explaining it. We never had to formally prove the correctness of algorithms. For a 300-level algorithms course, it wasn't rigorous enough.

I won't deny that CPSC 320 helped with my LeetCode skills, but I think there's more to the course than some people give it credit for.

#6. CPSC 317 - Internet Computing

This is a great course which introduces networking fundamentals. If you use the internet, you encounter daily the concepts covered in this class. Learning the how and the why behind the black box that is the "internet" was really enjoyable and opened a whole new world of computer science for me.

I really enjoyed the assignments. Building DIY versions of real networking systems (e.g., SMTP client, DNS client) was super cool and made them really fun to complete. This is what the 313 assignments should've been like. Actually implementing a concept really helped me understand it better.

I think this should be a required course for all CS majors. Networking is an important concept that you don't get in any other course and is encountered in many areas of enterprise CS.

My only regret is not taking it sooner, so I could've taken CPSC 417 before it was discontinued.

#5. CPSC 340 - Machine Learning and Data Mining

This course is quite hard, I won't deny it. Linear algebra isn't my strong suit in math, so I was scared coming into this course. Honestly though, it's feasible. I found the math to be relatively simple and the actual machine learning concepts took most of the precedence in the course.

If you're looking for a more rigorous and theoretical machine learning course, you should absolutely take this course over CPSC 330. We covered the fundamentals of machine learning and I felt the course built up to the more complex topics in an approachable way. When I took this course, it was recently after them adjusting the last portion of the content to cover neural networks more. I think this is a good sign as they're trying to adjust it to make it more relevant to modern day ML.

The assignments were quite hard. They were a mix of written questions and coding questions. While the coding questions were starters with some pre-filled helpers, this didn't take away from the learning in them. Like I said, this is a theoretical ML course, so we didn't miss out on the ML theory by not writing Python helpers.

The biggest downfall of this course were the professors. We had two, and while I think they were okay, you could tell they were researchers first and teachers, well... not first. One of them even told us on the first day that they were not a teacher and won't pretend like they're good at teaching. I appreciated the honesty but it ended up being a point of frustration when we got to harder concepts.

#4. CPSC 213 - Introduction to Computer Systems

I think CPSC 213 is an underrated course. It's a course I hear people hate on consistently for being "too hard." While I don't think the course is easy per se, it's definitely not as hard as people say.

The course introduces key systems concepts like memory management, the stack and the heap, concurrency and mutexes, and assembly programming. It was my first introduction to C, so learning how to manage memory and use pointers, while frustrating at times, was still an interesting and new experience for me. The assignments were challenging but satisfying and the exams were totally fair.

The course itself was a pretty standard 2nd year systems course, but I really think most of my love for the course came from our professor, Mike. He has a particular teaching style that I've heard works for some and not so much for others, but he made me love this course. He's the kind of person I'd want to grab a beer and chat with. While he's incredibly smart, he's also one of the most humble professors I've had. It's a shame I only had him for two of my courses. Sorry, enough fanboying; I appreciate you Mike!

#3. CPSC 404 - Advanced Relational Databases

I liked CPSC 404 a lot more than I thought I would.

Prior to this course, my only exposure to databases was in CPSC 304, which wasn't my favourite. But the 400-level variant seemed to be the solution to my issues with 304. While 304 is the boring intro to the theory of using relational databases, 404 is the explanation of how databases actually work under the hood. It's a lot more hands on and provides answers to the magic of using a database. Learning about how a join query is so efficient instead of just learning the JOIN keyword, or learning how a database survives a crash instead of just relying on trust was really interesting to me.

One small critique of the course would be the lack of an operating systems requirement. This meant that the first part of the course covered disks, which was already covered in pretty good detail in CPSC 313. I understand why this might've been done, as business CS majors don't have to take 313 but must take 304, but it was time spent that could've been spent elsewhere.

As much as I loved this course, I think it's very professor dependent. Shoutout to Rachel, she was an amazing professor for this course and is a huge reason as to why I enjoyed it so much. I've heard mixed reviews from friends who have taken the course with other professors, so I'm grateful I had Rachel.

All that being said, this course was a part of the reason why I became interested in infrastructure, distributed systems, databases, and how to build reliable systems.

#2. CPSC 436S - Computer Security

This was the most fun I've had in a CS course at UBC.

I had heard good things going into this course, but it's really hard to know how fun the course is until you're actually in it. The highlight of the course was definitely the assignments. They were CTF-style assignments, which let you apply what you learned in class to a "real world" situation, and made them so satisfying to complete.

The course introduces content that's entirely unique to it. No other course (apart from one lecture in CPSC 317) talks about cybersecurity, so an entire course dedicated to it was refreshing. Cybersecurity also has the advantage that it's relevant to almost any field in enterprise software. I know I'll be using what I learned in this class in my career.

Was it hard? Absolutely. I think I've discovered my hatred for the modulo operator. The exams were brutal (failing averages on both the midterm and the final) but the professor was more than accommodating. I never felt like the course was "out to get me" like I've felt in other courses. It felt hard, but it felt hard for the right reasons.

Also shoutout to my professor Mike, who returns from his mention in CPSC 213. He was another huge reason I enjoyed this course so much. While this isn't his course, he stepped in for Robert to teach it and I think he did a great job.

This course is a very close second to number one. I really hope it moves from a topics course to a full-fledged undergraduate course.

#1. CPSC 110 - Computation, Programs, and Programming

And finally, number one..

CPSC 110 is my favourite course I've taken at UBC. I might be a bit biased because I was a TA for this course, but CPSC 110 is awesome. Unsurprisingly, this can be a controversial opinion. The grade distribution is a bimodal distribution with modes at F (≤50%), and at A+ (≥90%).

CPSC 110 teaches you the most fundamental computer science concepts which are relevant across your entire degree. I can't count the number of times I would be working on a course later in my degree and realize Hey, we did this in 110! The flipped classroom structure really worked for me, and it forced you to learn the content before seeing it a second time in lecture.

The common complaint with CPSC 110 is that it's taught in Racket (well, technically BSL, ISL, and ISL+Lambda, but I digress). I think the fact it's taught in a niche, functional language like Racket isn't a weakness, but a strength. As a TA, I'd see it too often: students would come in with some programming experience and attempt to use their previous imperative programming knowledge to try and solve questions. They quickly realized that everything they knew was useless in a course like this and had to pivot. Using Racket levelled the playing field and allowed the focus to be on the programming concepts, not the language itself.

110 will always hold a special place in my heart and I hope the future generation of UBC CS students will feel the same.




Wow, that's a lot! I appreciate it if you made it through my rambling all the way to the end. This was my first ever blog post and hopefully the first of many!

Here are a few of my takeaways after reflecting on these courses:

  1. UBC computer science isn't rigorous enough
  2. Don't get me wrong, I was definitely challenged by a lot of the courses I took, but there were also a lot of instances where I felt we weren't pushed hard enough. For example, hand-wavy proofs in 320, the lack of end-to-end complex assignments in 313, or the GenAI policy in 418. I think for a program which touts itself as one of the best in Canada, UBC should, and arguably has an obligation to, push its CS undergrads a bit more.

  3. I'm strongly influenced by the professor
  4. It's pretty clear that the make or break for a lot of the courses I took was the professor. A mediocre course could be the most interesting thing in the world if the professor is good. Having a professor I can relate to and one that matches the energy I put in is the strongest indictor that I'll enjoy the course. Whether this is a positive or negative quality, that's up to you to decide.

  5. I like courses that remove the "black box" from concepts
  6. Some of my favourite courses were CPSC 317, CPSC 340, and CPSC 404. The common trend between all of these is that they removed the "black box" surrounding the concepts of networking, machine learning, and databases respectively. I think taking a concept that is so widely known and used and looking under the hood at the how and why of them is incredibly interesting and makes me engage with the material a lot more.

My final ranking:

  1. CPSC 110 - Computation, Programs, and Programming
  2. CPSC 436S - Computer Security
  3. CPSC 404 - Advanced Relational Databases
  4. CPSC 213 - Introduction to Computer Systems
  5. CPSC 340 - Machine Learning and Data Mining
  6. CPSC 317 - Internet Computing
  7. CPSC 320 - Intermediate Algorithm Design and Analysis
  8. CPSC 313 - Computer Hardware and Operating Systems
  9. CPSC 410 - Advanced Software Engineering
  10. CPSC 304 - Introduction to Relational Databases
  11. CPSC 311 - Definition of Programming Languages
  12. CPSC 221 - Basic Algorithms and Data Structures
  13. CPSC 210 - Software Construction
  14. CPSC 330 - Applied Machine Learning
  15. CPSC 416 - Distributed Systems
  16. CPSC 310 - Introduction to Software Engineering
  17. CPSC 418 - Parallel Computation
  18. CPSC 121 - Models of Computation
← Back to blog