← Back to blog Amazon Applied Scientist Interview Debrief: Five-Round Loop + LP
Amazon

Amazon Applied Scientist Interview Debrief: Five-Round Loop + LP

2026-08-14

The Amazon Applied Scientist (AS) interview has one defining trait: almost every round injects Leadership Principles (LP) behavioral questions, so grinding LeetCode and memorizing ML theory alone will not cut it. You must polish a handful of real project stories that can survive being drilled into detail after detail. Below is a round-by-round breakdown of what each stage evaluates, along with how the behavioral weighting differs across L4/L5/L6. Other role tracks can use it as a reference too. If you want VO assist or VO live support, you can align your pacing with this debrief.

AS Interview Flow Overview

Stage Time / Format Core Focus
Phone screen 45–60 min One LeetCode-level algorithm + ML fundamentals Q&A + 1–2 LP
Onsite round 1 Coding + LP Data-processing problem (hash map + hand-written heap) + open business question
Onsite round 2 Case study + LP Optimization theory by hand + operations-research modeling + system design
Onsite round 3 Pure Coding + Ownership OOD object-oriented design
Onsite round 4 ML Application + LP ML system design (HM-led)
Onsite round 5 Bar Raiser Leadership Principles final push

One pattern runs through the whole loop: nearly every round reserves about 15 minutes for one or two behavioral questions, so LP prep cannot be saved for the last round only.


Phone Screen: Algorithm + ML Fundamentals Combo

The phone screen is the gate to onsite. If you don't pass, the recruiter won't schedule the rest of the loop. The recipe is usually one LeetCode-difficulty algorithm question, plus ML fundamentals Q&A, seasoned with one or two LP behavioral questions.

The interviewer tends to dig deep along your resume projects. Common topics include:

What really separates candidates is the scenario-choice question: given different classification tasks, how do you pick among Logistic Regression, Decision Tree, Random Forest, and DNN? Memorizing model traits isn't enough — you must weigh data volume, feature types, degree of non-linearity, interpretability requirements, and inference cost, and articulate the trade-off logic to pass.

There are two fixed BQs, both drilled into technical detail (what problem you spotted, how you localized it, why you chose that approach, how you quantified the result):

The key takeaway: when preparing project and BQ stories, don't just memorize the hollow STAR shell — line up the technical rationale, the alternatives considered, and the final quantified result together, or you'll be exposed after two follow-ups.


Onsite Round 1: Coding + LP

Two Senior AS interviewers run this round jointly. The flow is self-introduction → deep dive into project details (why you chose that) → connecting your research direction with the team's business direction. The follow-up depth here is lighter than the phone screen.

Two BQs: how you handle a tight deadline, and how you Dive Deep. Then an open business question — no code, just approach: for a deals business, which features matter most, and how would you use ML to surface the features most likely to cause a deal to fail.

Coding Problem: The K Least-Active Users

You're given a batch of log data, each entry (user_id, timestamp). Compute each user's active days (the count of distinct dates) within a given window, and find the 5 least-active users.

It looks like a simple hash-map counting problem, but the interviewer adds a constraint — how do you optimize memory when the data volume is enormous. The optimal answer is a hash map paired with a min-heap: scan once to tally each user's set of active days, then maintain the K least-active with a size-K heap. And onsite you're not allowed to use heapq — you must hand-write the heap structure and its sift logic.

Approach:

  1. Use a hash map user -> set(day) to de-duplicate active days; keep only the count and discard the day set as you go to save memory.
  2. Maintain a min-heap holding (active_days, user). To find the "K smallest," a full build-heap then K pops is the most direct version; if memory is tight, flip to a size-K max-heap that evicts larger values on the fly.
class MinHeap:
    """Hand-written min-heap, compares on element index 0 (count). Used when heapq is banned."""

    def __init__(self):
        self.data = []

    def _swap(self, i, j):
        self.data[i], self.data[j] = self.data[j], self.data[i]

    def push(self, item):
        self.data.append(item)
        self._sift_up(len(self.data) - 1)

    def pop(self):
        top = self.data[0]
        last = self.data.pop()
        if self.data:
            self.data[0] = last
            self._sift_down(0)
        return top

    def _sift_up(self, i):
        while i > 0:
            parent = (i - 1) // 2
            if self.data[i][0] < self.data[parent][0]:
                self._swap(i, parent)
                i = parent
            else:
                break

    def _sift_down(self, i):
        n = len(self.data)
        while True:
            left, right, smallest = 2 * i + 1, 2 * i + 2, i
            if left < n and self.data[left][0] < self.data[smallest][0]:
                smallest = left
            if right < n and self.data[right][0] < self.data[smallest][0]:
                smallest = right
            if smallest == i:
                break
            self._swap(i, smallest)
            i = smallest

    def __len__(self):
        return len(self.data)


def least_active_users(logs, k=5):
    """logs: List[(user_id, timestamp)]; timestamp is epoch seconds.
    Returns the k user_ids with the fewest active days."""
    day_sets = {}
    for user, ts in logs:
        day = ts // 86400                 # normalize to a "day"
        day_sets.setdefault(user, set()).add(day)

    heap = MinHeap()
    for user, days in day_sets.items():
        heap.push((len(days), user))      # (active_days, user)

    result = []
    for _ in range(min(k, len(heap))):
        count, user = heap.pop()
        result.append(user)
        _ = count
    return result

Time complexity: tally O(N), build-heap plus K pops is O(M + K log M), where M is the user count and N the log count. Space complexity: O(M). If memory is tight, swap the min-heap for a size-K max-heap that evicts as it scans, dropping space to O(K).


Onsite Round 2: Case Study + Optimization Theory (Principal AS technical round)

This round starts with a project deep dive, then turns to hardcore optimization theory:

Here is a gradient descent reference you can hand-write onsite, using the most basic linear-regression MSE as the vehicle:

import numpy as np


def gradient_descent(X, y, lr=0.01, max_iter=1000, tol=1e-6):
    """Batch gradient descent minimizing MSE.
    X: (n, d), y: (n,). Returns weights w and bias b."""
    n, d = X.shape
    w = np.zeros(d)
    b = 0.0
    prev_loss = float("inf")

    for it in range(max_iter):
        pred = X @ w + b
        error = pred - y
        loss = np.mean(error ** 2)                 # MSE

        grad_w = (2.0 / n) * (X.T @ error)         # gradient w.r.t. w
        grad_b = (2.0 / n) * np.sum(error)         # gradient w.r.t. b

        w -= lr * grad_w
        b -= lr * grad_b

        if abs(prev_loss - loss) < tol:            # converged: loss no longer drops much
            break
        prev_loss = loss

    return w, b

Time complexity: O(n·d) per iteration, O(T·n·d) over T iterations. The stopping criterion is usually "loss change < tol" or hitting max iterations; too large a learning rate oscillates and fails to converge, too small converges too slowly.

Next comes an operations-research modeling question: design a replenishment plan for a distribution center that minimizes transport and inventory cost under demand, supply, and warehouse-capacity constraints. A follow-up asks how the objective and optimal strategy change when items have dynamic surge pricing.

The case study is designing a fresh-grocery delivery system that solves both vehicle routing and arrival-time prediction, accounting for real-time traffic, time windows, shelf life, and vehicle capacity. Follow-ups land on model training and evaluation — routing optimization cares about total mileage, cost, and on-time rate, while time prediction is measured by MAE, RMSE, and the late-order ratio; Precision / Recall don't apply here, and you need to argue that distinction on the spot. It wraps up with a 3D bin-packing problem: given cargo dimensions, weight, and truck space, how to arrange loads to raise the fill rate while satisfying load-bearing, orientation, and stacking constraints.


Onsite Round 3: Pure Coding (with one Ownership BQ mixed in)

After a quick Ownership behavioral question, the interviewer goes straight into coding. The problem is an OOD design — an item rental system that needs Item, User, and Rental entity classes, with a Manager class exposing borrow, return, and query interfaces.

The problem itself isn't hard; the focus is whether class responsibilities are cleanly split, whether object relationships are reasonable, and whether the code leaves room to extend. Follow-ups pile on: add due dates and late-fee logic, support fuzzy search by name, provide an interface returning the full catalog, and how you'd design unit tests. Overall it tests object-oriented modeling and interface design, not algorithmic tricks.

from dataclasses import dataclass
from typing import Dict, List, Optional


@dataclass
class Item:
    item_id: int
    name: str
    available: bool = True


@dataclass
class User:
    user_id: int
    name: str


@dataclass
class Rental:
    item_id: int
    user_id: int
    due_day: int
    returned_day: Optional[int] = None


class RentalManager:
    """Rental system entry point: borrow, return, search, catalog, late fees."""

    LATE_FEE_PER_DAY = 5

    def __init__(self):
        self.items: Dict[int, Item] = {}
        self.users: Dict[int, User] = {}
        self.rentals: List[Rental] = []

    def add_item(self, item: Item) -> None:
        self.items[item.item_id] = item

    def add_user(self, user: User) -> None:
        self.users[user.user_id] = user

    def borrow(self, user_id: int, item_id: int, due_day: int) -> bool:
        item = self.items.get(item_id)
        if item is None or not item.available or user_id not in self.users:
            return False
        item.available = False
        self.rentals.append(Rental(item_id, user_id, due_day))
        return True

    def give_back(self, user_id: int, item_id: int, today: int) -> int:
        """Return the item and report the late fee owed (0 if not overdue)."""
        for r in self.rentals:
            if r.item_id == item_id and r.user_id == user_id and r.returned_day is None:
                r.returned_day = today
                self.items[item_id].available = True
                overdue = max(0, today - r.due_day)
                return overdue * self.LATE_FEE_PER_DAY
        raise ValueError("no matching open rental record")

    def search(self, keyword: str) -> List[Item]:
        kw = keyword.lower()
        return [it for it in self.items.values() if kw in it.name.lower()]

    def catalog(self) -> List[Item]:
        return sorted(self.items.values(), key=lambda it: it.item_id)

Design notes: the Manager holds dict indexes over entities for O(1) lookup; borrow/return just flips the available flag and appends a record, which makes it easy to extend later with reservation queues or multi-copy inventory. Late fees come from the gap between due_day and the return day. Keeping each interface single-purpose makes unit testing straightforward.


Onsite Round 4: ML Application + LP (Hiring Manager-led)

This round leans into ML system design, built around real business scenarios like ad recommendation and CTR estimation. A good answer unfolds in a fixed order: requirement clarification → data and features → model selection → training and offline evaluation → online deployment → monitoring and A/B testing.

Note: L4 candidates aren't always scheduled for this round. It tests the breadth of your ML knowledge, spanning from linear regression all the way to Transformers. Common topics include L1 / L2 regularization, overfitting, vanishing gradients, loss-function design, and how Transformers work. When reviewing, don't just memorize definitions — be able to explain each method's use cases, pros, and cons, because interviewers love to ask "when should you not use this."


Onsite Round 5: Bar Raiser (LP final push)

This round is led by a Bar Raiser from outside the hiring team, focused on Leadership Principles, and it carries heavy weight in the final offer decision. But be clear on one thing: nearly every prior round already reserved about 15 minutes for one or two behavioral questions, so LP prep can never be saved for the last round alone.

L4 / L5 / L6 Behavioral Weighting

Level LP Depth Emphasized LP Dimensions
L4 Tell one complete story clearly; one layer of follow-up Learn and Be Curious, Ownership
L5 Show cross-team collaboration and technical decisions; two to three layers of follow-up Dive Deep, Deliver Results, Earn Trust
L6 Demand strategic vision, influence, and leading people/projects Think Big, Have Backbone, Hire and Develop

The higher the level, the more interviewers want to see your influence at a broader scope and your judgment when facing disagreement; the scale and complexity of your stories must rise accordingly.


Prep Tips


FAQ

Q1: What's the biggest difference between the Amazon AS and SDE interviews?

Beyond algorithms, AS also tests ML fundamentals, optimization theory, and ML system design, and its behavioral questions drill into technical detail. SDE leans more toward pure algorithms and system design, with little ML theory. AS candidates must prepare Coding, ML theory, and LP in parallel.

Q2: How hard is the phone-screen algorithm question?

Usually a LeetCode medium-to-hard, alongside ML fundamentals Q&A and LP. The algorithm itself isn't especially tricky, but expect added constraints like memory optimization and hand-written data structures — the test is whether you can articulate and implement the optimal solution under pressure.

Q3: Does every Applied Scientist round include behavioral questions?

Essentially yes. Besides the Bar Raiser dedicated to LP, every earlier round reserves 10–15 minutes for one or two behavioral questions. So LP prep must run through the entire loop, not just the final round.

Q4: How do L4, L5, and L6 differ in the interview?

The higher the level, the more the behavioral rounds weigh cross-team influence, strategic vision, and leading people/projects, with more layers of follow-up; the technical rounds expect more mature system design and deeper theory. L4 may skip the ML system-design round, while L5/L6 usually include it.

Q5: What if libraries like heapq are banned onsite?

Practice hand-writing the sift-up/sift-down logic for min-heaps and max-heaps until it's fluent, and be able to implement gradient descent and KNN from scratch. Banning libraries is precisely how interviewers check your real grasp of the underlying data structures and algorithms — memorizing APIs won't help.


Preparing for an Amazon Applied Scientist or another ML / AS VO? We know the AS-style loop that tests algorithms + ML theory + optimization + LP in parallel, and we can help you technicalize your project stories, sharpen hand-written algorithms, and cover LP across the loop in one pass, with full VO assist and VO live support.

Add WeChat Coding0201 now to get a one-on-one custom prep plan.

Contact