Interview track

ML Engineer interview prep

A spaced-repetition deck of 373+ ML Engineer interview questions — organised by topic and difficulty, and scheduled for review based on your ratings. Preview a few cards below, then choose access to study the whole track on an Anki-style SM-2 schedule.

373 cards20 topics
See access options

Eligible new monthly or yearly subscribers get 7 days free. Checkout confirms eligibility and charges.

Before you start

Start with Python, ML training/evaluation basics, and a tensor framework. Deployment, distributed training, and implementation questions assume you can read model code.

First pass: Python → CS Fundamentals. Begin with the foundational questions in these modules, then follow the outline. Revisit advanced and senior questions as the job requires; all cards remain available from the start.

Shared topics can appear in several tracks and keep one review history. The outline labels shared foundations and role-specific modules; choose your depth for the job you are preparing for.

What's covered

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

Python

122 cards

Shared foundations

Core LanguageData Model & InternalsConcurrency & AsyncStdlib, Typing & Testing

CS Fundamentals

43 cards

Shared foundations

Data Structures & Algorithms

ML Fundamentals & Validation

10 cards

Shared foundations

ML Fundamentals

Classical ML & Ensembles

12 cards

Shared foundations

Classical ML

Metrics & Class Imbalance

11 cards

Shared foundations

Metrics

Features, Data Prep & Leakage

10 cards

Shared foundations

Features & Leakage

Deep Learning

12 cards

Shared foundations

Deep Learning

NLP & LLMs

12 cards

Shared foundations

NLP & LLMs

DevOps & Infra

35 cards

Shared foundations

Docker, CI/CD & Linux

ML System Design

8 cards

Shared foundations

ML System Design

MLOps & Production

10 cards

Shared foundations

MLOps & Production

Model Serving & ML Infrastructure

12 cards

Role-specific module

Serving & Infrastructure

Distributed Training & GPU

11 cards

Role-specific module

Distributed Training

LLM Inference & Optimization

12 cards

Role-specific module

LLM Inference

ML Engineering Practice

9 cards

Role-specific module

ML Engineering

Live Coding: From Scratch

9 cards

Role-specific module

From Scratch

Behavioral

35 cards

Shared foundations

Behavioral

Sample questions

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

What's the difference between mutable and immutable types?

Short answer: Mutable objects can change in place (list, dict, set); immutable objects cannot (int, str, tuple). Rebinding a variable is different from mutating its object.

items = [1, 2]
alias = items
items.append(3)
assert alias is items and alias == [1, 2, 3]

text = "hello"
original = text
text += " world"
assert original == "hello"  # the original string did not change

In depth:

  • id() identifies an object and stays constant during its lifetime. Treating it as a memory address is a CPython implementation detail.
  • A tuple cannot replace its elements, but a list stored inside it can still change. Immutability is not automatically deep immutability or thread safety.
  • Dictionary keys and set elements must be hashable: their hash stays stable, and equal objects have equal hashes. A tuple containing a list is unhashable. A user-defined mutable instance can be hashable by identity, so hashability is not synonymous with immutability.
  • Functions receive references to objects. Mutating an argument can affect the caller; rebinding a local parameter does not rebind the caller's variable.

Sources: Python hashability, object identity.

What is Big O notation?

Short answer: Big O describes how an algorithm's running time or memory usage grows as the input size n increases, dropping constants and lower-order terms. It's an upper bound on the growth rate.

In detail:

Big O answers the question "what happens when n becomes very large?". We're not interested in the exact number of operations, only the nature of the growth. That's why O(2n + 100) simplifies to O(n), and O(3n² + n) — to O(n²).

The main growth classes (from best to worst):

# O(1) — constant: doesn't depend on n
def first(arr):
    return arr[0] if arr else None

# O(log n) — logarithmic: each step halves the problem (binary search)
def binary_search(arr, target):
    lo, hi = 0, len(arr) - 1
    while lo <= hi:
        mid = (lo + hi) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            lo = mid + 1
        else:
            hi = mid - 1
    return -1

# O(n) — linear: a single pass
def total(arr):
    s = 0
    for x in arr:        # n iterations
        s += x
    return s

# O(n log n) — efficient sorts (merge, quick, Timsort)
def sort_it(arr):
    return sorted(arr)

# O(n^2) — quadratic: a nested loop
def has_dup_naive(arr):
    for i in range(len(arr)):
        for j in range(i + 1, len(arr)):
            if arr[i] == arr[j]:
                return True
    return False

# O(2^n) — exponential: naive Fibonacci, enumerating subsets
def fib_naive(n):
    if n < 2:
        return n
    return fib_naive(n - 1) + fib_naive(n - 2)

A rough guide to growth at n = 1,000,000: O(1) — 1 operation, O(log n) — ~20, O(n) — a million, O(n log n) — ~20 million, O(n²) — a trillion (already too much), O(2^n) — infeasible even at n = 50.

⚠️ Gotcha: Big O is about asymptotics (behavior at large n), not about actual time. An O(n) algorithm can be slower than an O(n²) one on small data because of large constants. People also confuse: Big O (upper bound), Ω (lower bound), Θ (tight bound); in interviews "O" usually means Θ.

What is overfitting, how do you detect it, and how do you prevent it?

Short answer: Overfitting means the model learned the noise of the training set instead of the pattern: low error on train, high error on new data. You detect it via the train/validation gap and fix it with regularization, a simpler model, early stopping, and more data.

In depth:

  1. Detection — compare train vs validation error; learning curves: train error keeps falling while validation error stalls or rises → the model started memorizing noise.
  2. Treatment — reduce capacity or add signal, don't just chase the metric.
Detect Fix
Metric gap train ≈ 0, validation clearly worse regularization (L1/L2), simpler model
Learning curves curves diverge as training goes on early stopping
Cross-validation unstable metrics across folds more data, augmentation
Model complexity deep trees, millions of weights limit depth, prune features

⚠️ Common mistake: saying "cross-validation prevents overfitting." CV only detects it — it gives an honest quality estimate. Prevention comes from regularization, simpler models, and data.

How does a decision tree choose splits, and why do deep trees overfit?

Short answer: Greedily: at each node it scans features and thresholds and picks the split with the largest impurity reduction (Gini or entropy; MSE for regression). With unlimited depth the tree drives leaves to purity — i.e. it memorizes the training set, noise included.

In depth:

  1. Split criterion — the gain: impurity(parent) − weighted impurity(children); Gini G = 1 − Σpₖ², entropy −Σpₖ·log pₖ — nearly interchangeable in practice.
  2. Greediness — each node is optimized in isolation; the globally optimal tree is NP-hard, so a bad split near the root is never revisited.
  3. Why overfitting — the model is piecewise-constant: with unlimited depth every leaf shrinks to a single sample → zero training error, high variance on test.
Constraint What it does
max_depth caps the number of levels
min_samples_leaf stops leaves shrinking to 1 sample
ccp_alpha (pruning) cuts nodes that don't pay for their complexity
Ensembles RF/boosting turn the tree's weakness into strength

⚠️ Common mistake: believing the tree finds the globally "best partition" — it's greedy, and that's a fundamental limitation, not an implementation detail.

Define precision and recall via the confusion matrix. When does each matter more?

Short answer: Precision = TP/(TP+FP) — the share of true positives among everything the model flagged as positive. Recall = TP/(TP+FN) — the share of actual positives the model found. Recall is critical where a miss is costly (cancer screening, fraud); precision where a false alarm is costly (spam filters, content takedowns).

In depth:

Actual: 1 Actual: 0
Predicted: 1 TP FP
Predicted: 0 FN TN
  1. Precision — read the "predicted: 1" row: how many of the model's alerts are real. The cost-of-false-alarm metric.
  2. Recall — read the "actual: 1" column: what fraction of real positives we caught. The cost-of-a-miss metric.
  3. Trade-off via the threshold — on a fixed dataset, lowering the threshold cannot decrease recall, but precision can rise or fall depending on the labels of the newly included observations. For scores 0.9 (negative) and 0.8 (positive), lowering the threshold from 0.9 to 0.8 increases precision from 0 to 1/2. Evaluate the actual precision–recall curve instead of assuming monotonic precision.

⚠️ Common mistake: reciting the formulas and stopping. A strong answer starts from "which is more expensive — a miss or a false alarm", and only from that decides which metric leads.

Source: scikit-learn: precision–recall curve.

Which models need feature scaling and why?

Short answer: Scaling matters for models that rely on distances, dot products, or gradient descent: kNN, SVM, k-means, PCA, regularized linear models, neural nets. Trees, forests, and boosting don't need it — they are invariant to monotone transforms.

In depth:

Model Scaling Why
kNN, k-means, SVM required distances: a feature in meters drowns out one in kilometers
PCA required variance: components chase the feature with the largest scale
Linear + L1/L2 required the weight penalty depends on feature scale
Neural nets needed gradient descent convergence
Trees / RF / boosting not needed threshold splits; value order doesn't change

And the key point: the scaler is part of the model. Fit on train only, transform valid/test — otherwise test statistics leak into training.

⚠️ Common mistake: scaling everything "just in case" before the split — a harmless habit turns into leakage; and conversely, wasting time scaling for XGBoost.

Ready to make it stick?

Explore a sample, choose a track, and build a review routine that fits your preparation.

Questions about this track

How should I prepare for an ML Engineer interview?

Study the concepts you'll be asked to explain, not just the ones you can code. RecallDeck's ML Engineer track gives you 373+ curated interview questions and resurfaces each one with an Anki-style SM-2 schedule based on your ratings — to practise recalling and explaining them. Combine reviews with coding and mock interviews.

What topics does the ML Engineer track cover?

The ML Engineer track is organised into the core areas ML 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 ML Engineer interview prep?

Yes. Active recall and spaced practice can help retain what you study. Grade yourself honestly and check your understanding with practical work. RecallDeck schedules each ML Engineer card using your ratings, so familiar cards return less often and difficult ones get more practice.

Can I try the ML Engineer track before paying?

Eligible new monthly or yearly subscribers can try the complete ML Engineer track and every feature for seven days. Checkout confirms trial eligibility and the amount due; returning subscribers may be charged immediately. Cancel online before the trial ends to avoid its first charge. Lifetime access has no trial.

Other interview tracks