cswork / libraryOpen practice workspace

Interview guides · Bok financial

Bok financial Software Engineer Interview Guide

Bok financial Software Engineer interview guide: 3 reported rounds, Java backend, REST, system design and coding questions, plus a 7-day prep plan.

The 60-second brief

Candidates describe Bok financial as a financial services organisation whose software runs from personal banking applications to enterprise-level financial tools. The Software Engineer III - Java Backend title sits on the server side of that software: backend services that candidates say carry high transaction volumes and sit under compliance requirements. The work reported for the role is designing, building and testing those services, gathering requirements with product managers, UX designers and other engineers, reviewing code, tracing and tuning existing systems, and taking part in Agile ceremonies.

This guide is for engineers preparing for the Software Engineer III - Java Backend loop at Bok financial. It covers the three reported rounds (Phone Screen, Technical Interviews, Behavioral Interviews), the reported questions grouped as Java and domain, system design, behavioral, problem-solving and coding, and a seven-day plan. The requirements candidates describe list Java, RESTful API design, relational databases and Agile working as must-haves, with Spring Boot, cloud services, microservices, Docker and Kubernetes also named, so the preparation here leans on Java backend work for money-moving systems.

Candidates report three rounds spread over roughly 3-5 weeks: a Phone Screen, Technical Interviews that include coding and system design, and Behavioral Interviews.

Focus areas

  • Java (Backend Development)
  • Backend Software Engineering
  • Object-Oriented Programming (OOP)

Overview

The title is Software Engineer III - Java Backend, and the reported questions follow it closely. Java and domain questions cover object-oriented principles, design patterns, REST API structure, exception handling and unit testing. Design questions cover an online banking system, microservices, SQL against NoSQL for a financial application, and security with regulatory compliance. Coding questions are classic data-structure work: reversing a linked list, binary search, finding duplicates in an array, and reasoning about complexity.

The systems candidates describe handle high transaction volumes and compliance requirements, so a good design answer in this loop treats money movement carefully. Think about atomic transfers, idempotent retries, an audit trail and exact decimal amounts, and be ready to say why a relational store is or is not the right home for a ledger. A generic box-and-arrow diagram answers less than a design that says what happens when a transfer request is sent twice or a downstream service times out.

The reported responsibilities include code reviews, troubleshooting and optimizing existing systems, requirements gathering with product and UX colleagues, and Agile ceremonies. Those map directly onto the problem-solving questions (debugging a production issue, improving a process, balancing technical debt against features, working from unclear requirements) and the behavioral ones (a challenging project, prioritising, influencing a decision, conflict, motivation). Prepare a small set of real stories and reuse them across several prompts instead of memorising twenty separate answers.

The requirements candidates describe mention 5+ years of experience, preferably in the financial sector. If your background is outside finance, translate it: a payments-adjacent feature, anything with audit or access controls, or any system where a wrong number had a cost. Practise the Java answers aloud, because several reported questions are open conversations rather than exercises with a single correct output.

The Bok financial interview process

Candidates describe three stages. The reports give no per-round question lists, so treat the question groups in this guide as the pool to prepare from rather than a script for any one stage.

Phone Screen

Candidates report this as the first call, centred on your technical skills and your experience. The reports do not say which questions are asked on it, so prepare two things: a clear account of your most relevant Java backend project, and short spoken answers to the Java and domain questions (object-oriented principles, design patterns, REST API structure, exception handling, unit testing). Expect to be asked about the stack on your CV, so know exactly what you owned in each project and be able to name the framework, datastore and test tooling you used.

What to demonstrate

  • How clearly you describe your own Java backend experience
  • Command of core Java and backend concepts in conversation
  • How well your background lines up with the listed requirements: Java, RESTful APIs, relational databases, Agile

How to prepare

  • Write a short walk-through of your most relevant backend project: what the service did, which framework and database it used, what you personally built and one number or outcome you can defend.
  • Say aloud, in a few sentences each, how you would answer the questions on object-oriented principles, design patterns, REST structure, exception handling and unit testing.
  • List the stack items in the requirements (Spring Boot, relational databases, microservices, Docker, Kubernetes, cloud services) and mark honestly which you have used, so you never overstate on a call.
  • Prepare questions for the recruiter about what the technical and behavioral stages will contain.

Technical Interviews

Candidates report that this stage includes coding assessments and system design discussions. The coding questions people report are reversing a linked list, implementing binary search, finding duplicates in an array, discussing time and space complexity and optimizing an algorithm. The design questions reported are an online banking system, a performance bottleneck, microservices considerations, SQL against NoSQL for a financial application, and security with compliance. Prepare for both formats: write correct Java under pressure, then design a service and defend each trade-off.

What to demonstrate

  • Working Java code for standard data-structure problems, with complexity stated
  • Design of a backend system for a financial product, including data store choice
  • Trade-off reasoning on microservices, consistency and security
  • Debugging and optimization approach for a production system

How to prepare

  • Write the linked-list reversal (iterative and recursive), binary search and a duplicate finder in Java without help, and state time and space complexity for each.
  • Outline an online banking system: customer-facing API, accounts and ledger service, transfer flow, notifications, audit log, authentication, and how each piece scales and fails.
  • Prepare a one-minute comparison of SQL and NoSQL for a ledger, covering transactions, schema rigidity and where a document or key-value store would still earn a place.
  • Rehearse one real performance bottleneck from your own work: how you measured it, what you changed and how you confirmed the improvement.

Behavioral Interviews

Candidates report this stage as exploring your behavioral traits and leadership potential. The reported behavioral prompts cover a challenging project, prioritising across several projects, influencing a team decision, handling team conflict and what motivates you, and the problem-solving prompts add quick decisions with limited information, technical debt against features and unclear requirements. Build a bank of real stories in situation, task, action, result form, with your own decision at the centre of each.

What to demonstrate

  • Evidence of leadership and influence from past work
  • How you collaborate with product, design and engineering colleagues
  • How you decide and communicate under ambiguity or competing priorities

How to prepare

  • Write four to five stories (a difficult project, a prioritisation call, a decision you influenced, a conflict, a decision made with little information), each with a measurable result.
  • Map each story to several prompts so one story can answer more than one question, and note a different angle for each use.
  • For each story, write the sentence that says what you personally decided or did, and cut any passage that only describes what the team did.
  • Prepare a short account of mentoring or code-review work, since code review and cross-team collaboration are part of the reported responsibilities.

Where candidates lose points

Answering the object-oriented and design-pattern questions with textbook definitions and no Java code

Tie each principle to a class you can sketch: an Account abstraction with a SavingsAccount subtype for polymorphism, an interface for a payment gateway for abstraction. Pair each pattern with a case where you used it, such as Strategy for fee rules or Factory for gateway clients.

Presenting the online banking system as a diagram of boxes with no treatment of money movement

Add a ledger with atomic transfers, idempotent request handling, an audit trail, exact decimal amounts and an authentication and authorization layer. Then say what happens when a transfer is retried or a downstream service is down.

Picking SQL or NoSQL by habit, without reasoning about the financial workload

Argue from the requirements: transactions and constraints for balances favour a relational store, while denormalised read models or session data can sit in a NoSQL store. State where consistency is mandatory and where stale data is tolerable.

Coding the linked-list reversal or binary search with a dropped pointer, an off-by-one error or no edge cases, and never stating complexity

Practise in Java until you can write both without help. Check an empty list, a single node, an even-length array and a missing target, compute the midpoint as low + (high - low) / 2, and say O(n) time and O(1) space for the iterative reversal and O(log n) for binary search.

Telling behavioral stories in 'we' terms, with no personal decision and no measured result

For each story, write the one sentence that says what you decided and did, and attach a number or a concrete outcome. Rehearse the reported prompts (challenging project, prioritising, influencing a decision, conflict) against that same set of stories.

Questions & practice

Write a function to reverse a linked list.

Medium · Coding / Algorithms

Approach

  1. Clarify the node class and whether to return the new head; confirm singly linked unless told otherwise.
  2. Iterate with three references: prev = null, curr = head; in the loop save next = curr.next, set curr.next = prev, then advance prev = curr and curr = next; return prev as the new head.
  3. State complexity: O(n) time and O(1) extra space for the iterative version; the recursive version is also O(n) time but uses O(n) call-stack space and can throw StackOverflowError on a very long list in Java.
  4. Walk the edge cases out loud: empty list (return null), a single node, and two nodes, checking that the old head's next ends up null so there is no cycle.
  5. Test by building a list from an array, reversing it, and converting it back to compare against the expected order.

Follow-up

  • Reverse only the nodes between positions m and n.
  • Reverse the list in groups of k nodes.
  • Use reversal to check whether a linked list is a palindrome in O(1) extra space.

How would you implement a binary search algorithm?

Medium · Coding / Algorithms

Approach

  1. State the precondition: the array is sorted (ascending); binary search on unsorted data gives wrong answers.
  2. Write the closed-interval version: lo = 0, hi = n - 1, while (lo <= hi), mid = lo + (hi - lo) / 2 (or (lo + hi) >>> 1) to avoid int overflow, move lo = mid + 1 or hi = mid - 1, and return -1 if the loop ends.
  3. State complexity: O(log n) time and O(1) space for the iterative version; recursion adds O(log n) stack.
  4. Handle duplicates with the lower-bound variant: on a half-open range [lo, hi) find the first index whose value is >= target, which also gives the insertion point.
  5. Mention the library: Arrays.binarySearch returns the index if found, otherwise -(insertion point) - 1, and with duplicates it does not guarantee which matching index is returned.

Follow-up

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

Discuss the time and space complexity of your solution for a specific problem.

Medium · Coding / Algorithms

Approach

  1. Pick a concrete problem and compare solutions, for example pair-sum: nested loops are O(n^2) time and O(1) space, sorting plus two pointers is O(n log n) time, and a HashMap of seen values is O(n) expected time with O(n) space.
  2. Be precise about which case you mean: HashMap operations are O(1) on average; in Java 8+ a heavily colliding bucket becomes a balanced tree, so worst case per lookup is O(log n) rather than O(n).
  3. Explain amortised cost where it applies: ArrayList.add is amortised O(1) because the occasional resize copy is spread across many appends.
  4. Count space honestly: auxiliary space versus input, recursion stack depth, and whether the output itself is counted.
  5. Say which bound matters for the stated input size and memory limits, since an O(n log n) in-place solution can beat an O(n) solution that needs a large extra structure.

Follow-up

  • What is the space complexity of your recursive solution, including the call stack?
  • What does amortised O(1) mean, and where does it show up in the Java collections?
  • When would you choose the asymptotically slower solution?

Solve a problem related to data structures, such as finding duplicates in an array.

Medium · Coding / Algorithms

Approach

  1. Clarify the output (a boolean, the first duplicate, or all duplicates with counts), the value range, and whether the input may be modified.
  2. Give the options with costs: nested loops O(n^2) time and O(1) space; sort then compare neighbours O(n log n) time with little extra space but the input is mutated; HashSet O(n) expected time and O(n) space, using the fact that Set.add returns false when the element is already present.
  3. For counts, use a HashMap<Integer, Integer> with merge(x, 1, Integer::sum), then collect keys whose count is greater than 1.
  4. Know the constrained variant: for n + 1 values in the range 1..n, Floyd's cycle detection finds a duplicate in O(n) time and O(1) space without modifying the array.
  5. Test edge cases: empty array, no duplicates, all elements equal, negative values, and very large arrays where boxing Integer values costs memory.

Follow-up

  • Solve it with O(1) extra space and without modifying the array.
  • How would you find duplicates in a file too large to fit in memory?
  • How would you detect duplicates in an unbounded stream with limited memory, and what error would you accept?

Explain how you would optimize a given algorithm for better performance.

Medium · Coding / Algorithms

Approach

  1. Measure before changing anything: find where time is actually spent with a profiler or timing, and confirm the input sizes that matter.
  2. Reduce the complexity class first: replace repeated linear searches with a HashMap or HashSet, sort once and binary search, use prefix sums for repeated range sums, sliding window or two pointers for contiguous ranges, and memoisation or dynamic programming for overlapping subproblems.
  3. Then cut constant factors in Java: primitive arrays instead of boxed collections, StringBuilder instead of string concatenation in loops, hoisting repeated work out of loops, and avoiding needless object allocation.
  4. State the trade-off of each change, usually memory for time or code complexity for speed, and keep tests passing before and after so the result is still correct.
  5. Benchmark reliably: use JMH for microbenchmarks because JIT warm-up and dead-code elimination make naive timing loops misleading.

Follow-up

  • When is an optimisation not worth doing?
  • How would you benchmark a Java method so the result is trustworthy?
  • The faster version uses too much memory. What would you try next?

Describe the trade-offs between SQL and NoSQL databases for a financial application.

Medium · System Design / Architecture

Approach

  1. Anchor on the ledger: relational databases give multi-row ACID transactions, foreign keys, CHECK and unique constraints (for example on an idempotency key), and strong consistency, which is what balanced debits and credits need.
  2. Give relational's costs: a single primary limits write scaling, so growth means vertical scaling, read replicas, partitioning, and eventually sharding by account id with cross-shard transfers handled as sagas.
  3. Give NoSQL its real strengths: document stores for flexible, nested data such as customer profiles; wide-column stores such as Cassandra for very high write volume with tunable consistency; key-value stores such as Redis for sessions and caches.
  4. Correct the stereotype: several NoSQL databases now offer transactions (MongoDB supports multi-document transactions), so the deciding factors are the query patterns, joins and reporting needs, consistency guarantees and the team's operational experience.
  5. Land on a polyglot answer with reasons: ledger and transfers in a relational store, cache and sessions in a key-value store, analytics or event history in a store suited to append-heavy reads, each with a defined source of truth.

Follow-up

  • Which isolation level would you use for a transfer, and would row locks or SERIALIZABLE be the better fit?
  • How would you scale the relational ledger once one primary can no longer handle the writes?
  • Where in a banking application is eventual consistency acceptable?

Find version gaps and relay lag with window functions

Medium · window functions · event tables · frame semantics

outbox_event holds event_id, aggregate_type, aggregate_id, aggregate_version, event_type, payload, status ('pending','published','dead'), attempts, created_at, published_at. A projection is missing rows and you must decide whether the relay skipped events or the consumer dropped them. Write three queries over the last seven days: one listing every aggregate_id whose published aggregate_version sequence has a hole, one giving per-day counts with a running total, and one returning the newest published event per aggregate. For each, say where the window function is evaluated relative to WHERE and LIMIT. PostgreSQL 16.

Approach

  1. Gaps: compute lead(aggregate_version) OVER (PARTITION BY aggregate_id ORDER BY aggregate_version) in a subquery, then filter next_version <> aggregate_version + 1 in the outer query. Window functions are evaluated after WHERE, GROUP BY and HAVING and before the outer ORDER BY and LIMIT, so the predicate cannot sit in the same WHERE clause and PostgreSQL 16 has no QUALIFY.
  2. Say what the seven-day filter does to the answer: it truncates every partition, so the first row per aggregate has no predecessor inside the window and a hole spanning the boundary is invisible. Widen the window, or join to resource.version as the authority for the true maximum.
  3. Running total: SELECT date_trunc('day', created_at) AS d, count() AS n, sum(count()) OVER (ORDER BY date_trunc('day', created_at) ROWS UNBOUNDED PRECEDING). An aggregate inside a window call is legal because grouping runs before windowing. The grouping key is unique per row here so ROWS and RANGE agree, but write the frame anyway — over ungrouped rows with tied timestamps the default RANGE frame pulls in every peer row and the total jumps.
  4. Newest per aggregate: DISTINCT ON (aggregate_id) ... ORDER BY aggregate_id, aggregate_version DESC is the cheap PostgreSQL-only form when an index matches that order; row_number() OVER (PARTITION BY aggregate_id ORDER BY aggregate_version DESC) = 1 is the portable form and needs a subquery for the same evaluation-order reason as the gap query.

Follow-up

  • Relay failover redelivers events. Does a duplicate break the gap query, and how would you detect one from this table alone?
  • Turn the gap check into a continuous monitor rather than a query someone runs after an incident. What does it watch?

Explain the principles of object-oriented programming and how they apply to Java.

Medium · Technical / Domain Questions

Approach

  1. Name the four principles and tie each to a Java mechanism: encapsulation (private fields, validated methods, final fields for immutability), inheritance (extends for one superclass, implements for many interfaces), polymorphism, abstraction (abstract classes and interfaces).
  2. Use one running example, such as an Account class whose private balance changes only through deposit() and withdraw() methods that reject negative amounts, with BigDecimal rather than double for money.
  3. Separate the two kinds of polymorphism: overriding is dispatched at runtime on the object's actual class, while overloading is resolved at compile time from the declared argument types.
  4. Say when you prefer composition over inheritance: a deep class hierarchy couples subclasses to superclass internals, so I inject behaviour (a fee policy object) instead of subclassing for every variation.
  5. Mention the Java-specific limits: primitives are not objects, a class extends only one class, and since Java 8 interfaces can carry default and static methods.

Follow-up

  • When would you choose an abstract class over an interface now that interfaces can have default methods?
  • Why must equals and hashCode be overridden together, and what breaks in a HashMap if they are not?
  • Give an example of a subclass that violates the Liskov substitution principle.

What design patterns are you familiar with, and when would you use them?

Medium · Technical / Domain Questions

Approach

  1. Pick four or five patterns you have actually used and give each a trigger: Builder for objects with many optional fields, Strategy for swapping an algorithm such as a fee or interest calculation, Factory for choosing the implementation at runtime, Observer or domain events for reacting to a state change, Adapter for wrapping a third-party client.
  2. Show the before and after for one of them: a growing switch on account type replaced by a Strategy interface with one implementation per type, so a new type adds a class instead of editing a shared method.
  3. Connect patterns to the frameworks you use: Spring beans are singleton-scoped by default, and @Transactional works through a proxy, so a call from one method to another inside the same bean bypasses the transaction advice.
  4. Cover Singleton honestly: it hides global state and complicates tests; if one is needed, an enum or the holder-class idiom is thread-safe, and double-checked locking needs a volatile field.
  5. Close with when not to use a pattern: an abstraction with a single implementation and no expected second one adds indirection without benefit.

Follow-up

  • What is the difference between Strategy and State?
  • How would you make a lazily created singleton thread-safe in Java?
  • Which pattern does java.io's stream wrapping use, and why?

Describe your approach to unit testing and the tools you prefer.

Medium · Technical / Domain Questions

Approach

  1. Describe the tool set concretely: JUnit 5 for tests, Mockito for mocking collaborators, AssertJ for readable assertions, and for Spring Boot code the test slices (@WebMvcTest, @DataJpaTest) plus Testcontainers when a test needs a real database.
  2. State what a unit test should cover: one behaviour, written Arrange-Act-Assert, mocking only the boundaries (repositories, HTTP clients, clocks) rather than the class under test's own logic.
  3. Use @ParameterizedTest for edge cases that matter in money code: zero and negative amounts, BigDecimal scale and rounding, insufficient funds, and duplicate requests.
  4. Make code testable by design: constructor injection, and an injected java.time.Clock instead of calling LocalDate.now() directly so date logic is deterministic.
  5. Treat coverage as a signal, not a target: JaCoCo shows untested lines, and mutation testing (PIT) shows whether the assertions actually catch changed behaviour.

Follow-up

  • How do you test code that depends on the current date or time?
  • Where do you draw the line between a unit test and an integration test for a repository class?
  • A test passes locally but fails intermittently in CI. How do you find the cause?

How would you design an online banking system? What components would you include?

Medium · System Design / Architecture

Approach

  1. Fix scope before drawing boxes: customer login, account balances and history, transfers between own accounts and to external accounts, bill pay and notifications; then state non-functional needs (strong consistency for money, auditability, availability of the read path).
  2. Components: API gateway, authentication service with MFA (OAuth2/OIDC tokens), account service, a ledger service, a transfer or payment service, notification service, and an append-only audit log.
  3. Model the ledger as double-entry: every transfer writes balanced debit and credit entries in one database transaction; store amounts as integer minor units or BigDecimal, never floating point.
  4. Handle concurrency and retries: lock the two account rows in a fixed order (for example by account id, with SELECT ... FOR UPDATE) to avoid deadlocks and overdrafts, and require an idempotency key with a unique constraint so a client retry after a timeout does not post twice.
  5. For external transfers, use a state machine (pending, posted, failed) driven by a transactional outbox, plus daily reconciliation against the external settlement files; serve history with keyset pagination on (account_id, posted_at, id) and read replicas.

Follow-up

  • The client times out after submitting a transfer and retries. What prevents a double debit?
  • How do you stop two concurrent withdrawals from overdrawing the same account?
  • How would you reconcile your ledger with an external payment network that reports results a day later?

Discuss a time you faced a performance bottleneck in a system. How did you resolve it?

Medium · System Design / Architecture

Approach

  1. Open with the symptom in numbers: which endpoint or job, the latency percentile or throughput before, and who was affected.
  2. Show how you located the bottleneck rather than guessed: APM traces or a profiler (Java Flight Recorder, async-profiler), the database slow-query log and EXPLAIN ANALYZE, GC logs, connection-pool metrics.
  3. Name the root cause precisely; common real ones in Java backends are an N+1 query from a lazily loaded JPA relation, a missing or unusable index, connection-pool exhaustion, or long GC pauses from excess allocation.
  4. Describe the fix and its trade-off (a join fetch or batch size, a composite index that slows writes slightly, a cache with an invalidation rule) and how you verified it against the same baseline under similar load.
  5. End with what you added so it does not recur: an alert on the metric, a performance test, or a query-count assertion in tests.

Follow-up

  • How did you rule out other causes before settling on that one?
  • How did you confirm the improvement came from your change and not a drop in traffic?
  • What would you monitor so the same bottleneck is caught before users notice?

What considerations do you take into account when designing a microservices architecture?

Medium · System Design / Architecture

Approach

  1. Start with boundaries: split by business capability with clear data ownership (accounts, payments, notifications), one database per service, and say when a modular monolith is the better choice because the team or domain is too small to pay the operational cost.
  2. Choose communication per interaction: synchronous REST for queries that need an immediate answer, asynchronous messaging for events that other services react to; consumers must be idempotent because messages can be delivered more than once.
  3. Replace distributed transactions with sagas: each step commits locally, failures trigger compensating actions, and a transactional outbox makes the database write and the event publish atomic.
  4. Build in resilience: timeouts on every remote call, retries with exponential backoff and jitter only for idempotent operations, circuit breakers (for example Resilience4j), and bulkheads so one slow dependency does not exhaust all threads.
  5. Cover operations: correlation ids and distributed tracing (OpenTelemetry), centralised logs, health checks, containerised deployment (Docker, Kubernetes), backward-compatible API versioning and consumer contract tests.

Follow-up

  • How do you keep a money transfer consistent when the debit and credit live in different services?
  • How do you change an API that three other services call without breaking them?
  • What signs tell you a service was split too finely?

How do you ensure that your system is secure and complies with regulations?

Medium · System Design / Architecture

Approach

  1. Layer the answer: authentication (OAuth2/OIDC, MFA, short-lived tokens), authorization checked on every request, including that the caller owns the account id in the URL so one customer cannot read another's data (IDOR).
  2. Cover data protection: TLS in transit, encryption at rest, secrets in a secrets manager rather than code or config files, and masking of account numbers and personal data in logs.
  3. Cover application security: parameterised queries (PreparedStatement or JPA parameters) against SQL injection, input validation, the OWASP Top 10 as a review checklist, and dependency scanning in CI.
  4. Treat compliance as engineering work: an append-only audit trail of who changed what and when, data retention and deletion rules, least-privilege access to production, and change control through reviewed pull requests.
  5. Mention verification: security tests in the pipeline, periodic access reviews, and penetration test findings tracked to closure; if card data is involved, name PCI DSS as the standard that applies.

Follow-up

  • How do you store user passwords, and why not a plain SHA-256 hash?
  • How would you prove to an auditor who changed a customer's record and when?
  • A customer reports they can see another customer's transactions. What do you check first?

Describe a scenario where you had to make a quick decision with limited information.

Medium · Problem-Solving / Case Studies

Approach

  1. Pick a real decision with a clear cost of waiting, such as an incident, a release deadline, or a vendor outage, and state in one or two sentences what was at stake.
  2. Say what information was missing and what you did to get the most useful facts quickly (one log query, one call to the owning team) before deciding.
  3. Explain how you limited the risk: whether the decision was reversible, what fallback or rollback you prepared, and who you told before acting.
  4. Give the outcome honestly, including what you would change; a story where the decision was obvious or someone else made it shows nothing.
  5. Close with the rule you now use, such as acting fast on reversible changes and slowing down on irreversible ones like data deletion or money movement.

Follow-up

  • What piece of information would have changed your decision?
  • How did you communicate the decision and its risk to your manager or stakeholders?
  • What would you have done if the decision had turned out to be wrong?

What steps would you take to improve an existing process or system?

Medium · Problem-Solving / Case Studies

Approach

  1. Start from a measured baseline: build time, deploy frequency, failed-deploy rate, ticket cycle time, incident count or p95 latency, whichever describes the pain.
  2. Find the actual constraint by talking to the people who use the process and by looking at data, not by assuming; the slowest step is often a manual handoff or a flaky test suite.
  3. Make the smallest change that removes the constraint, pilot it on one team or service, and keep the old path available until the new one has proved itself.
  4. Measure again against the baseline and report the result in the same units, then roll out and document the new way of working.
  5. Use a concrete example from your own work, such as automating a manual deployment checklist into a CI pipeline or fixing flaky tests that blocked merges.

Follow-up

  • How did you get the team to adopt the change?
  • Which metric showed the improvement, and how did you rule out other explanations?
  • What would you have done if the pilot made things worse?

How do you balance technical debt against delivering new features?

Medium · Problem-Solving / Case Studies

Approach

  1. Make debt visible and costed: track it as backlog items that state the cost in incidents, slower delivery, or on-call time, so it can be ranked against features.
  2. Pay debt where it earns the most: refactor the module you are about to change for a feature, and leave stable code that nobody touches.
  3. Agree a standing mechanism with the product owner, such as a regular share of each sprint or debt work bundled into feature estimates, rather than asking for a separate rewrite.
  4. Hold a hard line on debt that risks correctness or security, such as missing validation on money movement or an unpatched vulnerable dependency, and explain that trade-off in business terms.
  5. Prevent new debt through code review, a definition of done that includes tests, and recording deliberate shortcuts with the reason and a follow-up ticket.

Follow-up

  • How did you convince a product manager to fund a piece of debt work?
  • Give an example of debt you deliberately chose not to fix.
  • How do you stop shortcuts taken under deadline from becoming permanent?

Discuss how you would approach a project with unclear requirements.

Medium · Problem-Solving / Case Studies

Approach

  1. Find the outcome behind the request: who the users are, what problem they have, and how success will be measured, before discussing solutions.
  2. Write down your assumptions and open questions, and get the stakeholders to confirm or correct them in writing; turn the agreed points into acceptance criteria.
  3. Build a thin end-to-end slice or prototype early and put it in front of users, so feedback replaces guessing; iterate in short Agile cycles.
  4. Keep design decisions reversible where requirements are unstable: clear interfaces, configuration over hard-coding, and no premature schema or API commitments to external consumers.
  5. Give a concrete example where clarifying early changed what you built, and say how you handled a requirement that changed late.

Follow-up

  • What do you do when two stakeholders want contradictory things?
  • At what point do you stop clarifying and start building?
  • A key requirement changes after half the work is done. How do you respond?

How would you approach debugging a complex issue in a production system?

Medium · Problem-Solving / Case Studies

Approach

  1. Size the impact first: which users or endpoints, error rate or latency since when, and whether it is getting worse; that decides whether to mitigate immediately.
  2. Check what changed around the start time: deploys, configuration or feature flags, traffic patterns, database migrations, and upstream dependencies; if a recent deploy lines up, roll back or switch off the flag before hunting the root cause.
  3. Gather evidence across signals: logs filtered by correlation id, metrics, distributed traces; for a hung Java service take thread dumps (jstack) to find blocked threads or an exhausted connection pool, and for OutOfMemoryError a heap dump plus GC logs.
  4. Form one hypothesis at a time and test it with the smallest experiment that rules something out, reproducing in a lower environment with production-like data where possible.
  5. Finish properly: fix, add a regression test and an alert for the signal that would have caught it earlier, and write a blameless postmortem with the timeline and follow-up actions.

Follow-up

  • The service hangs but logs no errors. What do you collect first?
  • The issue happens only in production and only intermittently. How do you narrow it down?
  • How do you decide between rolling back and fixing forward?

Suggested practice checklist

The plan follows the reported loop: Java and backend fundamentals first, then data and system design, coding, and finally behavioral stories. Each day ends with something written that you can reread the evening before an interview.

Day 1 — Map the loop and your gaps

  • Write the three reported rounds (Phone Screen, Technical Interviews, Behavioral Interviews) and the question groups to prepare: Java and domain, system design, behavioral, problem-solving, coding.
  • List the stack in the requirements candidates describe (Java, Spring Boot, RESTful APIs, relational databases, microservices, Docker, Kubernetes, cloud services) and rate your honest experience with each.
  • Write a short walk-through of your most relevant Java backend project, naming the datastore, the framework and your own contribution.

Deliverable: A one-page loop map, a stack self-rating with the weakest items marked, and a written project walk-through.

Day 2 — Object-oriented Java, patterns and unit tests

  • Write a small Account, SavingsAccount and PaymentGateway example that shows encapsulation, inheritance, polymorphism and abstraction in Java.
  • Choose five design patterns (for example Strategy, Factory, Builder, Observer, Decorator) and write for each a situation in a banking service where you would use it.
  • Write JUnit 5 and Mockito tests for a transfer service, covering a successful transfer, insufficient funds and a failing downstream call.

Deliverable: A working class example, a pattern table with a banking use for each pattern, and a test class for the transfer service.

Day 3 — A REST service with disciplined error handling

  • Outline a REST API for accounts, transactions and transfers: resource paths, methods, status codes, pagination and an Idempotency-Key header on transfers.
  • Write a Spring Boot @ControllerAdvice that maps a domain exception, a validation failure and an unexpected error to distinct HTTP responses.
  • Rehearse the explanations of checked against unchecked exceptions, try-with-resources and @Transactional rollback behaviour.

Deliverable: An API outline, an exception-handling class, and a spoken answer to each of the REST and exception questions.

Day 4 — Data stores, security and compliance

  • Write the SQL transaction for a funds transfer with a balance check and two ledger entries, and explain the isolation level you would pick.
  • Write a short comparison of SQL and NoSQL for a financial application, covering ledger, session data and reporting.
  • Write a security checklist for a banking API: authentication, authorization, encryption in transit and at rest, input validation, audit logging, secrets handling.

Deliverable: A transfer transaction script, a one-page SQL against NoSQL comparison, a security checklist and a solved window-function exercise.

Day 5 — Design and troubleshooting a banking backend

  • Design an online banking system on paper: client, API gateway, accounts and ledger services, payments, notifications, audit store, and the data each owns.
  • List what you weigh when splitting into microservices (service boundaries, data ownership, synchronous against asynchronous calls, failure handling, deployment with Docker and Kubernetes).
  • Write a debugging sequence for a slow or failing production service: check recent changes, metrics and logs, narrow by bisecting, confirm the cause, then fix and monitor.
  • Prepare one performance bottleneck story and one account of improving an existing process or system.

Deliverable: A system diagram with a written failure-modes list, a microservices checklist, a debugging runbook and two prepared stories.

Day 6 — Coding and complexity in Java

  • Write the linked-list reversal iteratively and recursively in Java, with tests for empty, single-node and long lists.
  • Write binary search in Java, including the overflow-safe midpoint, and test a missing target and duplicate values.
  • Solve duplicate detection with a HashSet, then by sorting, and compare time and space for each.
  • Pick one of your own solutions and write down how you would optimise it and what the complexity becomes.

Deliverable: Four tested Java solutions, each with a written time and space complexity and a note on its edge cases.

Day 7 — Behavioral stories and case prompts

  • Write the situation, task, action and result for five stories: a challenging project, a prioritisation call, a decision you influenced, a team conflict and a motivating moment.
  • Write short outlines for the case prompts on a quick decision with limited information, technical debt against features, and unclear requirements.
  • Say every story aloud and cut it until your own decision and the result are clear within the first few sentences.

Deliverable: Five written stories, three case-prompt outlines and a map from each story to the prompts it can answer.

Behavioural preparation

Candidates report a stage that explores behavioral traits and leadership potential, and the reported prompts cover a challenging project, prioritising, influencing a decision, conflict and motivation. The responsibilities candidates describe include code reviews, working with product managers, UX designers and other engineers, and Agile ceremonies, so choose stories from that kind of cross-team backend work. Put your own decision and a measured result at the centre of each story.

  1. Describe a scenario where you had to make a quick decision with limited information.

Discuss your experience with RESTful APIs and how you would structure one.

Medium · Technical / Domain Questions

Approach

  1. Open with one real API you built or used: the domain, its consumers, and your part in its design. Then walk through the structure you would choose, so the answer is both experience and method.
  2. Model resources as nouns with plural collections, for example accounts, accounts/{id}/transactions and transfers. Use HTTP methods by their meaning: GET is safe, PUT and DELETE are idempotent, POST creates. Return 201 with a Location header on creation.
  3. Make retries safe. For money-moving POST endpoints, accept an Idempotency-Key header and store the result against it, so a repeated request returns the original outcome rather than a second transfer.
  4. Use a consistent error body and precise status codes: 400 or 422 for validation, 401 and 403 for authentication and authorization, 404, and 409 for conflicts such as a stale version. Paginate transaction lists, ideally with a cursor, and version the API through the path or a header.
  5. Describe the layering in a Spring Boot service: controller, service, repository, request and response DTOs separate from entities, bean validation on input, and a global exception handler. Mention amounts as BigDecimal or minor units, never double.

Follow-up

  • How would you make a transfer endpoint safe against a client retrying after a timeout?
  • How do you evolve this API without breaking existing consumers?
  • Would you use offset or cursor pagination for a transaction history, and why?

How do you handle exceptions in Java?

Medium · Technical / Domain Questions

Approach

  1. Start with the split: checked exceptions are for recoverable conditions the caller must handle, and unchecked (RuntimeException subclasses) are for programming errors and unrecoverable states. Never catch Throwable or Error as routine handling.
  2. Catch the most specific type you can act on, wrap lower-level exceptions in a domain exception with the cause attached (for example an InsufficientFundsException), and never swallow an exception with an empty catch block.
  3. Use try-with-resources for anything closeable. Resources close in reverse order, and an exception thrown by close() is attached as a suppressed exception instead of hiding the original failure.
  4. Handle errors once, at the boundary. In a Spring Boot REST service, translate domain exceptions to HTTP responses in a @ControllerAdvice with @ExceptionHandler methods, log with context at that point, and avoid logging and rethrowing at every layer.
  5. Mention transactions: by default Spring's @Transactional rolls back on unchecked exceptions but not on checked ones unless rollbackFor is set, which matters when a failure should undo a transfer. Do not use exceptions for ordinary control flow.

Follow-up

  • Would you make a new business-rule exception checked or unchecked, and what are the consequences for callers?
  • What happens to a @Transactional method when a checked exception propagates out of it?
  • What does finally do if the try block returns, and when would try-with-resources be better?

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

Medium · Behavioral / Leadership

Approach

  1. Choose a project where the difficulty was real and technical or organisational, and where you made the key decisions. State the situation and goal in two sentences, then say precisely what made it hard, such as a legacy dependency, a tight data migration or conflicting requirements.
  2. Spend most of the answer on actions: the options you weighed, why you chose one, what you cut, and how you reduced risk, for example with a staged rollout, a feature flag or extra tests around the riskiest piece.
  3. Close with a result you can measure (error rate, latency, delivery against the plan, effort saved) and say what you learned or would change. A story that ends with only 'it shipped' is thin.
  4. The mistake that sinks it is describing a long project instead of a hard one, or saying 'we' throughout so your own contribution cannot be identified.

Follow-up

  • What was the riskiest decision in that project, and what did you do to limit the downside?
  • What would you do differently if you ran it again?
  • How did you keep stakeholders informed while it was going badly?

How do you prioritize tasks when working on multiple projects?

Medium · Behavioral / Leadership

Approach

  1. Give a method, then prove it with a real case. A workable method: list everything with its deadline and who is waiting on it, rank by impact and urgency, find dependencies and blockers, then confirm the ranking with the person who owns the priorities rather than guessing.
  2. Use a concrete conflict between items, such as a production defect against a planned feature, and say what you deferred or dropped and how you told the affected people. Naming what you did not do shows the prioritisation was real.
  3. Show how you keep the order honest afterwards: a written backlog or task board, short check-ins when something new arrives, and renegotiating scope instead of silently working longer hours.
  4. The mistake to avoid is answering 'I work harder' or 'everything is a priority'. Finish with the outcome of your choice and whether the deferred items suffered.

Follow-up

  • What do you do when two stakeholders each insist their item comes first?
  • Tell me about a time your prioritisation turned out to be wrong.
  • How do you handle an urgent production issue arriving in the middle of planned work?

Give an example of a time when you influenced a team decision.

Medium · Behavioral / Leadership

Approach

  1. Pick a decision where you had no formal authority, such as a library choice, an API design, a testing approach or a rollout plan, and say what you were trying to change and why.
  2. Show how you built the case with evidence: a short prototype, a benchmark, a comparison of options in writing, or an incident that showed the cost of the status quo. Influence backed by data is easier to defend than persuasion alone.
  3. Describe how you handled the objections, including something you changed in your own proposal because of them, and how you brought the sceptics along, for example through a pilot on one service.
  4. Report what happened (adoption, a measurable improvement, or a decision that went another way and how you committed to it anyway). The mistake is a story where the decision was yours to make from the start.

Follow-up

  • What was the strongest objection, and how did you respond?
  • What if the team had chosen the other option?
  • How did you check afterwards that the decision was right?

How do you handle conflicts within a team?

Medium · Behavioral / Leadership

Approach

  1. Choose a real disagreement with a colleague, such as a code review dispute, a design disagreement or a clash over scope, not an invented mild one. State the positions neutrally in a sentence or two.
  2. Show the steps you took: speak to the person directly and privately first, ask what constraint or goal sits behind their position, find the shared goal, and bring facts (a measurement, a requirement, a test result) into the discussion in place of opinions.
  3. Say how it was resolved: a compromise, a trial, or an agreed decision-maker, and what you did if you lost the argument. Involving a manager is fine as a later step, but not as the opening move.
  4. Finish with the working relationship afterwards and the result. The mistake is casting the other person as the problem or claiming you have never had a conflict.

Follow-up

  • What did you misjudge about the other person's position at the start?
  • When would you escalate a conflict instead of resolving it directly?
  • How do you disagree in a code review without it turning personal?

What motivates you to perform your best work?

Medium · Behavioral / Leadership

Approach

  1. Name one or two genuine drivers and back each with a moment from your work, not a slogan. For a backend role these might be building something whose correctness matters, removing a source of recurring incidents, or helping a colleague become independent on a hard area.
  2. Make the connection concrete: describe a time that driver showed up in your behaviour, such as staying with a bug until the root cause was found or writing the runbook after an outage.
  3. Link it to the work in this role without claiming to know the employer's preferences: backend services for financial applications, collaboration with product and design, and code review all give you natural examples.
  4. Be honest about what drains your energy and how you manage it. The mistake is a list of adjectives with no example, or an answer so generic it would fit any job.

Follow-up

  • What kind of work leaves you less motivated, and how have you dealt with it?
  • Tell me about a time that motivation was tested by a frustrating project.
  • How does that driver fit a Java backend role on financial systems?