Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
A computer science study plan to become a software engineer (github.com/jwasham)
374 points by sturza on Dec 16, 2020 | hide | past | favorite | 216 comments


This isn't a bad list of topics about data structures, algorithms, and software fundamentals, but let's not pretend that computer science has anything to do with most software engineering roles. I studied computer science, and in 30 years, I've hardly used any of it. There were a few jobs where some of the statistics and math were helpful, but in my long career, I've seen very little overlap between computer science and working as a software engineer. Google and other big tech companies use these criteria to filter people out at the hiring stage, but the vast majority of work has nothing to do with any of this stuff.


Your comment reflects a common meme that can often be summarized as: "Real World" work doesn't involve the academic nonsense you learn in school.

Many of the people who say this kind of stuff never really mastered the theory, and because they never mastered it they can't really use it, and because they can't really use it they find work that doesn't strictly require it, and then conclude it's useless... It's like when otherwise successful people tell you all that calculus they learned in high school is useless, it's not useless, they just found success in a career that didn't need it.

I resort to my textbooks and academic nonsense all the time. There are often two ways to solve a problem, the first is just code-until-it-works, the second often involves modeling it in some kind of formal structure, and defining the operations over that structure and their properties. Usually, in doing this, the resulting implementation is far less code and far more resilient. But those who are not comfortable with the foundational theory stuff just don't see it and don't even think to approach the problem in that way.


I think you've refuted something other than what caymanjim said here. I personally agree that "the vast majority" of software engineering does not require deep knowledge of computer science, and I also believe there are plenty of "real world" problems that absolutely do require computer science. In no way does my agreement with the first statement commit me to disagreeing with the second statement.

You say caymanjim's comment "reflects a common meme" that real world work "doesn't involve the academic nonsense you learn in school" Why? It seems like you swapped out his argument with something different, by claiming one "reflects" the other. Sounds like "We got trouble, with a capital T, and that rhymes with P, and that stands for Pool". Stating that most software engineering work doesn't require CS theory doesn't commit anyone to claiming that it never relates to real world work. Furthermore, I think you can claim that theory isn't used in the vast majority of real world work without dismissing that theory as "nonsense" - a word you supplied here that wasn't part of the OPs comment.

Now - I will agree with you that many people say this stuff, and you may very well have diagnosed why. But you refuted something you recall other people saying, not what caymanjim said.


CompSci theory hasn't helped me with the complexity of the industry i work in. It hasn't helped me when i've misunderstood something in our domain. It hasn't helped me release / distribute a product easier or faster or cheaper. It hasn't helped me navigate team dynamics or how to work effectively with others. It hasn't helped me write better technical texts.

So for some very specific cases, in my career (and i suspect for many business application developers) set theory has been the most useful thing i learned in CompSci. How much of a real world day do i spend using that knowledge? 0.0something% on average.

In fairness, It has sometimes helped me get a product finished sooner but this is tenuous at best because i can point to far greater influences from learning how to use specific tools that have helped me get to "done" sooner.

The difference between real world developer and CompSci isn't necessarily in more effective use of CompSci.


Maybe it's easy to overlook these things when you have a really deep computer science background, but coming to software engineering from a non-CS background (math degree) I found lots of valuable knowledge in CS. The most important parts for me would be:

- State machines. I run into a lot of state machines, especially incompletely specified ones. Not that everybody gets these wrong if they haven't studied state machines in a textbook and worked the exercises at the end of the chapter, but recognizing "oh, this is a state machine" gives me a mental framework, a notation, a vocabulary that other developers understand, and a better ability to understand when a problem is underspecified or inconsistent.

- Queueing theory and algorithmic complexity. These two usually come in handy from the perspective of spotting and avoiding stupid mistakes. It's true that people can do a pretty decent job from a handful of rules of thumb, but not everybody has that minimum knowledge, and sometimes a problem has a twist that an imprecise rule of thumb doesn't account for.

- Distributed systems. Just understanding the solution of a few problems in depth, and knowing from that how hard simple things really are, is incredibly valuable. Without that background, people can naively tackle extremely complex problems, bash their heads against them for years, and still underestimate the difficulty of the problems they've created for themselves by orders of magnitude.

In general, the rigor of doing theoretical problems, the discipline of actually proving things, creates habits that uncover lots of non-happy path possibilities.


I also don't have a CS degree and am self-taught. And I very much agree with you that many CS concepts have quite a practical impact. Some of them more on the side of approach and selecting the right tech/solution, but some have a more hands-on practical use.

- State machines: completely agree. I use them especially in the context of user facing stuff, like GUIs, animations and so on. In fact I would even argue that they are _inherent_: Even if you don't recognize and specifically structure your code around them, they are still _there_ just smeared all over your logic.

- A&D I find ubiquitous are: sets, graphs, trees. Sets especially are underused and graphs are the most expressive data structures if you need them and can help you model complex, long lasting models.

- Relational algebra is likely one of the most important concepts. It is fundamental to the Swiss army knife of databases: SQL.

- Algorithmic complexity: I rarely use this formally, but it really helps to get a decent intuition for performance.


> Relational algebra

Seriously? Currently working through my second databases course, I still can't help translating all of the relational algebra nonsense into proto-SQL in order to make sense of it. I was already working on large-ish business applications and databases for a few years before the first course and I didn't even know RA existed. Now it just gets in the way.

Not to mention relational expressions or whatever that thing is called where you use the "exists" and "for every" operators, which I still haven't been able to apply in practice.


Coming also from a SE/Practical background, the only time I need to use those complex expression in a SQL query, is when someone screwed up the datamodel, or over-engineered it. In theory you can do many things with SQL, but none of those things perform better than a straight up select query, which is usually what you're after-- performance.


For me the experience was different. I also knew SQL before, but after learning RA I first was slightly disappointed that SQL wasn’t as clean. But conceptually they’re the same.

I think the interesting Aha moment was the realization that SQL is syntax on top of a mathematical concept. Before I was distracted by the practice of reading and writing stuff to disk with it, if that makes sense.


> State machines

Probably one of the most powerful tool out here. You can catch a lot of things simply by identifying which state transitions should be possible and which shouldn't exist


Can you please describe when you had to use formal queueing theory in your work?

I have struggled - and failed - to find a use case relevant to daily SWE work, since (a) the probability distribution for most customers waiting in a queue is not known and must be "guessed" or predicted ahead of time using historical data and (b) nearly all queue requirements are simple (i.e. minimize total waiting time) and the solutions just as simple (scale up your queue consumers!)


Mostly simple things: if you have a messaging queue used for logging, and you need to predict the change in its memory footprint given some change in a message format before rolling out/testing the format change, just use Little's law. Or you need to determine the smallest number of consumers that you can have online safely to maximize how quickly you can do maintenance without degrading logging.


You might think that something as simple as Little's Law is intuitive, but people who haven't learned it don't always find its conclusions obvious, and they are less likely to see when a problem can be framed as a queueing problem. The value is really in simple stuff like this, where having something in your mental toolkit makes the difference between a problem requiring a trivial application of something you know versus requiring thought and creativity.

A particular example I remember was a poorly architected system that was essentially two systems connected like queues in sequence. The first one was fast and lightweight, basically a gateway/hydrator for the second one, and could handle a very large backup with no ill effects. The second one was very slow and fell over quickly if too many items accumulated in the queue during a load spike. An easy short-term fix to make the system stable in production was to introduce artificial slowness in the first queue to buffer load spikes and prevent backups in the second queue. Little's Law points straight to this solution, but people who didn't have queueing theory in their mental toolkit had not considered fixing the system by slowing part of it down. It looked like a big leap of imagination for them, even if they found it intuitive to understand after it was pointed out.


It sounds like you work in an industry that doesn't strictly require frequently delving into foundational theory in CS. I do believe it would be a mistake to conclude its useless, however, as there are many other industries that do need it, and people who are not in touch with the theory probably would not be competitive in those industries.


From your prespective how common are those types of roles in all industries as a whole?

There are interesting compiler roles but the vast majority who learn how to build a compiler never use it day to day work. Would you recommend spending more time building compilers to better compete for those few roles or would you recommend a different approach?


I use most of my CS skills almost daily.

I may not be writing compilers professionally, but on the surface, understanding parsing has gotten me out of more than a few tight corners. More abstractly, there are lessens to be learned in designing large applications; and appreciating the difference between a finite state machine and a deterministic turing machine, including the types of problems they can solve and how much of a pain in the ass one is to write compared to the other.


Challenges that benefit tremendously from just a bit of a dive into theory are all over the place. This has been true for me in my career as a software engineer whether I'm working at an energy company, federal research lab, tech startup, or networking services company. The key part is that it's not apparent (or apparently needed) unless you are familiar with the material.


I work in firmware, and 99.9% of the time the most exotic data structure we touch is a linked list

CS still comes in handy though, especially computer engineering to understand some of the workings of the hardware

Occasionally I'll use real CS knowledge when I'm building tools for work or working on games in my free time.

Full disclosure, I didn't actually study CS in school though.. I studied EE and then went and learned CS via Wikipedia when I needed it to find a better-paying coding job.


I have a degree in math and physics. I used it exactly once, in one aspect on one job. It was down below 0.0something% - need one or three more zeroes...

... until I took a job in X-ray imaging. We were working on a surgical X-ray (C arm) that could pinch-hit as a CT machine. And suddenly everything was 3D coordinate transforms and fourier transforms, plus X-ray physics, up to my eyeballs.

The theory stuff isn't useful... until it is. And when it is, it helps to have it.


This is true for the most part. But having the CS knowledge allows you to create much more efficient solutions once at scale.

I've personally revamped core parts of a product at previous companies to be over 1,000x more efficient just by applying some CS principles. This translates to $100K/mo+ in savings for a company that is at scale.


I have to ask though... Was it at scale?


I guess that's a relative term. But hosting bill was around $250K/mo from what I remember.


On the topic of useless subjects (on a personal level) I nominate chemistry. Never had to use it or depend on chemical knowledge, never had to write a chemical reaction or compute masses except as a student. So many years spent on chemistry instead of learning some other subject.


I also never use chemistry knowledge for anything, ever. But I find it quite interesting to know a little bit about how matter works, and how it combines into things that make up my body and (hey, let's go there) mind. I had to take an intro class in college to learn to appreciate all that, though; high school chemistry class was pretty dull and useless for me.


I find that hearing about how stuff works and how that directly relates to daily life is easy for me (and probably most people) to internalize and retain.

For example something that has stuck with me since high school was hearing that H20 expanding when it freezes into a solid is what makes ice skating possible. Pressure exerted by the skate blade forces the surface of the ice into a liquid state which makes it slippery.

Where educational curriculum tend to lose people is by overemphasizing the canon/trivia. Ironically that seems to be a result of needing to develop additional, obscure, test questions to deter students memorizing rote information or last years final exams.

In regards to computer science I think there is more to gain for students by learning the history and development of particular CS solutions and discoveries as they are more likely to encounter those situations in their careers than a particular need for a CS technique.


Play Omnifactory or any modpack with gregtech. It's not 100% realistic but you're doing practical chemistry all the time.


All this is true, but when I look at undergrad curricula for other engineering disciplines I don't see this stuff either. And the software engineering courses I did have in undergrad were terrible.


Software engineering needs to be learned on the job. I see lots of new grads that take classes in "Agile" and I cringe just knowing how instead they could be taking difficult courses in graph theory, theory of computation, abstract algebra, advanced algorithms, distributed systems, or any other number of advanced topics. As we get older it's easier to pick up tricks of the trade (various Git workflows, "agile", etc)... but it gets harder to sit down to do 3 hours of homework 4 days a week doing your pushdown automata or linear algebra exercises.


> but it gets harder to sit down to do 3 hours of homework 4 days a week doing your pushdown automata or linear algebra exercises.

38 year old studying astrodynamics for work. Can attest to the difficulty of this. No kids yet, that helps, but the wife and I are planning on starting a family soon so it'll get even harder with increased demands on my time.


I have no experience in the field and I would like to quickly get in it. I want to dive in with experience and I’m trying to figure out what things would get me there quicker if someone wanted to tutor me at work. What would you say are the things in your experience that are most useful to be able to contribute in a development team?


I'd say the ability to solve a real problem in the programming language of your choice is a minimum criteria to call yourself a programmer. Getting there would require a basic understanding of that language, data structures generally, many problems revolve around databases or REST APIs so learn how to use those, I'd also throw in version control and how to write unit tests.


Excellent, much appreciated


I agree with everything you're saying, but I didn't make the claims you're disputing. I don't think CS fundamentals are "useless" or "nonsense" by any stretch. There have been times in my career when I wished I had a stronger background. In particular, I've worked for NASA and in finance, and in both cases, I'd have benefitted from stronger statistics and math knowledge.

My comment was that most (I would say the vast majority) of software engineer roles don't require a computer science background (emphasis on the science), and wouldn't leverage it even if you had it. If you do have a strong CS background, it opens a lot of doors, and in particular opens doors to--in my opinion--more interesting and challenging work. There's nothing bad about getting a CS degree. It's just not required for a software engineering job. I'm not being dismissive of the education. I'm skeptical of the idea that it's important for most roles.


> it's not useless, they just found success in a career that didn't need it.

Or don't realize how often they actually do use the skills they learned in calculus class to solve problems that don't necessarily involve derivatives or integrals but do require a methodical, structured approach to solve that isn't something you're born being able to do but must instead be honed through practice on "toy" problems.


"Many of the people who say this kind of stuff never really mastered the theory, and because they never mastered it they can't really use it, and because they can't really use it they find work that doesn't strictly require it, and then conclude it's useless..."

this is quite the assertion. do you have any evidence supporting this statement?


I think the claim is easily sustained with just empirical evidence. If you want to do a career in embedded, or graphics, or robotics, or maybe flight control, etc., you're going to need the math and the comp sci in droves. HN tends to have a crowd skewed towards certain disciplines, which is why every time the topic of a whiteboard interview shows up, most of the comments voice a strong opposition. In my line of work (graphics), the whiteboard is used all the time, both in and out of the interview.


I've done both graphics and embedded systems. I don't think any of that is true. In fact I found most the formal education around graphics to be outdated or disconnected from the reality of how systems are built(mostly due to trade secrets and the industry moving much faster than coursework could keep up).


Oh yea, calculus and linear algebra is all washed up and the industry has moved way past it. /s

"I don't think any of that is true" is a strong statement. Nobody is saying that a toy renderer in school resembles a AAA rendering engine, but the point is that the thought process needed is the same, and I'm still going to expect a certain degree of rigor from any candidate. Also, the parent post is speaking more about the theory and fundamentals in general, not the direct contents of any particular coursework. FWIW, I am not formally trained in graphics or CS (my training was math).


My strong statement was in counter to your assertion that the empirical evidence holds that you'll need math and cs in spades.

Most of my graphics works was better served by an understanding of hardware(pipelining, SRAM vs DRAM caches and latency penalties including random vs linear reads). Most of the embedded work was done with a rigor towards memory management and not any "traditional CS". In fact we avoided traditional CS structures(lists, trees, etc) since they had negative performance penalties. The only thing that we came close to leveraging was radix sort along the view axis, and that was through a gnarly hack that let us use it for floating point values.

I've also yet to run into anyone in gamedev or the graphics world who could derive quaternions from first principals. They're damn useful but I think you you know their operations understanding the theory doesn't take you much further.

I think you have a point on rigor, but that has more to do with how to tackle problems broadly rather than any sort of academic or theoretical background.


Computer science courses these days do in fact teach about memory coherency and MESI protocols with respect to CPU cache management and architecture. You'd learn about pipelining as well, and scalar architectures for that matter. I guess my point is that even if you didn't, if you wanted a head start, it's sufficient to know at least the basics of what microarchitectures are, and how to reason about a computational model of complexity, even if you need to adjust it later (for a particular console, or GPU, or architecture).

As for quaternions, I can derive them (no really, I've written a ton of code in this space, although I prefer the GA formulation), but I want to know, does the candidate understand why they're mathematically advantageous (blending properties, linearity, etc). Can they productively read a paper that uses it and apply the technique, etc.


You can learn the relevant parts of calculus and linear algebra in isolation. I've experienced that knowing the abstract theory of linear algebra is actually just taking away time and resources that could have been spent in increasing your competence in the non abstract parts of linear algebra. A lot of students aren't ready for industry, not because they are incompetent or not smart enough but rather because they have directed all their time and energy on solving difficult problems which meant they had no time for the boat load of easy problems that industry actually needs.


90% of jobs in software engineering require very little CS knowledge. Yet interviews for entry level software engineering jobs focus 100% on CS 101.

It's not that CS knowledge is useless, in fact it's great to know the theory. It's just not the top priority in terms of doing everyday work. Recommending an aspiring engineer prioritize CS (outside of what you need to pass interviews) is like recommending an aspiring pianist to master music theory. Nice to have, sure, but not an efficient use of time.

Also when people defend the importance of knowledge of CS theory in this industry, their seems to be this implication that CS theory somehow can't be learned on the job. As if it's super complicated and only "real" engineers have the intelligence to pick it up. A load of crap. For example, I once had to use graph algorithms on the job (probably the only time I've ever had to use CS on the job), and I didn't remember any of that stuff from school, so I took a day or two to read up on graph data structures & algorithms, and was able to get the job done.

What's more important in this industry, or any field really (unless maybe you're doing something super special like nuclear physics), is knowing how to learn - especially at the junior level. That is way more important than any knowledge. Of course you need to have some base knowledge, but any junior engineer working their first job is going to have a hell of a lot to learn anyways, so for an entry level role I'd rather pick the smarter person who's dabbled in his own projects and is eager to learn than the CS major who's expecting to be tackling interesting CS problems all day at work - unless of course the job actually requires this which until now has never been the case for any of my software jobs.


> What's more important in this industry, or any field really [...], is knowing how to learn - especially at the junior level.

Here we completely agree.

> so for an entry level role I'd rather pick the smarter person who's dabbled in his own projects and is eager to learn than the CS major who's expecting to be tackling interesting CS problems all day at work - unless of course the job actually requires this which until now has never been the case for any of my software jobs.

I disagree.

Using CS problems has two advantages. The first is that it establishes a common vocabulary. The second is that it's stack agnostic.

Personal projects are great, but sometimes it's hard to tell how much help they got from the internet...

Being able to learn CS fundamentals is, to me, a bigger predictor of later performance when they'll be tasked to learn Enterprise X Custom Stack that's not really covered online instead of Well Documented Framework With 1000 Examples.


What is the base knowledge you’d like to see if your boss brought you someone new and told you ”he’s going to be learning with you”?


> and because they never mastered it they can't really use it, and because they can't really use it they find work that doesn't strictly require it, and then conclude it's useless...

But isn't this statement too specific to apply to the generalization that you're disagreeing with? "Most 'real world' work doesn't require CompSci" is a generally true statement, because most "real world work" is incredibly mundane and repetitive.

So, isn't your take kind of the inverse of what you're talking about? "I enjoyed ____, so I sought out industries that required ____". Almost as though computer science is a specialization within "real world" work?

I guess I think that most industries are not the industries that you're seeking out. Most software developers are employed to combine already-solved problems with new inputs for money.

What do you think?


Can you give some examples of where computer science academic theory helped in software engineering?


- For parsing, the difference between context free languages and regular languages. This has helped in a number of projects (usually at the clean up end).

- Boolean algebra has helped me greatly simplify hard to understand nested conditionals.

- Understanding data structures lets me pick the right ones for the problem.

- Algorithm analysis has let me take program runtimes from minutes or hours on modest data sets down to seconds or minutes.

- Discrete math topics helped me prove a problem that a coworker had spent a few weeks on was technically impossible.

- Again for parsing, understanding the ideas of parsing let me make a number of parsers over the years using a variety of mechanisms. The critical part, though, was understanding what was being parsed and how to parse so the code was clear. I replaced convoluted code with hardcoded values and assumptions about what would be in each part (line, or binary blob) with something more flexible and less hacky.

- Knowing how C stores data (stack versus heap) let me fix a lot of code from some engineer colleagues that would work, sometimes, but not reliably because they didn't understand how memory works.


Personally, I see it come up in more vague areas during my Web Development. It's more along the lines of, "based off my understanding of X, I can assume this bit of JavaScript code works like this under the hood". Understanding how memory works traditionally keeps me "memory-conscience", but this may be redundant when working with JavaScript. When writing complicated operations I can use things I've learned previously to improve efficiency. To put it nicely, I'm not balancing binary trees and sorting my arrays with JavaScript. However, it was helpful when learning how the VDom works.

In other industries...

I started my Software Development journey with C, then moved into Game Development in C++ as my first job. Game Development DEFINITELY requires a lot of CompSci info (that I lacked). Hash Maps, Pathfinding, Matrix math, physics calculations, Linked Lists; all the works. We were also using a proprietary Game Engine so maybe with other Engines CompSci isn't as needed, I haven't worked in different engines.


People can go on all day about this. The most major one for me is protocol engineering - there's a whole world out there on this. Others would be model based design and its formal verification. Also several problems in state synchronization in distributed systems.

In many of these cases, the team I joined had a code base in place that "kind of" did the solution, but was not grounded in any conceptual model - despite phenomenal code quality, peer reviews, etc. Recasting it as an implementation of a well-studied formal model generally yielded a codebase that was one-tenth the size of the original, and with far fewer defects. As I said in the parent comment, if you aren't familiar with this kind of stuff, you don't know about it, so you don't use it, so you find other (suboptimal) ways to do it.


What are resources you reference the most in this kind of work?


I use category theory quite frequently when doing functional programming. Unfortunately it is not taught in CS programs AFAIK. I rarely implement any tree kind of algorithms other than a simple tree visitor.

An understanding of time/space complexity (Big O Notation) is also relevant to evaluating approaches. A senior level developer will use this to make high level choices.

I also use compiler theory when writing parsers and simple DSL languages.

Honestly, never really had to deal much with red-black trees or linked list algorithms.


1. Unix was cutting edge OS theory and gave birth to the microcomputer industry.

2. AWS was cutting edge distributed systems theory and gave birth to cloud computing.

3. Renaissance Technology was cutting edge algorithms theory and gave birth to quantitative hedge funds.

Some people innovate for a living.


Never heard RenTec described that way, the only information that seems to be out there is that they use much simpler algorithmic techniques than people imagine, mainly just linear regression. Whatever unique insight they have, it's more likely to be based on pure mathematics than cutting edge algorithms theory. Also, they were not the first quant fund.


Unix was cutting edge OS theory? I mean, it was Bell Labs, and they were probably the premiere research facility in the world at the time, but my impression is that the trick on Unix was how small they were able to squeeze it, not that it was pushing theoretical boundaries.

Can you point me to any aspects of Unix that were theoretically new?


What we take for granted today was once brand new and hard won.


True. But what was new in Unix? What specifically?


Multitasking


Didn't Multics have that? I mean, Multics never went anywhere, but the theory wasn't new to Unix, was it?


Back then, Multics was designed to run on expensive and specialized proprietary hardware where as Unix could run on a variety of cheap computers.

One can say the philosophy behind Unix was new. I'm sure that's why modular and micro kernel designs caught on.


Please go pick up any of the Martin Fowler books. All are rooted in computer science fundamentals. Let’s not pretend software engineering isn’t rooted in computer science. That’s a categorically false assertion.


A moderate complexity task such as writing a JPEG codec requires understanding of Huffman coding, discrete cosine transform and a number of other minor concepts.

Right now am working on a physically distributed, synchornized system. It has some signal processing code: cross-correlation, FFT. The process planner builds spanning trees out of the layout graph to execute the tasks.


Tons: Cryptography, operating systems concepts including multi-threading, distributed systems, network communication, mobile and embedded systems which are basic backbones of all the things you use today. You know that's where majority of the tech companies are innovating on, right?


I have definitely worked on systems that tried to do parallelism without any real understanding of underlying primitives or theory. They were not ideal.


Dealing with unicode bugs taught me a lot about computer science academic theory. It helped to understand memory addresses and how encoding works.


I tend to use it quite regularly. I've had to diagnose many performance issues with our large code base. Understanding compilers, data structures, networking, OS internals, etc, have all been quite helpful. Even if it's simply finding a starting point for tackling the problem.

Sometimes it's trivial, replacing a for-each loop with something that's log(n) or O(1). Sometimes a little more complicated, like refactoring some code and realizing the original implementer was trying to do BFS but.. wrote something else. And the rarer cases are having to really dive in and trace some odd contention issues. All of these touch on what I learned in college at some level. Sometimes knowing something exists is helpful for looking up later and can save lots of time.

I do wonder if it's less about "requiring" the education and more about someone seeking out the kind of work that uses the education. I know many people in my company are the opposite of me, and definitely do not care to go much deeper than implementing things until they work.


I wish the whole industry would at least get to that latter level. I see a fair amount of “jiggle it until it’s no longer obviously broken”.


Relevant comment from a few days ago about Linus Torvald’s code handling of linked lists and the theory behind it:

https://news.ycombinator.com/item?id=25327683


Knowing the properties of a data structure and how it works under the hood is incredibly valuable when deciding if it's a good answer to the problem at hand. If you don't know why hashing is important or what it gets you, you might not understand why a hashmap is a very powerful tool. You might choose some other structure or hand-roll something involving manually managing multiple arrays, and down the line run into what feel like intractable performance problems.

That's just one example, pulled from people I've worked with. An understanding of fundamentals is required to do a real evaluation for yourself.


Currently writing software for electrical engineers. One example that comes to mind is graph theory. I use it frequently to answer questions about the data I'm looking at.

Imagine an electrical distribution network where there are 3 phases (A/B/C) and an overhead line can contain any combination of those phases. These networks can be modeled as a graph with nodes connected by links. The links do not have a direction, but they do have a phase. If you want to know what the phasing is at any point in the network, the way to figure that out is to use graph algorithms.


Boolean algebra, relational algebra, sets and graphs, reductions, runtime analysis, gossip and epidemic protocols, satisfiably, verification, turing machines, push down automata, etc.


it's a small thing, but I find it pretty useful to be comfortable with the basic boolean identities. makes it much easier to rearrange if conditions for readability without stressing that you might be changing behavior.


Dictionaries for O(1) lookups, b-tree indexes for fast SQL queries, interval trees in genomics analysis software.


If this was an interview I'd say dictionaries aren't O(1) but one popular implementation of this collection is.


> But those who are not comfortable with the foundational theory stuff just don't see it and don't even think to approach the problem in that way.

Or maybe all that "foundational theory" is oblivious to cache hierarchies(hello Big O notation) and generates worse performance on constrained devices. Or perhaps there's enough unknown, unknowns that throwing something at the wall is a legit way to get data if it's not a one-way decision.

However the attitude on display above is a problem because you've just alienated those people who may have come from a different background or do know the theory but are approaching a problem in a different way.


All approaches aren't equal. Yes, big-O notation hides constant factors like cache coherence but the solution isn't to analyse things less. Its to analyse things more. And thats what a proper CS education should teach.

And at least once a year I draw on my CS education to:

- Model something using state machine semantics

- Use heap-based priority queues, binary search, b-trees or skip lists. And of course I use hash tables and hash sets weekly.

- Read and implement something that CS researchers invented (PAXOS, interval tree clocks, CRDT work like RGA & YATA, etc).

A lot of self taught programmers also don't seem to have fluency with all the degrees of freedom you have as a software engineer. Off the top of my head: Do you know where the bottlenecks are in this program? Are there better algorithms you could use? Are there different dataflow architectures which would help? Can you trade off CPU for memory with caching or memoization? What are the memory allocation patterns? What do you expect the upper bound on performance to be for this process? What are the fundamental invariants your program / data model should always maintain? Can we use a fuzzer to ensure those variants are always maintained? If those invariants aren't being maintained, would we know about it? What are the single points of failure? (And how could we add redundancy?) How would reliability and performance change if we use a different database, or added or removed indexes or caches? If you wanted to steal our user data, what are all the ways you could you do it?

A junior engineer (or an engineer at a feature factory) might never need to ask these questions. But becoming a good senior requires a deeper expertise in seeing a program. And that requires an integrated knowledge of fundamentals, program analysis, tooling, experience and creativity. People learn all that without a degree, but personally? There's no way I would have learned all that stuff as well on my own.


> Yes, big-O notation hides constant factors like cache coherence but the solution isn't to analyse things less.

Yet I run into good developers with good CS backgrounds all the time who were never exposed to cache hierarchies in their traditional CS education but had Big-O pounded into their head like it was the gospel on high. Sometimes it seems like revealing how cache misses or prefetchers work is some sort of magic trick that academia skips over.

I've also seen where software engineers will stop at the boundaries of "CS" when it comes to problem solving(ex: not consider the hardware because it's a "hardware" problem rather than rolling up their sleeves and digging in). With the pace of development in software you need to continue to learn outside of a school setting and cultivate that curiosity that helps you come at problems from new and interesting ways.


> you need to continue to learn outside of a school setting and cultivate that curiosity

This is true of just about everyone in computing. This isn't an industry for people who expect to cruise on the knowledge they were given a decade ago. (Plenty of people do, but thats another rant.)

Regarding big-O, one habit / intuition I think its really important to develop is an intuition about how well something will actually perform in practice. Like, you should be able to guess within an order of magnitude or two:

- How many simple reads per second and writes per second your database can perform

- How many lookups / inserts per second to expect out of some standard data structures. (And how those numbers change as the collection grows)

- How many allocations your program does, and how much time is spent in the allocator

- About how large the steady state working memory size should be for your program

I'm not talking about theoretical O(n) numbers. I mean, right now, if I write a tight loop in nodejs on my laptop writing random numbers to a JS Map(), how fast will it go? How does that compare to C/Rust? How many SET calls per second can a redis instance on my laptop handle? How about SELECT queries to postgres, or find({id:...}) calls to mongodb? Will the database be faster or slower than the nodejs program on my laptop thats issuing those queries? How many HTTP requests per second should I expect out of my express server? How many milliseconds should it take to statically render my web app to HTML? Etc.

And arguably more importantly, it shouldn't take you more than ~20 minutes to go and find out the answer to any of those questions. Benchmarking is a delicate art, but if you can't measure, you programming blind.

I wrote a fuzzer the other day which did about 100 iterations / second. And I know something was wrong because the number was orders of magnitude lower than I intuitively expected. Some tweaking later its now running about 1000 iterations/second - still too slow. Profiling shows its now spending 99% of the time in a single function. I'm hoping for another 10x when I rewrite that function. Without my intuition whispering in my ear, my program could have ended up 100x slower than it should be for no good reason.

Aside: This might make a great interview question for a mid. "I have this simple piece of code. How fast do you think it will run on your laptop? Ok, share your screen and write a program to measure it. Talk to me about your answer!"


Big O is okay but for some reason when professors tell you that reasoning about universally valid performance characteristics of an algorithm is a lot of work if you are worrying about every tiny implementation detail the students ignore all of it and always disregard the constants even though the professor explicitly says that this is a method for estimating how fast the execution time of a function grows with increasing input. It's about building algorithms or datastructures and comparing them. Once you have a good baseline you can improve it further through engineering. The irony of course is that intuition and experience alone can get you 90% of the way but at a much lower time investment but theory can never replace experience because you have to turn that theory into experience first.


Agreed, but also some great moments are when you finally use something you learned and think “Oh, that’s why they taught me that.” Even if it’s many years later and I did NOT master the concepts, I’m just aware of them. It’s happened enough to me that I no longer have the opinion that stuff I learned was “useless” even if I don’t use it. I might one day or someone else might encounter a problem that requires that knowledge.


I'll also say you won't just come across a problem that requires it, but rather you will apply that knowledge to a problem that never seemed to have needed it in the first place, and then you'll come up with a very powerful, compact, and resilient solution.


> Your comment reflects a common meme that can often be summarized as: "Real World" work doesn't involve the academic nonsense you learn in school.

But isn't that generally true for most education and most jobs? For example, what percentage of Real World work that requires a high school degree, actually involves high school geography academic knowledge?


I enjoy CompSci as a distraction - my background is pure maths/mathematical physics so don't think I don't appreciate abstract nonsense - but using it daily is impossible without a lot of contortions.

Contortions I can do easily mind you, but other than recursive functions and linked lists any more complex data structures are too fragile to survive the harsh world of constantly changing business requirements.

As a younger developer I wrote a beautiful algebra that described the company hierarchy for giving permission levels to people from active directory. Within a week I needed to scrap that and redo it from scratch because people needed permissions in the specific app that had nothing to do with their job position.


haha no true Scotsman strikes again! If you are not using theoretical computer science in your daily work, you are either not a true programmer because you neglected to truly absorb the theory, OR not working on true problems, just some low grade commercial bs, right?


How is this not an ad hominem attack? Take your typical software job, can we not identify clearly what percentage requires formal computer science? You’re debasing his claim with a passive aggressive attack on ‘maybe you just didn’t learn shit in college’.


Before we lend your comment any credence, do you mind listing the projects you've worked on?

Groundbreaking software engineering projects that advance the state-of-the-art, like Google's Map-Reduce-based scaling architecture back in the day, or ones that provide some non-trivial edge or advantage, like the tight integration of hardware and software in iPhones (and the resulting responsiveness and battery life), or ones that provide high-assurance and provable correctness (Rust, Haskell, etc) actually do require CS knowledge.

Whenever someone makes a comment like this, I just assume their work thus far has consisted of linking together pre-existing building blocks to make web or mobile apps, rather than anything completely original or state-of-the-art.

And it's good that the industry has gotten to a point that such a job opportunity exists for so many people. But keep in mind it was only possible by decades of development of layers upon layers of abstracting away most of the CS into easily composable libraries, APIs, and other components. You many not need to know algorithms and datastructures yourself, but you're definitely using them by building on them and with libs that encapsulate them.


There is a level between installing wordpress plugins and creating state of the art massive scale infrastructure. And its likely where most developers sit.

I work on a project management application. Its pretty much entirely custom code with little external libraries but it also requires very little computer science theory. The problems I face are less "Find the fastest way to search this datastructure" and more "This code was designed for a legacy model of the system, how can we replace it with something modern without spending months on it"


> I just assume their work thus far has consisted of linking together pre-existing building blocks to make web or mobile apps, rather than anything completely original or state-of-the-art.

...otherwise known as the vast, vast majority of work in "most software engineering roles", as the parent commenter mentioned.

They didn't say CS knowledge was unimportant. They said it wasn't directly used in most SWE work. That's entirely accurate. They did not comment on whether the products of computer science are involved in most software engineering (of course they are, but I don't need to remember A* to use a graph database). They did not comment on (rare) roles in which that knowledge is required to make groundbreaking advancements.


Well, the premise that computer science is needed to be an effective software engineer comes from the original link (and the way interviews are structured). We cannot blame caymanjim for the premise, can we?


Well said.


I am inclined to agree. I think the issue is just with the HN title. The repo does say that it is for interview prep.

I will say that I've seen some companies improve their interview questions to be less about having CS insight or algorithmic "tricks" and more about writing good code.

But I've also been asked to essentially come up with quickselect in a 45 minute screener, the asymptotic analysis of which took me more than 45 minutes to understand.


> and in 30 years, I've hardly used any of it.

Isn't that similar to people saying "I've never used trig in 30 years"? Isn't the point to train your brain to think in a certain way, more so than actually needing sines and cosines?

For computer science specifically, the goal is to teach you to think in terms of loops, conditionals, recursion and so on. It's to train the muscle more so than memorize specific algorithms or data structures.


> Isn't the point to train your brain to think in a certain way

You might get that through other methods besides trig, meaning trig isn't strictly necessary -- it's just one option among potentially many. The hard part is proving efficacy and efficiency of each option.

CompSci interview questions go way beyond loops, conditionals and recursion though, such that if you don't already know some secret sauces, it's unlikely to get the best case solution that the interviewer wants.

The other thing throwing this off is interviews are looking for different grades of solutions or maybe just looking at your problem solving/communication skills, e.g. you can fail to find the best known solution but still get a job because of your reasoning.

So in this way, the algorithms & data structures interviews can sometimes be used to test knowledge, or test problem solving ability, or both.

The interview stopped being a test of "if you can do this job" and instead seeks to find a correlation backed up by some research that says "people that prepare, study, and do well at this interview also do well at this company". Similar research meant that they needed to stop asking brain teaser questions because it wasn't a good indicator of success.


I'm still new to the industry, but my CS education (yours may differ) was quite theory-heavy.

Perhaps the knowledge of data structures and algorithms can be useful for people who need to design whole architectures and systems, but I think the folks who are fixing bugs, tweaking the UI, or adding small features would benefit more from Code Complete than an Algorithms book.


Note that you may find your career limited to fixing (simple!) bugs, tweaking UIs, and adding small features.


That;s a sad career.


It's a career path that maximizes people helped rather than personal intellectual enjoyment.


I've done that kind of thing. It did not help many people, and I came to despise everything about my life. Give me some intellectual enjoyment and I'll be much more motivated to help people.


If you give a good person this job they will leave.


The screening is not optimized to find the best candidates, its just an arbitrary filter that will in the long term let some people that would be fundamental to the survival of the company out of it.

Sometimes its good to accept that the uncertain things are uncertain.

If i were them, i would find and train good "screeners", people with talent to spot talent and just let them do the job. Sometimes they will only have a hunch, giving their observations of things that escape most people of a particular candidate, and even without much to show of, they might be right.

Later the top screener's would help the new ones to be better at their job, teaching their tricks.

This is very subjective and personalized, and even if there might be some objective ways to train the screener's better, i think its just nuts trying to use objective tests to define a good hire.

I bet with you that there are a lot of "human gold" out there that would only be detectable only when its too late for the company.


I think the issue is the filter is based on the specific algorithms and not that problem solving ability.

There seems to be more emphasis on "the candidate knew to use bubble sort" or something stupid like that instead of "I observed this candidate reason through the problem and I don't really care that they didn't know a canned algorithm".


I think a big point people miss is that you need intuition which algorithm fits where. You don't need the details of how it works, but if you have a good idea how it works you usually have a better intuition.

It's a bad proxy, but better than no proxy in my opinion.


No, that's what you assume they are looking at. You're assuming they only look at whether you properly memorized bubble sort, but in reality good interviewers don't care if you don't even finish the problem or find the answer, they are looking at how you approach the problem and your problem solving skills.

You often need strange problems to really get to see people's problem solving, which is why they're often not things you see in real life, but again, the goal isn't to see if people know how to do the strange thing, it's to see how they approach a novel problem from scratch. Aka problem solving skills.


I learned trig before I learned to program and the symbolic dexterity from trig was useful. I think kidz today will learn to program before they learn trig. I don't really have a point here.


programming and trig can be elegant. I think interviewers sometimes look for elegance. They want to believe they are hiring someone smarter than them. Elegance is one feature they look for.


An interviewer proposes this scenario: There is a school bus full of ping pong balls, all the way to the ceiling, filled from back to front. You are asked to estimate the number of ping pong balls while explaining your line of thinking. Questions are welcome--and answered if on the fact sheet.

Explaining your abstract, critical thinking process seems much more valuable. HR screens someone for having the degree, assume they are familiar with all the facts (they can use Stack Overflow when they get in). Just learn how they think and how they communicate.


HR is unqualified labor attempting to do screening for qualified one, and they tired using tests which they themselves can comprehend as proxies for intelligence.

(In past tense because this "Microsoft interview" style quiz was dropped by Microsoft themselves long ago)


Maybe it is true that you got in a line of work where you rarely need those things; And you certainly got more experience than me. But I, for one, use and profit from the way of thinking I was taught in University very regularly.


> Google and other big tech companies use these criteria to filter people out at the hiring stage, but the vast majority of work has nothing to do with any of this stuff.

Yes, because at Google & Co. you actually NEED this stuff. I am not sure there is a day going by where being strong in math and computer science isn't immensely helpful for my job.

The problem is: All other companies immitate Google, not only through interviews, but also by copying their "scalability" which is completely crazy. For instance relational databases are perfectly fine for like 99% of companies. Single servers would probably work well for another 90% of companies. Monoliths instead of micro services would work well for 90% of companies... It's crazy.


At Google & Co. you might need this stuff, but 99.9% of the other engineers at Google & Co. don't. Source: me, as I work at "& Co.", who employs numerous ex-Google staff, and have friends in other "& Co."s, etc.

What Google & Co.'s engineers do is gatekeep. Sometimes it's out of ignorance, sometimes out of inappropriate generalization of their roles to others, and sometimes out of a deep angst caused by working in roles that effectively make almost all their CS-specific trivia next to useless in practice.


I came here to make a similar point. Electrical engineers study a certain amount of physics as part of their major, but their main focus and area of expertise is engineering, and you never hear them claim otherwise. If the main focus of a training is not to become a computer scientist, but to become someone who can engineer good software for real world applications, then don't call it a science degree.

This list is, "a software engineering study plan to become a software engineer".


> Electrical engineers study a certain amount of physics as part of their major, but their main focus and area of expertise is engineering

This is good. I took the E&M course for electrical engineers at my university, a very well-regarded engineering school. I ha no idea what I was doing. After every exam, I thought I'd have to drop the course. One of my scores was a solid B, another was the third highest. I got a B because I didn't know how to do the homework. Literally the only thing I could do was get the sign and units right in the multiple choice answer.


DISCLAIMER: I'm a dropout, never finished college.

I think that a lot of the math subjects that they focus on in colleges can be of questionable utility (Much as I wish this were the case, I don't think I've touched calculus at all since I've started working, outside of the occasional personal projects doing game physics or something), but I do think that having a decent understanding of set theory and discrete mathematics has made me a better engineer, if for no other reason than it made it easier for me to pick up TLA+, which is incredibly helpful when used correctly, at least when designing/building distributed systems.

That being said, I sadly feel like that basically any math is only useful earlier in your career. If you start working for one of the big FAANG-esque corporations, you end up doing substantially less compsci and spend a lot more of your time writing emails or sitting in meetings.


Your work doesn't depend on operating systems, databases, network communications and data structures? I can go on.


Not as much as it depends on human communications, organization, self-management, etc.

Most technical challenges in my experience end up being reduced to word problems.

All of the stuff you mentioned is probably 10% of it. You can be bad at the 10% if you're great at the 90%.


Word problem? That's not a technical challenge. That has to do with writing and communications, which are ubiquitous to all types of work.

I think you're misunderstanding the premise here.


I think you're mistaking work for being puzzle-solving.

Work is always about people. If it's not about people, it's probably research, which is different from work.


Someone needs to solve the technical puzzles, software engineers are people who can do that, being good at managing things is a plus but it isn't what defines the role. There are plenty of roles at companies for people who can manage everything else but not technical things, like product manager or people manager.


Work is a function of people and problem solving. A balance between the two provides an effective and productive environment for producing good work. I wouldn't praise or idolize the notion that work is always about people.


The reduction of a technical problem to a word problem is the application of years of accumulated knowledge, including, in many cases, Computer Science concepts.


Formalizing word problems and effectively transforming it to a program is inherently a complexity theory exercise.


My experience is that if everybody who took part in the development of software at enterprises would have studied CS, 90% of the word problems would be gone. Most problems arise from the fact that actors underestimate or not understand the complexities that lie in software systems.


Well good thing you learned to read, write, be disciplined and be organized in school along side CS.


I didn't learn CS in school. I'm self taught. I'm 20 years into my career.

That doesn't mean I don't respect a CS education, but I don't think this kind of testing is a good measure of potential.


But you did teach yourself the fundamentals to do your job. So this isn't a good argument against the practicalities of applying CS knowledge in software engineering?

Everything you've listed - communication, organization, and self-management - are qualities of a strong student. These are skills from college that last. I don't know a single successful student who got by on his own or did so without being extremely disciplined. Outside of the homework/exam grind, college was far more social than work life ever was.


Lets just pretend that this is working to filter good candidates.. even then good software have a lot to do with team work. Its better to have people who are experts in things that the product need to be good at, but also less expert in a certain field but that will do other parts of the product, than you have to manage the group work properly..

My point being, you need people with a myriad of skill sets, and some of them don't even have to do with expert knowledge needed in some areas.

Also you might have an expert in storage for instance that do poorly in certain tests giving he never needed to work with those kind of algorithms.

So in the end the company ends with the same type, the same kind of person, and how can you make a great team that needs people with different skills doing distinct stuff, if you optimized your hiring to filter for one particular type?


There's a big difference between understanding data structures and algorithms and being really good at solving algorithmic puzzles under time pressure. The former is what you need to know to do your job well (and much of that knowledge is at your disposal with a quick google search) but the latter is a useless skill that doesn't help you with anything but passing a coding interview. If you want to be hired by FAANG, don't waste your time learning intricate algorithms, but simply practice to solve coding puzzles in record time on whiteboards. It's a totally different skill set.


My degree was actually called Information Technology and I will say that it has proved to be a really good degree for me. It was essentially a CS minor with some different classes on networking, security, system administration, hardware, project management, etc. I would say I'm better off career-wise because I did that instead of Computer Science. I was even almost not considered for a job because of it, and I turned out to be a really good fit for that job!

That said, and admittedly I have gravitated to niches that might be more computer science-y niches at points in their hype cycles where lots of research was being applied, but I have occasionally wished I perhaps also had a stronger academic basis in computer science. In distributed systems, people are still writing new schedulers, and I wish I had taken that operating systems class when you had to write one. I don't always understand what my colleagues are talking about with some of the newer functional programming features popping up in languages. Stuff like that.

I do agree there's a disconnect between what universities deliver and what people expect of them (paths into academic research vs. career preparation) and I think a Bachelor's degree is overhyped for that. But I do think you're understating the role of CS theory and fundamentals in high-level software engineering. Just because you don't use many of the lessons does not mean they haven't improved your ability to think, and the general base of knowledge on which you're able to build.


Most places will also probably have you spending a good chunk of time maintaining legacy code rather than inventing entirely new business units / products / platforms. I can't imagine what the maintenance burden is like at huge companies for existing / mature products. Anyone care to shed some light?


I'm of the opinion that university trains you to reason better about problems and sharpens your problem solving skills. Especially complex problems. So although you might not always encounter the exact academic problem in your day to day work, you still unconsciously use the tools and techniques learned.


What differentiates a real career professional with someone who just "learned how to code" IS the fundamentals like Data Structures, Algorithms and their underlying math fundamentals.

Sure, you can become a "senior" engineer even at a big tech company if you take a more product-focused track, but even there your lack of mastery of fundamentals will eventually limit and stunt your career growth, because those around you at the same level will have that deep understanding and knowledge to pull from when they actually need it for their job.

Notice I didn't say this requires a COLLEGE education, I've met plenty of amazing, very senior engineers in my career with no formal degree or college education, but they sure as hell understood all the underlying fundamentals and theory of their field better than most.


As somebody who just "learned how to code", i oversee architecture of all products in saas company that just crossed 1B in sales.

At this level, nobody cares about fundamentals in 99% of companies. Also nobody cared about my lack of mastery of fundamentals during my career. If anything, people were bringing me into companies due to me having "out of box" vision and ability to see the big picture and not getting stuck in details.


> I studied computer science, and in 30 years, I've hardly used any of it.

Here's one way to look at it: I wear my seatbelt every time I ride in a car, but I haven't been in a serious accident in over twenty years. Does that mean I shouldn't have bothered?

Knowing things allows you to take an opportunity when it presents itself. It's really hard to know what opportunities are going to show up or which doors will be the doors that you want to walk through. But having more of those doors open is generally a good thing.

Of course, there is an opportunity cost to the time spent learning CS versus other stuff you could be learning. But, personally, I've found the CS stuff I've learned to be both personally rewarding and often helpful to my career in unexpected ways.


> I studied computer science, and in 30 years, I've hardly used any of it. There were a few jobs where some of the statistics and math were helpful, but in my long career, I've seen very little overlap between computer science and working as a software engineer.

I'm not challenging your experience, but I am replying to say that mine is the opposite. I certainly have used quite a bit of theory (over a little more than 30 years), not so much explicitly as to think about the problem I'm working on before starting to code, or in the process of discussion about some code with coworkers. Also has helped me look stuff up or learn new things.

Perhaps you've used it more than you think, but merely subconsciously?


It pays off in interviews to drill that stuff. If you want to be good at your job though, you just need to write a lot of code and understand design and architecture. The best book on this I read recently was “game programming patterns.” Ive had cause to use about a third of the patterns in the book in the last year alone, and my code base got simpler and easier to modify each time. Big payoff. Don’t read it start to finish though, use it as a resource for when you get stuck

http://gameprogrammingpatterns.com/


Reading and reviewing code: getting a feel for performance, appropriate use of data structures, implementation strategies, etc. As you get more senior, you spend more of your time reading code and are expected to offer insight and mentoring.

And, there is always pride of workmanship. There is a lot of beauty and elegance in computer science, appreciation of these things can have positive effects on morale, implementation quality, maintenance, and performance, and teamwork.


Engineering is about learning how to learn. It's a skill you should use every day.

If all someone knows is plumbing API and rote memorized glue code, don't expect much. If someone went through CS, expect to see a different caliber of work for the same task.

Believe me, it's night and day and a lot of orgs have no clue what real engineering talent looks like: they never had any to begin with!


> If someone went through CS, expect to see a different caliber of work for the same task.

I disagree. See: hordes of new CS graduates that feel they are completely unprepared for an entry-level software engineering job, or their interviewers.


There's often a gap between what the employer wants and market reality.

The employer really expects devs to be productive on day one and not have any training to do. Often they whine that a CS education isn't more like a bootcamp. But that's not how it works.


I've really only used dynamic programming once on a real problem, but I have to pick the right data structure all the time and at least think about the algorithm. I've seen people write code that's anywhere from n^2 to exponential, only to see it fail pretty hard when working on production data.


It's like the difference between knowing the theory behind combustion engines and driving a car.

But that being said... there are many different types of engineering jobs. If your company deals with low level stuff, requiring low level knowledge is acceptable.


> but the vast majority of work has nothing to do with any of this stuff

Like, it doesn't until it does, and when it does, it really does.


I think it honestly depends on what you do. I use data structures all the time; I just don't have to implement them.


This on cue comment is quite trite, IMO.

I went through school and did just okay in CS. 12 years later, I’m much more interested in topics within CS that felt like chores for my degree.

In the context of getting a majority of job, yeah, it’s not great. In the context of being a better programmer, I think it’s worthwhile to understand the “pillars” on which you are building your “house.”

HN has an interesting dichotomy of love for all things CS and hate for anything that involves interviewing.


> and in 30 years, I've hardly used any of it.

So you don't see the sine in the sky from sunrise to sunset?


i do really resent when people provide constructive-criticism laced just with criticism and nothing constructive.


Spoiler alert: https://medium.com/@googleyasheck/i-didnt-get-hired-here-s-w...

> Last week I received a rejection email from the recruiter, and at first, I thought it was a mistake, and laughed it off. I checked in with my referral and he inquired into it and lobbied on my behalf, but in the end, it didn’t change the situation.... The thing that bothers me is that I didn’t even get a phone screen. I didn’t even talk to a recruiter over the phone. After all this work and enthusiasm, I didn’t even get a chance to prove myself.... After speaking with some folks related to Google, the best I can determine is that they decided to pass because there wasn’t a good fit on any teams where I might be qualified. This is in agreement with the rejection email I received — there were no roles fitting my experience and background.

> I’ve been hired as a Software Development Engineer at Amazon!

Assuming you can get to the actual interview stage, the fastest option is to prepare by just grinding leetcode to maximize your chances of passing the interview. That won't help with aspects like the system design or behavioral interviews, but grinding leetcode will give you a better chance of passing the coding interview compared to studying CS theory.


> but grinding leetcode will give you a better chance of passing the coding interview compared to studying CS theory

It may surprise you to know that any LeetCode question can be easily answered by those with a solid education and background in computer science. Ironically enough, because this mindset is popular within the industry, you end up with quite a few interviewers who lack the ability to understand any solution they have not memorized. It's always fun reading posts of someone failing an interview because they gave a more optimized solution, which was different from what the other guy in the room had, and couldn't be convinced he was wrong because he didn't understand how mathematical proofs worked.

Discrete math, basic linear algebra, and a few mathematical concepts in computing, generally cover all the possible questions you can get. What I like to do is quickly scroll through all the LeetCode/HackerRank questions, identify which ones I'm unable to quickly label with the type of math to be used, and then learn that math subject/topic. It takes me more time learning the math/theory, it takes me longer still trying to memorize every possible solution out there.

Spend on the history, end all the mystery. Or just keep trying to collect all the rocks in the world.


I hate to nitpick, but your use of 'spoiler alert' here made me believe there might be some clever deception in the article, but he got hired at Amazon _after_ the Google rejection. this is slightly misleading.


It's a little frustrating how random the process is. I'd consider myself to have a decent resume for an undergraduate. I've interned at a "big N" so to speak, I've done side projects that are relevant in my field of interest and I'd consider myself to have amassed some domain specific knowledge. Yet my resume gets random rejected/ghosted from a remarkable amount of places. It's especially bad when I don't fit neatly into a category for recruiting. So many places wouldn't hire me because apparently "I want to work during COVID cause online school sucks" is too confusing.


You're currently still an undergrad ? That'll be why. It's obvious you'll likely leave a job when you go back to studying.


Yes, but it's frustrating that a lot of companies aren't willing to run internships over the spring or fall


If you want to do temp work then go to some contracting agency. Good companies want longer term commitments.


"When a measure becomes a target, it ceases to be a good measure."[1]

These coding challenges used to be a very good measure of ability, but now applicants are just memorizing the most common problems for each company. We're not at the point where these tests are useless but we will get there in the near future. The problem is that I haven't seen any good alternatives.

[1] https://en.wikipedia.org/wiki/Goodhart%27s_law


> These coding challenges used to be a very good measure of ability

I'm skeptical. The stereotypical interview question involves reciting algorithms from memory, where the thing you actually want to know of a software engineer is do they appreciate how things fit together to meet the constraints of the project.

> The problem is that I haven't seen any good alternatives.

Something we've done before (and had good success with in hiring good candidates) has been to pose a real problem we're dealing with now or have recently solved (so the solution and problems are fresh in the reviewers' mind) and ask the candidate for their solution at a high level. Not whiteboard coding, though. Something like if I tell you we're trying to filter out strings that contain creatively obfuscated obscenities, what should we do in order to maximize true positives while minimizing false negatives (and as the candidate offers solutions, provide sample strings that would fail their solution and see how they adapt)?


Do you mind if I ask what company you're with? I'd love to put it on my list of companies with good interview practices that I would want to apply to. If you're not comfortable with getting that specific, just for my personal curiosity, is it a FAAMG/big tech company, or other? haha :)


It's definitely not silicon valley. Small European tech company, very much just making things up as we go.


The best coding challenge I had to do was when the company basically gave me a set of requirements, said build this. Took about an hour. Then during the interview, I was asked about my decisions, and blockers. Afterwards I was given another feature to add. This took another half an hour.

I wish more companies would do this. The hardest part for me at least is staring at a blank document.


different companies need different skills and it changes even as a company grows. Part of the frustration about this entire process is that it feels very cookie cutter and sort of like a lowest-common-denominator type effort on behalf of companies.

Huge companies like google are for the most part hiring people they can slot into almost any team in the org so it makes sense for them to place less emphasis on tooling expertise. They have plenty of time and money to upskill employees.

The same can't be said for the vast majority of consumer start ups that really just need people who can rapidly prototype.

Of course those groups are not mutually exclusive, I just think it's sad that everyone has adopted the approach that works for a select few companies


The same can be said for the SAT. Unfortunately there seems to be significant enough overlap between "good test taker" (or in this case "good interviewee") and "good worker".


Studying for the SAT won’t actually improve your score much on expectation, but taking it multiple times of course will increase your expected score (since they take the max).

SAT is basically an IQ test, which is of course a reasonably strong predictor of white collar job performance (ceterus paribus).


I don't think its 'of course'. A study at the UofIowa showed only one correlation between tested psychological features and job performance (as measured by 1-year evaluation). It was 'conscientiousness'. That is, if you kept at a task until it was actually and fully done, your boss/coworkers valued your contribution.

That's it. Not about being smart or educated.


The conclusion of this IQ vs job perf paper is “it’s complicated”, but essentially every meta study they cite is pretty unequivocal that IQ predicts job performance. https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4557354/#!po=0.... The only room for doubt is in confounding effects like the fact that people with higher IQs are likely to enter more mentally difficult professions.


I agree that the predictive power of jeopardy-style interview questions has collapsed. However, I think it’s still quite predictive to ask more design-oriented and less algorithm-oriented questions, especially if there is some leeway for creative choice. It’s also relatively easy to detect people who have simply heard and memorized the question, since when you ask them for extemporaneous expansion on some aspect of the question, they usually fall apart.


From scanning through the course outline, the big omission is learning about distributed systems, and industry leading implementations of common tools.

At big tech companies, you typically have to work at a much larger scale. A solution that works, won’t necessarily work at 10x, 100x, 1000x the scale. You often need to use technologies architected differently than a monolithic Web App.

I would recommend learning more about the commonly used “tools” that a distributed systems engineer would use, more specifically:

- Load balancer - Nginx

- Key/Value storage - Redis

- Pub/sub - Kafka

- Queueing - SQS

- Map/reduce - Hadoop, EMR

- Databases - SQL


There's a different "knowledge" problem that must be tackled here.

Someone can form a cognitive bias from only being exposed to a few ways to solve a problem. Maybe it's because they haven’t seen it to larger scale, or that they only worked with monoliths, and thus are limited to only that problem scope.

Throwing more MySQL databases at a problem won’t fix all problems, but for a lot of people, this is all they know. How do discover those unknown unknowns, to learn the applications of tools you haven't yet been made aware of?


As a software engineer, you have a professional responsibility to stay abreast of current technology. That doesn’t mean hopping on every latest JS fad, but it does mean continually looking for more information, and learning how others in the field are solving problems.

Physicians have to keep up their board certifications/licenses by undergoing yearly(?) retraining, in order to continue practicing medicine.

It’s not that hard to find what other software engineers are doing, to start, Read hacker news! Talk to more experienced engineers, read blogs, as an intellectual exercise, surf through AWS services and think about how you could use each.


No it's not. A formal computer science education at least mention and cover the problems these tools are solving. And for those who want to solve these challenges, they take graduate courses.


These I expect a real software engineer to be able to learn pretty quickly.


Why not Kafka for Queueing?


The most important thing on your path to becoming a software engineer is building stuff, improving it, releasing it, and thinking how you can do it better. Having been through the lifecycle of a piece of software from design to maintenance will also provide a wealth of experience.

I understand that it's popular to let people solve toy problems during interviews, and think that's ok for people coming out of university. However for more senior roles I would rather hand out a coding assignment. You can judge the experience of a developer much better by the way she/he chooses algorithms, considers corner cases, supportability etc.


I strongly agree with this point. Most of day-to-day problems in software engineering / craftsmanship (i.e. the work most people are paid for in this industry) are not computer science problems, they are about the process of understanding your user requirements, iteratively improving your product, achieving and maintaining the appropriate level of quality, and the meta-cognitive skills around identifying when you just need need to fix a bug vs. step back and look for a way to improve your tools.

You will get some transitive learning of some of these things if you do lots of coding challenges, but I personally found a huge benefit in my formative years from building a single full-stack application over many months, much more than solving simpler day- or week-long standalone tasks.


The problem is more and more companies will not let you have a chance to do any of the above without first jumping through the fiery blazing hoops that comprise of solving the "toy problems" of a typical leetcode technical interview.


Studying theory to become a SE is one thing. Being a SE is another thing. Being able to communicate with your (tech or non technical) colleagues in a constructive/useful way is also another important thing.

What I have seen is that a lot of software engineers lack communication skills. Being able to deal and communicate with other people, feel empathy, see things from their perspective, deal with non technical POs or managers, crazy CEOs, offensive colleagues and all sort of things is something that should be taught before you enter the market somehow. And when I say "deal" and "communicate" I mean it in the most fruitful way for you, your colleagues, the company. In that order.

So "being" a SE is not only knowing the theory.


Let us use machines and mechanical engineer as an analogy.

These days, you don't need to be a mechanical engineer to operate 'most' machines.

Will being a mechanical engineer help if the machine breaks down? Yes. Will there be some machines that only a computer engineer could operate? Yes. Will there be come cases where being a mechanical engineer make you a better machine operator? Yes. But do you need to be a mechanical engineer to operate most machines? Answer is clearly no.

We are at the point where that analogy carries over easily to computer science and coding. Yes, there are many cases where knowing computer science will be essential to extremely helpful. But for 80% of the coding jobs, you don't 'need' to know theoretical computer science.


So funnily enough, my bachelor's was in mechanical engineering and I'm currently pursuing a master's in computer science after having worked in industry for a few years. While I think I agree with your point, I'm going to nitpick on your analogy.

A mechanical engineer will probably not be called upon to operate any particular mechanical device. They will be called upon to either design or maintain it, both of which will require substantial mechanical engineering knowledge. Operation is a totally different thing for a totally different group of people. Think of the difference between a frontend developer and someone who might use wordpress or wix.

Having said that, you hear the same complaint from mechanical engineers as you might be seeing on any hackernews thread about interviews and hiring - no one ever uses the academic knowledge in real life. And this is true, I've never had to use a Bode plot or whip out a stress-strain curve. But I've had to work with technicians and while several are very intelligent and capable, there was a noticeable lack of refinement in their thought process or lack of breadth. I suspect it's the same thing with programming jobs (although I haven't had one yet, so feel free to call me out on it). Knowing CS will help give context that allows for a more refined programming acumen. Is it necessary? Probably not. In my engineering case, both technicians and I did our jobs equally well, although I often had more responsibility. But if your brand is to have culture of incredibly deep thinkers, you probably want to interview for this quality.


I think we are in general agreement. While self taught developers have been around from the beginning, until a few years ago, most companies wanted only those with a CS degree regardless of what they were to actually do. DB admin - CS Degree; maintain a Wordpress site - CS degree; write ML algorithms from scratch - CS degree.

It is changing now. Don't get me wrong; I see the value in CS knowledge having spent a lot of time learning it though never for any degree. All I am saying is that we need to recognize that a job requires a specific skill set and theoretical CS may not be it.


This is a good starter list for the more Computer Science skills but I see little in the way of practical skills. It's definitely nice to have these skills but let's be real, you aren't going to use them on a daily basis.

I would add learning a few of the most popular languages and frameworks depending on your area of interest.

Without those practical skills I'm pretty sure you will be passed up during interviews.

When hiring, I look for people who can get stuff done first and foremost. I don't care if they have to look things up and don't have things memorized. Efficient "stack overflow driven development" is real world development.

Then if they have those skills I look to see what kind of theory and architectural understanding they have. Those are secondary.

The more senior the candidate the more I expect them to have CS and architectural background so I would normally forgive not knowing the CS theory stuff for junior developer candidates.

But practical "get it done" skills in the relevant language and frameworks are a minimum requirement for everyone.

One other thing that I would add is to customize your study plan based on where you want to apply. Startups will favor more practical skills during the interview. Larger companies and enterprises will favor more of the traditional CS during interviews.


> It's definitely nice to have these skills but let's be real, you aren't going to use them on a daily basis.

I mean, practice for the job you want.

The majority of software jobs don't need this stuff -- writing frontend code, writing some backend services, mobile.... the type of work where you a) aren't building the platforms / tools everything is based on b) don't need the best performance, just need it to work OK.

But there are plenty of jobs that do need this stuff. Working on an OS, or database, or a product used by millions, or a large scale platform...



> ...This is meant for new software engineers...

Do these big companies really need so many developers that only know how to use this long list of 'fundamentals'?

I've interviewed a lot of people of all ranges, ages and skews. No matter what, when it comes down to sitting down with them and asking them to write out a simple program without any technicalities, 9/10 of them fail due to clearly not spending enough time just making things.

Are these big companies _really_ hiring juniors with this as their laundry list?

> ...Write code on a whiteboard or paper, not a computer. Test with some sample inputs. Then test it out on a computer....

A junior to me who has spent a year banging away making real failing programs and can talk about what and where they struggled with is useful to me(and the company).

A junior who hasn't built a single project, but can tell me about the one time they spent 4 months writing data structures on white boards is little more then a warm, but dead silent body in a design meeting.


I think the whiteboard advice is for being comfortable in interviews.


Google expects you to write production ready code in a Google Doc for two Leetcode hard problems in 40 minutes.


This is a bit off-topic, and is probably a naïve question, so forgive me in advance for both.

I've always been under the impression that "engineer" was a protected professional title, just like "medical doctor" or "lawyer", at least in part because there are certain legal responsibilities that come with the title. It's thus a little confusing to see the title being used, here on HN and elsewhere, by self-taught folks who have not gone through any formal education or professional accreditation. In fact, it seems that "dev" and "engineer" are used essentially interchangeably, only sometimes depending on whether the particular employment involves actual engineering.

Does this mean that "engineer" is no longer considered a protected title? Or are software engineering and development (in the real world) considered so similar as to be indistinguishable? I'm asking out of genuine curiosity.


The National Society of Professional Engineers has managed to claim "Professional Engineer", "PE", and "EIT". They also have claim over "engineer" when used as self-promotion as a business or an independent contractor. However, they weren't able to have the claim on it as a job title stick. So, assuming you don't have PE quals: your consulting firm could not be gwerbret Engineering. Your job title at Microfang could be Software Development Engineer.


I got my engineering degree almost 30 years ago, and at my first job was working with other "engineers" who did not have a degree. I was dismayed at first, but got over it.

I think it only matters if you're offering services to the public as an engineer, or if you're doing public-works projects. Then you need to be licensed as a Professional Engineer.


>I've always been under the impression that "engineer" was a protected professional title

Based on what? I always thought it was well known that there is pretty much no such thing in the IT world, and beyond that, Americans tend to as whole disdain the old worlds fascination with titles and the people in America who use and abuse them (lawyers are some of the shittiest people)... so perhaps you aren't American?


What is the relationship to Google, mentioned in the title here? Cannot find any reference.



This sort of stuff is meant to leave the anarchists and the rule benders out of the company.

Its requires certain psychological threats to by guided to memorize and do all this stuff.

I bet a lot of people with the actual right skills would not pass into those exams.

It reminds me if a great lesson from the prince from Maquiavel, where he speaks about what sort of soldiers should be used and say that the mercenary soldiers should be the last resort, because giving they do not really believe into what they are doing, in the battle field they wont make the best soldiers.

Well, the filtering here will optimize for people willing to force themselves into this for a good salary, of course they can by chance get the passionate type, but they are not optimizing for it, and that's the point.

I rather work with people that are passionate about it, they are the ones that do the "impossible" things because they dont just do what they are told.

And this kind of people will at a certain point in their lives have nothing to show. But the curious, the creative, the people that learn fast, that are always hungry how can a company get them through this?


The big tech companies' hiring needs are so massive they'd go out of business if they relied on hiring only "passionate" people who are up to their standard.


> I studied about 8-12 hours a day, for several months.

He lists 8 months of study and that before starting the curriculum he was "self-taught" meaning he at least knew how to code and do a little more than "hello world".

If we add his "self-taught" time it gets us pretty close to an actual CS degree. He's missing language classes, some electives, math and stats but he's mostly there in terms of content. He's missing labs, projects, problem sets of course.

When viewed like that it doesn't sound as clickbaity as the tittle implies, that you don't need a degree to go in the field. He's just a really really motivated self learner. And almost got a CS degree's worth of material.

Kinda like Gates "dropping out" a few credits short of getting his diploma, not after failing intro to econ like a lot of "drop out entrepreneurs" out there.


I have been looking for work recently (frontend/full-stack) and have been pleasantly surprised, all my interviews so far have been fairly practical React, JS, CSS questions. I spent a month leetcoding and reading Cracking the Coding Interview also. 8 months of focused work on interviewing seems... insane haha.

That said I do feel smarter for having refreshed my knowledge on BST, linked-lists, etc. I don't know if there is a better way to interview, the algo/data-structure stuff will definitely reveal your ability to stay calm and problem solve though. A tricky tree or graph problem will also reveal how strong your mental context and ability to visualize code in your head is.


I would say that's definitely a study plan for learning key CS concepts, but not necessarily a plan for becoming a software engineer. Those are two very different things.


I used something similar to this as well as Khan Academy to learn CS, when I transitioned into software engineering, after being laid off at my previous position in a different industry.

It’s possible, but it takes work. I also benefited by contacting my peers from college on LinkedIn and getting referrals for interviews. Even though I didn’t major in STEM originally, I still ended up connecting/befriending many while in school. I would encourage you to try to utilize resources like that as much as you can.


If you are a CS graduate, it is up to you if you want to use what you've learned in the field. I've found that it is a useful perspective, sometimes it is overkill, but it's better than any testing sometimes.

Software engineering is all about making that domain knowledge useful. So sometimes you can just be lazy and "import" the knowledge.


Because I saw it was not mentioned yet. There is also a very good study path for game programmers.

https://github.com/miloyip/game-programmer


This is an algorithms crash course for people interviewing at Big N.


Netflix?


Big N for all N in Facebook, Amazon, Apple, Netflix, Google ...


I don't think Netflix actually belongs in there, it's just that if it weren't the acronym would be FAAG, and if you say you want to work for a FAAG company people will assume you're talking about Grindr or Mozilla or something.


Netflix is in there because they pay as much as or more than the others in that acronym.


Netflix surely is here because their pay is in par with Facebook/Google.


FAAMG?


why people always talk about those "data structures"

and in reality they have basics in mind?

Seriously when you've been writting any software for e.g >1 >2 years then I'm pretty sure you must've been using almost all of them

who cares about details of complexity when very often just pick of the correct one (that suits the problem) gives massive boost.

Ofc you may need sometimes something trickier, but hey - there's time to find it.


Was there a similar flurry of "how to ace the finance interview" in the 80s and 90s when everyone wanted to be a stock broker?


Godbolt (CS61C should probably have a Godbolt lab.)

Coursera Fundamentals of Parallelism on Intel Architecture

Emphasize STL, Boost, OpenMP, MPI, NUMPY, containers, ...


>CS 61C

Why do you guys refer to topics/branches of CS by course name at your higher edu institution?


Why the random "Google" in the title?



That doesn't really answer the question (also I see that the title is fixed)


Sorry, the idea is that this guy made a repo for how he wanted to study to get hired at google, and now it seems that a lot of people are contributing. I removed the google part from the title as i see now that it might have been misleading.


for a non-cs major with a quantitative background such as math or physics, would it be more prudent to study algorithms or gain actual programming skills in order to secure a job prior to graduation?

of course, actual programming skills are necessary, but it seems they can be learned after securing an offer.


The question is not to become a software engineer. The question is how to change the world.


Don't you feel this learning path makes you a cookie cutter SE?


clickbait title, this has no affiliation to google. edit: title changed now.


I removed that part as i saw it's misleading




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: