Acko General Insurance · Software Engineer
Updated · 2026-10-02

Acko General Insurance Software Engineer
Interview Guide

THE 60-SECOND BRIEF

Acko General Insurance is an insurer. Candidates describe a business built around digital flows where customers buy policies and file claims, with engineering sitting between older insurance processes and user-facing software. The Software Engineer role covers backend services and core platform functionality on a cloud-native footing. Candidates list REST APIs as the interface style, and AWS, distributed systems and microservices as nice-to-have experience. The reported interview questions use an expense-sharing app as the vehicle rather than an insurance scenario, so the domain you need is money, groups and balances rather than policies.

This guide is for candidates interviewing for a Software Engineer role at Acko General Insurance. It covers the machine coding and design topic that candidates report: designing a Splitwise-like system, handling concurrent expense updates, shaping a schema for group balances and individual debts, keeping code maintainable when features such as currency conversion arrive, and weighing an in-memory store against a relational database. It does not cover rounds that nobody has reported.

No round-by-round sequence is reported. Candidates describe a lean process in which machine coding is the central component, and the five reported questions all sit under machine coding and system design.

Machine CodingRequirements GatheringSplitwise-like Application Core Functionalities

27 min read

Browse Software Engineer questions

See the practice prompts

11Practice promptsAcross five skill areas

Every reported question for this loop circles one system: a Splitwise-like expense-sharing application. The questions ask you to design its core functionality, handle concurrent expense updates, shape a schema for group balances and individual debts, keep the code maintainable when currency conversion is added, and compare an in-memory store with a relational database. Candidates also report two concrete scenarios: an expense-sharing application with equal, exact and percentage-based splits, and the API endpoints a user would call to see their total outstanding balance. That makes this a loop where one well-prepared domain pays off many times.

Preparation therefore starts with the money model. Represent amounts in integer minor units, decide where the leftover cent goes when 100.00 is split three ways, and reject exact splits that do not add up to the total or percentages that do not add up to 100. Then derive balances: a net figure per user per group, built from an append-only list of expenses and settlements, plus a way to reduce who owes whom into few transfers. Once that core runs in your chosen language, the remaining questions become variations on it: what happens when two people edit the same group at once, what the tables look like, and which parts change when a second currency appears.

Candidates describe the process as lean, with machine coding as the central piece, and the role requirements they cite name Java, Python or Go as example object-oriented languages, plus clean, testable code and RESTful API experience. Tips that circulate among candidates are to clarify requirements at the start, talk through your reasoning, design for extension, mention scale briefly and favour readable code. Since no round order is reported, ask your recruiter whether you will write and run code, in which language, and in what environment, and then rehearse that exact setup.

01

Preparation focus

editorial

No named rounds are reported for this role. What candidates do report is a lean process in which machine coding carries the most weight, with questions grouped under machine coding and system design. Expect to turn a loosely stated requirement, such as a Splitwise-like application with equal, exact and percentage-based splits, into classes, interfaces and working logic, then defend the design: how balances are computed, how concurrent edits are handled, which storage you would pick and how a new feature such as currency conversion would fit. Approach it by clarifying requirements first, getting a small end-to-end path running before adding features, and keeping the split logic behind an interface so it can be extended. Ask the recruiter whether code must run, which languages are allowed and how the stages are ordered.

What to demonstrate

  • A working, readable solution in an object-oriented language, with sensible class and interface boundaries
  • Whether you pin down requirements and edge cases, such as split validation and rounding, before writing code
  • How you reason about shared state, storage and extension when the design is pushed past the first version

How to prepare

  • Build the Splitwise-style core from a blank file: users, groups, expenses, equal/exact/percentage splits and a per-user balance view, with unit tests
  • Write the schema for group balances and individual debts, then the query that returns one user's net balance
  • Practise the concurrent-update answer for the expense-editing path, naming the shared state and the lock or version check you would use
  • Prepare a short script of requirement questions and a verbal outline of the in-memory versus relational trade-off
PracHub preparation framework ↗

PracHub editorial advice for the preparation topics above.

01

Using floating-point numbers for money, so a 100.00 expense split three ways loses or invents a cent

Store amounts as integer minor units, give the leftover units to specific participants by a stated rule, and assert in a test that the shares always sum to the original total. For percentage splits, reject inputs that do not total 100.

02

Starting to code the Splitwise-like application before settling what it must do

Spend the opening minutes asking: must exact splits sum to the total, can a user be in several groups, are settlements recorded, is there more than one currency, who can edit an expense. State your assumptions out loud and build only what they require.

03

Hard-wiring split types into one method with if/else branches, so currency conversion or a fourth split type means editing the core

Put each split type behind a common interface with its own validation, wrap amounts in a Money type that carries a currency, and hide exchange rates behind a small provider interface. Be ready to point at the exact seam where a new feature plugs in.

04

Answering the concurrent-update question with only "use a lock"

Name the shared state (the group's expense list and balances), describe the lost-update case with two edits, then pick a mechanism: a per-group lock in process, or a version column or row lock in a database. Add idempotency keys for retried requests, and say how you would test it.

05

Treating the in-memory versus relational comparison as one-sided, either "memory is faster" or "SQL is safer"

Compare on durability across restarts, constraints and transactions, query flexibility, behaviour with more than one app instance, and memory limits. Conclude with a recommendation tied to the requirements, and note that a repository interface lets you start in memory and move later.

Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.

8 technical prompts0 include a worked solution

How would you handle concurrent expense updates in a multi-user environment?

medium
Machine Coding and System Design

How would you handle concurrent expense updates in a multi-user environment?

Approach
  1. Name the race first. Two requests read the same balance, each adds its own delta and writes it back, so one update is lost. The same thing happens when two users edit one expense at the same moment.
  2. For edits to one expense, use optimistic locking with a version column: UPDATE expense SET ..., version = version + 1 WHERE id = ? AND version = ?. If zero rows are affected, someone else won, so reload and either retry or return a 409 to the client.
  3. For balances, write the expense, its splits and the balance deltas in one transaction. Use an atomic UPDATE balance SET amount = amount + ? (or SELECT ... FOR UPDATE) instead of read-modify-write in application code. Lock rows in a fixed order, such as by user id, so A-B and B-A updates cannot deadlock.
  4. Another option is an append-only ledger. Each expense inserts ledger rows and balances are derived with SUM, so concurrent inserts never overwrite each other. The cost is heavier reads, or a materialised balance kept in the same transaction.
  5. In an in-memory machine-coding version, guard each group's state with a lock from a ConcurrentHashMap (computeIfAbsent per group id), or use synchronized methods on the BalanceSheet. Attach an idempotency key to each add-expense request so a client retry does not double-charge.
Follow-up
  • When would you choose pessimistic locking over optimistic locking here, and what changes under heavy contention on one group?
  • A mobile client times out and resends the same expense. How do you make sure it is recorded only once?
  • How would you detect and recover from a deadlock between two balance updates?

Explain the trade-offs between using an in-memory data store versus a relational database for this application

medium
Machine Coding and System Design

Explain the trade-offs between using an in-memory data store versus a relational database for this application.

Approach
  1. An in-memory store (HashMaps in a machine-coding solution, or Redis) gives fast reads and writes and no schema to manage. A plain in-process map loses everything on restart and is not shared when the app runs as more than one instance.
  2. Redis can persist data through RDB snapshots or an append-only file, but each has a durability window depending on fsync settings. MULTI/EXEC does not roll back when one command fails, and Redis has no foreign keys or cross-row constraints.
  3. A relational database gives ACID transactions, so an expense, its splits and the balance changes commit together. It also gives foreign keys and constraints, and joins and aggregates for balance and history queries. The cost is higher latency per operation and schema migrations.
  4. For money owed between people, keep the relational database as the system of record. Cache derived data, such as per-user totals, in memory or Redis, and invalidate or update it after the database transaction commits.
  5. In the machine-coding round, put storage behind a repository interface and start with an in-memory implementation. Explain how a SQL-backed implementation would replace it without changing the services.
Follow-up
  • An expense is edited after its balance was cached. How do you keep the cache consistent with the database?
  • What happens to your in-memory version if the process crashes halfway through adding an expense?
  • At what point, if ever, would a document or key-value store be the right primary store for this app?

Archive a resource graph without breaking live references or recursing

medium
graph traversaltopological ordertenant 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
  1. 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.
  2. 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.
  3. 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.
  4. 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?

The plan builds one Splitwise-style solution over seven days, adding the pieces the reported questions ask about in turn: split logic, balances and API, schema, concurrency, then extensibility and storage trade-offs, ending in a full timed run.

Small steps. Visible outcomes.0 / 7 completed
ONE WEEK · YOUR PACE

Prepare, practise & reflect

One practical outcome each day. Spend longer where you need it.

0 / 7 done
01Confirm the format and write the requirements checklist
  • Write to your recruiter asking for the sequence of stages, whether you will write and run code, which languages are allowed and what tools you get
  • Write a requirements checklist for a Splitwise-like application covering users, groups, payer, equal/exact/percentage splits, balance views, settling up and currency
  • For each checklist item, write the assumption you would state aloud and one edge case it creates

Deliverable: A list of format questions for the recruiter and a one-page requirements checklist with your stated assumptions and edge cases.

Practice prompt ↗
02Model the domain and the split strategies
  • Define User, Group, Expense, Split and a Money type holding integer minor units and a currency
  • Implement equal, exact and percentage split strategies behind one interface, each validating its own input
  • Write tests for 100.00 split three ways, exact shares that miss the total and percentages that do not reach 100

Deliverable: A runnable module with three split strategies, a Money type and a passing test file covering rounding and invalid input.

Practice prompt ↗
03Balances, settlement and the API surface
  • Compute each user's net balance per group from an append-only list of expenses and settlements
  • Implement debt reduction with a max-heap of creditors and a max-heap of debtors, matching the largest of each, which gives at most n-1 transfers but not always the fewest
  • Sketch REST endpoints for adding an expense, listing group balances, viewing a user's total outstanding balance and recording a settlement, with request and response shapes

Deliverable: A balance service with tests, plus an endpoint list showing method, path, request body and response for each of the four operations.

Practice prompt ↗
04Schema for group balances and debts
  • Write tables for users, groups, group membership, expenses, expense splits and settlements, with keys, foreign keys and a check that split rows sum to the expense amount where practical
  • Write the query returning one user's net balance in a group, and decide whether balances are always derived or also cached
  • Do the PracHub window-function practice question to strengthen running totals and gaps in ordered data

Deliverable: DDL for the schema, the net-balance query, and a short written decision on derived versus cached balances.

Practice prompt ↗Practice prompt ↗
05Concurrent expense updates
  • List the shared state in your solution and write out the lost-update case where two users edit the same group
  • Add a per-group lock to the in-process version and write a multi-threaded test that fails without it and passes with it
  • Write the database-level answer: a version column with compare-and-set, SELECT ... FOR UPDATE on the group row, and an idempotency key for retried requests

Deliverable: A threaded test that reproduces the race and then passes, and a written comparison of in-process lock, optimistic version check and row lock.

Practice prompt ↗
06Extensibility and storage trade-offs
  • Add currency conversion to your Day 2 code through a rate-provider interface and count how many existing classes you had to change
  • Write a comparison of an in-memory store against a relational database for this application, covering durability, constraints, concurrency and scale-out
  • Answer both questions aloud, then listen back and cut anything that is not tied to the Splitwise requirements

Deliverable: A diff showing currency conversion added with minimal edits to the split strategies, and a one-page in-memory versus relational comparison with your recommendation.

Practice prompt ↗Practice prompt ↗
07Full timed run and behavioral rehearsal
  • Starting from a blank file and a time limit you set yourself, build the Splitwise-style core while asking your requirement questions aloud and explaining each class as you add it
  • Afterwards, answer the schema and concurrency questions out loud without notes
  • Practise the PracHub behavioral prompt on unblocking an engineer without taking the keyboard, then list your three weakest points

Deliverable: A working, tested solution from the timed run, a recording or notes of your spoken answers, and a list of three weak points to fix.

Practice prompt ↗Practice prompt ↗Practice prompt ↗Practice prompt ↗

Expand any day for tasks and deliverables. Your progress is saved on this device.

No behavioral round is reported for this role. Candidates do describe the work as writing code, taking part in code reviews, turning requirements from product managers into technical specifications and discussing trade-offs with senior engineers, so these prompts rehearse stories from that kind of work. Each story should name the decision you made, the alternatives you rejected and the outcome.

Estimate work you have never done and defend the range

hard
estimationbackfillsexpand-contract

You are asked to estimate a change you have never attempted: add a column to a 100-million-row table, populate it, move reads across, and drop the old shape. Give a range with the assumptions that generate it, including batch size, the signal your backfill throttles on, and wall-clock hours, and name the three unknowns that would move the number most. Then describe a real estimate you gave under comparable ignorance: how you expressed its uncertainty, what you committed to, and how wrong you turned out to be.

Approach
  1. Decompose into independently deployable steps before estimating anything: add the column nullable, write both shapes, backfill in batches, verify, move reads, stop writing the old shape, drop it. That is four deploys spread over days, and the calendar estimate is dominated by them rather than by the loop's runtime.
  2. Do the arithmetic aloud for the part that has arithmetic in it: batch size times number of batches times per-batch duration, at a write rate the primary can absorb alongside roughly 1.2k writes per second of production traffic. The loop is throttled by replication lag and lock waits, not by how fast it can issue statements.
  3. Price the schema step by its lock rather than its statement duration. In PostgreSQL an ALTER TABLE taking ACCESS EXCLUSIVE waits for every open transaction on that table while later queries queue behind it, so a millisecond change issued during a thirty-second analytics query stalls that table for thirty seconds. Adding a nullable column with a non-volatile default avoids a rewrite from version 11; a new index wants CREATE INDEX CONCURRENTLY, which cannot run inside a transaction block and leaves an invalid index behind if it fails.
  4. Express the answer as a range whose endpoints each trace to a stated assumption, then name the cheapest experiment that collapses it, which is almost always running one real batch against the real table and multiplying.
Follow-up
  • How do you verify the backfill genuinely finished, given rows written by production traffic while it ran?
  • Where does the backfill resume from after a worker is killed mid-batch, and what makes that resume point trustworthy?

Tell callers you do not own that their integration breaks

medium
deprecationcompatibilitystakeholders

A field in a write endpoint's response must change shape. You own the endpoint; you do not own the four internal callers or the outbound webhook consumers who read it. Describe a deprecation you were responsible for: what you shipped first, how you established who was actually reading the field, the window you gave and what set its length, what you did about the consumer who never moved, and how you decided removal was safe. Name the signal you used, not the announcement you sent.

Approach
  1. Establish the reader set empirically rather than from a wiki of owners: per-field usage counters keyed by principal, or access logs attributed to a consumer. State the blind spot of whichever you pick, since a consumer that reads the field only on a monthly job will not appear in a week of logs.
  2. Ship additive first. Populate the new field alongside the old one so no reader is forced to move, which is also what keeps a rolling deploy safe, because old and new instances answer the same requests at the same time and a rollback must still find the old shape present.
  3. Set the window from the slowest legitimate consumer's release cadence, not from your calendar, and decide separately what to do for a consumer with no release process at all, such as an external webhook endpoint you can only email.
  4. Convert silence into evidence before you rely on it: a short, low-traffic removal window that makes a still-dependent consumer fail visibly and loudly while you are watching, rather than at three in the morning after you have moved on.
Follow-up
  • How would you detect a consumer that reads the field only during a monthly export?
  • One caller refuses to move and has a commercial relationship behind it. What changes in your plan and what does not?

Unblock an engineer without taking the keyboard

easy
mentoringleasesat-least-once

A teammate has spent two days on a job handler that occasionally writes duplicate rows. They are certain the queue is delivering twice by mistake. You suspect a lease expiring under a slow handler, so the job is running concurrently with itself. Describe how you have unblocked someone in this position: what you asked before offering a hypothesis, what you showed them rather than told them, and what you left them owning. Then say what you would do if their theory turned out to be the right one.

Approach
  1. Ask before diagnosing, and ask for things answerable from data they already have: the attempt count on the job rows that produced duplicates, the handler's observed duration against its lease expiry, and whether the duplicate rows share a natural key that a unique constraint could have caught.
  2. Teach the shape rather than the answer. A lease cannot distinguish a dead worker from a slow one, so a handler that outruns its lease is running twice by design, and deploys deliver the other half by killing handlers mid-run on every rollout. Both of their candidate theories produce identical duplicate rows, which is why the evidence has to come from timings rather than from argument.
  3. Hand over a checklist they execute: a natural key on every write the handler performs so the second copy collides rather than appends, the record of intent written before any external effect, a lease heartbeat while running, and the metric that shows it working.
  4. Keep ownership with them deliberately. Pair on the first write, then step back; if you finish it yourself you have closed one ticket and left the same person stuck on the next redelivery.
Follow-up
  • How would you distinguish a genuine double-delivery from a lease expiry using only the data already stored?
  • Their handler calls an external endpoint before recording that it did. What do you tell them to change first?
  • 01

    Tell me about a time you turned a vague product requirement into a technical design. What did you ask first, and what did you leave out of version one?

  • 02

    Describe a code review in which you disagreed with a senior engineer about a trade-off. What did each side argue and how was it resolved?

  • 03

    Tell me about a design you built that had to absorb a feature nobody planned for. What made the change easy or hard?

  • 04

    Describe a bug involving two users or two processes changing the same data. How did you find it, and what did you change to prevent it?

PracHub preparation framework ↗
How much time should I spend practising machine coding?

Most of your preparation. Practise end-to-end problems where you define the classes yourself and implement the business rules from scratch, using the Splitwise-style application as your main exercise. Candidates share the advice to aim for a working, clean solution within 60 minutes; treat that as a personal target, not a confirmed round length. Rebuild the same system several times in different shapes so the structure comes quickly.

Acko General Insurance Software Engineer candidate reports ↗
How long does the hiring process take and how many rounds are there?

No round count or schedule is reported. Candidates describe the process as lean and quick to move between stages. Ask your recruiter for the list of stages, whether each involves writing code, and which language and environment you will use, then rehearse in that setup.

Acko General Insurance Software Engineer candidate reports ↗
What topics should I cover?

Candidates report machine coding and system design, with the questions all built around a Splitwise-like application: core functionality, concurrent expense updates, a schema for group balances and debts, maintainability as currency conversion is added, and in-memory versus relational storage. Also be fluent in data structures, algorithms, object-oriented design and building RESTful APIs, which are among the skills the requirements list.

Acko General Insurance Software Engineer candidate reports ↗
Which language should I use?

Candidates describe Java, Python or Go as example object-oriented languages for the role. Choose the one in which you can write classes, interfaces and unit tests fastest, and confirm with your recruiter that it is allowed. Whatever you pick, be able to show the strategy-style split logic and a concurrency test in it.

PracHub Software Engineer practice ↗
How should I start the machine coding problem?

Begin with questions, not code. Ask which split types exist, whether shares must sum to the total, how a user's total outstanding balance is defined, whether settlements and multiple currencies are in scope, and who can edit an expense. Candidates share the tip of spending the first few minutes on this. Say your assumptions aloud, build the smallest end-to-end path first, then add features.

PracHub Software Engineer practice ↗
Do I need SQL and database knowledge?

Yes, enough to design the schema for group balances and individual debts: tables for users, groups, expenses, splits and settlements, the keys that connect them, and a query that returns one user's net balance. Be ready to explain how a database handles two simultaneous edits, through transactions, row locks or a version column, and what you give up if you hold everything in memory.

PracHub Software Engineer practice ↗
Sources & methodology 3 sources ↗

No official company page is cited. Rounds and questions come from candidate reports and PracHub editorial material; each source shows the date it was read.