cswork / libraryOpen practice workspace

Interview guides · Acrisure

Acrisure Software Engineer Interview Guide

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

The 60-second brief

Candidate reports describe Acrisure as a business where technology and data analytics work side by side, and they say little about specific products. The Software Engineer role is described as building software that connects with other platforms and services for clients and partners, with project work spanning data analytics, cloud solutions and customer-facing applications. Day to day, reports list gathering requirements with cross-functional teams, designing and implementing features, writing and reviewing code, taking part in the whole delivery cycle from planning to deployment, and debugging applications to improve performance. Reports do not name teams or internal systems, so treat any team-specific detail as something to ask the recruiter.

This guide is for engineers preparing for the Acrisure Software Engineer loop. It covers the three reported stages (Recruiter Conversation, Technical Assessments, Behavioral Interviews), the technical and domain questions about Java, Kotlin, the JVM, microservices and cloud platforms, the short coding problems, the system design prompts, and the behavioral questions, plus a day-by-day plan that uses all of them.

Candidates report three stages over roughly three to five weeks: a Recruiter Conversation, Technical Assessments that include coding challenges and system design, and Behavioral Interviews. Details vary by team and role.

Focus areas

  • Java
  • Kotlin
  • JVM (Java Virtual Machine)

Overview

The role as candidates describe it is general-purpose backend-leaning product engineering: requirements work with product and operations colleagues, building features that integrate with other services, code review, testing, deployment and debugging. That spread means your project stories should cover more than writing code. Have at least one story each about a review you gave or received, a release you shipped, and a performance or reliability problem you tracked down.

The technology list is specific even though the process description is not. Must-have skills are Java and Kotlin with JVM ecosystem experience, cloud familiarity (AWS, Azure), microservices and data structures and algorithms. Nice-to-haves are React or Angular, MySQL or MongoDB, and DevOps practice with CI/CD pipelines. Be ready to compare Java and Kotlin with real consequences (null handling, data classes, coroutines versus threads, interoperability), to explain how heap memory and garbage collection work on the JVM, and to describe the cloud services you have actually used.

The reported question set splits cleanly. The coding questions are short classic problems: reverse a linked list, longest substring without repeating characters, a Fibonacci dynamic programming problem, binary search, and a simple REST endpoint in a language of your choice. The design questions are broad: a URL shortener, data storage for a growing e-commerce platform, scalability and performance of a web application, factors in microservices design, and redundancy and backup. Short problems reward fluency and edge-case care; broad design prompts reward a clear structure and stated trade-offs, so rehearse an outline you can reuse across all five.

Reports do not say which question appears in which stage, whether the technical stage is live or take-home, or which language you must use, so confirm those with the recruiter early and prepare every question type. The behavioral set covers a significant challenge, prioritizing across projects, teamwork, handling feedback and motivation; two prompts that sound technical (Java memory management, cloud platform experience) are filed alongside them in the reports, so prepare each as a concrete experience as well as a concept.

The Acrisure interview process

Candidates describe three stages. Reports do not tie individual questions to stages, so this guide matches each stage to the question types its reported format covers.

Recruiter Conversation

Candidates report that the loop opens with a conversation with a recruiter about the role and your background. Nothing further is reported about its content, so treat it as two jobs: giving a tight account of your experience, and collecting the facts about the later stages that reports leave open (format of the technical stage, language, who you will meet, team context).

What to demonstrate

  • How clearly you summarize your background and recent work
  • How your experience lines up with the stack the role lists: Java, Kotlin, the JVM, AWS or Azure, microservices
  • Whether your expectations and logistics fit the role

How to prepare

  • Write a two-minute walk through your career that names your Java or Kotlin projects, the services you integrated with and the cloud platform you used.
  • Take the must-have and nice-to-have skills the role lists and put one concrete project next to each; mark the gaps (for example Azure, React or MongoDB) and decide how you will describe them honestly.
  • Prepare questions about the next stages: whether the technical stage is live or take-home, whether you choose the coding language, and whether system design is part of it for your team.
  • Have your location, notice period and compensation expectations ready so logistics do not use up the conversation.

Technical Assessments

Candidates report this stage as coding challenges plus system design interviews. The reported coding problems are reversing a linked list, longest substring without repeating characters, a Fibonacci dynamic programming problem, binary search and a simple REST endpoint. The reported design prompts are a URL shortener, data storage for an e-commerce platform, scalability and performance in a web application, microservices design factors, and data redundancy and backup. Practise both kinds in the language you will actually use.

What to demonstrate

  • Working code for short algorithm problems, including edge cases
  • Data structure and algorithm choice with complexity stated
  • Architectural reasoning about microservices, storage, scaling and backup
  • Ability to explain your thinking while you work

How to prepare

  • Write the five coding problems from scratch in Java and in Kotlin, run them against empty, single-element and duplicate-heavy inputs, and state time and space complexity for each.
  • Build a REST endpoint end to end (route, request validation, status codes, error body) so the structure is automatic.
  • Rehearse a reusable design outline: requirements and scale, API, data model, read and write paths, caching, failure handling, backup and recovery, then apply it to the URL shortener and the e-commerce storage prompts.
  • Prepare a balanced answer on when microservices help and what they cost, since the same topic is reported as both a technical question and a design question.

Behavioral Interviews

Candidates report behavioral interviews, in the plural, aimed at teamwork and how you fit with the team. The reported prompts cover a significant challenge, prioritizing across several projects, working effectively in a team, handling feedback, and what motivates you. The role also involves working with product management, operations and other engineers, so stories involving non-engineering colleagues are useful.

What to demonstrate

  • How you describe your own contribution in a team setting
  • How you handle feedback and disagreement
  • How you prioritize competing work and communicate trade-offs
  • What drives you, as you describe it

How to prepare

  • Build a bank of four stories (a hard problem, a conflict or disagreement, a feedback moment, a prioritization decision) and write each with situation, your action, result and what you would change.
  • Rehearse each story out loud and cut it to a spoken length that leaves room for follow-up questions.
  • Tag each story with the reported question it answers best, and check that two of them involve product, operations or other non-engineering colleagues.
  • Practise the answers in first person singular; replace every unexplained "we" with what you personally decided or did.

Where candidates lose points

Answering Java versus Kotlin as a syntax list, and treating JVM memory management as "the garbage collector handles it"

Give differences with consequences: null safety, data classes, coroutines versus threads, Java interoperability, and when you would choose each. For memory, cover heap generations, a collector trade-off and how you would diagnose a leak with a heap dump.

Describing AWS or Azure experience as a list of service names

For each service you mention, state the problem it solved, the alternative you rejected and one outcome. If you know only one platform, say so and map the concepts to the other.

Coding the classic problems without edge cases: empty list, empty string, binary search midpoint overflow

Before coding, list three or four edge cases aloud, then trace your solution on them once written, and state time and space complexity for the final version.

Presenting microservices only as advantages, with no costs, or giving a system design with no failure handling

Pair each advantage (independent deployment, scaling a hot service separately) with its cost (network calls, distributed data consistency, harder debugging and observability) and say when a single service is the better start. In any design, add what happens when a dependency is down and how data is backed up and restored.

Telling behavioral stories in the team's voice, so your own decision never appears

Write each story with a sentence for the situation, then your decision and reasoning in first person, a checkable result and what you would change. Name what teammates did separately.

Questions & practice

Write a function to reverse a linked list.

Medium · Coding / Algorithms

Approach

  1. Iterative version with three references: prev = null, curr = head; in the loop save next = curr.next, set curr.next = prev, then advance prev = curr and curr = next; return prev as the new head.
  2. State the cost: O(n) time and O(1) extra space, each node visited once and relinked once.
  3. Mention the recursive version (reverse the rest, then head.next.next = head; head.next = null) and its O(n) call stack, which in Java risks StackOverflowError on long lists.
  4. Walk the edge cases aloud before running: empty list (return null), a single node, two nodes, and check that the old head ends up pointing to null so no cycle is left.

Follow-up

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

How would you find the longest substring without repeating characters?

Medium · Coding / Algorithms

Approach

  1. Name the brute force first: check every substring for duplicates, O(n^3), or O(n^2) when you grow each start with a set; then move to a sliding window.
  2. Sliding window with a map from character to its last index: for each right index, if the character was last seen at or after left, move left to lastIndex + 1; record the index; best = max(best, right - left + 1).
  3. Complexity: O(n) time, since each pointer only moves forward, and O(min(n, alphabet size)) space; an int[128] array replaces the map for ASCII input.
  4. Test cases: empty string gives 0, "bbbbb" gives 1, "pwwkew" gives 3 ("wke"), and "abba", which breaks code that lets left move backwards.
  5. Note that a Java char is a UTF-16 code unit, so input with surrogate pairs needs codePoints() if the question means real characters.

Follow-up

  • Return the substring itself, not only its length.
  • Find the longest substring with at most k distinct characters.
  • How would you handle the input as a stream you cannot store in full?

Solve a dynamic programming problem involving the Fibonacci sequence.

Medium · Coding / Algorithms

Approach

  1. Show why plain recursion fails: fib(n-1) + fib(n-2) recomputes the same subproblems and grows exponentially (about O(1.618^n) calls).
  2. Top-down memoization caches each value, giving O(n) time and O(n) space plus O(n) recursion depth; bottom-up tabulation removes the recursion.
  3. Since each value needs only the previous two, keep two variables: O(n) time, O(1) space. Name the two DP properties at work: overlapping subproblems and optimal substructure.
  4. Handle the edges: F(0) = 0, F(1) = 1, reject negative n, and note that F(93) overflows a Java long, so use BigInteger or return the value modulo a prime such as 1,000,000,007.
  5. For very large n, matrix exponentiation of [[1,1],[1,0]] or fast doubling computes F(n) in O(log n) multiplications.

Follow-up

  • How many ways can you climb n stairs taking 1 or 2 steps at a time, and why is that Fibonacci?
  • Compute F(n) mod m for n up to 10^18.
  • Change the problem to allow steps of 1, 2 or 3 with a cost per step: how does the recurrence change?

Implement a binary search algorithm in your preferred programming language.

Medium · Coding / Algorithms

Approach

  1. Precondition: the array is sorted. Keep a closed interval lo = 0, hi = n - 1, loop while lo <= hi, and compare the middle element to the target, moving lo = mid + 1 or hi = mid - 1.
  2. Compute mid as lo + (hi - lo) / 2 or (lo + hi) >>> 1 in Java, because lo + hi can overflow int on large arrays.
  3. Complexity: O(log n) time, O(1) space iteratively. State your loop invariant (if the target exists it lies in [lo, hi]) so the boundary updates are justified.
  4. Cover duplicates and misses: write the lower-bound variant (first index with a[i] >= target) and say what you return when absent. Java's Arrays.binarySearch returns -(insertion point) - 1 and makes no promise about which duplicate it finds.
  5. Test an empty array, a single element, a target below the minimum, a target above the maximum, and a run of equal values.

Follow-up

  • Find the first and last position of a target in an array with duplicates.
  • Search a sorted array that has been rotated at an unknown pivot.
  • Use binary search on the answer, for example the minimum ship capacity to deliver packages within D days.

Stop tag and share joins from fanning out a page

Medium · join fan-out · semi-joins · many-to-many

resource_tag is (resource_id, tag_id) with PK (resource_id, tag_id); resource_share is (resource_id, shared_with_user_id, permission). The tagged-and-shared listing inner-joins resource to both, filters tenant_id, tag_id = ANY($2) and shared_with_user_id = $3, orders by updated_at DESC and takes 50. Pages come back with fewer than 50 distinct resources and the total in the header is far too high. Explain the row multiplication, rewrite both the page query and the count query so each is correct, and name the index each one needs. PostgreSQL 16.

Approach

  1. Do the arithmetic against the predicates that are actually there. An inner join emits one row per matching child row, and both joins are filtered: tag_id = ANY($2) admits only the requested tags, shared_with_user_id = $3 admits one user's share rows. So a resource holding three of the requested tags and shared with $3 once yields three rows, not one — the multiplier is its count of matching tags times its share rows for that single user, and that second factor is 1 unless the table admits duplicate (resource_id, shared_with_user_id) pairs. LIMIT 50 then limits rows rather than resources, and COUNT(*) counts pairs — the header is the product, not the population.
  2. Reject DISTINCT as the fix. It deduplicates after the product has been built, so the planner must materialise and sort the fanned-out set before the LIMIT can apply, and it leaves any SUM or AVG in the same select list wrong.
  3. Rewrite both filters as semi-joins, keeping resource as the only row source: AND EXISTS (SELECT 1 FROM resource_tag rt WHERE rt.resource_id = r.resource_id AND rt.tag_id = ANY($2)) and the same shape against resource_share. A semi-join stops at the first match per resource and preserves the driving index order, so ORDER BY updated_at DESC, resource_id DESC LIMIT 50 still stops after 50 rows.
  4. Count with the same predicates and no join at all: SELECT count(*) FROM resource r WHERE r.tenant_id = $1 AND r.status = 'active' AND EXISTS (...) AND EXISTS (...). Nothing multiplies a resource, so the number is the population.

Follow-up

  • The filter changes from 'any of these tags' to 'all of these tags'. Rewrite it and state what it costs relative to the ANY form.
  • A resource can be shared with the same user twice under different permissions. Does your count change, and should it?

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

  1. 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.
  2. 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.
  3. 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.
  4. 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 Java and Kotlin.

Medium · Technical / Domain Questions

Approach

  1. Start from what the two share: both compile to JVM bytecode and call each other directly, so a codebase can mix the two file by file. Then group the differences instead of listing syntax.
  2. Null safety: Kotlin puts nullability in the type (String vs String?) and gives you ?., ?: and !!. Java values reaching Kotlin arrive as platform types (String!), so the compiler cannot check them unless the Java side carries @Nullable/@NonNull annotations.
  3. Boilerplate and modelling: data classes generate equals/hashCode/toString/copy/componentN (Java 16+ records cover part of this); classes are final unless marked open; val/var with type inference; smart casts after an is check; sealed classes with exhaustive when.
  4. Language features with no direct Java match: extension functions (resolved statically, not virtual), default and named arguments instead of overloads (@JvmOverloads for Java callers), companion objects instead of static members, and no checked exceptions.
  5. Concurrency: Kotlin coroutines are suspendable functions scheduled on dispatchers; Java's answer is threads, CompletableFuture and, since Java 21, virtual threads. Say which you have used and why.

Follow-up

  • What happens when Kotlin code calls a Java method that returns null for a type Kotlin treats as non-null?
  • How would you introduce Kotlin into an existing Java service without a rewrite?
  • How do coroutines differ from Java 21 virtual threads?

What are the advantages of using microservices architecture?

Medium · Technical / Domain Questions

Approach

  1. Name the advantages concretely: independent deployment per service, scaling only the hot component, fault isolation so one failing service does not take down the whole app, and clear ownership of a service by one team.
  2. Add technology freedom per service and smaller codebases that are faster to build and test, but say each benefit holds only if service boundaries follow business capabilities.
  3. Balance it with the costs a strong answer always states: network latency and partial failure on every call, no cross-service ACID transactions (sagas instead), harder debugging without distributed tracing, and more infrastructure to run.
  4. Say when you would not choose it: a small team or an unclear domain, where a modular monolith gives most of the separation without the operational cost.

Follow-up

  • How would you keep an order consistent when payment and inventory live in different services?
  • What is a distributed monolith, and how do you notice you have built one?
  • When would you merge two services back together?

Describe a challenging technical problem you solved in a previous project.

Medium · Technical / Domain Questions

Approach

  1. Pick one problem you personally diagnosed, with a measurable symptom (latency, error rate, memory growth, a failing batch) and state the impact in one or two sentences.
  2. Spend most of the answer on the diagnosis sequence: the hypotheses you held, the evidence you gathered (logs, metrics, profiler, heap or thread dumps, a reproduction) and which hypothesis the evidence ruled out.
  3. Explain the fix and at least one alternative you rejected, with the trade-off that decided it (risk, effort, performance, maintainability).
  4. Close with the outcome in numbers and what you added so it cannot recur silently: a regression test, an alert, a runbook or a design change.
  5. Use I for your own actions; the answer sinks when it describes what the team did and never shows a decision you made.

Follow-up

  • What alternative did you consider and why did you reject it?
  • How did you confirm that your change, and not something else, fixed the problem?
  • What would you do differently if you faced the same problem today?

Create a simple REST API endpoint using your language of choice.

Medium · Coding / Algorithms

Approach

  1. Pick a stack and a concrete resource, for example a Spring Boot @RestController (or Ktor in Kotlin) exposing GET /items/{id} and POST /items, and keep the controller thin over a service layer.
  2. Use HTTP semantics correctly: 200 for a read, 201 with a Location header for a create, 400 for validation errors, 404 for a missing id, 409 for a conflict; return a consistent error body from one handler (@ControllerAdvice in Spring).
  3. Separate request/response DTOs from the persistence entity and validate input at the edge (Bean Validation with @Valid), so internal fields never leak and bad input never reaches the service.
  4. Say which methods are idempotent: GET, PUT and DELETE are, POST is not, so a retry-safe create needs a client-supplied idempotency key stored with the result.
  5. Show how you would test it: a slice test with MockMvc or @WebMvcTest for status codes and payloads, plus a unit test for the service logic.

Follow-up

  • How would you add pagination to a list endpoint, and why might you prefer a cursor over an offset?
  • How would you version this API once clients depend on it?
  • How would you secure the endpoint so only authenticated users can create items?

Design a URL shortening service (like bit.ly). What considerations would you take into account?

Medium · System Design / Architecture

Approach

  1. Pin the requirements: create a short link, redirect fast, optional custom alias and expiry, click analytics; note the load is read-heavy, so the redirect path drives the design.
  2. Key generation: base62-encode a unique numeric id (7 characters give 62^7, about 3.5 trillion keys), with id ranges handed out in blocks to each app server so no single counter is a bottleneck; or random keys with a uniqueness check on insert. Say that sequential ids are guessable.
  3. Storage and reads: a key-value or relational table keyed by short code, with a cache such as Redis in front for hot links; the redirect is a cache lookup, then a database lookup on a miss.
  4. Redirect status is a real trade-off: 301 lets browsers cache the redirect and cuts load but hides repeat clicks; 302 sends every click through the service so analytics stay complete. Record clicks asynchronously through a queue.
  5. Edge cases: the same long URL submitted twice, custom aliases that collide, expired links, and malicious destinations that need screening or takedown.

Follow-up

  • One link goes viral and gets a huge share of traffic: what changes?
  • How do you expire links, and would you ever reuse their keys?
  • How would you serve redirects from several regions?

How would you architect a data storage solution for a growing e-commerce platform?

Medium · System Design / Architecture

Approach

  1. Split the data by access pattern instead of choosing one database: product catalog (read-heavy, varied attributes), orders and payments (transactional), inventory (high contention), carts and sessions (short-lived), analytics (large scans).
  2. Orders and payments go in a relational store such as MySQL or PostgreSQL for ACID transactions; the catalog can be relational with JSON columns or a document store such as MongoDB, with a search index for text queries.
  3. Prevent overselling with a conditional update (UPDATE stock SET qty = qty - 1 WHERE sku = ? AND qty >= 1, then check the affected row count) or reservations with a timeout, not a read-then-write.
  4. Scale reads with caching and read replicas, and say how replica lag is handled (read the order confirmation from the primary). Shard orders by customer id when one primary is not enough, and name what that makes expensive: cross-customer reporting.
  5. Move analytics off the transactional store through change data capture or ETL into a warehouse, so reports never compete with checkout.

Follow-up

  • How would the design hold up during a flash sale on one product?
  • How do you keep the search index consistent with the catalog database?
  • How would you change a large table's schema without downtime?

Discuss how you would ensure scalability and performance in a web application.

Medium · System Design / Architecture

Approach

  1. Measure before changing anything: define targets as latency percentiles (p95/p99) and throughput, then find the bottleneck with metrics, profiling and load tests.
  2. Scale out the web tier: stateless application servers behind a load balancer, with sessions in a shared store, so instances can be added or removed freely.
  3. Cache at each layer: CDN for static assets, an application cache (cache-aside with a TTL) for hot reads, and say how stale data and invalidation are handled.
  4. Fix the database before scaling it: indexes for the slow queries, removing N+1 query patterns, connection pooling; then read replicas, and partitioning only when a single primary is the limit.
  5. Take slow work off the request path with a queue and background workers, and protect the system with timeouts, rate limiting and back-pressure. On the JVM, size thread pools and check GC pauses when tail latency spikes.

Follow-up

  • A popular cache entry expires and the database is flooded: how do you prevent that stampede?
  • p99 latency doubled after a release while p50 did not move: where do you look first?
  • At what point would you shard the database, and what does it cost you?

What factors do you consider when designing a microservices architecture?

Medium · System Design / Architecture

Approach

  1. Boundaries first: draw services around business capabilities (bounded contexts), each owning its data; a shared database between services removes most of the independence you split for.
  2. Communication: synchronous REST or gRPC when the caller needs the answer now, asynchronous events through a message broker when it does not; each choice changes coupling and failure behaviour.
  3. Resilience on every remote call: timeouts, retries with exponential backoff and jitter only for idempotent operations, circuit breakers, and idempotent message consumers because brokers can redeliver.
  4. Consistency across services: sagas with compensating actions instead of distributed transactions, and the transactional outbox pattern so a database write and its event cannot diverge.
  5. Operations: distributed tracing with correlation ids, central logs and metrics, an API gateway, service discovery, CI/CD per service, and backward-compatible contract changes (consumer-driven contract tests).

Follow-up

  • How would you break an existing monolith into services step by step?
  • A downstream service is slow rather than down: what protects the caller?
  • How do you change an event's schema when several services consume it?

Explain how you would handle data redundancy and backup in your system design.

Medium · System Design / Architecture

Approach

  1. Separate the two goals: replication keeps the system available when a node or zone fails, but it copies deletes and corruption too; backups let you restore to an earlier point. You need both.
  2. Start from RPO (how much data you can lose) and RTO (how long recovery may take), since they decide synchronous vs asynchronous replication and how often you back up.
  3. Replication trade-off: synchronous replication loses no committed data on failover but adds write latency; asynchronous is faster but replica lag means recent writes can be lost. Place replicas across availability zones, or regions if required.
  4. Backups: periodic full snapshots plus continuous log archiving (WAL or binlog) for point-in-time recovery, stored in a separate account or region, encrypted, versioned or immutable so a compromised account cannot erase them; the 3-2-1 rule is a useful summary.
  5. A backup is only proven by a restore: schedule restore tests, measure the actual recovery time against the RTO, and alert when a backup job fails.

Follow-up

  • Someone ran a DELETE without a WHERE clause in production: how do you recover?
  • How do you fail over to a replica without ending up with two primaries accepting writes?
  • How would you choose between a lower RPO and a lower cost for a given dataset?

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

  1. 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.
  2. 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.
  3. 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.
  4. 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

Seven days built around the three reported stages: the stack and recruiter pitch first, then Java and Kotlin fundamentals, the reported coding problems, microservices and REST, the five design prompts, cloud and project stories, and a behavioral rehearsal.

Day 1 — Map the stack and write your recruiter pitch

  • List the must-have and nice-to-have skills the role requires (Java, Kotlin, JVM, AWS or Azure, microservices, React or Angular, MySQL or MongoDB, CI/CD) and write one project or an honest gap next to each.
  • Write a two-minute career walk that names your Java or Kotlin work and your cloud experience.
  • Write a list of questions for the recruiter on the format of the technical stage and which language you may use.

Deliverable: A skills matrix with evidence per skill, a two-minute spoken pitch, and a list of recruiter questions.

Day 2 — Java, Kotlin and JVM memory

  • Write a one-page comparison of Java and Kotlin covering null safety, data classes, coroutines versus threads and interoperability, with one example for each.
  • Draw the JVM memory layout (heap generations, stacks, metaspace) and note which collector you would pick for a latency-sensitive service and why.
  • Write down one real memory or performance problem from your work, with symptom, measurement and fix, and say it aloud in under two minutes.

Deliverable: A Java and Kotlin comparison sheet, a memory diagram, and one rehearsed memory story.

Day 3 — The reported coding problems

  • Implement reversing a linked list iteratively and recursively, and the longest substring without repeating characters with a sliding window and a map of last positions.
  • Implement a Fibonacci solution as memoization, bottom-up table and constant-space loop, then binary search with an overflow-safe midpoint.
  • Run each solution on empty, single-element and duplicate-heavy inputs and write time and space complexity next to each.

Deliverable: Four working solutions in your chosen language with a test list and complexity for each.

Day 4 — REST endpoint and microservices trade-offs

  • Build a small REST endpoint end to end with route, input validation, correct status codes and a consistent error body.
  • Write a two-column list of microservices benefits and costs, with when you would stay on a single service.
  • Practise the answer to what factors you consider when designing microservices: service boundaries, data ownership, communication style, failure handling and observability.

Deliverable: A running endpoint with tests, plus a benefits-and-costs sheet for microservices.

Day 5 — System design outline and the reported prompts

  • Write a reusable design outline: requirements and scale, API, data model, read and write paths, caching, failures, backup and recovery.
  • Apply it to the URL shortener (ID generation, storage, redirect path, caching) and to the e-commerce storage prompt (what is relational, what is not, how it scales).
  • Write short answers for web application scalability and for redundancy and backup, covering replication, backups, restore tests and failover.

Deliverable: Four one-page design outlines, one per prompt.

Day 6 — Cloud experience and project stories

  • Prepare the AWS or Azure answer as a project story: services, the decisions behind them, access control, deployment and an outcome.
  • Write the challenging technical problem story and the significant challenge story with situation, your actions, result and what you would change.

Deliverable: Two project stories and a cloud answer, each written with a checkable result.

Day 7 — Behavioral rehearsal and full run-through

  • Answer the prioritization, teamwork, feedback and motivation questions out loud, each with a specific story.
  • Record yourself on one story and check that your own decisions are clear and that you used "I" for your actions.
  • Do a final pass through the weakest coding problem and the weakest design prompt from earlier days.

Deliverable: Five rehearsed behavioral answers and a note of the one coding and one design item to revisit.

Stories and answers for the behavioral stage

Candidates report behavioral interviews aimed at teamwork and how you fit with a team. For a role that involves requirements work with product and operations, code review and debugging, the useful stories show your own decision, how you worked with others and what you changed afterwards. Rehearse the reported prompts first, then the extra ones that follow.

  1. Describe a time when you had to convince a team member to change their approach.

How do you handle memory management in Java?

Medium · Technical / Domain Questions

Approach

  1. Start with the memory areas: objects live on the heap and are reclaimed by the garbage collector, each thread has a stack holding frames with local variables and references, and class metadata sits in metaspace. You never free objects by hand; you control how long they stay reachable.
  2. Explain reachability and generations. The collector begins from GC roots (thread stacks, static fields, native references) and reclaims whatever it cannot reach. New objects start in the young generation (eden and survivor spaces), long-lived ones are promoted to the old generation, and minor collections are cheaper than full ones.
  3. Name collectors and the trade-off: Parallel favors throughput, G1 splits the heap into regions to balance pause time and throughput, ZGC aims for very short pauses on large heaps. Tuning starts from heap size (-Xms, -Xmx), GC logs and a pause or throughput target, not from copying flags.
  4. Cover leaks in a managed runtime: they are objects still reachable but no longer needed, such as static maps used as caches with no eviction, listeners never removed, ThreadLocal values in pooled threads, and unbounded queues. Diagnose with a heap dump (jcmd or jmap), then read the dominator tree in Eclipse MAT or VisualVM and compare two dumps.
  5. Because this prompt is filed with the behavioral questions, close with one real case: the symptom (heap that stays high after collection, OutOfMemoryError, long pauses), what you measured, the fix and how you confirmed it.

Follow-up

  • How do you tell a memory leak from a heap that is simply too small for the workload?
  • What is the difference between an OutOfMemoryError for heap space and a StackOverflowError, and what causes each?
  • When would you use a WeakReference or SoftReference, and why is relying on finalizers a bad idea?

Can you discuss your experience with cloud platforms like AWS or Azure?

Medium · Technical / Domain Questions

Approach

  1. Choose the platform you have genuinely used, AWS or Azure, and lead with what you built on it and what you personally owned. Name the services in the context of a decision, for example why a queue sat between two services, why a managed database beat a self-hosted one, or why you picked a particular compute model.
  2. Cover the same checklist for every project: compute, storage, database, messaging, identity and access (least-privilege roles, secrets handling), monitoring and logging, and how code reached the environment (CI/CD pipeline, environments, rollbacks).
  3. Include one trade-off with a number or an observable outcome: a cost you cut, a deployment time you reduced, or an outage you diagnosed. Say what you would do differently now.
  4. If your experience is on only one of the two platforms, say so and map the concepts across (object storage, managed queues, identity roles, managed relational databases) to show you can transfer. Do not claim hands-on Azure time you do not have.
  5. Avoid the common failure of reciting service names with no decision attached; each service you mention should come with the problem it solved.

Follow-up

  • How did you manage secrets and permissions for your services in that environment?
  • What did a deployment look like, and how did you roll back a bad release?
  • What was the most expensive or least reliable part of that setup, and what did you change?

Describe a time you faced a significant challenge at work. How did you overcome it?

Medium · Behavioral / Leadership

Approach

  1. Pick a challenge where you had real ownership and the stakes were visible: a deadline, a production incident, a failing migration or a stalled integration. State the situation in two or three sentences, then spend most of the time on what you decided.
  2. Show your reasoning in order: how you diagnosed the problem, which options you weighed, why you chose one, and who you brought in (product, operations, another engineer). Use "I" for your actions and name the teammates who did theirs.
  3. End with a result you can check, such as latency down, incidents stopped, a release shipped, or a process adopted, and one thing you learned that you have used since.
  4. The story fails when the hard part was external and you only watched, when no result is given, or when the challenge was one you created and you do not own that.

Follow-up

  • What would you do differently if you faced the same problem again?
  • How did you know your fix worked, and what did you measure?
  • Who disagreed with your approach, and how did you handle it?

How do you prioritize tasks when working on multiple projects?

Medium · Behavioral / Leadership

Approach

  1. Give a method, then prove it with a case. A workable method: list everything with deadlines, rank by impact and urgency, find dependencies and blockers, then decide what goes first, what is delegated or shortened, and what is explicitly deferred.
  2. Use a case with real competition for your time, such as a production bug, a feature deadline and a review backlog landing in the same week. State which you did first and why.
  3. Show communication: you told the people affected what would slip and when, and you agreed the order with product management or your lead instead of deciding silently.
  4. Mention how you protect the plan afterwards (a short written list, regular re-ranking when something urgent arrives) and an example of re-prioritizing after new information.
  5. Avoid answers that amount to "I work hard and stay organized"; the point is the trade-off you made and who you told.

Follow-up

  • What do you do when two stakeholders each insist their request is the top priority?
  • Tell me about a time you got the order wrong and what it cost.
  • How do you handle urgent interruptions without dropping planned work?

Give an example of how you worked effectively within a team.

Medium · Behavioral / Leadership

Approach

  1. Choose a team effort with a clear shared goal, such as a joint release, a cross-service integration or a migration, and state your role in one sentence so the listener knows where your contribution begins and ends.
  2. Show specific collaboration behaviors: how you broke up the work, how you handled code review in both directions, how you shared context (design notes, pairing, handoffs) and how you worked with non-engineering colleagues such as product or operations.
  3. Include a moment of friction, a disagreement on design or a missed handoff, and how you resolved it with evidence or a quick prototype instead of escalating.
  4. Close with the team outcome and what you did beyond your own task, for example unblocking a teammate or documenting a process. A story where the team succeeded and your role is unclear is the usual mistake.

Follow-up

  • What was the hardest disagreement on that team, and how did it end?
  • How did you make sure everyone had the context they needed?
  • What would you change about how that team worked together?

How do you handle feedback and criticism of your work?

Medium · Behavioral / Leadership

Approach

  1. Tell a story about real, specific criticism, such as a rejected pull request, a design review that found a flaw, or a performance note. A story where the feedback was trivial or secretly flattering signals that you are avoiding the question.
  2. Describe your first reaction honestly, then your actions: you asked clarifying questions, checked whether the point was right, fixed what needed fixing, and followed up to confirm the fix landed.
  3. Show the lasting change in how you work (a checklist, writing tests earlier, smaller pull requests) and a result that came from it.
  4. Cover the other direction briefly: how you give feedback on someone else's code, by being specific, explaining the reason and offering an alternative. If you disagreed with feedback, say how you tested your position and what you did when the evidence went against you.

Follow-up

  • Tell me about feedback you disagreed with and what you did.
  • How do you give critical feedback to a teammate on a pull request?
  • What is the most useful feedback you have received in the last year?

What motivates you to do your best work?

Medium · Behavioral / Leadership

Approach

  1. Name two or three genuine drivers, for example solving hard debugging problems, seeing users use what you built, or mentoring, and attach a concrete episode to each so the answer is evidence instead of a slogan.
  2. Link your drivers to the work candidates describe for this role: building features that integrate with other services, working with data and cloud solutions, and shipping customer-facing applications alongside product and operations colleagues. Do this only where it is true for you.
  3. Show how motivation turned into behavior, for example staying to trace a flaky release problem or volunteering for a migration, and give the outcome.
  4. Be ready for the opposite: say what drains you and how you manage it. Generic claims such as "I am passionate about technology" with no example are the usual mistake.

Follow-up

  • Tell me about a time you were not motivated by your work and what you did.
  • What kind of project would you not want to own?
  • How does what motivates you fit the work you expect in this role?