cswork / libraryOpen practice workspace

Interview guides · Actian

Actian Software Engineer Interview Guide

Actian Software Engineer interview guide: reported rounds, coding and system design questions, behavioral prep and a 7-day plan.

The 60-second brief

Candidate-facing descriptions place Actian in data management and analytics software for businesses across industries. They describe the Software Engineer role as designing, building and maintaining applications, working alongside product managers, designers and other engineers, taking part in code reviews, and troubleshooting and debugging applications. Projects are described as possibly involving cloud technologies, big data processing or real-time analytics, which is why this guide includes a data-ingestion design question and database design alongside the usual coding material.

This guide is for engineers preparing for the Actian Software Engineer loop. The requirements candidates describe name Java, C# or Python, Agile and Scrum experience, algorithms, data structures and software design principles, with cloud platforms (AWS, Azure), DevOps tooling and SQL as extras, and a typical background of roughly two to five years. The guide also includes a C++ track: ask your recruiter whether the team you are interviewing for works in C or C++, and if it does, add the C++ task on Day 3 of the plan. The guide covers every reported question type: language and data-structure knowledge, coding and complexity, debugging, requirements and ambiguity cases, system design, and behavioral prompts.

Candidates report three stages over roughly three to five weeks: an Initial Screening, one or more Technical Interviews, and Behavioral Assessments.

Focus areas

  • Algorithmic problem solving
  • Coding/implementation
  • Time complexity analysis

Overview

The reported questions split into five groups: technical knowledge (languages you know, data structures, object-oriented principles, code quality), coding and algorithms (an algorithm problem, narrating your reasoning, time and space complexity, debugging, reversing a linked list), problem-solving cases (ambiguous requirements, a system performance scenario, gathering requirements), system design (real-time data ingestion, database design, microservices versus monolith) and behavioral prompts. Candidate-facing topic lists also name data lineage and explaining algorithms out loud, so plan to talk through your code, not only type it.

The requirements candidates describe list Java, C# or Python, so pick the one you can write fastest and use it for every coding exercise. The reported prompt for the algorithm problem has a blank where the specific problem would be, which means you cannot rehearse one question. Prepare the common families instead: arrays and strings, hash maps, linked lists, stacks and queues, trees, sorting and searching, each with a one-line complexity statement you can justify.

Because the company is described as working on data management and analytics, with cloud, big-data and real-time workloads possible, the design questions deserve real time. Be ready to sketch an ingestion pipeline (producers, a buffer or queue, consumers, storage, failure handling), to design a relational schema for a new application with its indexes and access patterns, and to argue microservices against a monolith for a specific team and product. SQL is listed as nice-to-have, but practice it concretely: joins, GROUP BY with HAVING, window functions, and reading a query plan. For AWS or Azure, a working knowledge of the main storage and compute services is enough to start.

The last stage is described as assessing collaboration and communication. Five of the reported prompts are behavioral: a difficult team member, prioritizing across projects, taking the lead, handling failure, and what motivates you. Build a small set of true stories from your own work and check each against several prompts, so you are adapting a story rather than inventing one under pressure.

The Actian interview process

The three stages below are what candidates describe. Reports give no format, duration or interviewer details for each stage, so ask your recruiter what each involves.

Initial Screening

Candidates describe the Initial Screening as the stage that checks your qualifications against the role. Little else is reported about its format, so treat it as a conversation about your background and fit with the requirements candidates list: Java, C# or Python, algorithms and data structures, Agile and Scrum, and roughly two to five years of software work. A reported question asks which languages you know best and how you have used them, so prepare for it early. Have a concrete answer ready for each language you claim: a project, what you built, and one design decision you made in it.

What to demonstrate

  • How your qualifications compare with the listed requirements
  • How your experience lines up with the languages and skills in the requirements candidates describe
  • Basic fit for the role before the technical stages

How to prepare

  • Write a short answer per language you list on your resume: one project, what you built in it, one decision you would defend.
  • Put the listed requirements (Java, C# or Python; Agile and Scrum; algorithms and data structures) next to your resume and note where you have evidence and where you have a gap.
  • Ask the recruiter what the Technical Interviews involve, how many there are, and whether the team works in C or C++, since candidates describe one or more technical interviews.

Technical Interviews

Candidates describe one or more Technical Interviews that test coding skill and problem-solving. Reports do not tie specific questions to this stage, but the reported technical questions fall into technical knowledge (data structures, object-oriented principles, code quality), coding and algorithms (including complexity and debugging), problem-solving cases, and system design, with the design material described as applying where relevant. Candidate-facing topic lists name algorithmic problem solving, coding and implementation, time complexity analysis, data lineage and explaining algorithms out loud. Work in one language, say your approach before you type, and finish every solution by stating time and space complexity.

What to demonstrate

  • Working code for an algorithm problem
  • Choice of data structure and the complexity you can justify for it
  • Clarity when explaining an algorithm aloud
  • Design reasoning for ingestion pipelines, schemas and architecture trade-offs

How to prepare

  • Reverse a linked list iteratively and recursively. The iterative loop that starts with prev = null handles the empty and single-node lists with no guard; the recursive version needs a base case of head == null or head.next == null.
  • Practice a family of problems (arrays, hash maps, stacks and queues, trees) and state time and space complexity for each; rehearse debugging as reproduce, narrow the failing input, inspect state, test one hypothesis, fix, add a test.
  • Sketch a real-time ingestion pipeline, a schema for a small new application, and a microservices-versus-monolith argument on paper.
  • Model data lineage as a DAG of datasets and jobs: downstream BFS/DFS for impact analysis, upstream traversal for root cause, topological sort for recompute order.

Behavioral Assessments

Candidates describe Behavioral Assessments as the stage that gauges collaboration and communication. Reports do not tie specific questions to this stage; the reported behavioral prompts cover a difficult team member, prioritizing across several projects, taking the lead on a project, handling failure or setbacks, and what motivates you, and candidate-facing material also mentions ambiguity and stakeholder requirements. Answer with specific experiences from your own work. Structure each as situation, task, action and result, spend most of the time on what you decided and why, and finish with the outcome and what you changed afterward.

What to demonstrate

  • Collaboration and communication, as the stage is described
  • How you handle conflict, competing priorities and setbacks
  • How you work through unclear requirements and stakeholder needs

How to prepare

  • Write four true stories from your recent work: a conflict, a lead role, a failure, and a project with unclear requirements.
  • For each story, make your own decisions explicit, note the result with a number or a concrete change, and the one thing you would do differently.
  • Cross-check the stories against all five reported prompts so each one can be reused, and rehearse your motivation answer separately since it is not a story.

Where candidates lose points

Naming languages without depth when asked what you are proficient in

The requirements candidates describe list Java, C# or Python. For each language on your resume, prepare one project, what you built in it and one decision you made, and be ready to write a short function in it live.

Coding silently, or stating a complexity without being able to justify it

Candidates see explaining algorithms aloud and time complexity analysis among the topics. Say your approach and data structure before typing, then derive the time and space cost from the loops and structures you used.

Reversing a linked list and losing the rest of the list, or mishandling the empty and one-node cases

Store the next node before you rewire the pointer, keep a previous pointer that starts as null, and return it as the new head. Test the empty list and a single node before saying you are done.

Answering the real-time data ingestion or database design question by listing tools

State the assumed volume, ordering and loss requirements first, then walk producers, buffer or queue, consumers, storage and failure handling. For a new application's schema, begin from the queries it must serve and choose keys and indexes from them.

Telling behavioral stories in the collective, with no personal decision and no result

Use I for your own actions, name a decision and the alternative you rejected, and end with a measurable outcome or a concrete change. Rehearse the difficult team member and failure prompts, since those need the most honest self-assessment.

Questions & practice

Solve the following algorithm problem: [insert specific algorithm problem].

Medium · Coding / Algorithms

Approach

  1. The reported question does not name the problem, so prepare the method, not one answer: restate the problem, confirm input size, value ranges, duplicates and the expected output, and work one small example by hand.
  2. State the brute-force solution and its complexity first, then name the constraint that rules it out (for n up to 10^5, O(n^2) is about 10^10 steps).
  3. Match the problem to a pattern: hash map for complement or frequency lookups, two pointers or binary search on sorted input, sliding window for contiguous ranges, BFS for shortest paths in unweighted graphs, a heap for top-k, dynamic programming for overlapping subproblems.
  4. Example: two-sum with a hash map of value to index is O(n) time and O(n) space; sorting with two pointers is O(n log n) time and O(1) extra space but loses the original indices unless you store them.
  5. Code it, then trace your example and the edge cases out loud: empty input, one element, all duplicates, negative numbers, integer overflow in Java or C#.

Follow-up

  • Can you reduce the space complexity, and what does that cost in time?
  • How does the solution change if the input arrives as a stream?
  • What test case would break your first version?

Explain your thought process while coding a solution to a problem.

Medium · Coding / Algorithms

Approach

  1. Narrate in a fixed order so the listener can follow: restate the problem, confirm constraints, work an example, state the brute force, improve it, outline the steps, then code.
  2. Say why at each decision: 'I am using a hash set because I need O(1) membership checks and order does not matter.'
  3. Write a short outline or function signatures before the body, so a bug later is easy to localise and the structure is visible.
  4. After coding, trace a small input line by line, then state time and space complexity and the edge cases you checked.
  5. When stuck, say what you are trying and why it is not working yet; silence hides your reasoning, and a stated dead end often points to the fix.

Follow-up

  • Where did your first idea go wrong, and how did you notice?
  • How would you test this function if you could run it?
  • How would you explain this solution to a teammate who has to maintain it?

Discuss time complexity and space complexity for your solutions.

Medium · Coding / Algorithms

Approach

  1. Big-O describes how cost grows with input size, dropping constants and lower-order terms. Count work per loop level: one pass is O(n), nested loops over the same input are O(n^2), halving the range each step is O(log n).
  2. For recursion, write the recurrence: merge sort is T(n) = 2T(n/2) + O(n), which solves to O(n log n). Naive Fibonacci recursion is exponential; memoising it makes it O(n).
  3. Distinguish average, worst and amortised cases: hash map lookups are O(1) on average and O(n) in the worst case; quicksort is O(n log n) on average and O(n^2) worst; a dynamic array append is amortised O(1) because resizes double capacity.
  4. Count space honestly: auxiliary structures plus the recursion stack. Recursive DFS uses O(h) stack for tree height h, which is O(n) on a skewed tree.
  5. Know the reference point: comparison sorts cannot beat O(n log n) in the worst case; counting or radix sort can when keys are bounded integers.

Follow-up

  • What is the difference between amortised and average-case complexity?
  • Your solution is O(n log n); could it be O(n), and what would that need?
  • When would you accept a worse big-O for better real-world speed?

Write a function to reverse a linked list.

Medium · Coding / Algorithms

Approach

  1. Confirm the node shape and whether to return the new head; mention the edge cases up front: empty list and single node both return the input unchanged.
  2. Iterative solution with three pointers: prev = null, curr = head; loop while curr is not null: next = curr.next; curr.next = prev; prev = curr; curr = next. Return prev.
  3. Complexity: O(n) time, O(1) extra space. Saving next before overwriting curr.next is the step that is easiest to get wrong; losing it cuts off the rest of the list.
  4. Recursive alternative: reverse the rest, then head.next.next = head and head.next = null. Also O(n) time, but O(n) stack space, so a very long list can overflow the call stack in Java, C# or Python (default recursion limit 1000).
  5. Trace a three-node list on paper, and write a quick test for null, one node and two nodes.

Follow-up

  • Reverse the list in groups of k nodes.
  • Reverse only the nodes between positions m and n.
  • How does the solution change for a doubly linked list?

Discuss how you would approach a project with ambiguous requirements.

Medium · Problem-Solving / Case Studies

Approach

  1. Name the unknowns explicitly: who the users are, what problem they have, what success looks like, and which constraints are fixed (deadline, data sources, platform).
  2. Write your assumptions down and confirm them with the person who owns the outcome; turn the answers into acceptance criteria you can test.
  3. Build a thin end-to-end slice or prototype early so stakeholders react to something concrete; feedback on a working demo resolves ambiguity faster than another meeting.
  4. Design for the parts most likely to change: keep them behind interfaces or configuration, and keep a short decision log so later changes do not reopen settled questions.
  5. Give a real example in first person: what was unclear, which assumption you checked, and what you built differently because of the answer.

Follow-up

  • What do you do when two stakeholders give conflicting answers?
  • How do you decide when you know enough to start building?
  • How do you handle a requirement that changes late in the project?

Denormalise tenant onto revisions and backfill it live

Hard · denormalisation · online migration · backfill

resource_revision (revision_id, resource_id, version, actor_user_id, change_kind, patch, request_id, created_at) has 400M rows and no tenant column; tenant_id lives only on resource. Two reads need it: a tenant-scoped audit feed ordered by created_at DESC, and an offboarding purge. Both join back to resource today. Justify adding tenant_id to resource_revision against those two reads, name the anomaly the copy introduces and the constraint that prevents it, then give the ordered migration for a live table taking 1.2k writes/second — the lock each step takes, how the backfill is batched, and where each step stops being reversible. PostgreSQL 16.

Approach

  1. Justify from the access path rather than from taste. Without the column, the audit feed either scans resource_revision by created_at and discards other tenants' rows, or resolves the tenant's resource_ids first and probes with them — both proportional to the tenant's whole history rather than to one page. With (tenant_id, created_at DESC, revision_id DESC) it is a seek that stops at 50 rows, and the purge becomes a ranged delete instead of a join.
  2. Name the cost exactly: a second copy of a fact can disagree with the first. Make the disagreement unwritable rather than documented — add UNIQUE (resource_id, tenant_id) on resource so it can serve as a foreign-key target, then FOREIGN KEY (resource_id, tenant_id) REFERENCES resource (resource_id, tenant_id) on the revision table. A revision can then only ever carry its parent's tenant.
  3. Step one, expand: ALTER TABLE resource_revision ADD COLUMN tenant_id BIGINT NULL, with no default, so it is a catalogue change and no rewrite. It still needs ACCESS EXCLUSIVE for an instant, and that instant queues behind the longest open transaction on the table while every later query queues behind it — set lock_timeout to 2s and retry rather than wait.
  4. Step two, dual-write: deploy the writer that populates tenant_id on every new revision while reads still use the join. Reversible by redeploying the previous build, because nothing reads the column yet.

Follow-up

  • The backfill is half finished and a rollback is required. What state is the table in, and what does the previous build do with a half-populated column?
  • How do you verify the backfill actually finished, given rows are still being inserted while it runs?

Keep soft-deleted accounts from blocking re-registration

Easy · soft delete · unique constraints · engine differences

app_user holds user_id, tenant_id, email CITEXT, password_hash (NULL for SSO principals), email_verified_at, auth_version, status ('invited','active','suspended','deactivated'), created_at, updated_at, deleted_at. Two live accounts for one address inside a tenant must be impossible, but an address freed by a soft delete must be reusable, and the same tenant may delete and re-register it repeatedly. Write the uniqueness DDL for PostgreSQL 16, then the equivalent for MySQL 8 where partial indexes do not exist, and say what each permits once three deleted rows already hold that address.

Approach

  1. Start from what is actually unique: not (tenant_id, email), but (tenant_id, email) among live rows. PostgreSQL says that directly — CREATE UNIQUE INDEX app_user_live_email ON app_user (tenant_id, email) WHERE deleted_at IS NULL. A full constraint over the same two columns burns the address permanently the first time someone deletes an account.
  2. Keep case-insensitivity in the type or the index, never in the application: CITEXT as given, or UNIQUE (tenant_id, lower(email)) as an expression index where the extension is unavailable. A case-sensitive unique column is exactly how two accounts for one human appear.
  3. For MySQL 8 the predicate has to move inside the key: add a discriminator column that is a constant 0 while the row is live and is set to user_id on delete, with UNIQUE (tenant_id, email, deleted_marker). Live rows share the constant and still collide; deleted rows differ from each other and stop colliding.
  4. State the NULL variant and its dependency: leaving the marker NULL for deleted rows also works, because a unique index treats NULLs as distinct — true in MySQL, and true in PostgreSQL only under the default NULLS DISTINCT, which PostgreSQL 15 lets you reverse. Check the polarity against the three existing deleted rows: constant-on-live is what preserves the collision you want, and reversing it silently admits duplicate live accounts.

Follow-up

  • A deleted account re-registers with the same address the next day. Do the old resource rows follow the new user_id, and how does the API keep the two principals apart?
  • How do you honour an erasure request while resource_revision.actor_user_id still references this table?

What programming languages are you most proficient in, and how have you applied them in your projects?

Medium · Technical / Domain Questions

Approach

  1. Lead with one primary language, ideally one the role lists (Java, C# or Python), and name the project, your part in it and what the code had to do. A long list of languages with no project attached says nothing.
  2. Show depth with one detail specific to that language: Java generics use type erasure, so List<String> and List<Integer> are the same class at runtime; in C#, deferred LINQ operators such as Where and Select run only when enumerated, while ToList, Count, First and similar operators execute immediately; in standard CPython builds the GIL stops threads from running CPU-bound Python code in parallel, so I would use multiprocessing for that work.
  3. Tie the language choice to a trade-off you actually hit, for example: 'I moved a CPU-heavy parsing step from Python threads to a process pool because threads gave no speed-up.'
  4. Close with a second language and how you work in it, including how quickly you get productive (tooling, tests, reading the standard library), without claiming expert depth you cannot defend.

Follow-up

  • What is a feature of that language you would avoid in production code, and why?
  • How does memory management differ between the two languages you named?
  • Which part of that project would you write in a different language today?

Can you explain the differences between various data structures and when to use them?

Medium · Technical / Domain Questions

Approach

  1. Organise the answer by access pattern, not by a list of names: index lookup, membership test, ordered traversal, min/max retrieval, insertion in the middle.
  2. Arrays and dynamic arrays: O(1) index access, amortised O(1) append, O(n) middle insert, good cache locality. Linked lists: O(n) to reach a position and poor locality; O(1) insert after a held node, but O(1) delete needs a doubly linked list or a pointer to the predecessor. In a singly linked list, deleting a held node takes O(n) to find its predecessor, unless you copy the next node's value into it, which fails on the tail.
  3. Hash maps and sets: O(1) average lookup and insert, O(n) worst case under heavy collisions, no ordering. Balanced BSTs (TreeMap, SortedDictionary): O(log n) operations with sorted iteration and range queries.
  4. Heaps: O(1) peek and O(log n) push/pop for top-k and scheduling. Stacks for undo and DFS, queues for BFS. Graphs as adjacency lists (O(V+E) space) for sparse graphs, matrices (O(V^2)) for dense ones.
  5. For a data-management role, add B-trees: shallow and wide, so a lookup on disk reads few pages and supports range scans, which is why most database indexes use them.

Follow-up

  • Why can a linked list lose to an array for middle insertions in practice, despite the better big-O?
  • How would you build an LRU cache with O(1) get and put?
  • When would you pick a sorted structure over a hash map even though lookups are slower?

Describe a complex technical problem you faced and how you resolved it.

Medium · Technical / Domain Questions

Approach

  1. Pick a problem that was technical at its core (a race condition, a slow query, a memory leak, a data inconsistency) where you did the diagnosis yourself, and say plainly what was broken and who it affected.
  2. Walk the reasoning in order: the symptom, the hypotheses you considered, the evidence that ruled each in or out (logs, profiler output, a minimal reproduction), and the root cause.
  3. Explain the fix and the alternative you rejected, with the trade-off: 'I added a unique constraint instead of an application-level check because two writers could pass the check at the same time.'
  4. Give a measurable result (latency before and after, error count, data repaired) and what you put in place so it cannot recur: a test, an alert, a runbook entry.
  5. The mistake that sinks this answer is a team story told with 'the team' throughout; keep your own decisions visible.

Follow-up

  • What was the hypothesis you were most confident in that turned out wrong?
  • How did you confirm the fix worked rather than the problem going quiet?
  • What would you do in the first hour if the same symptom came back?

What are the principles of object-oriented programming?

Medium · Technical / Domain Questions

Approach

  1. Name the four principles with a one-line definition and a small example each: encapsulation (private state behind methods that keep invariants, e.g. a BankAccount that rejects negative balances), abstraction (callers depend on an interface, not the implementation), inheritance (a subclass reuses and extends a base class), polymorphism (one call, different behaviour by runtime type).
  2. Separate the two kinds of polymorphism: overloading is resolved at compile time from the parameter types; overriding is resolved at runtime by the object's actual type. In Java, non-static, non-private, non-final methods are virtual by default; in C# a method must be marked virtual and override explicitly.
  3. Say when inheritance hurts and composition helps: deep hierarchies couple subclasses to base-class internals. The Square-extends-Rectangle example breaks the Liskov substitution principle because setting the width changes the height.
  4. Contrast interfaces and abstract classes: an abstract class can hold state and constructors and allows single inheritance only; a class can implement many interfaces. Mention SOLID briefly if time allows.

Follow-up

  • When would you choose an abstract class over an interface?
  • How is a virtual method call dispatched at runtime?
  • Show me a design where you replaced inheritance with composition.

How do you ensure the quality and maintainability of your code?

Medium · Technical / Domain Questions

Approach

  1. Answer with practices you actually use and one example of each, not a list of slogans: automated tests, code review, static checks, and design that keeps change cheap.
  2. Testing: mostly fast unit tests on business logic, fewer integration tests at the boundaries (database, external APIs), and a regression test for every bug fixed. Run them in CI so a failing test blocks the merge.
  3. Static checks: a formatter and linter in CI, type checking where the language allows it (mypy for Python, nullable reference types in C#), so reviewers spend time on design rather than style.
  4. Maintainability: small functions with one job, names that state intent, dependencies passed in so they can be replaced in tests, and refactoring done under test coverage in separate commits from behaviour changes.
  5. Give one measured example: 'After I added contract tests for the ingestion API, schema-breaking changes were caught in CI instead of in staging.'

Follow-up

  • How do you add tests to legacy code that has none?
  • How do you decide what not to test?
  • What do you do when a deadline pushes against your quality bar?

Provide a solution for a hypothetical scenario involving system performance issues.

Medium · Problem-Solving / Case Studies

Approach

  1. Define the symptom as a metric before touching anything: which endpoint or job, p50 versus p99 latency, throughput, error rate, when it started, and what changed then (deploy, data volume, traffic pattern).
  2. Check resources systematically (utilisation, saturation and errors for CPU, memory, disk and network) to tell CPU-bound from I/O-bound or lock-bound work.
  3. Profile the hot path. For database-backed systems, check slow query logs and query plans (EXPLAIN, or EXPLAIN ANALYZE in PostgreSQL) for full table scans, missing indexes and N+1 query patterns; check connection-pool exhaustion and lock waits.
  4. Apply the fix that matches the cause: an index, batching, caching hot reads with an invalidation plan, async processing for slow side work, or horizontal scaling once the code path is efficient. Little's law (concurrency = throughput x latency) helps size pools and workers.
  5. Verify with the same metric before and after, under a load test that resembles real traffic, and add an alert so a regression is caught early.

Follow-up

  • p50 latency is fine but p99 is bad: what are the likely causes?
  • CPU is low but requests are slow: where do you look next?
  • How would you add a cache without serving stale data?

How do you gather requirements and ensure stakeholder satisfaction?

Medium · Problem-Solving / Case Studies

Approach

  1. Identify every stakeholder group (users, product, operations, support) and what each needs; one sponsor's view is rarely the whole requirement.
  2. Separate functional requirements from non-functional ones (latency, data volume, availability, security, compliance) and ask for numbers, not adjectives.
  3. Write requirements as user stories or use cases with acceptance criteria, prioritise them (for example must, should, could, won't), and get written confirmation before building.
  4. Keep stakeholders in the loop with early demos and a visible backlog; record changes and their effect on scope or dates so trade-offs are explicit.
  5. Measure satisfaction against the agreed criteria after delivery (adoption, defect reports, the metric the project was meant to move), and give one example where this caught a misunderstanding early.

Follow-up

  • How do you handle a stakeholder who keeps adding scope?
  • What do you do when a requirement is technically infeasible as stated?
  • How do you know a stakeholder is actually satisfied, beyond them saying so?

Design a scalable system for handling real-time data ingestion.

Medium · System Design / Architecture

Approach

  1. Pin down requirements first: events per second at peak, event size, end-to-end latency target, ordering needs, whether loss or duplicates are acceptable, retention, and who queries the data.
  2. Outline the pipeline: producers send to a stateless, load-balanced ingest API that validates against a schema, then appends to a durable partitioned log (Kafka or a managed equivalent). Stream processors read from it, and results go to the serving store (for example a columnar analytics store), with raw events also kept in object storage for replay.
  3. Partition by a key that needs ordering (device or account id): order is guaranteed only within a partition, and in a consumer group each partition goes to one consumer, so partition count caps parallelism. Watch for hot keys.
  4. Delivery semantics: at-least-once with idempotent writes (dedupe on event id) is the usual choice; exactly-once costs extra coordination. Handle late events with event-time windows and watermarks, and send malformed records to a dead-letter queue.
  5. Operate it: monitor consumer lag, apply backpressure or rate limits at ingest, autoscale consumers, and attach source and processing-version metadata to records so lineage and reprocessing are possible.

Follow-up

  • One customer sends 50 times more events than the rest: what breaks and how do you fix it?
  • The downstream store is down for an hour: what happens to the data?
  • How do you roll out a schema change without breaking consumers?

How would you approach database design for a new application?

Medium · System Design / Architecture

Approach

  1. Start from the access patterns: the main reads and writes, their frequency, data volume and growth, and consistency needs. This decides most later choices, including relational versus another model.
  2. Model entities and relationships, normalise to roughly third normal form to avoid update anomalies, pick primary keys (surrogate versus natural), and enforce rules in the database with foreign keys, unique, NOT NULL and CHECK constraints.
  3. Index for the actual queries: a composite B-tree index on (a, b) is most useful for filters on a, or on a and b; a filter on b alone usually cannot use it efficiently. Every index also slows writes and uses storage.
  4. Denormalise only for a measured read bottleneck, and say how the copy stays consistent. Separate OLTP from analytics: row stores suit transactions, columnar stores suit large scans and aggregations.
  5. Plan for change: versioned migrations, additive changes first (add a nullable column, backfill, then enforce), and the transaction isolation level the critical operations need.

Follow-up

  • When would you denormalise, and how do you keep the copies consistent?
  • How would you add a non-null column to a large table that is serving live traffic?
  • When would you choose a document or key-value store over a relational database?

Discuss the trade-offs between different architectural patterns (e.g., microservices vs. monolith).

Medium · System Design / Architecture

Approach

  1. Define both: a monolith is one deployable unit, usually with one database; microservices are independently deployable services, each owning its data and talking over the network.
  2. Monolith strengths: in-process calls, single ACID transactions, simpler debugging and deployment. Costs: coupling grows with the codebase, the whole unit scales together, and every change ships with the whole release.
  3. Microservices strengths: independent deployment and scaling, fault isolation, team ownership by service. Costs: network latency and partial failure, no cross-service ACID transactions (sagas with compensating actions, transactional outbox), eventual consistency, and the need for distributed tracing, service discovery and more operations work.
  4. Name the middle ground and how to move between them: a modular monolith with enforced boundaries, then extracting services along bounded contexts using the strangler fig pattern when a module needs independent scaling or release cadence.
  5. Make the decision depend on context, team size, domain stability and scaling profile, and mention other patterns where they fit (event-driven, layered, serverless).

Follow-up

  • How would you keep an operation that spans two services consistent?
  • Which part of a monolith would you extract first, and how would you decide?
  • When is moving to microservices the wrong call?

How would you approach debugging a piece of code that is not functioning as intended?

Medium · Coding / Algorithms

Approach

  1. Reproduce first: get a reliable failing case and shrink it to the smallest input that still fails. Write down expected versus actual behaviour exactly.
  2. Read the evidence before guessing: the full error message and stack trace, recent changes to that code path, and the logs around the failure.
  3. Form one hypothesis at a time and test it by checking state at boundaries: breakpoints or logging of inputs and outputs, halving the code path until the wrong value first appears.
  4. If it worked before, bisect history: git bisect finds the breaking commit in about log2(n) test runs across n commits.
  5. Fix the root cause rather than the symptom, add a regression test that fails without the fix, and check whether the same mistake exists elsewhere.

Follow-up

  • How would you debug something that fails only in production and never locally?
  • How do you approach an intermittent failure, such as a suspected race condition?
  • How do you know you found the cause and not a coincidence?

Suggested practice checklist

The plan follows the three reported stages and the reported question groups: language and fundamentals first, then coding and debugging, then design, SQL and data lineage, then ambiguity and behavioral stories, ending in a full mock.

Day 1 — Map the loop and choose your language

  • Write out the three reported stages (Initial Screening, Technical Interviews, Behavioral Assessments) and what each seems to cover.
  • Choose Java, C# or Python as your single interview language and write a short answer about your proficiency with one project and one design decision.
  • List the gaps between your resume and the requirements candidates describe (algorithms, data structures, Agile and Scrum, cloud, SQL) and rank them.

Deliverable: A one-page loop map, a written answer for the languages question, and a ranked gap list.

Day 2 — Data structures and object-oriented principles

  • Build a table of array, linked list, hash map, stack, queue, heap and balanced tree with access, insert and delete costs and one use case each.
  • Explain encapsulation, abstraction, inheritance and polymorphism aloud, each with a short example in your chosen language.
  • Add one sentence per structure on when you would not use it.

Deliverable: The completed comparison table and spoken answers to the data-structure and object-oriented questions.

Day 3 — Linked list and algorithm coding with complexity

  • Write reverse-a-linked-list iteratively, then recursively, and test the empty, one-node and long cases.
  • Solve four problems from different families (array or string, hash map, stack or queue, tree) in your language and state time and space complexity for each.
  • Practice the open algorithm prompt by picking a problem at random, restating inputs and outlining brute force before optimizing.
  • C++ track, if the team works in C or C++: review manual memory management against RAII (destructors, unique_ptr), pointers versus references, move semantics, std::vector versus std::list, and the undefined behaviour of reading node->next after deleting or overwriting it while reversing a linked list.

Deliverable: Working linked-list reversal in two forms plus four solved problems, each with a written complexity line, and C++ notes if that track applies.

Day 4 — Narration, debugging and code quality

  • Solve one problem while speaking continuously: restate, outline, code, test, then give complexity.
  • Take a short function with a seeded bug and debug it as a sequence: reproduce, narrow the input, inspect state, test one hypothesis, fix, add a test.
  • Write your answer on code quality and maintainability: naming, small functions, tests, code review habits, with one example from your own code.

Deliverable: A recorded or written narrated solution, a debugging log for the seeded bug, and a code-quality answer.

Day 5 — System design, SQL and data lineage

  • Sketch a real-time data ingestion system: producers, buffer or queue, consumers, storage, ordering, duplicate handling and failure behavior; then design a schema for a small new application from its queries and argue microservices versus a monolith for it.
  • Write SQL against that schema: joins, GROUP BY with HAVING, window functions (ROW_NUMBER, running totals), and read the query plan for one slow query.
  • Model data lineage as a DAG of datasets and jobs: downstream BFS/DFS for impact analysis, upstream traversal for root cause, topological sort for recompute order. Compare table-level and column-level lineage, and note how lineage is captured from SQL parsing or job metadata.
  • Code the lineage traversal: given job edges, list every dataset affected by one bad input and the order to recompute them.

Deliverable: An ingestion diagram, a schema with indexes and SQL queries, an architecture trade-off paragraph, a lineage traversal in code, and the two SQL practice questions attempted.

Day 6 — Ambiguity, performance cases and stakeholders

  • Write how you would start a project with ambiguous requirements: questions to ask, assumptions to record, a first small deliverable.
  • Outline a response to a system performance scenario: measure first, find the bottleneck, change one thing, measure again.
  • Prepare your complex-technical-problem story and your requirements-gathering answer with a stakeholder example.

Deliverable: A written ambiguity plan, a performance-diagnosis outline, and two prepared stories.

Day 7 — Behavioral stories and full mock

  • Write STAR outlines for the difficult team member, taking the lead, failure and prioritization prompts, each with a measurable result.
  • Prepare a spoken answer on what motivates you with two examples.
  • Run a full mock: one coding problem, one design question, then three behavioral prompts, answered aloud.

Deliverable: Four STAR outlines, a motivation answer and notes from the mock listing what to fix.

Behavioral stories for the Actian loop

Candidates describe the final stage as Behavioral Assessments, aimed at collaboration and communication. For a software engineer these stories should show how you handle conflict, competing work, ownership and setbacks in real projects. All six prompts below are reported: the five behavioral questions come first, followed by a related prompt on ambiguous requirements.

  1. Discuss how you would approach a project with ambiguous requirements.

Describe a time when you had to work with a difficult team member. How did you handle it?

Medium · Behavioral / Leadership

Approach

  1. Choose a disagreement about the work, such as review standards, an interface contract or missed handoffs, not a personality clash. State in a sentence or two what the behavior was and what it cost the project.
  2. Show that you went to the person first: you asked what constraint or pressure sat behind their behavior and listened before proposing anything.
  3. Describe the concrete action that changed things, for example an agreed review checklist, a written interface, a shorter feedback loop or a shared task board, and say why you chose it.
  4. Escalate only if direct conversation failed, and say how you framed it (impact on delivery, not criticism of the person). Close with the outcome and the working relationship afterward.
  5. The story fails when the other person is only a villain, when you went to a manager first, or when nothing changed. Name your own part in the friction.

Follow-up

  • What would you have done if they had not changed after that conversation?
  • At what point would you have involved your manager, and what would you have said?
  • What did that experience teach you about how you give feedback?

How do you prioritize tasks when working on multiple projects?

Medium · Behavioral / Leadership

Approach

  1. Anchor the answer in one real situation with at least two competing commitments, then walk through how you sorted them: deadline, impact on users or teammates, dependencies on others, and the cost of delaying each.
  2. Say that you make the list visible: write down everything in flight, estimate each item, and check that your ordering matches what your manager and stakeholders believe is most important.
  3. Show the conversation, not just the ordering. Describe telling a stakeholder that something would slip, offering a smaller scope or a later date, and agreeing on it.
  4. Cover interruptions such as a production bug: how you decide whether it displaces planned work and how you re-plan afterward.
  5. A weak answer is a framework name with no example, or a claim that you simply work longer hours. Finish with what shipped and what you deliberately deferred.

Follow-up

  • Two managers each tell you their request is the urgent one. What do you do?
  • Tell me about a time you prioritized wrongly. What did you change?
  • How do you handle a production issue landing in the middle of planned work?

Tell me about a time when you took the lead on a project. What was the outcome?

Medium · Behavioral / Leadership

Approach

  1. Pick a project where you held no formal title but set direction: you broke the work into pieces, assigned or claimed them, and kept the plan current. Say plainly how the project started and what the goal was.
  2. Show leadership actions rather than project facts: a decision you made when the team disagreed, a blocker you removed for someone, a status update you sent so stakeholders were not surprised.
  3. Be precise about what you did and what teammates did. Use I for your decisions and name others' contributions, because inflating your role is easy to spot in follow-up questions.
  4. Give the outcome with something checkable, such as shipped on a date, defect count, latency or adoption, plus what was missed. Close with one thing you would run differently.

Follow-up

  • How did you handle someone on the team who disagreed with your plan?
  • What did you delegate, and what did you keep for yourself?
  • How did you know the project was on track, and what did you do when it was not?

How do you handle failure or setbacks in your work?

Medium · Behavioral / Leadership

Approach

  1. Choose a real setback in which you had a hand, such as a bug that reached production, a badly missed estimate or a design that did not hold up. A setback with no personal responsibility reads as evasion.
  2. Describe the immediate response in order: contain the damage, tell the people affected, then find the cause. Keep the root cause technical or procedural rather than blaming a person.
  3. Name the lasting change you made: a regression test, a review checklist item, an alert, a revised estimation habit. Say how you confirmed it worked, for example that the same class of failure did not recur.
  4. Avoid the disguised strength ("I work too hard") and the story that ends at the apology. A good ending shows what you do differently now.

Follow-up

  • What was the most damaging part of that mistake, and who felt it?
  • How did you tell your manager or the team, and how soon?
  • What would you check now before shipping something similar?

What motivates you to succeed in your role?

Medium · Behavioral / Leadership

Approach

  1. This prompt asks for drivers, not a single event. Name two specific ones, such as fixing a hard performance problem, seeing users rely on something you built, or helping a teammate get unblocked, instead of a general phrase like passion for technology.
  2. Back each driver with a short example from your work that shows the motivation in action, so the answer is evidence rather than a claim.
  3. Connect them to what candidates describe for this role: building and maintaining software, working with product managers, designers and engineers, code reviews and troubleshooting. Do not state what the company values; say what you would enjoy doing there.
  4. Be ready to say honestly what drains you and how you handle it, since a motivation answer with no limits sounds rehearsed.

Follow-up

  • What kind of work would drain your motivation, and how have you dealt with it?
  • How do you stay engaged on repetitive or maintenance tasks?
  • Tell me about a project where your motivation dropped and what you did about it.