Nobody implements a B-tree at work, yet the core subjects keep being asked, because how someone explains paging or an index is the cheapest available predictor of how they will reason about an unfamiliar system under pressure.
Steady demand22 min readBackend / Platform Engineer, Site Reliability Engineer, Database Engineer / DBA, Systems and Embedded Engineer, Campus and graduate hiring panellistUpdated 2026-07-27
Assumes you know: Comfort reading code in one language, Having deployed or operated something that other people used
Overview
What this area actually covers
The core-subject rounds draw on four or five undergraduate courses: operating systems,
computer networks, database theory, the object-oriented model, and how source code
becomes running instructions. Within each, an interview reaches for a small and stable
set of ideas — process versus thread and what a context switch costs, virtual memory
mapping addresses that do not exist to pages that do, TCP's guarantees against UDP's
absence of them, functional dependencies and what a transaction promises, and the
phases between text and execution.
The boundary that matters is against system design. System design asks you to choose
and arrange components; fundamentals ask you to explain why a component behaves as it
does. "Put a cache in front of the database" is a design answer. "The cache helps
because the working set fits in memory and a page fault costs several orders of
magnitude more than a hit" is a fundamentals answer, and only one of them survives
being asked why three times.
Data structures and algorithms are also frequently bundled in here and should not be.
Sorting, trees and complexity analysis are their own round with its own format — you
write code, and it either runs or it does not. Fundamentals questions are almost always
verbal, which changes what a good answer looks like entirely.
Now practise it
26 interview questions in CS Fundamentals, each with the rubric the interviewer is scoring against.
This section is divided into six subjects, and the division follows the undergraduate
curriculum because that is where the questions come from. Two of them — operating
systems and networking — pay for themselves in production work almost immediately. Two
more, database theory and runtimes, pay off the first time something is slow for a
reason the application code does not reveal. One is largely terminological, and one is
a recent addition that no longer behaves like an optional extra.
Subject
What it is for
Operating Systems
Explaining why a process stalls, blocks, swaps or deadlocks
Computer Networks
Reasoning about latency, timeouts, retries and connection cost
DBMS Theory
Knowing what a transaction guarantees and why a query chose its plan
OOP Theory
The classical definitions that screens ask close to verbatim
Compilers & Runtimes
Warm-up, JIT behaviour, memory layout and collection pauses
Security Fundamentals
Recognising a class of vulnerability before you ship it
Operating Systems is the subject that turns "the server is slow" into a specific
claim. It covers processes and threads and what actually differs between them, how a
scheduler decides who runs next and what a context switch costs, virtual memory and the
page table that makes each process believe it owns the machine, synchronisation
primitives, and the four conditions that together produce a deadlock. It exists as a
separate subject because everything above it is built on the assumption that these
mechanisms are free, and they are not.
Computer Networks is where most production surprises live, because the network is
the one component in your system that fails partially. The subject covers the layered
model, the difference between TCP's ordered reliable stream and UDP's fire-and-forget
datagrams, congestion control and what it does to your throughput under loss, routing,
and the canonical walkthrough of what happens between typing a URL and seeing a page.
That walkthrough is asked so often that it functions as a shared reference question
across the whole industry.
DBMS Theory is the formal half of databases, as distinct from writing SQL. It covers
relational algebra as the model underneath the query language, functional dependencies
and the normal forms derived from them, and the concurrency-control theory that explains
what an isolation level is protecting you against. It is separated from practical
database work because the theory is what lets you answer why — why this schema
produces an update anomaly, why two transactions that each look correct are not correct
together.
OOP Theory is the most exam-like subject on the list and the one where the questions
are most likely to be asked in almost the same words each time. Abstraction,
encapsulation, inheritance and polymorphism, the difference between overloading and
overriding, why an abstract class is not an interface. It exists separately from
low-level design because that round asks you to use these ideas on a problem, whereas
here you are being asked to define them precisely, which is a different and narrower
skill.
Compilers & Runtimes explains the gap between the code you wrote and the
instructions that ran. Compilation phases, the difference between ahead-of-time
compilation, interpretation and just-in-time compilation, how objects are laid out in
memory, and how a garbage collector decides what to reclaim and what that costs you in
pause time. It matters most if you work on a managed platform, where a large share of
unexplained performance behaviour is the runtime doing something reasonable at an
inconvenient moment.
Security Fundamentals used to sit outside the core-subject round and no longer does.
The content is the recurring vulnerability classes — injection, broken access control,
insecure deserialisation and the rest of the familiar catalogue — plus enough
cryptography to know that hashing and encryption solve different problems and that a
password store needs a slow hash with a per-user salt rather than a fast one. It has
been pulled into this section because the questions are conceptual rather than
tool-specific and are asked of ordinary application engineers, not only specialists.
Where it sits in a real system
Every abstraction an application developer works above is one of these subjects wearing
a friendlier name. A connection pool exists because a TCP connection has a setup cost
and a database has a bounded number of server-side processes. A slow endpoint that is
fast in isolation is usually a queue somewhere — the run queue, the pool, a disk. An
out-of-memory kill is virtual memory policy meeting an overcommitted host. A deadlock
in production is the dining philosophers, in a schema.
The usual sequence in an incident makes the connection obvious. Latency rises, the
application code has not changed, and the explanation is one layer down: the index that
stopped being used because the planner's statistics went stale, the garbage collector
pausing because every collection now reclaims almost nothing, the retry storm that is
congestion collapse with a modern logo. You do not need to have written a
page-replacement algorithm to reason about any of that, but you do need the mental
model, and the model is what these courses install.
Subject
Real thing it explains
Interview trivia to ignore
OS scheduling and memory
Why your service stalls under CPU steal or swap
Exact scheduler class names
Concurrency and locking
Deadlocks, races, why a lock hurts throughput
Reciting Banker's algorithm
Networking
Timeouts, retries, TLS cost, connection reuse
Memorising all seven OSI layers in order
DBMS internals
Why a query uses an index, what a transaction guards
Drawing relational algebra symbols
Compilers and runtimes
Warm-up, JIT behaviour, GC pauses, memory layout
Naming every compilation phase
The right-hand column is not a claim that the trivia is worthless; it is a claim about
where the marginal hour goes. Nobody has ever diagnosed an outage by recalling the
order of the OSI layers, and plenty of people have diagnosed one by knowing that a
half-open connection consumes a slot in a pool until a timeout fires. Study the middle
column and the right-hand column comes along for free, because the trivia is mostly
labels attached to mechanisms you will have had to understand anyway.
What happens when you load a URL
This is the most-asked question in the whole section, and it is asked because it is
elastic: the same prompt works on a graduate and on a principal engineer, because each
of them stops at a different depth. It is worth walking once properly, since almost
every other networking question is a zoom into one of its steps.
Loading diagram…
Look at the gap between the third and fourth boxes. Each of those is a round trip
before a single byte of your content moves, which is why connection reuse and keeping
sessions warm matter far more on a high-latency mobile network than any amount of
server-side optimisation. It is also the reason a service that opens a fresh connection
per request behaves acceptably in a data centre and terribly from a phone.
The other place candidates stop too early is the sixth box. "The server handles it" is
where a graduate finishes; the useful continuation is that the request lands on a
listening socket, is accepted by a process or thread that may have to wait for one from
a pool, issues a query that may itself wait on a connection pool and then on a disk,
and returns through the same stack. Every one of those waits is a queue, and a queue is
the concept that unifies operating systems, networking and databases into one subject.
The mechanisms worth holding in your head
Four mechanisms account for most of what these subjects are for. If you internalise
only these, you will be able to reason about the majority of production behaviour that
application code does not explain.
The first is the address space. Your process does not see memory; it sees addresses
that the hardware translates through a page table into physical frames. That
indirection is what gives you isolation between processes, lazy allocation, and the
ability to map a file as though it were memory. It also gives you the page fault: a
reference to a page that is not currently resident, which the kernel must satisfy
before your instruction can continue. A minor fault is cheap because the page is
already in memory somewhere; a major fault reaches the disk and is slower by orders of
magnitude, which is why a machine that has started swapping feels broken rather than
merely slow.
The second is the scheduler and the states a thread moves between. A thread is not
either running or stopped; it is in one of a small number of states, and knowing which
one tells you what to fix.
Loading diagram…
The transition worth staring at is Running to Ready. A thread that keeps being moved
back to Ready is competing for CPU, and adding threads makes that worse. A thread
sitting in Blocked is waiting for something else entirely, and adding threads may help.
Those two symptoms look identical from outside the process — high latency, low
throughput — and the remedies are opposite, which is why "is it CPU-bound or
IO-bound" is the first question any experienced engineer asks.
The third is the transaction, which is the database's promise about what other
people can see while you are halfway through. Atomicity and durability are usually
understood; isolation is the one candidates fumble, because it is not a single
guarantee but a scale, and each rung buys you protection from one more anomaly at some
cost in concurrency.
Isolation level
Prevents
Still allows
Read uncommitted
Nothing much
Dirty reads, non-repeatable reads, phantoms
Read committed
Dirty reads
Non-repeatable reads, phantoms
Repeatable read
Dirty and non-repeatable reads
Phantoms, in the standard's definition
Serializable
All three
Nothing, at the price of aborts or blocking
The practical point of that table is not the vocabulary but the direction. Every step
down the table costs concurrency, and real engines implement these levels with
different mechanisms and different behaviour at the edges, so the correct answer to
"what does repeatable read give me" always ends with "in which engine". A candidate who
adds that qualifier unprompted is telling the interviewer they have read the manual for
a specific database rather than a summary of the standard.
The fourth is the managed runtime. On a platform with garbage collection, memory is
reclaimed by a subsystem that has to find out which objects are still reachable, and
the ways it can do that trade throughput against pause length. The consequence you will
meet is that a process can be perfectly healthy on average and still produce
latency spikes, because a collection ran. The related consequence is warm-up: a
just-in-time compiler observes which code paths are hot before optimising them, so the
first requests after a deploy are genuinely slower than the ones ten minutes later, and
a benchmark that ignores this measures the wrong thing.
The concurrency questions that recur
Concurrency is the part of this section that is asked most often and understood least
well, partly because the vocabulary is used loosely in ordinary conversation and
precisely in an interview. Four ideas cover nearly all of it.
A race condition is not a bug in a line of code; it is a dependence on the order in
which two threads happen to interleave. The classic demonstration is two threads each
incrementing a shared counter, where the increment is really a read, an add and a
write, and one thread's read can happen before the other's write lands. The reason this
matters beyond the toy example is that the same shape appears wherever you check a
condition and then act on it — the file does not exist, so create it; the balance is
sufficient, so debit it — and the gap between the check and the act is where another
thread gets in.
A deadlock requires four conditions to hold simultaneously: resources are held
exclusively, a holder can request more while holding, resources cannot be taken away,
and there is a cycle of threads each waiting on the next. The useful thing about that
list is not reciting it but the corollary — you break a deadlock by breaking any one
condition, and in practice you almost always break the cycle by imposing a global order
in which locks must be acquired. The database version of the same problem is two
transactions updating the same two rows in opposite orders, and the fix is the same
ordering discipline expressed in SQL.
Mutexes and semaphores are asked about together because candidates conflate them. A
mutex protects a critical section and has an owner, so the thread that locked it is the
thread that unlocks it. A counting semaphore is a permit dispenser with no notion of
ownership, used to limit how many things may proceed at once, and one thread may
legitimately signal a permit that another acquired. A connection pool is a semaphore
wearing a domain name; the lock inside a data structure is a mutex.
The fourth idea is the one that turns concurrency from a correctness topic into a
performance topic: a lock is a queue. Every thread that cannot take a lock waits,
and waiting threads are throughput you have already paid for and are not using. That is
why lock granularity is the design question — one coarse lock is easy to reason about
and serialises everything, many fine locks preserve parallelism and multiply the ways
you can deadlock. It is also why the strongest available answer to a contention problem
is often to remove the shared state rather than to guard it better, whether by making
the data immutable, by giving each thread its own copy, or by making the operation
atomic at the hardware level so no lock is needed at all.
Who does this work
Almost nobody's job title is "fundamentals", which is exactly why the subject is
confusing to place. The people who work directly at this level build databases,
kernels, runtimes, compilers, network stacks and embedded firmware, and they are a
small population. Site reliability and platform engineers use the material constantly
without implementing any of it — reading flame graphs, tuning connection pools,
diagnosing packet loss, arguing about heap sizing. Backend engineers meet it twice a
year, during an incident or a migration, and those are the two occasions that determine
whether anyone thinks they are senior.
On the other side of the table, these questions are asked by campus panels, where
coursework is the only shared ground, and by senior engineers checking whether the
abstractions an experienced candidate uses daily are opaque to them.
It is worth naming the difference in what a day looks like for the two populations. An
engineer who builds at this level spends their time on correctness proofs, benchmarks
and careful reading of specifications, and their code changes slowly. An engineer who
uses this level spends their time on diagnosis: forming a hypothesis about which
layer is responsible, finding the cheapest observation that would falsify it, and
repeating. The second is far more common and is the skill the interview is trying to
detect, which is why questions increasingly arrive as scenarios rather than as
definitions.
Demand, adoption and how that is changing
Demand here is steady and structurally protected. The number of people who write
kernels or query planners is not growing quickly, but the number of interviews that ask
about paging and indexes is enormous, because the questions are cheap to ask, hard to
bluff, and portable across every technology stack an employer might use. A panel that
cannot agree on which framework matters can still agree on what a transaction
guarantees.
Two forces are strengthening rather than weakening it. Cloud infrastructure made the
underlying machine less visible while making its behaviour more expensive to
misunderstand: a noisy neighbour, a throttled disk, a cross-availability-zone round
trip. And as code generation makes surface-level output easier to produce, interviewers
have shifted weight towards what a candidate can explain about behaviour they did not
write, which is precisely this material.
The honest counterweight is that emphasis varies wildly by employer. Indian service
companies and campus processes ask these questions heavily and often verbatim, so the
terminology questions matter there in a way they do not at a product company, where the
same subject arrives disguised as a debugging conversation. Depth expectations also
flip with seniority: an entry-level candidate is asked for the definition, a senior
candidate is asked for the consequence, and giving the definition when asked for the
consequence is the single most common mismatch in these rounds.
There is a second, quieter shift. Containers and orchestration put a layer between the
application and the operating system that many engineers now treat as the operating
system, and the abstraction leaks in specific, learnable ways — a memory limit enforced
by the platform rather than by the kernel's own accounting, a CPU quota that throttles
rather than descheduling, a process running as the first process in its namespace and
therefore responsible for reaping children it did not know it had. Those are operating
systems questions in modern dress, and they are increasingly what a platform-leaning
interview asks instead of the textbook version.
What makes it hard
The difficulty is that recall and understanding feel identical from the inside. You can
read the ACID acronym, feel that you know it, and be unable to say what isolation
protects you from that atomicity does not. The material is written in definitions, and
definitions are the one form in which it is useless — an interviewer who wanted the
definition could have looked it up.
The second difficulty is calibrating depth, because every one of these subjects has a
floor you can keep descending towards. "Virtual memory gives each process its own
address space" is too shallow to be worth saying; the page table walk, the TLB and the
cost of a miss are the useful layer; the microarchitectural details of TLB shootdown
are almost certainly not what is being asked. Finding that middle layer takes being
wrong a few times.
Third, for anyone who came into the industry without a degree, the gap is not knowledge
but vocabulary. You have almost certainly debugged a race condition, waited out a
garbage-collection pause and worked around a missing index. What you lack is the name
and the frame, so the interviewer hears a gap where there is only a translation
failure.
Fourth, and least discussed, these subjects are hard to practise. Algorithms have
problem sets with automated feedback; there is no equivalent for "explain why this
service degrades under load", so most people revise by reading, which trains
recognition rather than production. The only reliable substitute is to explain a
mechanism out loud to someone who will ask why, or to write the explanation down and
notice where your sentences stop.
Calibrating how deep to go
Because depth is the hard part, it is worth having an explicit ladder in mind. Take
database indexing as the worked example, and notice how the same question has four
credible answers depending on who is asking.
The shallow answer is that an index makes queries faster. It is true, it is what
everyone says, and it earns nothing because it does not distinguish you from a
candidate who has never used one.
The working answer is that an index is a separate ordered structure over one or more
columns, usually a B-tree, which lets the engine find matching rows without scanning
the table — at the cost of extra storage and slower writes, because every insert must
maintain the index as well. This is the layer most interviews are aiming at.
The useful answer adds the planner. The engine does not have to use your index, and it
decides based on statistics about the data distribution; if it estimates that a
predicate matches most of the table, a sequential scan is genuinely cheaper than a
large number of random lookups. That explains the most common real complaint, which is
an index that exists and is not being used.
The specialist answer goes to the physical layer — page layout, fill factor, whether
the index is covering so the row itself need never be read, how the ordering of columns
in a composite index determines which predicates it can serve. Reach for this only if
the interviewer keeps pushing, because volunteering it unprompted often reads as
avoiding the question that was asked.
The rule that falls out of the ladder is simple. Answer one rung deeper than the
question, then stop and let them ask for more. Two rungs deeper is showing off; the
same rung is a definition.
Why study it
Study it if you want to be the person who can explain why something is slow rather than
which setting to change. That capability compounds, because it transfers intact across
languages, frameworks and employers, which almost nothing else in this industry does.
It is also the fastest way to become useful during an incident, and being useful during
incidents is how engineers get trusted with larger things.
If you are self-taught, here is the honest prioritisation. Backfill operating systems
and networking first and go properly deep: processes and threads, scheduling and
blocking, virtual memory, and TCP behaviour including what a timeout and a retry really
do. That pays for itself within weeks in production work. Take DBMS internals second —
indexes, transactions, isolation levels, query planning — because it converts directly
into faster code. Take runtimes third if you work on a managed platform, since
garbage-collection and JIT behaviour explain performance mysteries you are otherwise
stuck guessing at. Automata theory, computability, relational algebra notation and
hand-written parsers can wait indefinitely; they are genuinely interesting and they
will not change your Tuesday.
Security fundamentals deserve a separate note, because the prioritisation is different:
the return is not proportional to depth. A single afternoon spent understanding why
parameterised queries prevent injection, what an access-control check must be attached
to, and why passwords need a deliberately slow hash will prevent more real defects than
a month on cryptographic theory. Take the breadth early and leave the depth unless the
role calls for it.
Who should not bother: early in a frontend career, several hours on browser rendering,
the event loop and network waterfalls will do more for you than a month on scheduling
algorithms. And nobody should study this to pass a specific screen. Crammed
fundamentals are audible, because the second question in any thread is why, and
memorised material has no second layer.
Your first hour
Do not open a textbook. Take something running on your own machine and observe the
fundamentals in it. An hour with a real process is worth a chapter.
# Watch a live process: how many threads, how much resident memory, and# whether it is waiting on CPU or on I/O.
top -H -p <pid> # per-thread view; on macOS use: top -pid <pid># Count the page faults. Minor faults are cheap; major ones hit the disk,# and a rising major-fault count is usually the real cause of a stall.
ps -o min_flt,maj_flt,rss,vsz -p <pid>
# Then look one layer down at what the process is asking the kernel for.
strace -c -p <pid> # Linux; on macOS the rough equivalent is dtruss
Then do the same for a query. Take any non-trivial SELECT in a database you already
have and run EXPLAIN ANALYZE on it, once as written and once with the index it uses
removed. Read the row estimates against the actual rows. The gap between estimated and
actual is the single most diagnostic number on the page: when the planner's estimate is
badly wrong, its choice of plan was made on bad information, and that is a different
problem from the plan being a poor choice.
Finish with the network. Open the browser's developer tools on any site you use, reload
with the cache disabled, and read the timing breakdown for the first request — how long
was spent resolving the name, connecting, negotiating TLS, waiting for the first byte,
and downloading. Almost everyone is surprised by how much of it happened before the
server did any work at all.
The artefact at the end of the hour is half a page answering three questions about your
own program: how much of its memory is resident versus mapped, what it spends its time
waiting for, and how much of your query's cost came from the index. That note beats a
summarised syllabus, because in an interview you can describe something you saw rather
than something you read.
What this is not
It is not a prerequisite for employment. Plenty of effective engineers were never
taught this formally and picked up the parts they needed in the order they needed them,
which is a legitimate route and often a better one.
It is not the same as DSA. Fundamentals are explained out loud; algorithms are typed
and tested. Preparation for one does very little for the other, and conflating them is
why candidates who grind coding problems still fall over on "why is the database slow".
It is not exam recall, whatever the phrasing suggests. An interviewer asking about
normalisation is not checking that you can list the normal forms; they are checking
whether you know why you would deliberately break them. Memorising the list prepares
you for the wrong question with the right words.
It is not system design either, though the two are adjacent and often scheduled next to
each other. Design asks what to build; fundamentals ask why the thing you built behaves
the way it does. The connection runs one way: fundamentals make your design answers
defensible under questioning, but no amount of design vocabulary substitutes for
knowing what a page fault costs.
Nor is it a fixed body of knowledge you finish. The mechanisms are stable, but the
layer at which you meet them keeps moving — the scheduling question that was about
threads on a host is now about pods against a CPU quota, and the paging question is now
about a container being killed for exceeding a memory limit. The concepts survive the
move intact, which is exactly the argument for learning them rather than the current
tooling around them.
And it is not obsolete because you work three abstraction layers up. The abstractions
leak on exactly the days that matter, and the leaks are always in this material.
Prepare the consequence, not the definition: for every fundamental you revise, be
ready to say what breaks in production when you get it wrong.