Hacker News new | ask | show | jobs
by _delirium 3652 days ago
I may have been lucky, but I don't recognize this statement when I think of my own CS curriculum:

The vast majority of what a programmer does, forming good abstractions and avoiding complexity, is almost completely untouched by computer science curriculums.

That's the majority of what my CS degree covered, in several different programming paradigms. Even the idea that there are "programming paradigms" is something I learned at university, from a great course called Comparative Programming Languages. Granted, it's one thing to study it and another thing to gain years of experience doing it, but it was certainly a big focus. I took a whole course on design and structure of OO programs, which mainly at the time focused on C++, but also covered some alternative OO models and what pros/cons various people have claimed for this style of abstraction. And another one on design and structure of functional programs, which in the case of the one I took was mainly from the ML family perspective. These had some more "theoretical" content as well, especially the functional-programming one had quite a bit on type systems, but the overarching goal of the courses was abstraction and structuring (and even the type-theory stuff was introduced as a means to the end of useful programming abstractions).

When I read these kinds of summaries of computer-science degrees, I get the impression people went to some kind of program that was 100% algorithms courses, proving big-O running times and termination properties and that kind of thing. I thought I went to a pretty theoretical one (vs. one with more of a software-engineering bent), but it was maybe 20-25% algorithms. Where are people going where they are taking nothing but Algorithms 101 through Algorithms 1601 for four years?

I do agree that the standard tech company interview process seems to mainly test the algorithms part of the CS curriculum for some reason. I think tech interviewers love big-O notation tests more than actual CS academics do.

5 comments

I went to an Ivy League college with a notable connection to Basic, and I didn't write a line of code for my algorithms and data structures classes, or for my AI class, for that matter. I wrote a metric shit-ton of proofs, though, and I can say with 100% confidence, that that was a complete waste of time.
I also wrote a metric shit-ton of proofs in my CS graduate education, and have that to thank for a greatly increased capability for logical thought over my undergraduate self.
I really view that algorithms class as a massive, massive wasted opportunity. There are really two aspects to that kind of a subject - the theoretical underpinnings, and the practical applications. We beat the ever-living piss out of the theory, but I doubt anyone who didn't already know how to do it came out of that class knowing how you would actually code a linked list or a graph, and what the trade-offs of various implementations were. That kind of a subject would be such a rich field for a course in low level C or Rust or [insert manual-memory-management language]
I see complaints about big-O notation being a useless interview torture device all the time, and yet I'd be hard-pressed to find something else in my very theoretical CS education that (a) was easier to learn (it's the most hand-wavy math I've ever encountered), (b) I retained as well, or (c) is as useful to me as a full-stack web developer.

I can't speak for others, but knowing when to use an array vs. when to use a set feels pretty fundamental to me being able to do my job well.

>I can't speak for others, but knowing when to use an array vs. when to use a set feels pretty fundamental to me being able to do my job well.

I'm not sure why you assume that the only way to learn this knowledge is through a CS degree. These are things than can be quickly learned by reading a few articles online.

I also don't see why one would necessarily need to reason from complexity arguments, rather than more intuitive "I'm using a set because I want to use set operations like union and membership". If performance is crucial, reasoning by complexity analysis is not sufficient and often not even necessary.
This becomes tricky when you're using a language like Ruby where arrays also have built-in union and membership operations.

And I don't see why, if performance is critical, knowing which operations/techniques/algorithms are orders of magnitude slower than others wouldn't be useful (it has been for me).

With higher level languages it's even less important to know theoretic complexities, just represent the problem in the most natural representation and optimize later. (You're already giving up orders of magnitude in exchange for dev time by using a higher level language.) Good engineering practices like being able to swap out structures and algorithms later matter a lot more.

Operations/techniques/algorithms are great to know when performance is critical, the subset knowledge of worst-case time and space complexities not really. (And in interviews do you ask for best case or average-under-certain-probability-distributions cases? How expansive is the trivia matrix you get candidates to fill in?) They can sometimes help guide, but they'll just as often mislead. Bubble sort and insertion sort are both n^2 algorithms, but you should never use bubble sort, and if you never profile you'll be confused why my quicker quicksort uses insertion sort inside when n is small since quicksort is n * log(n) so it should always be better right? (Conveniently ignoring worst case for quicksort is n^2 because people usually just memorize the n * log(n) factoid.) Or you'll be confused why I don't use quicksort at all if I have multiple CPU cores to create a parallel algorithm on. Throw in other aspects of modern hardware like caches (try swapping the loop order in code that needs to loop over all cells in an NxM matrix and note how much performance can suffer if you do it wrong) and branch prediction and special instructions your CPU architecture supports, those are very good to know too if you care a lot about performance. For complexity analysis in the real world, "constants matter", but that doesn't really capture all of the caveats.

Maybe the classic case of my overall point is the existence of https://en.wikipedia.org/wiki/Simplex_algorithm#Efficiency

Edit: one interview problem I like to give (given I have to give one and can't do things my preferred way) is the jump game: https://leetcode.com/problems/jump-game/ Rot13 commentary: Bar fbyhgvba vf whfg qrcgu-svefg frnepu. Va Clguba zl pbqr sbe gung vf 12 yvarf, vg hfrf n fgnpx (jvgu n abezny clguba neenl; vg pna or n dhrhr gbb vs lbh whfg punatr gur nethzrag gb .cbc()) naq n frg, ohg lbh pbhyq whfg hfr n cynva neenl sbe rirelguvat. V yvxr guvf ceboyrz fvapr vg yrgf zr frr vs gur crefba xabjf ubj gb nccyl bgure fgehpgherf orfvqrf cynva neenlf. N ybg bs crbcyr pna erpnyy gur rkvfgrapr bs frgf naq dhrhrf naq znlor svyy va gurve pbzcyrkvgvrf bs PEHQ bcrengvbaf ba n zngevk ohg pna'g npghnyyl nccyl gurz be nal nytbevguzf orlbaq ovanel frnepu naq gur onfvp PEHQ vzcyrzragngvbaf sbe rnpu onfvp fgehpgher.

I'm not assuming this at all. By all means, learn via non-traditional routes! I only meant to push back on the parent comment's framing of big-O complexity as useless theory.
I got my degree in Computer Engineering rather than CompSci or Software Engineering at Waterloo, which is sort of a hardware/software hybrid program. In hindsight that was probably the wrong choice for me. I quickly found out I really didn't enjoy working with hardware, and that the software side of the program was woefully inadequate compared to some of the better CS programs out there, precisely because we had zero exposure to paradigms that were not imperative/OO programming.

My friends in CS at Waterloo got to work with Scheme in the first year for their introductory programming course, when we were using C# and Java and the like. I was young, stupid and arrogant at the time, and made fun of them because I dismissed Scheme as some weird language nobody would ever use, but now I really envy the CS grads for their clearly much more well-rounded and better thought-out software curriculum.

The saving grace of the Computer Engineering degree at Waterloo is of course the 6 4-month co-op terms (internships) sprinkled throughout the 5 years program, where I gained valuable real-world work experience and finally acquired an appreciation for functional programming, but there's a large degree of variance in students' experience in the co-op program depending on the jobs they can find, so not everyone can be so lucky.

Well, on the other hand you hopefully have a deeper appreciation of all the assumptions and approximations that make up the implementation of boolean logic underlying our computers.
Sounds like the kind of course that I would have wanted (I dropped out of mine). The sad thing is that they get squashed under the weight of students and industry railing against learning 'theoretical' stuff because it seems like it isn't 'real world' enough. On the contrary I've found my self-education in type theory, programming languages, and discrete mathematics hugely beneficial in helping me pick up new technology fast, and finding the right abstractions for the job at hand.
I probably covered more on networking than algorithms. I only did 2 papers on algorithms at university, as well as AI, which covered some more algorithms.

I did 2 papers on networking, a paper on computer security, and a paper on web development, and implemented an http client for Operating Systems.

I had 2 classes of data structures + algorithms, a couple more of algorithms and complexity analysis, and algorithms were heavy components of the AI and robotics electives that I took. I had one networking class, also an elective. I had a similar programming language comparison class as the poster you responded to, along with OOP design and a course on software engineering practices.

There were some other math and logic-related courses with some proofs and such, but almost all of that was backed by writing software projects. I didn't write many papers in my computer science classes, but I did a lot of projects, both individually and in groups.

It's interesting to read how different other people's university experiences were.