A Software Engineer at AMD writes software that runs on AMD silicon and exposes its performance: Ryzen processors, EPYC server chips, Radeon GPUs and Instinct AI accelerators. Depending on the group, that means systems software, compiler infrastructure, graphics drivers, embedded firmware, profiling tools such as AMD uProf, or ROCm, the open-source GPU computing platform.
The work is close to the hardware. The role notes list low-level C/C++ runtimes, system drivers and middleware, LLVM compiler passes, CUDA or HIP compute kernels, automated build and regression suites in Python, TCL or C++, and diagnosing hardware-software interaction bugs with system profilers, logic analyzers and custom tracing tools. Some teams also contribute to open-source projects such as LLVM, GCC, the Linux kernel and ROCm.
Candidate reports describe GPU software, compiler engineering, platform verification and firmware groups each running their own hiring pipeline, with timelines and panel makeup that vary, so expect the technical emphasis of your loop to depend on the team. Build a common core first: C/C++ pointers and memory, data structures and algorithms, and computer architecture (caches, memory hierarchy, interrupts, concurrency). Then add the team's specialism, such as GPU kernels and profiling for compute teams, or Verilog, digital logic and clock-domain crossing for hardware-adjacent teams.
Recruiter Screening
reportedAn initial assessment of your background and logistical fit for the role. Candidates report that different AMD engineering groups run their own hiring pipelines, so use this call to find out which group the role sits in (GPU software, compilers, platform verification, firmware or another) and which technical areas the later rounds will cover. That answer decides how you split the rest of your preparation.
What to demonstrate
- Whether your background matches the role's core requirement of strong C or C++ plus data structures and computer architecture fundamentals
- Logistical fit: location, start date, work authorisation and any timeline constraints you need to raise early
How to prepare
- Write a short summary of your background that names the languages, hardware concepts and tools you can discuss in depth, and leave out anything you cannot defend in a technical follow-up
- Ask which team the role belongs to, whether the technical loop leans toward systems, GPU, compiler or hardware-verification topics, and what format the technical assessment will take
- Have your constraints and any competing timelines written down so you can state them plainly
Hiring Manager Screening
reportedA technical discussion with the hiring manager built around your resume, plus high-level technical questions. Candidates report that project walkthroughs at AMD are detailed technical discussions, not short summaries, so expect follow-ups on any language, tool or hardware concept you list. Treat each resume project as something you may have to explain end to end.
What to demonstrate
- Whether you can explain the architecture of a project on your resume end to end and say which parts you personally built
- Whether you can defend technical trade-offs and debugging decisions from past work when the questions get specific
- How well your experience fits the team's area, such as drivers, compilers, GPU compute or verification
How to prepare
- For your two strongest projects, prepare an architecture walkthrough: components, data flow, your own contribution, one trade-off you made, and one bug you tracked down and how
- Collect the actual performance numbers or results from those projects so you can cite them instead of describing them vaguely
- Go through your resume line by line and remove or brush up on any tool, language or concept (Verilog, CUDA, HIP, LLVM, Linux internals) you could not discuss in detail
Core Technical Loop
reportedThe main evaluation phase, reported as 2 to 4 role-specific technical interviews, held either as one virtual panel or as separate sessions. Areas described for this phase are technical problem solving, live coding, systems architecture discussions, digital logic or embedded concepts where relevant, and in-depth project walkthroughs. Exact panel makeup is reported to vary by team.
What to demonstrate
- Technical problem solving and live coding, with attention to correctness, edge cases and complexity
- Systems architecture discussions
- Digital logic or embedded concepts, where relevant to the team
- Whether your project walkthroughs hold up under detailed technical follow-up
How to prepare
- For live coding, practise problems from the reported coding category (an LRU cache with a hash map and doubly linked list, in-place linked list reversal with cycle detection, grid minimum-path DP) by hand, without autocomplete
- For architecture discussions, work through the reported architecture category and give each answer a path from mechanism to software consequence, for example why pointer chasing defeats caching and prefetching and stalls the pipeline
- If the team is hardware-adjacent, practise the reported hardware-category questions: a synchronous D flip-flop and a divide-by-3 clock divider in Verilog, and async FIFO depth from burst length and the two clock rates
Technical Assessment
reportedReported to vary by candidate. It can be a coding session or a discussion of system architecture. Because the format is not fixed, ask your recruiter which one to expect and prepare for both rather than assuming.
What to demonstrate
- In a coding format, whether you reach a correct, traced solution and can state its complexity
- In an architecture format, whether you can reason about memory layout, concurrency and hardware behaviour, not only high-level components
How to prepare
- Confirm the format with your recruiter as soon as this stage is scheduled
- For coding, practise in a plain editor with no compiler help, then trace your code by hand against an empty input, a single element and a typical case
- For architecture, rehearse examples from the reported architecture category: optimising matrix multiplication for cache-line use on a CPU, memory coalescing in GPU kernels versus cache-line prefetching on CPUs, and the hardware steps during a page fault
- Also rehearse the reported low-level systems examples that touch architecture, such as a thread-safe circular queue in C++ and virtual-to-physical address translation
15 candidate reports. Individual accounts describe a particular role and hiring cycle.
AMD Software Engineer Interview Experience — GPU Systems, Inference, and an Offer
The author reports receiving an AMD GPU software engineering offer after interviews for a Toronto/Markham team. Recruiter outreach led to an initial screen and an extended hiring-manager conversation. An in-person onsite followed roughly two weeks after availability was requested, and the offer arrived about three weeks after that visit. The four onsite sessions covered inference systems, agent a…
Read full experienceAMD Software Engineer interview: WhatsApp-style design and DP questions
The hardest part of my loop was the systems-level design work. I was asked to cover both high-level and low-level design, then I got dynamic-programming prompts as part of the technical evaluation. One design prompt was essentially to build a messaging app like WhatsApp from scratch, and I had to explain what tech stack I'd use if I were developing it today. For the DP questions, I solved one med…
Read full experienceAMD Software Engineer interview: low-level C/C++ and hardware integration
My process began with an initial recruiter and hiring-manager screening, followed by a fairly rigorous technical loop. The format was described as a sequence of two to four rounds. The interviews focused on low-level systems knowledge, C/C++ coding, and how hardware and software need to work together. The questions weren't abstract brainstorming. They kept coming back to how I'd reason about syst…
Read full experienceAMD Software Engineer interview on timing and DFT
My interview centered on my project experience, beginning with how I handled both my master's and undergraduate work. The technical conversation moved into more specific areas, including timing and static timing analysis, where the questions became fairly in-depth. I also discussed architectural topics and some DFT basics. The interviewers wanted me to speak concretely about what I had done and c…
Read full experienceAMD Software Engineer interview: two in-person technical rounds and delayed feedback
I had a couple of in-person technical rounds, and the interviewers gave me a positive signal because the sessions went smoothly. The process felt normal at the time, so I expected that I was moving forward. Afterward, the recruiter didn't update me for about two weeks. I followed up repeatedly, asking several times, and the response eventually became negative. The communication felt unprofessiona…
Read full experiencePracHub editorial advice for the preparation topics above.
Giving a surface-level summary of a resume project in the hiring manager screen or a technical project walkthrough
Resume projects at AMD are reported to get detailed technical questioning. For each project you list, prepare the architecture end to end, the part you personally built, a trade-off you made and what you rejected, a hard bug and exactly how you found it, and the real performance figures. If you cannot go that deep on a project, cut it down or drop it.
Listing Verilog, CUDA, HIP, LLVM or Linux kernel experience you cannot discuss in detail
Candidates report that questions are often built from the tools and concepts on their resume. Before the loop, go through every keyword and ask yourself whether you could answer two follow-up questions on it. If not, revise it until you can or remove it. A keyword you cannot back up costs you more than one you left off.
Writing pointer and linked-structure code that breaks on edge cases, such as an LRU cache or in-place list reversal
For the reported coding questions, trace your code by hand on an empty list, a single node, a two-node list and a list with a cycle. For the LRU cache, check that get moves the hit node to the front of the list, that put inserts or updates the node in both the hash map and the list, and that eviction removes the tail node from both structures. Practise without a compiler, since reported questions include fixing a C snippet without compiling or running it.
Answering architecture questions with a definition and stopping there
For pointer chasing, cache coherence, DMA or CPU core versus GPU compute unit, go from the mechanism to what it means for software. For example, dependent loads serialise memory latency and defeat the prefetcher. Cache line bouncing between cores slows shared-counter code. DMA needs cache and ordering management before the CPU reads the buffer. Finish each answer with a change you would make to the code.
Guessing at the cause of a segfault, memory corruption or alignment bug instead of narrowing it down
Walk through the snippet line by line, say what each variable holds, and state your hypotheses out loud before you change anything. For driver-style questions where no standard debugger is available, have a method ready: logging or tracing, assertions and guard values around buffers, and bisecting recent changes.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
Implement an efficient cache mechanism using a combination of a HashMa…
Implement an efficient cache mechanism using a combination of a HashMap and a doubly linked list.
Approach
- Restate the input: its shape, its size, and what is guaranteed about it.
- Walk one small example through your approach before writing the whole thing.
- Choose the data structure from the access pattern, not from familiarity.
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?
Solve a dynamic programming problem to calculate the minimum path cost…
Solve a dynamic programming problem to calculate the minimum path cost in a grid with custom constraints.
Approach
- Name the brute-force solution and its complexity before improving on it.
- Restate the input: its shape, its size, and what is guaranteed about it.
- Choose the data structure from the access pattern, not from familiarity.
Follow-up
- Which test case would catch an off-by-one here?
- How does this change if the input no longer fits in memory?
Debug a given C snippet with memory alignment issues and fix it withou…
Debug a given C snippet with memory alignment issues and fix it without compiling or running the code.
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.
- 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?
How do you debug a segmentation fault or memory corruption issue in a …
How do you debug a segmentation fault or memory corruption issue in a C-based driver without using a standard debugger runtime?
Approach
- Name what is shared across threads and what owns each piece of state.
- Reach for the cheapest primitive that closes the race, not the broadest lock.
- Say what the runtime actually does before reasoning about the code.
Follow-up
- Where could this allocate more than you expect?
- How would you prove the race exists rather than suspect it?
Write a program to reverse a singly linked list and detect cycles with…
Write a program to reverse a singly linked list and detect cycles without using extra memory.
Approach
- Reach for the cheapest primitive that closes the race, not the broadest lock.
- Name what is shared across threads and what owns each piece of state.
- Distinguish a value from a reference to it, and say which one you handed out.
Follow-up
- How would you prove the race exists rather than suspect it?
- Where could this allocate more than you expect?
Schedule ordered webhook retries with a heap of subscription queues
Design the in-memory scheduler for webhook delivery. Up to 20 million rows sit in status pending or failed_retryable across 200,000 subscriptions, each row carrying next_attempt_at and attempt_count, and each endpoint having a circuit breaker. Deliveries for one subscription must be attempted in order, so at most one attempt per subscription may be in flight. Support due(now), complete(delivery, outcome) and insert(delivery) in O(log S), where S is the subscription count rather than the delivery count. Give the backoff formula you schedule retries with.
Approach
- Key the global heap by subscription, not by delivery. Each subscription owns a FIFO of its due deliveries in event order; the heap holds one entry per eligible subscription, keyed by its head's
next_attempt_at. That is 200,000 heap entries instead of 20 million, and it makes the one-in-flight rule structural rather than a check somebody can forget. due(now): peek the minimum. If its key is in the future, sleep until then instead of spinning. Otherwise pop it, move the subscription into an in-flight set, and do not re-push it. A subscription absent from the heap cannot be dispatched twice, which is precisely how ordering is preserved.complete: on success, drop the head and re-push the subscription keyed by its new head, or leave it out when the queue empties. On a retryable failure, incrementattempt_countand setnext_attempt_at = now + uniform(0, min(cap, base * 2^attempt)), sampled uniformly across the whole interval. That is full jitter; deterministic backoff re-synchronises the herd you just created.- Circuit breaker: park the subscription in a second heap keyed by its half-open time, so an endpoint dead for six hours costs one heap entry and zero attempts rather than consuming worker slots. Admit exactly one probe at half-open and close the breaker only on its success.
- Say the price of the ordering guarantee out loud. One in-flight attempt per subscription means an endpoint answering in 10 seconds drains at 0.1 deliveries/second however many workers you run, and its backlog grows until it recovers. If the customer does not need order, allow k in flight and document delivery as unordered; that is the trade, and it is a product decision.
- All three operations are O(log S) with O(S) resident heap memory and the queues themselves backed by the store. The database-backed equivalent is a partial index on
(subscription_id, next_attempt_at) where status in ('pending','failed_retryable')claimed withFOR UPDATE SKIP LOCKED, and the write-back must be fenced onlease_tokenso a worker that stalled and resumed cannot overwrite a newer attempt.
Worked solution 30 min
- Define the four structures explicitly:
queues: subscription_id -> deque[delivery],ready: min-heap of (next_attempt_at, subscription_id),inflight: set[subscription_id],breaker: min-heap of (half_open_at, subscription_id). - Write down the invariant you will assert after every operation: a subscription appears in at most one of
ready,inflightandbreaker, never in two. - Implement
due,completeandinsert, then simulate 200,000 subscriptions with Zipf-distributed queue depths totalling 20 million deliveries. - Add one endpoint that always times out after 10 seconds and one that always answers in 20 ms, then measure the fast endpoint's throughput with and without the per-endpoint breaker.
- Instrument heap size across the run.
Follow-up
- One subscription has 4 million queued deliveries. What stops it from starving the other 199,999, and what does your heap look like under that load?
- A customer requests redelivery of last Tuesday's events. Where do those rows enter your structure, and what keeps them from reordering live traffic?
- The process restarts. How much state do you rebuild, and what stops every subscription from being attempted in the same second?
Decide which facts an invoice line copies instead of joining
invoice_line_item already denormalises tenant_id, which is reachable through invoice_id, and stores amount_minor even though quantity times unit_price_micros would recompute it. A reviewer asks you to normalise both away, and separately asks whether the tenant's legal name and billing address should be copied onto the invoice header. Decide each case. For every field you keep denormalised, name the read pattern or the invariant that justifies it, the anomaly the copy can develop, and the mechanism that prevents that anomaly here.
Approach
- Split the question into two kinds of copy, because they fail differently. A copy of a currently mutable fact is a cache: it drifts and needs invalidation. A copy of a fact frozen at write time is not a cache at all, it is the record of what happened, and normalising it away destroys information the source no longer holds.
- Keep tenant_id on the line. It costs 8 bytes, it leads every index on the table so no read is ever accidentally cross-tenant, and it turns a wrong join into an empty result rather than another tenant's money. Prevent the drift structurally: a unique constraint on invoice (invoice_id, tenant_id) plus a composite foreign key from the line on (invoice_id, tenant_id) makes a mismatched pair impossible, so the database enforces agreement instead of a code review.
- Keep amount_minor. Rounding must happen exactly once, at a named site, with a stated mode (half-even here). If readers recompute from quantity and unit_price_micros, every reader owns a rounding decision, and half-up and half-even diverge systematically across thousands of lines rather than cancelling out. A check constraint can bound the stored value but deliberately cannot re-derive it.
- Copy the legal name and billing address onto the invoice header, written once and never updated. The statement must show what was true when it was sealed, and the tenant record will change afterwards. This is a snapshot for the same reason
source_rollup_watermarkis stored per line: without it, nobody can reconstruct what the customer was told. - Name the read pattern that pays for all of it. Rendering, dispute response and export are per-tenant, per-period reads over thousands of lines that would otherwise join back to slowly changing dimensions that no longer hold the historical value. The write side is a once-per-period batch, so the extra columns cost nothing that matters.
- Concede the case where the reviewer is right: a mutable operational attribute such as the tenant's current plan name has no business on a line. If a report wants it, join. If a statement needs the plan as of the period, that is another snapshot and it belongs on the header with the rest.
Worked solution 25 min
- Write the DDL: unique (invoice_id, tenant_id) on invoice, the composite FK from the line, and a comment on each denormalised column saying whether it is a snapshot or a cache.
- Attempt to insert a line whose tenant_id differs from its invoice's and confirm the foreign key rejects it.
- Rename a tenant, re-render a sealed invoice, and confirm the rendered name is the one stored on the header.
- Recompute amount_minor from quantity times unit_price_micros for a thousand synthetic lines rounding half-up, sum both ways, and record the divergence from the stored half-even values.
Follow-up
- Write the composite foreign key and the unique constraint it requires on the parent. What does it cost on every line insert, and what does it do to a bulk load?
- A tenant is renamed after being invoiced. Which rows change, and what does the customer see on last quarter's PDF?
- Where does currency live, and what breaks if a tenant's billing currency changes between two periods?
Enforce a concurrent-run quota that survives simultaneous requests
A plan allows at most 20 concurrently running rows in job_run per tenant. The table holds run_id, tenant_id, workspace_id, status (queued, leased, running, succeeded, failed, timed_out, cancelled, lost), lease_token, leased_until, started_at and finished_at. Today the service runs select count(*) from job_run where tenant_id = $1 and status = 'running', compares the result to 20, then inserts. Under load a tenant exceeds the cap by exactly the number of concurrent requests. Name the anomaly, say which isolation levels do and do not prevent it, and give a version that holds, as SQL.
Approach
- Name it: write skew. Each transaction reads a predicate (the count of running rows), neither modifies what the other read, and both then insert rows that jointly violate an invariant no single row expresses. Read committed permits it. So does repeatable read, because snapshot isolation's first-updater-wins check fires only on conflicting row updates, and these are inserts touching disjoint rows.
- Enumerate the fixes with their real costs. SERIALIZABLE works: PostgreSQL's SSI tracks the predicate read and aborts one transaction with SQLSTATE 40001, which obliges the caller to retry and makes the abort rate rise with contention on a hot tenant. Folding the predicate into the write as
insert ... select ... where (select count(*) ...) < 20narrows the race to the statement's snapshot but does not close it under read committed. - Give the version that holds at read committed: serialise on a row both transactions must touch.
update tenant_concurrency set running = running + 1 where tenant_id = $1 and running < 20 returning runningupdates zero rows when the cap is reached, and zero rows is the rejection. This works because at read committed a blocked UPDATE re-evaluates its WHERE clause against the newly committed row; at repeatable read the same statement raises a serialisation error instead, so the isolation level changes the calling contract. - State the cost you just bought. That row is now a per-tenant serialisation point, so admission throughput for the tenant is bounded by one divided by the lock hold time; at a 2 ms hold that is roughly 500 admissions/second. Keep the critical section to the single UPDATE, with no network call or scheduling decision inside the transaction, and decrement in the same transaction that writes the terminal status.
- Close the leak the status enum implies: a run can end as
lost, so a crashed worker otherwise consumes a slot forever. Reconcile on a schedule againststatus = 'running' and leased_until < now(), and treat the counter as a fast path overjob_run, which stays the system of record.
Follow-up
- Write the retry loop for the SERIALIZABLE version. What does the caller see when it keeps aborting, and what bounds the retries?
- Two regions each keep a counter. What is the effective cap, and what does admission do when the counter store is unreachable?
- The cap changes mid-flight on a plan upgrade. Do running jobs get killed, and what does the counter row look like during the change?
How does pointer chasing affect CPU cache utilization and pipeline thr…
How does pointer chasing affect CPU cache utilization and pipeline throughput?
Approach
- Choose a partition key and say what query it makes expensive.
- Name the failure you are designing for, then the recovery path.
- 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 would you drop to keep the system up under load?
Explain the role of Direct Memory Access (DMA) and how asynchronous me…
Explain the role of Direct Memory Access (DMA) and how asynchronous memory transfers are coordinated with the CPU.
Approach
- 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.
- Choose a partition key and say what query it makes expensive.
Follow-up
- What would you drop to keep the system up under load?
- How does this behave when that dependency is down for an hour?
Describe the architectural differences between a CPU core and a comput…
Describe the architectural differences between a CPU core and a compute unit within a modern AMD GPU.
Approach
- Name the read and write paths separately; they rarely have the same bottleneck.
- Choose a partition key and say what query it makes expensive.
- Fix the scope first: who calls this, how often, and what they do when it fails.
Follow-up
- What breaks first when traffic grows ten times?
- What would you drop to keep the system up under load?
How do you calculate asynchronous FIFO depth to prevent overflow durin…
How do you calculate asynchronous FIFO depth to prevent overflow during cross-clock domain transfers?
Approach
- Say what you would check first and why it is the highest-information step.
- Work from the requirement backwards to the design.
- State your assumptions explicitly before working the problem.
Follow-up
- What assumption would you test first?
- How would you know your answer was wrong?
Metering ingest that survives a six-hour producer replay
metering-ingest consumes usage events at-least-once - 250M/day, 10-40k/second at peak - and folds them into usage_rollup_hourly keyed (tenant_id, workspace_id, sku, hour_start). usage_event is partitioned daily on ingested_at with unique (ingested_day, tenant_id, idempotency_key). A producer outage ends in a six-hour replay that re-sends events already ingested, some of whose originals crossed midnight. Design the consumer: partitioning, where the acknowledgement sits relative to the commit, the deduplication horizon and its storage cost, and how the rollup watermark advances. Nothing may be double-counted and nothing may be silently dropped.
Approach
- Choose the acknowledgement position deliberately and name what each choice costs. Acknowledging after the fold commits makes the consumer at-least-once: a crash between the two replays the batch and produces duplicates, which are ordinary and absorbable. Acknowledging first makes it at-most-once: a crash between the two drops revenue with no error raised anywhere and no way to detect it later. Take at-least-once and design everything downstream to absorb duplicates.
- Put the dedup and the fold in one transaction so there is no window between them. Insert the batch into usage_event with ON CONFLICT DO NOTHING, take the rows actually inserted, and fold only those into usage_rollup_hourly with an upsert on (tenant_id, workspace_id, sku, hour_start) bucketed by occurred_at, not ingested_at. A batch of about 2,000 rows is one round trip and one index probe per event.
- Attack the partition-key flaw head on: the unique index includes ingested_day because a unique index on a partitioned table must contain the partition key, so the same (tenant_id, idempotency_key) re-sent after midnight is a different index entry and passes. Deduplicate instead against a store keyed (tenant_id, idempotency_key) with no date component, whose horizon exceeds the producer's maximum retry window plus the longest replay you intend to support. At 14 days that is 250M x 14 = 3.5 billion keys, which is a dedicated key-value store, not a larger index on the same table. The alternative - partitioning usage_event on (tenant_id, occurred_day) so the natural key is stable - fixes dedup but loses pruning on ingest time and makes retention by dropping partitions awkward.
- Partition the consumer by hash of tenant_id so one tenant's replay stalls only its own partitions, and give replay traffic a separate lower-priority lane so live ingest keeps its latency. The cost is explicit: that tenant's watermark lags while the replay drains, and everything gated on the watermark waits for it.
- Define the watermark as a property of committed work, not of wall-clock time: per partition it is the largest occurred_at such that every event with a smaller occurred_at has committed, and the sealing decision uses the minimum across partitions. Record source_max_ingested_at on every rollup row so any number can prove what it did and did not include, and keep restatement legal only while status = 'open' - after sealed_at the value is frozen and a late event becomes an invoice adjustment instead.
Worked solution 40 min
- Write the consumer loop in pseudocode with the acknowledgement after the commit, then annotate each line with what is lost or duplicated if the process dies exactly there.
- Size the dedup store: events/day x horizon_days keys, bytes per key including the tenant prefix, and the resulting memory or disk. Compare that cost against simply extending retention on the partitioned table and say why the latter does not fix the problem.
- Take one event ingested at 23:59:58 and replayed at 00:00:04 and work out its fate under (a) the partitioned unique index alone and (b) the separate dedup store.
- Write the per-partition watermark formula, then what the seal uses, then what a single stalled partition does to sealing.
Follow-up
- The dedup store is lost entirely. What can you still guarantee, and how do you rebuild it from what remains?
- A replay delivers events for an hour that is already sealed. Trace exactly what happens to them, row by row.
- One partition is stuck on a poison message, so the minimum-across-partitions watermark never advances and no tenant can be sealed. What is your escape hatch and what does it cost in correctness?
Metering partition crash-loops and the sealing watermark freezes
One metering-ingest partition has stopped advancing. Lag grows linearly, the consumer restarts about every 40 seconds, and the same offset appears in every startup log while other partitions stay healthy. Events are committed in batches of a few thousand and the acknowledgement follows the commit. Sealing is six hours away and source_max_ingested_at for that partition's tenants is frozen. Give an ordered checklist, a containment action available within minutes, and the durable fix, saying what each does to exactly-once accounting.
Approach
- Distinguish a poison record from a capacity problem in one measurement: compare the offset and the exception across restarts. An identical pair every time is deterministic failure on one record, whereas a throughput problem still advances the offset between crashes.
- Read the record from a separate consumer group so the bytes can be inspected without perturbing the stuck consumer, then classify the defect: schema violation, a quantity failing the non-negative check, a null workspace, an unmappable SKU enum, or a payload past a size limit. That classification decides whether this is a producer bug or a missing consumer guard.
- Account for batch granularity before acting. With commits of a few thousand, one bad record fails thousands of good ones, so the blast radius is the batch. Halve the batch around the offset to isolate the record, or move to per-record error isolation so the radius becomes the record.
- Contain by diverting that record to a dead-letter store with its raw bytes and offset, then resume. This is safe here precisely because the acknowledgement follows the commit: the good records from the failed batch are re-consumed and absorbed by the uniqueness check on (tenant_id, idempotency_key) rather than counted twice.
- Make the fix durable with per-record error isolation, a bounded poison counter, and an alert on dead-letter rate rather than on lag alone, since lag only reveals this after the sealing margin has already been eaten.
- Check the horizon before replaying anything. The unique index lives on a daily-partitioned table and therefore includes the partition key, so it deduplicates within a day only; a replay landing on a later ingest day needs the separate dedup store or it double-counts into a tenant's bill.
Follow-up
- Move the acknowledgement before the commit and describe exactly what is lost and what is duplicated in each of the two crash windows.
- Sealing is in six hours and the partition will not drain in time. What do you seal on, and what does the invoice have to record so the difference is explainable later?
- A producer replays two weeks of events next month. Which part of your fix stops holding, and what is the dedup horizon you would actually configure?
Day one measures instead of guessing, under a fixed rubric, and the remaining hours are allocated in proportion to the gaps before any studying begins. The allocation is deliberately not renegotiated midweek, because the area that feels worst on day three is usually the one that is moving.
Prepare, practise & reflect
One practical outcome each day. Spend longer where you need it.
0 / 7 done01Resume defence and screen preparation
- Pick your two strongest resume projects and write, for each, an end-to-end architecture walkthrough, your own contribution, one trade-off with the option you rejected, and one hard bug with how you found it
- Go through every language, tool and hardware concept on your resume and mark any you could not answer two follow-up questions on; fix or remove them
- Write your screen notes: constraints, timeline, and the questions to ask the recruiter about which team the role is in and what the technical assessment format is
Deliverable: Two project walkthroughs you can deliver without notes, and a cleaned-up resume with no undefended keywords.
Practice prompt ↗Practice prompt ↗Practice prompt ↗Worked solution ↗02Low-level C/C++ and memory
- Explain out loud how virtual functions and vtables work and what dynamic dispatch costs, then stack versus heap allocation and how leaks happen in C
- Write, by hand, in-place linked list reversal and Floyd cycle detection with O(1) extra space, and trace them on empty, single-node and cyclic lists
- Write set-bit counting for a 32-bit integer two ways (shift-and-mask, and n & (n - 1)) and say how many loop iterations each takes
- Outline how you would debug a segfault or memory corruption in a C driver with no standard debugger
Deliverable: Hand-written, hand-traced solutions for list reversal, cycle detection and bit counting, plus a written debugging method for a driver crash.
Practice prompt ↗Practice prompt ↗Practice prompt ↗03Data structures and algorithms, timed and without autocomplete
- Implement an LRU cache with a hash map and a doubly linked list with O(1) get and put, and check that eviction removes the tail node from both structures
- Solve a grid minimum-path-cost DP, state the recurrence and base cases, then reduce memory to a single row
- Solve a bipartite check with BFS two-colouring, stating complexity before you code
- Find the kth largest distinct value with a bounded min-heap of size k (O(n log k)), then find the largest k elements with quickselect partitioning (O(n) average, O(n^2) worst case) and say when you would pick each
Deliverable: Four solutions written in a plain editor, each with its complexity stated and an edge-case trace.
Practice prompt ↗Practice prompt ↗Practice prompt ↗04Computer architecture and system fundamentals
- Explain how pointer chasing affects cache use and pipeline throughput, and how you would change the data layout to fix it
- Explain DMA and how asynchronous transfers are coordinated with the CPU, then what happens at the hardware and kernel level when a peripheral raises an IRQ
- Compare a CPU core with a GPU compute unit, and link that to memory coalescing on GPUs versus cache-line prefetching on CPUs
- Explain cache coherence and cache line bouncing, process versus thread, and virtual-to-physical address translation, using a diagram for each
Deliverable: One-page notes per topic, each ending with a concrete code change the concept would lead you to make.
Practice prompt ↗Practice prompt ↗Worked solution ↗05Debugging without a compiler and concurrency
- Find and fix a C snippet with memory alignment issues by reading alone, stating each hypothesis before you change the code
- Implement a thread-safe circular queue in C++ without standard containers, and explain which race each lock or atomic closes
- Take a snippet that corrupts memory during concurrent array updates, trace the interleaving that breaks it, and fix it
Deliverable: Annotated fixes that name each bug, the input or interleaving that triggers it, and why the fix holds.
Practice prompt ↗Practice prompt ↗06Team specialism: hardware-adjacent or GPU and performance
- For hardware-adjacent teams: write a synchronous D flip-flop and a divide-by-3 clock divider with a 50% duty cycle in Verilog, and explain blocking versus non-blocking assignments
- For hardware-adjacent teams: work out an async FIFO depth from burst size and the write and read clock rates, and explain setup and hold violations
- For GPU or performance teams: study cache conflicts, GPU register spills, the roofline model and the memory access patterns of a GPU matrix transpose, and prepare an example of using performance counters
- For every team: write a Python script that parses a build log, pulls out error codes and prints a summary
Deliverable: Your team's specialism set completed, plus a working log-parsing script.
Practice prompt ↗Practice prompt ↗07Mock loop and behavioural stories
- Run back-to-back mocks on three kinds of question: a coding problem from days 2-3, an architecture question from day 4, and a project walkthrough with detailed follow-up questions
- Prepare behavioural stories: a complex bug and your step-by-step debugging method, a technical disagreement with a teammate or senior architect, and optimising a legacy codebase when profiling shows bottlenecks in several subsystems
- Practise asking clarifying questions and stating assumptions when you get stuck, and practise taking a hint from the mock interviewer
Deliverable: Mock feedback notes plus three behavioural stories, each covering what you did, what you decided and the result.
Practice prompt ↗Practice prompt ↗Worked solution ↗Expand any day for tasks and deliverables. Your progress is saved on this device.
The behavioural questions reported for this role are mostly about technical depth: how you debug, how you handle design disagreements, and whether you can explain your own projects in detail. Prepare stories with real technical content (the bug, the measurement, the trade-off) and be clear about which decisions you made yourself.
Walk me through the architecture of a major software project listed on…
Walk me through the architecture of a major software project listed on your resume from end to end.
Approach
- Name the disagreement and how you resolved it with evidence.
- 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 did you decide not to do, and why?
- How did you know your change caused the improvement?
Estimate a tenant-leading index migration you have never run
Someone needs a date. usage_event carries an index on (occurred_at) and needs (tenant_id, occurred_at); the largest tenant holds roughly a hundred times the median tenant's rows, the table is partitioned daily with years of retention, and you have never run a migration on a table this large. Give an estimate you would defend: how you decompose the work, the two or three numbers you would go and measure first, the range and confidence you state, and what you commit to when the person asking needs a single date today.
Approach
- Refuse the bare number and then give one anyway, in the form that is actually useful: a range plus the measurement that collapses it. 'Four to eleven days; one afternoon building this index on a restored copy of the largest partition takes that to within a day' is an answer, while 'it depends' is not.
- Decompose by failure mode rather than into equal chunks, because that is where estimates go wrong. On a partitioned parent you create the index ON ONLY the parent, build each partition's index with CREATE INDEX CONCURRENTLY, then ALTER INDEX ... ATTACH PARTITION, at which point the parent index becomes valid. CONCURRENTLY does not block writes but scans each partition twice, waits out older transactions, cannot run inside a transaction block, and on failure leaves an invalid index you must drop concurrently and retry.
- Name the two unknowns that dominate and price them: build time on one restored partition of realistic size, and whether the planner actually chooses the new index for the skewed tenant, since selectivity for a tenant holding most of the rows is a different question from selectivity for the median tenant. Both are half-day measurements against a replica, and both are cheaper than being wrong by a week.
- State the assumptions the range is conditional on, because that is what makes a slip a re-estimate instead of a credibility event: no partition above a stated row count, one concurrent build at a time so it does not compete with ingest for I/O, and an ingest backlog that can absorb the added write amplification while both indexes exist.
- Budget the step nobody budgets: verification and the old index's removal. Dropping the old index is fast, but deciding it is safe to drop means confirming no plan still uses it, and that confirmation waits on real traffic across a full weekly cycle rather than on your patience.
- Answer the single-date request honestly. Commit to a date for the first checkpoint — the measured build number from the replica — and to re-estimating on that date, and say plainly what you are not committing to yet. A date with a scheduled re-estimate is worth more to the asker than a confident wrong one, and you should say why in those words.
Follow-up
- The concurrent build fails half way through the largest partition. What is the state of the database and what do you do next?
- Your estimate slips by sixty percent. Which assumption broke, and at what point would you have known?
- The person asking needs the date for a customer commitment. Does your answer change?
Argue against failing open when the control plane is unreachable
The gateway caches credential-to-context decisions with a sixty-second TTL. A design proposal says that when control-plane reads fail, pods should keep serving from expired entries indefinitely so a control-plane outage never becomes a product outage. You believe that converts every revocation into an unbounded one. Describe a design you argued against while it was still a live proposal: what you measured or modelled to make the case, what you conceded, who decided, and what happened afterwards. Say what would have changed your mind before the decision, not after it.
Approach
- Reframe it from a values argument into a bounded-staleness argument. Both sides already accept the cache; the disagreement is only about the ceiling on how long a revoked credential keeps authorising. Put a number on the table — serve stale for up to fifteen minutes, then fail closed — and make the other side argue against a number rather than against a principle.
- Bring arithmetic rather than adjectives: the rate of revocations with revoked_reason in ('suspected_leak','auth_version_bump'), the observed distribution of control-plane unavailability, and the product of the two, which is expected requests served by revoked credentials per outage-hour. At 30k requests/second the unbounded version is not a subtle exposure and the number says so.
- Concede the strong half of the opposing case first, because that is what buys you the room: failing closed turns one service's outage into a total outage across three regions, and a control plane doing tens of writes per second is not engineered to the gateway's availability target. A proposal you have not steelmanned reads as reflex.
- Propose the asymmetry that usually resolves this: stale entitlements cost bounded money (a quota fifteen minutes out of date over-serves by a computable amount), while a stale revocation costs unbounded access. Split the cached decision by what it authorises, give the two halves different staleness ceilings, and let the entitlement half fail open while the revocation half fails closed.
- State the propagation dependency plainly, since it is the part that is missed: validity is also derived from the principal's auth_version, so password reset and sign-out-everywhere flow through this same cache. A design that bounds staleness for explicit revocation and not for auth_version bumps has only fixed half of it.
- Say who decided, and what you did afterwards in either outcome: write the decision down with its number and a review date, and instrument the exposure you were worried about so the next round of the argument is settled by data instead of by seniority.
Follow-up
- Publish-subscribe invalidation is lossy under a partition, and a TTL is the only hard bound. What TTL do you pick, and what does it cost you at 30k requests/second?
- The key was revoked because it was found in a public repository. Does your answer change, and where does that urgency live in the design?
- You lost the argument and six weeks later the failure you predicted happens. What do you say in the review, and what do you not say?
- 01
Describe a complex technical bug you encountered in a previous project and step through your exact debugging methodology.
- 02
Tell me about a time you had a technical disagreement with a teammate or senior architect regarding design choices.
- 03
How do you approach optimizing a legacy codebase when profiling metrics show bottlenecks across multiple subsystems?
- 04
Walk me through the architecture of a major software project listed on your resume from end to end.
- 05
Describe your experience with performance counters and what they told you about a system.
- 06
Explain how you learn new technical topics.
Is this an official AMD interview guide?
No. It is PracHub's own research and practice material for the Software Engineer role at AMD. Rounds and questions reflect what candidates have reported, not a process AMD has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How difficult are coding questions in AMD software engineer interviews?
Reported coding questions range from LeetCode Easy to Medium. The emphasis falls on low-level memory handling, pointer manipulation, bitwise operations and practical C/C++ rather than abstract puzzles alone. Reported examples include an LRU cache built from a hash map and a doubly linked list, reversing a linked list and detecting cycles without extra memory, and counting set bits in a 32-bit integer.
PracHub interview research ↗Do I need extensive GPU programming experience to apply for software roles at AMD?
Not for every role. For GPU compute or graphics driver roles (including ROCm), CUDA, HIP or graphics API experience is the relevant background to prepare. Many other teams work on CPU compilers, Linux kernel drivers, cloud platform integration, embedded firmware or digital logic verification, and for those, prepare C/C++ and systems knowledge first. Ask your recruiter which group the role sits in.
PracHub interview research ↗How long does the AMD interview process take from start to finish?
Reports differ. The round summary for this guide lists roughly 3-5 weeks, and other candidate notes say two to four weeks. Candidates also report that timelines vary by team, so the gaps between stages may differ. Ask your recruiter for the expected schedule, and raise any competing deadline early.
PracHub interview research ↗Are interview rounds at AMD conducted virtually or in person?
Candidates report that most technical interviews are held virtually over Microsoft Teams. Some university recruiting drives and hardware-focused engineering hubs such as Austin, Markham or Bengaluru may invite candidates for in-person panels. Confirm the format with your recruiter.
PracHub interview research ↗What should I prepare if the team is close to hardware design or verification?
Reported questions for hardware-adjacent teams include writing a synchronous D flip-flop in Verilog and explaining blocking versus non-blocking assignments, a divide-by-2 and divide-by-3 clock divider with a 50% duty cycle, async FIFO depth for clock-domain crossing, HVT versus LVT cell trade-offs, and a Python script that parses build logs. Review setup and hold time basics too, plus whatever Python, TCL or Bash automation you have done.
PracHub Software Engineer practice ↗What is the most effective way to prepare?
Get comfortable with C/C++ memory management, pointers and bit manipulation without IDE help. Review computer architecture: cache behaviour, memory hierarchy, interrupts and concurrency. Prepare a detailed technical walkthrough for every project on your resume. Then add the specialism of your target team, whether GPU, compiler, firmware or hardware verification.
PracHub Software Engineer practice ↗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