As a Software Engineer at NIKE, you play a central role in driving technical innovation that powers the world's leading sports brand. Technology at NIKE is not just a back-office support function—it is the engine behind global supply chains, cutting-edge direct-to-consumer digital experiences, enterprise Consumer Product & Innovation (CP&I) tools, and data-driven athletic solutions.
In this role, you will work on engineering challenges at massive scale. Whether you are architecting microservices to support high-traffic global product launches, developing intuitive frontend applications for internal product creation, or engineering high-throughput data pipelines on cloud infrastructure, your work directly influences how NIKE designs, manufactures, and delivers products to millions of athletes worldwide.
NIKE's engineering ecosystem relies heavily on cloud-native technology, modern frontend frameworks like React, resilient backend systems built with Node.js, Java, or, and cloud services powered by. Engineers collaborate in dynamic, cross-functional Agile teams alongside product managers, system architects, and business stakeholders, shaping software solutions that redefine digital retail and sports innovation.
Online Assessment
reportedInput bounds are the part of the prompt most often skimmed, and they usually contain the answer. They tell you which complexity class is admissible, which narrows the search before you have thought about the problem itself. As a rough planning figure, a compiled language does on the order of 10^8 simple operations per second and an interpreted one roughly an order of magnitude less. So n up to about twenty admits enumerating subsets, a few thousand admits a quadratic pass, and a million admits neither: you need near-linear, or linear with a log factor. If the bounds are missing, ask for them.
What to demonstrate
- Whether the approach is justified by the stated input size rather than by whichever pattern you recognised first
- Whether you ask about the properties that change the algorithm: whether the input arrives sorted, whether duplicates occur, whether values are bounded integers, whether it all fits in memory
- Whether you can name the bottleneck in your own solution and what would remove it, even when you deliberately leave it in place
- Whether a claimed speedup is real, since memoising a recursion only helps when subproblems genuinely overlap and the state can be keyed cheaply
How to prepare
- For each algorithm you rely on, write down the largest n it handles in roughly a second, then check two of those figures by timing them in the language you will actually type in
- For two weeks, write one line naming your target complexity and the bound that justifies it before you write any code, then compare that line with what you ended up submitting
- Practise the conversion backwards: given a required O(n log n), list the mechanisms that get you there (sorting, a heap, an ordered map, divide and conquer) and choose by what the problem needs to query, not by what you used last
Recruiter Screen
reportedBefore anything technical happens, someone has to decide which rung of the ladder your loop is calibrated to, and that decision sets the bar for every round after it. It comes from how you describe scope, not from your title, because titles do not convert cleanly between companies. The weak version of the answer is team size and years. The strong version names the largest change you shipped where nobody reviewed the design, what would have broken if you had been wrong, and what you were paged for. Get the level said out loud on this call, because the range and the loop both follow from it.
What to demonstrate
- Whether the scope in your own account maps onto a level the team actually has an opening at, so a mismatch ends the process cheaply rather than after four interviewers have spent a day
- Whether your title needs re-mapping: the same word describes very different amounts of independent decision-making at a twenty-person company and a ten-thousand-person one
- Whether your compensation expectation can be filled at that level in the structure the role pays in, which is why the number gets asked for before any engineer is scheduled
How to prepare
- Write down two changes from the last two years: the largest one you designed with nobody reviewing the design, and the largest one where someone more senior did. Lead with the first when scope comes up, and be ready to say which parts of the second were yours
- Ask which level the loop is calibrated to and what changes at the level above it, then plan your weeks from that answer rather than from the posting
- Settle a total-compensation range beforehand with the split named, base against bonus against equity and its vesting period, so a question about numbers gets a number instead of the word market
Technical 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
Onsite Interview Loop
reportedCoding rounds mostly set a floor. They decide whether you clear the bar, not where you land on the ladder. Level tends to come out of the design discussion and the ownership stories, so the question worth auditing beforehand is whether the scope you describe matches the scope of the job. Work that stops at your own service, or a story whose hard part was writing the code rather than getting several people to agree on an interface, reads a level below where you think you are interviewing, and that gap is usually resolved downwards.
What to demonstrate
- Whether the largest thing you describe owning ran end to end — the decision, the migration path, the rollout, and what you did when it went wrong — or stopped at the change you merged
- Whether design answers include what you would not build, what you would defer, and what you would measure before committing, rather than only what the boxes are
- Whether a disagreement in a story was settled with something checkable — a benchmark, a prototype, a written proposal — instead of by seniority or by waiting it out
- Whether you can say which calls you made alone and which you escalated, and why the line sat where it did
How to prepare
- Write your largest piece of owned work as a timeline of decisions — who decided what, when, and what you did when the plan broke — then delete every sentence whose subject is "we" and see how much survives
- Take one system you know well and drill the migration answer: how old and new paths run side by side under live traffic, how you compare their outputs, what the rollback is once writes are going to both, and which step you would not automate
- Map each line of the ladder in the job posting to a specific thing you have done, find the line you cannot support, and prepare the closest evidence you have plus an honest account of the gap
1 candidate reports. Individual accounts describe a particular role and hiring cycle.
NIKE Software Engineer interview: repeated follow-ups and hostile response
The process felt odd and frustrating from the start. I received a virtual interview call only after several follow-ups with HR, even though I had not been invited to an ongoing face-to-face hiring drive. After the interview, I contacted HR for an update and expected a normal status message. Instead, the response was essentially a demand that I stop texting. There was no clear closure, and that ho…
Read full experiencePracHub editorial advice for the preparation topics above.
Representing money as floating point, or rounding tax at a different grain than the total is computed at
Binary floating point cannot represent most decimal fractions exactly, so sums over thousands of lines drift and two services computing the same total from the same inputs disagree in the last place. Rounding grain is the subtler half: rounding tax per line and summing gives a different total than computing tax on the order subtotal and rounding once, and the difference is a cent or two per order — small enough to pass every test and large enough to make the payment provider's amount, the invoice and the finance ledger disagree at month end. Store minor units as integers, and treat the rounding rule as a specification that is applied at exactly one point, propagated everywhere else, and pinned by a CHECK constraint on the order total; which rule is required is jurisdiction-specific, so the engineering obligation is consistency and explicitness rather than a single universal choice.
Charging from a denormalised read model without a quote the checkout re-validates
Prices, promotions and tax rates reach the storefront through an asynchronous pipeline, so the number rendered on the page is a snapshot of state that has already moved on by the time the customer reaches capture. Charging whatever the cache said means honouring expired promotions indefinitely, because nothing in the flow ever re-derives the price; charging whatever is current means the captured amount differs from the displayed amount, which is the failure customers escalate and regulators care about. Mint a signed quote with a short TTL, store its id on the order, re-evaluate at capture, and make the mismatch branch an explicit, visible failure. The detail that gets skipped is the TTL: an unbounded quote is a durable discount that anyone who scripts the checkout can hold open.
Writing code before the input contract is pinned down
Before the first line, state the types, the size bounds, whether duplicates, negatives or an empty input are possible, whether the input is sorted, whether you may mutate it, and what the function returns when nothing matches. Every one of those answers changes the code, and discovering one at minute twenty costs a rewrite you no longer have time for.
Not asking what the system looks like if it dies halfway through
For any multi-step write, say what state remains if the process stops between step two and step three, and what brings it back: a single transaction, a saga with compensating actions, an outbox, or a reconciliation job. Partial failure is routine at any real call volume, so 'that shouldn't happen' is an answer with nothing behind it.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
Write a function to flatten a deeply nested object or tree structure i…
Write a function to flatten a deeply nested object or tree structure into a single-level key-value mapping.
Approach
- State the target complexity and say which constraint rules the naive version out.
- Restate the input: its shape, its size, and what is guaranteed about it.
- Name the brute-force solution and its complexity before improving on it.
Follow-up
- How does this change if the input no longer fits in memory?
- Which test case would catch an off-by-one here?
Demonstrate standard dynamic programming, recursion, or graph/tree tra…
Demonstrate standard dynamic programming, recursion, or graph/tree traversal techniques on live coding platforms or whiteboards.
Approach
- State the target complexity and say which constraint rules the naive version out.
- Walk one small example through your approach before writing the whole thing.
- Name the brute-force solution and its complexity before improving on it.
Follow-up
- Which test case would catch an off-by-one here?
- What is the worst case, and how likely is it on real data?
Reverse letters in an array of strings without affecting spaces and wi…
Reverse letters in an array of strings without affecting spaces and without using built-in array methods.
Approach
- Name the brute-force solution and its complexity before improving on it.
- State the target complexity and say which constraint rules the naive version out.
- Restate the input: its shape, its size, and what is guaranteed about it.
Follow-up
- How does this change if the input no longer fits in memory?
- Which test case would catch an off-by-one here?
Solve array, string, and hash map manipulation problems with optimal t…
Solve array, string, and hash map manipulation problems with optimal time and space complexity.
Approach
- Restate the input: its shape, its size, and what is guaranteed about it.
- Choose the data structure from the access pattern, not from familiarity.
- State the target complexity and say which constraint rules the naive version out.
Follow-up
- How does this change if the input no longer fits in memory?
- What is the worst case, and how likely is it on real data?
Roll up facet counts over a category graph without double counting
Categories form a directed acyclic graph of up to 100,000 nodes and 300,000 child-to-parent edges, and a category may have several parents. Two million active variants each sit in exactly one category. For every category, return the number of distinct active variants in it or any descendant, and refuse to produce counts at all if a supplier feed has introduced a cycle. The memory budget is one gigabyte. State your complexity and where exactness is lost, if it is.
Approach
- Run Kahn's algorithm first: repeatedly remove zero-in-degree nodes, and if any node remains the graph contains a cycle. It costs O(V+E) and hands you the topological order the rollup needs anyway. Report the residual node set so the feed owner sees which edges close the cycle, rather than an assertion that the feed is bad.
- Show why addition is wrong here. On a tree, counts accumulate exactly in reverse topological order. On a DAG, a category reachable from an ancestor by two paths contributes twice, so a straight sum overstates every node above a diamond — and the overstatement is largest at the high-traffic parent categories, which is where a wrong number is most visible.
- Exact distinct counting needs set union. A bitset per node is 2,000,000 bits, or 250 KB, and 100,000 nodes is 25 GB — twenty-five times the budget. Compute that number and abandon the approach explicitly instead of hand-waving past it.
- Use HyperLogLog and merge in reverse topological order. Union is lossless because it is the register-wise maximum, which is exactly the property that makes it safe on a DAG where one variant arrives by two paths. At m = 4,096 registers the relative standard error is 1.04/sqrt(m), about 1.6%, at roughly 4 KB per sketch — about 400 MB for 100,000 nodes, inside budget. At m = 1,024 it is 3.25% error and about 100 MB.
- Complexity: O(V + E) traversal with one sketch merge per edge, O(V*m) space. Then state the exactness policy rather than leaving it implicit: keep exact sets below a cardinality threshold and switch to sketches above it, because the pages where an off-by-a-few count is noticeable are the small ones.
Worked solution 35 min
- Build a 12-node DAG containing one diamond, assign variants to leaves by hand, and write down the exact per-node distinct counts.
- Implement the additive rollup and confirm it overstates at and above the diamond by exactly the shared subtree's variant count.
- Implement the HLL rollup at m = 4,096 and compare against exact counts on the toy graph and on a generated 100,000-node graph.
- Add an edge that closes a cycle and confirm the job refuses with the residual node list rather than looping or emitting partial counts.
Follow-up
- A facet count and the filtered result count differ by 1.4%. What do you show the customer, and which of the two numbers do you fix?
- One variant moves between categories. What must be recomputed, and can it be done incrementally?
- Counts must now exclude variants with zero ATP at every node. Where does that predicate live, and what does it do to your refresh cadence?
Keep the search read model correct when events arrive out of order
Search serves 10,000 queries per second over two million variants with filters, facets and sorting. The origin tables are product_variant, a price table, and one inventory_position row per variant per node. Design the denormalised row the index is built from, justify it from that read pattern rather than from convenience, and write the upsert a consumer runs. Catalog, pricing and inventory publish independently, each with its own monotonic per-row counter, and delivery is at-least-once. State exactly what your upsert does with an event older than the row it hits.
Approach
- Justify the denormalisation with arithmetic rather than with the word performance. Every query filters, facets and sorts, so a live join would hit three sources, and availability alone is a GROUP BY over one inventory_position row per node per variant. At 10^4 queries per second that join is not affordable per request; at 10^2 it would be, and saying so is the difference between a judgement and a habit. One precomputed row per variant is what the read pattern forces.
- Pin the grain and state its cost. One row per variant means a product with forty colourways floods the first page; collapsing to product grain means the displayed price is an aggregate — the cheapest variant satisfying the active filters, which is a different number from the cheapest variant overall. Pick one and make the facet counts agree with it, because counts computed before the filter and results produced after it is a correctness defect, not a ranking preference.
- Reject a single version column. Three producers with independent sequences cannot share one counter: gating a price update with catalog's version either discards good prices or admits stale ones, depending on which producer happens to be ahead. Carry catalog_version, price_version and inventory_version, each gating only the columns its producer owns.
- Make a stale event a no-op rather than an error: INSERT ... ON CONFLICT (variant_id) DO UPDATE SET ... WHERE variant_search_row.catalog_version < EXCLUDED.catalog_version. Then state the consequence the consumer must handle, because it is the part teams miss: a conflict suppressed by that WHERE affects zero rows and RETURNING yields nothing, and a consumer that reads zero rows as failure will retry that event forever.
- Decide availability semantics before storing them. in_stock_any_node is a hint for filtering and ranking and never a promise; the binding decision stays the conditional write against inventory_position. That makes seconds of staleness acceptable here, and makes the worst outcome a customer reaching a variant that turns out to be gone — a refusal at reserve time rather than an oversell.
- Set freshness budgets by consequence rather than uniformly. Price and availability must propagate within seconds because they are user-visible and materially wrong when late; synonyms, boosts and relevance weights ride the next full rebuild, which doubles as the recovery path for a consumer that mis-applied events for an hour.
Worked solution 40 min
- Create variant_search_row with variant_id as primary key, the display and filter columns, and three separate version columns; seed 100,000 rows.
- Apply a catalog event at version 7, then replay version 5 for the same variant, recording rows affected on each.
- Interleave a price event and a catalog event for one variant in both orders and compare the final rows.
- Time the filtered facet query against the denormalised row versus a live three-way join with a per-node GROUP BY, using the same predicate.
- Collapse the three version columns into one, repeat step three, and record what changes.
Follow-up
- A consumer lags an hour and then replays from its offset. What does your version guard do, and what is still wrong after the replay finishes?
- Out-of-stock variants: disappear, sink, or render with a restock date? Give the answer and say what each choice does to facet counts.
- A repricing job emits 200 events per second for one variant for ten minutes. What do you change in the consumer so the rest of the index does not fall behind?
Add a partial unique index to a live reservation table
inventory_reservation holds 400 million rows and takes 2,000 writes per second. You must add UNIQUE (owner_type, owner_id, variant_id, node_id) WHERE state IN ('held','committed') so a double-submitted checkout cannot create two live holds, and separately make a newly added column NOT NULL. Duplicates already exist in the table. Give the ordered plan with the exact statements, state which lock each one takes, say what happens if the concurrent build fails halfway, and say why the application change ships before the index rather than after.
Approach
- Ship the application guard first, and be able to say why. CREATE UNIQUE INDEX CONCURRENTLY validates rows inserted while it is running, so a duplicate created mid-build fails the build after it has already done most of its work. Closing the window in code — the reserve path looking for an existing live hold and returning it — is what makes the build succeed on the first attempt instead of the third.
- Resolve the existing duplicates before building: GROUP BY owner_type, owner_id, variant_id, node_id with state IN ('held','committed') HAVING count(*) > 1, then release all but one through the normal release path. Not a blind UPDATE — releasing units without decrementing reserved_units leaves the counter permanently high, which is exactly the drift the reconciliation job then has to explain to somebody.
- Build concurrently and know the failure mode precisely. CREATE UNIQUE INDEX CONCURRENTLY takes SHARE UPDATE EXCLUSIVE rather than ACCESS EXCLUSIVE, cannot run inside a transaction block, and makes two passes over the table. On failure it leaves an invalid index behind that is ignored by queries but still maintained on every write, and a unique one still enforces uniqueness against newly inserted rows; find it with pg_index.indisvalid = false and remove it with DROP INDEX CONCURRENTLY before retrying.
- Be precise about promoting the index to a named constraint: ALTER TABLE ... ADD CONSTRAINT ... UNIQUE USING INDEX takes ACCESS EXCLUSIVE but only briefly because the index already exists — and it refuses a partial index. On this table the partial index is the enforcement mechanism, and there is no constraint object to attach.
- Get NOT NULL without a full-table scan under ACCESS EXCLUSIVE. ADD COLUMN with a constant DEFAULT is metadata-only from PostgreSQL 11; backfill in batches keyed on the primary key with a commit per batch; then ADD CONSTRAINT chk CHECK (col IS NOT NULL) NOT VALID, VALIDATE CONSTRAINT under SHARE UPDATE EXCLUSIVE, then SET NOT NULL, which from PostgreSQL 12 uses the validated check and skips the scan.
- Wrap every ALTER in SET lock_timeout = '2s' with a retry loop, because ACCESS EXCLUSIVE queues behind any open transaction on the table and every statement arriving afterwards queues behind it — so one long-running report turns a metadata-only change into a full stall on the write path. Between backfill batches, watch replication lag and dead tuple accumulation rather than only wall-clock progress.
Follow-up
- The build fails at 2am with a duplicate-key error naming a reservation created ten minutes earlier. What does that tell you about step one, and what do you do before retrying?
- Roll the whole thing back. What is the reverse of each step, and which one is not reversible?
- The same constraint is wanted on a table range-partitioned by created_at_utc. What changes, and which columns must now be in the key?
Explain how you build serverless architectures utilizing AWS Lambda, S…
Explain how you build serverless architectures utilizing AWS Lambda, Step Functions, DynamoDB, and S3.
Approach
- State the consistency you need, and where you are willing to be stale.
- Fix the scope first: who calls this, how often, and what they do when it fails.
- Name the read and write paths separately; they rarely have the same bottleneck.
Follow-up
- What breaks first when traffic grows ten times?
- How does this behave when that dependency is down for an hour?
How do you approach modernizing legacy enterprise applications into cl…
How do you approach modernizing legacy enterprise applications into cloud-native microservices?
Approach
- Name the failure you are designing for, then the recovery path.
- State the consistency you need, and where you are willing to be stale.
- Name the read and write paths separately; they rarely have the same bottleneck.
Follow-up
- How does this behave when that dependency is down for an hour?
- What breaks first when traffic grows ten times?
How do you manage asynchronous programming, authentication, and core e…
How do you manage asynchronous programming, authentication, and core event loops in Node.js?
Approach
- Work from the requirement backwards to the design.
- State your assumptions explicitly before working the problem.
- Clarify what is being asked and what a complete answer contains.
Follow-up
- How would you know your answer was wrong?
- What assumption would you test first?
Reconcile payment attempts whose outcome is unknown
Your payment service leaves payment_transaction rows in state 'pending' or 'unknown' whenever a provider call times out; the partial index (state, requested_at_utc) WHERE state IN ('pending','unknown') exists for this sweep. The provider permits 50 status lookups per second and answers in 100 to 1000ms. Design the reconciliation worker: how it claims rows, how it avoids racing a request handler still in flight, how it behaves when the provider rate-limits, and why two copies running at once must be safe. Say what happens to a row still unknown after an hour.
Approach
- Claim work with SELECT ... FOR UPDATE SKIP LOCKED LIMIT k over that partial index, ordered by requested_at_utc. SKIP LOCKED is what makes two workers safe without coordination: neither blocks on the other's rows, and a single slow row cannot head-of-line block the sweep. Keep the claiming transaction short and commit the resolution in its own transaction, so a lookup taking a second does not hold locks for a second.
- Resolve by lookup, never by re-issue. Query the provider for your own idempotency key or psp_reference and write the answer. The outcome type has three values, so a lookup that itself times out leaves the row unknown and increments an attempt counter; back off exponentially with jitter, because a fixed interval synchronises every worker onto the provider's next blip.
- Handle the race with the original handler by time and by compare-and-set, not by locking across processes. Only act on rows older than a grace period that exceeds the client timeout, and write with UPDATE ... WHERE state = 'unknown'; zero affected rows means the handler resolved it first and the worker drops the row silently rather than treating it as an error.
- Size concurrency from the rate limit rather than from thread count. By Little's Law, concurrency equals arrival rate times service time, so at 50 lookups/s and a 1s worst case the limiter is 50 in-flight requests, and anything above that just queues at the provider and turns into timeouts. On a 429, halve the limiter and honour the retry-after header; a bounded queue with an explicit shed policy beats an unbounded one that converts overload into latency.
- Define the escalation and the invariant it protects. After the horizon, an unresolved row moves to a manual queue and the order is held: no further capture and no refund against that payment until the row is definite, because a refund issued while an earlier attempt is unresolved is exactly how total refunded exceeds total captured.
Worked solution 30 min
- Write the claim query against the partial index and confirm it is an index scan, not a sequential scan over payment_transaction.
- Implement resolution as a provider lookup plus a compare-and-set write, with an explicit no-op branch for zero affected rows.
- Compute the concurrency limit from the rate limit and worst-case latency, and state the number.
- Run two worker copies against the same backlog and confirm each row is looked up once and written once.
- Force a 429 from a stub provider and confirm the limiter halves and the backlog drains rather than erroring out.
Follow-up
- The provider's lookup returns 'not found' for a key you know you sent. What are the possible causes, and what do you write?
- A worker resolves a row to 'succeeded' after the order was already cancelled and the authorization voided. What happens next?
- How far back does the sweeper look, and what stops it rescanning a year of settled rows every minute?
One search partition stops updating while the others stay current
The search index is rebuilt from catalog, pricing and inventory events on a partitioned log keyed by variant_id across 16 partitions. Support reports that a subset of products show a price and availability that are three days stale, while everything else is current within seconds. Consumer lag on partition 7 is growing linearly; the other 15 are flat near zero. Diagnose it, give the ordered checks, the fix, and state precisely what the fix costs.
Approach
- Confirm the blast radius matches the partition key before touching the consumer. Hash a dozen of the reported SKUs and check that every one maps to partition 7. If some do not, the stale set is not explained by one partition and the consumer is the wrong suspect.
- Look at the committed offset rather than the lag graph. Lag growing at exactly the produce rate with a frozen committed offset is head-of-line blocking, not slowness; lag growing more slowly than the produce rate is a throughput problem and has a completely different fix.
- Read the consumer log around the frozen offset. A handler that throws and retries the same record in place never commits, so the same offset appears repeatedly with the same exception. Here the record is a supplier-feed variant whose attributes JSONB carries a facet value with a unit suffix, and the index mapper coerces that facet to a number.
- Reproduce by replaying that single record into a scratch consumer before changing anything, so the fix is verified against the actual poison rather than a guess about it.
- Fix the class, not the record: bound the in-place retries, then route the record to a dead-letter topic, commit the offset and let the partition drain. Add an alert on dead-letter depth. Replay is safe afterwards because product_variant.version is monotonic per row and the indexer already discards any event below the version it holds.
- State the cost plainly. A dead-lettered record means that variant's price and availability stay stale until someone replays it, which for a legally material field is worse than an alert nobody reads — so dead-letter depth has to page a human, not fill a dashboard.
Follow-up
- The poison record is a price change. What does the storefront render for that variant between dead-lettering and replay, and who decides?
- The same feed writes 400 bad records in one run. What should the consumer do differently from the single-record case?
- How do you validate supplier feeds at the catalog service so this class of record never reaches the log?
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 ↗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 ↗Practice prompt ↗Worked solution ↗Expand any day for tasks and deliverables. Your progress is saved on this device.
Counting review comments or mentees proves nothing. The useful version is a specific change you approved with a reservation you stated, or one you blocked and the delay that cost. Say which standard you were holding and why it was worth the friction. A mentoring story needs the thing the other person can now do without you.
Why do you specifically want to work at NIKE compared to other global …
Why do you specifically want to work at NIKE compared to other global technology companies?
Approach
- Pick a story where you made the decision, not one where you watched it.
- State the situation in two sentences and spend the rest on the reasoning.
- Close with what you would do differently, concretely.
Follow-up
- What did you decide not to do, and why?
- How did you know your change caused the improvement?
How do you handle cross-functional collaboration and technical disagre…
How do you handle cross-functional collaboration and technical disagreements with product managers or engineering managers?
Approach
- Close with what you would do differently, concretely.
- Give the blast radius: what could have broken, and what you measured.
- 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?
Unblock an engineer chasing a duplicate authorization
A less experienced engineer is investigating reports of two pending amounts on one order. Their branch retries the provider call with a freshly generated idempotency key after a timeout, and they argue the provider must not have received the first request because no response came back. You have half an hour and you are not going to take the keyboard. Describe how you unblock them, what you make them work out rather than tell them, and describe a real time you did this — including what you checked afterwards to know it had landed.
Approach
- Correct the premise with a question rather than a statement: ask what a timeout tells you about the server's state. The answer is nothing — the request may have been processed and either the request or the response lost — so the outcome type has three values, and a new key on retry creates a second authorization the customer can see on their statement.
- Make it concrete in the schema they are already reading, because abstractions do not transfer. In payment_transaction the state column already carries 'unknown' alongside 'pending', 'succeeded' and 'failed', the row is written before the call, and the idempotency_key column is unique, so the retry that is safe is the one carrying the same key.
- Give the resolution rule explicitly since it is not derivable from first principles: an 'unknown' is resolved by querying the provider for that key or reference, never by issuing anything new, and nothing else on that payment proceeds until it is definite.
- Push the structural point one level up, which is the part worth their time: a boolean return type makes this bug unavoidable no matter how careful the caller is, so the fix in their branch is a type change plus the sweeper, not a better retry.
- Check the transfer instead of assuming it. Ask them to write the sweeper's predicate themselves — the partial index on state IN ('pending','unknown') with a requested_at_utc bound — and to say how it avoids racing the original caller and why it must be safe to run twice concurrently.
- Follow through afterwards: review their pull request rather than rewriting it, and have them present the three-state model at the next team session, which is what turns one fix into a change in how the next one is written.
Follow-up
- They ask why the provider cannot just make every call idempotent. What do you tell them?
- Their sweeper runs every minute and occasionally resolves a transaction the original caller is still waiting on. How do you have them handle that?
- How do you know a fortnight later whether the mentoring landed, without asking them?
- 01
Why do you specifically want to work at NIKE compared to other global technology companies?
- 02
How do you handle cross-functional collaboration and technical disagreements with product managers or engineering managers?
- 03
A less experienced engineer is investigating reports of two pending amounts on one order. Their branch retries the provider call with a freshly generated idempotency key after a timeout, and they argue the provider must not have received the first request because no response came back. You have half an hour and you are not going to take the keyboard. Describe how you unblock them, what you make them work out rather than tell them, and describe a real time you did this — including what you checked afterwards to know it had landed.
Is this an official NIKE interview guide?
No. It is PracHub's own research and practice material for the Software Engineer role at NIKE. Rounds and questions reflect what candidates have reported, not a process NIKE has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How difficult are the technical interviews for a Software Engineer at NIKE?
The technical interviews are moderately challenging and focused on practical software engineering. While you will encounter algorithmic problem-solving and coding assessments, the questions prioritize clean code writing, data structure choices, and practical system design over obscure mathematical puzzles.
PracHub interview research ↗How much weight is placed on the behavioral "Why NIKE?" question?
A significant amount of weight is placed on this question. NIKE values corporate culture and brand passion deeply, so interviewers across technical and managerial rounds look for an authentic connection to NIKE's product mission, values, and workplace environment.
PracHub interview research ↗What primary tech stack should I focus on during my preparation?
While tech stacks vary across different teams within Global Technology, focusing on core JavaScript / Node.js, React, Java, SQL, and general AWS cloud services will cover the majority of engineering team stacks.
PracHub interview research ↗What is the typical timeline from the initial interview screen to an offer?
The recruitment lifecycle usually takes around 3 to 4 weeks. It begins with recruiter outreach, proceeds through online assessments and technical panel rounds, and concludes with managerial discussions and offer negotiations.
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-24 - 02PracHub Software Engineer practice ↗
Cross-company practice questions for this role.
platform · Accessed 2026-09-24 - 03PracHub interview preparation framework ↗
The framework the preparation plan follows.
platform · Accessed 2026-09-24