A Software Engineer at News Corp plays a vital role in sustaining and evolving the digital ecosystem of one of the world's most influential media and information services companies. You will be responsible for building, maintaining, and scaling the platforms that deliver high-traffic news, data, and digital content to millions of global users. This role is not just about writing code; it is about solving complex engineering challenges that ensure high availability, performance, and reliability across diverse digital properties.
Working at News Corp means operating at the intersection of traditional media and cutting-edge technology. You will collaborate with cross-functional teams, including product managers, platform architects, and fellow engineers, to translate business requirements into robust technical solutions. Whether you are focusing on backend infrastructure, platform reliability, or data-driven features, your work directly impacts how the world consumes information. You can expect a high-stakes, fast-paced environment that demands both technical precision and a strong sense of ownership.
Phone Screens
reportedThe title covers product work, platform work, infrastructure, mobile and frontend, and those are different jobs with different loops behind them. A screening call is the cheapest place to find out which one the seat is, and asking reads as experienced rather than fussy. The questions that separate them: what the team is on call for, what the last three projects were, and whether any round happens inside an existing repository instead of a blank file. Then say which of that you have done and which you have not. Claiming the whole posting is the fastest way to be found out one round later.
What to demonstrate
- Whether you can locate your experience inside one flavour of the role honestly instead of claiming the entire requirements list
- Whether you name what you have not done, which an experienced screener reads as a level signal and can plan the loop around
- Whether what you want next matches what the seat is: someone who wants greenfield work landing on a team that mostly operates an existing system is a hire that leaves within the year
How to prepare
- Mark every line of the posting as done, adjacent or new, and write one sentence for each adjacent line naming the closest thing you actually built
- Split your last two years into rough percentages across feature work, operating and debugging live systems, and design or review, so a question about scope gets numbers rather than adjectives
- Bring three questions that discriminate between seats: what the team is paged for, how much of the work is changing existing code versus standing up something new, and what shipped in the last quarter
Technical Tests
reportedThe same problem is scored by two different mechanisms depending on the format, and preparing for one does not cover the other. With a person watching, partial progress is visible and a hint is a correction you can absorb; silence is the expensive failure, because nobody can read a half-written function. With an automated grader there is no partial credit for what you were about to do, nobody to ask, and the worked examples in the prompt are the entire specification. Read them as a contract, down to whether an empty result should be an empty list or no output at all.
What to demonstrate
- In a live session, whether your commentary tracks what your hands are doing, and whether a hint redirects you or gets defended against
- In an automated one, whether you cover the cases the examples do not show, since the hidden cases are where the score moves
- Whether you manage the clock on purpose: abandoning an approach that is not converging while there is still time to write something simpler that finishes
How to prepare
- Have someone hand you a problem and feed you one deliberately wrong hint. Practise testing it against a concrete case instead of accepting or rejecting it on authority.
- Do one timed run a week in a plain browser editor with autocomplete, linting and your own snippets switched off, which is closer to what these environments give you
- For the automated format, write the harness before the solution: a main that feeds the worked examples plus an empty and a single-element case and prints expected against actual, so a wrong submission is caught by you first
Panel Interviews
reportedA day like this is several different games in a row, and the expensive mistake is carrying the previous one into the next room. Coding rewards narrow precision and finishing inside a timer. Design rewards breadth, stated assumptions and naming what you are deliberately not building. Behavioural rewards specificity about people and decisions. Candidates who over-engineer a coding problem they were supposed to finish, or who start sketching class hierarchies before anyone has agreed what the system has to do, are usually still playing the last round. Between rooms, name out loud which game the next one is.
What to demonstrate
- Whether the coding round ends with something that runs and has been traced against a degenerate input, rather than an extensible design that was never finished
- Whether a design discussion opens by agreeing on traffic shape, read-to-write ratio and what is allowed to be stale, instead of proceeding from an architecture you arrived with
- Whether a behavioural answer names a person, a disagreement and what you did about it, rather than describing the system the story happened inside
- Whether the opening habits still appear late in the day: restating the problem, asking for constraints, saying the plan before typing
How to prepare
- Book three mocks of different types back to back on one afternoon and ask each interviewer afterwards which round you answered in the wrong mode
- Write a three-line opening script per round type — coding: restate, name the approach and its cost, then type; design: ask for scale, read-write mix and what must not break; behavioural: name the person, the stakes and the decision — and run it off a card so the switch is mechanical rather than remembered
- Practise coding with a timer you do not extend, stopping when it stops, so the trained reflex is to finish a correct solution rather than to keep improving one
Final Discussions
reportedNobody in the room with you decides this. Interviewers typically write their rounds up separately, often before seeing anyone else's, and the outcome is settled later from those write-ups. A split panel gets resolved by whichever note carries specific evidence, so what you want out of each room is one concrete thing that person could write down: a bug you caught yourself, a trade-off you named, a decision you owned. The rest is arithmetic. The project you describe in a behavioural conversation is often the same system you sketched an hour earlier, and the two accounts have to agree.
What to demonstrate
- Whether the scale, team size and timeline you attach to a project hold steady when that project resurfaces in a different round
- Whether each interviewer leaves with a specific thing to cite rather than a general impression of competence
- Whether a trade-off you defended in one round survives a challenge in another, instead of being quietly swapped for the answer the new interviewer seemed to want
- Whether a question you have already answered earlier in the day gets the same answer at the same depth, without visible impatience
How to prepare
- Write a one-page sheet per project fixing the figures you will quote — request volume, data size, team size, elapsed time, what broke — and say them aloud from the sheet until they come out identical every time
- For each round on the schedule, decide in advance the one sentence you want in that person's notes, then check in a mock that you said it outright instead of leaving it to be inferred
- Have someone ask you the same project question twice, an hour apart, and diff the two answers for numbers that moved or a trade-off that reversed
PracHub editorial advice for the preparation topics above.
Letting the live playlist grow with the DVR window.
A sliding-window playlist carries one entry per segment, so a four-hour DVR at two-second segments is 7,200 entries - at roughly 100 bytes per entry, about 720,000 bytes - and every viewer refetches the document about once per target duration. At 100,000 concurrent viewers that is 720 kB x 100,000 every two seconds, roughly 288 Gbit/s of playlist text that is nearly identical between fetches. Delta playlist updates and byte-range addressing solve it, but they have to be designed in, not discovered once the playlist has become the largest object being served.
Assuming one encrypted copy of the ladder serves every DRM system.
Common encryption (ISO/IEC 23001-7) defines several protection schemes, and two matter in practice: AES-CTR full-sample ('cenc') and AES-CBC pattern encryption ('cbcs'). One of the three widely deployed DRM systems accepts only cbcs, and older client versions of the other two accept only cenc, so a single-copy strategy is correct only if every device class you still support has reached cbcs. Discovering late that one legacy class has not means a second packaging run, a second set of objects in every cache, and roughly double the storage for the affected catalogue.
A cache with no invalidation story
Say how an entry goes stale, how long you can serve it stale, and what happens when many requests miss the same key at the same instant. One popular key expiring under load sends every concurrent request to the origin together; single-flight coalescing, jittered expiry, or serving stale while revalidating are the standard answers.
Finishing a solution without stating its complexity
Give time and space in the same breath as the code, and define n explicitly when there are two sizes, since n nodes and m edges are not interchangeable. Space is the half that gets skipped: count the auxiliary structures you allocate and the recursion stack at its deepest, not only the answer you hand back.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
Rank delivery groups by rebuffer ratio without ranking on noise
A completed hour of telemetry yields roughly 10^6 groups keyed (cdn_pop, device_class, isp), each arriving as an unordered stream of per-minute partials carrying qualified_starts and rebuffered_starts. On-call needs the 50 worst groups by rebuffer ratio, excluding groups too small to mean anything: a group with 3 starts and 1 rebuffer reads as 33%. Return the top 50 with their ratios and sample counts. Target something better than a full sort, and state both time and space.
Approach
- Two phases, forced by the fact that the ranking key is a ratio that is only final once every partial for a group has landed. Phase one is a hash aggregation of partials into per-group counters, O(n) time and O(g) space for g groups.
- Phase two selects with a size-50 min-heap keyed on the ratio: O(g log k) time and O(k) space, against O(g log g) for a sort. At g = 10^6 and k = 50 that is about 6 comparisons per group rather than 20. Quickselect is O(g) but needs every group resident and mutable, so the heap wins when phase one streams.
- Apply the minimum-sample floor before the heap, never after. At a floor of 200 qualified starts the standard error of the ratio is sqrt(p(1-p)/n), about 1.5 percentage points at p = 5%, so the ordering carries information. Filtering after the heap leaves it full of three-sample groups and returns fewer than 50 usable rows.
- Offer the alternative that removes the arbitrary cutoff: rank on the lower bound of a Wilson score interval, which shrinks small groups toward the population mean automatically. The cost is a heavier comparison per group and a figure that is no longer the raw ratio people expect on the dashboard.
- If g does not fit in memory, partition by hash of the group key, take a local top-50 per shard and merge. Top-k decomposes this way only because each group's aggregate is complete within its shard, which the hash partition guarantees.
Worked solution 20 min
- State why the ratio cannot be ranked incrementally and draw the phase boundary explicitly.
- Write the heap selection with the floor applied at the push site, and give its complexity against a full sort at g = 10^6, k = 50.
- Compute the standard error at your chosen floor and use it to defend the floor's value.
- Describe the shard-local top-50 merge and say why hash partitioning is what makes it valid.
Follow-up
- Make it a rolling one-hour top-50 recomputed every minute. What changes when groups must also be evicted as old minutes leave the window?
- Two groups tie on ratio but differ 100x in volume. Which do you page on, and what does that argue about ranking on count-weighted impact instead of on ratio?
Choose ladder rungs against a measured bandwidth distribution
You have 60 candidate encoding rungs sorted ascending by bitrate, and an audience bandwidth histogram of 1,000 buckets measured from delivered throughput. A viewer plays the highest rung whose bitrate is at most 80% of their sustained throughput, and cannot play at all if no rung qualifies. Choose exactly 12 rungs, always including the lowest candidate, maximising total delivered bitrate across the audience. Return the chosen rungs and the objective value, state the complexity, and say why a log-spaced ladder is not automatically the answer.
Approach
- Precompute for each candidate i the bucket at which viewers can first afford it, threshold_i = bitrate_i / 0.8, by binary search over the bucket edges: O(n log m). Build a prefix sum over bucket counts so any viewer-count range is O(1).
- Formulate the contribution: with the selected set sorted, if rung i is selected and j is the next selected rung, every viewer whose threshold falls in [threshold_i, threshold_j) plays rung i, contributing count * bitrate_i. Call it value(i, j), computable in O(1) from the prefix sums.
- Run the DP over (last selected rung, rungs used): f[j][t] = max over i < j of f[i][t-1] + value(i, j), with the lowest rung forced selected and a sentinel j = n+1 closing the final interval. O(n^2 k) = 60^2 * 12, about 43,000 transitions. The point is that the ladder is measured, not that the algorithm is clever.
- Say when the structure buys more: if value satisfies the concave quadrangle inequality, the inner maximisation admits divide-and-conquer optimisation at O(n k log n). That condition depends on the histogram's shape and must be tested on the real distribution rather than assumed.
- Name what the objective leaves out, because the interview point is the modelling: storage and cache footprint scale with rung count, device decode limits make some rungs unusable by whole client classes, and delivered bitrate is a crude proxy for perceived quality. Log spacing is a prior about a smooth unimodal distribution, and measured throughput is usually bimodal, which is exactly where the prior loses.
Follow-up
- Add a per-device decode cap so one client class cannot use rungs above 1080p. Does the DP still decompose, and along which dimension?
- Throughput varies during playback and the player switches rungs. What does that do to the highest-affordable-rung model, and what would you measure instead?
- Storage and cache footprint become a hard budget rather than a fixed rung count. Which dimension of the DP state changes?
Recompute the downstream job set after a single rendition re-encode
The packaging pipeline for one content version is a DAG of up to 10^5 jobs and 5 x 10^5 edges: source validation, per-chunk encodes, per-rendition concatenation, packaging, encryption, manifest generation, publish. QC fails one video rung, so its chunk encodes are re-run on a different encoder build. Given the edge list and a set of dirty job ids, return every job that must re-run plus a valid execution order for them, and report whether the graph contains a cycle. Target O(V + E) time.
Approach
- Build forward adjacency (job -> dependents) in one O(E) pass over the edge list. No sorting is required anywhere in this problem.
- Collect the affected set S by BFS or DFS from the dirty set over forward edges, marking a visited bitset. O(V + E), each node and edge touched once.
- Order S with Kahn's algorithm run on the induced subgraph, recomputing in-degrees counting only edges whose tail is also in S. Reusing whole-graph in-degrees is the failure here: clean predecessors outside S leave phantom in-degrees, the ready queue starts empty and nothing is ever emitted.
- Detect the cycle from Kahn's own termination condition: if emitted count < |S|, the residual nodes contain a cycle and everything it feeds. Report the residual set rather than asserting, because a malformed encoder profile is a data bug, not a crash.
- State the trade-off against re-running the whole version: the affected set is one rung's chunks plus concatenation, packaging, encryption, manifest and publish, so you save the 6-12x ladder fan-out. But manifest and publish are common descendants of every rung and are therefore always in S, which is precisely why re-encoding one rung is not a local change.
Follow-up
- The re-encode uses a different encoder build. Which additional nodes become dirty, and why is encoder_build_id pinned per asset rather than taken from the pipeline default?
- Two rungs fail QC concurrently and two invalidation runs overlap. What makes the recomputation idempotent so the second run does not restart jobs the first already completed?
Stop two devices winning the last concurrent stream slot
playback_session(id UUID PK, account_id, status ENUM('starting','active','ended'), last_heartbeat_at, started_at) and account_plan(account_id PK, max_concurrent_streams INT). Session start currently runs SELECT count(*) FROM playback_session WHERE account_id = :a AND status = 'active', compares the result with the plan limit, then inserts. A household on a two-stream plan regularly ends up with three. Name the anomaly, say which PostgreSQL isolation levels do and do not prevent it, then give a schema and a statement that hold the limit, plus the lease TTL and heartbeat interval you would set and why.
Approach
- Name it precisely: write skew over a phantom. Both transactions evaluate the same predicate, both see one active session, and each inserts a row the other's read would have matched. Neither writes a row the other wrote, so there is no write-write conflict for the database to block on and no constraint to violate.
- Give the isolation answer without hand-waving. READ COMMITTED does not prevent it. REPEATABLE READ in PostgreSQL is snapshot isolation and does not prevent it either — snapshot isolation stops lost updates on the same row, not write skew across a predicate. SERIALIZABLE does, via SSI predicate locks: one transaction aborts with SQLSTATE 40001 and the caller retries. Price that: a retry loop sits directly in front of the first frame, and SSI's conflict tracking runs on a path taking 10^3 to 10^4 starts per second.
- Prefer materialising the conflict to raising the isolation level. Pre-create the plan's slots as rows:
account_stream_slot(account_id, slot_no, session_id NULL, expires_at NULL, PRIMARY KEY (account_id, slot_no)). A phantom problem becomes a row-lock problem, which every isolation level already handles correctly and cheaply. - Acquire in exactly one statement:
UPDATE account_stream_slot SET session_id = :sid, expires_at = now() + interval '90 seconds' WHERE (account_id, slot_no) = (SELECT account_id, slot_no FROM account_stream_slot WHERE account_id = :a AND (session_id IS NULL OR expires_at <= now()) ORDER BY slot_no LIMIT 1 FOR UPDATE SKIP LOCKED) RETURNING slot_no. Zero rows updated means the account is at its limit — a product outcome to return to the viewer, not an exception. SKIP LOCKED makes two simultaneous starts take different slots instead of one queueing behind the other. - Reclaim by predicate rather than by a sweeper.
expires_at <= now()inside the acquire means a crashed client's slot is reusable the instant it expires, with no background job anywhere in the correctness path. Renew withUPDATE ... WHERE account_id = :a AND slot_no = :n AND session_id = :sid: thesession_idequality is what stops a late heartbeat, from a client whose slot already expired and was reassigned, from stealing it back. - Defend the numbers in both directions. At a 10-second heartbeat and a 90-second TTL a client must miss eight consecutive heartbeats before eviction, and a crashed client strands a paid slot for up to 90 seconds. Do not compute the eviction rate as a per-heartbeat loss probability raised to the eighth power — losses are correlated, a mobile handover drops a burst — so size the TTL against the measured distribution of short outages, not against an independence assumption that does not hold.
Worked solution 35 min
- Reproduce: open two sessions, run the count in both, then insert in both, and confirm a two-stream account ends with three active rows.
- Repeat at REPEATABLE READ and confirm both still commit; repeat at SERIALIZABLE and record which transaction receives 40001.
- Create the slot table with two rows for the account and implement the single-statement acquire.
- Run two acquires concurrently and record the returned slot numbers and affected row counts, then run a third.
- Force one slot's
expires_atinto the past, acquire from a fourth client, and then run the original holder's renew.
Follow-up
- The lease store is Redis and the session table is PostgreSQL. What happens when the Redis acquire succeeds and the session insert then fails?
- A viewer moves from phone to television mid-title. Should the phone's slot be released explicitly, and what failure modes does that add?
- Two starts arrive for the same device and the same title four milliseconds apart. Should they consume one slot or two, and what key decides?
Make a monthly payout scan use an index at two billion rows
qualified_play(id BIGSERIAL PK, session_id, content_version_id, rights_holder_id, account_id, territory_code, qualified_at TIMESTAMPTZ, status ENUM('pending','counted','reversed'), source ENUM('online','offline_sync'), dedupe_key UNIQUE, counted_in_period) holds about two billion rows, roughly 150 million per month, and is physically ordered by insert time. The monthly close runs SELECT rights_holder_id, count(*) FROM qualified_play WHERE date_trunc('month', qualified_at) = DATE '2026-08-01' AND status = 'counted' GROUP BY 1 and scans the entire table. Give three separate reasons it does, and the change you would make for each.
Approach
- Reason one is the expression. Wrapping the column in
date_truncmakes the predicate non-sargable, so no b-tree onqualified_atis usable and the planner also falls back to a default selectivity guess instead of the column's histogram. Rewrite to the half-open rangequalified_at >= DATE '2026-08-01' AND qualified_at < DATE '2026-09-01', which selects the same rows. An expression index is the alternative, but in PostgreSQLdate_trunc(text, timestamptz)is STABLE rather than IMMUTABLE because it depends on the session TimeZone, so it cannot be indexed directly — you would indexdate_trunc('month', qualified_at AT TIME ZONE 'UTC')and write the predicate in exactly that form. - Reason two is selectivity, and the fixed predicate does not remove it. One month is about 7.5% of the table; at roughly 50 rows per page the table is about 40 million pages, and 150 million rows scattered across it touch essentially every page. A plain index scan would pay random I/O for the whole table while a sequential scan reads it in order — the planner is right. Make the scan index-only instead:
(status, qualified_at, rights_holder_id)covers every column the query touches, so the plan reads index pages alone. That holds only while the visibility map is current, which makes it a dependency on autovacuum keeping up with continuous inserts. - Reason three is structural.
status = 'counted'is most of the table and is not selective by itself, but a partial indexWHERE status = 'counted'keeps reversed and pending rows out of the index entirely. At two billion rows the real fix is range partitioning byqualified_atmonth: the close reads one partition, the planner prunes the rest, and the partition boundary lines up withcounted_in_periodso a period close and a partition are the same object. - Name the BRIN trap before someone reaches for it. BRIN is the obvious cheap index for an append-ordered table and it is tight on the arrival timestamp — but
qualified_atis when the threshold was crossed, andoffline_syncrows land days later, so physical order correlates with arrival rather than withqualified_at. Checkpg_stats.correlationfor the column instead of assuming; poor correlation makes every block range a candidate and the index worthless. - Settle it with EXPLAIN (ANALYZE, BUFFERS) rather than argument, and look at estimated versus actual rows for the range predicate first. A plan that goes wrong at this size usually went wrong at the estimate, and a wrong estimate has a different fix from a wrong index.
- Sequence the work by cost and risk: rewrite the predicate first because it is free and takes no lock, measure, then build the covering index with CREATE INDEX CONCURRENTLY, and only then consider partitioning, which is a migration of the whole table rather than an addition to it.
Follow-up
- The close also needs plays that qualified in August but arrived in September. Which of your changes still works, and which partition does a late row live in?
- The same aggregate is now wanted per territory as well. Do you widen the covering index or accept the scan?
- How would you prove the scan really is index-only in production rather than on a freshly vacuumed copy?
What is your approach to designing a data layer or system specificatio…
What is your approach to designing a data layer or system specification?
Approach
- State your assumptions explicitly before working the problem.
- Clarify what is being asked and what a complete answer contains.
- Work from the requirement backwards to the design.
Follow-up
- How would you know your answer was wrong?
- What assumption would you test first?
How would you implement multi-threading in Java?
How would you implement multi-threading in Java?
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 contains.
- Work from the requirement backwards to the design.
Follow-up
- What assumption would you test first?
- How would you know your answer was wrong?
Turn at-least-once heartbeats into exactly-once qualified plays
Heartbeats arrive at 100,000 per second carrying (session_id, seq, played_ms, position_ms, client_ts). Delivery is at-least-once and out of order, a crashed player resumes under the same session_id, and an offline client can deliver days of buffered events in one burst. qualified_play carries dedupe_key UNIQUE, status ENUM('pending','counted','reversed') and counted_in_period, and money is paid against it. Give the stream partition key, how watch time is accumulated, the sessionisation rule including sessions that never report an end, the dedupe key, the period-close policy, and the backpressure for bulk replay.
Approach
- Partition by session_id and say why the alternative loses. The dedupe grain is the session, so partitioning by session_id makes the seen-sequence state partition-local and gives per-session ordering from per-partition ordering alone; client-generated UUIDs hash evenly, so no partition goes hot. Partitioning by account_id colocates an account's sessions and buys nothing, because no rule in this pipeline spans sessions.
- Order and deduplicate on (session_id, seq), never on client_ts. Client clocks are skewed and untrusted, so a timestamp is a data field rather than an ordering key; the per-session sequence number is the only monotone thing the client produces. Keep the seen-sequence set per session with a TTL past the idle gap so the state does not grow with lifetime session count.
- Accumulate watch time as MAX(played_ms) over the session rather than a sum of position deltas. Seeking backwards makes deltas negative and seeking forwards makes them enormous, so delta accounting turns a viewer scrubbing a title into a negative or multi-hour watch. MAX is also idempotent under duplicate and out-of-order delivery, which is exactly the property at-least-once transport demands, and it is the reason the naive version passes every test written from a happy-path trace.
- Sessionise as gaps-and-islands with an explicit idle gap, and close the sessions nobody closed. Order by (session_id, seq), open a new island when the gap since the previous heartbeat exceeds three heartbeat intervals plus margin, and run a reaper that sets ended_at = last_heartbeat_at and end_reason = 'unknown' for sessions past the gap, because a client that simply stopped reporting will never send an end. The query is O(n log n) dominated by the sort unless the store already clusters by (session_id, ts).
- Derive dedupe_key deterministically from session_id, content_version_id and the qualification-threshold version, so a crashed player regenerating it collides on the unique index. Insert with ON CONFLICT DO NOTHING and never update in place; a correction is a reversing row so the period close stays reproducible from the table alone. Hold the period open for at least the maximum offline licence life, then close, and let anything later land in the next period with counted_in_period set to that close.
- Give bulk replay its own path. A days-long offline sync is not proportional to current concurrency and cannot be capacity-planned from it, so route it to a separate topic with its own consumer group and lower priority, keeping operational alerting on startup time and rebuffer ratio out from behind a replay. Rate-limit per device at ingest with 429 and Retry-After, and require a durable client-side queue with jittered retry, because these events are payable and dropping them loses a rights holder money.
Worked solution 40 min
- Choose the partition key and state the ordering and dedupe guarantee it gives you, plus the one it does not.
- Write the gaps-and-islands query with the idle-gap constant, and add the reaper that closes never-ended sessions.
- Define dedupe_key's inputs and argue it survives client retry, a player crash and a bulk offline sync.
- Write the period-close rule and the shape of a reversing row for an arrival after close.
- Size the replay path: separate topic, per-device limit, and the consumer-lag signal you alert on.
Follow-up
- A device ships with a bug that resets seq to zero every 65,536 events. What breaks, and how do you repair the affected days?
- Finance needs a period closed on the third working day, but offline licences last 30 days. Reconcile those two requirements concretely.
- How would you detect that a client is inflating played_ms, and what would you do with the sessions you flag?
Licence p99 collapses at live start while dependency looks healthy
At a scheduled live start, licence issuance goes from 300 to 3,000 requests per second, p99 rises from 40 ms to 9 s, 12% of requests time out and playback fails with decrypt errors. One entitlement-store read replica sits at 400 ms, up from 5 ms, with zero errors and a green health check. The licence path opens a transaction, locks the account's entitlement-snapshot row, calls the entitlement service, writes a license_grant row and commits. Fleet connection pools total 800. Give the ordered checklist and the two changes you would make.
Approach
- Separate queueing from service time first. Break the request into time waiting for a pool connection and time executing. If pool wait dominates, the pool is the queue and the cause sits upstream of the database: a long hold, not a slow statement.
- Do the concurrency arithmetic. Required concurrency is arrival rate times hold time. At 3,000 per second with a 5 ms hold that is 15 connections; with the entitlement call at 400 ms inside the transaction the hold is roughly 405 ms, so required concurrency is about 1,215 against 800 available. Demand exceeds capacity, the queue grows without bound for the duration of the spike, and p99 becomes queueing delay rather than work.
- Measure lock wait per row before assuming which lock matters. Fan-in on the account's entitlement-snapshot row is one account's own sessions, so it is small and is not the ceiling here. State the conditional you are ruling out: had the lock been on a per-channel key row, every session on the channel would serialise on it and the ceiling would be one over the hold time, about 2.5 acquisitions per second at 400 ms, which would collapse far harder than observed.
- Explain the green dashboard so it stops being reassuring. A degraded replica that still answers has no error rate, and availability or p50 indicators hide it. The signals that show it are the dependency's p99 by replica and the caller's own pool-wait metric; a health check that the replica passes tells you nothing about hold time.
- Change one: never hold a lock or a pooled connection across a network call. Resolve entitlement before opening the transaction, so the transaction contains only local writes and the hold drops back to a couple of milliseconds and required concurrency to single digits.
- Change two: bound the blast radius with a per-dependency timeout well below the client's, a concurrency limiter or circuit breaker on the entitlement call, and no unbounded retries, since retrying into a saturated dependency is what turns a slow replica into an outage. Name the degradation you choose: refusing a licence stops playback, so failing open would delete the only enforcement point in the system, and the correct behaviour is to shed load and fail closed with a retryable error.
Follow-up
- Key rotation on a live channel makes every session ask for a licence in the same second. How do you spread that without weakening enforcement?
- What should a client do on a licence timeout, and how do you stop its retries becoming the second wave?
- Would caching licences fix the load, and exactly what would it cost you?
Four days sample coding, design, fundamentals and the practical rounds at deliberately shallow depth, which is enough to surface the topics you did not know were in scope. That map, rather than a guess made on day one, decides where the last three days go.
Prepare, practise & reflect
One practical outcome each day. Spend longer where you need it.
0 / 7 done01Coding, one pass at shallow depth
- Solve one problem from each of six families, an array with two pointers, hash counting, binary search, a tree traversal, a graph traversal and one dynamic program, under a hard twenty-minute cap with no extensions, marking each finished, late, or stalled.
- For every stall, write the exact move you could not make rather than the subject, so the note reads could not turn the recurrence into a loop rather than bad at dynamic programming.
- Fix nothing today. The value of the pass is the unfixed record.
Deliverable: Six timed attempts marked finished, late or stalled, each stall carrying a named blocking move.
Practice prompt ↗Practice prompt ↗Worked solution ↗02Design, one pass at shallow depth
- Spend twenty minutes each on three different shapes, a read-heavy feed, a write-heavy ingest path, and something needing a transaction across two entities, stopping each at requirements, interface and data model.
- After each, write the first question you could not answer, which is usually a number you could not estimate or a failure mode you had no vocabulary for.
- Mark which of the three you would be most relieved not to be asked, and treat that as data rather than as a preference.
Deliverable: Three shallow designs, each with the first unanswerable question written at the bottom.
Practice prompt ↗Practice prompt ↗03Fundamentals and the practical rounds
- Answer eight short questions in writing at four minutes each, covering the material that fills the gaps between the big rounds: what happens between a URL and a rendered page, what an index costs on write, when a process is preferable to a thread, and what conditions a deadlock requires.
- Do one thirty-minute practical task of the kind a take-home compresses: read an unfamiliar two-hundred-line file and write what it does, what you would change, and the one thing you remain unsure of.
- Score every answer fluent, correct but slow, or absent, and keep the absent ones visible.
Deliverable: Eight scored short answers and one written reading of unfamiliar code.
Practice prompt ↗Practice prompt ↗04The rounds that are about you, and the map
- Deliver three behavioural answers aloud against a timer, a conflict, a failure you owned, and a decision made without enough information, marking any that ran past three minutes or contained no number.
- Assemble the map: every marked item from days one to three on a single page, sorted by how likely it is to appear in your loop rather than by how uncomfortable it felt.
- Choose exactly two areas for the remaining three days and write down what you are deliberately abandoning.
Deliverable: A one-page scored map of the whole surface area with two areas chosen and the rest explicitly abandoned.
Practice prompt ↗Practice prompt ↗Worked solution ↗05First chosen area, to the depth you skipped
- Work the higher-ranked area in four focused blocks, choosing items one level above where you stalled rather than repeating what already works.
- After each block write the rule you extracted in one sentence with its precondition attached, since a rule carrying no precondition is exactly what fails under a variation.
- Re-attempt the day-one or day-two item that exposed this area and compare against the original timing.
Deliverable: Four worked blocks, a timed re-attempt against the original, and three one-sentence rules with preconditions.
Practice prompt ↗Practice prompt ↗06Second chosen area, where the gap is coverage rather than speed
- Treat the second area differently from the first. Day five drilled something you could already half-do; this one is usually a topic you had simply never met, so build one worked reference example end to end and keep it, rather than attempting six problems badly.
- Write down the vocabulary you were missing on day two or three, five terms at most, each with the one sentence that makes it usable in an answer rather than the textbook definition.
- Redo the shallow attempt that exposed this area and note whether you now fail later in the problem, because moving the failure point is the realistic gain from a single day and is worth more than a score that did not change.
Deliverable: One worked reference example for the newly covered area, a five-term vocabulary list, and a note on where the failure point moved.
Practice prompt ↗Practice prompt ↗07Reassemble the loop
- Sit two rounds back to back with no gap, ordering them so the area you chose second comes last, because the map was built from rested, isolated attempts and the loop will reach your weaker area when you are already spent.
- Write where the second round suffered from the first, which is normally the point at which structure collapses into narration.
- Reduce the week to one page holding only the rules you can state without reading them.
Deliverable: Mock notes on cross-round carryover plus a one-page card of rules you can recite from memory.
Practice prompt ↗Worked solution ↗Expand any day for tasks and deliverables. Your progress is saved on this device.
Team size, service count and tickets closed say very little. Seniority shows in the decision you owned: what you chose not to build, which constraint you traded away, whose objection you had to resolve before anything could move. A large project where you executed someone else's plan is a small story.
Can you walk us through your previous experience and the projects you …
Can you walk us through your previous experience and the projects you have led?
Approach
- Close with what you would do differently, concretely.
- Name the disagreement and how you resolved it with evidence.
- Give the blast radius: what could have broken, and what you measured.
Follow-up
- What did you decide not to do, and why?
- What would you do differently if you ran that again?
How do you handle the build, deployment, and ongoing support of a prod…
How do you handle the build, deployment, and ongoing support of a production system?
Approach
- Give the blast radius: what could have broken, and what you measured.
- State the situation in two sentences and spend the rest on the reasoning.
- Pick a story where you made the decision, not one where you watched it.
Follow-up
- What would you do differently if you ran that again?
- How did you know your change caused the improvement?
What are some of your biggest professional achievements to date?
What are some of your biggest professional achievements to date?
Approach
- Give the blast radius: what could have broken, and what you measured.
- Close with what you would do differently, concretely.
- Pick a story where you made the decision, not one where you watched it.
Follow-up
- How did you know your change caused the improvement?
- What would you do differently if you ran that again?
Can you explain your experience with Python programming?
Can you explain your experience with Python programming?
Approach
- Give the blast radius: what could have broken, and what you measured.
- State the situation in two sentences and spend the rest on the reasoning.
- Pick a story where you made the decision, not one where you watched it.
Follow-up
- What would you do differently if you ran that again?
- What did you decide not to do, and why?
- 01
Can you walk us through your previous experience and the projects you have led?
- 02
How do you handle the build, deployment, and ongoing support of a production system?
- 03
What are some of your biggest professional achievements to date?
- 04
Can you explain your experience with Python programming?
Is this an official News Corp interview guide?
No. It is PracHub's own research and practice material for the Software Engineer role at News Corp. Rounds and questions reflect what candidates have reported, not a process News Corp has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How long should I prepare for the interview?
Given the technical nature of the role, plan at least 2–3 weeks to review your core technical skills and practice system design scenarios. Consistent, focused practice is more effective than last-minute cramming.
PracHub interview research ↗What differentiates successful candidates?
Successful candidates are those who can clearly articulate their technical choices and demonstrate a genuine interest in News Corp's mission. Being able to explain "why" you made a decision is just as important as the code you write.
PracHub interview research ↗Is the interview process difficult?
Candidates generally describe the process as rigorous and demanding. Expect to be pushed on your technical knowledge, but know that the panel is typically professional and focused on finding the right fit.
PracHub interview research ↗What is the typical timeline for the hiring process?
Timelines can vary, but you should expect the process to take several weeks from the initial screen to the final decision. Stay communicative with your recruiter throughout the process.
PracHub interview research ↗Sources & methodology 3 sources ↗
No official company page is cited. Rounds and questions come from candidate reports and PracHub editorial material; each source shows the date it was read.
- 01PracHub interview research ↗
PracHub editorial research into this company and role, maintained with this guide. Candidate-reported, not an employer publication.
PracHub page · Accessed 2026-09-22 - 02PracHub Software Engineer practice ↗
Cross-company practice questions for this role.
PracHub page · Accessed 2026-09-22 - 03PracHub interview preparation framework ↗
The framework the preparation plan follows.
PracHub page · Accessed 2026-09-22