Meta Applied Scientist Interview Preparation Guide - Junior Level
Meta's Applied Scientist interview process evaluates your ability to conduct applied research, implement ML/AI solutions, and bridge theoretical concepts with production systems. The process consists of phone screens followed by an onsite loop assessing research fundamentals, algorithm implementation, system design for ML systems, statistical reasoning, coding proficiency, and cultural fit. Success requires demonstrating technical depth, clear communication of research ideas, ability to implement and validate solutions, and collaboration mindset.
Interview Rounds
Recruiter Screening
What to Expect
Initial conversation with a Meta recruiter to assess your background, interest in the Applied Scientist role, and fit with the company culture. The recruiter will discuss your previous research and industry experience, explain the interview process timeline and expectations, answer questions about the role and Meta, and gauge your motivation for applied research vs. pure academic research.
Tips & Advice
Prepare a clear 1-2 minute summary of your research background and key projects. Articulate why you're transitioning to applied research at Meta. Research Meta's AI/ML initiatives and products that leverage these technologies. Ask thoughtful questions about the team, research direction, and how research influences product decisions. Be authentic and enthusiastic about applied research problems. Clarify the role's focus on real-world impact versus pure research.
Focus Topics
Meta's AI/ML Initiatives and Products
Knowledge of Meta's major AI/ML products and research areas (e.g., recommendation systems, computer vision, language models, content moderation, ranking algorithms). Understand how research translates into product features.
Practice Interview
Study Questions
Research Background and Experience Summary
Concise overview of your ML/AI projects, research focus areas, and key technical contributions. Emphasize projects where you moved from research to implementation or had measurable impact.
Practice Interview
Study Questions
Motivation for Applied Research at Scale
Clear explanation of why you want to do applied research at a tech company rather than remain in pure research or academia. Connect your interests to Meta's business problems and products.
Practice Interview
Study Questions
Technical Phone Screen 1: ML Research Fundamentals
What to Expect
First technical interview assessing your understanding of machine learning theory, statistical foundations, and research methodology. You will discuss a real applied ML problem, design an experiment or approach to solve it, and explain your reasoning. The interviewer evaluates your ability to think through research problems systematically, make sound statistical decisions, and communicate complex ideas clearly.
Tips & Advice
Expect an open-ended problem like 'How would you improve a recommendation system's diversity?' or 'Design an experiment to validate a new ranking algorithm.' Ask clarifying questions to understand constraints, metrics, and business context. Structure your approach: define success metrics, identify assumptions, outline your experimental design, and discuss potential pitfalls. Explain your statistical reasoning at each step. For junior level, demonstrate sound fundamentals and logical thinking rather than novel insights. Be honest about what you don't know and show willingness to learn. Practice explaining trade-offs (e.g., accuracy vs. interpretability, precision vs. recall).
Focus Topics
Trade-offs and Limitations in ML Systems
Understanding of accuracy vs. latency, interpretability vs. performance, fairness vs. optimization objectives, computational cost vs. quality. Ability to articulate when simple solutions outperform complex ones.
Practice Interview
Study Questions
Applied ML Problem-Solving Framework
Systematic approach to applied problems: problem scoping, baseline establishment, data understanding, solution design, evaluation, and iteration. Know when to use simple baselines vs. complex models.
Practice Interview
Study Questions
Statistical Inference and Hypothesis Testing
Understanding of p-values, confidence intervals, statistical significance, power analysis, and minimum detectable effect (MDE). Know when to use t-tests, chi-square tests, and multi-armed bandit approaches.
Practice Interview
Study Questions
Hypothesis Formation and Experimental Design
Ability to translate vague product problems into testable hypotheses. Design A/B tests, offline experiments, or evaluation methodologies. Define control conditions, treatment conditions, and success metrics clearly.
Practice Interview
Study Questions
Metrics Definition and Business Impact
Ability to translate vague product goals into quantifiable metrics. Understand leading vs. lagging indicators, proxy metrics, and overall evaluation criteria (OEC). Connect technical improvements to business outcomes.
Practice Interview
Study Questions
Technical Phone Screen 2: Coding and Algorithm Implementation
What to Expect
Technical coding interview assessing your ability to implement ML algorithms and write production-quality Python code. You will implement a machine learning algorithm or solve a data manipulation problem. The focus is on code clarity, correctness, testing, and your ability to explain algorithmic decisions. This round also evaluates problem-solving approach and communication during implementation.
Tips & Advice
Before coding, clarify the problem, constraints, and edge cases. Ask for clarification on input format, output requirements, and performance expectations. Explain your approach and discuss trade-offs before implementing. Write clean, modular code with descriptive variable names. Test your code with multiple test cases including edge cases. Explain your code as you write it. For ML-specific problems, you may need to implement gradient descent, decision trees, or data preprocessing. Know time and space complexity. Practice implementing algorithms from scratch in Python without frameworks where possible. If stuck, think out loud, ask for hints, and show you can pivot approaches.
Focus Topics
Testing and Validation of Code
Writing test cases, testing edge cases and boundary conditions, debugging code systematically. Understanding numerical stability and correctness verification.
Practice Interview
Study Questions
Algorithm Complexity Analysis
Understanding and articulating time and space complexity of implementations. Recognizing optimization opportunities and computational bottlenecks. Comparing algorithmic approaches based on complexity.
Practice Interview
Study Questions
Data Manipulation and Preprocessing
Efficient data handling, cleaning missing values, feature engineering, normalization, and working with DataFrames. Understanding data structures and algorithmic complexity of operations.
Practice Interview
Study Questions
Python Implementation of ML Algorithms
Ability to implement core algorithms: gradient descent, decision trees, k-means clustering, logistic regression, or neural networks from scratch. Demonstrate understanding of algorithm mechanics, not just library usage.
Practice Interview
Study Questions
Clean Code and Software Engineering Practices
Writing readable, maintainable code with clear variable names, proper structure, and documentation. Avoiding code duplication, handling edge cases, and following Python conventions.
Practice Interview
Study Questions
Onsite Round 1: Advanced ML Algorithms and Implementation
What to Expect
Deeper technical interview focused on implementing sophisticated ML algorithms and solving complex data problems. You will work on a more challenging problem that requires combining multiple techniques or optimizing an implementation. The interviewer assesses your ability to think through algorithmic complexity, optimize solutions, and handle real-world constraints like missing data or scalability.
Tips & Advice
Expect more complex problems than phone screens, possibly involving optimization, novel combinations of techniques, or scaling challenges. Start by understanding the full problem and constraints before diving into implementation. Consider multiple approaches and discuss trade-offs. Write code incrementally, testing as you go. If the problem involves numerical methods or optimization, be prepared to discuss convergence, stability, and numerical precision. Show your ability to recognize when a problem requires specialized techniques. Communicate your reasoning clearly. If you get stuck, talk through the problem, ask for hints, and show you can recover. At junior level, solving the problem correctly with a clear approach matters more than a perfectly optimized solution.
Focus Topics
Numerical Computing and Stability
Understanding numerical precision issues, floating-point arithmetic, and stability of algorithms. Recognizing and avoiding common pitfalls like underflow, overflow, and ill-conditioned systems.
Practice Interview
Study Questions
Advanced Data Structures and Algorithms
Knowledge of graphs, trees, hash tables, heaps, and algorithms for search, sorting, and dynamic programming. Applying data structures efficiently to ML problems.
Practice Interview
Study Questions
Scaling and System-Level Thinking
Recognizing when algorithms need to scale to larger datasets or systems. Understanding distributed computing concepts, sampling strategies, and approximation algorithms when exact solutions are infeasible.
Practice Interview
Study Questions
Optimization Algorithms and Techniques
Understanding of gradient-based optimization, stochastic optimization, Newton's method, and convergence properties. Ability to optimize code for performance and discuss trade-offs between optimization and interpretability.
Practice Interview
Study Questions
Handling Data Quality and Real-World Constraints
Dealing with missing data, outliers, class imbalance, and data drift. Understanding how data quality impacts model performance and implementing robust solutions.
Practice Interview
Study Questions
Onsite Round 2: ML Systems Design and Production Considerations
What to Expect
This round evaluates your ability to design ML systems that work in production. You will discuss how to architect an ML system, considering data pipelines, model training, serving, monitoring, and maintenance. The focus is on end-to-end system thinking, trade-offs between complexity and maintainability, and ability to prototype and iterate quickly. You should demonstrate understanding of how research ideas translate into deployed systems.
Tips & Advice
Expect questions like 'How would you build a recommendation system from scratch?' or 'Design an ML pipeline for a ranking algorithm.' Start with clarifying questions about scale, latency, accuracy requirements, and user needs. Outline the system components: data collection, preprocessing, feature engineering, model training, evaluation, serving, and monitoring. Discuss trade-offs (e.g., batch vs. online learning, simple models vs. complex ensembles). For junior level, demonstrate understanding of the full ML lifecycle and ability to make reasonable architectural decisions. You don't need expert knowledge of distributed systems, but show you understand their importance. Discuss how you'd measure system success and iterate. Be honest about what you'd need to learn or what challenges exist.
Focus Topics
Prototyping and Rapid Iteration
Ability to prototype research ideas quickly, validate assumptions with minimal viable implementations, and iterate based on results. Understanding when to invest in engineering vs. when to iterate on research.
Practice Interview
Study Questions
Model Serving and Inference Optimization
Strategies for serving models in production: online serving, batch prediction, latency optimization, model compression, and caching. Understanding trade-offs between accuracy and serving constraints.
Practice Interview
Study Questions
Monitoring, Evaluation, and Continuous Improvement
Metrics for production systems, monitoring model performance and data drift. A/B testing for model changes and feedback loops for continuous improvement. Understanding canary deployments and rollback strategies.
Practice Interview
Study Questions
Data Pipeline Design and Feature Engineering at Scale
Designing data pipelines for model training and serving. Feature engineering, feature stores, and handling data freshness. Understanding batch vs. streaming processing and data consistency requirements.
Practice Interview
Study Questions
End-to-End ML System Architecture
Understanding of complete ML pipelines: data sources, feature stores, model training infrastructure, inference serving, monitoring, and feedback loops. Ability to design systems that balance accuracy, latency, and maintainability.
Practice Interview
Study Questions
Onsite Round 3: Behavioral and Research Culture Fit
What to Expect
Final onsite round assessing cultural fit, collaboration style, and alignment with Meta's values. You will discuss your research experience, how you've handled challenges, collaborated with teams, communicated findings, and demonstrated impact. Interviewers evaluate your ability to work in fast-paced environments, navigate ambiguity, learn from feedback, and contribute to team goals beyond your individual work.
Tips & Advice
Prepare 3-4 concrete project examples showcasing different qualities: a project with technical depth, one where you collaborated across teams, one where you faced challenges and learned, and one where your work had measurable impact. Use the STAR method (Situation, Task, Action, Result) but focus on what you personally did and learned. Be specific with metrics and outcomes. Discuss how you communicate research to non-technical stakeholders. Share what you learned from failures. Ask thoughtful questions about team collaboration, research direction, and how the team measures impact. Be authentic; Meta values culture fit and team collaboration. Avoid canned answers. For junior level, emphasize learning ability, coachability, and growing independence rather than past leadership or major achievements.
Focus Topics
Communication of Technical Findings
Ability to present research findings clearly, write technical reports or papers, and communicate complex ideas to diverse audiences. Experience publishing or presenting work.
Practice Interview
Study Questions
Motivation for Applied Research and Meta's Mission
Clear articulation of why you're drawn to applied research vs. pure research. Understanding of Meta's business, values, and how AI/ML impacts billions of users. Alignment between your interests and Meta's research priorities.
Practice Interview
Study Questions
Learning from Failure and Iterating
Examples of research projects that didn't work out, experiments that failed, or approaches that needed adjustment. How you learned from setbacks and adjusted your approach.
Practice Interview
Study Questions
Research Project Impact and Storytelling
Ability to clearly articulate your research projects, the problems you solved, methodology, results, and business/scientific impact. Telling compelling stories about your work that demonstrate both technical depth and practical value.
Practice Interview
Study Questions
Collaboration Across Teams and Disciplines
Examples of working with engineers, product managers, other researchers, or domain experts. Ability to explain complex technical concepts to non-technical partners and incorporate diverse perspectives.
Practice Interview
Study Questions
Frequently Asked Applied Scientist Interview Questions
Design a feature store that must sustain 100,000 feature writes per second while keeping average online read latency under 50ms. Outline the architecture layers (ingestion, transformation, offline store, online store, materialization jobs), the partitioning strategy, and the online storage technology choice, with emphasis on the write path.
Sample Answer
Direct answer: Sustaining 100,000 writes per second while keeping reads under 50ms means the write path and read path need to be architecturally separated: an ingestion and transformation layer absorbs the write volume and batches it efficiently into the offline store, while materialization jobs push a summarized, read-optimized copy into the online store on a cadence the read SLA (service-level agreement) can tolerate, rather than the online store taking every write synchronously.
Structured elaboration:
flowchart LR
Producers["Producers (100k writes/sec)"] --> Log["Kafka log"]
Log --> Xform["Transform layer"]
Xform --> Offline["Offline store (Parquet/Iceberg)"]
Xform --> Materialize["Materialization job"]
Materialize --> Online["Online store, 20 shards (DynamoDB / Cassandra)"]
Reader["Reads, under 50ms"] --> Online
- Ingestion layer. A message queue (Kafka or similar) absorbs the 100k writes/sec as an append-only log, decoupling producers from the rate the downstream stores can actually sustain and giving replay capability if a downstream consumer falls behind.
- Transformation layer. Stream or micro-batch processors (Flink/Spark Structured Streaming) consume the log, compute or pass through feature values, and write to both the offline store (for training, at full fidelity and volume) and a materialization pipeline feeding the online store.
- Offline store. Columnar, append-friendly storage (Parquet on object storage, or a table format like Iceberg/Delta) handles 100k writes/sec easily since it is optimized for high-throughput sequential writes, not point lookups.
- Online store and materialization. Rather than writing every one of the 100k events/sec directly into the low-latency online store, materialize periodically (e.g. every few seconds to a minute) into the online store's write path, or use an online store designed for high write throughput (a wide-column store like Cassandra, or a managed store like DynamoDB with provisioned write capacity) if genuinely every write must be reflected online quickly.
- Partitioning strategy. Partition by entity ID (consistent hashing) across enough shards on both the write and read side that no single partition absorbs a disproportionate share of the 100k writes/sec; monitor for and rebalance around emerging hot partitions.
- Online storage technology choice. DynamoDB or Cassandra are natural fits here because they are built for high sustained write throughput with horizontal scaling, unlike a single-node Redis instance which would need careful cluster sharding to sustain 100k writes/sec reliably.
Worked example: At 100k writes/sec, if you partition into 20 shards, each shard handles 5,000 writes/sec, which is comfortably within a single Cassandra or DynamoDB partition's sustained write capacity when the partition key is well-distributed (recall DynamoDB's roughly 1,000 WCU per-partition soft limit, so 5,000 writes/sec on one logical shard would actually need to be spread across at least 5 underlying partitions, reinforcing that partition-key design, not just shard count, determines whether the write path holds up).
Trade-offs & pitfalls: A store optimized for 100k writes/sec is not automatically also optimized for sub-50ms reads; the two workloads have different access patterns (append-heavy, roughly uniform writes vs. skewed, latency-sensitive reads), so the same store often needs different tuning (or a different store entirely) for each, which is why materializing into a separate, read-optimized online copy is the standard pattern rather than serving reads directly off the write-optimized store. Under-partitioning the write path is the single most common way this design fails in practice: a partition key that looks well-distributed in aggregate can still have local hot spots (a batch of correlated writes for related entities arriving together), so monitoring per-partition write rates, not just the aggregate, is necessary to catch it before it causes write throttling.
You must lead a cross-functional post-mortem after deploying a model that caused a measurable regression in retention. Draft the structure of the post-mortem presentation, list the data analyses you would perform to root cause the issue, and propose process changes and guardrails to prevent future incidents.
Sample Answer
Post-mortem presentation structure
- Title / TL;DR — one-slide summary with measurable impact (delta retention, user cohorts affected, timeline).
- Timeline of events — deployment, monitoring alerts, stakeholder actions.
- Scope & impact — metrics, affected segments, business impact estimate.
- Root-cause analysis summary — hypotheses tested and outcomes.
- Data analyses — methods and key charts.
- Remediation & immediate actions taken.
- Long-term fixes & guardrails.
- Action items, owners, and deadlines.
- Lessons learned and follow-up review cadence.
Data analyses to perform (concrete, role-specific)
- Overall and cohort retention delta by day/week; plot cohort survival curves.
- A/B slice: compare treatment vs. control on retention, engagement, and upstream metrics (exposure rate, feature usage).
- Funnel attribution: where drop-off increased (onboarding, conversion, session length).
- Feature importance / SHAP drift: compare model feature distributions pre/post and per-cohort.
- Model score distribution and calibration shifts; population shift detection (covariate and label shift tests).
- Error analysis on degraded segments: qualitative review of representative user sessions and prediction examples.
- Correlate downstream product changes or experiments deployed concurrently.
- Statistical significance and sensitivity analyses (bootstrap, CIs, false discovery controls).
Process changes & guardrails
- Pre-deploy: mandatory rollout checklist including holdout validation on representative production-like cohorts, drift tests, and offline counterfactual retention simulation.
- Canary rollout with automated metric gates (early-warning thresholds + rollback automation).
- Model observability: dashboards for score distribution, feature drift, calibration, and cohort retention with alerting.
- Experimentation policy: require paired-A/B with retention primary metric and minimum exposure/duration.
- Post-deploy runbook and SLA for incident triage; blameless retrospective culture.
- Ownership & training: assign model-level SRE/ML engineer owner, quarterly calibration and fairness audits.
I would lead the post-mortem focusing on evidence-first root cause, clear owners for fixes, and measurable preventive controls.
When should you use a t-test versus a z-test for comparing a sample mean to a population mean or between two sample means? Discuss assumptions about known versus unknown population variance, sample size, and robustness to violations, and describe how you proceed when variances are unknown and sample sizes are small.
Sample Answer
Direct answer
Use a z-test only when the population standard deviation is genuinely known in advance, which is rare in practice. Use a t-test whenever the standard deviation has to be estimated from the sample itself, which is the normal situation, and this holds regardless of sample size. Sample size affects a different thing: how close the t and z critical values are to each other and how much you can lean on the Central Limit Theorem if the underlying data isn't very normal.
Structured elaboration
Known vs. unknown variance. This is the formal criterion. If σ is known (rare outside quality-control settings with a long-established process variance), use z. If σ is estimated from the sample as s (the normal case), use t with df=n−1; the t-distribution's heavier tails are exactly the correction for the added uncertainty of estimating σ rather than knowing it.
Sample size's actual role. As n grows, tn−1 converges to z, so at large n the choice barely changes the numeric answer, which is why "just use z for n≥30" survives as a practical shortcut even though it's not the formal reason. Separately, larger n also makes the Central Limit Theorem a stronger justification for treating the sampling distribution of the mean as approximately normal even when the raw data isn't, which matters for the validity of either test, not for the t-vs-z choice itself.
Comparing two means: pooled vs. Welch's t. If assuming the two groups have equal population variances, use the standard (pooled) two-sample t-test. If variances might differ, and there's rarely a strong reason to assume they're equal, use Welch's t-test, which does not assume equal variances and adjusts the degrees of freedom accordingly. Welch's costs very little power when variances actually are equal but protects against inflated Type I error when they aren't, which is why it's the safer default.
Robustness. t-tests are reasonably robust to mild-to-moderate non-normality once n is moderate (roughly 30+ per group), thanks to the CLT. They're not robust to strong skew or heavy outliers at small n, where a few extreme points can dominate both the mean and the variance estimate.
Worked example: how close t and z actually are, by sample size
| df | t critical value (two-sided, 95%) | z (reference) |
|---|---|---|
| 5 | 2.571 | 1.960 |
| 10 | 2.228 | 1.960 |
| 30 | 2.042 | 1.960 |
| 60 | 2.000 | 1.960 |
| 120 | 1.980 | 1.960 |
(All values from scipy.stats.t.ppf(0.975, df), verified directly.) At df=5 the t critical value is about 31% larger than z, meaningfully widening the interval or raising the bar for significance; by df=60 the gap has shrunk to about 2%. This is the practical justification behind "large n, t and z are basically the same," even though the theoretically correct reason to pick t is always "σ is estimated," not "n is small."
When variances are unknown and sample sizes are small: the actual procedure
- Look at the data: a histogram or Q-Q plot per group, and check for obvious outliers.
- If approximate normality looks plausible, default to Welch's t-test (not pooled, unless there's a specific reason to believe variances are equal, such as both groups measuring the identical underlying process).
- If normality looks clearly violated, or the sample is extremely small (single digits per group) with visible skew, switch to a nonparametric alternative like the Mann-Whitney U test, or use a bootstrap for the confidence interval and p-value instead of the t-distribution's analytic formula.
Trade-offs & pitfalls
- Defaulting to the pooled t-test "because it's the classic one" without checking the equal-variance assumption is a common shortcut that inflates false positives when variances genuinely differ; Welch's is essentially free insurance against this.
- Small samples with heavy skew or outliers can pass a superficial normality check while still producing an unreliable t-test; this is where nonparametric or bootstrap alternatives earn their keep, not just as a formality but as a real fix.
- The "n≥30 use z" heuristic is useful as a rule of thumb but wrong as a justification; it should never be given as the reason to choose z over t in an interview answer, since the real criterion is whether σ is known.
Leadership wants a model that predicts 'customer satisfaction' for every account, but there is no survey data and no existing label for satisfaction anywhere in the system. How would you approach constructing a usable target from scratch?
Sample Answer
Direct answer
With no existing label for "customer satisfaction," the first move is to construct a usable proxy from behaviors that plausibly correlate with satisfaction, while being explicit with stakeholders that a proxy is not the same thing as the real construct, and validating it before trusting it.
Structured elaboration
- Identify candidate proxy signals. Support-ticket volume and sentiment, renewal or churn behavior, usage frequency and depth, and any lightweight in-product feedback (a thumbs-up, a one-question survey) that could be added cheaply.
- Validate the proxy before building on it. Run a small, targeted survey on a sample of accounts to get SOME direct satisfaction signal, then check whether your candidate proxy (say, a composite of usage and support-ticket sentiment) actually correlates with that direct signal. If it doesn't, the proxy needs rethinking before any model gets built on it.
- Be explicit about the gap. Present the proxy to stakeholders as an approximation, with its known blind spots (a satisfied but quiet, low-usage customer might look identical to an unhappy one on pure usage signals), not as ground truth.
- Iterate the label over time. As more direct feedback accumulates (even a small ongoing survey), refine the proxy rather than treating the first version as final.
Worked example
A first proxy combining renewal likelihood, support-ticket sentiment, and usage trend might correlate reasonably well with a small validation survey's results for most accounts, but systematically misclassify a segment (say, accounts that use the product lightly but are highly satisfied with that light use); surfacing this blind spot to stakeholders, rather than shipping the proxy silently, is what keeps the eventual model honest about its limitations.
Trade-offs and pitfalls
The biggest risk is presenting a proxy metric as if it were the real thing once it's embedded in a model and a dashboard; stakeholders tend to forget the approximation over time. Re-validating the proxy periodically against any fresh direct-feedback data, and clearly labeling dashboards and reports as showing a proxy, helps guard against this.
Compare batch scoring, a low-latency hosted endpoint, and a serverless inference setup as ways to serve a model's predictions. When would you actually reach for each one?
Sample Answer
Direct answer
Batch scoring runs predictions over a large set of inputs on a schedule and writes the results somewhere for later use; a low-latency hosted endpoint keeps a model warm and always-on behind an API to answer individual requests in milliseconds; serverless inference spins compute up on demand per request and back down when idle, trading an occasional cold-start latency hit for not paying for idle capacity. Reach for batch scoring when nobody is waiting synchronously for that specific prediction; reach for a hosted endpoint when request volume is high and steady enough to justify always-on capacity and latency must be predictable; reach for serverless when traffic is bursty or low-volume enough that paying for an idle endpoint is wasteful and occasional cold starts are acceptable.
Structured elaboration
| Batch scoring | Hosted endpoint | Serverless inference | |
|---|---|---|---|
| Latency | Not on the critical path at all | Low and predictable | Low once warm, spikes on cold start |
| Cost model | Pay for a compute run, amortized over many predictions | Pay for always-on capacity regardless of volume | Pay per invocation (or per burst) |
| Best traffic shape | Nobody waits synchronously; a scheduled job is fine | Steady, high enough volume to justify fixed cost | Bursty, sparse, or unpredictable volume |
| Freshness | As stale as the last scheduled run | As fresh as the request | As fresh as the request |
| Main operational risk | A silent job failure serves stale results for days if unmonitored | Paying for idle capacity during low-traffic periods | Cold-start latency under a concurrency spike |
Worked example
Suppose keeping a model warm on a small always-on instance costs $0.50 per hour, while a serverless platform charges $0.0004 per invocation, and every request genuinely needs an individual synchronous answer (batching is not an option).
At 200 requests per day:
Hosted endpoint (monthly)=0.50×24×30=$360 Serverless (monthly)=200×30×0.0004=$2.40At this volume serverless is roughly 360/2.40≈150 times cheaper, so the decision comes down entirely to whether occasional cold-start latency is tolerable. The two costs are equal at the volume V where V×30×0.0004=360:
V=30×0.0004360=0.012360=30,000 requests per dayBelow roughly 30,000 requests per day, serverless is cheaper; above it, the always-on hosted endpoint becomes the cheaper and lower-tail-latency choice. Batch scoring sits outside this comparison entirely: scoring 10 million items once overnight on a shared batch cluster is typically far cheaper per prediction than serving each one synchronously through either of the other two options, precisely because nothing is paying for an always-on or per-invocation serving layer; the cost is traded for freshness, since results are only as current as the last run.
Trade-offs and pitfalls
A common wrong turn is choosing serverless for a latency-critical path without checking cold-start behavior under the platform's real concurrency model, since a burst of concurrent requests can each trigger a separate cold start rather than sharing one warm instance. Another is defaulting to a hosted endpoint out of habit for something that is genuinely a batch problem, such as a once-a-day digest score that never needs an always-on API. Batch scoring's biggest pitfall is treating it as maintenance-free simply because nothing is synchronous: a broken nightly job can silently serve yesterday's scores for days if nobody watches the job's completion status or output row count.
A message of digits was encoded by mapping 'A' to 1, 'B' to 2, and so on up to 'Z' to 26. Given the encoded digit string, count how many ways it could be decoded back into letters. Explain how a '0' digit constrains which of the previous one or two decodings are still valid.
Sample Answer
Direct answer
Let ways[i] count the number of valid decodings of the first i characters; each position either extends a valid one-character decode from ways[i-1] or a valid two-character decode from ways[i-2], so only the last two counts ever need to be kept, not a full array. A '0' can never stand alone as its own letter (there is no letter mapped to 0), so it only contributes when paired with the digit directly before it as 10 or 20; any other appearance of '0' makes the whole string, from that point on, undecodable.
Structured elaboration
The recurrence
For position i (1-indexed, looking at character s[i-1]):
- If
s[i-1] != '0', that character alone is a valid letter, contributingways[i-1](every decoding of the prefix before it, extended by this one digit). - If the two-character combination
s[i-2:i](as a number) falls between10and26inclusive, that pair is a valid letter, contributingways[i-2]. ways[i]is the sum of whichever of those two contributions apply. If neither applies,ways[i] = 0, and every position after it inherits0as well, since nothing downstream can repair an already-broken prefix.
Why '0' is the entire source of edge cases here
Every digit 1-9 is a valid single-letter decode on its own. '0' is the one digit with no single-letter meaning, so it must always be consumed as the second digit of a 10 or 20 pair. That single fact is what makes "100" invalid (the trailing 0 has no digit after it to pair with and no single-letter meaning of its own) while "10" is valid (exactly one way: "J").
Worked example
def num_decodings(s: str) -> int:
if not s:
return 0
n = len(s)
prev2 = 1 # ways[0]: one way to decode the empty prefix
prev1 = 1 if s[0] != '0' else 0 # ways[1]
for i in range(1, n):
cur = 0
if s[i] != '0':
cur += prev1
two = int(s[i-1:i+1])
if 10 <= two <= 26:
cur += prev2
prev2, prev1 = prev1, cur
return prev1
for s in ("12", "226", "0", "06", "100", "10", "2101", "11106"):
print(s, "->", num_decodings(s))
This prints:
12 -> 2
226 -> 3
0 -> 0
06 -> 0
100 -> 0
10 -> 1
2101 -> 1
11106 -> 2
Tracing "226": prev2 = 1 (empty prefix), prev1 = 1 ("2" decodes as "B"). At i=1 (s[1] = '2'): single-digit contributes prev1 = 1 ("22" extended by "B" -> "BB" is being built up); two-digit "22" is in [10, 26], contributes prev2 = 1; cur = 2, so prev2, prev1 = 1, 2. At i=2 (s[2] = '6'): single-digit contributes prev1 = 2; two-digit "26" is in [10, 26], contributes prev2 = 1; cur = 3. Final prev1 = 3, matching "BBF", "BZ", "VF", the three valid decodings.
Key points
- Only two rolling variables (
prev2,prev1) are needed, since the recurrence only ever looks back one and two positions. - The single-digit and two-digit contributions are checked independently and summed; both, one, or neither can apply at a given position.
- Once
curis0at any position, it propagates forward permanently, since a broken prefix cannot be fixed by anything after it.
Complexity
Time: O(n), one pass over the string. Space: O(1) extra, only two rolling integers are kept regardless of string length.
Edge cases
- String starting with
'0': no valid single-letter decode for the first character, and there is no preceding digit to pair it with, so the result is0immediately. - A
'0'with no valid pairing before it (such as the trailing'0'in"100"): the two-digit check for that position fails (00is not in[10, 26], and even the valid pairing"10"earlier does not help the next'0'), so the whole count collapses to0from that point forward. - Very long input: the rolling two-variable approach handles arbitrary length in a single linear pass without extra memory growth.
Trade-offs & pitfalls
The most common bug is treating '0' as never valid at all, rather than valid specifically when paired as 10 or 20, or forgetting that a '0' can only ever be consumed as the second digit of a pair, never the first (there is no letter for "0X" where X is a placeholder, and no letter for a leading zero in a two-digit code above 26). A second common mistake is keeping a full O(n)-sized array when only the last two values are ever read, unnecessary if the goal is genuinely constant extra space rather than just correctness.
Some aggregations (sum, count) are associative and trivially parallelizable across a distributed dataset with a guaranteed deterministic result. Others, like median or percentile, are not. Discuss how you would compute an approximate percentile at scale with a mergeable, deterministic algorithm (for example a t-digest or histogram sketch), and separately, how you would implement a scalable approximate 'distinct count' (for example unique users in the last 30 days) using a structure like HyperLogLog, including the accuracy/memory trade-off of each.
Sample Answer
Direct answer
Associative aggregates like sum and count can be computed on partitions independently and combined trivially and exactly; non-associative statistics like median or an arbitrary percentile cannot be combined that way, and computing them exactly at scale requires either collecting all the data to one place (expensive) or accepting an approximate, mergeable summary structure like a t-digest, histogram sketch, or HyperLogLog instead of the exact value.
Structured elaboration
- Why percentile doesn't parallelize like sum does: the median of the combination of two datasets is not a simple function of the two datasets' individual medians; you need something closer to the full sorted order, which is exactly what doesn't scale.
- Sketch-based approximation: a t-digest or histogram sketch summarizes the DISTRIBUTION in a small, fixed-size, MERGEABLE structure, mergeable meaning two workers' partial sketches can be combined into one sketch representing the union of their data, without re-processing the raw values, which is what makes it parallelizable where the exact computation isn't.
- HyperLogLog for approximate distinct counts: the same idea, applied to "how many distinct values," a small, mergeable sketch trades a small, well-understood error for tractable memory and merge cost at huge cardinality.
- The error is the price of mergeability: both structures accept a small, quantifiable error bound in exchange for being computable in parallel and mergeable afterward; whether that trade is acceptable depends entirely on how the number will be used (a rounded, monitoring-dashboard metric can usually tolerate it; a billing calculation usually cannot).
Worked example
Against 100,000 synthetic random values, verified via execution: the exact median was 501.0 and the approximate (t-digest-style) quantile computed 501, a negligible difference. The exact distinct count was 1,001 and the HyperLogLog-style approximate count returned 1,249, a measured relative error of about 25% at this specific (fairly low) cardinality; HyperLogLog's accuracy improves at larger cardinalities and with more allocated registers, this measured number (not an assumed "single-digit percent" figure) is what an honest answer reports, along with the caveat that the observed error is specific to this run's cardinality and configuration.
Trade-offs and pitfalls
- Approximate structures have tunable size/accuracy trade-offs (more registers/buckets, less error, more memory); the honest answer states that the error depends on configuration and cardinality rather than quoting a single always-true percentage.
- Combining sketches from different sources only works correctly if they were built with compatible parameters (the same hash function and register count for HyperLogLog, for instance); mixing incompatible sketches produces a meaningless merge, not a graceful degradation.
- These techniques are for read-time or reporting-time aggregation; if the aggregate needs to be EXACT for a financial or compliance reason, this whole toolkit is the wrong tool regardless of how attractive the performance is.
A monitoring system runs a KS-test per feature every hour across thousands of features and triggers many alerts. Propose a statistically principled way to control the false discovery rate across all these simultaneous tests while preserving sensitivity to true drift events.
Sample Answer
Direct answer
Running a KS test on thousands of features every hour and using a flat significance threshold guarantees false alarms by construction: Benjamini-Hochberg false discovery rate (FDR) correction controls the EXPECTED PROPORTION of your flagged features that are false alarms, which is the right guarantee for an alerting system that has to stay actionable at scale.
Structured elaboration
- Why flat thresholds fail: at α=0.05 per test, testing 1000 independent features with NO real drift anywhere still produces roughly 50 false alarms per run, purely from chance. Testing more features doesn't make your monitoring better, it makes the false-alarm count worse, unless you correct for it.
- BH-FDR procedure: sort your m p-values ascending, p(1)≤p(2)≤⋯≤p(m). Find the largest k such that p(k)≤mkα. Flag all features with p≤p(k). This adapts the effective threshold to how many true signals are actually present in the batch: with many real drifting features, BH is more lenient per-test than with few, unlike a flat Bonferroni correction which is the same regardless.
- What the guarantee actually means: BH controls E[total flaggedfalse positives] at your chosen α, not the probability of ANY false positive (that's the stricter family-wise error rate a Bonferroni correction controls). For a monitoring system where a human triages the flagged list, FDR is the right guarantee: you're accepting that some fraction of what you investigate will be noise, in exchange for far more sensitivity to real drift than the ultra-conservative Bonferroni bound gives you.
Worked example
Verified in a Python sandbox (scipy): simulating 20 features, 4 with genuine drift (mean-shifted 0.6 std) and 16 with none, KS p-values computed per feature and BH-FDR applied at α=0.05 correctly flagged EXACTLY the 4 truly-drifting features with zero false positives in this run (p-values for the 4 true positives were all effectively 0, well separated from the 16 null p-values ranging 0.12-0.99). Compare that to a naive per-test α=0.05 threshold on this SAME batch, which also happened to flag exactly 4 in this run purely because the true signals were strong and well-separated from the noise: the real divergence between naive and BH-corrected thresholds shows up as feature count grows into the hundreds or thousands, where naive thresholding's false-positive count scales linearly with m while BH's stays controlled as a proportion.
Trade-offs & pitfalls
BH assumes your tests are independent or positively dependent; features in a real feature store are often correlated (several features derived from the same upstream signal), which can make BH's guarantee slightly conservative or slightly loose depending on the correlation structure: the standard practical response is to still use BH (it's robust enough in most positively-correlated real-world cases) but corroborate any flagged cluster of CORRELATED features as one investigation rather than treating each as independent evidence. A composite-indicator approach (aggregating correlated features into one health score before testing) is a complementary way to reduce the effective m and sidestep some of this.
Explain what a single artificial neuron computes and how a multilayer perceptron's forward pass works. Walk through the forward-pass equations (weighted sum, bias, activation) and compute a small numeric example end to end.
Sample Answer
Direct answer
A single artificial neuron computes a weighted sum of its inputs plus a bias, then passes that through a non-linear activation function. Stacking neurons into layers and repeating this (matrix multiply, add bias, apply activation) is the forward pass of a multilayer perceptron (MLP).
Structured elaboration
For one neuron, z=w⋅x+b=∑iwixi+b, then a=ϕ(z) for an activation ϕ. The weights scale each input's contribution and encode which directions in input space matter; the bias shifts the decision threshold so the neuron's boundary need not pass through the origin; the activation introduces non-linearity, without which stacking layers would collapse algebraically to one linear transform no matter how many layers you add. For a full MLP with one hidden layer, this generalizes to z(1)=W(1)x+b(1), a(1)=ϕ(z(1)), z(2)=W(2)a(1)+b(2), y^=softmax(z(2)) for a classification head.
A single neuron is geometrically a linear classifier: the set w⋅x+b=0 is a hyperplane, with points on one side giving z>0 and the other z<0. That is also why a lone perceptron cannot separate XOR (the two positive-label points and two negative-label points cannot be split by any single straight line), but two layers of neurons can, because the hidden layer can carve the input space into pieces the output layer then recombines.
Worked example
Single neuron: x=[0.5,−1.2], w=[0.8,0.3], b=0.1, ReLU activation.
z=0.8(0.5)+0.3(−1.2)+0.1=0.4−0.36+0.1=0.14
a=ReLU(0.14)=max(0,0.14)=0.14
Full 3-layer MLP forward pass with ReLU hidden and softmax output: input x=[0.5,−1.0], W1=[0.21.0−0.50.1], b1=[0.0,0.1]:
z1(1)=0.2(0.5)+(−0.5)(−1.0)+0.0=0.1+0.5=0.6
z2(1)=1.0(0.5)+0.1(−1.0)+0.1=0.5−0.1+0.1=0.5
a(1)=ReLU([0.6,0.5])=[0.6,0.5] (both already positive, unchanged)
With W2=[1.00.5−1.00.5], b2=[0.0,0.0]:
z1(2)=1.0(0.6)+(−1.0)(0.5)=0.6−0.5=0.1
z2(2)=0.5(0.6)+0.5(0.5)=0.3+0.25=0.55
Softmax: e0.1≈1.105, e0.55≈1.733, sum ≈2.838, giving probabilities ≈[0.389,0.611].
Trade-offs & pitfalls
The most common conceptual error is forgetting that without a non-linear activation, any number of stacked linear layers reduces to a single linear layer algebraically (W2(W1x)=(W2W1)x), so depth alone buys nothing without non-linearity. A second common gap is treating the perceptron's linear-separator limitation (XOR) as a limitation of neural networks in general, rather than of a single layer specifically.
Implement a simple Python function that, given GPU peak FLOPS (TFLOPS), memory bandwidth (GB/s), per-sample memory traffic (bytes), and batch size, estimates whether a training step is compute-bound or memory-bound using a heuristic. Define the compute and memory time estimates and use a threshold (e.g., compute_time > 2 * memory_time => compute-bound). Provide example outputs for different configurations.
Sample Answer
Direct answer
Classifying a training step as compute-bound or memory-bandwidth-bound from hardware specs (peak FLOPS, memory bandwidth) and the workload's per-sample memory traffic and batch size means comparing the time each resource would take if it were the sole bottleneck: whichever takes longer is the actual bottleneck (the step's real time is at least that long, assuming imperfect overlap between compute and memory access).
Structured elaboration
- Compute time estimate: given the workload's FLOPs per sample (not provided directly here, but implied by whatever operation is being analyzed) and the GPU's peak FLOPS, compute_time = (FLOPs_per_sample * batch_size) / peak_FLOPS.
- Memory time estimate: given per-sample memory traffic (bytes read/written per sample) and the GPU's memory bandwidth, memory_time = (bytes_per_sample * batch_size) / memory_bandwidth.
- Classification: if memory_time > compute_time, the operation is memory-bandwidth-bound (the GPU's compute units would sit idle waiting for data even if compute were instantaneous); if compute_time > memory_time, it's compute-bound (the memory system could keep up with idealized data delivery, and compute is the limiting factor).
- Arithmetic intensity as the underlying concept: the ratio of FLOPs to bytes moved (FLOPs per byte) is what actually determines this classification, independent of batch size (since both FLOPs and bytes scale linearly with batch size for a simple, non-batched-interaction operation, batch size cancels out of the ratio, though it still affects each individual estimate's absolute magnitude).
Worked example
def classify_compute_or_memory_bound(peak_tflops: float, memory_bandwidth_gbs: float,
flops_per_sample: float, bytes_per_sample: float,
batch_size: int) -> dict:
peak_flops = peak_tflops * 1e12
bandwidth = memory_bandwidth_gbs * 1e9
compute_time = (flops_per_sample * batch_size) / peak_flops
memory_time = (bytes_per_sample * batch_size) / bandwidth
classification = "memory-bound" if memory_time > compute_time else "compute-bound"
return {
"compute_time_s": compute_time, "memory_time_s": memory_time,
"classification": classification,
"arithmetic_intensity": flops_per_sample / bytes_per_sample,
}
# Verification: an elementwise operation (low arithmetic intensity) vs a matmul-like operation (high)
elementwise = classify_compute_or_memory_bound(
peak_tflops=312, memory_bandwidth_gbs=2000,
flops_per_sample=1024, bytes_per_sample=1024*4, # 1 FLOP per byte roughly, read+write a value
batch_size=1_000_000,
)
matmul_like = classify_compute_or_memory_bound(
peak_tflops=312, memory_bandwidth_gbs=2000,
flops_per_sample=1024*1024, bytes_per_sample=1024*4, # much higher FLOPs per byte moved
batch_size=1_000_000,
)
assert elementwise["classification"] == "memory-bound"
assert matmul_like["classification"] == "compute-bound"
Running this confirms the elementwise-style operation (low FLOPs relative to bytes moved) classifies as memory-bound, while the matmul-like operation (much higher FLOPs per byte, from reusing loaded data across many multiply-accumulate operations) classifies as compute-bound, matching the general expectation that elementwise operations tend to be memory-bound and dense matrix multiplies tend to be compute-bound on modern hardware.
Trade-offs & pitfalls
This model assumes compute and memory access happen sequentially (not overlapped) for the estimate; real GPU execution often overlaps compute and memory access to some degree (especially with good kernel design and enough independent work to hide memory latency behind ongoing compute), so real measured time is often somewhat better than this simple additive/max-of-the-two model predicts, meaning this classification is a useful diagnostic heuristic, not a precise performance predictor.
Want to create your own tailored preparation guide using our deep research?
Get Started for FreeInterview-Ready Courses
Visual-first, interactive, structured learning paths
Browse Applied Scientist jobs
AI-enriched listings across hundreds of company career pages
Explore Jobs