For the past few years, most of my learning as a developer has followed the same pattern: a project needs a new framework, database, deployment platform, or tool, so I learn enough to use it and move forward. That approach helped me build things, but it also made me realize how quickly the surface of software engineering changes.
So I am changing the way I learn. I will still keep up with new technologies, but I want that learning to sit on top of something more durable: computer science fundamentals. Instead of treating every new tool as a completely new world, I want to understand the systems, constraints, and ideas underneath it well enough that adapting becomes easier.
Day 1 of rebuilding my understanding of software from the machine upward.

The tools change. The underlying problems do not.
React will change.
Next.js will change.
Cloud platforms will change.
AI-assisted development will keep changing the way we build software.
Some of the tools we consider essential today may look completely different a few years from now.
But underneath those tools, the same problems keep appearing:
Programs still need CPU time and memory.
Operating systems still manage processes, files, devices, and isolation.
Networks still have to move data between machines.
Databases still need to store, index, query, and recover data.
Distributed systems still deal with failure, latency, retries, and consistency.
Large systems still depend on caching, queues, load distribution, and reliability.
The abstraction changes.
The underlying problem often does not.
That distinction matters.
Learning another framework can make me productive with that framework. Understanding the mechanism underneath it makes me more adaptable when the framework changes.

Why fundamentals make adaptation easier
This does not mean ignoring new technology.
Quite the opposite.
The industry is evolving too quickly for us to stop learning new tools. The difference is that I no longer want every new technology to feel like an entirely new world.
I want to understand the ideas underneath it.
For example:
If I understand networking properly, a new API gateway becomes easier to reason about.
If I understand processes, threads, memory, and system calls, a new runtime becomes less mysterious.
If I understand indexes, transactions, MVCC, WAL, and replication, learning another database becomes easier.
If I understand distributed systems, technologies such as Kafka, Redis, Kubernetes, queues, and distributed databases begin to connect.
Instead of seeing dozens of unrelated products, I start seeing different implementations of familiar problems.
That is the kind of adaptability I want to build.
Not:
"I know this tool."
But:
"I understand the problem this tool is solving, the mechanisms it probably relies on, and the trade-offs I should investigate."
That feels far more durable.
So I built my own Computer Science roadmap
Today I decided to restart from the bottom.
Not because I am starting software development from zero.
I have already spent years building applications and working with real technologies.
But there is a difference between:
using an abstraction
and
understanding what is happening underneath it.
So I created a structured roadmap for myself.
The learning path starts with low-level computer systems and gradually moves upward through:
Computer systems and architecture
Operating systems
Computer networking
Databases and storage systems
Distributed systems
System design
Infrastructure and SRE
Algorithms and data structures
Programming languages, compilers, and runtimes
CS theory and mathematics
Security fundamentals
Agentic AI and AI systems
Research and engineering writing
I am not trying to finish this list as quickly as possible.
The goal is to connect the layers.

My fundamentals-first Computer Science roadmap.
The questions I want to be able to answer
For a long time, most of my learning started with:
How do I use this?
I want to spend more time asking:
Why does this work?
That means getting comfortable with questions such as:
What actually happens when a program starts running?
How are values represented in memory?
What does the CPU actually execute?
What happens when an application makes a system call?
How does an operating system switch between processes?
How does TCP make communication reliable over an unreliable network?
Why does an index speed up one database query but not another?
How does a database recover after a crash?
What makes distributed systems difficult when machines can fail independently?
Why does an architecture work well at one scale and become a bottleneck at another?
These are not questions tied to one framework.
They are questions that help explain many frameworks.
Reading alone is not enough
I also do not want this journey to become a collection of highlighted textbooks and unfinished notes.
For every major area, I want to build something that exposes the mechanism.
That may include projects such as:
a memory allocator
a Unix-style shell
an HTTP server
a reverse proxy
a small database engine
a B+ tree
a replicated key-value store
a consensus implementation
a compiler or small runtime
The point is not to compete with Linux, PostgreSQL, Nginx, or any other mature system.
The point is to understand why those systems need the mechanisms they have.
When you build even a tiny version yourself, the theory becomes something you can:
inspect
benchmark
break
debug
measure
reason about
That is a very different kind of learning.
Where I am starting
My first focus is computer systems from a programmer's perspective: how data is represented, how programs become machine instructions, how memory behaves, and how operating systems expose hardware through useful abstractions.
Two resources that strongly match this direction are:
Computer Systems: A Programmer's Perspective, Carnegie Mellon University
Operating Systems: Three Easy Pieces, University of Wisconsin-Madison
I am using resources like these as references, not as a checklist to finish as quickly as possible. The goal is to understand the ideas well enough to explain them, experiment with them, and eventually build smaller versions myself.
I want to document the journey as I go
This blog will become part of that process.
I do not want to write polished tutorials pretending I mastered something after reading about it once.
I want these posts to be closer to an engineering journal.
I want to write about:
what confused me
what finally made sense
assumptions I had that turned out to be wrong
how a fundamental concept connects to technologies I already use
which books, papers, experiments, and projects were genuinely useful
how my understanding changes as I go deeper
Some posts may be detailed.
Some may simply capture one idea that clicked that day.
The important thing is that I keep a record of the journey.
This is not a rejection of modern tools
I still want to build products.
I still want to explore new technologies.
I will still learn new frameworks when they are useful.
And I will continue using AI where it genuinely improves productivity.
The change is in what I want underneath all of that.
I want a foundation strong enough that a new technology feels like another abstraction to understand, not another stack to memorize from scratch.
Frameworks will keep changing.
Tools will keep changing.
The fundamentals underneath them will move much more slowly.
So I am starting again from the machine upward.
This time, I want to understand the layers in between.
Next: how computers represent information
I have started with data representation and low-level computer systems fundamentals.
The next step is going deeper into some of the most basic things we use every day without thinking much about them:
bits and bytes
fixed-width integers
signed and unsigned values
integer overflow
floating-point representation
precision and rounding
endianness
UTF-8
bitwise operations and masks
Very basic ideas on the surface.
But almost everything above them depends on getting them right.
Related
More posts from this Computer Science learning journey will be linked here as the series grows.
This post is part of Relearning Computer Science, a series where I document my journey of rebuilding my software engineering knowledge from the fundamentals upward.
