Software development may feel like a bit of a race to keep up with new technologies.
There's always a new frontend framework to learn, or a new database or language that's a variation of another language. It's never ending and feels like you always have to keep up.
But it doesn't have to be this way.
Everything is Built From the Fundamentals
If you learn the fundamentals, then everything else will become easier.
For example, if you learn how the TCP/IP protocol works, then from that you can easily learn all the other protocols that are built on top of it.
You're essentially having to cover less ground. The more fundamentals you know, the less you will struggle learning new things.
I believe there are 10 core subjects which, if you learn them, will give you a solid foundation.
Why Should You Learn These Key Concepts?
Learning the fundamentals will really put you in the top 5% of all programmers.
If we look at it from a different perspective, here's a great quote from Ras Bodik.
Don’t be a boilerplate programmer. Instead, build tools for users and other programmers. Take historical note of textile and steel industries: do you want to build machines and tools, or do you want to operate those machines?
But There are a Million Different Courses to Choose From
Well, look no further.
Below, I've compiled a bunch of helpful resources on each subject – with some alternatives, of course. So you can focus on learning and not on mindlessly researching which books/videos/courses are the best.
A few notes
This article is well-suited for self-taught developers or developers who don't feel quite comfortable with certain computer science concepts.
If you are learning to program for the first time, I would recommend r/learnprogramming community on Reddit.
Table of Contents
- Computer Architecture
- Algorithms and Data Structures
- Math for Computer Science
- Operating Systems
- Computer Networking
- Languages and Compilers
- Distributed Systems
- Web Security
I'm not talking about syntax here. But actually programming or problem solving. Things such as abstraction, functions as data, recursion, and the different kinds of programming paradigms (object-oriented, functional, and declarative).
The book I recommend to learn programming is Structures and Interpretations of Computer Programs (SICP) (It's also known as the wizard book).
The book is free and has a set of MIT lectures. But the MIT lectures are a bit hard to watch due to the poor quality of that time (2005). So I recommend Brian Harvey’s SICP lectures (for the 61A course at Berkeley) instead.
Why this book?
Because this book focuses on the big picture.
It doesn't care about the programming language. It uses a variation of Lisp called Scheme. Scheme is very easy to learn (you can probably learn it in less than an hour), so it let's you focus on ideas not syntax.
Because of its simplicity, it makes it possible to examine different programming paradigms. It's a functional first approach, but you can implement your own OOP.
Scheme is a great language for teaching because it takes the focus away from the language and puts it on the big ideas.
If you're worried about it not being used in the industry, it's ok – you can always learn a more commonly-used programming languages after you grasp these high-level concepts.
But what if I REALLY don't want to learn Scheme?
But, I highly recommend at least trying to do the Scheme version. It's just magical once you get it.
Okay, I've tried it but it's really hard
Yes, I understand.
Some of you will find SICP a bit too hard. It's not meant for purely beginner programmers.
Tips on Studying
Don't read these books like a story.
It's not meant to be read cover to cover. Instead, focus on the exercises. You don't have to do them all, but just make sure you know how to solve most of them.
The lectures are optional and only needed if they help. It's really up to you.
- Virtual meetups that talk about SICP
- Racket (IDE for Scheme) (Checkout this StackOverFlow answer for Scheme setup)
You wrote some code and it magically runs.
How does that work? Well, this is what you will learn with computer architecture. This is by far the most neglected subject by most self taught engineers.
As engineers, we don't believe in magic. We have to unravel the magic behind computers. You will also learn some useful stuff such as:
- What is the L1, L2 cache?
- Why does cyberpunk lag?
The book I recommend here is Computer Systems: A Programmer's Perspective. I would also recommend an introductory course that will cover chapters 1-6 of the book (That was made by the authors of the book).
But there's a catch
This book is not meant to be read cover to cover. It has a lot of content, that may not well be presented in the optimal order.
So I recommend that you follow the course and do the labs.
What if I find it too hard?
A lot of people will find the content a bit heavy, so to ease into it, I would recommend doing the following:
- Read Code: The Hidden Language of Computer Hardware and Software\
- Read this handbook on Software Architecture
- Watch all 4 videos of Exploring How Computers Work
- Watch all 41 videos of Crash Course: Computer Science
- Take the course NAnd2Tetris
- Learn a bit of C by reading the book: C Programming a Modern Approach
Once you finish that you can then come back to Computer Systems: A Programmers Perspective.
Data Structures and Algorithms
Everyone wants to work at a FAANG company, but no one wants to learn Data Structures and Algorithms.
Nevertheless, I don't want you to learn these just because of technical interviews. Data structures and algorithms are important because they help build your problem solving skills.
There are many great books and courses on Data Structures and Algorithms but the one I would recommend is a book named The Algorithm Design Manual by Steven Skiena. You can also check out his course here.
Don't forget to practice
Same rules apply here. Don't just learn about data structures, but create them in whatever language you want. Don't just memorize algorithms but implement them and see where and how you can use them.
A good tip is solving some Leetcode problems while going through the book/course.
What if I find it too hard?
If you find the material a bit heavy, then I would recommend the following resources:
- Read the book: Grokking Algorithms
- Read the book: How to Solve It: A New Aspect of Mathematical Method
In general there are many different books/courses that teach Data Structures and Algorithms – Here are some other great resources:
- Data Structures and Algorithms course on freeCodeCamp
- Algorithms Illuminated
- Princeton Algorithms Course
- ThePrimegeans Data Structures and Algorithms Course
- MIT Introduction to Algorithms
Math for Computer Science
Many new developers skip this.
But, hear me out – computer science is essentially a branch of mathematics. Learning it will make you a better developer by honing your problem solving skills.
The most relevant area for CS is Discrete Mathematics
Discrete mathematics is the branch of mathematics that deals with countable or finite numbers.
The topics in discrete mathematics are many, but the ones which are relevant for CS are:
- Discrete Probability
- Set Theory
- Graph Theory
- Number Theory
How to Study Discrete Mathematics
I would suggest starting with a set of lecture notes by László Lovász.
Professor Lovász notes are easier to digest than formal texts and are just generally fun. He starts of with a problem and solves it using discrete mathematics.
What if it's too hard?
Don't worry – sometimes you just have to accept that you won't always get it right away.
But if you feel like you're missing some fundamental knowledge, then it's a different story. The fundamental prerequisite subjects for discrete mathematics are:
There are many free resources, but the ones I would recommend are:
Remember when I told you that we as developers want to remove the magic in computing?
Same thing applies here – operating systems seem like some sort of magical black box. But they're not – it's just a lot of clever engineering.
If you know how these operating systems are built and work, then you will definitely be in a league of your own.
It's somewhat difficult to find good resources online for operating systems but the most recommend book is Operating Systems: Three Easy Pieces (OSTEP). There isn't any official video lecture online that fully covers the book but I found this playlist on YouTube.
I would suggest learning computer architecture first and a little bit about C before embarking on the operating systems journey.
Now, I recommend finishing OSTEP first and then checking out the other recommend resources. They are all optional.
- Want to build your own Linux system? Check out Linux from Scratch.
- Want an in-depth overview of Linux, MacOS, and Windows? Here's a handbook for you.
- Want to build your own OS? Check out OSDEV
- Want to build your own Sockets? Check out Beej's Guide to Network Programming
Since the dawn of the internet, computer networking has been one the most important subjects for software engineers.
If you don't know things like IP, TCP, UDP, HTTP, TLS, DNS, SMTP, and so on — then you should learn about computer networking (especially if you are a backend engineer).
Databases are somewhat new – they came around the 1970s and have since become integral parts of many applications.
I highly recommend the below courses from the CMU Database Group. They're all freely available on YouTube. I would recommend going through at least the first one.
Languages and Compilers
You may know how to code in one or more programming languages.
But do you know how to create or design one? That's what you will learn by studying programming languages and compilers.
The recommended introductory book is called Crafting Interpreters.
After that you can move on to Compilers: Principles, Techniques & Tools, also called “the Dragon Book”. The book is covers a lot of topics so I highly recommend taking a course with it. The one I recommend is from Alex Aiken on edX.
And here's a helpful beginner-friendly tutorial on how the compiler works in C programming.
If you choose to study only one subject from the list, make it distributed systems. It's the holy grail for tech companies, and if you want to get a developer job, you should be proficient about distributed systems.
My recommend path in learning the subject is:
- Read the book: Understanding Distributed Systems
- Read the book: Designing Data Intensive Applications also known as the "red book"
- While reading the "red book", take its accompanying MIT course on YouTube.
- Read the book: Software Architecture: The Hard Parts (Optional)
- You can also check out my handbook about design patterns for distributed systems.
There have been a lot of security breaches in the last 2-3 years.
It's getting dangerous out there – and as a software engineer, knowing some fundamentals of web security will give you an edge.
The course I recommend first is CS253 Web Security by Stanford. It gives a comprehensive overview of web security. So expect topics like web app vulnerabilities, injection, denial-of-service, and many more.
You can also review these common vulnerabilities and learn how to prevent attacks that take advantage of them.
Later on, if you want, you could learn how to hack using pwn.college.
Learning all these subjects will take you a while, and will require consistent effort. But if you like what you do and are interested in the subject, then it should feel like play and not a chore.
Regardless of the subjects you choose to study. The most important tip I can give you is...
Don't be a passive learner
Don't just watch videos – do the exercises as well. Build the projects along with the tutorials.
Don't just read books but engage in the book by asking questions and doing your own research.
You want the information to stick, so you don't forget it. And to make it stick you have to actively engage in the subject.
I sincerely hope that I encouraged you to study some of these subjects. As always I want to end it of by thanking you for reading this article.
I wish you all the best.