Interview guides · Set of X
Set of X Software Engineer Interview Guide
Set of X Software Engineer interview guide: reported rounds, questions and how candidates describe the process.
The 60-second brief
At Set of X, the Software Engineer role is defined by a culture of ownership and high-impact engineering. You are not merely writing code to specification; you are an active participant in designing, integrating, and optimizing complex systems that directly support mission-critical government operations. Whether you are building CNO-focused analytical tools or developing high-performance Java applications, your work bridges the gap between raw data and actionable intelligence. This role is critical because Set of X operates at the intersection of advanced technology and national security. You will be expected to provide technical leadership, navigate complex data environments, and collaborate with stakeholders to solve unique problems that have real-world consequences.
This guide is scoped to a Software Engineer candidate at Set of X.
Focus areas
- Python
- Java
- Performance Optimization
The Set of X interview process
Set of X candidates report 3 rounds over 3-5 weeks. The stages below are what candidates describe, not a published process.
Technical Screening
Initial assessment of technical capabilities to ensure candidates can perform the job.
What to demonstrate
- Initial assessment of technical capabilities to ensure candidates can perform the job
- Depth in Python
How to prepare
- Answer aloud and timed: How do you manage memory and performance optimization in a high-throughput Java application?
- Answer aloud and timed: Can you describe a complex debugging scenario you encountered in Python and the steps you took to resolve it?
Deep-Dive Interviews
In-depth discussions with engineering leads and mission stakeholders to evaluate fit.
What to demonstrate
- In-depth discussions with engineering leads and mission stakeholders to evaluate fit
- Depth in Python
How to prepare
- Answer aloud and timed: What are the trade-offs when choosing between different data structures in Python for large-scale data processing?
- Answer aloud and timed: How do you ensure thread safety and concurrency in multi-threaded Java applications?
Cultural Fit Assessment
Conversations with potential peers to assess collaboration and problem-solving approach.
What to demonstrate
- Conversations with potential peers to assess collaboration and problem-solving approach
- Depth in Python
How to prepare
- Answer aloud and timed: Explain your approach to writing clean, maintainable, and testable code in a production environment.
- Answer aloud and timed: How do you design a system to handle data ingestion from multiple, disparate sources?
Where candidates lose points
Own your answers
When discussing past mistakes or technical hurdles, be direct and focus on what you learned and how you corrected the path.
Ask meaningful questions
Use your interview time to ask about the team’s current technical challenges and how they prioritize their roadmap.
Highlight your impact
Don't just list tasks; explain how your work improved performance, reliability, or mission outcomes.
Questions & practice
How do you ensure thread safety and concurrency in multi-threaded Java applications?
Medium · Java and Python Technical Proficiency
Approach
- Say what the runtime actually does before reasoning about the code.
- Name what is shared across threads and what owns each piece of state.
- Identify the window where an invariant is briefly untrue.
- Distinguish a value from a reference to it, and say which one you handed out.
Follow-up
- What happens if two callers reach this at the same time?
- Where could this allocate more than you expect?
Find overlapping job attempts and peak concurrency from lease records
Medium · sweep line · intervals · leases
A day of job_run history yields about 50,000,000 attempt records: (job_run_id, job_type, attempt, started_at, finished_at which is NULL when the worker died, lease_expires_at). Leases expire on a clock, so a job that outran its lease ran twice. Produce (a) every job_run_id whose attempts overlapped in wall-clock time and (b) the peak number of simultaneously running attempts per job_type with the minute it occurred. Target O(n log n). State how you treat a NULL finished_at and what clock skew does to your answer.
Approach
- Define the interval before sorting anything: an attempt occupies [started_at, COALESCE(finished_at, lease_expires_at)). finished_at is observed and lease_expires_at is only a promise, so every attempt without a finish contributes an estimate and the whole result is a lower bound on overlap rather than an exact count.
- For peak concurrency, sweep: emit 2n endpoints, sort by (timestamp, kind) with ends ordered before starts at equal timestamps, then walk the sequence maintaining a counter per job_type and record each type's maximum with its timestamp. O(n log n) dominated by the sort, O(n) space, or O(1) extra if the sort is external and the walk streams.
- For overlap detection, do not compare attempts pairwise. A single global sort by (job_run_id, started_at) gives both the grouping and the order; within a group, keep the maximum end seen so far and report an overlap exactly when the next start is less than that running maximum, which is one linear pass after the sort.
- Half-open intervals matter and are easy to get wrong: with closed intervals an attempt ending at the same millisecond another begins reads as concurrency two, and across 50,000,000 records that artefact swamps the real signal.
Follow-up
- A handler is not idempotent and you have found 400 overlapping jobs. Which of them actually caused damage, and what would you query to find out?
- Peak concurrency for one job_type is 4 against a configured cap of 4. Is the cap working, or is the data hiding attempts that never started?
Canonicalise a request body into a stable idempotency fingerprint
Medium · parsing · canonicalisation · hashing
idempotency_key.request_fingerprint is a SHA-256 over the method, path and canonicalised body, and a retry whose fingerprint differs must be rejected with 422 rather than served the stored response. Write the canonicaliser. Bodies are JSON up to 256 KB nested at most 32 levels; clients vary key order, whitespace and unicode escaping, and some send 64-bit ids as JSON numbers. Produce a deterministic byte string such that semantically identical bodies match and any semantic difference does not. State your complexity and name two normalisations you refuse to perform.
Approach
- Parse once into a tree, then re-serialise under fixed rules: object keys sorted, array order preserved, one escaping convention, no insignificant whitespace. Parsing is O(n) and sorting keys is O(k log k) per object, so O(n log n) overall with O(depth) stack, and the 32-level cap is enforced during parsing because hostile nesting is how a canonicaliser becomes a stack overflow.
- Sort keys by their UTF-8 bytes and say why the obvious implementation is wrong in some runtimes: a default string comparison that orders by UTF-16 code units places surrogate pairs, meaning code points from U+10000 up, below U+E000 to U+FFFF, which is not UTF-8 byte order, so two services written in different languages disagree on the same document.
- Do not re-encode numbers through a double. IEEE-754 binary64 represents integers exactly only up to 2^53, so normalising a 19-digit id through a float changes it, and 1 against 1.0 cannot be reconciled without deciding whether they are the same value. Preserve the literal token, and require ids as strings at the API boundary if you want them comparable.
- Reject duplicate keys rather than picking one. JSON permits them and parsers disagree, most keeping the last, so any choice you make ties the fingerprint to a parser detail that the code handling the request does not necessarily share.
Follow-up
- A client sends the same logical request with an extra field your API ignores. Same key, different fingerprint, so you return 422. Is that the right answer?
- Where does the fingerprint get computed relative to request decompression and the body-size limit?
How do you approach designing a database schema for complex, non-relational data types?
Medium · System Design and Integration
Approach
- Name the grain you start from and join outward from it.
- Check whether any join is one-to-many before aggregating, or the sums inflate.
- Say which index the query would use, and what makes it unusable.
- Handle the rows that do not match: that is usually the actual question.
Follow-up
- How does the query change if that join becomes one-to-many?
- What happens to this when the table is ten times larger?
Stop tag and share joins from fanning out a page
Medium · join fan-out · semi-joins · many-to-many
resource_tag is (resource_id, tag_id) with PK (resource_id, tag_id); resource_share is (resource_id, shared_with_user_id, permission). The tagged-and-shared listing inner-joins resource to both, filters tenant_id, tag_id = ANY($2) and shared_with_user_id = $3, orders by updated_at DESC and takes 50. Pages come back with fewer than 50 distinct resources and the total in the header is far too high. Explain the row multiplication, rewrite both the page query and the count query so each is correct, and name the index each one needs. PostgreSQL 16.
Approach
- Do the arithmetic against the predicates that are actually there. An inner join emits one row per matching child row, and both joins are filtered: tag_id = ANY($2) admits only the requested tags, shared_with_user_id = $3 admits one user's share rows. So a resource holding three of the requested tags and shared with $3 once yields three rows, not one — the multiplier is its count of matching tags times its share rows for that single user, and that second factor is 1 unless the table admits duplicate (resource_id, shared_with_user_id) pairs. LIMIT 50 then limits rows rather than resources, and COUNT(*) counts pairs — the header is the product, not the population.
- Reject DISTINCT as the fix. It deduplicates after the product has been built, so the planner must materialise and sort the fanned-out set before the LIMIT can apply, and it leaves any SUM or AVG in the same select list wrong.
- Rewrite both filters as semi-joins, keeping resource as the only row source: AND EXISTS (SELECT 1 FROM resource_tag rt WHERE rt.resource_id = r.resource_id AND rt.tag_id = ANY($2)) and the same shape against resource_share. A semi-join stops at the first match per resource and preserves the driving index order, so ORDER BY updated_at DESC, resource_id DESC LIMIT 50 still stops after 50 rows.
- Count with the same predicates and no join at all: SELECT count(*) FROM resource r WHERE r.tenant_id = $1 AND r.status = 'active' AND EXISTS (...) AND EXISTS (...). Nothing multiplies a resource, so the number is the population.
Follow-up
- The filter changes from 'any of these tags' to 'all of these tags'. Rewrite it and state what it costs relative to the ANY form.
- A resource can be shared with the same user twice under different permissions. Does your count change, and should it?
How do you manage memory and performance optimization in a high-throughput Java application?
Medium · Java and Python Technical Proficiency
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.
- State the consistency you need, and where you are willing to be stale.
Follow-up
- What breaks first when traffic grows ten times?
- How does this behave when that dependency is down for an hour?
What are the trade-offs when choosing between different data structures in Python for large-scale data process
Medium · Java and Python Technical Proficiency
What are the trade-offs when choosing between different data structures in Python for large-scale data processing?
Approach
- Clarify what is being asked and what a complete answer contains.
- State your assumptions explicitly before working the problem.
- Say what you would check first and why it is the highest-information step.
- Work from the requirement backwards to the design.
Follow-up
- What assumption would you test first?
- How would you know your answer was wrong?
Explain your approach to writing clean, maintainable, and testable code in a production environment.
Medium · Java and Python Technical Proficiency
Approach
- Clarify what is being asked and what a complete answer contains.
- State your assumptions explicitly before working the problem.
- Say what you would check first and why it is the highest-information step.
- Work from the requirement backwards to the design.
Follow-up
- What assumption would you test first?
- How would you know your answer was wrong?
How do you design a system to handle data ingestion from multiple, disparate sources?
Medium · System Design and Integration
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.
- State the consistency you need, and where you are willing to be stale.
Follow-up
- What breaks first when traffic grows ten times?
- How does this behave when that dependency is down for an hour?
What strategies do you use to ensure software reliability when working with distributed systems?
Medium · System Design and Integration
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.
- State the consistency you need, and where you are willing to be stale.
Follow-up
- What breaks first when traffic grows ten times?
- How does this behave when that dependency is down for an hour?
Can you describe a complex debugging scenario you encountered in Python and the steps you took to resolve it?
Medium · Java and Python Technical Proficiency
Approach
- Establish what changed and when, before forming any theory.
- Pick a bisection that eliminates candidates whichever way it turns out.
- Check the instrumentation before believing the symptom.
- Separate the trigger from the cause; the deploy is rarely the bug.
Follow-up
- What would you look at first, and what would it rule out?
- How would you tell a cause from a coincidence here?
Suggested practice checklist
Built from the rounds and topics Set of X candidates report.
Day 1 — Map the Set of X loop
- Write out the reported sequence: Technical Screening, Deep-Dive Interviews, Cultural Fit Assessment.
- For each round, write one sentence on what it is judging, from the description above, and mark the one you are least ready for.
Deliverable: A one-page map of the 3 reported rounds, with the weakest marked.
Day 2 — Work Python
- Spend the session on Python, which Set of X candidates report being tested on.
- Write one worked example in Python and time yourself on it.
Deliverable: One timed worked example in Python.
Day 3 — Work Java
- Spend the session on Java, which Set of X candidates report being tested on.
- Write one worked example in Java and time yourself on it.
Deliverable: One timed worked example in Java.
Day 4 — Work Performance Optimization
- Spend the session on Performance Optimization, which Set of X candidates report being tested on.
- Write one worked example in Performance Optimization and time yourself on it.
Deliverable: One timed worked example in Performance Optimization.
Day 5 — Answer out loud: Java and Python Technical Proficiency
- Answer aloud, timed: How do you manage memory and performance optimization in a high-throughput Java application?
- Answer aloud, timed: Can you describe a complex debugging scenario you encountered in Python and the steps you took to resolve it?
Deliverable: Spoken answers to 2 reported Java and Python Technical Proficiency question(s), under time.
Day 6 — Answer out loud: System Design and Integration
- Answer aloud, timed: How do you design a system to handle data ingestion from multiple, disparate sources?
- Answer aloud, timed: Describe a time you had to integrate a new software module into a legacy system. What were the biggest challenges?
Deliverable: Spoken answers to 2 reported System Design and Integration question(s), under time.
Day 7 — Answer out loud: Behavioral and Stakeholder Management
- Answer aloud, timed: Tell me about a time you had to elicit requirements from a stakeholder who was unsure of what they needed.
- Answer aloud, timed: How do you handle technical disagreements within a team?
Deliverable: Spoken answers to 2 reported Behavioral and Stakeholder Management question(s), under time.
Behavioural preparation
Behavioural rounds judge the decision you made and what it cost.
Describe a time you had to integrate a new software module into a legacy system. What were the biggest challen
Medium · System Design and Integration
Describe a time you had to integrate a new software module into a legacy system. What were the biggest challenges?
Approach
- Pick a story where you made the decision, not one where you watched it.
- State the situation in two sentences and spend the rest on the reasoning.
- Give the blast radius: what could have broken, and what you measured.
- Name the disagreement and how you resolved it with evidence.
Follow-up
- What would you do differently if you ran that again?
- How did you know your change caused the improvement?
Tell me about a time you had to elicit requirements from a stakeholder who was unsure of what they needed.
Medium · Behavioral and Stakeholder Management
Approach
- Pick a story where you made the decision, not one where you watched it.
- State the situation in two sentences and spend the rest on the reasoning.
- Give the blast radius: what could have broken, and what you measured.
- Name the disagreement and how you resolved it with evidence.
Follow-up
- What would you do differently if you ran that again?
- How did you know your change caused the improvement?
How do you handle technical disagreements within a team?
Medium · Behavioral and Stakeholder Management
Approach
- Pick a story where you made the decision, not one where you watched it.
- State the situation in two sentences and spend the rest on the reasoning.
- Give the blast radius: what could have broken, and what you measured.
- Name the disagreement and how you resolved it with evidence.
Follow-up
- What would you do differently if you ran that again?
- How did you know your change caused the improvement?
Describe a project where you had to pivot your technical strategy due to changing mission requirements.
Medium · Behavioral and Stakeholder Management
Approach
- Pick a story where you made the decision, not one where you watched it.
- State the situation in two sentences and spend the rest on the reasoning.
- Give the blast radius: what could have broken, and what you measured.
- Name the disagreement and how you resolved it with evidence.
Follow-up
- What would you do differently if you ran that again?
- How did you know your change caused the improvement?
What does "ownership" mean to you in the context of software development?
Medium · Behavioral and Stakeholder Management
Approach
- Pick a story where you made the decision, not one where you watched it.
- State the situation in two sentences and spend the rest on the reasoning.
- Give the blast radius: what could have broken, and what you measured.
- Name the disagreement and how you resolved it with evidence.
Follow-up
- What would you do differently if you ran that again?
- How did you know your change caused the improvement?