Interview guides · CLARA analytics
CLARA analytics Software Engineer Interview Guide
CLARA analytics Software Engineer interview guide: Java, SQL vs NoSQL, LRU cache, API and system design questions, a 3-round loop and a 7-day plan.
The 60-second brief
CLARA analytics applies data analytics to the insurance industry, turning large volumes of data into insights that clients use for decisions. Candidates describe the Software Engineer role as building and maintaining the applications around that work: large-scale data processing, API development and integration of machine learning. The requirements candidates list center on Java with Spring, RESTful APIs and both SQL and NoSQL databases.
This guide is for engineers preparing for the Software Engineer loop at CLARA analytics. It covers the three reported rounds (Phone Screening, Technical Assessment, Onsite Interview), the Java, API, database, coding and system design questions candidates report, the production troubleshooting questions, and three behavioral prompts, then ends with a seven-day plan.
Candidates report three stages, a Phone Screening, a Technical Assessment and an Onsite Interview, spread over roughly 3-5 weeks. The onsite is described as several interviews covering coding and system design.
Focus areas
- Java
- SQL
- System Design
Overview
The reported requirements read like a Java backend job: Java and Spring, RESTful APIs, SQL and NoSQL databases, data structures and algorithms, and basic system design principles. Cloud services (AWS, Azure), machine learning frameworks and JavaScript or React are listed as extras, not requirements. The reported questions follow the same shape: Java language basics (immutability, the final keyword), an LRU cache in Java, a function that calls an API and parses JSON, SQL versus NoSQL, then classic array problems.
The design questions lean toward data-heavy services: a scalable web API for document processing, high-volume data ingestion, microservices versus a monolith, and consistency in a distributed system. Candidates also report two troubleshooting questions, one about diagnosing performance problems and one about a bug in production. For these, practise a repeatable order: scope, measure, narrow down, fix, then prevent recurrence. Bring concrete numbers and tools from your own past work.
Candidates report that live coding on a shared screen is common, so rehearse writing Java while talking: state the approach, name the complexity, write the code, then run through a small example and the edge cases by hand. Three reported prompts are behavioral (a significant challenge, prioritizing across projects, working in a team). The responsibilities candidates describe include code review and working with product managers and UX designers, so pick stories where you worked with people outside engineering.
The CLARA analytics interview process
Candidates describe three stages over roughly 3-5 weeks. What follows is their account, not a published process, and details can differ by team.
Phone Screening
Candidates describe the Phone Screening as an initial call about your background and fit for the role. No specific questions are reported for this stage. Because the role lists Java, Spring, REST APIs and SQL/NoSQL, expect the conversation to touch the projects on your CV that used them. Prepare a tight walkthrough of your career, with one or two projects you can discuss in depth.
What to demonstrate
- How your experience lines up with the Java, Spring, REST API and database stack the role lists
- Whether you can explain your own past projects clearly and concisely
How to prepare
- Write a two-minute CV walkthrough that ends with the project closest to Java services and REST APIs, and be ready to go one level deeper on it.
- Review the Java basics candidates report (immutability, the final keyword) so a short technical question does not catch you cold.
- Prepare a sentence on why you want to work on insurance data analytics, tied to something real in your background.
Technical Assessment
The Technical Assessment is described as practical coding challenges. The reports do not say whether it is live or offline, so ask the recruiter. Tips from candidates say live coding on a shared screen is common, and the coding-style questions reported for this loop include an LRU cache in Java, a function that calls an API and parses JSON, two-number sum, binary search and longest increasing subsequence. Practise writing complete, compiling Java and narrating your reasoning as you go.
What to demonstrate
- Working code in Java, which is the language the role names
- Data structure and algorithm choice with a stated time and space complexity
- How clearly you explain your approach while coding
How to prepare
- Implement an LRU cache two ways: a HashMap plus a doubly linked list, and LinkedHashMap with access order and removeEldestEntry. State why get and put are O(1).
- Write binary search iteratively and get the boundary conditions right (loop condition, mid calculation, returning not-found) on arrays with duplicates and a single element.
- Solve the longest increasing subsequence both as the O(n^2) dynamic program and the O(n log n) tails-array version, then the two-number sum with a hash map in one pass.
- Write a small Java method that calls a REST endpoint and parses JSON, with timeouts, status code checks and a plan for malformed bodies.
Onsite Interview
The Onsite Interview is described as multiple interviews focused on coding and system design. The system design questions candidates report are a scalable web API for document processing, a high-volume data ingestion system, microservices versus a monolith, and consistency in a distributed system. The database question (SQL versus NoSQL) and the production troubleshooting questions are also reported, and behavioral questions appear in the reported set. Prepare designs you can sketch end to end and defend with trade-offs.
What to demonstrate
- Coding in a longer, multi-interview setting, not only a single problem
- System design reasoning: components, data flow, scaling and consistency choices
- Communication across the whole loop, since the role works with product managers and UX designers
How to prepare
- Practise the document processing API out loud: upload, queueing and asynchronous processing, status polling or callbacks, storage, idempotency and retries.
- Prepare a consistency toolkit you can name and compare: transactions, idempotent writes, eventual consistency, the outbox pattern and sagas, and when each fits.
- Write a one-minute microservices-versus-monolith answer that ends in a recommendation for a small team, not a list of pros and cons.
- Rehearse a performance diagnosis routine: reproduce, check metrics and logs, find the bottleneck layer, fix, verify.
Where candidates lose points
Treating the final keyword as the same thing as immutability
Explain that final on a variable prevents reassignment of the reference, while an immutable class also needs private final fields, no setters, no leaking of mutable internals (defensive copies) and a class that cannot be subclassed. Use String or a small value class as your example.
Presenting an LRU cache with linear scans or an unbounded structure
Aim for O(1) get and put: a hash map to nodes plus a doubly linked list ordered by recency, evicting the tail at capacity. Mention LinkedHashMap with access order as the shortcut, and say what changes if the cache is shared by several threads.
Writing binary search or longest increasing subsequence with boundary errors or only the slowest version
Fix an invariant for binary search (for example, the answer lies in [lo, hi]) and test an empty array, one element and a missing target. For the subsequence, give the O(n^2) dynamic program first, then the O(n log n) tails-array improvement, and say which you would write under time pressure.
Answering the microservices versus monolith and consistency questions with a list and no decision
Finish with a recommendation tied to team size, deployment needs and data boundaries. For consistency, say which operations need strong guarantees (for example, a financial or status change) and which can be eventually consistent, and how retries stay safe through idempotency keys.
Jumping to a fix when asked about a performance problem or a production bug
Narrate the order you would follow: confirm the symptom and when it started, check recent changes, read metrics and logs, find which layer is slow (database, network, application, a dependency), make one change at a time, then add monitoring or a test so it does not return.
Questions & practice
Explain the concept of immutability in Java.
Medium · Technical / Domain Questions
Approach
- Define it: an immutable object's observable state cannot change after construction. String, Integer, BigDecimal and LocalDate are examples, and their 'modifying' methods (concat, add, plusDays) return new instances.
- Give the recipe: make the class final (or use a private constructor plus a static factory), make every field private final, write no setters, and defensively copy mutable inputs in the constructor and in getters (List.copyOf, new Date(d.getTime())).
- Separate a final reference from an immutable object. A final List can still be add()ed to; Collections.unmodifiableList is only a view whose backing list can still change; records and List.of are shallow, so mutable elements stay mutable.
- State the payoff: thread safety without locks, safe publication of final fields once the constructor finishes (provided 'this' does not escape during construction), and stable hashCode, so the objects work as HashMap keys and can cache their hash as String does.
- Name the cost: every change allocates a new object. Use StringBuilder for concatenation in loops, or a builder for objects with many fields.
Follow-up
- Why is String immutable, and what would break in the string pool and in HashMap keys if it were not?
- How would you make a class with a List<Date> field fully immutable?
- Is a Java record immutable? What about a record holding an array?
Write a function to find two numbers in an array that sum to a specific target.
Medium · Coding / Algorithms
Approach
- Clarify: return indices or values, whether exactly one answer is guaranteed, whether the same element may be used twice (normally not), whether the array is sorted, and whether duplicates and negatives occur.
- Name brute force (check every pair, O(n^2)), then the one-pass hash map: for each i, compute complement = target - nums[i]; if the map holds it, return [map.get(complement), i], otherwise put nums[i] -> i. That is O(n) time and O(n) space. Checking before inserting handles [3,3] with target 6 and never pairs an element with itself.
- Offer the sorted alternative: on sorted input, move two pointers inward from both ends (sum too small, advance left; too big, move right back). That is O(n) time and O(1) extra space, or O(n log n) if you must sort first while keeping the original indices.
- Cover the Java details: HashMap<Integer, Integer> boxes every value; target - nums[i] can overflow int near Integer.MIN_VALUE or MAX_VALUE, so compute it in long when the range is unbounded; decide whether 'no pair' returns an empty array or throws.
- Test: no solution, duplicates, negatives, a two-element array, and target zero.
Follow-up
- Return all unique pairs instead of one. How do you skip duplicates?
- Extend it to three numbers summing to the target. What complexity do you get?
- Numbers arrive as a stream with add and find calls. Which operation do you make cheap?
How would you implement a binary search algorithm?
Medium · Coding / Algorithms
Approach
- State the precondition: the array is sorted, or more generally a predicate over the range is monotonic. Use lo = 0, hi = n - 1, loop while lo <= hi, take mid = lo + (hi - lo) / 2 to avoid the overflow that (lo + hi) / 2 hits on large arrays, then return mid or move to lo = mid + 1 or hi = mid - 1. Return -1 if not found. O(log n) time, O(1) space.
- Say the loop invariant out loud (if the target is present, it lies in [lo, hi]) and stick to one interval convention. Off-by-one bugs come from mixing closed [lo, hi] with half-open [lo, hi).
- Write the lower-bound variant: lo = 0, hi = n, while lo < hi, if a[mid] < target then lo = mid + 1 else hi = mid; the result is the first index whose value is >= target. It also gives first and last occurrence with duplicates, and it supports binary search on the answer (smallest capacity that ships within D days, integer square root).
- Know the library behaviour: Arrays.binarySearch returns -(insertionPoint) - 1 when the key is missing, and with duplicates it does not guarantee which matching index it returns.
- Test: empty array, one element, a target below the minimum or above the maximum, and runs of duplicates.
Follow-up
- How do you search a sorted array that has been rotated?
- Find the first and last positions of a target in O(log n).
- Why does binary search lose its advantage on a linked list?
Given a list of integers, write a function to find the longest increasing subsequence.
Medium · Coding / Algorithms
Approach
- Clarify: strictly increasing or non-decreasing, and whether to return the length or the subsequence itself. Subsequence means not necessarily contiguous; brute force over all subsets is O(2^n).
- Give the O(n^2) DP: dp[i] = 1 + max(dp[j]) over j < i with a[j] < a[i] (or 1 if there is none), and the answer is the maximum dp[i]. O(n) space.
- Improve to O(n log n) with patience sorting: tails[k] holds the smallest tail of any increasing subsequence of length k + 1. For each x, binary search for the first tail >= x and replace it, or append x if there is none. The answer is tails.size(). For non-decreasing, search for the first tail > x. tails is not itself a valid LIS.
- To reconstruct the sequence, store the array index behind each tails slot and a parent[i] pointer to the previous element, then walk back from the index behind the last slot.
- Test: empty input gives 0, all-equal input gives 1 (strict), strictly decreasing gives 1, and [10, 9, 2, 5, 3, 7, 101, 18] gives 4 (2, 3, 7, 18).
Follow-up
- Why does overwriting a tail never shorten the answer?
- Count how many longest increasing subsequences there are.
- Nesting envelopes by width and height: how does sorting reduce it to an LIS?
What are the differences between SQL and NoSQL databases?
Medium · Technical / Domain Questions
Approach
- Contrast the data models. Relational databases use tables with a schema enforced on write, foreign keys and joins. NoSQL covers several families: document (MongoDB), key-value (Redis, DynamoDB), wide-column (Cassandra) and graph (Neo4j), each modelled around known access patterns, often with a flexible schema.
- Compare transactions and consistency without absolutes. Relational systems give multi-row ACID transactions. Many NoSQL stores guarantee atomicity per item or per partition and offer tunable or eventual consistency, but MongoDB has had multi-document transactions since 4.0 and DynamoDB offers TransactWriteItems.
- Compare scaling. A relational database usually scales vertically plus read replicas, with sharding done by hand or through distributed SQL (Spanner, CockroachDB). Most NoSQL stores partition horizontally by key, so a query that does not use the partition key turns into a scatter-gather.
- Compare query flexibility. SQL handles ad hoc joins and aggregations over indexes. In NoSQL you denormalise for the queries you know in advance, and every secondary index adds write cost.
- Finish with a decision rule: relational data with integrity constraints and reporting needs points to SQL; very high write volume on simple keys, or documents with changing shape, points to a document or wide-column store. Many systems use both.
Follow-up
- In a document store, when do you embed a one-to-many relation and when do you reference it?
- What does CAP say about a network partition, and what does PACELC add?
- How would you keep a SQL system of record and a NoSQL read model in sync?
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
- 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.
- 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.
- 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.
- 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 is the purpose of the final keyword in Java?
Medium · Technical / Domain Questions
Approach
- Cover the three targets. A final variable (local, parameter or field) can be assigned exactly once, a final method cannot be overridden, and a final class cannot be subclassed (String and Integer are final).
- Point out that final blocks reassignment of the reference, not mutation of the object: a final ArrayList still accepts add().
- Explain blank finals. A final instance field must be definitely assigned on every constructor path, and a static final field in its initializer or a static block, or the compiler rejects the class. A static final primitive or String set from a constant expression is inlined into calling classes, so changing it means recompiling those callers.
- Connect it to lambdas and the memory model. Lambdas and anonymous classes may capture only final or effectively final locals. Final fields are guaranteed visible to other threads after construction without synchronization, as long as 'this' does not leak from the constructor.
- Keep final apart from finally (a block that runs on every exit from a try) and finalize() (deprecated for removal by JEP 421 in Java 18; use try-with-resources or Cleaner instead).
Follow-up
- Can a final field be changed through reflection, and what does the JIT's constant inlining do to that change?
- When would you make a class final, and when would a private constructor do the job instead?
- Does marking a method final make it faster on a modern JVM?
How would you design a function to interact with an API and parse JSON data?
Medium · Technical / Domain Questions
Approach
- Pin down the contract first: endpoint and auth, pagination style (cursor or offset), rate limits, response schema, and what the caller gets on failure (a typed exception, Optional, or a result object).
- Split the function into layers: transport (java.net.http.HttpClient from Java 11, or Spring's RestTemplate/WebClient), deserialization (a Jackson ObjectMapper mapping into a typed DTO or record) and mapping to domain objects. Reuse one configured HttpClient and one ObjectMapper; both are thread-safe once configured.
- Check the status code before parsing. Parse 2xx; do not retry other 4xx; on 429 honour Retry-After; retry 5xx and timeouts with capped exponential backoff and jitter, and only for idempotent calls or calls that carry an idempotency key. Always set connect and request timeouts.
- Make parsing robust: disable FAIL_ON_UNKNOWN_PROPERTIES so new fields do not break you, validate required fields, handle nulls and type mismatches, stream very large payloads with JsonParser, and wrap JsonProcessingException in a domain exception that carries the URL and status.
- Test with a stub server (WireMock or MockWebServer): a 200, a 404, a 500 followed by a success, malformed JSON, a timeout, and a pagination loop that stops on an empty page or a null cursor.
Follow-up
- How would you page through millions of records without holding them all in memory?
- How would you make the call non-blocking, for example with sendAsync and CompletableFuture?
- How would you stop hammering the API while it is degraded, for example with a circuit breaker?
Describe how you would implement an LRU cache in Java.
Medium · Technical / Domain Questions
Approach
- State the requirement: get and put in O(1), and when capacity is exceeded, evict the least recently used entry. Both get and put count as a use.
- Hand-write it as a HashMap<K, Node> plus a doubly linked list with sentinel head and tail nodes. get unlinks the node and moves it to the front. put either updates the value and moves the node, or inserts a new node at the front; if size then exceeds capacity, remove tail.prev and delete its key from the map, which is why each node stores its key.
- Mention the library shortcut: new LinkedHashMap<>(capacity, 0.75f, true) gives access order, and overriding removeEldestEntry to return size() > capacity does the eviction. Be ready to write the manual version anyway.
- Address concurrency. Neither version is thread-safe, and in access-order mode even get changes the list, so reads need the lock too. Wrap whole operations in a lock, or for heavy concurrency use a library such as Caffeine. ConcurrentHashMap alone gives no recency order.
- Handle the edge cases: capacity zero or negative, put on an existing key (update the value and refresh recency), your policy on null keys and values, and an optional eviction callback.
Follow-up
- How would you add a time-to-live on entries?
- How would you keep throughput up when many threads read the cache at once?
- When does LRU do badly, for example during a one-off full scan, and what would you use instead?
Design a scalable web API for document processing. What considerations would you take into account?
Medium · System Design / Architecture
Approach
- Clarify first: document types and size range, how many documents per day at peak, which processing steps run (parsing, OCR, extraction, classification), whether callers need results synchronously, and the retention and access-control rules for documents that may hold personal data.
- Make the API asynchronous. POST /v1/documents takes an idempotency key and returns 202 Accepted with a job id. Large files go straight to object storage (S3 or Azure Blob) through a pre-signed URL so they never pass through the API servers. Callers poll GET /v1/documents/{id} or register a webhook.
- Build the pipeline as job metadata in a relational table with a state machine (received, processing, done, failed), plus a queue (SQS, Kafka or RabbitMQ) feeding stateless workers that autoscale on queue depth. Retry with backoff and send a job to a dead-letter queue after N failures. Delivery is at-least-once, so workers must be idempotent.
- Protect the system: per-client rate limits, a maximum file size, content-type validation and malware scanning on upload, paginated list endpoints, and versioned routes so the response schema can evolve.
- Add observability and security: per-stage latency and failure metrics, a trace id carried through the job, encryption in transit and at rest, and authorization checks per tenant on every read.
Follow-up
- A worker crashes halfway through a document. What happens to that job, and how do you avoid processing it twice?
- How do you reprocess every stored document after a parser change without starving new uploads?
- How does the design change if a few callers need results within a second?
How would you approach designing a system that handles high-volume data ingestion?
Medium · System Design / Architecture
Approach
- Size the problem: peak and average events per second, payload size, whether order matters per key, how soon data must be queryable, retention, and whether duplicates are acceptable.
- Lay out the path: stateless ingestion endpoints behind a load balancer write to a durable partitioned log (Kafka or Kinesis) keyed so per-key order holds; consumer groups validate, transform and write in batches to raw object storage and to the serving database or warehouse. The log absorbs bursts so producers never wait on slow sinks.
- Handle throughput and backpressure: batch and compress writes, autoscale consumers on lag, and return 429 to producers when the front door is saturated. Partition count caps consumer parallelism within a group, so size it for future peak.
- Get correctness right under at-least-once delivery: idempotent writes (upsert on a dedupe key), schema validation against a registry, a dead-letter topic for bad records that can be replayed, and an immutable raw copy so any stage can be re-run.
- Plan for hot partitions: one skewed key can overload a single partition. Salt or split that key, and say what per-key ordering you give up by doing so.
Follow-up
- The downstream database is down for an hour. What buffers the data, and how do you size retention for it?
- How would you backfill a year of history alongside live traffic?
- How would you detect silent data loss between the producer and the final store?
Discuss the trade-offs between microservices and monolithic architecture.
Medium · System Design / Architecture
Approach
- Give the monolith a fair hearing: one deployable, in-process calls, single-database transactions, simple local development, debugging and deployment. The costs are whole-app deploys, scaling everything as one unit, and coupling that grows until one team's change breaks another's.
- List what microservices buy: independent deploys and scaling per service, team ownership, fault isolation (if timeouts and bulkheads are designed in), and freedom to choose a stack per service.
- List what they cost: network latency and partial failure, no cross-service ACID transactions (sagas instead), duplicated data, versioned API contracts, distributed tracing, and the operational load of CI/CD, service discovery and on-call for every service.
- Give decision criteria: number of teams, deploy conflicts, components with very different scaling profiles (a CPU-heavy processing worker next to a CRUD API) and how stable the domain boundaries are. A modular monolith is a common middle step, and the strangler fig pattern migrates gradually.
- Name the anti-pattern: a distributed monolith, where services share one database or must deploy in lockstep, so you pay the costs of both designs.
Follow-up
- How would you split an existing monolith, and where would the first boundary go?
- How do you handle a business operation that must update data owned by two services?
- How do you stop one service's API change from breaking its consumers?
What strategies would you use to ensure data consistency in a distributed system?
Medium · System Design / Architecture
Approach
- Start from the invariants: decide which ones need strong consistency (no negative balance, unique usernames) and where eventual consistency is acceptable (search indexes, counters). CAP forces a choice between consistency and availability during a partition; PACELC adds the latency-versus-consistency trade-off when there is no partition.
- Within one store: ACID transactions, optimistic concurrency with a version column and compare-and-set, or pessimistic locks. Across replicas: quorums with R + W > N, so every read set overlaps the latest write set. For leader election and configuration, use consensus (Raft or Paxos, through etcd or ZooKeeper).
- Across services, avoid two-phase commit because the coordinator blocks. Use sagas with compensating actions, plus a transactional outbox: the state change and the event row commit in one local transaction and a relay publishes the event. Consumers deduplicate because delivery is at-least-once.
- Cover read guarantees and conflicts: read-your-writes by reading from the leader or using session tokens, and monotonic reads. For conflict resolution, compare last-write-wins (clock skew silently drops writes), version vectors and CRDTs.
- Close with detection: reconciliation jobs that compare sources of truth, invariant checks, and alerts on replication lag.
Follow-up
- The service commits its database write and crashes before publishing the event. What happens, and how does an outbox fix it?
- Why is last-write-wins risky, and when is it acceptable?
- How would you guarantee a unique username across two regions?
Given a scenario where a system is experiencing performance issues, what steps would you take to diagnose and
Medium · Problem-Solving / Case Studies
Given a scenario where a system is experiencing performance issues, what steps would you take to diagnose and resolve the problem?
Approach
- Scope the symptom: which metric moved (p50 or p99 latency, throughput, error rate), since when, on one endpoint or all, and for every user or one segment. Then line it up against deploys, config changes and traffic shifts.
- Work methodically. Apply USE (utilization, saturation, errors) to each resource (CPU, memory, disk I/O, network) and RED (rate, errors, duration) to each service, then follow a slow request through distributed tracing to find the span that grew.
- Check the usual suspects. In the database: the slow query log, EXPLAIN ANALYZE, missing indexes, N+1 queries, lock contention, connection pool exhaustion. In the JVM: GC logs for long pauses, heap dumps for leaks, thread dumps (jstack) for blocked threads. Also look for slow downstream calls with no timeout and saturated thread pools.
- Mitigate before finding the root cause if users are hurting: roll back, scale out, shed load or switch off a feature flag. Then fix (index, cache, batching, async work) and confirm the same metric recovers under a load test.
- Prevent a repeat: add an alert on the metric that moved, a performance test for that path, and a short written root cause.
Follow-up
- p99 latency doubled while p50 stayed flat. What does that point to?
- CPU is low but latency is high. Where do you look next?
- How would you catch this regression before it reaches production?
How would you approach troubleshooting a bug in a production environment?
Medium · Problem-Solving / Case Studies
Approach
- Triage first: how many users are affected, whether data is being corrupted, and whether to mitigate right away (roll back, turn off a feature flag, fail over) while keeping stakeholders updated.
- Gather evidence before forming theories: error logs and stack traces found by correlation id, metrics showing exactly when it started, and the deploys, config changes and data changes around that moment. Then find one concrete input that triggers it.
- Reproduce safely in staging or locally with prod-like, sanitized data, never by experimenting on production. If it will not reproduce, add targeted logging behind a flag. If a release introduced it, git bisect between the last good and first bad versions.
- Fix behind a test: write a failing test that reproduces the bug, fix it, ship through the normal pipeline with a canary, and confirm the error rate returns to baseline. Repair any records the bug corrupted.
- Follow up with a blameless postmortem that separates trigger from root cause and ends with concrete actions: an alert, a test, a guardrail.
Follow-up
- The bug shows up on only one of ten hosts. What do you compare?
- You cannot reproduce it anywhere except production. What next?
- The bad release also ran a schema migration. Do you roll back or hotfix?
Suggested practice checklist
The seven days follow the reported loop: the phone screen first, then Java and coding practice, API and database topics, system design, troubleshooting and finally behavioral stories with a full run-through.
Day 1 — Map the loop and your Java story
- Write down the three reported rounds (Phone Screening, Technical Assessment, Onsite Interview) and next to each the question types in this guide that belong to it.
- Write a two-minute career walkthrough and pick the two projects closest to Java, REST APIs or data processing.
- List the requirement keywords (Java, Spring, REST, SQL, NoSQL, system design basics) and rate your confidence in each from one to five.
Deliverable: A one-page loop map, a written two-minute CV walkthrough and a confidence-rated list of the stack keywords with your two weakest circled.
Day 2 — Java fundamentals and the LRU cache
- Write a short explanation of immutability in Java, then build an immutable class with a mutable field to show defensive copying.
- Write down every use of final (variable, method, class) and one sentence on what each prevents.
- Implement the LRU cache twice in Java: a HashMap plus doubly linked list, then LinkedHashMap with removeEldestEntry. Write tests for eviction order.
Deliverable: A written answer on immutability, a final-keyword summary and two working LRU cache implementations with eviction tests.
Day 3 — Coding problems on a shared screen
- Solve the two-number sum with a hash map in one pass, and note the sorted two-pointer alternative.
- Write binary search iteratively, then a variant that finds the first occurrence in an array with duplicates.
- Solve longest increasing subsequence as an O(n^2) dynamic program and as an O(n log n) tails array. Talk through each while typing, as you would on a shared screen.
Deliverable: Three solved problems in Java with stated time and space complexity and a list of edge cases you tested for each.
Day 4 — API functions and databases
- Write a Java function that calls a REST endpoint and parses JSON, with timeouts, status checks, a retry rule and handling for missing or malformed fields.
- Prepare a SQL versus NoSQL comparison: schema flexibility, joins, transactions, scaling pattern, and one concrete case for each.
- Solve the SQL practice problem on soft-deleted accounts and re-registration, and explain which index or constraint makes your answer correct.
Deliverable: A tested API-calling function, a one-page SQL versus NoSQL comparison and a solved SQL practice problem with the query and its explanation.
Day 5 — System design practice
- Sketch the document processing API: endpoints, queue, workers, storage, status reporting, idempotency and retries, and say what breaks first as volume grows.
- Sketch a high-volume ingestion pipeline and name where backpressure, batching and duplicate handling live.
- Write a short answer for microservices versus a monolith and another listing consistency strategies with when to use each.
Deliverable: Two annotated design diagrams (document API and ingestion) and two written trade-off answers ready to say aloud.
Day 6 — Performance and production troubleshooting
- Write a step-by-step diagnosis plan for a slow system: reproduce, measure, isolate the layer, change one thing, verify.
- Write a production bug plan that starts with what changed and what the logs and metrics show, and ends with a fix, a rollback decision and a prevention step.
- Record yourself giving both answers using an incident from your own work as the example.
Deliverable: Two written diagnosis checklists and one recording of each answer told through a real incident.
Day 7 — Behavioral stories and a full run-through
- Write STAR outlines for the significant-challenge, prioritization and teamwork prompts, with at least one story involving a product manager, designer or code reviewer.
- Rewrite each outline so every action is stated with 'I' and each ends with a checkable result.
- Do a spoken mock: one coding problem, one design question and one behavioral prompt back to back.
Deliverable: Three STAR outlines with results and one recorded mock session with notes on what to fix.
Behavioural preparation
Three behavioral prompts are reported: a significant project challenge, prioritizing across projects and collaborating in a team. The role as candidates describe it includes code review and working with product managers and UX designers, so choose stories that show your own decisions and how you worked with people outside engineering.
- Tell me about feedback you received in a code review and what you changed because of it.
- Describe a time you explained a technical trade-off to someone who was not an engineer.
Describe a time you faced a significant challenge in a project. How did you overcome it?
Medium · Behavioral / Leadership
Approach
- Pick a technical challenge you owned, such as a slow data job, a failing integration or a hard migration, so the story fits a role built on APIs and data processing.
- Open with the situation in two sentences, then spend most of the answer on your own actions: what you investigated, which options you weighed and why you chose one.
- Say 'I' for what you did and name teammates only where they actually contributed, so your part is unmistakable.
- Close with a result that can be checked, such as latency, error rate, a delivery date met or a recurring incident removed, and one thing you learned.
Follow-up
- What would you do differently if you faced the same situation again?
- What was the hardest trade-off you made, and who disagreed with it?
- How did you confirm your fix was what changed the outcome?
How do you prioritize tasks when working on multiple projects?
Medium · Behavioral / Leadership
Approach
- Describe a real period with competing commitments (for example a feature, a bug fix and a code review queue) and say how you listed them.
- Name your ranking factors: user or customer impact, deadline, dependencies on other people, and the cost of delaying each item.
- Show that you communicated: tell the product manager or requester what moves, what slips and why, then confirm the plan with them.
- Give the outcome and the habit it created, such as renegotiating scope early or protecting time for a long-running task. Avoid answering with only a generic tool or list.
Follow-up
- What do you do when two stakeholders each say their request is urgent?
- How do you handle a production issue that lands in the middle of planned work?
- Tell me about a time you said no or pushed a deadline, and how it went.
Can you provide an example of how you have worked collaboratively in a team setting?
Medium · Behavioral / Leadership
Approach
- Choose an example involving more than one role, such as engineers with a product manager or UX designer, or a code review exchange, since those collaborations are part of the role as candidates describe it.
- State the shared goal, your specific contribution and one point of friction, such as a disagreement over scope, an API shape or a review comment.
- Explain how you resolved the friction with evidence or a prototype, and how you gave or took feedback along the way.
- End with what the team shipped and what you changed in how you work with others afterward. Avoid a story that only says 'we'; the listener needs to hear your actions.
Follow-up
- Tell me about a disagreement with a teammate over a technical decision and how it ended.
- What feedback from a code review changed how you write code?
- How do you explain a technical constraint to someone who is not an engineer?