Now that I've finished with all my 2nd year CPSC courses, I guess it's a good idea to write down my review before I forget about it, especially since I'm now on a co-op work position. So, without further ado, I present to you my overall thoughts and comments on both CPSC 213 and CPSC 221 (taken in 2012W1).
In a nutshell:
Language: C, Java, Assembly (SM213)
Prereqs: CPSC 121, 210
Textbook: Computer Systems 2nd ed by Bryant and O'Hallaron
CPSC 213 is your introduction to some lower-level, operating system and software architecture basics. Essentially, you'll be spending roughly 2 months learning to program in assembly language, specifically referred to as SM213 in this course; since I can't find any references to it outside of the course, I'm going to assume that this is specific to CPSC 213 (but it's conceptually similar to programming in assembly language on another architecture, e.g. Intel x86). Then you'll spend the remaining month learning about topics like threading, schedulers, concurrency, and virtual memory.
The purpose of learning assembly is for you to learn how higher-level languages like C and Java get translated into simple, concise instructions that computers can understand and execute, e.g. adding 2 variables and assigning the resulting value to a 3rd variable (c = a + b) would involve loading the values of a and b into different registers, using the add operation provided by SM213's ISA, and then storing the value obtained from the register into the address of c. Each assembly instruction has an one-to-one correspondence with machine language, hence even the most simple programs with just a few lines in C/Java can be very lengthy in assembly. In fact, in many of the labs, you will end up translating short snippets of code from C into assembly and vice versa (Java will be thrown into the mix later). You'll come to appreciate just how much work your C/C++ compiler actually does for you...
The latter half of the course is all about lower-level operating systems related material, i.e. I/O, interrupts, threads & scheduling, concurrency, synchronization, and virtual memory. You'll learn about all the considerations you must make when designing programs that run in parallel (which is an increasingly relevant issue now that CPUs are becoming multi-core behemoths), e.g. how to make it safe to run code asynchronously, how to protect shared variables using locks/monitors/semaphores, common pitfalls like race conditions and deadlock, as well as a fairly brief introduction to how virtual memory is implemented, e.g. how your OS maps physical memory into virtual memory addresses and vice versa.
The course itself goes at a pretty brisk pace and builds upon stuff that you've previously learned (within each half of the course), so keeping up is pretty important. Debugging also plays a very important role, probably more so than in previous CPSC courses. It's easy to make errors while programming in assembly, and not so easy to find them, so do yourself a favour and learn early on to use that Simple Machine program you're provided with. In my opinion, the course tends to get progressively more and more difficult (for the first half of the course, up to the point where you'll be handling polymorphism with assembly), and the labs in the second half of the course can be extremely frustrating at times.
The course has a fairly generic marking scheme: 50% final, 30% spread across 2 midterms (15% each), and the remaining 20% spread across 9 labs (~2.2% each; 6 labs for the first half, 3 labs for the second half of the course). You do not have to go to your scheduled lab sessions (and to be honest I never went to my labs after the first one); labs are all handed in online via the 'handin' command-line program. Speaking of handin, you'll also gain a bit of practical Linux experience in this course, i.e. how to SSH into one of the Linux servers owned by the department, how to compile your C code using gcc remotely instead of on your own computer, how to navigate with a bash shell, etc. For many, this is probably one of their first encounters with Linux; a friend of mine ended up complaining that handing in his first lab seemed harder than actually doing the lab itself. :P
My prof (Dr. Tamara Munzner) generally explained concepts well and was an effective prof overall for 213 (and she even brought cookies in-class occasionally, yum!). I didn't really interact with the TAs in the course (labs aren't mandatory -> more time for me to sleep) in person, hence Piazza was an extremely helpful resource at times (especially right before labs are due). Workload is manageable, but again, do make sure you keep up. As for textbooks, to be honest I never once opened up the required textbook for the course; lectures + lecture notes + the 213 Companion PDF were sufficient (and there's no substitute for actually doing the labs that involve assembly...that's much more effective than just reading stuff).
In a nutshell:
Prereqs: CPSC 121, 210 | Coreqs: MATH 101/103/105
Textbooks: Discrete Mathematics with Applications 4th ed. by Epp (same book required for CPSC 121), Objects, Abstraction, Data Structures, and Design Using C++ by Koffman and Wolfgang
The other CPSC course I took concurrently in the same term as 213 was CPSC 221, "Algorithms and Data Structures". The course name pretty much says it all: this is going to be a course where you'll learn tons about various data structures, and some of the algorithms that you can build given those data structures. It sounds simple enough, but this content covered in this course is extremely useful (if somewhat brief), and IMHO this is one of the most important CPSC courses you'll end up taking at UBC. If you think back to the material you covered in CPSC 110, you'll remember that there was a strong emphasis on designing data structures that meet your needs (HtDDD); if not done properly, writing functions that operate on that data (HtDF) would often be futile and frustrating. In CPSC 221, this important lesson is further hammered home, and you'll also deal with an additional factor to worry about: efficiency (run-time complexity), not just correctness of the implementation of your data structures/algorithms.
You'll begin the course with review of material that partially overlaps with CPSC 121, including sets and functions, proofs, induction, iteration vs recursion, loop invariants (if you hoped that proofs and induction were a thing of the past after you finished 121, sorry :P ). You'll also cover Big-O/Omega/Theta notation (time complexity), which along with proofs are concepts that you should master early on in the course, within the first few weeks or so. The rest of the course is going to explore lots of different data structures and the algorithms that build upon them: linked lists, priority queues and heaps, various sorting algorithms (mergesort, insertion sort, quicksort, heapsort, including implementation examples and analysis of complexity), hashing (and implementation details, e.g. open addressing vs. chaining, collisions, etc., and proofs using the pigeonhole principle), trees (properties and traversal, and different types: binary trees, binary search trees, B+ trees), graph theory (properties, breadth/depth first search, Dijkstra's algorithm, Kruskal's algorithm, etc.), concurrency/parallelism (some degree of overlap with CPSC 213), counting (lots of overlap with permutations and combinatorics in high school - Math 12).
The above is not a conclusive list...that was just a brain dump of everything I could remember from a few minutes of thinking.
As for coursework, you'll have both written assignments (3 in my term), and C++ programming assignments (again, 3 in my term). The written assignments are roughly as challenging as the assignments from CPSC 121; on the other hand, the programming assignments are likely harder than programming assignments done in past courses (I'd say somewhat harder than the Android end-of-term project for CPSC 210). I think I averaged 10-12 hours per assignment in total. If you're curious, here are links to Project #1, Project #2, and Project #3 (you'll likely get different assignments, so treat these as examples of what to expect). I don't really have any specific advice for the projects, besides the generic "don't leave it till the last minute", but I think most of you have figured that out by now. Oh, and as with CPSC 213, test compile your code on the department Linux machines before handing in your code (not just on your own machine), unless you want to risk hitting a compile error and getting a big fat zero. You'll also have ~9 labs that follow the course material as it is taught, but labs are usually pretty short (I've finished quite a few in under a hour, with the help of the lecture slides). Unlike 213, you do have to go to lab sections since they're marked in-lab by your TAs, but technically you could just go every other week since labs are due the week after they're assigned.
Grading scheme is as follows: 45% final, 25% distributed between 2 midterms, 15% for the programming assignments, 10% for the written assignments, and 5% for the labs. Written assignments handed in-class, projects handed in via the command-line "handin" program (like the 213 labs), and labs handed in by showing your TAs your work and answering questions to make sure you understand the concepts.
My prof (Dr. Will Evans) is a decent prof. It's pretty clear that he knows the material he's teaching well, but unfortunately he can be quite soft spoken at times...it made it hard to stay awake in class sometimes (as with MATH 200, but there it's because the material is just so dry). As I noted in the "nutshell" section above, there's luckily a web page of recorded lectures for CPSC 221, so if you've slept through a lecture, you can just rewatch a video of the lecture in your own spare time.