RecallDeck
Interview track

DevOps Engineer interview prep

A spaced-repetition deck of 210+ DevOps Engineer interview questions — organised by topic and difficulty, and resurfaced right before you'd forget. Preview a few cards below, then sign in to study the whole track on an Anki-style SM-2 schedule.

210 cards12 topics

Free · sign in with GitHub · your progress stays yours.

What's covered

Every topic in this track, grouped the way you'd study it.

Linux & Troubleshooting

11 cards
Linux & Troubleshooting

Networking in Operations

10 cards
Networking in Ops

Container Internals

8 cards
Container Internals

Kubernetes

13 cards
Kubernetes

CI/CD & GitOps

8 cards
CI/CD & GitOps

Terraform & Ansible (IaC)

8 cards
Terraform & Ansible

Observability & SRE

11 cards
Observability & SRE

Cloud & Security

9 cards
Cloud & Security

DevOps & Infra

35 cards
Docker, CI/CD & Linux

CS Fundamentals

33 cards
Networks

System Design

29 cards
System Design

Behavioral

35 cards
Behavioral

Sample questions

A few cards from the deck — reveal each answer, then sign in to study the full set on a schedule.

free shows almost no free memory. Is the server actually out of RAM?

Short answer: Almost certainly not. Linux deliberately fills “spare” memory with page cache — it is handed back to applications instantly. Look at the available column, not free; real memory pressure shows up as swap-in and major page faults.

In depth:

Metric What it means Worry?
free memory occupied by nothing at all no — near zero on a healthy server
buff/cache page cache: file and block cache no — evicted on demand
available what can really be handed out without swapping yes, if it steadily heads to zero
  1. Empty memory is wasted memory — the kernel caches disk so repeated reads come from RAM instead of the device.
  2. Real signs of pressure — growing si in vmstat 1 (swap-in), major page faults, OOM-killer entries in dmesg.
free -h       # watch available, not free
vmstat 1 5    # si/so columns — is active swapping happening

⚠️ Common mistake: “no free memory — let’s reboot” or dropping caches via drop_caches. Page cache is a feature: clearing it only slows the system down until it warms up again.

L4 vs L7 load balancing: what can each layer see, and what can it do?

Short answer: An L4 balancer sees only IPs and ports — it spreads TCP/UDP flows, fast and cheap, but the protocol is opaque to it. L7 parses HTTP: routing by path and headers, retries, TLS termination, cookie affinity — at the cost of CPU spent parsing.

In depth:

L4 L7
Sees IP:port, SYN method, path, headers, cookies
Routing round-robin/hash over flows /api → one pool, /static → another
Retries & timeouts none — can't tell where a request ends per-request retries, circuit breaking
TLS passthrough only termination, X-Forwarded-For
Cost near zero, millions of pps HTTP parsing: CPU and latency

Examples: L4 — IPVS, AWS NLB; L7 — nginx, Envoy, AWS ALB. A common cascade: L4 on the edge → L7 inside.

⚠️ Common mistake: expecting retries or path-based routing from L4 — it doesn't see HTTP and fundamentally can't tell where one request ends and the next begins.

What is a container at the Linux kernel level, and which mechanisms implement it?

Short answer: A container is just a regular Linux process that the kernel hands an isolated view of the system: namespaces hide everything else, cgroups cap resources, and a layered filesystem provides its own rootfs. There is no guest kernel — one kernel serves everyone, and that is the real difference from a VM.

In depth:

  1. Namespaces — visibility isolation: each type hides its own slice of the system.
  2. cgroups — limits on CPU, memory, IO: how much the process may use, not what it sees.
  3. Layered rootfs (overlayfs) — its own filesystem on top of shared read-only image layers.
Namespace What it isolates
pid process tree: its own PID 1 inside
net network stack: interfaces, routes, its own ports
mnt mount points, its own rootfs
uts hostname and domainname
ipc System V IPC, POSIX queues
user UID/GID mapping: root inside ≠ root outside
cgroup the visible cgroup hierarchy

⚠️ Common mistake: "a container is a lightweight VM." A VM has a hypervisor and its own guest kernel; a container shares the host kernel — that's why it starts in milliseconds, but isolation is weaker: one kernel vulnerability pierces every container at once.

What happens after kubectl apply -f deployment.yaml? Walk through the full chain to a running pod.

Short answer: kubectl validates the manifest and sends it to the API server: authn → RBAC → admission webhooks → persisted to etcd. That is where the synchronous part ends — controllers, the scheduler, and kubelet notice changes asynchronously via watch and drive the cluster toward the desired state. Nobody pushes anything.

In depth:

  1. API server — authentication, authorization (RBAC), admission (mutating → validating webhooks), object stored in etcd.
  2. Deployment controller — sees the new Deployment (watch) and creates a ReplicaSet.
  3. ReplicaSet controller — creates Pod objects, with no node assigned yet.
  4. Scheduler — finds pods with an empty nodeName, filters and scores nodes, binds.
  5. kubelet — on the chosen node sees "its" pod: pulls images, starts containers via CRI, networking comes up via the CNI plugin.
  6. Readiness — probe passes → the pod joins the EndpointSlice and starts receiving traffic.
kubectl ──► API server (authn → RBAC → admission) ──► etcd
              ▲ watch      ▲ watch       ▲ watch      ▲ watch
  deploy-ctrl → RS    rs-ctrl → Pods   scheduler → bind   kubelet → CRI/CNI

⚠️ Common mistake: "the API server schedules the pod and starts containers." It only stores and serves state — all the work is done by independent controllers via the watch/reconcile model.

Trunk-based development vs GitFlow: which model enables continuous deployment, and why?

Short answer: Continuous deployment is only real with trunk-based + feature flags: small batches, branches that live hours, main always deployable. GitFlow with long-lived develop/release branches means big batches and merge hell; its home is boxed, versioned software.

In depth:

Trunk-based GitFlow
Branches main + branches < 1–2 days develop, release/, hotfix/ — long-lived
Batch size small, integrate daily large, integrate at release time
Deploy vs release decoupled via feature flags glued together: release = merging the release branch
Fits SaaS, continuous deployment boxed software, several supported versions
  1. Flags decouple deploy from release — code ships to prod turned off; turning it on is config, not a deploy. That removes the fear of merging unfinished work into main.
  2. The argument is batch size, not taste: the longer a branch lives, the more conflicts, the longer the lead time, the scarier the rollback — DORA metrics are exactly about this.

⚠️ Common mistake: answering "whatever the team prefers." It is not taste: long branches → big batches → long lead time — a measurable argument.

Two engineers run terraform apply at the same time. What happens with and without state locking?

Short answer: With locking, the second apply blocks or fails with "Error acquiring the state lock" — the first one holds the lock. Without it — a race: both read the same state version and overwrite each other's writes, leaving the state inconsistent.

In depth:

with lock:    A: apply ──► lock OK ──► works ──► unlock
              B: apply ──► Error acquiring the state lock ✗

without lock: A: read state v1 ──► write v2a ─┐
              B: read state v1 ──► write v2b ─┴─► last writer
                                                  "wins"
  1. Consequences of the race — lost records: a resource exists in the cloud but not in state (orphan), or the state is corrupted and gets fixed by hand via state rm/import.
  2. Mechanics — the backend takes a lock for the duration of the operation (a DynamoDB table for S3); force-unlock is only for stuck locks.
  3. The full answer — applies run only through the CI pipeline, serially; humans run plan locally.

⚠️ Common mistake: treating locking as an optional nicety "for big teams" — one overlapping apply is enough to spend a day untangling state by hand.

Ready to make it stick?

Start your first session in under a minute. Your future self, mid-interview, will thank you.

Questions about this track

How should I prepare for a DevOps Engineer interview?

Study the concepts you'll be asked to explain, not just the ones you can code. RecallDeck's DevOps Engineer track gives you 210+ curated interview questions and resurfaces each one with an Anki-style SM-2 schedule right before you'd forget it — so the answers are still there under pressure on interview day.

What topics does the DevOps Engineer track cover?

The DevOps Engineer track is organised into the core areas DevOps Engineer interviews actually test, grouped by topic and by difficulty (Concept, Junior, Middle, Senior). You can preview the full outline and sample questions above before signing in.

Is spaced repetition effective for DevOps Engineer interview prep?

Yes. Actively recalling an answer and grading yourself honestly builds far more durable memory than re-reading notes. RecallDeck schedules each DevOps Engineer card to reappear at the moment you're about to forget it, so your daily reviews shrink while your recall holds.

Is the DevOps Engineer track free?

Yes — the DevOps Engineer track and the full SM-2 scheduler are free, with 20 new cards a day. Sign in with GitHub and your progress syncs to your account. RecallDeck Pro ($5/month or $29/year) raises the daily budget and adds cram mode.

Other interview tracks

RecallDeckSpaced-repetition interview prep