The Forward Deployed

Interview Practice

Forward Deployed Engineer Codebase and Learning Drills

Practice becoming useful quickly in unfamiliar code by tracing one path, forming hypotheses, reproducing failures, and defending every change.

By Reviewed

Two Palantir rounds test the same muscle, and it's the one the job runs on every day: getting useful fast in code you've never seen. (Both are reported in candidate accounts, a personal write-up and anonymous forum posts, so treat the specifics as corroboration rather than proof.) In the re-engineering round, you "fix bugs in a codebase of over 250 lines" with subtle logical flaws. A described example was a "double-counting issue." In the learning round you build against unfamiliar documentation. One candidate account describes being handed interviewer-written modules to enhance using the library docs supplied, and another, preparing for the round, planned to "read the API or docs of a language [they] haven't messed around with" and implement something basic. This is the interview version of week one on any engagement: dropped into a customer's unfamiliar stack, be productive by the afternoon.

The signal is not "do you already know this code." It's whether you orient before you type: read the one path that matters, form a hypothesis, and use the tools and docs (including AI assistants) to close the gap fast.

Drill 1 — the subtle bug in unfamiliar code

Prompt: you're given ~250 lines you've never seen, say an order-totaling service, and told a test is failing: some orders report a total that's slightly too high. Find and fix it. (The bug shape mirrors the "double-counting issue"; the code is invented for practice.)
Before reading on: you have twenty-five minutes. What do you do in the first five? It isn't "read all 250 lines top to bottom."

Bad / Good / Great — the first five minutes

Bad — read everything, then start editing. You scroll all 250 lines, lose the thread by line 120, and start changing things that look suspicious. Now you're debugging your own edits on top of the original bug. The interviewer sees someone who can't orient.

Good — read the failing test, then the relevant function. You open the test, see what input produces the wrong total, and jump to the totaling function. Solid. If you then start editing on the first suspicious line, you're guessing. Better than shotgunning the whole file, but still not a hypothesis.

Great — reproduce, hypothesize out loud, then confirm. "The test says a two-item order overcounts. Let me trace one order through: it's summed in the loop here, and there's also a subtotal field set in addItem. I bet tax or a discount is being applied in both places. Let me add a print to confirm before I touch anything... yes, the discount is subtracted in the loop and again in finalize. That's the double-count. I'll fix it in finalize and re-run the failing test plus one I'll add for a discounted order." You never edited on a guess, and you left the code with a test that proves the fix.

The probe to expect

Interviewer: "You found it fast. What if you hadn't been able to reproduce it?"
You: "Then I'd narrow by bisecting the path: comment out the discount logic and see if the total's right, then the tax, until the wrong number moves. I trust reproduction over reading, because a bug I can't reproduce is a bug I can't prove I fixed."

Drill 2 — the unfamiliar API

Prompt: here are the docs for a library you've never used. Build a small working thing against it in twenty minutes, say, call this vector-store client to index three documents and run a query.
Before reading on: you don't know this API. What's the fastest path to a working call, and what do you read first?

Bad / Good / Great — learning on the clock

Bad — read the docs front to back. You start at the overview and read every page. Twenty minutes later you understand the library and have written nothing. The round tests shipping under unfamiliarity, and you didn't ship.

Good — find an example and adapt it. You search the docs for a quickstart, copy the closest snippet, and modify it. Good, this is how real engineers move. If it breaks and you go quiet debugging silently, you lose the narration signal.

Great — quickstart first, narrate the gaps, use every tool. "I'll grab the quickstart to get a call working, then adapt it to three docs. The signature wants an embedding function. The docs say it defaults to one, so I'll rely on that for now and note it. It errored on the query shape; let me check the reference for the query method's arguments... it wants a list rather than a string. Fixed." You got to a working call fast, said what you assumed and why, and treated the docs (and, where allowed, an AI assistant) as the tools they are on the job.

The probe to expect

Interviewer: "You leaned on the quickstart and the docs a lot. Is that how you'd really work?"
You: "Yes. On an engagement I'm productive in a new stack by reading the one path I need and standing on the examples, not by mastering the whole library first. I'd go deeper where it matters. Here, I'd read carefully on how embeddings and persistence work, because that's where correctness lives. I read deeply where the risk is and shallowly everywhere else."

Drill 3 — AI-assisted, done well

Prompt: same unfamiliar-codebase task, but you're allowed an AI coding assistant. Fix the failing test.
Before reading on: an assistant can write the fix for you. What does a strong candidate do differently from one who just pastes the error in and ships whatever comes back?

Bad / Good / Great — operating the assistant

Bad — paste the error, ship the reply. You hand the assistant the stack trace, get a plausible patch, and apply it without reading it. It might even pass the one test. But you can't explain why it works, and when the interviewer changes an input, you're stranded. You demonstrated that the assistant can code, not that you can.

Good — use it to explore, then verify. You ask it to explain the totaling function and suggest where the double-count might be, read its answer, and confirm against the code. That's the assistant as a fast reader, legitimate and effective.

Great — drive it, verify it, own it. "I'll ask it to locate where the discount is applied, because that's my hypothesis. Then I read the two call sites myself before trusting it. I'll write the failing test first so I'm grading its fix against something real, not its own say-so. And I'll keep the change small enough that I can explain every line, because in front of a customer I have to defend it." You used the assistant to go faster and stayed the engineer accountable for the result. That last part is the whole FDE posture, and this author's related course on operating coding agents treats it in depth.

The probe to expect

Interviewer: "The assistant wrote most of that. What did you add?"
You: "The hypothesis, the failing test that proved the fix, and the judgment to keep the change small and explainable. The assistant is fast; it's not accountable. On a customer's system, I am. So I verify what it gives me and I only ship what I can defend."

How to practice this

Both halves of this round can be drilled solo, on repeat. The Rep Kit below turns them into a protocol: an assistant that seeds a bug for you without saying what it is, and a bank of unfamiliar-library tasks. Grade yourself on orientation, not on prior knowledge: did you trace one path, hypothesize before editing, and reproduce before fixing? Getting useful fast in unfamiliar code is the FDE's daily reality; the round just puts a clock on it.

Rep Kit

The drills above explain their own answers, so they stop being tests after a first reading. This round has an advantage over the others, though: an AI assistant can manufacture fresh, genuinely unseen tests for you on demand. The protocol below makes it hide a bug from you; the bank after it holds twenty learning-round tasks. In both, narrate the entire time and grade against the frame at the top of this page: trace one path, hypothesize before changing anything, reproduce before fixing, and say what you'd do with more time.

The seeded-bug protocol

Paste the block below into a capable AI chat, unmodified. It sets up the round, tracks the clock you report, demands narration, and grades against the frame. Where the chat supports voice mode, use it. Every one of these rounds is spoken.

You are the bug-seeder and timekeeper for a Forward Deployed Engineer
re-engineering drill.

Setup:
1. I will tell you a language I am comfortable in and pick one of two setups:
   - "generate": write me a self-contained program in that language — a few
     hundred lines, real logic (totaling, parsing, scheduling, caching), no
     external dependencies — with exactly ONE subtle logic bug seeded in it:
     the kind that still runs and produces plausibly wrong output (an
     off-by-one, a double-count, a wrong boundary, a swapped condition).
     Give me the complete code to save and run.
   - "real repo": I will pick a single open-source file, a few hundred lines at most,
     paste its full contents into this chat, and set the original aside
     unopened (comparing files would find the bug without the drill). You return the SAME code with exactly
     ONE subtle logic bug of that kind introduced, as the complete file, top to
     bottom — never a diff or a patch, and never an elision like "rest
     unchanged"; if the file is too long to return whole, say so and stop —
     changing nothing else.
2. Either way, do NOT tell me what the bug is, where it is, or what kind it
   is. Describe only the symptom, the way a ticket would: "this input
   produces a slightly wrong result."
3. Give me one failing input and its expected output — and, for pasted
   code without an entry point, a minimal snippet that exercises it — so I
   can reproduce the failure before I hunt. Derive the expected output by
   tracing the code, keep the input small enough to check by hand, and
   confirm the seeded bug actually changes the output for that input.

Running the round:
4. I run a twenty-five-minute timer myself and prefix each message with
   my elapsed minutes; when my reported time passes twelve and twenty
   minutes, tell me how long remains, and call time at the end.
5. Demand narration. If any message of mine reports an edit or a
   conclusion without the reading and hypothesis that led to it, ask:
   "What are you thinking?" Treat that as a mark against me.
6. Give no hints unless I explicitly say "hint" — then give the smallest one
   possible: which region of the file, then which function, then which line, one level per
   request, and note each hint in the grade.

Grading (when I say "done" or time runs out):
7. Reveal the bug. Grade against four moves, citing specific moments: (a) did
   I trace one path from input to the wrong output instead of reading
   everything; (b) did I state a hypothesis and confirm it (a print, a trace, a
   re-read) before changing anything; (c) did I reproduce the failure before fixing it, and verify
   after; (d) did I say what I would do with more time — the test I would
   add, the edge I left. Grade hard: a typical first rep fails at least two of the four moves — if none failed, re-examine before praising, and never soften a grade because I argue with it.
8. End with exactly one thing to fix on the next rep. Then offer to seed a
   fresh bug in a new area.

The learning-round bank

  • Index three short documents and run one similarity query with a vector-store client (Chroma, Qdrant, or Weaviate).
  • Publish one message and read it back with a message queue (NATS, Redis streams, or RabbitMQ).
  • Draw a bar chart from a hard-coded list with a plotting library outside your usual stack (Vega-Lite, ggplot2, or Plotly).
  • Write one record and read it back with an embedded database you've never touched (DuckDB, LevelDB, or SQLite from a language you don't use).
  • Schedule a job to fire in ninety seconds with a scheduling library (APScheduler, node-cron, or Quartz).
  • Parse a date out of a messy string with a date-time library in a language you don't write daily (java.time, chrono for Rust, or Luxon).
  • Validate a nested configuration object with a schema-validation library (pydantic or zod).
  • Extract every link from a live web page with a scraping library (BeautifulSoup, cheerio, or goquery).
  • Resize an image and write it to disk with an image library (Pillow, sharp, or ImageMagick's bindings).
  • Fill and render a template with a templating engine outside your stack (Jinja, Handlebars, or Tera).
  • Count the tokens in a paragraph with a tokenizer library (tiktoken or Hugging Face tokenizers).
  • Stand up a one-route web server in a framework you've never used (Fastify, Actix, or Sinatra) that echoes back a query parameter.
  • Read a spreadsheet and sum one column with a spreadsheet library (openpyxl or SheetJS).
  • Define one message type and round-trip it through a serialization library (protocol buffers or MessagePack).
  • Turn one sentence of text into audio with a text-to-speech client, or one audio clip into text with a transcription library.
  • Run one point-in-polygon check with a geospatial library (Shapely or Turf.js).
  • Compute a file's checksum and verify it with a cryptography library you've never called directly (libsodium bindings or Web Crypto).
  • Load a small public dataset and filter it with a data-frame library outside your usual one (Polars, dplyr, or DataFrames.jl).
  • Stream a model's response token by token using a language-model provider's client library you haven't used, printing as it arrives.
  • Parse a Markdown file into a list of its headings with a Markdown parser (markdown-it, goldmark, or comrak).

A task passes when one call works end to end and you can say out loud what you assumed and where you'd read deeper if correctness mattered. Grade against the frame, on a twenty-minute timer, narrating throughout: quickstart first, name the gaps as you hit them, read deeply only where the risk is. Docs are always allowed; add an AI assistant when you're drilling the assistant-permitted variant from Drill 3.

Next: AI System Design Cases. Defend a production system, where the senior move is leading with how you'd measure correctness, not with the architecture.
NextAI System Design Cases