Skip to content
QSWEQB

Computer Science Fundamentals

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.

The six subjects underneath

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.

SubjectWhat it is for
Operating SystemsExplaining why a process stalls, blocks, swaps or deadlocks
Computer NetworksReasoning about latency, timeouts, retries and connection cost
DBMS TheoryKnowing what a transaction guarantees and why a query chose its plan
OOP TheoryThe classical definitions that screens ask close to verbatim
Compilers & RuntimesWarm-up, JIT behaviour, memory layout and collection pauses
Security FundamentalsRecognising 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.

SubjectReal thing it explainsInterview trivia to ignore
OS scheduling and memoryWhy your service stalls under CPU steal or swapExact scheduler class names
Concurrency and lockingDeadlocks, races, why a lock hurts throughputReciting Banker's algorithm
NetworkingTimeouts, retries, TLS cost, connection reuseMemorising all seven OSI layers in order
DBMS internalsWhy a query uses an index, what a transaction guardsDrawing relational algebra symbols
Compilers and runtimesWarm-up, JIT behaviour, GC pauses, memory layoutNaming 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.

flowchart TD
    A[Browser parses the URL and checks its caches] --> B[Resolve the hostname via DNS]
    B --> C[Open a TCP connection to the resolved address]
    C --> D[Negotiate TLS and agree a session key]
    D --> E[Send the HTTP request over the encrypted channel]
    E --> F[Server routes, queries and builds a response]
    F --> G[Browser parses HTML and fetches subresources]
    G --> H[Layout, paint and interactivity]

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.

stateDiagram-v2
    [*] --> Ready
    Ready --> Running: scheduler picks it
    Running --> Ready: time slice expires or preempted
    Running --> Blocked: waits on IO or a lock
    Blocked --> Ready: the event it waited for completes
    Running --> [*]: exits

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 levelPreventsStill allows
Read uncommittedNothing muchDirty reads, non-repeatable reads, phantoms
Read committedDirty readsNon-repeatable reads, phantoms
Repeatable readDirty and non-repeatable readsPhantoms, in the standard's definition
SerializableAll threeNothing, 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.

Now practise it

11 interview questions in CS Fundamentals, each with the rubric the interviewer is scoring against.

All CS Core questions
operating-systemscomputer-networksdbmscompilerscore-subjects