just roamin'

Ranking my Computer Science courses by usefulness after 3 years of working as a full-time software engineer

Intro

I had a nontraditional path to graduating with a B.S. in Computer Science in 2022 that involved me moving around and working full-time at various jobs beforehand, but since then have been very consistently working at the same place as a software engineer. Although I've been in the same job since graduation, I'm probably more diversified in experience than the average person of my tenure at my company, just by necessity of the role I'm in. This gives me a little wider breadth to appreciate my CS curriculum, but still I'm probably missing professional experience that would have been aided by things taught in certain courses like assembly (the most I do is use gdb on coredumps once in a blue moon), formal methods (I defer to AI for regex, sorry), and algorithms (a course I and nearly all of my peers considered completely useless due to the unenthusiastic, irreverent teaching style of a tenured professor who admitted to me he cannot teach).

With that being said, this is going to be a quick, stream-of-consciousness reflection on how I feel each course prepared me for life as a software engineer mainly writing high-performance Java in a distributed low-latency environment, Python for tooling and automation, and the occasional Rust for fun. There's no defined criteria or point system, just a general feeling for "if I never took this, would I have been worse off?" This will be almost all CS classes but I may also include other technical/mathematics courses that I think could basically be a part of CS as a study. This is entirely based on my personal experience and is not trying to be objective/one-size-fits-all. Here we go.

The rankings

  1. Data Structures (Java)

The first class where I could finally see the puzzle pieces of my prior coursework falling into place. This class, man. Not only were the projects fantastic from a teaching perspective, but they fulfilled me at a visual, creative level. We covered arrays, trees, graphs, hashmaps, stacks and queues, and many other data structures used every day not only in a SWE position but also to acquire a SWE position, making it an exceptional class out of any other. The projects were fantastic, the teaching was fair, and I still use the skills I developed to work on them to this day, even if I'm not building an image compression algorithm from scratch anymore (tough one).

  1. Operating Systems (C)

An excellent capstone course that sets the foundation for a systems programming career. Even if you never touch C again, you benefited from this class' projects which synthesized scheduling, concurrency, multithreading, file systems, and memory management. Though I think it was graded a little too softly, I have no complaints about the content especially since it was taught by one of the best professors at the school. I think this class influenced me the most in my choice to work closer to the metal in my career, which shows how big of an impact it has. My one complaint is the insistence on using CLI editors only, which I dread for large projects. Also, it had students actually work together on a project, which was a novel idea until then for 99% of CS courses. I unfortunately have lost much of my C skills since then so I'm in the process of picking up where I left off with a refresher in the form of Modern C by Jens Gustedt.

  1. Discrete Mathematics (N/A)

I loved this class. This is the class that tells you if you will enjoy computer science, and if you do, you will find this class extremely satisfying. The building blocks of CS, the course taught boolean logic, set theory, recurrence and equivalence relations, probability, tree and graph theory, and was overall just a very well taught introduction to the math necessary to understand CS from the ground up. It was also taught by a(n unintentionally) hilarious professor which made it all the more memorable. I probably don't use most of the material learned explicitly day-to-day, but subconsciously I absolutely use it when thinking about solving complex data-focused problems at work.

  1. Computer Systems Programming (C)

The precursor to Operating Systems. Introduced using debuggers, C in a serious manner, lower-level programming concepts, processes/context switching, virtual memory/addressing etc. Once again, all things I use on an almost daily basis and essential for understanding how to improve the performance of your system at more micro scale. I do not work in C++ or C so I can't say I've built upon the practical project experience, but they were certainly entertaining (including the famous binary bomb project which is a staple among what seems like every CS curriculum country-wide).

  1. Object-Oriented Programming (Java)

An introduction to Java based OOP concepts. Encapsulation, abstraction, polymorphism, inheritance. This class took a while for me to fully understand and to this day I probably don't properly use everything I learned in it, but it was necessary. I think you can learn all of this on your own but just based on the fact that I write Java every day of my work (sometimes willingly), I can't say this wasn't an essential part of my SWE journey.

  1. Comparative Languages (Misc., mostly Haskell)

A survey class that exposed students to the world of functional programming, I wish I could say this class was more influential because I remember being hopeful to get into it, taking it, and being successful and entertained by it. I found the succinctness of Haskell and Lisp enticing. I suppose I still use what I learned whenever I'm using modern language features which take pages from functional programming such as Python's list comprehension and Java's lambda expressions. I still remember the excitement when coming up with the following one liner and the feeling of satisfaction when it worked:

-- augdentity creates a 2d matrix given r(ow), c(ol) with 1s across diagonals; it creates a 2d list and matches the
-- iteration (x for row, y for col) such that the 0th element in the 0th row is a 1, 1st element in the 1st row is 1 etc
-- parameters: r, c, returns 2d list
augdentity :: Int -> Int -> [[Int]]
augdentity r c = [x | x <- [1..r], x <- [[y | y <- [1..c], y <- if (y == x) then [1] else [0]]]]

It's rare I find it possible to write such code day-to-day because of readability and a nagging thing called code review, but perhaps in the future...

  1. Intro to Programming (Python)

A standard programming intro class that one could likely find online through MIT Free Courseware or another open source university class. I remember it having a lot of busywork in the form of quizzes + online textbook homework and needing extra help outside of class for a few of the projects. I had done some self-taught online courses before starting college, as I was at the tail end of the learn-to-code bootcamp mania. The projects (12 of them in a quarter!) mainly consisted of many small methods where use of the standard Python library was heavily restricted in order to encourage understanding of the data structures at a base level, which is painful. I think an intro to programming class is best taught in C if you're trying to force the students to do things entirely "by hand." Looking back at projects, I think the size and frequency of them did not help build proper programming skills and fostered bad habits that I had to unlearn later (including some very old school C ideas like no methods over ~30 lines long, 80 character width, etc.) in my upper-level Java and C courses. Overall I didn't really like this course and think something like CS50x is 50x better.

  1. Intro to Low-Level Programming (C)

Your bog-standard intro to C course. Anyone who picked up K&R could ace this course, and like the Python class, could probably have had a better experience in doing so due to an extremely lackluster professor who saw students like prisoners trying to break out of his rigid guidelines (the most egregious being "honor-coded," i.e. using external resources including another student's code). I suppose it can be appreciated for laying the foundation for better C courses to come.

  1. Formal Methods (N/A)

An extremely professor-dependent course, this class taught material that was unlike anything else in the CS curriculum, being entirely based in theoretical CS land including automata theory, Turing machines, formal verification, grammars, developing proofs, etc. I wanted to truly absorb this as I knew it's essential for developing a deeper understanding about CS but quickly found myself treading unfamiliar waters, and looking back on it, I don't think it was of much use given that I never pursued postgraduate education and went directly into industry. The most related thing that is interesting to me would be the world of formal verification audits for smart contracts/blockchain.

  1. Blockchain/Cryptofinance (Misc. (Python, JS))

An excellent "special topic" senior elective that was educational and entertaining. I would say this was influential since it certainly made in impact as I was always curious about the technology in the space (as divisive as it is, I find the decentralized aspect fascinating) filled in some of the gaps around the history and technical specifications of Bitcoin, for which it seemed highly centered around. It's incorrect to say it ended up being useful to me in the day-to-day, but it was influential in terms of sparking my interest and provided a much-needed refuge compared to my more rigorous courses.

  1. Databases (some SQL)

I am beginning to realize, whilst writing this list, how much of the impact of a course was entirely professor dependent, where an excellent professor who has a passion for pedagogy can make a lasting impact on me and others less memorable than a Tweet. This is one of those forgettable classes, but it did introduce me to SQL which I use heavily throughout my work, so I have to thank it for that. Unfortunately, it was too in-the-weeds on database theory to make more of an impact than an introduction (for a senior level course nonetheless).

  1. Algorithm Analysis (N/A)

See above first sentence and mention in the introduction. An almost useless class that was a firehose of information with hardly a foundation to stand on. I would say it was at least an exposure to a fundamental part of CS, but looking back it's hard to say I took away anything more than a participation trophy in the form of a steep curve. Just another thing to re-learn on my own, probably in the form of interview preparation. As a note, it's funny that the professor bemoaned that Data Structures was going too far ahead and teaching Algorithms (as if you can have one without the other) during its course, but it did a far better job of actually teaching the concepts than he did in his dedicated class.

  1. Software Engineering (Python)

A silly, outdated course taken over the summer that was supposed to teach modern software engineering in a team scenario. Our final project was nothing short of embarrassing, or would have been if it were any better than others. But what can you expect from a course that has more material than a page on "Agile methodology." I know, I'm being cynical, but truthfully it didn't prepare me for working as a SWE in a team environment at all.

  1. Networking (N/A)

This one stings! Such a crucial part of applied CS and it was botched by a poorly performing teacher. I tried to do the best I could to grab onto the coursework but ultimately learned everything I actually needed on the job. That's not to say I wasn't grateful to be exposed to it before as a precursor, but the pace & delivery of the material made it difficult to absorb and apply past the barrage of quizzes and exams. Can probably fill in the gaps with Claude in the future.

  1. Data Science (Python)

A fun elective, but more of an excursion never to be looked at again, this taught the basics of classification, clustering, relational models, etc. The projects were intriguing, the material was dry, and ultimately I never became a data scientist so it was a bit meaningless.

  1. Ethics for Computer Professionals (N/A)

One of the most loathed courses by CS majors for a very good reason. This was nothing but a constant burden for juniors & seniors who needed to address it in addition to their actual legitimately challenging coursework that taught essential skills for future work. As someone who writes better than the average CS student I found the individual material to be quick and painless, but in a group project setting it was the thing I dreaded the most next to Algorithms. The professors knew all of the students hated the fact that the school thought it necessary to make them take this course when it's better suited as "Intro to Technology Law" or something similar for law students. The sad thing? I would have enjoyed a prescient philosophical course on ethics centered around technology and the future, but instead I got LARPing as a paralegal for 15 hours a week with no pay.

  1. Essentials of Computer Science

If you were born between the years 1990 to 2001 and ever had to go on a forum to install a mod for a PC game, you should have been able to test out of this class. Just laughably outdated and useless, a self-guided/self-paced enrollment of CS50x would have been actually quite useful, but probably not as revenue generating for the university as coming up with its own half-baked version.

Not mentioned: Advanced calculus, statistics, organic sciences, etc. since it isn't CS-specific.


Conclusion, reflection

I think having a university curriculum to give students a structured path for studying Computer Science will always be in demand, but looking at how many courses I would not consider to be influential in my daily life as a software engineer I can't help but feel a little duped. So much time spent on irrelevant busywork and following arbitrary guidelines in the name of fostering a more well-rounded student. So much time spent rushing to complete a writing assignment for a make-work class so I could dedicate more time to my "real" classes. Why does this much fluff exist? I can't imagine going back now, after 3 years of industry work, and trying to listen to professors and advisors try to convince me that a class like "Ethics for Computer Professionals" would be necessary at all for my career.

It's clear to me that we can greatly reduce the amount of work given to students and distill what they need to develop genuine mastery of CS while still allowing them to explore related and unrelated topics of interest. We just need to go about it in a different way, and stop pretending most things we're teaching students now is actually worth their time. In doing this, we could probably slash the amount of time it takes to gain a Bachelor's in half. But I could go on and that's a rant for another day.

It's not all bad. I met fellow classmates I'm happy to call my friends to this day and I still have fond memories of working late together to finally understand what the hell an AVL tree is and how it works. The professors that were good, were actually great. And it showed me that I can do some pretty amazing things (namely just balancing some insane class schedules later on) when I put forth the effort, which is always valuable. Overall I'm thankful for that piece of paper on my wall, busywork and all, as a memento of a certain time where I decided to take the reigns of my life and make it happen.