Interview guides · An applied AI
An applied AI Software Engineer Interview Guide
An applied AI Software Engineer interview guide: reported questions on Java GC, OAuth and JWT, payment design and caching, plus a 7-day prep plan.
The 60-second brief
Candidates describe An applied AI as a company that builds AI-driven products for the everyday operational work of professionals. As candidates relay it, the Software Engineer role owns large parts of the product stack: backend services, data pipelines, and the experimentation infrastructure used for user acquisition, with engineers taking features from a hypothesis through to deployment. The requirements candidates cite are a strong primary language (Java, or TypeScript with React), database design across SQL and NoSQL stores, and microservices experience. AWS, Kubernetes and experimentation tools such as GrowthBook or Statsig are listed as nice to have.
This guide is for engineers preparing for the An applied AI Software Engineer loop, especially backend-leaning candidates working in Java or TypeScript. It covers the three rounds candidates report (Technical Screening, Architectural Discussion, Behavioral Assessment), gives a worked approach and likely follow-ups for each of the sixteen reported questions, from Java 8 garbage collection and OAuth/OIDC to distributed median finding and idempotent payments, and turns them into a seven-day plan. It does not cover frontend-only or ML-specific preparation, because the reported questions do not ask for it.
Candidates report three rounds over roughly three to five weeks: a Technical Screening, then an Architectural Discussion centred on how you design and structure systems, then a Behavioral Assessment about fit and about how you work without close direction.
Focus areas
- Object-Oriented Programming (OOP)
- Authentication & Authorization
- Java
Overview
The work candidates describe is backend-heavy product engineering: services, data pipelines and experimentation infrastructure, owned from idea to production. The reported questions follow the same line. Several ask you to choose between real options and defend the choice (relational versus non-relational storage, horizontal versus vertical scaling, embedded versus external caches), and several are about correctness across services (authentication in a distributed system, an idempotent payment flow, debugging a production issue across microservices). Prepare each one as a decision with named trade-offs, not as a definition.
Java depth is the clearest technical theme. Candidates describe an evaluation area on core Java and backend fundamentals that spans threads and concurrency, heap and memory behaviour, Streams, Spring Boot with Hibernate, JVM tuning, custom annotation processing and how dependency injection works inside the framework. The reported question on Java 8 garbage collection, and a related example about a high-throughput Java service suffering frequent GC pauses, mean you should be able to explain the generational heap, the move from PermGen to Metaspace, the Parallel, CMS and G1 collectors, and how you would read a GC log before changing a single flag.
For design, candidates list API gateway patterns, load balancing, microservice boundaries, database consistency models, distributed locking, CAP trade-offs and partial failure handling, and cite an example of designing an app for EV charging stations that takes payments and finds nearby services in real time. Candidates also report that some interviewers push back on design choices and that teams sometimes adapt the technical portion to the domain of the specific role. Practise defending a choice under a changed constraint, and practise abandoning it cleanly when the new constraint makes it wrong.
On coding, candidates report that a baseline in data structures and algorithms is expected but that the emphasis leans toward practical problem solving and clean code over memorised puzzle patterns; the reported coding question is an anagram problem on a 2D table. The topic tags candidates attach to this loop are object-oriented programming, authentication and authorization, Java, JWT and system design, so make sure your OOP vocabulary (encapsulation, composition over inheritance, interfaces for testability) and your JWT handling are as fluent as your design answers. Candidates also report that talking through your reasoning matters even before you reach a final answer.
The An applied AI interview process
Candidates report three stages in this order, moving from a technical baseline check to architecture and then to behavior and autonomy.
Technical Screening
Candidates describe the Technical Screening as the first check of your technical baseline and of how clearly you communicate. Nothing more specific about its format is reported, so prepare for both short concept questions and a hands-on problem in your main language. Because candidates report that explaining your thinking counts, practise narrating as you work: restate the problem, say which interpretation you are choosing, name the brute force and its cost, then improve it. Keep concept answers structured (definition, how it works, when it fails, what you did with it) so they stay short and checkable.
What to demonstrate
- A working technical baseline in your primary language, Java or TypeScript per the requirements candidates cite
- Clear communication of your reasoning, per the round's reported description
How to prepare
- Solve the anagram-in-a-2D-table problem in Java or TypeScript out loud, covering both the grid-search and the group-anagrams interpretations, with a sliding-window frequency count
- Write a concise spoken answer on how a service validates a JWT (signature via JWKS, iss, aud, exp, algorithm pinning) and where authorization checks belong
- Review OOP and Java concurrency basics with one example each: an interface used for dependency injection, composition replacing inheritance, and a ConcurrentHashMap or ExecutorService use you can explain
- Rehearse the Java 8 garbage collection explanation so you can deliver the collector names, the Metaspace change and one tuning example without notes
Architectural Discussion
Candidates report that the Architectural Discussion centres on how you design and structure systems. They also report that some interviewers push back on design choices and that teams may adapt the technical content to the role's domain. Approach it by fixing requirements and scale first, writing down the read and write paths, choosing storage from the access pattern, and stating the consistency you need on each path. When a choice is challenged, restate the new constraint, say what it breaks in your design, and either defend the choice with a concrete reason or change it and name the cost.
What to demonstrate
- System design and architecture, the round's reported subject
- Design choices on database selection, caching and service communication, which candidates advise being ready to defend
- Database consistency models and partial failure handling, which candidates list among the design topics
How to prepare
- Outline a payment flow end to end: idempotency keys with a unique constraint, a payment state machine, an append-only ledger, the outbox pattern and a reconciliation job
- Design the EV charging app candidates cite as an example: a geospatial lookup for nearby stations plus the payment path, and say which parts need strong consistency
- Write a one-page comparison of embedded (Caffeine), external (Redis) and CDN caching with invalidation and stampede protection for each
- Practise the distributed median question with an exact counting approach and a mergeable KLL sketch, and explain when you would accept the approximate answer
Behavioral Assessment
Candidates report that the Behavioral Assessment looks at cultural fit and at whether you can work on your own without close direction. Candidates report four behavioral questions without saying which round asked them: a technical disagreement with a stakeholder, getting productive on a new team, running out of time on requirements, and stepping into a leadership role you feel unready for. A question on keeping code quality up under deadline pressure is reported under problem solving and coding, so it may come up in the technical screen instead; a short story for it is still worth having. Candidates suggest the STAR structure. Build each story around a decision you made yourself, the alternatives you rejected, and a result you can state with a number or a concrete outcome.
What to demonstrate
- Cultural fit, per the round's reported description
- Ability to operate autonomously, per the round's reported description
How to prepare
- Write four STAR stories, one per reported behavioral question, each naming the decision you made and the measurable result
- Prepare stories that show how you handle disagreement and ambiguity, and for the scope-cut story list exactly what you cut, what you protected and how you tracked the debt
- Rehearse every story in first person singular, keeping your own actions separate from the team's, and remove any sentence where the team acted but you did not
- Prepare a follow-up answer for each story: what you would change if you ran it again
Where candidates lose points
Answering the Java 8 garbage collection question with only "Java 8 uses G1" and nothing on Metaspace or pause behaviour.
Learn the facts precisely: Parallel GC is the Java 8 default, CMS and G1 are available, G1 became the default in Java 9, and PermGen was replaced by Metaspace. Pair them with a tuning sequence that starts from GC logs and allocation rate, not from flags.
Designing the payment system with "retry until it succeeds" and no idempotency or reconciliation.
Lead with the duplicate-charge failure: idempotency keys with a unique constraint and stored response, a state machine, an append-only ledger, an unknown state after provider timeouts, an outbox for events, and a reconciliation job against provider reports.
Treating OAuth 2.0 as a login protocol and skipping how a JWT is verified or revoked.
Separate authorization (OAuth 2.0), authentication (OIDC) and enterprise SSO (SAML). Be ready to list the JWT checks (signature via JWKS, iss, aud, exp, pinned algorithm) and to explain short expiry plus refresh-token rotation as the answer to revocation.
Starting to code the 2D anagram problem before agreeing what it means, then recounting every window from scratch.
Spend the first minutes on which reading applies (grid search or grouping) and on the directions allowed. Use a sliding window with a 26-count difference so each step is O(1), and state the complexity before you write code.
Behavioral answers told as "the team decided" with no personal decision or outcome.
Candidates report the behavioral round looks at working autonomously, so every story needs a decision you made, the option you rejected and a result you can state. Rewrite each story in first person singular and cut any part where you only watched.
Questions & practice
Explain the evolution of Garbage Collection in Java 8 and its impact on performance.
Medium · Technical & Domain Expertise
Approach
- Lay out the generational heap first: young generation (Eden and two survivor spaces) collected by frequent minor GCs, old generation collected by major or full GCs, and stop-the-world pauses as the cost that matters for latency.
- State the Java 8 changes precisely: PermGen was removed and class metadata moved to Metaspace in native memory (bounded with MaxMetaspaceSize); the default collector in Java 8 is Parallel GC; CMS is available for lower old-generation pauses; G1 is available and production ready, and it became the default in Java 9. Java 8u20 added G1 string deduplication.
- Compare the impact: Parallel maximises throughput but has long full pauses; CMS collects the old generation concurrently but fragments and can fall back to a full GC on concurrent mode failure; G1 splits the heap into regions and targets a pause goal set by MaxGCPauseMillis, with humongous allocations as a known pitfall.
- Show a tuning sequence for a service with frequent pauses: turn on GC logging (PrintGCDetails, Xloggc), check allocation rate and promotion rate with jstat or the logs, reduce allocation in hot paths first, then size the heap (Xms equal to Xmx), then choose or tune the collector.
- Close by noting later options such as ZGC and Shenandoah for very low pause targets, so the answer shows you know Java 8 is not the end state.
Follow-up
- How would you optimise a high-throughput Java application that is seeing frequent GC pauses?
- What causes a full GC under G1, and how would you spot it in the log?
- How would you find a memory leak in a running service?
How would you approach an Anagram problem in a 2D table?
Medium · Problem Solving & Coding
Approach
- Clarify the problem before coding, because the title fits two readings: find occurrences of anagrams of a target word in rows, columns (and possibly diagonals) of a character grid, or group the strings stored in a 2D table into anagram groups.
- Grid reading: for each row, column and diagonal, slide a window of length k (the target length) and keep a 26-entry count difference against the target plus a counter of matching letters, so each step updates two counts in O(1). Total cost is O(R x C) per direction instead of O(R x C x k) for recounting each window.
- Group reading: flatten the table and build a hash map from a canonical key to the list of words. The key is either the sorted word, O(L log L) per word, or a tuple of 26 letter counts, O(L) per word. Return the groups with their cell positions if the caller needs them.
- Edge cases: target longer than a row or column, upper and lower case, non-letter characters, overlapping matches, single-letter targets, and empty cells. Test with a small grid where the answer is known by hand.
Follow-up
- What if the word may follow any path of adjacent cells instead of a straight line?
- How would you search for many target words at once?
- How does the solution change if the alphabet is Unicode rather than 26 letters?
How do you ensure code quality when working under tight deadlines?
Medium · Problem Solving & Coding
Approach
- Treat this as a judgment question backed by an example: state what you never drop (tests on core logic and on money or auth paths, code review, CI checks) and what can wait (refactors, polish, broad edge-case coverage on rarely used paths).
- Describe the mechanics that keep quality cheap under pressure: small pull requests, linting and static analysis in CI, feature flags so unfinished work ships safely, and a quick self-review checklist before requesting review.
- Make the debt visible: file tickets for every shortcut with the risk written down, and agree with the team when they will be addressed.
- Give a concrete case: the deadline, the shortcuts you took, the ones you refused, and what happened after release, including any bug the protected tests caught.
Follow-up
- When is it acceptable to ship without tests?
- Tell me about a shortcut that came back to cause a problem.
- How do you convince a team to pay down the debt after the deadline?
Replace offset paging on the resource feed with keyset
Easy · keyset pagination · composite index · sort order
resource holds resource_id, tenant_id, owner_user_id, title, body_ref, version, status ('draft','active','archived','deleted'), created_at, updated_at, deleted_at, with an index on (tenant_id, status, updated_at DESC, resource_id DESC). The listing endpoint returns active resources for one tenant, newest update first, 50 per page, today with LIMIT 50 OFFSET n. Tenants reach page 400 and rows are created while they read. Write the keyset query, define what the cursor carries and how it is encoded, and say which part of the index each predicate uses. Assume PostgreSQL 16.
Approach
- Name the two failures separately. OFFSET 20000 makes the server produce and discard 20,000 rows, so page cost grows with depth rather than with page size. Independently, any write that changes how many rows sort above the offset moves the window between two fetches, and the direction decides which anomaly you get: an insert lands at the head of updated_at DESC and pushes already-returned rows down past the boundary, so they are returned a second time; a delete above the offset, or a row whose updated_at is bumped above the cursor, pulls rows up and one is never returned at all. Nothing in the response reveals either.
- Write the seek: WHERE tenant_id = $1 AND status = 'active' AND (updated_at, resource_id) < ($2, $3) ORDER BY updated_at DESC, resource_id DESC LIMIT 50. The row-value comparison is one index range rather than a disjunction, and both columns are NOT NULL, which is what makes that comparison well defined.
- Map each predicate onto the index: tenant_id and status are equality on the leading columns, (updated_at, resource_id) is the range, and the ORDER BY matches the index order so no Sort node appears and the scan stops after 50 rows. The DESC in the definition only matters for mixed directions — a plain ascending btree on the same columns is read backwards for this query.
- Put both sort columns in the cursor and nothing the client can tamper with into another tenant: base64 of (updated_at, resource_id), validated server-side, with tenant_id taken from the principal.
Follow-up
- The client asks for 'jump to page 400'. What do you offer instead, and what does the honest version cost?
- Sort order becomes user-selectable across four columns. How many indexes is that, and which would you refuse to add?
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?
Explain the 12-factor app methodology and how you apply it to your projects.
Medium · Technical & Domain Expertise
Approach
- Name the twelve factors in groups so the list is easy to follow: codebase and dependencies; config in the environment and backing services as attached resources; build, release, run as separate stages; stateless processes, port binding and concurrency through the process model; disposability; dev/prod parity; logs as event streams; admin processes run as one-off tasks.
- Pick the four you actually apply and give a concrete example of each: Spring Boot reading config from environment variables or Kubernetes ConfigMaps, one Docker image built once and promoted across environments, sessions moved out of memory into Redis so instances stay stateless, and logs written to stdout and shipped by the platform.
- Cover disposability properly: fast startup, handling SIGTERM with graceful shutdown that drains in-flight requests and stops consuming from queues, and idempotent jobs so a killed process can be safely restarted.
- Say where you deviate and why: secrets belong in a secret manager rather than plain environment variables, and stateful components such as databases are not twelve-factor processes and are run as managed backing services instead.
Follow-up
- How do you keep secrets out of config while still following the config factor?
- Which factor is hardest to keep in a microservices setup, and how have you handled dev/prod parity?
- How does your service behave when Kubernetes kills a pod mid-request?
What are the differences between relational and non-relational databases, and how do you decide which to use f
Medium · Technical & Domain Expertise
What are the differences between relational and non-relational databases, and how do you decide which to use for a new feature?
Approach
- Contrast the models: relational stores give a fixed schema, joins, ACID transactions and a flexible query planner; non-relational stores split into key-value, document, wide-column and graph, each optimised for a known access pattern, usually with easier horizontal partitioning and tunable or eventual consistency.
- Decide from the feature, not the fashion: list the queries the feature needs, whether writes must be transactional across entities, the expected write volume, how often the schema changes, and what the team already operates.
- Give two contrasting examples: a billing ledger or account model belongs in a relational database because of multi-row transactions and constraints; a high-volume event or activity feed keyed by user and timestamp fits a wide-column or key-value store with a partition key on user.
- Mention the middle ground: PostgreSQL with JSONB covers many semi-structured needs without a second datastore, and adding a second store brings dual-write consistency problems you then need an outbox or change data capture to solve.
Follow-up
- How would you model a many-to-many relationship in a document store?
- What happens to your NoSQL design when a new query appears that does not match the partition key?
- How do you change a relational schema on a large table without downtime?
How do you design a REST API to be secure, scalable, and maintainable?
Medium · Technical & Domain Expertise
Approach
- Model resources as nouns with standard method semantics: GET is safe, PUT and DELETE are idempotent, POST is not, so accept an Idempotency-Key header on POST endpoints that create things like orders or payments.
- Security: TLS everywhere, OAuth 2.0 bearer tokens validated on every request, object-level authorization checks on every resource id, input validation against a schema, rate limiting per client, and no secrets or personal data in URLs or logs.
- Scalability: stateless handlers behind a load balancer, cursor or keyset pagination instead of large offsets, ETag and Cache-Control on cacheable reads, and asynchronous 202 Accepted responses for long-running work.
- Maintainability: an OpenAPI contract as the source of truth, one consistent error format (for example RFC 7807 problem details) with stable error codes, a versioning scheme (URL prefix or header) and a deprecation policy with sunset dates.
Follow-up
- How do you roll out a breaking change to a field that mobile clients depend on?
- How does your pagination behave when rows are inserted while a client is paging?
- How do you stop one customer from reading another customer's records by changing an id?
How would you design a system to find the median value across multiple servers with massive datasets?
Medium · System Design & Scalability
Approach
- Clarify exact versus approximate, whether data is static or streaming, whether values are bounded integers, and whether each server's data is sorted. Note that the total count N is cheap to get first (each server reports its count).
- Exact approach without moving data: binary search on the value domain. The coordinator picks a candidate x, every server returns how many of its values are at most x, and the coordinator narrows the range until it finds the smallest x whose total count reaches the middle rank N/2 (two ranks when N is even). That costs O(log of the value range) rounds, with each round a scan or a binary search if the data is sorted.
- Alternative exact approach: distributed quickselect. The coordinator broadcasts a pivot, servers return counts below and equal, and the search recurses into one side. With a random pivot, or the median of sampled per-server medians, it needs an expected O(log N) rounds, and each round costs O(local n) work per server to partition and count.
- Approximate approach for very large or streaming data: each server builds a mergeable quantile sketch and the coordinator merges them in one round. Choose KLL when you need a guaranteed bound on the median, because it gives a provable rank-error bound. t-digest gives only empirical accuracy, strongest at the tails and weakest near the median, so it suits p99 better. For bounded integers, a fixed-bucket histogram gives exact per-bucket counts.
- Cover edge cases: duplicates around the median, even N, a server failing mid-protocol (snapshot or version the data so counts are consistent), and a slow server that delays every round.
Follow-up
- How does your design change if new values keep arriving?
- How would you return the 99th percentile instead of the median?
- What do you do if one server is consistently slow to answer?
Explain the difference between horizontal and vertical scaling and when to choose one over the other.
Medium · System Design & Scalability
Approach
- Define both: vertical scaling adds CPU, memory or faster disks to one machine; horizontal scaling adds more machines and spreads load across them.
- Vertical: no code change and no distributed-systems complexity, but a hard ceiling, rising cost per unit at the top end, a single point of failure, and often a restart to resize.
- Horizontal: near-linear capacity and fault tolerance, but it requires stateless services (sessions in Redis, no local file state), a load balancer, and for data stores replication or sharding with the consistency trade-offs that come with them.
- Give the typical pattern: scale the stateless application tier horizontally with autoscaling from day one; scale the primary database vertically first, then add read replicas, and shard only when write volume or data size forces it.
Follow-up
- What makes a service hard to scale horizontally?
- Which metric would you autoscale on, and why not just CPU?
- At what point would you shard the database, and on what key?
How do you approach designing a payment system to ensure reliability, idempotency, and data consistency?
Medium · System Design & Scalability
Approach
- Start with the failure case that defines the design: a client retries after a timeout, so every create request carries an idempotency key stored with a unique constraint, a hash of the request body, and the saved response that is replayed on retry.
- Model the payment as a state machine (created, authorized, captured, failed, refunded) with transitions guarded by conditional updates, and record money movement in an append-only double-entry ledger so balances can be rebuilt and audited.
- Treat calls to the payment provider as unreliable: pass the provider's own idempotency key, and on a timeout mark the payment as unknown and query the provider rather than charging again.
- Publish events with the transactional outbox pattern so the database write and the event cannot diverge, and make every consumer idempotent because delivery is at least once.
- Run a reconciliation job that compares internal records with provider settlement reports and flags mismatches. If the EV charging example comes up, the same core applies, with an authorization hold before charging starts and capture of the final amount when the session ends.
Follow-up
- The provider timed out after possibly charging the card: what does your system do next?
- How do you handle two refund requests for the same payment arriving at once?
- How would you reconcile when the provider's report disagrees with your ledger?
What strategies do you use for caching (e.g., embedded vs. external, CDN, Redis)?
Medium · System Design & Scalability
Approach
- Lay out the layers: a CDN for static assets and cacheable public GET responses at the edge; an embedded in-process cache (Caffeine, Guava) for hot, small, rarely changing data with nanosecond reads; an external cache (Redis, Memcached) shared by all instances for larger or shared state.
- Name the trade-offs: embedded caches are fastest but each instance holds its own copy that can go stale, and they add heap pressure in Java; external caches stay consistent across instances but add a network hop and become a dependency you must plan around.
- Pick a write pattern deliberately: cache-aside for most reads, write-through when reads must see fresh writes, write-behind only where some data loss is acceptable.
- Handle invalidation and stampedes: TTLs with jitter, explicit delete on write, versioned keys, request coalescing or a lock so one caller rebuilds a hot key, and probabilistic early refresh.
- Say what you do not cache, or cache carefully: per-user authorization results and anything personal, which must be keyed by user and never served from a shared CDN entry.
Follow-up
- How do you keep in-process caches consistent across instances when data changes?
- What happens to your service when Redis is down?
- How do you deal with a single very hot key?
Describe your process for debugging a complex production issue in a microservices environment.
Medium · Problem Solving & Coding
Approach
- Start with impact and mitigation: confirm the symptom and who is affected, then roll back the latest deploy or turn off a feature flag if one correlates, before looking for the root cause.
- Find what changed: deploys, config changes, traffic shape, and dependency or infrastructure changes in the time window when the metrics shifted.
- Localise the failing service: use per-service error rate, latency and throughput dashboards, distributed traces with a trace id (OpenTelemetry), and centralized logs filtered by that correlation id to find where errors or latency start rather than where they surface.
- Check the patterns specific to microservices: retry storms and missing timeouts that cascade, connection pool exhaustion, a slow downstream filling thread pools, version mismatches in service contracts, and data issues from out-of-order events.
- Confirm the cause with a reproduction or a targeted fix, verify with metrics, then write a blameless postmortem with action items such as alerts, timeouts or circuit breakers.
Follow-up
- How would you proceed if there is no distributed tracing?
- How do you debug an issue that happens only once in thousands of requests?
- How would you prevent the same retry storm from recurring?
Suggested practice checklist
Each day targets one cluster of the reported questions, in the order of the reported rounds: Java and coding fundamentals first, then auth, data and design, then behavioral stories. Every day ends with something written or recorded that you can review before the loop.
Day 1 — Core Java: memory, GC, concurrency, Spring and OOP
- Write a one-page explanation of the Java 8 heap (young and old generations, Metaspace replacing PermGen, Parallel, CMS and G1 with their pause trade-offs), then run a small program with GC logging on and note how pauses change with heap size and collector
- Concurrency: build a fixed thread pool with ExecutorService, compare ReentrantLock with synchronized, explain ConcurrentHashMap versus Collections.synchronizedMap, chain two CompletableFuture calls, and explain volatile and happens-before with one example
- Spring and Hibernate: refactor a loop into a Streams pipeline with Collectors.groupingBy, explain how Spring wraps a bean in a proxy for @Transactional and why self-invocation skips it, and fix a Hibernate N+1 query with a fetch join or entity graph, noting lazy-loading pitfalls
- Write short examples of an interface used for dependency injection, composition replacing inheritance, and an immutable value class, and explain each aloud
Deliverable: A GC explainer with a log comparison, a concurrency notes page, a Spring/Hibernate fix-up sheet and three annotated OOP examples.
Day 2 — Coding: the anagram grid problem
- Write both readings of the 2D anagram problem in Java or TypeScript: sliding-window search across rows, columns and diagonals, and anagram grouping with a count-tuple key
- Test each on hand-made grids covering a target longer than a row, mixed case, overlapping matches and an empty grid
- Solve it again while talking through every step aloud, stating complexity before coding
Deliverable: Two tested solutions with their complexity written at the top and a recording of the spoken attempt.
Day 3 — Authentication, JWT and REST API design
- Diagram the login and request flow for OIDC with a gateway and two services, marking where the token is issued, verified and where object-level authorization happens
- Write the JWT verification checklist and a revocation strategy using short-lived access tokens and rotating refresh tokens
- Outline a REST API for one resource with idempotency keys on POST, keyset pagination, an error format and a versioning rule
Deliverable: An auth flow diagram, a JWT checklist and an outlined API contract for one resource.
Day 4 — Databases: relational versus non-relational and SQL practice
- Write a decision table for choosing a datastore: access pattern, transactions, write volume, schema change rate, operational cost, with one example feature for each choice
- Work the keyset paging practice question, replacing offset pagination on a feed and explaining why it stays fast on deep pages
- Work the soft-deleted accounts practice question, using a partial unique index on active rows so a deleted email can register again
Deliverable: A datastore decision table and two worked SQL solutions with the indexes they rely on.
Day 5 — Design: payments, caching and scaling
- Outline the payment system end to end: idempotency table, state machine, ledger, outbox, provider timeout handling and reconciliation
- Extend it to the EV charging example candidates cite: station lookup by location plus an authorization hold and final capture
- Write a caching plan for the same system covering CDN, Caffeine and Redis, invalidation, stampede protection, and a note on which tier scales horizontally versus vertically
Deliverable: A payment and EV charging design diagram with a caching and scaling page attached.
Day 6 — Distributed problems, production debugging and twelve-factor
- Write the distributed median solution three ways: binary search on the value range with count queries, distributed quickselect with its expected O(log N) rounds, and a merged KLL sketch with its rank-error bound
- Write a step-by-step debugging runbook for a latency spike across microservices: mitigation, what changed, traces and logs, retry and timeout checks, postmortem
- Map the twelve factors to a service you have built, marking which you follow, which you break and why
Deliverable: A median design note, a debugging runbook and a twelve-factor audit of your own service.
Day 7 — Behavioral stories and a full mock
- Write STAR stories for the four reported behavioral questions: stakeholder disagreement, joining a new team, running short of time, and an unfamiliar leadership role
- Prepare a short answer with a real example for the code-quality-under-deadline question candidates list under coding
- Rehearse each aloud in first person, then answer one follow-up per story about what you would change
- Run a mock covering one concept answer, the anagram problem and the payment design, and note where your explanation slowed down
Deliverable: Four written STAR stories with follow-up answers, a code-quality answer, and a list of weak spots from the mock.
Behavioural preparation
Candidates describe the Behavioral Assessment as a check on fit and on working autonomously, and the reported behavioral questions centre on disagreement, ramping up, scope pressure and leadership. Prepare stories where you made the call, can name the trade-off, and can state the result; candidates suggest STAR to keep them tight.
How do you handle authentication and authorization in a distributed system (e.g., OAuth 2.0, OIDC, SAML)?
Medium · Technical & Domain Expertise
Approach
- Separate the protocols first: OAuth 2.0 is delegated authorization that issues access tokens; OIDC adds an authentication layer with an ID token and userinfo; SAML is an older XML-based SSO standard common with enterprise identity providers. Say which you would use for user login (OIDC, with SAML federation for enterprise customers) and for service-to-service calls (client credentials or mTLS).
- Describe the request path: an identity provider issues short-lived signed access tokens (JWT, RS256 or ES256); the API gateway validates them, and each service still verifies signature against the cached JWKS plus iss, aud and exp, with the accepted algorithm pinned so alg=none or key-confusion tricks fail.
- Keep authorization separate from authentication: coarse scopes or roles in the token, fine-grained checks (does this user own this record) inside the service that owns the data, which is where object-level authorization bugs are prevented.
- Address revocation and lifetime: short access-token expiry with rotating refresh tokens, a deny-list or token introspection for high-risk actions, and the trade-off that self-contained JWTs avoid a network call but cannot be revoked instantly.
- Mention propagation: forward the user identity or a downscoped token between services, and carry it in message metadata for asynchronous work so consumers can still enforce access.
Follow-up
- How do you revoke a JWT before it expires?
- Would you enforce authorization at the gateway or in each service, and why?
- How do you rotate signing keys without logging everyone out?
Tell me about a time you had a technical disagreement with a stakeholder. How did you resolve it?
Medium · Behavioral & Leadership
Approach
- Choose a disagreement with real technical stakes, for example a product manager wanting a feature shipped on a schema you believed would not scale, and state both positions fairly in a couple of sentences.
- Show how you made the trade-off concrete: a quick benchmark, a prototype, a cost or risk estimate, or a phased plan that gave the stakeholder the date while limiting the risk.
- Say what you conceded and what you held firm on, and how the decision was recorded so it was not reargued later.
- End with a measured result and the effect on the working relationship. The story fails if it reads as you being right and the other person being wrong, or if it never reaches a decision.
Follow-up
- What would you have done if the decision had gone against you?
- What did you learn about how that stakeholder makes decisions?
- Looking back, was your position actually correct?
You are new to a team and don't know anyone; what steps do you take to ensure you are productive quickly?
Medium · Behavioral & Leadership
Approach
- Use a real onboarding story and give the sequence of steps: get the local environment and the deploy pipeline working, then ship a small change to production early to learn the path end to end.
- Build context deliberately: read the architecture docs and incident write-ups, sketch the system diagram yourself and ask a teammate to correct it, and hold short one-on-ones with engineers and the product owner to learn priorities and pain points.
- Show independence: keep a written list of questions, batch them, and answer what you can from code and logs first. Candidates report the behavioral round looks at working autonomously, so make this part concrete.
- Close with an outcome, for example the first meaningful feature or fix you owned and how soon it shipped, and one thing you improved for the next new hire, such as fixing setup docs.
Follow-up
- What do you do when the documentation is wrong or missing?
- How do you know when you have become productive?
- How do you ask for help without blocking on someone else?
What is your process for handling a project where you do not have enough time to finish all requirements?
Medium · Behavioral & Leadership
Approach
- State the process first: separate must-have requirements from nice-to-haves with the stakeholder, using the user outcome as the test, and size what remains honestly.
- Bring options rather than a problem: cut scope, move the date, or phase delivery behind a feature flag, each with its consequence, and raise it early rather than at the deadline.
- Protect the parts that are expensive to fix later (data model, correctness on core paths, tests around them) and record deferred work as tracked tickets with an owner.
- Back it with a real example: what was cut, who agreed, what shipped, and whether the deferred items were later completed or dropped.
Follow-up
- Who made the final call on scope, and how did you get agreement?
- What did you cut that you later regretted?
- How did you communicate the change to people who expected the full scope?
How do you handle a situation where you are asked to take on a leadership role for which you feel you lack exp
Medium · Behavioral & Leadership
How do you handle a situation where you are asked to take on a leadership role for which you feel you lack experience?
Approach
- Pick a real case, such as leading a project, a migration or a small group for the first time, and state honestly which skills you lacked.
- Show a plan: what you did to close the gap (asking an experienced lead to mentor you, reading, setting up regular check-ins and a clear plan document), and how you split work and delegated rather than doing it all yourself.
- Show how you asked for feedback and what you changed because of it.
- Finish with the outcome of the project and what you would now do differently. Avoid both extremes: claiming no gaps, or describing so much doubt that you never took ownership.
Follow-up
- What was the hardest part of the role, and how did you handle it?
- What feedback did you get, and what did you change?
- Would you take on the same role again?