A Data Scientist at PriceLabs plays a pivotal role in driving the core engine of the company’s product: dynamic pricing and revenue management. Because PriceLabs is an inherently data-heavy platform serving the hospitality and vacation rental industries, your work directly impacts the revenue of thousands of property managers worldwide. You will be tasked with analyzing massive datasets of booking patterns, market supply, seasonal trends, and hyper-local demand shocks to build and refine algorithms that calculate the optimal price for a listing at any given second.
The complexity of this role lies in the sheer scale and volatility of the vacation rental market. Unlike traditional hotels, short-term rentals have highly unique characteristics, localized demand drivers, and sparse booking data. As a Data Scientist, you will not merely train off-the-shelf models; you will design, scale, and optimize custom time-series forecasting, pricing elasticity models, and predictive algorithms. This requires a deep understanding of mathematical modeling, statistical analysis, and robust software engineering practices to ensure models run efficiently at scale.
Working in this team offers a high degree of ownership and strategic influence. You will collaborate closely with product and engineering teams to translate complex data insights into production-ready code. The environment is intellectually demanding, fast-paced, and deeply analytical, making it an exceptionally rewarding place for data scientists who thrive on solving real-world economic and predictive challenges.
Technical Screening
reportedA handful of shapes account for most of what gets asked in this format: a ranking or deduplication inside groups, a running or rolling total, a period-over-period comparison, and a cohort tracked forward over time. Recognising the shape quickly is most of the speed here; deriving it from scratch while a clock runs is where the time goes. Know that a window function keeps every row while a GROUP BY collapses them, and know which one the question needs. If the exercise is in Python instead of SQL, the same shapes arrive as groupby with transform, shift and merge, and the same grain mistakes are available.
What to demonstrate
- Whether you reach the right construct without a detour, such as ROW_NUMBER over a partition to deduplicate instead of a self-join against a MAX subquery
- Whether you know what your window frame actually is, since adding ORDER BY inside OVER changes the default frame and silently changes a running total
- Whether the thing runs. A near-miss that throws an error scores below a plainer query that returns the right rows.
How to prepare
- Write each of the four shapes once from memory against a small schema and keep the working version somewhere you will reread it: dedupe with ROW_NUMBER, a running total, a month-over-month change with LAG, and a retention table
- Compute one running total twice on data with tied timestamps, once on the default frame and once with ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, and look at where the two disagree
- If Python is on the table, rebuild the dedupe and the running total with groupby and cumsum, then assert the two implementations return identical rows
Introductory Call
reportedBecause the format is not fixed, prepare the reasoning rather than the ritual. Nearly every version of this round draws on the same underlying material: a design you can defend, a metric you can define exactly, an analysis whose assumptions you can state out loud. Only the wrapper changes, whether that is a take-home, a live case, a deep dive on past work, or a rough estimate on a whiteboard. Answers rehearsed to fit one shape stall the moment the shape differs. Practise naming the assumption behind a number, then saying how much the conclusion moves if that assumption is wrong.
What to demonstrate
- Whether your justification for a method survives the question 'why not the simpler thing', including when the simpler thing would have worked
- Precision under pressure: what exactly counts as an active user, a conversion or a success, over what window, with what exclusions
- Whether you carry an argument through to a recommendation instead of stopping at a list of tradeoffs
How to prepare
- For each project you plan to mention, write the metric definition in one sentence: numerator, denominator, time window, exclusions. Say it out loud once, because vagueness shows up in speech before it shows up on paper.
- Rehearse the same project at three lengths: two minutes, ten minutes, and a deep dive on one technical decision. Cutting live is harder than it sounds.
- For your headline result, write down what would have had to be true for it to be wrong, and how you ruled that out.
Live Coding Round
reportedMuch of what gets scored here happens out loud while you type. Nobody can see your reasoning inside a half-written query, so five silent minutes read as being stuck even when they are not. State the plan in plain language first: which tables, what grain you are aggregating to, and the one filter that defines the population. Then write it. The narration doubles as insurance, because a wrong plan gets caught early and cheaply while a wrong query gets caught at the end with no time left to redo it. A timed statistics section, where one exists, is a separate test with its own clock.
What to demonstrate
- Whether the query you write matches the plan you just described
- What you do with a hint, meaning whether the correction gets absorbed or the first approach gets defended
- Whether you can debug your own wrong output by reading the result set and naming which part of the query produced the anomaly
How to prepare
- Solve three problems while screen-sharing into a recording, then watch it back and mark every stretch longer than thirty seconds where you said nothing
- Practise compressing the plan into one sentence before typing, then check afterwards whether the finished query actually matched it
- Time yourself on statistics questions that carry a business reading, such as what a confidence interval does and does not claim, rather than re-reading notes without a clock
Take-Home Assignment
reportedA take-home is graded as an argument, not as a notebook. Somebody reads the submission without you in the room, so every choice has to survive on the page: why the question was framed this way, and what was deliberately left out. The gap between a strong and a weak submission is almost never model quality. It is whether the writeup names the specific question it answers and commits to a recommendation, including what evidence would overturn it. A high-accuracy model attached to no conclusion reads as effort that stopped before the decision.
What to demonstrate
- Whether the question you answered is stated outright, and whether it is the question the prompt posed rather than an easier neighbour of it
- Whether the recommendation is specific enough to act on, with the uncertainty attached to it instead of parked in a caveats section at the end
- Whether analytical choices such as the metric definition, the population filter and the time window are justified in the prose, not merely visible in code
How to prepare
- Take a dataset you have already worked with, write the one-paragraph conclusion first, then check whether the analysis you were planning actually supports it and cut whatever does not
- Practise stating a metric in one sentence that fixes the population, the time window and the denominator, then confirm your query computes exactly that sentence and nothing adjacent to it
- Hand a draft to someone outside the problem and ask them to tell you back what you recommended and why; anything they cannot recover is not on the page yet
Technical Review
reportedBefore anything else, this round is a reading test. You are given a small schema and a question phrased in business language, and most of the difficulty sits in the gap between them. Who counts as an active user, does a refunded order still count as an order, is that date column an event time or a load time. Weak answers start typing immediately and compute something precise about the wrong population. Strong ones pin the definition in one sentence, name the column that encodes it, then write the query. On a timed assessment with nobody to tell, write the definition in a comment anyway.
What to demonstrate
- Whether an ambiguous term becomes a specific column and filter before any computation happens
- Whether you read the schema for keys and cardinality rather than only for column names
- Whether the result answers the question at the grain it was asked at, per user or per session or per day
How to prepare
- Take three metrics you already use and write down the exact filter and exact grain behind each, then practise stating one of them in a single sentence out loud
- On a schema you have never seen, spend the first minute writing what one row of each table means and which key it is unique on, then predict which joins can duplicate rows
- Rehearse a version where the definition changes halfway through, and edit the query you have instead of starting over
Culture Fit Round
reportedRounds of this kind usually include one question about work that did not go well, and it is the part that carries the most information. Anyone can narrate a shipped win. What the interviewer learns from a project that stalled is how you behave without a result to hide behind: whether you noticed the problem yourself, how long it took, and who you told. Answers that route the failure onto a data pipeline or a reorganisation close the topic without answering it, and the follow-up comes back to your own part.
What to demonstrate
- Whether you found the error yourself or someone else found it, and how long it sat before anyone knew
- What you changed afterwards, stated as a check you now run rather than a lesson you now believe
- Whether the mistake you choose has real cost attached, such as a quarter of misdirected roadmap or a metric that was reported upward, instead of one that flatters you
How to prepare
- Choose a failure you caught yourself and be ready to say what tipped you off. A story where someone else caught it is still usable, but you will be asked why you missed it.
- Write down the check you added afterwards and where it lives now, so the correction is a concrete artefact rather than a resolution.
- Rehearse saying the cost out loud. Candidates shrink the number by instinct once the interviewer is in the room.
PracHub editorial advice for the preparation topics above.
Reading cancellation, completion or repeat rates on cohorts that have not matured
A cohort of bookings made last week for stays six months out cannot have cancelled at the check-in gate yet, so its cancellation rate is mechanically near zero and its completion rate mechanically near zero as well, in opposite directions. Comparing that cohort with a mature one is not a noisy comparison, it is a guaranteed wrong one, and the bias always makes the recent period look different in a way that invites a false story about a recent change. Because lead time is heavily right-skewed, the mean lead time is a bad maturity threshold; use the cohort's 95th percentile, or report a hazard at a fixed age (cancelled within k days of booking) with k capped at the youngest cohort's elapsed age. The same applies to repeat rate, where the honest answer is often that the cohort in question is not readable for another nine months.
Using the search as the demand unit when the trip is the demand unit
One trip intent generates dozens of searches over days, across devices, mostly while logged out, and the number of searches per intent is a property of the interface rather than of demand. Any product change that encourages comparison or re-sorting inflates the denominator, so look-to-book falls while the product improves, and a change that reduces re-searching raises the metric while nothing about demand moved. The logged-out majority also means traveller_id is NULL for most early-funnel rows, so joining searches to bookings on traveller_id silently drops the part of the funnel you were trying to measure. Collapse on trip_intent_key first, then count, and report searches per intent separately as a diagnostic rather than letting it sit inside a conversion rate.
Over-explaining the method and under-explaining the implication
Lead with the answer and what you would do about it, then give the approach when asked. Roughly one sentence of method per three of implication is the right ratio for a stakeholder-facing answer; the interviewer already knows what a regression is.
Optimising accuracy on a heavily imbalanced target
State the base rate first, then choose the metric from the relative cost of a false positive against a false negative: precision and recall at the operating threshold, PR-AUC, or expected cost. At a 1 percent positive rate, predicting the majority class for everyone scores 99 percent accuracy and is worthless.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
How would you design a validation strategy for a time-series model to …
How would you design a validation strategy for a time-series model to prevent data leakage and ensure reliable out-of-sample performance?
Approach
- Pick an evaluation metric that matches the cost of each error type, not a default.
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
- Say how the offline result would be validated online before it is trusted.
Follow-up
- How would you choose the decision threshold, and who owns that choice?
- What would you monitor after launch to know the model is still valid?
When evaluating a price prediction model, what are the trade-offs of o…
When evaluating a price prediction model, what are the trade-offs of optimizing for Mean Squared Error (MSE) versus Mean Absolute Percentage Error (MAPE)?
Approach
- Say how the offline result would be validated online before it is trusted.
- Pick an evaluation metric that matches the cost of each error type, not a default.
- Check what information would not exist at prediction time, and exclude it.
Follow-up
- How would you choose the decision threshold, and who owns that choice?
- What would you monitor after launch to know the model is still valid?
Identify the time and space complexity (Big O notation) of a provided …
Identify the time and space complexity (Big O notation) of a provided data-manipulation algorithm and suggest optimizations to improve its runtime.
Approach
- Say how the offline result would be validated online before it is trusted.
- Set a baseline first, so any model has something honest to beat.
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
Follow-up
- How would you choose the decision threshold, and who owns that choice?
- What would you monitor after launch to know the model is still valid?
How do you prioritize your modeling efforts when faced with a strict d…
How do you prioritize your modeling efforts when faced with a strict deadline? Give an example of how you balanced model complexity with execution speed.
Approach
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
- Say how the offline result would be validated online before it is trusted.
- Check what information would not exist at prediction time, and exclude it.
Follow-up
- Where could label leakage enter this setup?
- What would you monitor after launch to know the model is still valid?
Write invariant checks for a rate availability snapshot
The DataFrame snap holds one row per supply_unit_id per forward stay_date per snapshot_date, with units_available, units_sold_to_date, units_blocked, listed_price_usd (nullable), is_closed_to_arrival, min_length_of_stay and lead_time_days. Write check(snap) returning a tidy failure frame with columns check_name, supply_unit_id, stay_date, snapshot_date, detail, plus a per-check summary count. Cover at least: primary-key uniqueness, lead_time_days equal to (stay_date - snapshot_date) in days, listed_price_usd null exactly when units_available is 0, and non-negative counts. It must return the right empty frame on empty input.
Approach
- Write each check as a boolean mask over the whole frame, not a row-wise function, and append a small frame carrying check_name plus the three key columns and a
detailstring built from the offending values. Concatenate at the end with a typed empty frame in the list so an all-clean or empty input still returns the declared columns and dtypes. Declare the check names once as a module-level tuple, CHECK_NAMES, and drive both the run loop and the summary off that tuple rather than off whatever happened to fail. - Test nullity with .isna(); listed_price_usd is a float column so a NULL is NaN, and NaN == NaN is False, which means any
== Noneor== np.nancomparison returns an all-False mask and the check passes vacuously on every row. - Check the price rule in both directions: a non-null price where units_available is 0 means someone imputed the last known price onto a sold-out unit-date, which is the single most damaging corruption here because it turns censored observations into apparently-observed ones for any elasticity work.
- Separate hard invariants from business expectations and label them with a severity column. Uniqueness of (supply_unit_id, stay_date, snapshot_date), the lead-time identity and non-negativity are invariants. Monotonicity of units_sold_to_date across snapshot_date is not: cancellations legitimately reduce cumulative pickup, so it belongs at warn severity with a threshold on the size of the drop.
- Build the summary by grouping the failure frame on check_name and then reindexing against CHECK_NAMES with fill_value=0. A bare groupby emits no row for a check that found nothing, so a clean input returns a summary listing only the broken checks and an empty input returns no summary at all — which on a dashboard is indistinguishable from the suite never having run, the one state a summary exists to rule out. Return counts per stay_date alongside it so a caller can see whether failures are uniform or concentrated on a single partition, which is what distinguishes a code bug from one bad ingest day.
Worked solution 20 min
- Declare CHECK_NAMES as a fixed tuple of the four check names, then define a helper that takes a mask and a check_name and returns the key columns of the failing rows plus a detail string; collect results in a list.
- Check 1: snap.duplicated(subset=['supply_unit_id','stay_date','snapshot_date'], keep=False) flags every member of a duplicate key group, not just the later ones.
- Check 2: (snap['stay_date'] - snap['snapshot_date']).dt.days != snap['lead_time_days'].
- Check 3: two masks, (units_available == 0) & listed_price_usd.notna(), and (units_available > 0) & listed_price_usd.isna().
- Check 4: any of units_available, units_sold_to_date, units_blocked below zero; and min_length_of_stay below 1.
- Concatenate with an explicit empty typed frame, then build the summary as failures.groupby('check_name').size().reindex(CHECK_NAMES, fill_value=0), so a check that found nothing reports 0 instead of vanishing and a clean or empty input still returns one row per declared check.
Follow-up
- Which of your checks would you make a hard pipeline failure and which a warning, and what is the cost of getting that wrong in each direction?
- units_sold_to_date drops by 4 between two consecutive snapshots for one unit-date. Give two innocent explanations and one that should page someone.
- How would you run these on a table too large to hold in memory, keeping the same failure frame?
Pick the last availability snapshot before each stay date
fct_rate_availability_snapshot is keyed on (supply_unit_id, stay_date, snapshot_date) and carries units_available, units_sold_to_date, units_blocked, listed_price_usd, is_closed_to_arrival and min_length_of_stay. For every supply_unit_id and every stay_date in one target month, return exactly one row: the values from the latest snapshot_date that is on or before that stay_date. Output supply_unit_id, stay_date, snapshot_date, units_available, units_sold_to_date and listed_price_usd. A single global maximum snapshot_date is not acceptable.
Approach
- Restrict to the target stay_date range and to snapshot_date <= stay_date inside the same CTE; that predicate is evaluated per row, which is what makes this an as-of pick rather than a latest-snapshot pick.
- Rank with ROW_NUMBER() OVER (PARTITION BY supply_unit_id, stay_date ORDER BY snapshot_date DESC) and keep rank 1. RANK() would return two rows if the table ever holds a duplicate snapshot_date; ROW_NUMBER guarantees one.
- Filter on the rank in an outer query, or use DISTINCT ON / QUALIFY where the engine supports it. A window function cannot be referenced in the WHERE clause of the SELECT that computes it.
- Leave unit-dates with no qualifying snapshot out of the result and say so explicitly; if the deliverable needs them present, LEFT JOIN from a unit-by-date spine so the absence surfaces as a NULL row instead of a missing one.
- Keep snapshot_date in the output, because every downstream consumer needs to know how stale the as-of value is before acting on it.
Worked solution 20 min
- Count distinct (supply_unit_id, stay_date) pairs in the window; that is the row count the final query must return, less any unit-dates with no snapshot on or before arrival.
- Write the ranked CTE, then select rank 1 from an outer query.
- Assert across the result that no snapshot_date exceeds its stay_date.
- Spot-check one unit-date against its raw snapshot rows to confirm the chosen row really is the last capture before arrival.
Follow-up
- Now pick the snapshot as at exactly 30 days before arrival instead. What changes in the query, and which of the two do you use for a pace report?
- The table is partitioned on snapshot_date. How do you keep partition pruning while still ranking within each unit-date?
- You find two rows sharing a snapshot_date for one unit-date. What does that mean about the capture pipeline, and how do you break the tie deterministically?
Compare booking pace against last year aligned on days out
fct_rate_availability_snapshot carries units_sold_to_date, the cumulative pickup for a unit-date as at snapshot_date, and lead_time_days, which is stay_date minus snapshot_date. For one destination_market_id and one target stay week, build the booking curve: for each lead_time_days from 120 down to 0, the total units sold across the market's units and the seven-day pickup. Join the equivalent stay week last year aligned on lead_time_days rather than on calendar date, and return both curves side by side.
Approach
- Restrict to the market's supply units and the seven stay_dates of the target week, then aggregate to lead_time_days by summing units_sold_to_date across units and across those seven stay_dates. This is a cross-section at a fixed days-out, so the snapshot_date differs across the week's stay dates, which is exactly what aligning on days out means.
- Repeat for last year's aligned stay week, chosen on the market calendar. A 364-day offset preserves day of week but drifts a moving holiday; a same-date offset preserves the date and breaks day of week. State which you chose, and use market_holiday_flag on fct_stay_night to check whether a holiday sits inside one week and not the other.
- Compute seven-day pickup as value minus LAG(value, 7) OVER (ORDER BY lead_time_days DESC). Ordering descending makes time run forward, because days out counts down towards arrival. Every value is a rolling window and adjacent rows share six of their seven days, so this column is not additive and must never be summed to recover total pickup.
- Join the two curves on lead_time_days with a FULL OUTER JOIN so a days-out point missing on one side stays visible as a NULL rather than dropping the row and silently shortening the comparison.
- Index each curve to its own final on-hand value when the two weeks differ in sellable size, so the comparison reads as pace rather than level.
Follow-up
- At 30 days out you are 8% behind last year. What else do you need before telling revenue management to cut price?
- Two new units joined this market in March. What does that do to this comparison, and how would you control for it?
- The curve at days out zero sits above the stayed-night count for that week. Is that a bug, and how would you show which it is?
Write a clean, efficient Python function to identify overlapping date …
Write a clean, efficient Python function to identify overlapping date ranges in a dataset of vacation rental bookings.
Approach
- Say what you would check first and why it is the highest-information step.
- State your assumptions explicitly before working the problem.
- Clarify what is being asked and what a complete answer would contain.
Follow-up
- How would you know your answer was wrong?
- What assumption would you test first?
Given a 10-line Python pseudocode block outlining a recursive function…
Given a 10-line Python pseudocode block outlining a recursive function, describe succinctly and accurately what the code is trying to achieve and what its final output will be.
Approach
- Say what you would check first and why it is the highest-information step.
- Clarify what is being asked and what a complete answer would contain.
- State your assumptions explicitly before working the problem.
Follow-up
- How would you know your answer was wrong?
- What assumption would you test first?
Measure a loyalty threshold effect with regression discontinuity
Travellers reach the gold loyalty_tier in dim_traveller at 10 completed stay-nights within a rolling 12 months; the rule is deterministic and evaluated nightly. Leadership wants the causal effect of gold status on completed stay-nights in the following 90 days, and tier cannot be randomised. Specify the design, the running variable, the estimand you can actually identify, and the two validity checks that would kill it. Then say what you conclude if the density of travellers at exactly 10 nights is 2.3 times the density at 9.
Approach
- Set up a sharp RDD: assignment is a deterministic step function of completed nights in the rolling window, so identification comes from continuity of potential outcomes at the cutoff rather than from randomisation. Estimate with local linear regression on each side, a triangular kernel, a data-driven bandwidth, and bias-corrected robust confidence intervals rather than conventional ones.
- Name the estimand before quoting it: a local average treatment effect for travellers sitting at 9 to 10 nights. It says nothing about travellers at 3 nights or at 40, and the difference matters because the business question is usually about the latter.
- Handle the discreteness of the running variable. Nights are integers with most mass below 15, so the local window holds very few distinct values; use inference designed for a discrete running variable rather than treating it as continuous, and never cluster the standard errors on the running variable itself.
- Run the manipulation test (a density test at the cutoff) and read a 2.3x jump at 10 over 9 as a failed check on its face, since it is consistent with travellers adding a night to qualify, which is self-selection into treatment and breaks continuity.
- Distinguish deliberate manipulation from mechanical heaping before condemning the design: integer stay lengths pile at round totals whether or not a threshold exists, so compare the histogram against a period before the threshold existed or against a cohort on a different threshold. If the heaping predates the rule, it is mechanical; if it appeared with the rule, it is manipulation.
- Confirm nothing else changes at 10 nights. If a coupon, an email trigger or a cancellation-policy change fires at the same cutoff, the discontinuity identifies the bundle and not gold status, and that has to be stated in the headline rather than in a footnote.
Worked solution 45 min
- Define the running variable as completed nights in the rolling 12-month window at the nightly evaluation, and freeze the outcome window as the 90 days after that evaluation date.
- Fit local linear regressions either side with a triangular kernel and a data-driven bandwidth, and report the bias-corrected robust interval alongside the conventional one.
- Run the density test at the cutoff and record the 2.3x ratio, then compare the integer-nights histogram against a pre-threshold period to classify the heaping as mechanical or manipulated.
- Run placebo RDDs at 8 and at 12 nights and confirm both return estimates indistinguishable from zero.
- If the heaping is manipulation, re-estimate as a donut RDD excluding a symmetric window around the cutoff, report the precision cost, and state plainly if the design no longer identifies the effect.
Follow-up
- The threshold is evaluated nightly on a rolling 12-month window, so travellers cross and fall back repeatedly. What does that do to the design and to the running variable?
- The density test fails and manipulation is real. Name an instrument you would consider for tier status and state the exclusion restriction it needs.
- Leadership actually wants the effect at 40 nights. What design gives them that, and what would it cost?
First-stay completion falling for every recent monthly cohort
New-traveller first-stay completion rate, defined as travellers whose first booking reached booking_status = 'stayed' over travellers whose first_booking_created_at_utc fell in the cohort month, has fallen for six consecutive monthly cohorts, from 78% to 54%. Growth has been spending heavily on paid_social over that period. You have dim_traveller (traveller_id, first_booking_id, first_booking_created_at_utc, acquisition_channel) and fct_booking (booking_id, booking_status, lead_time_days, check_in_date). Separate the maturity artefact from any real change, and state what you can and cannot yet conclude about the paid_social cohorts.
Approach
- Say first that the metric as published is not readable for recent cohorts. A cohort is complete only once its 95th-percentile lead time plus the stay length has elapsed, which for lodging commonly runs six to nine months, and six consecutive falling cohorts with the newest falling most is the exact shape maturity produces on its own.
- Re-express at a fixed cohort age: the share whose first booking completed within 90 days of first_booking_created_at_utc, computed identically for every cohort including the mature ones, with 90 no greater than the youngest cohort's elapsed age. That is the only version of this metric that compares cohorts rather than calendars.
- Replot raw against fixed-age. If the fixed-age series is flat, the whole fall was maturity and the investigation is finished. If it still declines, there is something real and the remaining cuts are now worth making.
- Cut the fixed-age series by acquisition_channel and plot each cohort's lead_time_days distribution beside it. A channel bringing longer-lead-time first bookings lowers a 90-day completion rate with no change in follow-through, which is a second maturity effect hiding inside what looks like a channel comparison.
- Control for it by comparing channels within lead-time buckets, or by setting the fixed age per bucket, then state plainly which paid_social cohorts are old enough to judge and which are not.
Follow-up
- The two oldest paid_social cohorts are readable and sit six points below organic at fixed age. Is that the channel or the traveller it brings?
- Growth needs a weekly number to steer spend. What do you give them that will not have to be retracted in six months?
- How do you choose the fixed age when lead time is itself drifting across cohorts?
Instead of guessing where the week should go, day one measures it under a fixed rubric and allocates the remaining hours in proportion to the gaps. The method is deliberately rigid: the allocation is written down before any studying starts and is not renegotiated when a topic turns out to be unpleasant.
Prepare, practise & reflect
One practical outcome each day. Spend longer where you need it.
0 / 7 done01Diagnostic, scored before you study anything
- Sit a 100-minute timed diagnostic in four blocks: 30 minutes of SQL across three prompts, 25 minutes of short-answer statistics, 25 minutes on one modelling or case prompt, and 20 minutes delivering one behavioural story aloud.
- Score each block from 0 to 3 on a fixed rubric where 3 is correct and fluent, 2 is correct but slow or prompted, 1 is partially correct, and 0 is stuck, grading the output rather than how the attempt felt.
- Allocate the hours for days two to five roughly in proportion to 3 minus the score in each block, write the allocation down, and commit to not revising it midweek.
Deliverable: A scored rubric and a fixed hour allocation for the rest of the week.
Practice prompt ↗Practice prompt ↗Worked solution ↗02Largest gap: find the boundary rather than the subject
- Break the weakest area into five named sub-skills (for query work: grain control, window frames, date arithmetic, set logic with NULLs, and reading a query plan) and rate each one, so the rest of the week targets a sub-skill instead of a subject.
- Solve three problems chosen to sit just above where the rating drops off, and for each write the first move you failed to make.
- Re-solve one of them from memory four hours later, on paper, with nothing open.
Deliverable: A five-item sub-skill map with the two blocking sub-skills circled.
Practice prompt ↗Practice prompt ↗03Largest gap: drill the blocking sub-skill
- Do eight short repetitions of the same shape rather than eight different problems, so what you practise is the pattern and not the puzzle.
- Write the rule you now hold in one sentence, then test it against a case built to break it: a ranking function over a column with ties, or a two-sample test on observations that are obviously dependent.
- Have someone else read your one-sentence rule and find the precondition you left out.
Deliverable: One rule statement with its preconditions attached and one counterexample that would have caught the incomplete version.
Practice prompt ↗Practice prompt ↗04Second gap, plus maintenance on your strongest area
- Run the same sub-skill map and boundary protocol on the second-largest gap, compressed into half the day.
- Spend 25 timed minutes on your strongest area to stop it decaying, choosing the hardest problem you can still finish rather than an easy warm-up.
- Compare how the two areas fail: whether you lose time on recall, on setup, or on arithmetic, because the fix differs for each.
Deliverable: A second sub-skill map plus a one-line diagnosis of how each area fails you.
Practice prompt ↗Practice prompt ↗Worked solution ↗05The gap that is not a skill
- Record yourself answering one technical and one behavioural prompt, then count two things in the playback: how many seconds before your first clarifying question, and how many sentences you started without knowing where they ended.
- Rewrite your three most-used stock phrases into shorter versions, and practise saying "I do not know, here is how I would find out" without softening it into a guess.
- Deliver one answer again with a hard 90-second limit to force structure before detail.
Deliverable: Two recordings with a counted improvement in time-to-first-question.
Practice prompt ↗Practice prompt ↗06Retest under day-one conditions
- Sit the same 100-minute diagnostic structure with new prompts of comparable difficulty and score it on the identical rubric.
- Compare block by block, and for any block that did not move, change the method rather than adding hours: a block stuck at 1 usually means the practice was too varied, not too short.
- Write which single block you would still lose the offer on.
Deliverable: A second scored rubric placed next to the first, with one named remaining risk.
Practice prompt ↗Practice prompt ↗07Full loop under interview conditions
- Run a 60-minute mock covering the two blocks that moved least, with an interviewer instructed to interrupt and change direction.
- Write your recovery script for the moment you go blank: restate the question, state your assumption, name the first thing you would check.
- Reduce the week to the rule statements you wrote, each with its preconditions attached, then say every one of them out loud without reading it and cut any you cannot state in a single sentence, since a rule you have to reconstruct mid-answer will not survive being interrupted.
Deliverable: A one-page card holding the recovery script and only the rules you could state from memory.
Practice prompt ↗Practice prompt ↗Worked solution ↗Expand any day for tasks and deliverables. Your progress is saved on this device.
Have two ready. In one, the data was on your side and you had to move someone who outranked you. In the other, the pushback was correct and you changed position. The second is the harder story and it lands better, because it shows you separate being right from being attached to an answer. Name the person's actual objection.
Describe a situation where your model's predictions did not align with…
Describe a situation where your model's predictions did not align with business expectations. How did you investigate the root cause, and how did you communicate your findings to non-technical stakeholders?
Approach
- Pick a story where you drove the decision, not one where you observed it.
- State the situation in two sentences and spend the rest on your reasoning.
- Name the disagreement or constraint, and how you resolved it with evidence.
Follow-up
- What did you decide not to do, and why?
- What would you do differently if you ran that project again?
How do you handle strong seasonality and sudden trend shifts when buil…
How do you handle strong seasonality and sudden trend shifts when building a daily demand forecasting model?
Approach
- Quantify the outcome, including what you would not claim credit for.
- State the situation in two sentences and spend the rest on your reasoning.
- Close with what you would do differently, concretely.
Follow-up
- How did you know the outcome was caused by your change?
- What would you do differently if you ran that project again?
Rank three urgent requests with one analyst-week
You have one week. The pricing team wants a price elasticity for a constrained market to set next quarter's strategy. The supplier team wants a list of suppliers at risk of delisting, for outreach starting Monday. Finance needs a closed stay-month restated after a batch of late cancellations changed platform_net_revenue_usd on fct_stay_night, ahead of a reporting deadline on Thursday. All three escalated to your manager. Produce your order, the reason for each position, and the message you send to whoever is deferred.
Approach
- Sort by deadline irreversibility rather than by who escalated hardest. The finance restatement has an external reporting date, so a miss cannot be recovered later; the other two can start a week late at a cost.
- Check each request for a cheap partial that unblocks the requester without the full job: the supplier team needs a ranked outreach list to start Monday, not a churn model, so a ranked cut on rating_avg, listing_status and recent availability withdrawal may be a few hours rather than days.
- Push back on the elasticity on substance, not capacity. On constrained inventory, price is set from a demand forecast and sold-out unit-dates record capacity rather than demand, so a fast estimate would be biased toward zero and could come out positive; say what you would deliver instead and what a clean estimate would cost.
- Write the deferral message with a date, a reason the requester can verify, and a concrete alternative, because a deferral without a date gets re-escalated within 48 hours.
- Take the ordering to your manager as a decision already made with a named tradeoff, not as a question, and include what you will drop if a fourth request arrives.
Follow-up
- The pricing team says a rough elasticity is better than nothing. What do you give them?
- Two days in, finance's restatement turns out to be twice the size you scoped. What gives?
- How would you stop all three landing in the same week next quarter?
- 01
Describe a situation where your model's predictions did not align with business expectations. How did you investigate the root cause, and how did you communicate your findings to non-technical stakeholders?
- 02
How do you handle strong seasonality and sudden trend shifts when building a daily demand forecasting model?
- 03
You have one week. The pricing team wants a price elasticity for a constrained market to set next quarter's strategy. The supplier team wants a list of suppliers at risk of delisting, for outreach starting Monday. Finance needs a closed stay-month restated after a batch of late cancellations changed platform_net_revenue_usd on fct_stay_night, ahead of a reporting deadline on Thursday. All three escalated to your manager. Produce your order, the reason for each position, and the message you send to whoever is deferred.
Is this an official PriceLabs interview guide?
No. It is PracHub's own research and practice material for the Data Scientist role at PriceLabs. Rounds and questions reflect what candidates have reported, not a process PriceLabs has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How difficult is the Python coding round?
The coding round is rated as moderately difficult. It focuses heavily on practical coding, data manipulation, and logical problem-solving rather than abstract competitive programming puzzles. If you are comfortable manipulating arrays, handling date-times, and writing clean, optimized loops in Python, you will be well-prepared.
PracHub interview research ↗What is the most common reason candidates get rejected during the take-home assignment stage?
Candidates are frequently rejected because they submit a basic baseline model and do not show an iterative process of improving the forecast. The grading team expects you to actively experiment with feature engineering, try different modeling approaches, and demonstrate a deep analytical curiosity to push the model's predictive limits.
PracHub interview research ↗How should I prepare for the culture fit round with the founders?
The founders want to understand what drives you, your interest in the vacation rental space, and how you handle autonomy. Be prepared to talk about your past experiences, how you prioritize tasks, and how you manage ambiguity. They value candidates who are collaborative, humble, and deeply curious.
PracHub interview research ↗What is the typical timeline from the initial screen to an offer?
The process generally takes 3 to 4 weeks. However, because there are multiple assignment-based rounds, the timeline can stretch if there are scheduling delays. Maintaining proactive communication with your recruiter is key.
PracHub interview research ↗Sources & methodology 3 sources ↗
Official role evidence, timestamped platform data and clearly labeled preparation advice.
- 01PracHub interview research ↗
PracHub editorial research into this company and role, maintained with this guide. Candidate-reported, not an employer publication.
platform · Accessed 2026-09-22 - 02PracHub Data Scientist practice ↗
Cross-company practice questions for this role.
platform · Accessed 2026-09-22 - 03PracHub interview preparation framework ↗
The framework the preparation plan follows.
platform · Accessed 2026-09-22