Interview guides · Columbia Bank
Columbia Bank Software Engineer Interview Guide
Columbia Bank Software Engineer interview guide: phone screen, technical interview and project presentation, with reported questions and a 7-day plan.
The 60-second brief
Columbia Bank is a bank, and candidates describe the Software Engineer role as building and maintaining the software behind it. The work reported ranges from online banking platforms that customers use to backend services that handle transaction processing. Engineers are described as working with product management, infrastructure and security teams, and with user experience designers and data analysts, on software that has to satisfy regulatory requirements as well as users.
This guide is for software engineers preparing for Columbia Bank. It covers the three reported rounds (Phone Screening, Technical Interview, Project Presentation), the reported domain, design, coding and behavioral questions, and a seven-day plan. Reported questions are representative and can vary by team, so use them to rehearse patterns rather than to memorise answers.
Candidates report three rounds: a phone screening with an HR representative, a technical interview that may include live coding or problem-solving exercises, and a project presentation. Timelines are reported as roughly 3-5 weeks, though one description puts the process nearer two weeks.
Focus areas
- Communication Skills
- Professionalism
- Technical Problem Solving
Overview
The role candidates describe is application and backend work in a bank: customer-facing online banking, services that process transactions, code reviews, and debugging. The description also mentions large transaction volumes, high availability and security, and teamwork with product, infrastructure and security colleagues. For preparation, that means being ready to reason about money-moving systems (retries, duplicates, consistency, audit trails) and to talk plainly with people who are not engineers.
The reported questions fall into four groups. Domain questions cover version control, the differences between REST and SOAP APIs, unit testing, cloud experience and code you optimized. Design questions cover a banking application for millions of users, data security, microservices and high availability. Coding questions cover the longest substring without repeating characters, writing a sorting algorithm from scratch, stating time and space complexity, and level order traversal of a binary tree. Behavioral questions cover a challenging project, conflict, explaining a technical concept to a non-technical stakeholder, and motivation for banking.
The requirements candidates describe list Java, Python or C#, experience with SQL or NoSQL databases, and familiarity with Agile or Scrum. Cloud services such as AWS or Azure, DevOps tooling and cybersecurity knowledge are listed as nice to have, and a computer science degree with several years of development experience, ideally in finance, is described as typical. Pick one listed language for the coding questions, keep one database project ready to discuss, and build one project story you can present end to end.
The Columbia Bank interview process
Candidates report three rounds over roughly 3-5 weeks, listed below in the order they describe. Treat the round contents as reports, since the bank publishes no official process.
Phone Screening
Candidates report a phone screening with an HR representative, where the conversation centres on your background and qualifications. No coding is reported for this stage. Treat it as the first test of how clearly you can describe your work, and make sure the story matches the languages and database experience the role lists.
What to demonstrate
- How clearly you summarise your background and qualifications
- Whether your experience lines up with the listed skills: Java, Python or C#, and SQL or NoSQL
- Communication in a short, unstructured conversation
How to prepare
- Write a two-minute walk through your career that ends on the kind of work you want next, and say it aloud until it flows.
- Prepare a one-line answer for each listed skill: your strongest language, your main database, and any AWS or Azure work.
- Have a specific reason for choosing banking ready, built from a real project or interest rather than general praise.
Technical Interview
Candidates report a technical interview that may involve live coding or problem-solving exercises. This is the stage where the reported coding questions are practised (longest substring, sorting from scratch, level order traversal, complexity analysis), alongside the domain and design topics such as REST versus SOAP, unit testing, microservices and availability. Write and run real code in your chosen language, and say your complexity out loud each time.
What to demonstrate
- Working code for algorithm problems, written live
- Ability to state time and space complexity for your own solution
- Command of domain topics: version control, API styles, unit testing
- Structured reasoning on banking-style design topics: scale, security, availability
How to prepare
- Solve the longest-substring problem with a sliding window and a map of last-seen positions, then repeat it from a blank file in your interview language.
- Code a level order traversal with a queue, then write merge sort or quicksort from scratch, and give the complexity of each aloud.
- Prepare a clear contrast of REST and SOAP, and a description of your unit testing workflow, using a real project as the example.
- Outline a design for a banking application at scale with a security section and an availability section, speaking for a few minutes without notes.
Project Presentation
Candidates report a project presentation in which you present past projects and discuss your approach in detail. Tips candidates repeat emphasise challenges faced and solutions implemented. Pick one project you owned, and structure it as problem, options, decision, result and lesson, so questions about testing, security, scale or teamwork have a place to land.
What to demonstrate
- Depth of understanding of work you say you did
- Ability to explain technical decisions and trade-offs clearly
- Communication with an audience that may include non-engineers
How to prepare
- Choose one project and build a short deck or outline: context, your role, architecture, hardest problem, result, what you would change.
- Prepare to show how it was tested, how it was secured and how it handled failure or load, since those are themes in the reported domain and design questions.
- Rehearse the challenging-project and conflict stories as parts of the presentation, with your own decisions named.
- Practise explaining one technical decision to a listener without a technical background.
Where candidates lose points
Presenting a past project as a feature tour with no decisions, trade-offs or failures
Structure the project presentation as problem, options considered, your decision, measured result and what you would change. Prepare one thing that went wrong, and be ready to go deeper on testing, security and scale for that project.
Solving the coding problem silently, or stating complexity only when asked
Narrate the plan before you type, then close each solution by stating time and space complexity. For the longest-substring problem, say it is linear in the string with space bounded by the character set, and name the brute-force version you improved on.
Answering REST versus SOAP with slogans such as "REST is lighter" and unit testing with "it catches bugs"
Give concrete contrasts: SOAP uses XML envelopes and a WSDL contract, REST uses resources over HTTP methods. For testing, describe your real workflow: what you test, how you isolate dependencies, and when the tests run.
A banking design answer that only adds load balancers and more servers
Cover the money path explicitly: idempotent requests so retries cannot double-apply, consistency for balances, encryption and access control, audit logging, and what happens when a dependency fails. Give each of security, microservices boundaries and high availability its own section.
Behavioral stories told as "we" with a generic motivation for banking
Name your own decisions and measured results in the optimization, challenging-project and conflict stories. For the banking motivation, tie two honest reasons to a project or interest you can describe.
Questions & practice
Write a function to find the longest substring without repeating characters.
Medium · Coding / Algorithms
Approach
- Brute force checks every substring for duplicates in O(n^3), or O(n^2) when each start extends with a set; name it, then move to a sliding window.
- Keep a window [left, right] with no repeats and a map from character to its last index. For each right, if the character was seen at index i >= left, set left = i + 1 (equivalently left = max(left, last[c] + 1)); then record last[c] = right and update best = max(best, right - left + 1).
- Explain why the max matters with "abba": at the final 'a' its last index is 0, which is already left of the window, so jumping left backwards would be wrong.
- Complexity: O(n) time because each index enters the window once and left only moves forward; O(min(n, k)) space for the map, where k is the alphabet size (a fixed 128-entry array for ASCII).
- Test the edges aloud: empty string returns 0, a single repeated character returns 1, all-distinct input returns n, and spaces or digits count as characters.
Follow-up
- Return the substring itself rather than its length.
- Change it to the longest substring with at most k distinct characters.
- Does your solution handle Unicode input correctly in your language's string type?
How would you implement a sorting algorithm from scratch?
Medium · Coding / Algorithms
Approach
- Ask what is being sorted and what matters: size, whether data is nearly sorted, whether equal keys must keep their order (stability), and whether extra memory is allowed. Those properties choose the algorithm.
- Merge sort as the safe default to write from scratch: split in half, sort recursively, merge with two pointers taking from the left on ties to stay stable. O(n log n) in every case, O(n) extra memory.
- Quicksort when memory is tight: partition around a pivot, recurse on both sides. Average O(n log n), worst O(n^2) on already sorted input with a first-element pivot, so use a random or median-of-three pivot, three-way partitioning for many duplicates, and recurse on the smaller side to keep the stack at O(log n). Not stable.
- Know the others: insertion sort is O(n^2) but stable and fast on small or nearly sorted arrays; heap sort is O(n log n) worst case with O(1) extra space but not stable; counting or radix sort reach O(n + k) for bounded integer keys.
- Connect to libraries: Python's sorted uses Timsort (stable, adaptive); Java's Arrays.sort uses dual-pivot quicksort for primitives and Timsort for objects. Test empty, single-element, duplicate-heavy and reverse-sorted inputs.
Follow-up
- You must sort transactions by amount and keep equal amounts in timestamp order. Which algorithms are safe?
- Why does quicksort degrade to O(n^2), and how do you make that unlikely?
- How would you sort a file far larger than memory?
Can you explain the time and space complexity of your solution?
Medium · Coding / Algorithms
Approach
- Define the variables first: n for input length, plus any second dimension (m for another input, k for alphabet or key range, h for tree height), so the bound is stated in terms the interviewer can check.
- Derive time from the work per element: count how many times each element is touched across all loops. For a sliding window, each index enters and leaves the window at most once, so two nested-looking loops are still O(n).
- State auxiliary space separately from the output: hash maps, queues and the recursion stack all count. Recursion over a balanced tree costs O(log n) stack, a skewed tree O(n).
- Be precise about averages: hash map lookups are O(1) on average but O(n) in the worst case with bad collisions; dynamic array append is amortised O(1) even though a resize copies everything.
- Close with whether it can be improved: comparison sorting has an Omega(n log n) lower bound, and any solution must read the input once, so O(n) is optimal when every element matters. Name the time-space trade-off you chose.
Follow-up
- What happens to your bound if the hash map degrades to its worst case?
- Could you reduce the space at the cost of time? What would the new bounds be?
- Is the recursion depth a practical risk for the input sizes you assumed?
Given a binary tree, how would you perform a level order traversal?
Medium · Coding / Algorithms
Approach
- Use breadth-first search with a FIFO queue: push the root, then repeatedly pop a node, record its value and push its left and right children. In Python use collections.deque with popleft, which is O(1); list.pop(0) is O(n).
- To return values grouped by level, read the queue length at the start of each level and pop exactly that many nodes into one list before moving on.
- Complexity: O(n) time since each node is enqueued and dequeued once; O(w) extra space where w is the widest level, which for a perfect tree is the leaf level, about n/2 nodes.
- Handle the edges: a null root returns an empty list, a single node returns one level, and a skewed tree degenerates to one node per level.
- Mention the alternative: DFS passing the depth and appending to result[depth] produces the same grouping using O(h) stack instead of a queue, but recursion depth can overflow on a deep skewed tree.
Follow-up
- Return the levels in zigzag order, alternating left-to-right and right-to-left.
- Return only the rightmost node visible at each level.
- Compute the maximum width of the tree, counting gaps between nodes.
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
- 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.
- 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.
- 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.
- 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?
Hold a per-tenant active cap against concurrent creates
Hard · write skew · isolation levels · constraints
A tenant on the standard plan may hold at most 50 resources with status='active'. The create handler runs SELECT count(*) FROM resource WHERE tenant_id = $1 AND status = 'active', compares to 50, then inserts. Two creates arrive 3 ms apart on different instances and the tenant lands at 51. Name the anomaly, say whether PostgreSQL 16 READ COMMITTED or REPEATABLE READ prevents it and why, then give an implementation that holds the cap at READ COMMITTED with the exact statements. Finally, say what changes when the cap is 'at most one running export per tenant' on job_run.
Approach
- Name it: write skew. The two transactions read an overlapping set and write disjoint rows, so there is no row-level conflict for the engine to detect and each commit is individually legal.
- Rule out the levels precisely. READ COMMITTED takes a fresh snapshot per statement and takes no lock on the counted rows, so both see 49. PostgreSQL's REPEATABLE READ is snapshot isolation: it removes non-repeatable reads and phantoms within the snapshot but still admits write skew, because the anomaly is not a re-read of a changed row, it is a read of a set that a concurrent transaction invalidates. Only SERIALIZABLE closes it, by tracking the read dependency and aborting one transaction with SQLSTATE 40001 — a guarantee that exists only if the application re-runs the whole transaction from the read.
- Convert the set predicate into a single-row conflict: keep tenant.active_resource_count and run UPDATE tenant SET active_resource_count = active_resource_count + 1 WHERE tenant_id = $1 AND active_resource_count < 50 in the same transaction as the INSERT. Zero affected rows is the cap, returned as 409. The row lock serialises the decision at any isolation level, and contention is bounded to one tenant's row — which is also the fair-scheduling unit, unlike a global counter that would convoy every tenant behind one row.
- State the cost you just took on: a counter is a second source of truth that can drift, so every path that changes status must adjust it inside the same transaction, and a periodic reconciliation has to exist, with resource_revision as the authority for what the count should have been.
Follow-up
- A resource moves from archived back to active. Which statements change, and what breaks if the counter update and the status change land in different transactions?
- The cap becomes plan-dependent and a plan can change mid-month. Where does the number 50 live, and who reads it?
How do you manage version control in your projects?
Medium · Technical / Domain Questions
Approach
- Name the branching model and why: short-lived feature branches merged into a protected main (trunk-based), or release branches when several versions must be supported at once. Say which one you used and what made it fit the release cadence.
- Describe the path a change takes: small focused commits, a pull request, at least one reviewer, and CI running the build and unit tests before merge is allowed. Branch protection enforces it rather than convention.
- State your merge-versus-rebase rule: rebase your own local branch to keep history linear, never rebase or force-push a branch others have pulled, because it rewrites commits they already have.
- Explain how a bad change is undone on a shared branch: git revert adds a new commit that inverts it, so history stays intact; git reset is for local, unpushed work only. Tag releases so a deployed version maps to one commit.
- Cover secrets: they never go into the repository; if one is committed, rotate the credential first, because rewriting history does not remove copies already cloned or cached.
Follow-up
- Walk me through resolving a merge conflict in a file two people changed in the same function.
- A commit that broke production is already on main and three commits sit on top of it. What do you do?
- How would you ship an urgent fix while a larger release branch is still in testing?
Can you explain the differences between REST and SOAP APIs?
Medium · Technical / Domain Questions
Approach
- Open with the category difference: SOAP is a protocol with a fixed XML envelope (header, body, fault) and a machine-readable WSDL contract; REST is an architectural style built on resources addressed by URIs and manipulated with standard HTTP methods.
- Compare the mechanics: SOAP usually sends every operation as an HTTP POST and reports errors as SOAP Faults; REST maps intent to GET, POST, PUT, PATCH, DELETE, reports outcome through HTTP status codes, and can use any representation, most often JSON.
- Cover statelessness and caching: REST requests carry everything needed to serve them, and safe GET responses can be cached by HTTP intermediaries; SOAP calls through POST are not cached by standard HTTP caches.
- Name the security and reliability split: both rely on TLS for transport, but SOAP adds WS-Security for signing and encrypting the message itself, which survives intermediaries; REST typically uses OAuth 2.0 bearer tokens and leaves message-level signing to the application.
- Close on when each fits: SOAP for existing enterprise integrations with strict typed contracts; REST for web and mobile clients. Mention idempotency: GET, PUT and DELETE are idempotent by definition, POST is not, so payment-style POSTs need an idempotency key.
Follow-up
- A client times out on a POST that creates a transfer and retries. How do you stop the transfer happening twice?
- How would you version a REST API without breaking existing clients?
- When would you choose gRPC over both of these?
Explain the importance of unit testing and how you implement it in your workflow.
Medium · Technical / Domain Questions
Approach
- Define the unit and the payoff: one function or class tested in isolation, fast and deterministic, so a failure points at a specific piece of logic and refactoring is safe. Place it in the test pyramid: many unit tests, fewer integration tests, few end-to-end tests.
- Show the structure of a test: arrange, act, assert; one behaviour per test; a name that states the expected behaviour. Name the framework for your language: JUnit for Java, pytest for Python, xUnit or NUnit for C#.
- Explain isolation: replace the database, network calls and the clock with test doubles (stubs for canned answers, mocks to verify interactions, fakes for in-memory versions), and inject them through constructors so the code is testable by design.
- List the edge cases you would write for money-handling code: zero and negative amounts, rounding at the smallest currency unit, decimal types instead of floating point, overdraft limits and duplicate requests.
- Describe the workflow: tests run in CI on every pull request and block the merge on failure; coverage is a signal for untested branches, not a target; a flaky test is fixed or quarantined, never ignored.
Follow-up
- How do you unit test code that depends on the current date or time?
- What would you deliberately not cover with unit tests, and what covers it instead?
- A test passes locally and fails intermittently in CI. How do you find out why?
How would you design a banking application that can handle millions of users?
Medium · System Design / Architecture
Approach
- Fix the scope and split the paths: reads (balance, transaction history) far outnumber writes (transfers, payments), and the write path needs strong consistency while the read path can tolerate slight staleness if it is labelled. Estimate peak requests per second from the user count before choosing components.
- Lay out the components: load balancer and API gateway, stateless application services scaled horizontally, an identity service (OAuth 2.0/OpenID Connect with MFA), and a relational database with ACID transactions for the ledger.
- Model money as a double-entry ledger: each transfer writes a debit and a credit that sum to zero inside one transaction, entries are append-only, and balances are derived or updated under row locks or optimistic version checks so concurrent transfers cannot overdraw an account.
- Make writes retry-safe with an idempotency key stored with a unique constraint; publish downstream events (notifications, fraud checks) through a transactional outbox so the event and the ledger write commit together.
- Scale reads with replicas and a cache for history pages, and partition the ledger by account id once one primary is not enough. State the cost: a transfer between accounts on different shards then needs a saga with compensation or two-phase commit.
Follow-up
- Two transfers hit the same account at the same moment and together exceed the balance. What stops the overdraft?
- How do you serve years of transaction history cheaply without slowing the ledger?
- What changes when the two accounts in a transfer live on different shards?
What considerations would you take into account for data security in your design?
Medium · System Design / Architecture
Approach
- Start by classifying data: credentials, personal identifiers, account and card numbers, and ordinary metadata, because each class gets different controls. Card data brings PCI DSS scope, so shrink that scope with tokenisation.
- Encrypt in transit with TLS 1.2 or later everywhere, including service-to-service, and at rest with AES-256 using keys held in a KMS or HSM; use envelope encryption so data keys can be rotated without re-encrypting everything at once.
- Control access with least privilege: role-based access for people, separate identities per service, MFA for administrative access, and secrets fetched from a vault at runtime rather than stored in code or config files.
- Close common holes in the application: validate input, use parameterised queries with bind parameters against SQL injection, mask account numbers in logs and API responses, and never copy unmasked production data into test environments.
- Make it auditable: append-only, tamper-evident audit logs of who accessed or changed what, alerting on anomalous access, and a threat model (for example STRIDE) run per feature so the controls follow the actual risks.
Follow-up
- How would you rotate an encryption key without downtime?
- How do you stop personal data from leaking into application logs?
- An engineer needs realistic data to reproduce a production bug. How do you give it to them safely?
Can you walk us through your approach to designing a microservices architecture?
Medium · System Design / Architecture
Approach
- Decompose by business capability, not by technical layer: for a bank that might be accounts, payments, customer profile and notifications, each owning its own database so no service reads another's tables.
- Choose communication per interaction: synchronous REST or gRPC when the caller needs the answer now, asynchronous events through a message broker when it does not; asynchronous calls decouple availability but add eventual consistency.
- Handle a business operation spanning services with a saga (choreographed through events or run by an orchestrator) and compensating actions, plus a transactional outbox so state changes and published events never diverge.
- Build in resilience: timeouts on every remote call, retries with exponential backoff and jitter only for idempotent operations, circuit breakers and bulkheads so one slow dependency cannot exhaust threads across the system.
- Name the operational cost and how you pay it: correlation ids and distributed tracing, centralised logs and metrics, independent CI/CD pipelines per service. State that a modular monolith is often the better start until team size or scaling needs justify the split.
Follow-up
- One downstream service starts responding slowly and the whole system degrades. What went wrong and how do you contain it?
- How would you migrate a monolith to services without a big-bang rewrite?
- How do you change an event schema that three other services consume?
How would you ensure high availability in a critical banking system?
Medium · System Design / Architecture
Approach
- Turn the goal into numbers first: an availability target (99.99% allows about 52.6 minutes of downtime a year), a recovery time objective and a recovery point objective, because they decide how much redundancy is worth paying for.
- Remove single points of failure: stateless service instances across multiple availability zones behind a load balancer with health checks, sessions held outside the instance, and no component that exists only once.
- Protect the data tier: synchronous replication to a standby in another zone with automatic failover for near-zero data loss, plus asynchronous cross-region replicas for disaster recovery, accepting a non-zero recovery point there. Guard failover against split brain with fencing or a consensus-based leader.
- Degrade instead of failing: serve balances from a cache with a timestamp, switch to read-only mode, or queue non-urgent writes when a dependency is down; shed load with rate limits before the system tips over.
- Make changes and failures routine: blue-green or canary deploys with fast rollback, feature flags, monitoring against the SLO with alerting and runbooks, and regular failover and restore drills, since an untested backup is not a backup.
Follow-up
- During a failover both database nodes believe they are the primary. How do you prevent or recover from that?
- Would you run the ledger active-active across regions? What does it cost you?
- How do you prove the disaster recovery plan works before you need it?
Listing latency scales with page size, not with filters
Easy · n+1 · latency · query batching
The tenant listing endpoint reads resource filtered by tenant_id and status, ordered by updated_at DESC, and returns each row plus the owner's display name from app_user and the actor of that resource's latest resource_revision. p99 is 55 ms at 10 rows per page and 1.4 s at 200. Database telemetry shows 401 statements per request, each under 1 ms, and nothing in the slow-query log. Diagnose the cause and give the fix, stating the statement count per request and the p99 you expect afterwards.
Approach
- Read the counters before forming a theory. 401 statements for 200 rows is one driver query plus two per row, and sub-millisecond execution with an empty slow-query log rules out a bad plan. The time is round trips, which is why it is invisible in every per-query metric and scales with rows returned rather than with filter selectivity.
- Name the two per-row statements from their normalised text: a single-row app_user lookup by user_id, and a resource_revision lookup by resource_id ordered by version DESC LIMIT 1. Confirm by dropping those two response fields and watching the statement count fall to one. That locates the calls in the serialisation layer, not the repository.
- Check that the arithmetic accounts for the whole gap. Measure one round trip to the replica in isolation; 400 trips at roughly 3 ms of network plus 0.2 ms of execution is about 1.3 s on top of a 55 ms baseline, which matches. If the multiplication had fallen short, the N+1 would only be part of the story and you would keep looking.
- Batch both lookups. Collect owner_user_ids and resource_ids from the driver query, then issue WHERE tenant_id = $1 AND user_id = ANY($2) for the users, and PostgreSQL's SELECT DISTINCT ON (resource_id) ... WHERE resource_id = ANY($2) ORDER BY resource_id, version DESC for the latest revision, which the UNIQUE (resource_id, version) index serves directly. On an engine without DISTINCT ON, use a lateral join or a row_number window. Three statements per request at any page size.
Follow-up
- The page size is capped at 200 today. What breaks first if it is raised to 2,000, and is it still this bug?
- How do you stop the next N+1 from reaching production, given that no individual query is slow and the endpoint's tests pass?
Suggested practice checklist
The plan follows the three reported rounds: coding and domain practice for the technical interview, banking design practice, and project and behavioral stories for the presentation and phone screen. Question-specific days point at the reported questions they train.
Day 1 — Map the loop and build your project inventory
- Write the three reported rounds (Phone Screening, Technical Interview, Project Presentation) and list what you would show or say in each.
- List three projects you could present and pick the one with the most decisions, tests and security or scale detail.
- Write your two-minute background summary and a one-line answer for your strongest language, database and any AWS or Azure work.
Deliverable: A one-page loop map, a chosen presentation project with a rough outline, and a written two-minute background summary.
Day 2 — Strings and trees under live-coding conditions
- Solve the longest substring without repeating characters in your interview language: first the brute force, then a sliding window with a map of last-seen indexes.
- Write level order traversal of a binary tree with a queue, returning a list per level, and handle the empty tree.
- After each solution, state time and space complexity aloud and test it on an empty input, a single element and repeated characters.
Deliverable: Two working solutions with test inputs and a spoken complexity statement for each.
Day 3 — Sorting from scratch and complexity vocabulary
- Write merge sort and quicksort from a blank file, and list their worst case, extra memory and stability.
- Write a short explanation of when you would use insertion sort, merge sort or quicksort in practice.
- Reanalyse your day-2 solutions and write the complexity derivation for each in one sentence.
Deliverable: Two sorting implementations plus a half-page comparison table with complexity and stability.
Day 4 — Domain questions, data and debugging
- Write a contrast of REST and SOAP covering message format, contract, security options and when each fits, then say it aloud.
- Describe your version control workflow (branching, pull requests, merge conflicts) and your unit testing workflow using a real project.
- Work through the listing-latency debugging exercise and write down your debugging sequence.
Deliverable: Spoken answers on version control, REST versus SOAP and unit testing, plus finished SQL and debugging exercises with notes.
Day 5 — Banking system design
- Design a banking application for millions of users: components, read and write paths, data stores, and where consistency matters.
- Add a security section: authentication, encryption in transit and at rest, access control, secrets and audit logging.
- Sketch a microservices split with service boundaries, communication style and failure handling.
- Add a high-availability section: redundancy, failover, health checks, and what degrades when a dependency is down.
Deliverable: One diagram and a spoken walkthrough for the banking application, with separate sections for security, microservices and availability.
Day 6 — Project presentation and story bank
- Build the presentation of your chosen project with context, your role, architecture, hardest problem, result and lessons, and rehearse it aloud.
- Write bullet outlines for the optimization story, the cloud experience answer and the challenging-project story, each with your own decisions and measured results.
- Collect the numbers (before and after) for each story so none is vague.
Deliverable: A presentation outline plus three story outlines, each with a measured result.
Day 7 — Full mock across all three rounds
- Run a mock phone screen using your background summary and your banking motivation answer.
- Practise the conflict story and the technical-concept-for-non-technical-stakeholder story out loud, in first person singular.
- Do one timed coding problem from days 2-3 and one spoken design answer from day 5, then run your project presentation start to finish.
Deliverable: A recorded or timed mock of the phone screen, one coding problem, one design answer and the presentation, with a list of fixes.
Behavioural preparation
Candidates describe collaboration and communication as one of the evaluation areas, including working with cross-functional teams and explaining technical ideas to non-technical stakeholders. The project presentation also invites stories about challenges you faced. Prepare each story in first person singular, with your own decisions and a measured result.
Describe a time you optimized a piece of code. What was the outcome?
Medium · Technical / Domain Questions
Approach
- Pick code you changed yourself and open with the measured problem, such as a slow report, a repeated query or a quadratic loop, and the number you started from.
- Say how you found the hot spot: a profiler, timing around suspect calls, or a query plan. Optimising by instinct is the usual weak point of this story.
- Describe the change in concrete terms, for example replacing a nested loop with a hash lookup, batching repeated database calls, or adding a cache, and the trade-off it added.
- Show you protected correctness: existing or new tests ran before and after, which matters for any code that touches balances or transactions.
- Close with before-and-after figures from your own project, and one lesson about when the optimization was and was not worth the added complexity.
Follow-up
- How did you know that was the bottleneck and not something else?
- Did the change make the code harder to maintain, and how did you handle that?
- What would you do if the improvement had regressed another path in production?
What is your experience with cloud services, such as AWS or Azure?
Medium · Technical / Domain Questions
Approach
- State your real scope first: which provider, which services you used, and whether you built, deployed or only consumed them. Do not claim operating experience you cannot defend.
- Anchor the answer in one deployment you can walk through: compute, storage, a managed database, networking, and how code reached the environment.
- Cover the decisions a bank-style workload raises: least-privilege access (IAM on AWS, role-based access on Azure), where secrets live, encryption of stored data, and logging and monitoring.
- If you know only one provider, map the concepts to the other (virtual machines, object storage, serverless functions, identity roles) so the answer still covers both. AWS and Azure are both named as nice to have.
- End with one thing that went wrong or cost more than expected and what you changed, such as an over-broad permission or an oversized instance.
Follow-up
- How did you control access to that storage or database, and where were the credentials kept?
- How did you deploy changes and roll one back?
- How would you decide between a managed service and running it yourself?
Describe a challenging project you worked on. How did you handle it?
Medium · Behavioral / Leadership
Approach
- Choose a project where the difficulty was real: an ambiguous requirement, a legacy system, a hard deadline or a technical unknown. Avoid one that was merely long.
- Set the scene in two sentences, then spend most of the time on your own decisions: the options you weighed, why you chose one, and what you rejected.
- Name the obstacle and how you worked through it, for example a prototype to settle a risk, splitting the work into stages, or involving another team early.
- Say what you owned in first person singular and what teammates did, so the contribution is unambiguous.
- Finish with the outcome in concrete terms, what you learned, and what you would do differently. This story also works as the core of the project presentation.
Follow-up
- Which decision on that project would you change today?
- Where did you disagree with someone, and how was it settled?
- What was the hardest part that only you could have handled?
How do you approach conflict resolution within a team setting?
Medium · Behavioral / Leadership
Approach
- Use a real disagreement about substance, such as a design choice, scope, a code review comment or priorities, not a personality clash with no resolution.
- Show the order of your actions: listen and restate their position, find the shared goal, then move the discussion to evidence such as a benchmark, a prototype or a requirement.
- Say how it ended: you changed your mind, they changed theirs, or the decision went to the owner with both options laid out. All three can be good outcomes if the reasoning is clear.
- Keep the other person fair. A story where they are plainly wrong tells the listener little about you.
- Add what you do differently since, such as writing down decisions or phrasing review feedback as a question about behaviour rather than the person.
Follow-up
- What if they still disagreed after the evidence?
- When do you escalate, and to whom?
- How has this changed the way you give feedback in code reviews?
Can you provide an example of how you effectively communicated a complex technical concept to a non-technical
Medium · Behavioral / Leadership
Can you provide an example of how you effectively communicated a complex technical concept to a non-technical stakeholder?
Approach
- Choose a concept with a real stakeholder decision behind it, such as why a release slipped because of a security fix, why a retry could double-charge, or why a system needs planned downtime.
- Open with who the audience was and what they had to decide, then lead with the impact and the choice before any mechanism.
- Show the translation you used: a plain analogy, a small diagram, or numbers in their terms (customers affected, risk, cost) in place of jargon.
- Describe how you checked understanding, for instance by asking them to say it back or answering their follow-up questions, and what decision followed.
- Avoid the failure of oversimplifying until the risk disappears. The story should show you kept the important caveat.
Follow-up
- How did you know they had understood?
- What would you have done if they had pushed to ship anyway?
- How would you explain the same concept to a senior manager versus a business analyst?
What motivates you to work in the banking sector?
Medium · Behavioral / Leadership
Approach
- This is a motivation question, not a STAR story. Give two or three reasons that are specific and honest rather than a statement about stability or reputation.
- Tie them to the work: software that moves money has to be correct, secure and available, and the role is described as including online banking and transaction-processing services. Say which of those problems interests you and why.
- Back each reason with evidence from your history, such as a project with reconciliation or audit requirements, a security course, or reliability work you did.
- Show you understand that regulated software carries extra constraints (regulatory requirements are part of the role description) and that you see them as part of the engineering problem.
- Do not recite claims about the bank's mission or culture. Mention only facts you have checked in public sources, and keep the focus on what you will contribute.
Follow-up
- What have you done to learn about regulated or financial systems?
- What would you miss if you moved from a faster-moving environment into banking?
- How do you balance shipping quickly with compliance and review requirements?