Interview guides · Acme Industries
Acme Industries Software Engineer Interview Guide
Acme Industries Software Engineer interview guide: the three reported rounds, reported questions, machining topics and a 7-day prep plan.
The 60-second brief
Acme Industries is described by candidates as a manufacturer whose engineering work runs from CNC programming through to quality engineering. The Software Engineer role is reported as building and maintaining software that supports engineering operations and manufacturing processes, working alongside engineering teams, product managers and quality engineers. Day to day, candidates report code reviews, adherence to coding standards, continuous improvement of existing systems and written documentation of designs and processes.
This guide is for candidates interviewing for the Software Engineer role at Acme Industries. It covers the three reported rounds, the reported technical, problem-solving and behavioral questions, the languages and skills candidates say the role lists, and the machining and measurement topics that appear in the reported topic breakdown. It ends with a seven-day plan that mixes spoken answers, small coding exercises and story preparation.
Candidates report three rounds over roughly 3-5 weeks: an Initial Screening Call, Technical Assessments and a Final Interview. The stage descriptions are short, and candidates do not tie specific questions to specific rounds.
Focus areas
- 5-Axis Turning/Milling
- CNC Programming
- CMM Programming (Coordinate Measuring Machine)
Overview
Candidates describe a three-stage loop: an Initial Screening Call, Technical Assessments and a Final Interview, spread over roughly 3-5 weeks. The reported questions are general software engineering ones. They cover object-oriented versus functional programming, how you keep code quality high, version control, language choice, a hard technical problem you solved, troubleshooting a complex system, designing a feature for an existing application, prioritising under a tight deadline, optimising a slow application and the metrics that show a project succeeded. A further group covers teamwork, feedback, taking the lead and communicating with non-technical stakeholders.
Because candidates do not say which question comes in which round, prepare the whole set for every stage. The technical and problem-solving questions are open-ended: they reward answers with a concrete method (measure first, compare two options on named criteria, state the trade-off) rather than a list of definitions. Rehearse each one aloud with an example from code you actually wrote, since the same question can be answered well only from real experience.
The reported topic breakdown also lists 5-Axis Turning/Milling, CNC Programming, CMM Programming (Coordinate Measuring Machine), Metals Machining Domain and Process Improvement. None of the reported questions are about machining itself, so treat this as vocabulary that lets you place your examples in a manufacturing setting: what a CNC program is, why a fifth axis changes tool-path planning, what a coordinate measuring machine reports against a tolerance, and how a software tool could shorten the loop between measuring a part and correcting a program. Candidates list manufacturing or engineering experience as a nice-to-have, not a requirement.
The requirements candidates describe name Java, C++ or Python, database systems, data structures, software development methodologies and strong analytical skills. Cloud platforms such as AWS or Azure, machine learning or data analysis tools, automated testing frameworks and manufacturing experience are listed as nice-to-have. The responsibilities include code reviews, coding standards, continuous improvement and documentation, so keep one example for each: a review you gave or received, a design you wrote up, and a system you made measurably better.
The Acme Industries interview process
Candidates describe three stages, from a preliminary call through technical evaluations to a concluding conversation with key stakeholders. The descriptions are brief, so the preparation below is built from the reported question types and the listed requirements.
Initial Screening Call
Candidates describe the Initial Screening Call as a preliminary call to check qualifications and fit for the role. No format or question set is reported for it. Treat it as the point where your background is matched against the requirements candidates describe: Java, C++ or Python, database systems, data structures and development methodologies. Prepare a short account of your experience that makes that match easy to see, and be ready to say what draws you to a manufacturing and engineering employer.
What to demonstrate
- How clearly you summarise your experience against the listed requirements
- Whether your background and the role fit
- How you describe your strongest language and the work you did in it
How to prepare
- Write a short career summary that names your main language, the databases you have used and one system you owned, in that order.
- Prepare one or two sentences on why a manufacturing and engineering setting interests you, tied to something you have built or read about.
- Collect your logistics (notice period, location, availability) and a few questions about the remaining stages.
Technical Assessments
Candidates describe the Technical Assessments as technical evaluations of skills and problem-solving ability. The format is not reported, so prepare for spoken technical answers, small coding problems and design discussion. The reported technical and problem-solving questions are the best material: object-oriented versus functional programming, code quality, language choice, designing a feature, optimising a slow application and judging project success. Candidates do not link any of them to this round specifically, so practise the full set.
What to demonstrate
- Working knowledge of your main language and of data structures
- How you structure an open-ended technical problem
- Whether your examples come from real experience
- Familiarity with the listed requirements: databases, development methodologies and, where you have it, automated testing
How to prepare
- Solve a few array, hash map and string problems in Java, C++ or Python, whichever you will use, and say your complexity out loud.
- Rehearse the optimising-a-slow-application answer as a fixed sequence: reproduce, measure, find the bottleneck, change one thing, measure again.
- Write one SQL query with a join and an aggregate, and be able to explain when an index helps it.
- Learn the machining vocabulary in the topic breakdown well enough to use it in one example.
Final Interview
Candidates describe the Final Interview as a concluding conversation with key stakeholders about overall fit and alignment with company values. The reported behavioral questions (difficult team member, feedback, taking the lead, communicating with non-technical stakeholders, the most important qualities of a software engineer) are the natural preparation. Because the role is reported to involve product managers and quality engineers, have an example of explaining a technical decision to someone outside engineering.
What to demonstrate
- Fit with the team and the role as a whole
- How you describe teamwork, feedback and leadership with concrete stories
- How well you communicate with people who are not engineers
How to prepare
- Write a story for each reported behavioral question in situation, task, action, result form, with your own actions in the first person.
- Prepare a plain-language explanation of one technical decision, aimed at a product manager or a quality engineer.
- Bring questions about how engineering and quality teams work together on the software this role supports.
Where candidates lose points
Answering the object-oriented versus functional programming question as two lists of definitions
Compare them on concrete axes: where state lives, mutation versus returning new values, composition versus inheritance, and how each affects testing and concurrency. Then show a short example in your own language, such as computing totals over measurement records with a loop and mutable accumulator versus map and reduce, and say that real code mixes both.
Reducing the version control answer to a list of git commands
Explain why history matters: traceability of a change, safe rollback, review through pull requests, bisecting to find a regression. Add one real situation from your work, such as a conflict resolved or a bad commit reverted, and state the branching approach you used and why.
Jumping to a fix when asked how you would optimise a slow application
Open with measurement: reproduce the slowness, profile it, and identify whether the time goes to CPU, database queries, I/O or memory. Change one thing at a time, measure after each change, and say what number would tell you the change worked.
Telling behavioral stories in the plural, with no personal action and no result
Say what you decided and did, in the first person, and close with a result you can support from your own records. For the difficult-teammate story, describe the behaviour and the conversation you had, not the person's character.
Giving only generic examples when the role sits next to CNC programming, measurement and process improvement
Learn a handful of terms (G-code, work offsets, axes, tool paths, probing, tolerance) and use them to frame one or two examples, for instance software that compares measured values to tolerances. Do not claim machining expertise you lack; show you can learn the domain quickly.
Questions & practice
Identify the heaviest tenants in a five-minute window under memory pressure
Medium · top-k · heavy hitters · streaming
The edge service handles about 3,000 requests per second across roughly 50,000 tenants, peaking near 9,000. Expose the 50 heaviest tenants by request count over the trailing five minutes so limits can be tightened before one tenant's backfill starves the fleet. You may not retain five minutes of raw records. Give the exact solution and its memory, then the bounded-memory approximation with its error stated as a formula, and say which you would ship and at what tenant cardinality that choice changes.
Approach
- Do the exact version first, because it is affordable at this cardinality: a ring of 300 one-second counters per tenant, advanced lazily, is 1,200 bytes of counters per tenant and roughly 60 to 90 MB for 50,000 tenants with overhead. Carry a running total and subtract the bucket you overwrite so a window read is O(1) rather than 300 adds.
- Extract the top 50 with a size-k min-heap over the tenant sums: O(d log k) for d tenants, against O(d log d) to sort them all. Maintaining the heap continuously instead of on query requires a tenant-to-heap-index map, because incrementing a count already inside the heap means sifting from a known position, and without that map you rebuild the heap on every request.
- State the approximation precisely rather than gesturing at sketches. Misra-Gries with m counters retains every item whose true count exceeds N/(m+1), and each retained count underestimates the truth by at most N/(m+1). With m = 1,000 and N = 900,000 requests in the window the error is roughly 900 requests, which is fine for spotting a tenant sending 50,000 and useless for ranking two tenants 200 apart.
- Say what breaks when the window slides: Misra-Gries and Space-Saving are insert-only and cannot be decremented as records age out. The workable construction is one summary per sub-window, say ten seconds, with 30 summaries merged at query time, and the merged error is the sum of the per-summary errors, so the bound degrades linearly in the number of sub-windows.
Follow-up
- The heaviest tenant is heavy because of one export job rather than user traffic. Should the limiter treat those as the same tenant?
- Two tenants sit tied at the boundary of the top 50. Does your answer flap, and does the flapping matter?
Track a rolling failure rate per destination for circuit decisions
Easy · sliding window · ring buffer · circuit breaker
The egress service delivers about 1,500 webhooks per second across roughly 40,000 destinations, each call bounded by a 10 second timeout. Maintain, per destination, the failure rate over the trailing 60 seconds so a caller can ask before dispatch whether the circuit should open. Attempts arrive as (destination_id, finished_at_ms, outcome). Requirement: amortised O(1) per attempt, with total memory bounded by the destination count rather than by traffic. Give the structure, its exact memory, and the rule that stops a destination with three attempts from opening a circuit.
Approach
- Name the exact-deque version and then reject it as the default. Holding timestamps and advancing a tail pointer past anything older than now minus 60 seconds is a correct two-pointer window at amortised O(1) per attempt, but its memory tracks in-window traffic, so one destination in a retry storm holds hundreds of thousands of entries while thousands of quiet destinations hold none.
- Use a ring of 60 one-second buckets per destination, each bucket a pair of counters for attempts and failures. On an attempt, advance the ring by the elapsed whole seconds, zeroing at most min(elapsed, 60) buckets, then increment the head. That is amortised O(1) with a fixed footprint per destination.
- State the footprint: 60 buckets times two 4-byte counters is 480 bytes of payload per destination, so 40,000 destinations is roughly 20 to 25 MB with per-entry overhead, bounded by the catalogue rather than by the rate. The cost is granularity, since the oldest bucket ages out in whole seconds, which is far tighter than the decision needs.
- Require a minimum sample before the circuit may open. A destination with three attempts and three failures reads as 100 percent and is not evidence; a floor of roughly 20 attempts in the window makes the ratio meaningful, and below that floor use a run of consecutive failures as the trigger instead.
Follow-up
- The fleet is 30 instances and each sees roughly a thirtieth of a destination's traffic. Where does the rate actually live, and what does a per-instance answer get wrong?
- A destination answers in 9.5 seconds and succeeds. It is not failing but it is consuming your per-destination concurrency. What signal should open the circuit here?
Archive a resource graph without breaking live references or recursing
Medium · graph traversal · topological order · tenant isolation
Resources reference other resources within a tenant; for the largest tenant the reference table holds up to 2,000,000 nodes and 8,000,000 edges. Archiving a resource must archive everything reachable from it that nothing outside the set still references, refuse when a live external referrer exists, and terminate when references form cycles, which they legitimately do. Produce the archive order and the refusal list, targeting O(V+E). Say what stops the traversal crossing a tenant boundary, and why recursion is the wrong control structure at this size.
Approach
- Load the subgraph with the tenant predicate on both endpoints of the edge, not only on the side you started from. Scoping the left table alone is the classic cross-tenant leak: one mis-entered edge then pulls another tenant's resources into the traversal and, worse, into the archive.
- Traverse iteratively with an explicit stack. A 2,000,000-node graph can hold a chain deep enough to exhaust a native stack in the low tens of thousands of frames, and that failure is a process crash rather than an error you can return.
- Treat cycles as data rather than corruption: compute strongly connected components with Tarjan in O(V+E) using its own explicit stack, then condense. The condensation is a DAG, so a topological order over it gives the archive order, and every member of a component archives in one transaction because no order within a cycle is valid.
- Decide refusals with reverse edges. A candidate is archivable only if every in-edge originates inside the candidate set, so build the transpose or count in-degrees restricted to the visited set, and emit each blocked resource with the id of the external referrer, which is the only part of the answer an operator can act on.
Follow-up
- The graph is read in one query and the archive writes a minute later. What can change in between, and how do you make the write safe?
- The candidate set is 400,000 resources. Is that one transaction, and if not, what does a half-finished archive look like to a reader?
Explain why the owner filter ignores the listing index
Medium · composite index · query plans · sort elimination
The only index on resource is (tenant_id, status, updated_at DESC, resource_id DESC). A new endpoint returns one user's resources across all statuses, newest created first: WHERE tenant_id = $1 AND owner_user_id = $2 ORDER BY created_at DESC LIMIT 20. On a tenant with 2M rows it takes 900 ms and EXPLAIN shows a sort above a large scan. Explain precisely why the existing index cannot serve it, give the index that can, and state which of these the new index still will not help: owner_user_id alone across tenants; the same query ordered by updated_at. PostgreSQL 16.
Approach
- Separate the two jobs an index does. For filtering, a composite btree is seekable only on a left prefix, so with no predicate on status the scan can at best range over tenant_id and test owner_user_id per row; PostgreSQL 16 has no btree skip scan to jump the unconstrained column.
- For ordering, the index is sorted by (status, updated_at) within a tenant and not by created_at, so the LIMIT cannot stop early: every matching row is read and then sorted. That is the 'Sort Method: top-N heapsort' line, and it is why the plan reads 2M rows to answer with 20.
- Derive the replacement from the access path — equality, equality, then the ordering column: CREATE INDEX CONCURRENTLY ON resource (tenant_id, owner_user_id, created_at DESC). The scan seeks to the (tenant, owner) range and walks 20 entries in order, so the Sort node disappears along with the row-read.
- Treat INCLUDE (title, status) as conditional, not free. An index-only scan still visits the heap for any row whose page is not marked all-visible, so on a table taking 1.2k writes/second the win depends on autovacuum keeping the visibility map current, and the wider index costs more on every insert.
Follow-up
- 90% of rows are status='active'. Would a partial index WHERE status = 'active' change your answer, and for which of the three queries?
- A dashboard runs this for 40 owners in one page load. What changes about the design?
Find version gaps and relay lag with window functions
Medium · window functions · event tables · frame semantics
outbox_event holds event_id, aggregate_type, aggregate_id, aggregate_version, event_type, payload, status ('pending','published','dead'), attempts, created_at, published_at. A projection is missing rows and you must decide whether the relay skipped events or the consumer dropped them. Write three queries over the last seven days: one listing every aggregate_id whose published aggregate_version sequence has a hole, one giving per-day counts with a running total, and one returning the newest published event per aggregate. For each, say where the window function is evaluated relative to WHERE and LIMIT. PostgreSQL 16.
Approach
- Gaps: compute lead(aggregate_version) OVER (PARTITION BY aggregate_id ORDER BY aggregate_version) in a subquery, then filter next_version <> aggregate_version + 1 in the outer query. Window functions are evaluated after WHERE, GROUP BY and HAVING and before the outer ORDER BY and LIMIT, so the predicate cannot sit in the same WHERE clause and PostgreSQL 16 has no QUALIFY.
- Say what the seven-day filter does to the answer: it truncates every partition, so the first row per aggregate has no predecessor inside the window and a hole spanning the boundary is invisible. Widen the window, or join to resource.version as the authority for the true maximum.
- Running total: SELECT date_trunc('day', created_at) AS d, count() AS n, sum(count()) OVER (ORDER BY date_trunc('day', created_at) ROWS UNBOUNDED PRECEDING). An aggregate inside a window call is legal because grouping runs before windowing. The grouping key is unique per row here so ROWS and RANGE agree, but write the frame anyway — over ungrouped rows with tied timestamps the default RANGE frame pulls in every peer row and the total jumps.
- Newest per aggregate: DISTINCT ON (aggregate_id) ... ORDER BY aggregate_id, aggregate_version DESC is the cheap PostgreSQL-only form when an index matches that order; row_number() OVER (PARTITION BY aggregate_id ORDER BY aggregate_version DESC) = 1 is the portable form and needs a subquery for the same evaluation-order reason as the gap query.
Follow-up
- Relay failover redelivers events. Does a duplicate break the gap query, and how would you detect one from this table alone?
- Turn the gap check into a continuous monitor rather than a query someone runs after an incident. What does it watch?
Explain the differences between object-oriented programming and functional programming.
Medium · Technical / Domain Questions
Approach
- Start with the core split: OOP bundles mutable state with the methods that change it behind an interface (encapsulation, inheritance, subtype polymorphism via dynamic dispatch); FP builds programs from pure functions over immutable values, uses higher-order functions and composition, and pushes side effects to the edges.
- Use the expression problem to show depth: in OOP adding a new type is one new class, but adding a new operation touches every class (the Visitor pattern is the workaround); with algebraic data types and pattern matching, adding an operation is one new function, but adding a variant touches every function.
- Name the practical consequences: immutable values and pure functions can be shared across threads without locks and tested without mocks; the cost is copying, which persistent data structures reduce through structural sharing (typically O(log n) per update).
- Tie it to the languages this role lists: Java mixes both (interfaces and classes plus lambdas, the Stream API, records for immutable values, sealed interfaces with switch pattern matching in Java 21); C++ has lambdas, std::function and const; Python has first-class functions and functools but mutable built-in collections.
- Close with how you actually combine them: a functional core (pure calculations that are easy to unit test) inside an imperative shell, with objects owning resources that have a lifecycle such as files, sockets or device connections.
Follow-up
- How would you make a Java class truly immutable, including fields that hold mutable collections?
- When does inheritance cause trouble, and how would composition fix that case?
- How do you test a function that has side effects such as writing to a database?
How do you ensure the quality of your code?
Medium · Technical / Domain Questions
Approach
- Answer as layers, cheapest first: compiler and static checks, then automated tests, then review, then production feedback. Name tools per language: warnings as errors (-Wall -Werror) and clang-tidy for C++, SpotBugs or Checkstyle for Java, ruff and mypy for Python.
- Describe the test pyramid concretely: many fast unit tests on pure logic (JUnit 5, pytest, GoogleTest), fewer integration tests against a real database instance rather than mocks, and a thin end-to-end layer; every bug fix lands with a regression test that failed before the fix.
- Explain that CI gates merges: branch protection requires green builds and a review; pull requests stay small so a reviewer can read the whole change, and the review checks error handling, naming and that tests cover the changed behaviour.
- Treat coverage as a signal, not a target: a covered line with no assertion proves nothing. Mutation testing (PIT for Java, mutmut for Python) shows whether tests fail when the code is altered. For C++, run AddressSanitizer and UBSan in CI to catch memory errors and undefined behaviour.
- Cover the edge case of legacy code with no tests: write characterization tests that pin current behaviour before refactoring, then improve in small, reviewed steps.
Follow-up
- A test fails one run in twenty. How do you deal with it?
- How would you add tests to a large module that has none and is hard to instantiate?
- When time is short, which tests do you write first and which do you skip?
Can you describe a challenging technical problem you've solved in the past?
Medium · Technical / Domain Questions
Approach
- Pick a problem with a real technical constraint you diagnosed yourself (race condition, memory leak, performance cliff, data corruption, integration with hardware or a vendor system) and open with the symptom and its impact in one or two sentences.
- Walk through your hypotheses in order and the evidence that ruled each in or out: logs and metrics, a minimal reproduction, a profiler or debugger, git bisect to find the change that introduced it.
- State the root cause precisely enough to be checked, for example two threads doing an unsynchronised read-modify-write on a shared counter, then the fix and the alternatives you rejected with the reason (cost, risk, time).
- Show verification: a test that failed before and passes after, a before-and-after number, and the change that prevents recurrence (an alert, a lint rule, a design change). Be ready to go one level deeper on any component you mention.
Follow-up
- How did you prove that was the root cause and not a coincidence?
- What would you do differently if you faced the same problem again?
- Would your fix still hold at ten times the load or data volume?
What programming languages are you most proficient in, and how do you choose which one to use for a project?
Medium · Technical / Domain Questions
Approach
- Name one primary language and back the claim with depth you can defend: for Java, the garbage collector, the memory model and generics type erasure; for C++, RAII, move semantics and undefined behaviour; for Python, the GIL, packaging and where CPU time goes. The requirements candidates describe list Java, C++ and Python.
- Give selection criteria in order: the existing codebase and the team's skills, required libraries or vendor SDKs, runtime constraints (latency, memory, real-time or embedded targets), deployment environment and interoperability with other systems.
- State the trade-offs accurately: C++ gives deterministic destruction and no GC pauses at the cost of manual memory-safety risk; Java gives a managed runtime, strong tooling and portability with GC overhead; Python is fastest to write, but in standard CPython the GIL lets only one thread run Python bytecode at a time, so CPU-bound parallel work needs multiprocessing or native extensions.
- Finish with a real decision: I chose X over Y for this project because of Z, and here is what that choice cost later.
Follow-up
- A Python loop over millions of records is too slow. What are your options?
- Explain RAII and what the Java equivalent is for releasing a file handle.
- When would you deliberately not use your strongest language?
How would you approach designing a new feature for an existing application?
Medium · Problem-Solving / Case Studies
Approach
- Clarify before designing: who uses the feature, what problem it solves, how success is measured and what is out of scope; then read the existing code, data model and call paths it will touch so the design follows the patterns already there.
- Design the changes with backward compatibility: additive API changes or a new version, database changes as expand-and-contract (add a nullable column, backfill, switch reads, then enforce constraints and drop the old path), and logic placed in the module that already owns that data.
- Check non-functional impact on existing paths: an extra query per request or an N+1 loop, permissions and input validation, and the logs and metrics needed to see whether the feature works.
- Plan the rollout: feature flag, tests for new behaviour plus regression tests for old behaviour, incremental exposure and a rollback plan that does not require reverting a migration. Ship the smallest useful version first.
Follow-up
- How would you change a column's type on a large live table without downtime?
- Some users depend on the workflow your feature changes. How do you handle that?
- When and how do you remove the feature flag afterwards?
If you were given a task with a tight deadline, how would you prioritize your work?
Medium · Problem-Solving / Case Studies
Approach
- Pin down what is fixed: the date, the minimum that must ship and what done means; ask which outcome matters most rather than accepting the whole list as equally important.
- Break the work into tasks, estimate them, find the dependency chain that sets the end date, and start anything that depends on other people first. Do the riskiest unknown early as a short spike so surprises appear while there is still time to react.
- Cut scope, not quality, on the core path: sort into must, should and could, defer the rest, keep tests on the core logic, and record any shortcut as a tracked follow-up item.
- Communicate early with options: if the estimate exceeds the deadline, say so with concrete choices (smaller scope, later date, more help) and their costs, and check progress against the plan daily. Back it with one real example.
Follow-up
- What would you refuse to cut even under deadline pressure?
- Two stakeholders each say their item is the top priority. What do you do?
- How do you estimate a task you have never done before?
Walk us through your process for optimizing a slow-running application.
Medium · Problem-Solving / Case Studies
Approach
- Define slow with a number first: which operation, p50/p95/p99 latency or throughput, under what load and data size. Reproduce it with a repeatable benchmark and record a baseline before changing anything.
- Measure to locate the time: a profiler (async-profiler or Java Flight Recorder for Java, perf for C++, cProfile or py-spy for Python) and tracing to split time between application code, database, network and disk, and to tell CPU-bound work from waiting.
- Apply fixes by layer: in the database, EXPLAIN ANALYZE, missing indexes, N+1 queries, fetching too many rows or columns; in code, algorithmic complexity (a nested-loop O(n^2) match replaced by a hash map lookup in O(n)), repeated work cached with a clear invalidation rule, batched I/O; in resources, pool sizes, GC pressure and leaks.
- Change one thing at a time and re-measure against the baseline. Amdahl's law bounds the gain: speeding up a part that takes fraction p of the time by factor s gives an overall speedup of 1/((1-p)+p/s), so target the largest share first.
- Name the trade-offs: caching adds staleness and memory use, denormalising adds write cost, and parallelism adds contention. Keep a benchmark in CI so the regression cannot return unnoticed.
Follow-up
- The profile shows most time inside database calls. What do you check next?
- Average latency is fine but p99 spikes. What are the likely causes?
- How do you stop the same slowdown from coming back after the fix?
What metrics would you consider to evaluate the success of a software project?
Medium · Problem-Solving / Case Studies
Approach
- Separate outcome from output: start with the outcome the project was meant to change for its users (time saved per task, errors avoided, adoption by the intended users) and agree a baseline before launch so there is something to compare against.
- Add delivery metrics, such as the DORA set: deployment frequency, lead time for changes, change failure rate and time to recover from a failed deployment.
- Add quality and reliability measures: defects found after release, incident count and severity, and service-level objectives such as availability and p95 latency; include cost and schedule against plan.
- Name the pitfalls: vanity counts such as lines of code or story points compared across teams, Goodhart's law (a metric used as a target stops measuring well), and missing guardrail metrics that catch harm elsewhere. Pair early indicators such as adoption with later ones such as defect trends.
Follow-up
- If you could track only one metric for an internal engineering tool, which would it be and why?
- How would you show the improvement came from this project and not from other changes?
- The metrics say the project succeeded, but users complain. What do you do?
Every query on one table stalls for forty seconds mid-deploy
Medium · lock contention · ddl · migrations
During a release on PostgreSQL, every query touching resource times out for about 40 seconds and then recovers with no intervention. The release ran one migration, ALTER TABLE resource ADD COLUMN archived_reason TEXT, and the migration log shows it completing in 6 ms. Unrelated tables showed no change in error rate. Explain how a 6 ms statement caused a 40-second stall, give the ordered checks you would run on a live system to confirm it, and give the migration procedure that prevents a repeat.
Approach
- Separate the statement's duration from the lock's duration. ADD COLUMN with no default is a catalogue-only change and genuinely runs in milliseconds, but it requires ACCESS EXCLUSIVE, and it cannot acquire that until every transaction already touching the table has finished.
- Account for the queueing, which is the part that surprises people. A lock request that is waiting blocks later requests for conflicting modes behind it rather than letting them overtake, so one long-open transaction holds the DDL and the DDL holds all the traffic. The stall length is set by the longest open transaction, not by the size of the change.
- Confirm on a live system in this order: pg_stat_activity for that table ordered by xact_start, looking for the oldest transaction and specifically for state = idle in transaction; then pg_locks where granted = false to find the waiter; then join them on pid to name blocker and blocked. pg_blocking_pids() does that join for you and is the fastest single call.
- Prevent rather than merely time it better. Set lock_timeout to a second or two on the migration session so the DDL abandons the queue after a bounded wait and is retried, instead of holding it for as long as the oldest transaction lives. Be exact about what that buys: queries arriving during the wait still queue behind the pending ACCESS EXCLUSIVE request, so each attempt costs them up to one lock_timeout of added latency. The outage goes from 40 seconds to about one second per attempt, not to zero. Also run migrations away from deploy-time peaks, and put a statement timeout and an idle-in-transaction timeout on the analytics role that opens the long transactions.
Follow-up
- The same release also wants NOT NULL on that column. What is the sequence that gets there without a long lock?
- Your lock_timeout retry fails ten times in a row because the analytics transaction is always open. What do you change?
Suggested practice checklist
The plan moves from mapping the three reported rounds and the machining vocabulary, through the technical and problem-solving questions, to a full run of the reported behavioral questions.
Day 1 — Map the loop and the requirements
- Write the three reported rounds on one page: Initial Screening Call, Technical Assessments, Final Interview.
- List the requirements candidates describe (Java, C++ or Python, databases, data structures, methodologies) and next to each write your strongest example.
- Mark the nice-to-haves you can claim (cloud, data analysis, automated testing, manufacturing) and the ones you cannot.
Deliverable: A one-page loop map plus a requirement-to-example table with gaps marked.
Day 2 — Machining and measurement vocabulary
- Write a glossary covering CNC programming, 5-axis turning and milling, CMM programming, metals machining and process improvement, each entry in one or two sentences of your own.
- Sketch a small software tool that serves one of these areas, for example one that compares CMM measurements to tolerances, with its inputs, outputs and failure cases.
Deliverable: A one-page glossary and a one-page sketch of a tool, ready to use as an example.
Day 3 — Paradigms and language choice
- Implement the same small task, such as summarising measurement records, in an object-oriented style and in a functional style in your strongest language.
- Write a two-minute spoken answer on the differences between the two styles, using your two implementations as the example.
- Write your language-choice answer: your strongest language, a second one, and the criteria you use to choose between them.
Deliverable: Two short implementations, a spoken comparison and a language-choice answer you can say aloud.
Day 4 — Code quality and version control
- Write a code-quality checklist from your own practice: tests, review, static checks, standards, documentation.
- Write a version control story covering a conflict, a revert or a bisect, and the branching approach you used.
- Say the merge versus rebase trade-off aloud without notes.
Deliverable: A written checklist, one version control story in situation-action-result form and a recorded spoken answer for each of the two questions.
Day 5 — Performance, feature design and project metrics
- Profile a small program of yours, change one thing and record the before and after numbers.
- Outline how you would add a feature to an existing application: requirements, impact on current code, tests, rollout.
- List metrics for judging a software project and say which one you would choose for a tool used by engineers and quality staff.
Deliverable: A profiling log with numbers, a feature outline, a short metric list with a chosen metric, and your written explanation of the index question.
Day 6 — Troubleshooting, deadlines and a hard problem
- Write the complex-system troubleshooting story: impact, mitigation, hypotheses, evidence, fix, follow-up.
- Choose your hardest technical problem and outline it in problem-approach-result form.
- Write how you decide what to cut or defer under a tight deadline, with one real example.
Deliverable: Two written stories, a short prioritisation answer and the debugging question's diagnosis written step by step.
Day 7 — Leadership, feedback and stakeholders
- Write the difficult-teammate, feedback and taking-the-lead stories in situation, task, action, result form.
- Prepare a plain-language explanation of a technical decision for a non-technical stakeholder.
- Choose three qualities for the most-important-qualities question and attach one example to each.
- Run all five aloud in one sitting and record them.
Deliverable: Five rehearsed answers with a recording, and a revised version of whichever story sounded weakest.
Behavioural preparation
Candidates describe the Final Interview as a conversation with key stakeholders about fit and company values, and the reported behavioral questions cover teamwork, feedback, taking the lead and communicating with non-technical people. For this role, build stories around work with product managers, quality engineers and other engineers, and around code review, documentation and improving existing systems.
What is your experience with version control systems, and why are they important?
Medium · Technical / Domain Questions
Approach
- Give your real experience in one sentence (the tool, the team size, the branching approach), then spend the answer on why it matters: traceable history, safe rollback, review through pull requests and a trigger point for automated checks.
- Anchor it with a specific episode: a conflict you resolved, a regression you located with git bisect, or a bad commit you reverted without losing later work.
- Be able to state the merge versus rebase trade-off: merge keeps true history and is safe on shared branches, rebase gives a linear history but rewrites commits, so never rebase work others have pulled.
- Mention what belongs outside normal diffs, such as large binary files or generated programs, and how you handled them (ignore rules, large-file storage, or a separate artifact store).
- Avoid an answer that is only a list of commands; the sinking mistake is describing the tool and never saying what it protected.
Follow-up
- How would you recover if a bad commit reached the main branch?
- Which branching strategy would you choose for a small team, and why?
- How do you handle long-running feature branches that keep diverging?
Describe a time when you had to troubleshoot a complex system issue. What steps did you take?
Medium · Problem-Solving / Case Studies
Approach
- Choose an incident where you drove the diagnosis, and open with impact: who or what was affected and how you knew.
- Describe the sequence: stabilise or mitigate first, reproduce, list hypotheses, then use logs, metrics or traces to rule them out one by one rather than changing several things at once.
- Name the evidence that located the cause (a log line, a query plan, a diff between two releases) and the fix you shipped, with the check that proved it worked.
- Close with prevention: the test, alert or runbook step you added, and what you would do sooner next time.
- The mistake that sinks it is a story of guessing and restarting until it worked, or one where a colleague found the cause.
Follow-up
- What did you rule out first, and why?
- How did you confirm the fix did not just hide the symptom?
- What did you change afterwards so it would be caught earlier?
Tell us about a time when you had to collaborate with a difficult team member.
Medium · Behavioral / Leadership
Approach
- Choose a real disagreement with a colleague over work, not a personality clash, and describe the behaviour and its effect on the project in neutral terms.
- Show what you did first: asked questions to understand their constraints, then had a direct private conversation instead of escalating or complaining to others.
- Describe the working agreement that came out of it (a clearer review process, a split of ownership, shorter check-ins) and what changed.
- State the result honestly, including a partial one, and what you would do differently.
- The mistake that sinks it is a story that casts the other person as the problem and you as the hero.
Follow-up
- What would you have done if the conversation had not helped?
- When did you involve your manager, and why then?
- What did you learn about your own part in the friction?
How do you handle feedback on your work?
Medium · Behavioral / Leadership
Approach
- Use a specific piece of feedback, ideally from a code review or a performance conversation, and say what it was in one sentence.
- Show your process: listen without defending, ask a clarifying question, check the claim against the code or data, then decide what to change and what to discuss.
- Show that you acted and that the change lasted: a later pull request where you applied the lesson, or a checklist you added to your own workflow.
- Include one case where you disagreed, and how you put your reasoning forward with evidence while staying open to being wrong.
- The mistake that sinks it is saying you welcome feedback with no example, or choosing a minor, flattering one.
Follow-up
- Tell me about feedback you disagreed with and what you did.
- How do you give feedback in a code review?
- How did you know the change you made was an improvement?
Describe a situation where you took the lead on a project. What was the outcome?
Medium · Behavioral / Leadership
Approach
- Choose a project where you owned the outcome, and state its goal and constraints in two sentences.
- Spend the answer on leadership actions: breaking the work into pieces, assigning them to match people's strengths, removing blockers, and keeping stakeholders informed.
- Describe one decision where you chose between options and the reason, plus how you handled someone who disagreed.
- Give the outcome with figures from your own records (delivery date, defect count, time saved), and say what fell short.
- The mistake that sinks it is a team story told as if you did all the work, or an outcome with no result.
Follow-up
- How did you decide who did what?
- What went wrong, and how did you respond?
- What would you change if you ran the project again?
How do you ensure effective communication with stakeholders from non-technical backgrounds?
Medium · Behavioral / Leadership
Approach
- Start from the other person's decision: what a product manager or quality engineer needs to choose, then give the answer first and the detail after.
- Describe your habits: plain words in place of internal terms, one concrete example or diagram, a written summary after a meeting, and an explicit statement of risk and uncertainty.
- Give a real instance, such as explaining a delay, a trade-off between speed and correctness, or a tooling change, and say how you checked they understood.
- Mention feedback: asking them to restate the decision, or adjusting after a question showed a gap.
- The mistake that sinks it is saying you simplify things with no instance, or one where you only told people what to do.
Follow-up
- How do you explain a technical risk without alarming people?
- Tell me about a misunderstanding with a non-engineer and how you fixed it.
- How do you handle a request that is not feasible in the time given?
What do you consider the most important qualities of a successful software engineer?
Medium · Behavioral / Leadership
Approach
- Pick three qualities and rank them; a short, justified list is stronger than six adjectives.
- Back each with behaviour from your own work, for example care about correctness shown by tests you wrote, clear communication shown by design notes, ownership shown by following a bug to its cause.
- Tie them to the role as candidates describe it: reading and changing existing systems, code review, documentation and working with quality engineers and product managers.
- Be ready to say which of the three you are still developing and what you are doing about it.
- The mistake that sinks it is a generic list (hard-working, passionate, team player) with no evidence.
Follow-up
- Which of those qualities is hardest for you, and what do you do about it?
- Which would you trade off first under a tight deadline?
- How do you see those qualities in a code review?