I feel uncomfortable admitting that when I got my job at Microsoft in 2005, I didn't know how to implement BFS (Breadth First Search). At that time, I was six years into my professional software engineering career and held a master’s degree in Computer Science.
I still didn't know this a few years later when, one day, during lunch, someone mentioned that the candidate they had interviewed earlier "didn't even know how to find the shortest path in a graph." This made me feel horrible - I knew I couldn't do it, too. In a few seconds, I turned from a seemingly successful Software Engineer at Microsoft into an impostor. This incident prompted me to improve my Computer Science fundamentals.
While I eventually learned BFS, my example shows that making solid progress in the software engineering career does not require knowing Introduction to Algorithms (a.k.a. CLRS) by heart. This is even more true today than it was twenty years ago. These days, we are working at a much higher level of abstraction. Most common algorithms, like binary search, are included in standard libraries, and implementing them is a waste of time.
Despite this, I urge every developer to learn the basics of Computer Science.
Why learn Computer Science fundamentals?
The answer is simple: learning Computer Science fundamentals can boost your career. Here is how.
You will understand unfamiliar systems quickly.
Once you learn the basic algorithms and data structures, you will see them everywhere. You will realize that HTML and XML documents are trees, key-value stores can be conceptually thought of as HashTables, and that from a single consumer perspective, Kafka topics are queues. This is powerful as it allows you to understand the behaviors and limitations of these systems even if you don't know them deeply.
When I first started using git, I felt overwhelmed. I couldn't understand how it worked, and the commands didn't make much sense. One day, I watched yet another git explainer on YouTube, and it mentioned that git is a DAG (Directed Acyclic Graph). Overnight, I became a git guru fixing team members' repos.
You will be able to solve challenging problems.
Most of the problems software developers deal with day-to-day don't require advanced computer science knowledge. Once in a while, however, a challenging problem pops up. This is when knowing algorithms and data structures can be very handy. I remember struggling for a couple of days on a dependency graph problem when my co-worker pointed out that I could solve it quickly if I applied topological sorting.
You will do better at coding interviews.
Many interviews, especially in Big Tech companies, include coding questions. Usually, these problems can be solved with one of the standard algorithms. If you are familiar with them, you have a better chance to do well during these interviews.
How to keep skills up to date.
Most skills degrade over time. Algorithmic skills are not different. Even if you remember the idea behind an algorithm or a data structure, the details can get hazy with time. This is why it is good to refresh your skills periodically. There are many ways to do it. My favorite is participating regularly in Advent of Code. Advent of Code is an online event in December where you are presented with two problems every day until Christmas. Solving these problems is a lot of fun and allows me to brush up on my algorithmic and problem-solving skills. But the best part is Solution megathreads - dedicated subreddits where others post their solutions. I check these threads once I solve the problems for the given day. They are a trove of startling insights, unconventional approaches, and programming tricks I would never think of, and I learn a lot from them.
Image: https://cs.stackexchange.com/a/107190
💙 If you liked this article...
I publish a weekly newsletter for software engineers who want to grow their careers. I share mistakes I’ve made and lessons I’ve learned over the past 20 years as a software engineer.
Sign up here to get articles like this delivered straight to your inbox.
Top comments (35)
I disagree!
I'm a CS grad student, university topper (100% scholar), proficient in C++, JavaScript, TypeScript, and many other languages.
You can check out my GitHub to verify my skills.
While the fundamentals are useful for developing hardcore systems using networks or OS, they may not be as crucial in general cases.
Neither my college nor my degree taught me how to write code with good architecture and system design.
I do agree that it improves the intelligence to solve problems in a better way.
But it's not mandatory at all.
I think there is still a fundamental issue on how CS is perceived and what people expect from it. Computer Science is primarily not about writing software but, as the name implies, a science. The goal is not for graduates to necessarily become great software engineers.
There are Universities that understood this issue and splitted into Computer Science (lots of theory, algorithm design and verification, lots of maths, science methodology, computing, conducting studies, formal validation etc.) and Software Engineering (applied science, creating software on a professional level, knowing algorithms and which ones to use when / not, software architecture, patterns, design, more empirical work etc.)
Many Universities and Colleges still have no distinction between them so it's up to you to check their curricula and see if the education will match your future career expectations :-)
wow! this is a good one! seriously great point @jankapunkt . I think it's the same difference between pure mathematics and applied mathematics: there is a clear separation between abstract concepts and the application of those concepts to real-world industry. this separation is not well-defined between computer science and software engineering.
As I mentioned in the article, you can get quite far without solid fundamentals. But from my experience, these fundamentals are extremely useful if you want to tackle bigger problems, and they don't have to be network or OS-related. For instance, I worked with trees on every single job, so DFS and recursion were our daily bread.
Clean code and good architecture are mostly orthogonal to CS fundamentals. System Design isn't - if I need to design a system for geolocation, I probably need to be aware of quadtrees.
the reason you can "get quite far without solid fundamentals" is because very few software shops have the scale, traffic, or unique circumstances that even demand solid fundamentals. the majority of software shops can get by with poor fundamentals, which is why CS fundamentals are not terribly important. they are important to an extent, and they are valuable in narrow contexts, but in the grand scheme, CS fundamentals aren't nearly as important as people want you to think. the average developer doesn't even have the liberty or political leverage to design systems and architectures. 99% of the time, code must conform to the existing pile of garbage.
I do not think the article was saying that it was mandatory.
Also, in my perspective, you are being contradictory. To say that the fundamentals are useful and say that you disagree with the post that says "fundamentals are still important" does not seem accordingly.
I think that you are implying that CS is useful, but not mandatory. And I don't see how that can be in disagreement with the post. It was a complementary opinion.
Also, the post was not about having a degree. It's about studying the fundamentals.
Yeah, I actually said this after reading the comment. (whatever came to mind)
I know the article didn't imply that. My mistake!
You seem to lack basic reading comprehension skills. Nowhere in the article was it mentioned that those skills were fundamental: if anything, the author stated quite the opposite. Important != fundamental.
totally agree, @anmolbaranwal. real world scenarios and job duties rarely demand CS fundamentals. it's important, but sadly, it's not that important. really.
When I first started my degree in computer science, one of my first teachers provided helpful definition of computer science. Here is the definition:
Computer Science (or informatics) is the study of algorithms and data structures, and:
Courses of study which emphasize point 1 over 2 and 3 are usually called "computer science." Courses of study which emphasize point 2 over 1 and 3 are usually called "computer engineering." Courses of study which emphasize point 3 over 1 and 2 are usually called "information systems."
So, computer science fundamentals are all about algorithms and data structures. This is a rich field of study, and the well-spring from which flows all kinds of insights and helpful problem-solving tools. But concerns from the other areas become important, too, once you take a job, and work alongside real people, from many other walks of life and who have different experiences from your own!
I found that once I started working, there were so many other things in which I had not received formal instruction, such as source-code control habits and systems and the soft skills of working collaboratively.
But none of the rest of that stuff matters without the solid foundation of algorithms and data structures: they are a crucial springboard into making things happen in the real world.
Also, once you start working, it is also possible to keep on learning, and to review, strengthen, the areas where you felt weak or which only got a light touch in your formal schooling. Learn how to learn new things and to strengthen those areas where you are weak. Pick a topic and start reading about it. If you're reading a textbook, try to work through the examples on your own before reading ahead to the author's answers, and then work lots of the exercises. This is painful at times, but can also be rewarding: when you're not in school, you're not forced to hurry to an answer and move onto the next problem in the hopes of maximizing a test or homework score. This takes some of the pressure off! There are wonderful sites, like math.stackexchange.com, etc, which can help when you get stuck.
In summary, learn how to learn: then books like David Gries' The Science of Programming and Charles Pinter's A Book of Set Theory can open up a whole new world for you, and help you to build new skills and insights to the job. Then you can move onto weightier tomes, too, like Knuth's Art of Computer Programming, etc.
This is solid advice! I loved the paragraph about learning, which mentioned that learning complex topics is often a struggle. Also, thanks for the book pointers. I haven't heard of the first two, and will check them out.
Such a great article. I recently interviewed with one of the big tech companies and they tend to dig deep into candidate's CS fundamentals. This article reinforced why I should master CS fundamentals and brush up on those concepts periodically.
I am glad you liked it! In the meantime I wrote two more posts that are follow ups to this one that you might find interesting:
Thank you for sharing these posts! I have read part 1 before and will surely check the part 2 as well.
Could not agree more.
I also want to add 1 important benefit of knowing the fundamentals, especially the algorithms. That is we can quickly know a solution is scalable or not based on the complexity. For example, an algo that is O(users^2) may not be scalable enough for any growing business with tens of thousands users or more.
Totally agree! Not only when interviewing, fundamental knowledge of computer science helps me a lot in my daily work.
Excellent article! One concern I have is that many fundamental data structures and algorithms are already implemented in numerous languages, which can sometimes feel like reinventing the wheel.
If available, you almost always want to use the version from your library. The chances that your implementation will be better or more thoroughly tested are slim. It is still worth implementing these algorithms as an exercise. It will take your understanding to the next level.
The intro of this blog has my heart
I agree, but. Although it is important to know they exist and their purpose, very few of the CS concepts and algorithms learned at university are employed daily. They might be fresh in the mind of new graduates but those of us who graduated more than a decade ago have to look things up to recall the detail.
I have found that interview panels seldom take this into account, expecting candidates to be able to recant something like Dijkstra algorithm verbatim, as if it were memorised only weeks before. Those of us with a few years experience, might have to delve deeper into our memory to recall the exact details. But why do that in the day job when we have the internet or, dare I say it, find a book to look things up.
Any company that asks Dijkstra, Kruskal's, or A* during interviews will have trouble filling open positions. These algorithms are useful to solve only a narrow set of problems. However, tree traversal or backtracking are far more common, and knowing them can pay off.
I think it's by design. CS fundamentals are a gatekeeping device to surface young, fresh minds. it doesn't have much to do with your ability to apply the CS fundamentals. it has more to do with what you alluded to: a new graduate will be more familiar with CS fundamentals.
think of it this way: if CS fundamentals were employed daily in real world business, then interview panels wouldn't even bother with CS fundamentals. they only bother with them because it shows you recently graduated, and they would rather hire new, impressionable graduates. those with battle scars and real-world experience (beyond just writing code) are wise, worldly, and refuse to put up with the nonsense.
I also agree (in theory), but not completely. in a professional environment, knowledge of CS fundamentals and understanding what makes a framework bad is only meaningful if the entire team values craftsmanship and quality software. otherwise, your just fighting an uphill battle.
I agree CS fundamentals has helped me think differently when it comes to solving problems. The reality in my point of view is that most developers that I have worked with don't keep up to date with currently tech and frameworks that they work with. For those who do then going deeper on fundamentals should be beneficial.
In regards to topics, what do you consider are the main ones for CS fundamentals?
I am planning to write a separate post on this, but here is what I think is important:
hashtables, trees, BST, sets, stacks, queues, heap, graphs, DFS, BFS, recursion, searching (binary search), sorting, bitwise operation. You wouldn't implement most of them these days, but many types in your standard library rely on them (e.g., std::map uses BST under the hood - if you know this and know BST, you immediately know the runtime complexity of basic operations like add, find, remove)
Now, depending on your work, you may need to learn other algorithms - frontend work requirements are different from systems engineering.
Here is the first post on this: - When was the last time you used this? - Part 1: Data Structures
And the second one When was the last time you used this? - Part 2: Algorithms
yea most developers you work with don't value CS fundamentals, and this is a big part of the problem. it really only matters if it's a team effort. this is how CS fundamentals kinda backfire. you start stepping on everyone's toes and soon they want to crucify you. it's an uphill battle when everyone isn't on the same page, and sadly, few devs are on the same page.