cswork / libraryOpen practice workspace

Interview guides · Omnissa

Omnissa Software Engineer Interview Guide

Omnissa Software Engineer interview guide: six reported stages, coding, OOP, design and security questions, and a 7-day prep plan tied to each round.

Interviewing at Omnissa

  • Practice bank: 9+ questions
  • Rounds: 1
  • Typical prep: 1–2 weeks
  • Interview reports: 1

Interview rounds

RoundQuestions
Onsite9

How hard is the Omnissa Software Engineer interview?

DifficultyShareQuestions
Easy0%0
Medium100%9
Hard0%0

What Omnissa actually tests for

TopicShareQuestions
Coding & Algorithms56%5
Behavioral & Leadership22%2
System Design22%2

The 60-second brief

The same notes mention desktop virtualization layers, authentication workflows and customer escalations as areas engineers work in, alongside product management, platform engineering and QA. Read those as the likely themes for technical and project questions, and confirm your target team's stack with your recruiter.

Omnissa candidates report 6 rounds · ≈ 4-6 weeks. The stages below are what candidates describe, not a published process.

What a Software Engineer does at Omnissa

The same notes list the problems engineers deal with: performance-sensitive desktop virtualization layers, secure authentication workflows, and customer escalations, often where older systems meet newer cloud services. For interview preparation this points to two things. You need to reason about how a system behaves end to end, not only produce a correct function. And you need to be able to explain the security mechanics of work you have shipped, such as token validation or encryption choices, in detail.

The reported questions reflect that mix. Candidates describe standard coding problems (valid parentheses, 3-sum, a running median over a stream), a news-feed subscription problem to be solved without LINQ or built-in sorting, OOP and Docker image-layer fundamentals, a system design walkthrough, and project deep-dives covering JWTs, WS-Federation and encryption. Plan your preparation around those categories rather than around a single interview format.

The Omnissa interview process

Omnissa candidates report 6 rounds · ≈ 4-6 weeks. The stages below are what candidates describe, not a published process.

Resume Shortlisting

Candidates report that the process starts with resume-based shortlisting. Nothing is asked of you live at this stage, but the resume you submit becomes the script for the later project discussions, which the source notes describe as detailed deep-dives with lead and staff engineers. Any line you cannot defend under repeated follow-up questions is a liability. Edit the resume with that later conversation in mind: every project bullet should name your own contribution, the technology involved and a result you can explain.

What it evaluates

  • Whether your resume shows work in the languages the source notes name for this role (C#/.NET, C/C++) or clearly transferable systems and backend experience
  • Whether each project bullet states your own contribution specifically enough to support a detailed conversation later
  • Whether security, authentication or infrastructure work you have done (tokens, federation, encryption, containers) is visible, since those topics recur in reported questions

How to prepare

  • Rewrite each project bullet as action, technology and outcome, and remove any claim you could not explain three levels deep
  • Mark the bullets that involve authentication, encryption, Docker or performance work, because those are the ones most likely to draw follow-up questions
  • Ask the recruiter which team and language stack the role uses so you can weight later preparation toward C#/.NET or C/C++

Online Assessment

The source notes describe an online assessment of core coding ability and system logic. One reported item is a medium-difficulty LeetCode-style problem under a time limit, and the notes mention HackerRank for early assessments. Treat it as an unassisted timed environment. Read the constraints before choosing an approach, write your own edge-case tests instead of relying on the visible samples, and submit a correct solution before trying to optimise it.

What it evaluates

  • Whether you produce a correct, complete solution to a medium problem within the time limit
  • Whether your code handles edge cases the sample tests do not cover: empty input, a single element, duplicates, extreme values
  • Whether your chosen complexity fits the stated input bounds

How to prepare

  • Solve timed problems in a HackerRank-style editor with autocomplete off, starting with valid parentheses, 3-sum and first unique character index, then bank problems such as maximum subarray sum and repeatedly removing adjacent equal characters
  • Before coding each problem, write a one-line note naming the target complexity and the input bound that justifies it
  • Keep a short list of edge cases you missed in practice and check against it before every submission

Technical Rounds

Candidates report one or more technical rounds held virtually or on live coding platforms. The reported question list includes fundamentals that could come up in any technical conversation: OOP concepts, abstract classes versus interfaces, the purpose of Docker image layers, preventing SQL injection, and normalization, indexing and denormalization. Prepare each as a short explanation followed by a concrete example or code, because a textbook definition gives the interviewer nothing to follow up on.

What it evaluates

  • Whether you can explain a fundamental such as encapsulation, polymorphism or interface design and then apply it in code
  • Whether you connect a concept to its practical effect, for example how Dockerfile instruction order affects layer caching and rebuild time
  • Whether you reason about trade-offs, such as when an abstract class suits better than an interface, or when to denormalize for read performance
  • Whether you think and explain aloud while working in a shared environment

How to prepare

  • For each OOP pillar, prepare one short C# or C++ snippet from your own experience that shows it, plus one case where misusing it caused a problem
  • Explain Docker layers from memory: each filesystem-changing instruction (RUN, COPY, ADD) adds a read-only layer, while ENV, CMD, LABEL and similar only add metadata; layers are cached and shared between images, and a container adds a writable layer on top, so putting rarely changing steps first speeds up rebuilds
  • Explain SQL injection defence at both layers (parameterized queries, least-privilege database accounts, input validation) and practise the concurrency drill on the page (drill-sql-1) to rehearse database reasoning out loud

Algorithmic Problem-Solving

The source notes describe live algorithmic problem-solving together with system design discussion. Reported coding problems include valid parentheses, 3-sum, a running median after each insertion, and a news-feed system with subscribe and unsubscribe that must be built without LINQ or built-in sorting. That last constraint matters: if you rely on library shortcuts, practise building the underlying structures yourself. Reported design prompts ask you to walk through component interactions and data flow.

What it evaluates

  • Whether you choose a data structure from the operations the problem needs, for example two heaps for a running median, giving O(log n) insertion and O(1) median reads
  • Whether you can still solve the problem when standard utilities are ruled out, by writing your own ordering or merge logic
  • Whether your design walkthrough names components, the data flow between them and the read and write paths separately
  • Whether you state complexity and edge cases before being asked

How to prepare

  • Implement a min-heap and max-heap pair, a merge of k sorted lists and a simple insertion into an ordered structure in C# or your main language without LINQ or built-in sort calls
  • Solve the news-feed subscription problem end to end: subscription storage, feed assembly by merging per-source lists, and the cost of subscribe, unsubscribe and read
  • Practise one design prompt from the bank, such as a multi-channel notification system or a cloud file storage and sync service, stating data model, APIs and data flow in that order

Project Discussions

The source notes describe deep-dive conversations with lead and staff engineers about your past projects and domain expertise, and say these can go into fine detail on resume projects. Reported questions include walking through a recent project, explaining encryption practices, JWTs and WS-Federation in a past project, the business reason behind a complex feature, and how you would modify and scale a resume project in future. Prepare at least one project deeply enough to take repeated follow-up questions on it.

What it evaluates

  • Whether you can explain the architecture of a project you built and your specific part in it, separate from the team's
  • Whether your security explanations are mechanically correct: what a JWT's signature proves, which claims are validated, how a federated sign-in hands a token to the relying application
  • Whether you can say why a feature existed and what problem or business driver justified it
  • Whether you can propose credible future changes and scaling steps, with their costs

How to prepare

  • Choose two or three projects and write one page each covering the problem, architecture, your decisions, the alternatives you rejected, what broke and what you would change
  • For any authentication work, practise the full flow aloud: token issuance, signature and expiry validation, audience and issuer checks, refresh and revocation, and where WS-Federation's redirect to an identity provider fits
  • For each project, prepare one scaling or extension plan that names the first bottleneck, the change you would make and what it would cost

Managerial/HR Round

The source notes describe the final stage as a managerial or HR round covering cultural alignment, communication skills and long-term career direction. Bank questions for this role include prioritising two important tasks with competing deadlines, resolving a conflict between senior engineers, presenting a project's architecture and your hardest technical decision, and discussing strengths and weaknesses. Prepare a small set of stories you know thoroughly rather than a scripted answer for every possible prompt.

What it evaluates

  • Whether you can explain technical work clearly to a listener who may not share your context
  • Whether your stories show how you handled competing priorities, disagreement and your own mistakes
  • Whether your stated career direction fits the kind of work the role involves

How to prepare

  • Prepare four stories (a competing-deadline trade-off, a technical disagreement, a mistake you owned, your hardest technical decision) and map each common prompt to one of them
  • Give a strengths-and-weaknesses answer where the weakness is real and comes with a concrete step you are taking
  • Write two sentences on where you want your career to go and why this role's work, such as systems, security or platform engineering, is part of that path

Questions Omnissa candidates report

Data structures and algorithms

Every fast solution here throws work away, and the claim you have to defend is that the discarded work could not have held the answer. A two-pointer walk over sorted values advances the left index only because every remaining pair using that element is also too small. A monotonic deque drops an element because a larger one sits to its right and will stay in the window longer. Say that sentence out loud. A weak answer names the technique and shows it passing the given examples, which is indistinguishable from a wrong technique that happens to pass the given examples.

  • Solve the 3-sum problem efficiently.
  • Design a news feed system where users can subscribe and unsubscribe without using LINQ or sorting.
  • Find the median of a stream of numbers coming in, calculating the median after each insertion.
  • Write a function to determine if a string has valid parentheses.

System design and architecture

At any point in a design you should be able to name the one resource that gives out first and what it costs to move it. Most follow-ups push on exactly that: traffic rises tenfold, a region is lost, a stricter consistency requirement appears. Answers hold up when the assumptions were said out loud early, because the design can then be re-derived from them rather than defended. The weak move under pressure is to add a component. The strong one is to say which part absorbs the change, which part has to be rebuilt, and roughly what the rebuild costs.

  • Walk through a system design problem, detailing component interactions and data flow.
  • Explain and apply various concepts in object-oriented programming (OOPs).

Behavioural and engineering judgement

Every question in this category has a number in it somewhere, and engineers routinely tell the story without one. What the outage cost, what the delay cost, what the rewrite consumed in engineer-weeks against what it saved, and who absorbed it when it was not users: the on-call rotation, another team's quarter, the support queue. You will rarely have an exact figure, and an estimate with its method stated beats both a precise-sounding invention and silence. Say how you got to it and what it leaves out. That is the sentence that makes the follow-up about whether it was worth doing answerable at all.

  • Tell me about a project you worked on in recent memory at your previous job.

Other topics

A large share of these are really questions about evidence: why something is slow, or how much of something you would need. Convert the prompt into a number or an observation. For diagnosis, name the measurement that would tell two candidate explanations apart and say what each predicts before you collect it. For sizing, carry the units through and stop at one significant figure. Listing everything that could plausibly be true is what the weak version looks like. What separates the strong one is a hypothesis, the observation that would falsify it, and what the arithmetic already rules out before any new data arrives.

  • Discuss a project on your resume and explain its future modifications and out-of-the-box scaling strategies.

Practice exercises with worked solutions

The prompts above tell you what gets asked.

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.

How a strong candidate works it

  • 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(*) ...) < 20 narrows 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 running updates 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 against status = 'running' and leased_until < now(), and treat the counter as a fast path over job_run, which stays the system of record.

Follow-ups

  • 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?

Migrate a live partitioned event table without blocking ingest

usage_event is range-partitioned daily on ingested_at, holds roughly 250M rows per day across 400 live partitions, and is written at 10-40k rows/second. Two changes are required: quantity must move from double precision to numeric(20,6), and a new environment column must become NOT NULL with a default of 'production'. Ingest cannot stop. Give the ordered plan, naming for each step the lock it takes, what that lock blocks, and roughly how long it is held. Identify the one step that cannot be rolled back cleanly once traffic depends on it.

How a strong candidate works it

  • Classify the two changes before planning anything. Adding a column with a non-volatile default has been metadata-only since PostgreSQL 11, so it is cheap. Changing double precision to numeric is not binary-coercible, so alter column ... type rewrites every partition under ACCESS EXCLUSIVE and rebuilds its indexes; on this volume that is hours of blocked ingest and is simply not an option, which is why the plan is expand-and-contract rather than one statement.
  • Expand: add quantity_numeric numeric(20,6) and environment with its default on the parent. Both are catalogue-only but both take a brief ACCESS EXCLUSIVE that cascades to partitions, so run each with lock_timeout set to a second or two and retry on failure. A queued ACCESS EXCLUSIVE request blocks every reader behind it, which is how a metadata-only change turns into an outage.
  • Dual-write: deploy producer code that populates both columns on every insert, and leave it running before anything reads the new column. This is the step that cannot be reverted cleanly. Once readers depend on quantity_numeric, reverting the writer leaves rows with a null there, and the gap is only discoverable by re-reading the old column, which the readers have stopped doing.
  • Backfill older partitions in batches keyed on the primary key, oldest first, committing every few thousand rows with a pause between batches, and skipping the partition still receiving writes until it rotates. Each batch is an ordinary UPDATE taking row locks only. The cost is bloat and WAL rather than blocking, so watch dead tuples and let autovacuum keep pace instead of wrapping 400 partitions in one transaction.
  • Make NOT NULL cheap with the three-step form: add constraint ... check (environment is not null) not valid (brief ACCESS EXCLUSIVE, no scan), then validate constraint (SHARE UPDATE EXCLUSIVE, scans while reads and writes continue), then set not null, which from PostgreSQL 12 uses the validated check and skips its own full scan. Do this per partition, then on the parent.
  • Switch and contract: move reads to the new column behind a flag, verify over a full period that both columns agree on freshly written rows, drop the old column (metadata-only), and only then remove the dual-write. Any index on the new column goes on with CREATE INDEX CONCURRENTLY per partition, since CIC is not supported on a partitioned parent: create the parent index with ONLY, build each child concurrently, then ALTER INDEX ... ATTACH PARTITION until the parent index becomes valid.

Expected result (45 min): An ordered expand, dual-write, backfill, switch, contract plan with the lock named per step: metadata-only ADD COLUMN under a brief ACCESS EXCLUSIVE taken with lock_timeout; batched UPDATE backfill under row locks; CHECK NOT VALID, then VALIDATE under SHARE UPDATE EXCLUSIVE, then SET NOT NULL; CREATE INDEX CONCURRENTLY per partition with ATTACH PARTITION; and the dual-write-to-read switch identified as the step that cannot be reverted cleanly.

Check yourself

  • No step in the plan holds ACCESS EXCLUSIVE for longer than the configured lock_timeout.
  • The writer's error rate stays at zero through the rehearsal apart from the deliberate lock timeout.
  • After VALIDATE, SET NOT NULL completes in milliseconds on a table where the naive form scanned every row.
  • Freshly written rows agree on both columns for a full verification period before the old column is dropped.

Follow-ups

  • A CREATE INDEX CONCURRENTLY fails halfway through the partition list. What state is the table in, how do you detect it, and what do you run?
  • The producer computes quantity itself. What happens to a request already in flight when the dual-write deploy lands, and does it matter?
  • Give two queries that prove the backfill is complete: one cheap enough to run every minute, one authoritative.

Seal an hour under late data with bounded memory

Metering ingest reads 256 partitions at 10,000 to 40,000 events/second. Events carry occurred_at and ingested_at, and during a producer replay the gap between them is hours. Seal each UTC hour once no more than 50 parts per million of that hour's eventual quantity can still arrive, using memory that does not grow with the size of the replay. Define the watermark, the lateness parameter and how you measure it, the structure holding open hours, and the write that performs the seal. State what an idle partition does to your watermark.

How a strong candidate works it

  • Two clocks, two jobs. Bucket by occurred_at, because that is the hour the customer is billed for, and advance the watermark on ingested_at, because that is what the fold has consumed and what source_max_ingested_at records. Conflating them is what makes late data invisible.
  • The global watermark is the min over partitions of each partition's committed ingested_at, not the max: the fold is trustworthy only as far as the slowest partition. The consequence is that one idle partition pins the watermark forever and nothing seals, so an idle partition must promote its watermark to wall clock after a stated idle timeout, and that timeout becomes a correctness parameter, because a partition that is slow rather than idle gets sealed past.
  • Choose the lateness L from the measured distribution of ingested_at - occurred_at, weighted by quantity rather than by event count. The target is 50 ppm of the hour's quantity, and a replay is rare in events while carrying disproportionate mass, so an event-weighted quantile picks an L that is comfortably wrong at exactly the moment it matters.
  • Measure that quantile in bounded memory. A Greenwald-Khanna summary gives epsilon-approximate quantiles in O((1/epsilon) log(epsilon n)) space; a t-digest costs more per merge but has relative error that tightens at the tails, which is the half of the distribution you are reading at p99.99. Keep a separate summary per tenant class, because one tenant's batch importer is not the population.
  • Hold open hours in a min-heap keyed by hour_start. When the watermark advances, pop every hour with hour_end + L < W and seal it: O(log H_open) per advance and O(1) amortised per event to touch its bucket. Memory is open hours multiplied by distinct (tenant, workspace, sku) keys, so cap the number of simultaneously open hours and spill the oldest into usage_rollup_hourly as status='open' with a revision bump. While an hour is open the row is upsertable, so the store is your overflow.
  • The seal itself is a conditional write: update ... set status='sealed', sealed_at=now() where status='open' returning .... Two sealers race on every restart, and the loser must see zero rows and stop rather than write a second value. After the seal, an event for that hour is not an upsert but an adjustment, and source_max_ingested_at is what proves it arrived afterwards.

Expected result (40 min): The quantity-weighted p99.99 is hours larger than the event-weighted one. Choosing L from the event-weighted number lets roughly the tail's 3% of quantity land after the seal, 600 times the 50 ppm target. With the min watermark and no idle timeout, the stalled partition blocks all sealing; with a 60-second timeout, the stall is sealed past and its events arrive late.

Check yourself

  • Post-seal quantity as a fraction of the hour's total is at or below 50 ppm at the chosen L, measured rather than assumed.
  • The second sealer's update reports zero rows affected and writes nothing.
  • Heap size equals the number of open hours and does not grow with the replay's event count.

Follow-ups

  • A replay starts during the sealing window for a period you are about to close. What do you do, and what is the customer-visible consequence of each option?
  • Your measured quantity-weighted p99.99 lateness is six hours and the invoice must be issued at 02:00 UTC on the first. How do you reconcile those two numbers?
  • How would you detect that L has drifted before it costs you an hour's quantity?

Build a resumable usage export the customer can reconcile against

Customers reconcile invoices against usage_event (event_id uuid, tenant_id, workspace_id, environment, sku, quantity numeric(20,6), idempotency_key, occurred_at, ingested_at, source_service, request_id), partitioned daily on ingested_at. The current export is ?page=N&per_page=1000 ordered by occurred_at, and a customer syncing hourly reports rows that never appear in their export but do appear on their invoice. Design the replacement: the ordering, the cursor's contents, the index it requires, and the rule deciding where a page stops. State what the client does on a timeout and on a cursor older than retention.

How a strong candidate works it

  • Separate the two defects in the current shape. Offset makes the database produce and discard N * per_page rows, so page cost grows linearly and a deep page degrades from milliseconds to seconds. Concurrent inserts also shift the window between requests, so a walker skips rows with no error raised anywhere, which for a customer sync is silent data loss.
  • Order by ingestion, not by occurrence. During a replay events arrive hours out of occurred_at order, so a consumer holding an occurred_at high-water mark can never see a late event that falls below it; (ingested_at, event_id) is the only ordering under which 'everything after my cursor' is a complete statement.
  • Page with a row comparison: where tenant_id = $1 and (ingested_at, event_id) > ($2, $3) order by ingested_at, event_id limit $4, backed by an index on (tenant_id, ingested_at, event_id). That seeks directly to the resume point, so every page costs the same regardless of depth.
  • Trail the head of the table. With ingested_at defaulting to now(), which is transaction start time, a long insert transaction receives an earlier timestamp and becomes visible after a reader has already passed it. Cap each page at ingested_at <= now() - delta, with delta larger than the longest write transaction as bounded by statement_timeout and idle_in_transaction_session_timeout, or the export skips exactly the rows written under load.
  • Make the cursor opaque and self-describing: base64 of the timestamp, the event id and a fingerprint of the filters, rejected when the filters differ from the current request. Return 410 with a cursor_expired code once the cursor's partition has been dropped, so the client restarts from a known time instead of resuming into a hole.
  • Keep a page a pure GET with no server-side consumption, so a timeout is resolved by retrying the identical cursor.

Expected result (30 min): Keyset pagination over (ingested_at, event_id) with an index on (tenant_id, ingested_at, event_id), a trailing head predicate sized above the longest write transaction, an opaque filter-bound cursor, and 410 for a cursor past retention.

Check yourself

  • A late event with an old occurred_at is still delivered by the export.
  • Page cost is independent of how many pages have already been read.
  • The cursor persists across a client restart and survives retrying the same page.
  • The tie-break column is unique, so no row can be skipped or repeated at a page boundary.

Follow-ups

  • The customer asks for a total count alongside the first page. What do you offer instead, and why is an exact count both expensive here and wrong by the time it is read?
  • How would you let a customer re-read a window they have already consumed without giving up the forward-only cursor?

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.

How a strong candidate works it

  • 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-ups

  • 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?

Disclose a cross-tenant webhook delivery to affected customers

An enqueue path took the subscription from one lookup and the payload from another. For nineteen minutes, webhook_delivery rows were created whose tenant_id did not match the subscription's tenant, and eleven payloads were signed and sent to four endpoints belonging to other customers. You hold payload_digest, delivery timestamps and response codes. Describe how you handle a disclosure of this kind: what the records prove, what they cannot prove, what you say before you know everything, the one code change that closes it, and which parts you personally drove.

How a strong candidate works it

  • Bound the population before saying anything externally. The affected set is deliveries in the window where the event's tenant and the subscription's tenant differ; the ones that actually left are those with delivered_at set and a 2xx in last_response_code. Attempted and delivered are two different counts and a disclosure has to use the right one in the right sentence.
  • Separate what the records prove from what they do not, and say both halves rather than the flattering one. They prove which payloads were signed, where they went, and — through payload_digest — exactly which bytes. They do not prove what the receiving system did with them, and they do not bound the window more precisely than your deploy timestamps do.
  • Communicate on the facts you hold, with the scope stated as an upper bound: 'at most eleven payloads, four recipient endpoints, these fields, this window' is more useful and more honest than waiting a day for certainty. The field list matters more than the event count, because a customer cannot assess exposure from 'an event'.
  • Name the code change precisely, because this class never originates in the delivery worker. Compare the event's tenant against the subscription's tenant at enqueue and again immediately before the payload is signed, and make the second comparison drop the delivery rather than log a warning. Say why one check is insufficient: the enqueue check protects against the bug you know about, the pre-signing check protects the boundary itself.
  • Run the history question in parallel and say so: a query over historical deliveries for the same mismatch tells you whether this was nineteen minutes or a year, and you would rather find the second case yourself than have a customer find it after your disclosure.
  • Split the response into workstreams with owners — recipients asked to delete, affected customers notified, the check landed with a test, history swept — and say which you personally drove and which you handed off. Claiming all four is not credible and claiming none is not ownership.

Follow-ups

  • The historical sweep finds two more instances from last year. What changes in what you have already told people?
  • Who approves the wording, and what do you do when you are asked to soften the scope?
  • A customer asks you to prove a redelivery contained the same bytes as the original. What do you show them?

Unblock an engineer on a job run that finished twice

An engineer two weeks into the team brings you a job_run row showing status succeeded with an exit_code written by a worker declared dead ten minutes earlier; the retry attempt also shows succeeded. They have spent a day adding logging and are no closer. You have twenty minutes and you do not want to take the keyboard. Describe how you unblock someone: the question you ask first, what you let them find themselves, the concept you name and when, and how you check the next day that they own the fix rather than having watched you produce it.

How a strong candidate works it

  • Ask what they expect rather than what they see: which statement set status to succeeded, and what did it check before writing? That question points directly at the update's WHERE clause, which is where the answer lives, and it costs them nothing to answer, so it does not read as a test.
  • Let them build the timeline themselves from the row: queued_at, started_at, leased_until, finished_at and worker_id, on both the original run and the retry. Two different worker_ids with a lease expiry between them tells the whole story, and they will see it before you say it.
  • Name the concept once the evidence has earned it. A lease bounds time; it does not prevent a write. The store has to reject a stale writer, which means the update carries a fencing token the row compares — update job_run set status = 'succeeded' where run_id = $1 and lease_token = $2 and status = 'running' — and a long garbage-collection pause or a brief partition is enough to produce what they are looking at.
  • Point at the second, less obvious half and let them decide it: 'lost' exists in the status enum precisely so a run whose worker vanished is not recorded as failed, because failed asserts an outcome nobody observed and the system then bills and retries on that assertion. Ask them what these two rows should have said.
  • Leave them with the next step rather than the patch — a test that kills the first worker after the sandbox exits and before the row is written — and say when you are available again, so the offer is real rather than polite.
  • Check ownership the next day by what they produced, not by asking if it went well: a test that reproduces the window proves they understood it; a test that only asserts the new WHERE clause proves they copied it. Ask them to explain it to a third person and listen for whether the explanation is theirs.

Follow-ups

  • They propose a longer lease instead of a token. What do you say, and what breaks when legitimate runs last thirty minutes?
  • How can you tell whether your explanation landed or they simply deferred to you?
  • The same engineer hits a variant of this next month. What did you fail to teach the first time?

Where candidates lose points

Reaching for LINQ, built-in sort or other library shortcuts when the prompt rules them out

One reported problem asks for a news feed with subscribe and unsubscribe but no LINQ or sorting. Before the interview, build the underlying pieces by hand in your main language: a heap, a k-way merge of per-source lists, an insertion into an ordered list. Then state the cost of each operation. If a standard solution depends on sorting, as 3-sum usually does, say so and either write the sort yourself or explain a hash-based alternative and its trade-off.

Describing JWTs, WS-Federation or encryption in your own project only at the buzzword level

Reported project questions ask how these worked in work you did. Be ready to explain what a JWT signature protects and what it does not (the payload is readable), which claims you validated (expiry, issuer, audience), how keys were rotated, how the federated sign-in redirect returned a token to your application, and which algorithms you used for data at rest and in transit and why. If a teammate built part of it, say so rather than guessing.

Submitting the timed online assessment after passing only the visible sample tests

The reported assessment is a medium problem under a time limit. Check the input bounds first, then test empty, single-element, duplicate and extreme-value cases yourself before submitting. Practise in a plain editor without autocomplete so syntax lookups do not use up the clock.

Answering OOP and fundamentals questions with textbook definitions and no example

For abstract classes versus interfaces, OOP concepts and Docker image layers, follow each definition with a concrete case: a class hierarchy you designed, why you chose an interface there, or how you reordered a Dockerfile to improve layer caching. The example is what the next follow-up question builds on.

Offering generic scaling ideas when asked how a past project would change in future

When asked about future modifications or scaling for a resume project, name the component that would fail first under growth, the change you would make, and what that change costs in complexity, consistency or operations. Base it on the real numbers of that system, not on a generic answer of adding caching and sharding.

Weakness triage, driven by a day-one self-assessment

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.

Day 1 — Resume shortlisting and project inventory

  • Rewrite each resume project bullet as action, technology and outcome, and remove claims you cannot explain in depth
  • Choose the two or three projects you will use in project discussions and write one page each: problem, architecture, your decisions, rejected alternatives, what broke
  • Mark every place where authentication, encryption, Docker or performance work appears, since those topics recur in reported questions
  • Ask the recruiter which team and language stack (C#/.NET or C/C++) the role uses

Deliverable: An edited resume and one project page per chosen project.

Day 2 — Online assessment: timed problems

  • Solve problems in a HackerRank-style editor with autocomplete off: valid parentheses, 3-sum, first unique character index
  • Add bank problems under the same conditions: maximum contiguous subarray sum and repeatedly removing adjacent equal characters
  • Before coding each one, write the target complexity and the input bound that justifies it
  • After each submission, list the edge cases you missed

Deliverable: A personal edge-case checklist and a note of which problems went over time.

Day 3 — Algorithmic problem-solving without library shortcuts

  • Implement the running median with two heaps, building the heaps yourself, and state the insertion and read complexity
  • Build the news-feed subscription problem without LINQ or built-in sorting: subscription storage, a k-way merge for feed reads, and the cost of subscribe and unsubscribe
  • Solve bank problems that test structure choice: checking whether a singly linked list is a palindrome and finding the celebrity in a knows matrix
  • Solve the bank concurrency problem of alternating odd and even numbers with two threads, and explain the synchronisation you used

Deliverable: Working implementations of a heap, a k-way merge and the feed problem, each written without library sorting.

Day 4 — Technical rounds: OOP, containers and databases

  • Prepare examples for OOP concepts and for abstract classes versus interfaces, each with a snippet from your own work
  • Explain Docker image layers aloud: filesystem-changing instructions (RUN, COPY, ADD) create read-only cached layers while metadata instructions do not, layers are shared between images, the container adds a writable layer, and instruction order affects rebuilds
  • Cover SQL injection defence at the application and database layers, plus normalization, indexing and when to denormalize
  • Work through drill-sql-1 (concurrent quota) and review the worked SQL migration exercise to practise reasoning about locks and isolation out loud

Deliverable: A one-page fundamentals sheet with an example next to every definition.

Day 5 — System design walkthroughs

  • Design a multi-channel notification system from the bank: data model, subscription schema for fast reads and writes, delivery path, retries
  • Design a cloud file storage and sync service from the bank, naming the read and write paths separately
  • Work through the worked design exercise on resumable usage export to practise cursor pagination and API contracts
  • For each design, describe component interactions and data flow in order, as the reported design question asks

Deliverable: Two design sketches, each with a schema, API list and a named first bottleneck.

Day 6 — Project discussions: security and scaling depth

  • For each chosen project, practise explaining the authentication flow end to end: token issuance, signature and claim validation, expiry, refresh, and where a WS-Federation redirect fits if you used it
  • Prepare your answer on encryption at rest and in transit: algorithms chosen, key management, and why
  • For each project, prepare the future-modification and scaling answer: first bottleneck, change, cost
  • Have a peer ask why repeatedly on one project and note where your answer starts repeating itself

Deliverable: A security-flow explanation and a scaling plan for each chosen project, rehearsed aloud.

Day 7 — Managerial/HR round and a full mock

  • Prepare four stories: competing deadlines, a conflict between senior engineers, a mistake you owned, and your hardest technical decision
  • Prepare a strengths-and-weaknesses answer and two sentences on your career direction
  • Prepare an answer to the reported question about writing a prompt for an AI coding assistant such as Cursor to solve a DSA problem: state constraints, ask for complexity, and verify the output yourself
  • Run a mock covering one coding problem, one fundamentals question and one project deep-dive with follow-ups

Deliverable: A story index mapping common prompts to your four stories, plus notes from the mock.