cswork / libraryOpen practice workspace

Interview guides · BankUnited

BankUnited Software Engineer Interview Guide

BankUnited Software Engineer interview guide: the three reported rounds, 17 reported questions with answer approaches, and a 7-day preparation plan.

The 60-second brief

BankUnited is a bank, and the Software Engineer role candidates describe sits in the technology behind its banking operations and the digital platforms used by clients and internal teams. Reports tie the work to messaging and collaboration tools, and the topics that come up around this role are messaging systems, real-time communication and event-driven architecture. The duties candidates list are working with product managers and system architects, taking features from requirements through release and upkeep, reviewing teammates' code, and tuning existing systems for performance and scalability.

This guide is for Software Engineer candidates, described as having roughly 2-5 years of experience, with a banking or financial-services background counted as a plus. It covers the three reported stages (phone screen, technical interviews, team engagement) and the 17 questions candidates report, from linked lists and graph search to messaging-system design and conflict stories. The languages listed for the role are Java, C# and Python, the cloud platforms are AWS and Azure, and the working methods are Agile and Scrum.

Candidates report three stages: an HR phone screen, one or more technical interviews, and an engagement round with team members and leadership. Reports put the whole process at about 3-5 weeks, though one report says 4-6.

Focus areas

  • Messaging Systems
  • Collaboration Systems
  • Software Engineering (General)

Overview

The reported questions cluster around one theme: moving messages between parts of a system reliably. Candidates are asked to design a messaging system for a large-scale application, to describe their experience with messaging and collaboration technologies, to design an API for a new feature, and to explain what they would weigh for data storage and retrieval. That means your design answers need concrete vocabulary: delivery guarantees (at-most-once, at-least-once), idempotent consumers, ordering per key, retries with backoff, dead-letter queues, backpressure, and how you would watch queue depth and consumer lag.

The coding questions reported are fundamentals: reverse a linked list, implement a search algorithm over a large dataset, and explain depth-first versus breadth-first search. These reward clean, correct code in the language you know best (the role lists Java, C# and Python) more than exotic tricks. Be ready to write the iterative reversal without losing a pointer, to state complexity for every solution, and to say which data structure (stack, queue, hash index, sorted array) fits which access pattern.

Candidates also report production-minded questions: debug a performance issue in a production environment, scale a system when demand jumps unexpectedly, and ensure the security of a new application. Answer these as sequences. For debugging, measure first, narrow by bisection, then fix and verify. For scaling, find the bottleneck before adding capacity. For security, walk through authentication, authorization, encryption in transit and at rest, secrets handling, input validation and audit logging. Data security and regulatory compliance are listed as nice-to-have knowledge for the role, so a short, accurate answer on audit trails and access control is worth having.

The rest of the loop is behavioral: a conflict with a team member, juggling multiple deadlines, taking the lead on a project, learning a new technology quickly, and a recent challenging technical problem. Candidates also report being asked about unit testing, CI/CD pipelines and Git. Prepare five real stories told in the first person, each with a decision, a result and a lesson, and reuse them across prompts instead of memorizing scripts.

The BankUnited interview process

Candidates describe three stages. Pace and structure reportedly vary by team, so confirm the exact format with your recruiter after the first call.

Phone Screen

Candidates report that the first call is run by HR and centers on your background and motivations. Treat it as a short, structured conversation about why you fit this role. Have a clear account of your career that connects your strongest languages and any cloud or messaging work to the requirements listed for the role, and a concrete reason for wanting a bank engineering job rather than a generic one.

What to demonstrate

  • How clearly you describe your background and the work you have owned
  • Your motivations for this role and this employer
  • How your experience lines up with the listed languages (Java, C#, Python) and cloud platforms (AWS, Azure)

How to prepare

  • Write a CV walkthrough that ends on this role, with two projects you can explain in depth, one of them involving messaging, integrations or event-driven work if you have any.
  • Decide which of Java, C# or Python you will code in and be ready to say why, since the language question is reported.
  • Prepare practical answers on availability, location and the next steps, and ask the recruiter what the technical stage will contain.

Technical Interviews

Candidates report one or more technical interviews that may include coding challenges or system design discussions. The reported question types fit that format: linked lists and graph search for coding, and messaging, API, storage and security design for the discussion side. Practice both by speaking your reasoning while you write, and practise stating requirements and trade-offs before drawing any boxes.

What to demonstrate

  • Working code for fundamentals such as list reversal and graph traversal, with correct complexity
  • Reasoning about design trade-offs in a messaging or API design discussion
  • Engineering habits candidates describe being asked about: unit tests, CI/CD pipelines, Git and coding standards

How to prepare

  • Write the reverse-a-linked-list solution iteratively and recursively in your chosen language, then test it on empty, single-node and two-node lists.
  • Implement depth-first and breadth-first search on both a tree and a graph with a visited set, and be able to say when each is the right choice.
  • Sketch a messaging system end to end: producers, broker or queue, consumers, delivery guarantee, ordering, retries, dead-letter handling and monitoring.
  • Prepare a two-minute-free, concrete account of how you test: what you unit test, what runs in the CI pipeline, and how code review catches defects.

Team Engagement

Candidates report an engagement round with team members and leadership, aimed at cultural fit and strategic thinking. Expect conversation about how you work with others, handle disagreement and manage competing priorities, so the behavioral stories matter most here. Bring a view on how technical choices affect users and the business, and questions of your own about the team's work.

What to demonstrate

  • Collaboration and communication, including how you work with non-technical stakeholders
  • How you handle disagreement and feedback
  • How you think about priorities and the wider effect of technical decisions

How to prepare

  • Rehearse the conflict, prioritization and lead-a-project stories until each names a decision, a result and a lesson.
  • Prepare to explain one technical decision to a non-technical listener in plain language, without jargon.
  • Write three questions about how the team ships, reviews code and handles production issues.

Where candidates lose points

Losing the next pointer while reversing a linked list, or skipping the empty and one-node cases

Use three names (previous, current, next), save current.next before you overwrite it, and return previous. Run it by hand on zero, one and two nodes, then state O(n) time and O(1) space, noting the recursive version uses O(n) stack.

Answering the messaging-system design with 'use a queue' and stopping there

Name the delivery guarantee, how ordering is kept (a key per conversation or account), idempotent consumers, retries with backoff, a dead-letter queue, backpressure and the metrics you would watch. Then say what changes at ten times the load.

Reciting definitions for depth-first versus breadth-first search without saying when to choose each

Tie each to its structure (stack or recursion for DFS, queue for BFS), say BFS gives shortest paths in unweighted graphs, compare memory use and recursion depth, and always mention the visited set for graphs with cycles.

Giving generic answers on code quality, scaling and security ('I write tests', 'add servers', 'use encryption')

Be specific: what you unit test and what the CI pipeline gates on; find the bottleneck before scaling; for security, walk through authentication, authorization, encryption in transit and at rest, secrets, input validation and audit logging.

Telling behavioral stories in the plural, with no personal decision, result or lesson

Pick stories where you made a choice, say I for your own actions, and end each with a measurable or visible result and one thing you would change. Prepare five stories that cover conflict, deadlines, leading, learning fast and a hard technical problem.

Questions & practice

Write a function to reverse a linked list.

Medium · Coding / Algorithms

Approach

  1. Iterative version with three pointers: prev = null, curr = head; in a loop save next = curr.next, set curr.next = prev, then advance prev = curr and curr = next; return prev as the new head. O(n) time, O(1) extra space.
  2. Test the edge cases aloud: empty list (return null), a single node, two nodes, and confirm the old head's next ends up null so no cycle remains.
  3. Recursive version: reverse the rest, then set head.next.next = head and head.next = null. It is also O(n) time but uses O(n) call stack, so on a long list it can hit Python's default recursion limit of 1000 or a stack overflow in Java or C#; prefer the iterative one.
  4. For a doubly linked list, swap each node's next and prev pointers while walking, and the last node visited becomes the head.

Follow-up

  • Reverse only the nodes between positions left and right in a single pass.
  • Reverse the list in groups of k nodes, leaving a final group shorter than k unchanged.
  • Check whether a linked list is a palindrome with O(1) extra space. (fast/slow pointers to find the middle, reverse the second half, compare, then restore)

How would you implement a search algorithm in a large dataset?

Medium · Coding / Algorithms

Approach

  1. Clarify the shape of the problem first: is the data sorted, static or frequently updated, does it fit in memory, and is the query an exact match, a range, a prefix or a full-text search? Each answer changes the structure.
  2. Single lookup on unsorted data is a linear scan, O(n). Many exact-match lookups justify building a hash index once: O(n) to build, O(1) average per lookup, but no range queries.
  3. On sorted data use binary search, O(log n): compute mid as lo + (hi - lo) / 2 to avoid integer overflow in Java or C#, and use a lower-bound variant to find the first occurrence or the start of a range.
  4. If the data changes often, a sorted array costs O(n) per insert, so use a balanced tree in memory or a B-tree/B+tree index on disk, which keeps lookups and range scans logarithmic in page reads. For text search, an inverted index maps terms to document ids.
  5. Beyond one machine, partition the data and query the partitions in parallel, then merge results; state the cost of building and maintaining any index against the query speed it buys.

Follow-up

  • Write binary search that returns the first index of a target when the array contains duplicates.
  • Search for a target in a sorted array that has been rotated at an unknown pivot.
  • The dataset no longer fits in memory on one machine. How does your approach change?

Can you explain the difference between depth-first and breadth-first search?

Medium · Coding / Algorithms

Approach

  1. Mechanism: DFS follows one branch as deep as possible using a stack (explicit or the call stack), while BFS visits nodes level by level using a FIFO queue. With an adjacency list both run in O(V + E) time and need O(V) for the visited set.
  2. BFS finds the shortest path in number of edges on an unweighted graph; DFS does not. For weighted graphs with non-negative weights, switch to Dijkstra.
  3. Memory differs by shape: BFS holds the whole frontier, which can be very wide; DFS holds only the current path, O(depth), but recursive DFS on a deep graph can overflow the stack, so write it iteratively there.
  4. Typical uses: DFS for cycle detection, topological sort (reverse post-order), connected components and backtracking; BFS for shortest hops, level-order traversal and nearest-neighbour searches. In BFS, mark a node visited when it is enqueued, not when dequeued, to avoid enqueuing it twice.

Follow-up

  • Modify BFS to return the actual shortest path, not just its length. (keep a parent map and walk it back)
  • How do you detect a cycle in a directed graph with DFS? (three colours or an on-stack set)
  • When would iterative deepening DFS be a better choice than either plain BFS or DFS?

Keep soft-deleted accounts from blocking re-registration

Easy · soft delete · unique constraints · engine differences

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

Approach

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

Follow-up

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

Denormalise tenant onto revisions and backfill it live

Hard · denormalisation · online migration · backfill

resource_revision (revision_id, resource_id, version, actor_user_id, change_kind, patch, request_id, created_at) has 400M rows and no tenant column; tenant_id lives only on resource. Two reads need it: a tenant-scoped audit feed ordered by created_at DESC, and an offboarding purge. Both join back to resource today. Justify adding tenant_id to resource_revision against those two reads, name the anomaly the copy introduces and the constraint that prevents it, then give the ordered migration for a live table taking 1.2k writes/second — the lock each step takes, how the backfill is batched, and where each step stops being reversible. PostgreSQL 16.

Approach

  1. Justify from the access path rather than from taste. Without the column, the audit feed either scans resource_revision by created_at and discards other tenants' rows, or resolves the tenant's resource_ids first and probes with them — both proportional to the tenant's whole history rather than to one page. With (tenant_id, created_at DESC, revision_id DESC) it is a seek that stops at 50 rows, and the purge becomes a ranged delete instead of a join.
  2. Name the cost exactly: a second copy of a fact can disagree with the first. Make the disagreement unwritable rather than documented — add UNIQUE (resource_id, tenant_id) on resource so it can serve as a foreign-key target, then FOREIGN KEY (resource_id, tenant_id) REFERENCES resource (resource_id, tenant_id) on the revision table. A revision can then only ever carry its parent's tenant.
  3. Step one, expand: ALTER TABLE resource_revision ADD COLUMN tenant_id BIGINT NULL, with no default, so it is a catalogue change and no rewrite. It still needs ACCESS EXCLUSIVE for an instant, and that instant queues behind the longest open transaction on the table while every later query queues behind it — set lock_timeout to 2s and retry rather than wait.
  4. Step two, dual-write: deploy the writer that populates tenant_id on every new revision while reads still use the join. Reversible by redeploying the previous build, because nothing reads the column yet.

Follow-up

  • The backfill is half finished and a rollback is required. What state is the table in, and what does the previous build do with a half-populated column?
  • How do you verify the backfill actually finished, given rows are still being inserted while it runs?

Can you explain how you would design an API for a new feature?

Medium · Technical / Domain Questions

Approach

  1. Start from the consumer and the use case: who calls the endpoint, what they need back, and the failure they must handle. Then model resources as nouns, for example POST /v1/transfers to create one and GET /v1/transfers/{id} to read it, with consistent status codes (201 created, 400/422 validation, 404, 409 conflict).
  2. Make retries safe. GET, PUT and DELETE are idempotent by HTTP semantics but POST is not, so accept an Idempotency-Key header, store the key with the first response, and replay that response on a retry instead of executing twice.
  3. Write the contract first (an OpenAPI spec) with one error envelope (code, message, field details), cursor-based pagination for lists, and a versioning rule: additive changes in place, breaking changes behind /v2 or a version header.
  4. Cover security and limits in the design: OAuth 2.0 bearer tokens for authentication, an object-level authorization check on every resource id (the token owner must own that record), and rate limiting that returns 429 with Retry-After.

Follow-up

  • A client's POST times out and it retries. Walk through exactly what your server does on the second request.
  • How would you rename or change the type of a field without breaking clients already in production?
  • Why cursor pagination over offset when rows are inserted while a client is paging?

Describe a challenging technical problem you solved recently.

Medium · Technical / Domain Questions

Approach

  1. Pick a problem with a measurable symptom and a clear personal role, for example a latency regression, a data-corruption bug or a failing integration, and say "I" for what you did yourself.
  2. Structure it as symptom, constraints, hypotheses you ruled out and the evidence that ruled each one out, the fix, and the result in numbers (latency before and after, error rate, hours saved).
  3. Name the alternative fix you rejected and the trade-off that decided it (risk, effort, reversibility); that shows judgement rather than luck.
  4. Close with what you changed so it cannot recur: a regression test, an alert, a runbook entry or a design change. Avoid stories where the root cause stayed unknown unless you can explain how you contained it.

Follow-up

  • What was the second-best solution, and under what conditions would you have chosen it?
  • How did you confirm in production that your fix, and not something else, resolved the problem?
  • If the same symptom appeared tomorrow, what would you check first?

How do you ensure code quality in your projects?

Medium · Technical / Domain Questions

Approach

  1. Describe layers, not a slogan: many fast unit tests, fewer integration tests against real dependencies (for example Testcontainers for a database), and a small set of end-to-end tests, all run by CI on every pull request so a red build blocks the merge.
  2. Automate the mechanical checks so review time goes to design and correctness: a formatter plus linters and static analysis for the language in use (Ruff or flake8 for Python, Checkstyle or SpotBugs for Java, Roslyn analyzers for C#), and dependency scanning for known-vulnerable libraries.
  3. Explain your review practice: small pull requests, a description of intent and risk, tests in the same change, and reviewers checking edge cases, error handling and naming rather than style the tools already enforce.
  4. Treat coverage as a signal, not a target: a high percentage can still miss assertions, so focus tests on branches with business rules and failure paths; mutation testing shows whether tests actually catch changes.
  5. Close the loop from production: error tracking, feature flags for risky changes, and a regression test written for every bug fixed.

Follow-up

  • How do you unit-test code that calls a database or an external payment API? (dependency injection and test doubles, then a contract or integration test)
  • Would you enforce a minimum coverage number in CI? Defend the number or the refusal.
  • A reviewer and you disagree on a design choice in a pull request. How do you settle it?

What programming languages are you most comfortable with, and why?

Medium · Technical / Domain Questions

Approach

  1. Name one primary language and back it with evidence: what you built in it, at what scale, and which libraries or frameworks you know well. The requirements candidates describe for this role list Java, C# or Python, so be ready to code in whichever of those you claim.
  2. Show you understand the runtime, not just the syntax: the JVM's generational garbage collector and java.util.concurrent (plus virtual threads, final since Java 21); .NET's async/await and LINQ; CPython's GIL, which stops threads from running Python bytecode in parallel, so CPU-bound work goes to multiprocessing or native code.
  3. Give honest trade-offs: static typing and tooling for large codebases versus Python's speed of iteration and data ecosystem, and the cost of each at startup, memory and deployment.
  4. Mention a pitfall you have hit in your main language and how you guard against it, such as Python's mutable default arguments, Java null handling, or C# async void swallowing exceptions.

Follow-up

  • How does memory management differ between the JVM and CPython? (tracing GC versus reference counting plus a cycle collector)
  • Which language would you choose for a CPU-bound batch job and for a quick internal tool, and why?
  • Describe a bug your favourite language made easy to write.

Given a scenario where user demand increases unexpectedly, how would you scale the system?

Medium · Problem-Solving / Case Studies

Approach

  1. Find the bottleneck before adding capacity: check which tier is saturated (web, application, database, a downstream dependency) using latency, CPU, pool usage and queue depth, because scaling the wrong tier just moves the queue.
  2. Scale the stateless tier horizontally behind a load balancer with autoscaling (AWS Auto Scaling groups or Azure VM Scale Sets, for example). That only works if session state lives outside the process, in a shared cache or a token.
  3. Protect the system while capacity arrives: rate limiting, load shedding of low-priority work, timeouts, circuit breakers, and retries with exponential backoff and jitter so clients do not create a retry storm.
  4. Relieve the data tier: cache-aside with TTLs and request coalescing against stampedes, read replicas for read-heavy paths (accepting replication lag and handling read-your-writes), connection pooling, then partitioning if writes are the limit.
  5. Move non-urgent work onto a queue so spikes become backlog instead of errors, and autoscale the consumers on queue depth.

Follow-up

  • Autoscaling takes minutes to add instances. What keeps the service up in the meantime?
  • The database is the bottleneck and already on the largest instance. What are your options and their costs?
  • How would you tell a real demand spike from a bot attack or a retry storm?

How would you design a messaging system for a large-scale application?

Medium · System Design / Architecture

Approach

  1. Scope it out loud: one-to-one and group chat, message history, online presence, offline notifications, required delivery guarantee and ordering, and rough numbers for users, messages per second and group sizes.
  2. Connection layer: clients keep a persistent WebSocket to gateway servers; a registry (for example Redis) maps user to gateway so a message can be routed to whichever server holds the recipient's connection.
  3. Write path: the message service assigns a sortable id (Snowflake-style or a per-conversation sequence), writes to durable storage before acknowledging the sender, then publishes to a log such as Kafka partitioned by conversation id, which preserves order within a conversation.
  4. Delivery is at-least-once, so clients attach a client-generated message id and receivers deduplicate on it; track sent, delivered and read states with acks. Offline users get a push notification and, on reconnect, sync everything after their last seen sequence.
  5. Storage keyed by (conversation_id, message id) in a partitioned store (a wide-column store or sharded SQL) supports fetching recent history by range. For fan-out, write per recipient for small groups and read from the shared conversation for very large channels; add TLS, per-conversation authorization and retention rules.

Follow-up

  • Two people in the same conversation send at the same moment. How do all members see the same order?
  • A gateway server holding many open connections crashes. What do clients and the system do next?
  • How would you implement read receipts for a group with thousands of members without flooding it with events?

What considerations would you take into account for data storage and retrieval?

Medium · System Design / Architecture

Approach

  1. Start from access patterns: read/write ratio, query shapes (point lookup, range, aggregation, full text), latency targets, data volume and growth. The store follows from those, not the other way round.
  2. Match consistency to the data: a relational database with ACID transactions and constraints where invariants must hold (balances, ledgers, anything that moves money); key-value or wide-column stores for high write volume with simple key-based access, accepting weaker cross-row guarantees.
  3. Index deliberately: B-tree indexes serve equality and range queries, a composite index only helps queries that filter on its leftmost columns, and every index adds write cost and storage. Add a cache-aside layer with explicit TTL and invalidation for hot reads.
  4. Plan for scale: read replicas (with replication lag), then partitioning on a key that spreads load evenly and keeps common queries on one partition, avoiding hot keys such as a timestamp alone.
  5. Cover operations and compliance: backups with tested restores and stated RPO/RTO targets, retention and archival tiers, encryption at rest, access control and audit logging for personal and financial data.

Follow-up

  • When would you denormalise a schema, and how do you keep the copies consistent?
  • How do you choose a shard key, and what symptoms does a bad one produce?
  • How would you change the schema of a large, busy table without downtime? (expand, backfill, switch reads, contract)

Describe how you would ensure the security of a new application.

Medium · System Design / Architecture

Approach

  1. Threat model first: list the assets, the actors, the trust boundaries and the data flows, then walk STRIDE (spoofing, tampering, repudiation, information disclosure, denial of service, elevation of privilege) to decide which controls matter most.
  2. Identity and access: OIDC/OAuth 2.0 with MFA rather than custom login code, passwords (if any) hashed with Argon2, bcrypt or scrypt, short-lived access tokens, and server-side authorization on every object id, since broken object-level authorization tops the OWASP API Security Top 10 (2023).
  3. Input and output: bind parameters or an ORM for every query against SQL injection, context-aware output encoding against XSS, CSRF tokens or SameSite cookies, and strict validation at the API boundary.
  4. Data protection: TLS for everything in transit, encryption at rest with keys in a managed service (AWS KMS or Azure Key Vault), secrets kept out of source control and rotated, and no secrets or personal data written to logs.
  5. Build it into delivery and operations: SAST and dependency scanning in CI, DAST or a penetration test before launch, audit logging and alerting on suspicious access, and a patching process for libraries and base images.

Follow-up

  • How would you stop an authenticated customer from reading another customer's records by changing an id in the URL?
  • An access token leaks. What limits the damage? (short expiry, refresh-token rotation, revocation, anomaly detection)
  • How do you store, distribute and rotate database credentials for a service running in the cloud?

How would you approach debugging a performance issue in a production environment?

Medium · Problem-Solving / Case Studies

Approach

  1. Quantify before theorising: which endpoint or job, p50 versus p99 latency, error rate, and when it started; then line that start time up against deploys, configuration changes, traffic shifts and dependency incidents.
  2. Mitigate first if users are affected (roll back, scale out, disable the feature behind a flag), then find the root cause; say explicitly that mitigation and diagnosis are separate steps.
  3. Check resources with the USE method (utilisation, saturation, errors): CPU, memory and GC pauses, thread and connection pool saturation, disk and network. Use distributed tracing on a slow request to see which span dominates.
  4. If the database dominates, read the slow-query log and run EXPLAIN ANALYZE to spot a sequential scan, a missing or unused index, N+1 queries from the ORM, or lock waits. If application code dominates, take a low-overhead sampling profile in production (async-profiler for the JVM, py-spy for Python, dotnet-trace for .NET).
  5. Confirm the fix against the same metric that showed the problem, then add an alert or a load test so the regression is caught earlier next time.

Follow-up

  • p99 latency doubled but p50 is flat. What does that point to? (GC pauses, lock or pool contention, one slow tenant or query shape, retries)
  • Latency rose with no deploy in the window. Where do you look next?
  • How do you profile a production service when you cannot attach a debugger or restart it?

Suggested practice checklist

The plan follows the three reported stages and the reported question types: coding fundamentals, messaging and API design, production reasoning, and behavioral stories. Each day ends with something you can show or say aloud.

Day 1 — Map the loop and choose your language

  • Write a one-page map of the phone screen, technical interviews and team engagement, noting which reported questions belong to each question type.
  • Choose Java, C# or Python for coding and write two honest sentences on why, for the language question.
  • List five projects from your career and mark which involve messaging, integrations, events or cloud services.

Deliverable: A one-page loop map, a language rationale, and a list of five annotated projects.

Day 2 — Coding fundamentals

  • Write the iterative and recursive reversal of a linked list, and test on empty, single and two-node inputs.
  • Write depth-first and breadth-first search on a graph with a visited set, and note complexity and when to choose each.
  • Write binary search and a hash-index lookup, and explain which fits a large dataset and why.

Deliverable: Working, tested code for list reversal, DFS, BFS and search, plus a short note of complexities.

Day 3 — Messaging system design

  • Sketch a messaging system for a large-scale application: producers, broker, consumers, storage, delivery guarantee, ordering, retries and dead-letter handling.
  • Write a one-page table of at-most-once, at-least-once and effectively-once delivery with the consumer behavior each requires.
  • Prepare your answer about your own messaging and collaboration experience, with one decision per technology you name.

Deliverable: A labeled messaging design diagram, a delivery-guarantee table and a spoken answer about your own experience.

Day 4 — API and storage design

  • Write the contract for one new feature's API: resources, methods, status codes, pagination, an idempotency key and versioning.
  • Make a storage decision sheet covering access patterns, indexes, consistency needs, retention and backup.

Deliverable: An API contract, a storage decision sheet, and two solved practice SQL questions.

Day 5 — Production debugging, scaling and security

  • Write a debugging sequence for a slow production service: what changed, which metrics to check, how to bisect, how to confirm the fix.
  • Write a scaling plan for a sudden demand spike: find the bottleneck, then cache, scale out, queue or shed load, with the trade-off of each.
  • Write a security checklist for a new application covering authentication, authorization, encryption, secrets, input validation, dependencies and audit logging.

Deliverable: A debugging runbook, a scaling plan and a security checklist, each fitting one page.

Day 6 — Engineering practice and your technical story

  • Write your answer on code quality: what you unit test, how code review works, what the CI/CD pipeline checks and how you use Git branches.
  • Outline the challenging technical problem you solved recently: context, what made it hard, your steps, the result and what you would change.
  • Say your language answer aloud, with one strength and one limitation of the language you chose.

Deliverable: Spoken answers to the code quality, challenging problem and language questions, with notes.

Day 7 — Behavioral stories and questions for the team

  • Write out the conflict, prioritization, lead-a-project and learn-fast stories with a decision, a result and a lesson in each.
  • Say each story aloud and cut anything that does not show your own action.
  • Write three questions about how the team ships, reviews code and handles production issues.

Deliverable: Four rehearsed stories and a list of three questions to ask the team.

Stories to prepare for the team rounds

The team engagement round, as candidates describe it, covers cultural fit and strategic thinking with team members and leadership, and the evaluation areas reported are collaboration, communication, feedback and stakeholder engagement. For a Software Engineer, that means stories about disagreeing productively, managing deadlines, taking ownership and learning quickly, told with a clear personal decision and result.

  1. Describe a time when you had to pivot your approach mid-project.

What is your experience with messaging and collaboration technologies?

Medium · Technical / Domain Questions

Approach

  1. Open with one real system where you moved messages or coordinated people: a queue-backed service, a notification pipeline, a chat or comment feature, an event stream, or email and webhook delivery. Say what it carried and what your part was.
  2. Attach a decision to each technology you name: the delivery guarantee you chose (at-least-once with idempotent consumers, for example), how you kept ordering per key, how retries and a dead-letter queue worked, and which signals you watched (queue depth, consumer lag, redelivery count).
  3. If collaboration tooling was your angle, describe how you used it in practice to run a release or an incident, not a list of product names.
  4. If your direct experience is thin, say so in one sentence and bridge with the closest real work, such as a REST integration, a scheduled job or a small producer and consumer you built in Java, C# or Python. Never claim experience you cannot explain.

Follow-up

  • How would you guarantee a message is not processed twice?
  • What happens to ordering when you add more consumers?
  • How did you notice it was failing, and what alert fired first?

Describe a time when you had to learn a new technology quickly to complete a project.

Medium · Problem-Solving / Case Studies

Approach

  1. Choose a case with a real deadline and a real gap, such as your first time with a cloud service, a framework or a messaging library. State what was due and what you did not know in two sentences.
  2. Show a method: decide what the task actually needs, read official documentation and sample code, build a throwaway spike to test the riskiest assumption, ask someone experienced for a short review, then implement with tests.
  3. Show how you protected delivery while learning: reduced scope, a feature flag, extra review on the unfamiliar parts, tests around the integration points.
  4. Finish with the outcome and what stayed behind, such as a short write-up for the team. The story fails if it has no obstacle (read the docs, it worked) or if you hid the gap from the people depending on you.

Follow-up

  • What did you get wrong first, and how did you find out?
  • How did you decide what not to learn yet?
  • When do you ask for help rather than keep digging?

Tell me about a time you had a conflict with a team member and how you resolved it.

Medium · Behavioral / Leadership

Approach

  1. Choose a genuine disagreement on something concrete: an API shape, review feedback, how to split work, or an estimate. Skip personality clashes with no technical content.
  2. Describe the other person's position fairly in a sentence before giving yours, so it is clear you understood it.
  3. Show how it was resolved: a direct private conversation first, then evidence such as a benchmark, a prototype or a written comparison, and escalation to the tech lead only if evidence could not settle it.
  4. State the outcome and the relationship afterward, including whether you changed your mind. A story where the other person is a villain, or one where you avoided conflict entirely, sinks the answer.

Follow-up

  • What would you have done if they still disagreed after the evidence?
  • Did you change your position at any point?
  • How do you raise a disagreement in a team meeting versus one to one?

How do you prioritize your work when you have multiple deadlines?

Medium · Behavioral / Leadership

Approach

  1. Give your method in a sentence, then prove it with a case: list everything due, estimate each item, rank by the consequence of missing it, and note dependencies, since work that blocks others goes first.
  2. Show that you communicate: tell each affected stakeholder which date moves and why, and ask the product manager to confirm the order instead of deciding silently.
  3. Show a trade-off you made: cutting scope, splitting a first release, delegating or deferring. Name what slipped and how you handled it.
  4. If you work in Agile and Scrum, mention the mechanics honestly: backlog ordering, sprint commitments, flagging risk early. Avoid answers such as working longer hours or treating everything as top priority.

Follow-up

  • Two stakeholders both say their request is urgent. What do you do?
  • What did you do when an estimate turned out wrong?
  • How do you protect time for code review and production support?

Describe a situation where you took the lead on a project.

Medium · Behavioral / Leadership

Approach

  1. Pick a project where you owned the outcome. Informal leadership counts, and no title is needed. Say what the goal was and why it needed someone to take charge.
  2. Show concrete actions: you broke the work into pieces, wrote the plan or design outline, assigned tasks by strengths, set up check-ins, unblocked others and took the riskiest piece yourself.
  3. Show how you kept quality up: the review standard, the tests, the release steps, and how you handled a teammate who fell behind.
  4. Give the result and a reflection, credit the team accurately and use I for your own decisions. A story where your role is unclear, or one that claims all the credit, weakens the answer.

Follow-up

  • What did you delegate and what did you keep?
  • How did you handle someone who fell behind?
  • What would you change about how you ran it?