cswork / libraryOpen practice workspace

Interview guides · Ava2I

Ava2I Software Engineer Interview Guide

Ava2I Software Engineer interview guide: the reported rounds, Java and Angular prep, coding, system design and behavioral answers, and a 7-day plan.

The 60-second brief

Candidate reports describe Ava2I's engineering work in general terms rather than naming a specific product: full-stack applications with Java on the server and Angular in the browser, built alongside product managers, designers and other engineers. The responsibilities candidates list for this role run across the whole lifecycle: designing, coding, testing and deploying applications, reviewing code, joining architecture discussions, maintaining and troubleshooting systems already in production, and improving their performance. The requirements candidates describe are Java and Angular, Agile ways of working, database management and API design, with AWS or Azure, DevOps tooling and Docker listed as nice-to-haves.

This guide is for software engineers interviewing for the Ava2I Software Engineer role, especially those whose experience is in Java back ends, Angular front ends, or both. It covers the three reported stages, all twenty-five reported questions with concrete answer outlines (coding fundamentals, web and API knowledge, system design, troubleshooting scenarios and behavioral stories), the mistakes that cost candidates on those question types, and a seven-day plan. It does not cover compensation, team placement or remote-work policy, which candidates do not report reliably.

Candidates report three stages over roughly 3-5 weeks: a Technical Assessment, then a Behavioral Interview, then Advanced Technical Questioning focused on specific tools and programming languages.

Focus areas

  • Software Engineering
  • Java
  • Angular

Overview

The work candidates describe is full-stack: Angular components and services in the browser, Java services behind them, a database underneath, and APIs joining the layers. For preparation, this means you should be able to follow one user action through the whole stack, from an Angular HttpClient call through a Java REST endpoint to the query it runs. You should also be able to say where it gets slow and how you would test each layer. Many of the reported questions (web performance, REST versus SOAP, dependency management, design patterns) reward answers that name concrete mechanisms in both Java and Angular rather than general principles.

The reported questions fall into five groups. Technical and domain questions cover REST versus SOAP, web performance, design patterns, dependency management and your own Java and Angular projects. System design covers a URL shortener, a real-time chat application, microservices for an e-commerce platform, NoSQL versus relational storage, and consistency in distributed systems. Problem-solving scenarios cover a production bug, a teammate who keeps missing deadlines, estimating a project, learning a new technology and a serious performance problem. Coding covers linked-list reversal, shortest paths, sorting complexity, array and string manipulation and recursive Fibonacci. The behavioral questions cover challenging projects, conflict, leadership, prioritisation and motivation.

The coding questions are classic fundamentals, so a correct first version only gets you started. Prepare to state the complexity, handle the edge cases (an empty list, unreachable nodes, integer overflow) and improve the naive version, for example by turning exponential Fibonacci into linear time. Write all of them in Java, the language the role lists, and know the Java details that change the answer: recursion depth limits, StringBuilder versus string concatenation, and which algorithms Arrays.sort uses.

Candidates name the three stages but do not say which reported question comes up in which one. Have the design and scenario questions ready before the first technical stage, not just before the last. The final stage is described as being about specific tools and languages, so go deeper on Java and Angular there: collections and concurrency, Angular change detection and RxJS, Maven or Gradle and npm, unit and integration testing, and any Docker or cloud work on your CV.

The Ava2I interview process

Candidates describe three stages in this order: a technical assessment, a behavioral interview, then a final round of deeper technical questions about tools and languages. They do not report which question appears in which stage.

Technical Assessment

Candidates report that the loop opens with a Technical Assessment of coding ability and of the technologies the role uses. The format and the questions asked are not reported, so prepare for both kinds of question: writing working code, and explaining the Java and Angular technologies on your CV. The reported coding questions are the obvious practice set: reversing a linked list, shortest path in a graph, sorting complexity, array and string manipulation, and recursive Fibonacci. Write each one in Java without an IDE, state its time and space complexity, and test it on edge cases yourself before calling it done. Also prepare short, precise answers to the reported domain questions, such as REST versus SOAP and web performance, in case the technology part of this stage turns to them.

What to demonstrate

  • Writing correct, runnable code for fundamental data-structure and algorithm problems
  • Stating time and space complexity and handling edge cases
  • Working knowledge of the technologies the role lists, Java and Angular

How to prepare

  • Write iterative and recursive linked-list reversal, Dijkstra with a PriorityQueue, and memoised plus iterative Fibonacci in plain Java, then run each on an empty input, a one-element input and a large input.
  • Drill three array and string patterns (two pointers, sliding window with a HashMap, prefix sums) on one problem each, and explain why StringBuilder beats string concatenation inside a loop.
  • Write a one-paragraph spoken answer to REST versus SOAP and to how you would speed up a slow Angular page backed by a Java API.

Behavioral Interview

Candidates report that the second stage is a Behavioral Interview about past experience and cultural fit. The reported behavioral questions cover a challenging project, team conflict, taking the lead, prioritising across projects and motivation. Reported example questions add handling differing opinions, explaining technical material to a non-technical audience, and acting on feedback. Build a bank of five or six real stories from Java and Angular work that you personally drove. Write each one in STAR form, with a measurable result and an honest account of what you would change, and practise adapting one story to several prompts. The problem-solving scenarios (a teammate missing deadlines, estimating a project, learning a new technology) are judgement questions too, so prepare them alongside these stories.

What to demonstrate

  • Concrete evidence from past projects, told with your own role clearly separated from the team's
  • Collaboration: handling conflict and differing opinions, giving and receiving feedback
  • Cultural fit, as candidates describe the stage

How to prepare

  • Write STAR outlines for the five reported behavioral questions, each with a number in the result (latency cut, defects reduced, deadline met) and one sentence on what you would do differently.
  • Prepare one story about explaining a technical trade-off to a product manager or designer without jargon, and one about changing your work after review feedback.
  • Rehearse the teammate-missing-deadlines scenario twice: once as a peer and once as the person leading the work, since the actions you can take differ.

Advanced Technical Questioning

Candidates report that the final stage, Advanced Technical Questioning, focuses on specific tools and programming languages. Expect depth on what you list rather than breadth. For Java, that means collections internals, concurrency, memory and garbage collection, and the build tooling you use. For Angular, it means components, dependency injection, change detection, RxJS, routing and the build pipeline, plus how you test each layer. Candidates do not say whether system design comes up here or earlier. Because the requirements include API design and database management, prepare the reported design questions (URL shortener, chat application, microservices for e-commerce, NoSQL versus relational, distributed consistency) so you can discuss them at the level of concrete components and trade-offs.

What to demonstrate

  • Depth in the languages and tools you claim, especially Java and Angular
  • Practical engineering knowledge: dependency management, testing, debugging and performance tooling
  • Ability to defend design and technology choices with trade-offs

How to prepare

  • For every tool on your CV (Maven or Gradle, npm, Docker, a cloud provider, a test framework), write the two hardest questions you could be asked about it and answer them out loud.
  • Explain Angular OnPush change detection, trackBy and lazy-loaded routes, and Java HashMap internals, ConcurrentHashMap and how a memory leak can happen in a garbage-collected heap.
  • Sketch the URL shortener and the chat application end to end, naming the storage, cache, ID scheme and failure handling for each.

Where candidates lose points

Answering REST versus SOAP or web performance with slogans ('REST is JSON, SOAP is XML', 'add caching') and no mechanisms.

Prepare each domain answer as three or four concrete mechanisms with names: the WSDL contract and Fault element against HTTP status codes and idempotent methods, or OnPush change detection, lazy routes and N+1 query fixes. Close each one with when you would choose which.

Stopping a fundamentals coding question at the first working version: exponential recursive Fibonacci, recursive list reversal with no word on stack depth, Dijkstra applied to negative weights.

For every reported coding question, rehearse the full sequence in Java: naive version, complexity, improved version, edge cases (empty input, overflow, unreachable nodes) and a quick test run. Say the complexity before you are asked.

Listing Java and Angular on the CV but not being able to explain them below surface level when the questions turn to specific tools and languages.

For each language and tool you list, prepare the internals: HashMap and ConcurrentHashMap, garbage collection and memory leaks, Angular change detection, dependency injection and RxJS subscriptions, and Maven or Gradle dependency resolution. Remove anything from your CV you cannot discuss at that depth.

Drawing service boxes for the URL shortener, chat or e-commerce design without requirements, data model or a story for failures and consistency.

Open every design answer with requirements and the read-write ratio. Then name the ID scheme, partition key, cache and how retries stay idempotent. For the consistency and microservices questions, have a saga and outbox explanation ready.

Troubleshooting and behavioral answers told as 'we', with no mitigation step, no numbers and no reflection.

For the production-bug scenario, say 'mitigate, then diagnose' explicitly. For every behavioral story, separate your own actions from the team's, give a measurable result and name one thing you would change.

Questions & practice

Write a function to reverse a linked list.

Medium · Coding / Algorithms

Approach

  1. Iterative solution: prev = null, curr = head; while curr is not null, store next = curr.next, set curr.next = prev, then move prev = curr and curr = next; return prev. O(n) time and O(1) extra space.
  2. Recursive solution: reverse the rest of the list, then set head.next.next = head and head.next = null, and return the new head. It is also O(n) time, but uses O(n) stack, so a very long list can throw StackOverflowError in Java.
  3. Test the edge cases explicitly: an empty list, a single node, two nodes, and a long list. Walk through the pointer changes on a three-node example before writing code.
  4. Mention the doubly linked variant, which swaps prev and next on every node and returns the old tail.

Follow-up

  • Reverse the nodes in groups of k.
  • Reverse only the sublist between positions m and n.
  • How would you check whether the list has a cycle before reversing it?

How would you implement an algorithm to find the shortest path in a graph?

Medium · Coding / Algorithms

Approach

  1. Choose the algorithm from the graph's properties. For an unweighted graph, use BFS in O(V + E). For non-negative weights, use Dijkstra with a binary heap in O((V + E) log V). Negative weights need Bellman-Ford in O(VE), which also detects negative cycles. For weights of only 0 and 1, use 0-1 BFS with a deque. For all pairs on small graphs, use Floyd-Warshall in O(V^3).
  2. Dijkstra in Java: an adjacency list, a long[] dist array initialised to infinity, and a PriorityQueue of {distance, node} pairs. On each poll, skip stale entries where the polled distance exceeds dist[node], then relax each outgoing edge.
  3. Rebuild the path from a parent array, and use long distances so large weights cannot overflow.
  4. Edge cases: unreachable targets (return -1 or an empty path), self-loops, parallel edges, and source equal to target.

Follow-up

  • Why does Dijkstra give wrong answers with negative edge weights?
  • Find the cheapest route using at most k edges.
  • How would you speed up point-to-point queries on a very large road network?

Explain the time complexity of your favorite sorting algorithm.

Medium · Coding / Algorithms

Approach

  1. Pick one algorithm and know it fully. Merge sort runs in O(n log n) in every case: the recurrence T(n) = 2T(n/2) + O(n) gives log n levels with O(n) work each. It needs O(n) extra space and is stable.
  2. Contrast quicksort: O(n log n) on average but O(n^2) in the worst case when pivots are poor (for example a first-element pivot on sorted input). Randomised or median-of-three pivots make that unlikely. It is in place with O(log n) average stack, and not stable.
  3. Give the rest of the picture: heap sort is O(n log n) worst case with O(1) space but not stable. Insertion sort is O(n^2) in general but close to O(n) on nearly sorted data, which is why hybrids use it for small subarrays. Comparison sorts cannot beat Omega(n log n). Counting and radix sort can for bounded integer keys.
  4. Java detail: Arrays.sort uses dual-pivot quicksort for primitives and TimSort, a stable merge-insertion hybrid that is fast on presorted runs, for objects. Collections.sort is stable.

Follow-up

  • Why does Java use a stable sort for objects but not for primitives?
  • How would you sort a file too large to fit in memory?
  • When does stability actually matter in an application?

Solve a coding challenge that involves manipulating arrays or strings.

Medium · Coding / Algorithms

Approach

  1. Clarify before coding: input size, character set (ASCII or full Unicode), whether in-place modification is allowed, and what to return for empty or null input.
  2. Prepare the core patterns, since the reported question names only the topic. Two pointers: palindrome check, reversing in place, pair sum in a sorted array. Sliding window with a HashMap: longest substring without repeating characters in O(n). Counting maps: anagrams, two-sum in O(n). Prefix sums: count subarrays summing to k.
  3. State the brute force and its complexity, then the improvement and what data structure buys it. For example, two-sum goes from O(n^2) nested loops to O(n) with a HashMap from value to index.
  4. Java details: Strings are immutable, so concatenating in a loop is O(n^2); use StringBuilder or a char[]. Watch for int overflow in sums. Test with empty input, one element, all duplicates and negative numbers.

Follow-up

  • Solve it with O(1) extra space.
  • How does your solution change for Unicode input with surrogate pairs?
  • What if the input arrives as a stream you can read only once?

Can you write a recursive function to calculate Fibonacci numbers?

Medium · Coding / Algorithms

Approach

  1. Write the naive version with base cases fib(0) = 0 and fib(1) = 1, then fib(n) = fib(n-1) + fib(n-2). Explain why it takes exponential time (about phi^n calls, often quoted as O(2^n)): the same subproblems are recomputed again and again. Recursion depth is O(n).
  2. Fix it with memoisation (an array or HashMap cache) for O(n) time and O(n) space, then give the bottom-up loop with two variables for O(n) time and O(1) space.
  3. Handle the limits: reject negative n. fib(92) is the largest value that fits in a Java long and fib(93) overflows, so use BigInteger or work modulo a number when larger n is required.
  4. Mention the O(log n) options, matrix exponentiation or fast doubling, for very large n.

Follow-up

  • Does Java optimise tail-recursive calls, and what does that mean for deep recursion?
  • Compute fib(10^18) modulo 1,000,000,007.
  • How would you count the ways to climb n stairs taking one or two steps at a time, and why is it the same recurrence?

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?

Keep soft-deleted accounts from blocking re-registration

Easy · soft delete · unique constraints · engine differences

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

Approach

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

Follow-up

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

Explain the difference between REST and SOAP.

Medium · Technical / Domain Questions

Approach

  1. Frame the difference first: SOAP is a protocol with a fixed XML envelope (Envelope, Header, Body, Fault) and a machine-readable WSDL contract. REST is an architectural style built on resources at URIs, standard HTTP methods, stateless requests and representations, usually JSON.
  2. Compare error handling and semantics. SOAP reports errors as a Fault element inside the body and sends most calls as POST, so HTTP caching does not apply. REST uses status codes (400, 404, 409, 500), and GET, PUT and DELETE are idempotent while POST is not, which matters for retries and caching.
  3. Cover the contract and tooling. With SOAP, the WSDL drives code generation (JAX-WS in Java) and the WS-* standards add message-level security and reliable messaging. With REST, an OpenAPI spec plays that role, served from Spring MVC or JAX-RS and consumed by Angular's HttpClient.
  4. Give the decision rule. SOAP still fits enterprise or legacy integrations that need strict contracts or WS-Security. REST fits browser and mobile clients, such as an Angular front end, because it is lighter, cacheable and easy to debug.
  5. Avoid stopping at 'JSON versus XML'. REST can carry XML, and the real differences are contract, transport semantics, caching and the standards around each.

Follow-up

  • How would you version a REST API without breaking existing Angular clients?
  • How would you make a POST that creates an order safe for the client to retry after a timeout?
  • When would you choose gRPC or GraphQL over either of these?

How do you optimize a web application’s performance?

Medium · Technical / Domain Questions

Approach

  1. Measure before changing anything. Use Lighthouse or Core Web Vitals (LCP, INP, CLS) for the front end, the browser network panel for request waterfalls, and server-side p95 latency from logs or an APM tool. Then say which layer the time goes to.
  2. Front end (Angular): production AOT build with tree-shaking, lazy-loaded feature routes, bundle budgets, OnPush change detection, trackBy on ngFor lists, no expensive function calls in templates, CDK virtual scrolling for long lists, and compressed, correctly sized images.
  3. Network: gzip or Brotli compression, long-lived cache headers on hashed static assets, a CDN, HTTP/2, fewer and smaller API calls through pagination and server-side filtering.
  4. Back end (Java): remove N+1 queries (JPA fetch joins or batch fetching), add indexes after reading EXPLAIN output, size the connection pool, cache hot reads with a defined invalidation rule, and move slow work such as email or reports off the request path.
  5. Close the loop: compare before and after numbers, and add a performance budget or alert so the fix does not quietly regress.

Follow-up

  • LCP is four seconds on mobile but fine on desktop. What do you check first?
  • How do you invalidate a cached value when the underlying row changes?
  • How would you detect N+1 queries in a Java service before they reach production?

What are some common design patterns you use in your programming?

Medium · Technical / Domain Questions

Approach

  1. Name three or four patterns you have actually used, each with the problem it solved. A useful set: Strategy (swapping pricing or validation rules instead of long if-else chains), Builder (immutable Java objects with many optional fields), Observer (RxJS observables and event listeners in Angular), and Adapter (wrapping a third-party API behind your own interface).
  2. Connect them to the frameworks. Dependency injection in Spring and Angular is inversion of control. Spring beans are singletons by default, so they must not hold per-request mutable state. Angular HTTP interceptors form a chain of responsibility. Java I/O streams are decorators.
  3. For one pattern, outline the code: an interface, two implementations and a context that receives the implementation through its constructor. Explain why that makes it testable.
  4. Show judgement about the costs. A hand-rolled Singleton hides global state and hurts testing, and adding factories for a class with one implementation is over-engineering. Say when you would not use a pattern.

Follow-up

  • Write a thread-safe lazy singleton in Java. Which approach do you prefer: holder class, enum, or double-checked locking with volatile?
  • How is dependency injection different from the Service Locator pattern?
  • Tell me about a time a pattern made the code harder to work with.

How do you manage dependencies in your projects?

Medium · Technical / Domain Questions

Approach

  1. Ask which meaning is intended: build and library dependencies, or dependency injection. Answer the build meaning first and offer the other.
  2. Java side: Maven or Gradle with versions centralised in a BOM, dependencyManagement or a Gradle version catalog. Inspect transitive conflicts with mvn dependency:tree or gradle dependencies. Know the default resolution rules (Maven picks the nearest declaration, Gradle the highest version) and use exclusions when needed.
  3. Angular side: package.json semver ranges, a committed package-lock.json, npm ci in CI for reproducible installs, and ng update to move across Angular major versions one at a time.
  4. Security and upkeep: automated update PRs (Dependabot or Renovate), vulnerability scanning (npm audit, OWASP Dependency-Check), and a test suite strong enough to trust an upgrade. Upgrade often in small steps rather than in rare large jumps.

Follow-up

  • Two libraries need incompatible versions of the same transitive dependency. What are your options?
  • A scanner flags a critical CVE in a transitive dependency on a Friday. What do you do?
  • How would you plan an Angular upgrade across two major versions in a large app?

Design a URL shortening service. What components would you include?

Medium · System Design / Architecture

Approach

  1. Scope it: create a short link (with optional custom alias and expiry) and redirect to the long URL. Redirects far outnumber creations, so the read path dominates. Say this before drawing anything.
  2. API: POST /urls returns a short code, and GET /{code} redirects. Explain 301 versus 302: browsers cache a 301, which saves load but loses click analytics, while a 302 keeps every click visible.
  3. Code generation: either base62-encode a unique numeric ID, with each app server taking ID ranges from a central counter so there are no collisions, or hash the URL and check for collisions. Seven base62 characters give about 3.5 trillion codes.
  4. Storage and reads: a key-value lookup from code to URL in a store partitioned by code, a cache such as Redis in front for hot codes, and expiry handled by TTL or a cleanup job.
  5. Extras: publish click events to a queue for asynchronous analytics, rate-limit creation, and check submitted URLs for abuse.

Follow-up

  • How do you guarantee two servers never hand out the same code?
  • Should the same long URL submitted twice get the same code? What does that cost?
  • What breaks first if redirect traffic grows a hundredfold, and what do you add?

How would you approach building a real-time chat application?

Medium · System Design / Architecture

Approach

  1. Requirements: one-to-one and group messages, message history, delivery and read receipts, presence, and delivery to users who are offline.
  2. Transport: persistent WebSocket connections to a gateway tier, with long polling as a fallback, and a session registry (for example Redis) that maps each user to the gateway holding their connection.
  3. Message path: the sender's gateway forwards to a chat service, which assigns a per-conversation sequence number, persists the message, then fans it out to recipients' gateways over pub/sub. Offline recipients get a push notification and fetch from their last seen sequence number when they reconnect.
  4. Storage: messages partitioned by conversation ID and ordered by sequence, which suits a wide-column or similar store. Ordering is guaranteed only within a conversation, and the client attaches its own message ID so retries are deduplicated.
  5. Trade-offs: fan-out to a large group is expensive (consider fan-out on read for very large groups). Presence and typing indicators are ephemeral and should not go through durable storage.

Follow-up

  • How do you guarantee message order in a group chat when members are on different gateways?
  • A gateway node crashes. What happens to its connected users and in-flight messages?
  • How would you add end-to-end encryption, and what does it rule out on the server?

Explain how you would structure a microservices architecture for an e-commerce platform.

Medium · System Design / Architecture

Approach

  1. Split by business capability, each service owning its data: catalog, search, cart, order, payment, inventory, user and auth, shipping, notification. Say why a service boundary goes where it does, not only that it exists.
  2. Communication: an API gateway handling routing and auth for the web client, synchronous REST for reads that need an answer now, and asynchronous events (OrderPlaced, PaymentCaptured, StockReserved) through a message broker for the rest.
  3. Checkout spans services, so use a saga (orchestrated or choreographed) with compensations: reserve stock, charge payment, and release the reservation if the charge fails. Use a transactional outbox so the database write and the published event cannot diverge.
  4. Resilience: timeouts, retries with idempotency keys, circuit breakers and bulkheads so a slow recommendation service cannot take checkout down.
  5. Operations: one container image and pipeline per service, distributed tracing with a correlation ID, and centralised logs. Say when a modular monolith is the better starting point for a small team.

Follow-up

  • How do you prevent overselling stock during a flash sale?
  • How do you build an order-history page that needs data from orders, payments and shipping?
  • How would you carve the first service out of an existing Java monolith?

Discuss the trade-offs of using a NoSQL database versus a relational database for a specific use case.

Medium · System Design / Architecture

Approach

  1. Anchor the comparison in a concrete use case and its access patterns. For example, orders and payments need multi-row transactions, foreign keys and ad-hoc reporting, which points to a relational database. A product catalog with highly variable attributes, a session store or an activity feed may fit a document or key-value store.
  2. Relational strengths: ACID transactions, joins, constraints, mature SQL tooling and flexible querying. Scaling: vertical first, then read replicas, with sharding as the hard step.
  3. NoSQL families and their costs: document, key-value, wide-column and graph stores, designed around known queries, with built-in horizontal partitioning and often tunable or eventual consistency. Denormalised copies must be kept in sync, and a new query pattern can force a remodel.
  4. Give the decision rule and the hybrid option. Use relational when correctness across entities and evolving queries matter, and NoSQL when one access pattern at very high scale dominates. Many systems combine them, such as PostgreSQL for orders and Redis for caching, and JSON columns in PostgreSQL blur the line.

Follow-up

  • How would you model a many-to-many relationship, such as products and categories, in a document store?
  • Product asks for a new query your NoSQL key design does not support. What are your options?
  • How do read replicas affect read-your-own-writes behaviour, and how do you handle it?

How do you ensure data consistency in distributed systems?

Medium · System Design / Architecture

Approach

  1. Start by naming the consistency each operation needs: strong or linearizable for balances and stock counts, read-your-own-writes for a user's profile, eventual for counters and feeds. Use CAP and PACELC to explain the trade-off under a network partition and under normal latency.
  2. Within one database, use transactions and optimistic locking (a version column, for example JPA @Version) to prevent lost updates. Across services, avoid two-phase commit, whose coordinator can block, and use sagas with compensating actions.
  3. Make messaging safe: a transactional outbox so the state change and the event commit together, at-least-once delivery, and idempotent consumers that record processed message IDs.
  4. For replicated storage, use leader-based replication or quorum reads and writes (R + W > N). Add reconciliation jobs that detect and repair drift, because some divergence will happen anyway.

Follow-up

  • The service commits to its database and crashes before publishing the event. What happens, and how does the outbox fix it?
  • How do you make a payment consumer idempotent?
  • Where would you refuse eventual consistency in an e-commerce system?

A team member is consistently missing deadlines. How would you address this situation?

Medium · Problem-solving / Case Studies

Approach

  1. Start with a private, curious conversation. Look for the cause before deciding on a fix: unclear requirements, too many parallel tasks, consistent underestimation, a skill gap or something personal.
  2. Bring data rather than impressions: which tasks slipped, by how much, and whether there is a pattern, such as always on integration work.
  3. Match the remedy to the cause: smaller tasks with earlier checkpoints, clearer acceptance criteria, pairing on unfamiliar parts of the stack, and raising blockers at standup.
  4. Say what you can do as a peer versus as the lead, when you would bring in the manager (with facts, after giving support a fair chance), and how you protect the team's commitment in the meantime.

Follow-up

  • They tell you the cause is personal. How does your approach change?
  • They disagree that there is a problem. What now?
  • At what point do you involve their manager?

Given a set of requirements, how would you estimate the time needed for a software project?

Medium · Problem-solving / Case Studies

Approach

  1. Break the requirements into tasks small enough to estimate with confidence, about a day or two each, and include the work people forget: tests, code review, integration, deployment, documentation.
  2. Estimate against comparable past work. Use three-point estimates (optimistic, most likely, pessimistic; PERT weights them (O + 4M + P) / 6) or story points with the team's measured velocity.
  3. Find the biggest unknowns and spike them first, account for dependencies on other teams, and give a range with stated assumptions rather than a single date.
  4. Re-estimate as you learn and track actual effort against estimates, so the next estimate is calibrated.

Follow-up

  • Your manager needs a number tomorrow and the requirements are vague. What do you give them?
  • The business says your estimate is too high. How do you respond?
  • Tell me about an estimate you missed and why.

How do you approach learning a new technology or programming language?

Medium · Problem-solving / Case Studies

Approach

  1. Describe a repeatable process: official docs and a tutorial, then build something small but real, then read production code that uses it well, then ship a low-risk change and get it reviewed.
  2. Map new concepts onto ones you know. Coming to Angular from another framework, for example, means mapping components, services, dependency injection and RxJS streams onto their equivalents.
  3. Give one recent concrete example: what you learned, the first thing you shipped with it, and what you got wrong at first.
  4. Mention how you check understanding: writing tests, explaining it to a teammate, reading the source when the docs fall short.

Follow-up

  • What is the most recent technology you learned, and what surprised you about it?
  • How do you decide whether a new tool is worth adopting for the team?
  • How do you learn something whose documentation is poor?

What steps would you take if you encountered a significant performance issue in your application?

Medium · Problem-solving / Case Studies

Approach

  1. Define the problem in numbers: which metric (p95 or p99 latency, throughput, CPU, memory), the baseline, when it began and what changed then.
  2. Localise with tools. Use traces to find the slow span. On the JVM, use a profiler (JFR, async-profiler), GC logs, thread dumps for lock contention and heap dumps for leaks. In the database, use the slow query log and EXPLAIN ANALYZE. In Angular, use the DevTools profiler to spot change-detection churn.
  3. Fix the biggest contributor first, and check the usual causes: N+1 queries, missing indexes, connection-pool exhaustion, unbounded caches, synchronous calls that could be batched or made asynchronous.
  4. Prove it with a before-and-after load test (JMeter or Gatling) on the same scenario, then add an alert or performance budget so it does not regress.

Follow-up

  • CPU is low but latency is high. Where do you look?
  • How do you confirm a memory leak in a JVM service and find what holds the references?
  • How do you stop the same regression from shipping again?

You have a bug reported in production. Walk us through your troubleshooting process.

Medium · Problem-solving / Case Studies

Approach

  1. Triage first: severity, affected users and whether it is spreading. Mitigate before diagnosing (roll back, disable a feature flag) when users are harmed, and post status updates while you work.
  2. Gather evidence: error logs and stack traces, request or correlation IDs, metrics around the onset, and what changed (deploys, config, data, dependencies).
  3. Reproduce and narrow: copy the failing input into a test environment, then split the stack. Use the browser console and network tab for Angular, and server logs and thread dumps for Java. Then check the database and external calls, and use git bisect if a release is involved.
  4. Fix and prevent: write a failing unit or integration test first, deploy the fix, confirm the metrics recover, then hold a blameless postmortem with owned action items.

Follow-up

  • You cannot reproduce it locally. What do you do next?
  • It affects only some users. How do you find what they have in common?
  • How do you tell the actual cause from something that merely changed at the same time?

Suggested practice checklist

Each day targets one cluster of the reported questions in the order of the reported stages: coding fundamentals first, then domain and design questions, then stories and scenarios. Every day produces an artifact you can review on the last day.

Day 1 — Java fundamentals: linked lists and recursion

  • Write iterative and recursive linked-list reversal in Java and test both on empty, one-node, two-node and long lists.
  • Write naive, memoised and iterative Fibonacci, time all three for n = 40, and confirm where a long overflows.
  • Say the complexity of every version out loud, as if explaining it to an interviewer.

Deliverable: A Java file with both reversal methods and three Fibonacci methods, their tests passing, and a comment stating each one's complexity.

Day 2 — Graphs, sorting and array or string patterns

  • Implement BFS shortest path and Dijkstra with a PriorityQueue in Java, including path reconstruction and the unreachable-node case.
  • Write merge sort from memory and explain quicksort's worst case and what Arrays.sort does for primitives and for objects.
  • Solve one two-pointer, one sliding-window and one prefix-sum problem, each first as a brute force and then optimised.

Deliverable: Working Dijkstra and merge sort implementations plus three solved array or string problems, each with brute-force and optimised complexities noted.

Day 3 — Web and API knowledge

  • Write a one-page comparison of REST and SOAP covering contract, errors, idempotency, caching and when to choose each.
  • Pick three design patterns you have used, and for each write a short Java or Angular outline and the problem it solved.
  • Run mvn dependency:tree or npm ls on a real project and note one conflict or outdated package and how you would resolve it.

Deliverable: A REST versus SOAP comparison page, three pattern outlines, and a dependency audit note from a real project.

Day 4 — Performance and production troubleshooting

  • Run Lighthouse on an Angular app you know, fix one finding (lazy route, OnPush, trackBy or image size) and record the before and after numbers.
  • Write your production-bug runbook: triage, mitigation, evidence, reproduction, fix with test, postmortem.
  • Write the steps for a slow Java endpoint: tracing, profiler, EXPLAIN on the slow query, load test to confirm.

Deliverable: One measured front-end fix, a written troubleshooting runbook and a performance-investigation checklist.

Day 5 — System design

  • Sketch the URL shortener and the real-time chat application end to end: API, ID or sequence scheme, storage, cache, failure handling.
  • Split an e-commerce platform into services and walk through checkout as a saga with an outbox and compensations.
  • Write a decision table comparing relational and NoSQL storage for orders, catalog and sessions, and work through the soft-deleted-accounts SQL practice question as a relational modelling exercise.

Deliverable: Two design diagrams, a checkout saga walkthrough, a storage decision table and a solved SQL practice question.

Day 6 — Behavioral story bank

  • Write a two-minute account of your strongest Java and Angular project: architecture, one hard problem per layer, and your role.
  • Write STAR outlines for the challenging-project, conflict, leadership, prioritisation and motivation questions, each with a measurable result.
  • Record yourself answering three of them and cut any sentence where 'we' hides what you did.

Deliverable: Six STAR outlines with results and reflections, plus three recorded answers you have reviewed.

Day 7 — Scenarios and a full mock

  • Answer the teammate-missing-deadlines scenario twice, once as a peer and once as the lead, and note how your options differ.
  • Estimate a small feature from a written requirement list using a task breakdown and three-point estimates, and present it as a range.
  • Run a mock with a friend: one coding question, one design question, two behavioral questions and a learning-a-new-technology answer; then review the artifacts from days 1-6.

Deliverable: Written answers for the two scenarios, one worked estimate, and notes from the mock listing the three weakest spots to revisit.

Behavioural preparation

Candidates report a dedicated Behavioral Interview about past experience and cultural fit. Reported example questions also cover differing opinions, feedback and explaining technical work to non-technical colleagues. Prepare stories from your own Java and Angular work that show decisions you made, how you worked with product and design partners, and a measured result.

  1. Describe a situation where you had to communicate complex technical information to a non-technical audience.

Describe your experience with Java and Angular, including key projects.

Medium · Technical / Domain Questions

Approach

  1. Choose one or two projects and describe the architecture in a few sentences: what the Angular client did, which Java services it called, how they talked (REST, JSON) and where the data lived.
  2. Show specific depth in each layer. In Angular, cover components and services with dependency injection, RxJS observables, routing with guards, reactive forms and change detection. In Java, cover the framework you used, collections, streams, concurrency and how you tested it.
  3. Tell one hard technical problem per layer and the numbers around it, for example cutting an Angular list's render time with OnPush and trackBy, or fixing a slow endpoint by removing N+1 queries.
  4. Make your own role explicit: what you designed, what you owned in review, what you would change now. Skip the list of every library you touched, because it hides your decisions.

Follow-up

  • How did you manage shared state in Angular: services with a BehaviorSubject, NgRx, or something else, and why?
  • How did authentication work between the Angular client and the Java API?
  • Which part of that codebase would you restructure today, and how?

Describe a challenging project you worked on. How did you manage the challenges?

Medium · Behavioral / Leadership

Approach

  1. Choose a project where the difficulty was real and specific (a hard technical constraint, a moving deadline, unclear requirements, a legacy Java or Angular codebase) and where you made the key decisions.
  2. STAR structure: set the situation in two sentences, state your task, then spend most of the answer on actions: the options you considered, the one you chose and why, and how you reduced risk (a spike, a feature flag, an incremental rollout).
  3. Give a measurable result (shipped by a date, latency reduced by a figure, defects down) and one thing you would do differently.
  4. The usual mistake is a 'we' story where your contribution never appears, or a challenge that amounts to long hours rather than a hard problem.

Follow-up

  • What was the hardest trade-off, and what did it cost?
  • How did you keep stakeholders informed when the plan slipped?
  • If you started that project again tomorrow, what would you change first?

How do you handle conflicts within a team?

Medium · Behavioral / Leadership

Approach

  1. Use a real disagreement, ideally a technical one such as a library choice, REST versus messaging, or how much to refactor before a release, with real stakes.
  2. Show the sequence: you restated the other person's position until they agreed with your summary, agreed decision criteria, and settled it with evidence (a prototype, a benchmark, a small trial) rather than seniority.
  3. Explain the outcome for both the project and the relationship, including disagreeing and committing if the decision went the other way.
  4. Answers fail when they cast the colleague as the villain, settle everything by escalating, or claim you never have conflicts.

Follow-up

  • What would you have done if the evidence had shown you were wrong?
  • When is escalating to a manager the right call?
  • How do you handle a disagreement with someone more senior than you?

Give an example of a time when you took the lead on a project.

Medium · Behavioral / Leadership

Approach

  1. Pick a case where you led without being asked or without a title: a migration, a feature across front end and back end, an incident follow-up.
  2. Name the mechanisms you used: a short design note, a kickoff that agreed scope, broken-down tasks with owners, a visible tracker, a risk list and regular status updates.
  3. Include a setback in the middle (a blocker, a dependency that slipped, a teammate who was overloaded) and how you handled it.
  4. End with the measured result and how the team worked afterwards. Leading means coordinating and unblocking others, not doing all the work yourself.

Follow-up

  • What did you delegate, and how did you decide?
  • How did you handle a team member who was not delivering their part?
  • How did you know the project had succeeded?

How do you prioritize tasks when working on multiple projects?

Medium · Behavioral / Leadership

Approach

  1. State your rule: impact and cost of delay first, then deadlines, then dependencies (work that unblocks other people goes first), with production incidents interrupting everything.
  2. Back it with one real example of two competing projects: what you compared, what you put off, and who you told.
  3. Show that you make trade-offs visible rather than absorbing them. Raise conflicts in sprint planning or with your manager, renegotiate scope, and timebox work.
  4. Weak answers are a tool list with no example, or 'I just work longer hours'.

Follow-up

  • Two stakeholders each say their request is the top priority. What do you do?
  • A production bug lands mid-sprint. How do you rebalance the sprint?
  • Tell me about a time you got the priority wrong.

What motivates you to perform well in your role?

Medium · Behavioral / Leadership

Approach

  1. Name one or two honest, specific motivators, such as shipping features users actually touch, untangling hard bugs, or learning a new layer of the stack.
  2. Prove each one with a short example from your work where that motivator changed what you did.
  3. Tie it to this role: full-stack work from Angular screens to Java services gives a direct line from your code to what users see.
  4. Avoid generic 'passion for technology', answers that only praise the company, and answers that admit nothing you find draining.

Follow-up

  • What drains your motivation, and how do you handle it?
  • Tell me about a time your motivation dropped on a project.
  • What would make you leave a role?