HackTheRounds Interview Experiences
Anthropic Software Engineer Interview Experience (2026) - Banking System OA, Web Crawler & LRU Persistence, Offer
Anthropic SDE loop: CodeSignal Banking System OA, HM multi language code review, onsite with concurrent Web Crawler, Claude serving system design, persistent LR
By Anonymous ยท 2026-03-28
Background
Just finished Anthropic's SDE loop. I want to flag up front that this is the SDE track, not the Research Engineer track. The questions and the evaluation are noticeably different between the two, and I've seen candidates confuse themselves by prepping the Research Engineer material only to get hit with a banking-system simulation on the OA. I came in with about 3 years of backend experience at a mid-stage infra startup, mostly Python and Rust, and applied in late January. The whole pipeline took about 6 weeks from application to offer.
Anthropic's SDE loop has four interview stages after the recruiter call: a coding take-home, a hiring manager call, and a four-round onsite. The coding volume is genuinely higher than any other 2026 loop I did, including the FAANGs.
Timeline
- Application: late January
- Recruiter call: 1 week later
- Coding challenge (CodeSignal take-home): 2 weeks after recruiter call
- Hiring manager call: 5 days after coding
- Onsite (4 rounds, same day): 2 weeks after HM
- Offer call: 4 business days after onsite
Total: about 7 weeks.
Recruiter Call (30 min)
Not technical. Mostly questions about why Anthropic, what I know about the org, and which teams I had in mind. One non-obvious question: "What does B Corp certification mean and why does Anthropic have it?" I had read the About page that morning and knew that Anthropic was the first AI lab with a B Corp certification, which signals accountability to stakeholders beyond shareholders. She seemed glad I could answer without stalling.
Second non-obvious question: "In your own words, what is Anthropic's thesis on AI safety?" I talked about Constitutional AI at a high level: using a set of principles to shape model behavior during training rather than relying only on human preference data after the fact. She did not grade me on accuracy, but she did grade on whether I could speak about it without buzzwords.
If you cannot fluently explain CAI, RLHF, and why Anthropic cares about the distinction, redo this prep before the recruiter call or you will get filtered.
Coding Challenge (90 min take-home CodeSignal)
Problem: Banking System simulation.
You implement a BankingSystem class that passes a hidden test suite. The operations come in tiers and build on each other:
- Create account
- Deposit
- Transfer
- Pay (with cashback rules on a delay)
- Query transaction history
- Merge two accounts (history, balances, and scheduled cashback all have to combine)
- Query cashback status
- Query current balance
The evaluation is test-case based but some test cases hide concurrency behavior. The spec does not explicitly say "thread-safe" but if you leave obvious race windows, later tests fail on non-deterministic outputs.
I budgeted 15 minutes to read the spec carefully and take notes, 60 minutes to code in tiers, and 15 to test.
The structure I landed on was a BankingSystem class holding a balances dict, a per-account history list, a timestamp-sorted cashback queue, a cashback status dict, and a merged into redirect map. A single RLock guards everything and every public method first resolves the account id through the merge redirects.
Three design calls that paid off:
- Always resolve through merge redirects. Every public method calls `_resolve` first. Then a merge is just a pointer update plus history concat, not a data copy.
- Cashback as a priority queue keyed on timestamp. On any operation I lazily process all cashback events with `fire_ts <= now()` before executing the request. Means cashback fires in deterministic order relative to reads.
- Single coarse lock. I did not try to shard locking across accounts. Simpler code, and the hidden concurrency test cases seemed satisfied. If this were a production system I'd reconsider, but a take-home is not where you fight with lock granularity.
I passed all public test cases. Never saw the hidden ones but the recruiter told me the overall score was "strong."
Practice it: [[problem/330?company=7|Banking System]]
Hiring Manager Call (60 min)
This was not a standard behavioral round. It had two parts, and the first was normal project deep-dive while the second was something I had not seen before.
Part 1: Project deep dive. Pick your most technically involved project. The HM will drill on specific implementation choices and ask what you would do differently. I had rehearsed a streaming job rewrite project where we moved from Kinesis to Kafka and had to solve exactly-once delivery. He asked about the consumer-rebalance behavior, why we chose idempotent producers over transactional semantics, and how we handled schema evolution. Thirty minutes on a single project. You want something you can defend at a level of detail most people stop at.
Part 2: Code review. He pasted code into the shared doc. Three snippets, in Python, JavaScript, and Rust, maybe 30 to 50 lines each. For each snippet I had to identify what it did, point out bugs or smells, and suggest improvements. The code was subtle:
- The Python snippet had a closure bug where a loop variable was captured by reference in a list of lambdas.
- The JavaScript snippet had an async/await flow that unnecessarily serialized three independent fetches.
- The Rust snippet was a cache implementation that called `.unwrap()` on a lock acquisition, which would panic if another thread had poisoned the mutex.
I caught all three. The interviewer said afterward that this round filters people who can write code but cannot read unfamiliar code. If you are a Rust primary and panic on reading async JavaScript, this round will hurt.
Onsite Round 1: Coding โ Web Crawler
Problem: Implement a single-domain web crawler in Python. You are given a helper get urls(url) - list[str] that handles HTTP and link extraction. Your job is to BFS from a seed URL and collect every same-domain URL reachable.
I wrote the synchronous version first in about 10 minutes: a standard BFS from the seed URL with a seen set, a deque, and a same-domain filter using urlparse().netloc . The interviewer asked: "If get urls is slow because of network latency, how do you parallelize this?"
Switched to ThreadPoolExecutor with a shared seen set guarded by a lock, and a queue of futures. Key detail: I used as completed so each finished fetch immediately spawned child fetches rather than waiting for a full BFS level.
The follow-up train got specific:
- How do you make it polite? I added a per-domain rate limit via a token bucket. For a single-domain crawler this reduces to a simple minimum delay between requests.
- How do you detect duplicate content at different URLs? I proposed a content hash on the response body stored in a second set.
- Threads vs processes here? Threads, because this is I/O-bound. `get_urls` is a network call. The GIL does not hurt us when the thread is waiting on a socket.
- How do you scale to millions of URLs? I sketched a distributed version: a Kafka queue of URLs, N worker processes, shared Redis for the seen set with a Bloom filter in front to cap memory.
Practice it: [[problem/594?company=7|Web Crawler - Concurrent Version]]
Onsite Round 2: System Design โ Serve Claude to Millions of Concurrent Users
Problem: Design the serving infrastructure for a chat model that has to serve many concurrent users over a single-threaded autoregressive decoding loop per user.
This was my favorite round because the questions were genuinely specific to the domain and not generic "scale Twitter."
My architecture:
- Request router. Authenticate, check rate limits per API key, route to a regional cluster.
- Batching layer. The key observation: GPU utilization is poor if you run one user's decode at a time. Continuous batching (in the style of vLLM) lets us interleave tokens from multiple active sessions through the same GPU. I talked through the sliding-batch vs static-batch tradeoff.
- KV cache. Per-session KV cache lives on the GPU for the duration of the session. Evict to CPU when sessions go idle beyond a threshold. Evict to disk on very long idleness.
- Streaming. SSE from the server to the client. Each token flushes as soon as the scheduler emits it.
- Safety hooks. Pre-generation content filter plus a sampling-time filter that can abort generation mid-token if the rolling logits suggest a policy violation.
The interviewer pressed on point 2. "How do you handle a session whose user sends a very long prompt? Does that stall batching for others?" My answer: prefill is expensive and stall-inducing, so the scheduler separates prefill and decode stages. Long-prefill requests are deprioritized so they don't block short decode work. She said that's what Anthropic actually does.
Last 10 minutes: "Where would you add monitoring for reward hacking or jailbreak attempts in this pipeline?" I drew a tap at the sampling layer: log per-token logit distributions for a sampled fraction of requests, run them through an offline alignment evaluation pipeline.
Onsite Round 3: Coding โ Persistent LRU Cache
Problem: Extend a given in-memory LRU cache to support disk persistence. After the process restarts, cached items that existed before the restart should still be there. Also, there is a bug in the existing code; find it first.
The bug was in the key-generation step. The cache was using Python's default hash() which varies per interpreter run (hash randomization is on by default in Python 3). Two requests from the same logical key would map to different cache slots after a process restart. I caught it in about 2 minutes.
Once the bug was fixed, I extended the cache with a write-through to SQLite. On put(key, value) , write to the in-memory OrderedDict and asynchronously flush to disk. On process start, reload the top N entries by recency from disk. Keep write amplification low with a simple journal pattern: append-only log of operations, periodic snapshot, truncate the log after snapshot.
Follow-up: "How do you make this work across multiple processes reading and writing concurrently?" My sketch: switch from a local file to a shared-memory + fsync pattern (or, more realistically, move the cache to a Redis instance and keep disk only as a cold tier).
Practice it: [[problem/326?company=7|LRU Cache with Disk Persistence]]
Onsite Round 4: Behavioral + AI Ethics
Not a standard behavioral round. Half the questions were about ethics and policy.
Behavioral questions I got:
- Tell me about a project where you disagreed with the direction.
- Tell me about a time you broke production.
- Tell me about a time you thought someone's work was unsafe and how you handled it.
Ethics / policy questions:
- What categories of AI misuse concern you most in the next 12 months?
- If a customer asked our system to help them write a convincing phishing email, walk me through how you'd design the refusal.
- How would you measure, quantitatively, whether a model is honest?
- In which situations is it acceptable for an LLM to refuse to answer even when no obvious harm is present?
The interviewer did not want pat answers. She was watching whether I could hold nuance: acknowledge uncertainty, name tradeoffs, avoid both naive techno-optimism and performative doom. My most honest answer was to the "unsafe work" question. I talked about a time we shipped a consent flow that I thought moved the line on what users truly understood, and how I escalated internally without being preachy about it. She nodded and said "that's useful."
Result
Recruiter called on Wednesday. SDE offer, San Francisco. Compensation conversation took two rounds but landed within expected range for the level.
Tips
- The Banking System OA is the SDE loop's filter. Half the candidates I know who applied to the SDE track got filtered here. Prep by building an in-memory banking class from scratch in one sitting. The skill being tested is incremental complexity management, not algorithms.
- HM code review is underpublicized. Practice reading code in languages that aren't your daily driver. Pick a project in Rust or JavaScript (whichever is less familiar), read its source, and practice narrating what it does without running it.
- For the web crawler problem, default to `ThreadPoolExecutor` not `asyncio`. Easier to reason about, easier to explain, the interviewer will still let you discuss the async version. If you try async cold and get the semantics wrong, you sink time recovering.
- Know vLLM's continuous batching vocabulary. Prefill, decode, KV cache, continuous vs static batching. These terms appear in the system design round and having them ready changes the entire conversation.
- For the ethics round, prepare three genuinely hard questions you actually hold. Do not prep company-friendly answers. The interviewer is a researcher and she can smell scripted answers from across the video call. Pick things you have thought about and can defend under pushback.
- Do not take the Research Engineer track's prep material and apply it here. The SDE loop asks different questions: less RLHF mechanism, more systems. If you prep Constitutional AI internals for hours and don't touch banking-system-style code, you will regret it on day of.