cswork / libraryOpen practice workspace

Interview guides · Buzzclan

Buzzclan Software Engineer Interview Guide

Buzzclan Software Engineer interview guide: reported questions, Java, Spring Boot and Flowable topics, project-story prep and a 7-day plan.

The 60-second brief

Candidate reports describe Buzzclan engineering work as joining specialised services together and tuning workflows, with business process automation and process modelling among the reported topics. Flowable (the Java engine for BPMN workflows, CMMN case management and DMN decisions), Java and Spring Boot are the technologies candidates tie to the interview. The reports do not name specific products or customers, so treat the stack as the concrete part and ask your recruiter which team and which systems the role touches. A Software Engineer there is described as someone who turns business requirements into maintainable services and can explain the choices behind them.

This guide is for Software Engineer candidates preparing for a Buzzclan loop. It covers the eight reported questions: coding practice, design patterns, edge cases and error handling, production debugging, documentation, career and project walkthroughs, balancing business and time constraints, and third-party integration. It also covers the reported topics: Flowable, Java, Spring Boot, business process automation and workflow modelling. It ends with a seven-day plan.

Candidates report a preliminary HR screen followed by several technical and management-focused rounds, mixing architecture discussion with deep dives into your previous work. No round names, order or durations are reported.

Focus areas

  • Flowable (BPM/Workflow/Case Management/DMN)
  • Java
  • Spring Boot

Overview

The reported questions are conversational rather than puzzle-shaped. They ask how you keep code to a standard, which design patterns you have used, how you handle edge cases, how you debug in production, how you document, and how you integrate outside services. Each one is answered best with a real example from your own code, so the main preparation is mining your history, not memorising theory.

Two question groups are reported: technical practices and project deep-dives. The project group asks for your career journey, your most challenging delivery, a time you balanced technical requirements against business or time pressure, and your approach to third-party integration. Candidates also report that some interviewers press for detail on the business side of a past project. Know where your scope started and stopped, and be able to return to the engineering you personally did.

The topics extracted from candidate reports are Flowable, Java, Spring Boot, business process automation and workflow or process modelling. If these are on your resume, expect to explain how you used them: how a process definition is deployed, what a service task does when it throws, how a Spring Boot service is configured and tested. If one is not on your resume, learn its basics and say plainly what you have and have not done with it.

The reports also say rounds include management-focused conversations and that you may need to explain technical decisions to stakeholders. Prepare two versions of each project story: a technical one with the decision, the alternative you rejected and the trade-off, and a shorter one a project manager could follow.

Where to focus your preparation

Candidates report an HR screen and then several technical and management-focused rounds, without a published order. The single entry below covers the whole loop.

Preparation focus

Candidates report an HR screen first, then several technical and management-focused rounds that combine architecture-level discussion with detailed walkthroughs of work you have already done. Names, order, count and length of the rounds are not reported, and the reports say whether code is written on a whiteboard varies, so ask your recruiter for the format of each stage. Prepare in two layers. First, your own history: two or three projects you can describe from requirement to release, including the decisions you would defend today. Second, the reported technical practice questions and stack topics (Java, Spring Boot, Flowable, process modelling), each with a concrete example from your work.

What to demonstrate

  • Fluency in your main stack and how it fits into a larger system, as candidates describe the rounds
  • How clearly you explain technical decisions, including to non-engineering stakeholders
  • How well you can account for every technology and project on your resume
  • How you turn a business need into an engineering approach and handle pressure on scope or time

How to prepare

  • Write an outline for two or three projects covering the problem, the constraint, your own scope, the decision, the alternative you rejected and the outcome
  • Review each technology on your resume and write one sentence on why it was used and one on something that went wrong with it
  • Refresh Java and Spring Boot error handling and testing, plus the BPMN, CMMN and DMN basics behind Flowable
  • Ask the recruiter which stages involve live coding, and who will be in the management-focused rounds

Where candidates lose points

Telling project stories only in business terms, or getting pulled into the business details of a past project and never returning to your own engineering

Candidates report that interviewers may press on the business side of earlier work. Acknowledge the context in one sentence, then state your scope: the component you built, the technology, the decision and the trade-off. Rehearse that pivot aloud.

Naming design patterns from a textbook list without pointing to a place in your own code where you used one

Pick three patterns you really applied. For each, state the problem, where it sits in the codebase, what the alternative was and what the pattern cost you in indirection. If you only used one pattern in a project, say so instead of padding.

Listing Java, Spring Boot or Flowable on your resume and then being unable to explain how you used them, such as what happens to a process definition at deployment or what a failing service task does

Go through the resume line by line and write two facts for each technology: why it was chosen and what broke. Learn the BPMN, CMMN and DMN basics behind Flowable, and state plainly any part you have not used.

Answering the production-debugging question with a guess at the cause instead of a sequence

Give an order: scope the impact, find what changed, read logs, metrics and traces, reproduce or narrow down, mitigate first if users are hurt, fix the cause, verify, then write down what would have caught it earlier. Illustrate it with one real incident.

Describing third-party integration as 'call the API and handle the response', with no mention of failure

Cover the contract and versioning, authentication, timeouts, retries with backoff, idempotency, mapping the vendor's errors to your own, an adapter layer that isolates the dependency, contract tests, and monitoring or a fallback when the service is down.

Questions & practice

Collapse a redelivered event batch into per-aggregate high-water marks

Easy · hashing · at-least-once · aggregation

You drain a batch of up to 5,000,000 events, each (aggregate_id BIGINT, aggregate_version INT, event_type, payload). The log guarantees order within one aggregate only; the batch merges 64 partitions, and a relay failover has redelivered a range, so an older version for an aggregate can appear after a newer one. Given a map of last_applied_version per aggregate, produce the events worth applying, at most one per (aggregate_id, version), plus the count discarded. Target O(n) time. State the memory for 2,000,000 distinct aggregates and what you do when it does not fit.

Approach

  1. One pass, one hash map from aggregate_id to the highest version kept, and a discard counter. An event whose version is at or below last_applied_version for its aggregate is dropped without further work, which is the whole reason the event carries its version rather than a delta. O(n) expected time, O(d) space in distinct aggregates.
  2. Keep the maximum, never the last occurrence. The redelivered range means the final appearance of an aggregate in the batch can be an older version than one seen earlier in the same batch, so last-wins applies stale state over newer state and the projection regresses with no error anywhere.
  3. Cost the memory instead of calling it large: an 8-byte key plus a 4-byte version is 12 bytes of payload, and an open-addressed table held at a 0.7 load factor costs roughly 17 bytes per entry before per-slot metadata, so 2,000,000 aggregates is tens of megabytes in a native layout and several times that in a runtime that boxes both key and value.
  4. If the distinct set exceeds memory, partition on hash(aggregate_id) mod P and reduce each partition independently. Every event for one aggregate hashes to the same partition, so the per-partition result is exact and the merge is concatenation rather than a second reduction.

Follow-up

  • The payload is a patch rather than a snapshot, so applying only the highest version loses the intermediate changes. What changes in your reduction?
  • How do you detect that version 7 arrived while version 6 was never delivered, and what should the consumer do about the gap?

Track a rolling failure rate per destination for circuit decisions

Easy · sliding window · ring buffer · circuit breaker

The egress service delivers about 1,500 webhooks per second across roughly 40,000 destinations, each call bounded by a 10 second timeout. Maintain, per destination, the failure rate over the trailing 60 seconds so a caller can ask before dispatch whether the circuit should open. Attempts arrive as (destination_id, finished_at_ms, outcome). Requirement: amortised O(1) per attempt, with total memory bounded by the destination count rather than by traffic. Give the structure, its exact memory, and the rule that stops a destination with three attempts from opening a circuit.

Approach

  1. Name the exact-deque version and then reject it as the default. Holding timestamps and advancing a tail pointer past anything older than now minus 60 seconds is a correct two-pointer window at amortised O(1) per attempt, but its memory tracks in-window traffic, so one destination in a retry storm holds hundreds of thousands of entries while thousands of quiet destinations hold none.
  2. Use a ring of 60 one-second buckets per destination, each bucket a pair of counters for attempts and failures. On an attempt, advance the ring by the elapsed whole seconds, zeroing at most min(elapsed, 60) buckets, then increment the head. That is amortised O(1) with a fixed footprint per destination.
  3. State the footprint: 60 buckets times two 4-byte counters is 480 bytes of payload per destination, so 40,000 destinations is roughly 20 to 25 MB with per-entry overhead, bounded by the catalogue rather than by the rate. The cost is granularity, since the oldest bucket ages out in whole seconds, which is far tighter than the decision needs.
  4. Require a minimum sample before the circuit may open. A destination with three attempts and three failures reads as 100 percent and is not evidence; a floor of roughly 20 attempts in the window makes the ratio meaningful, and below that floor use a run of consecutive failures as the trigger instead.

Follow-up

  • The fleet is 30 instances and each sees roughly a thirtieth of a destination's traffic. Where does the rate actually live, and what does a per-instance answer get wrong?
  • A destination answers in 9.5 seconds and succeeds. It is not failing but it is consuming your per-destination concurrency. What signal should open the circuit here?

Archive a resource graph without breaking live references or recursing

Medium · graph traversal · topological order · tenant isolation

Resources reference other resources within a tenant; for the largest tenant the reference table holds up to 2,000,000 nodes and 8,000,000 edges. Archiving a resource must archive everything reachable from it that nothing outside the set still references, refuse when a live external referrer exists, and terminate when references form cycles, which they legitimately do. Produce the archive order and the refusal list, targeting O(V+E). Say what stops the traversal crossing a tenant boundary, and why recursion is the wrong control structure at this size.

Approach

  1. Load the subgraph with the tenant predicate on both endpoints of the edge, not only on the side you started from. Scoping the left table alone is the classic cross-tenant leak: one mis-entered edge then pulls another tenant's resources into the traversal and, worse, into the archive.
  2. Traverse iteratively with an explicit stack. A 2,000,000-node graph can hold a chain deep enough to exhaust a native stack in the low tens of thousands of frames, and that failure is a process crash rather than an error you can return.
  3. Treat cycles as data rather than corruption: compute strongly connected components with Tarjan in O(V+E) using its own explicit stack, then condense. The condensation is a DAG, so a topological order over it gives the archive order, and every member of a component archives in one transaction because no order within a cycle is valid.
  4. Decide refusals with reverse edges. A candidate is archivable only if every in-edge originates inside the candidate set, so build the transpose or count in-degrees restricted to the visited set, and emit each blocked resource with the id of the external referrer, which is the only part of the answer an operator can act on.

Follow-up

  • The graph is read in one query and the archive writes a minute later. What can change in between, and how do you make the write safe?
  • The candidate set is 400,000 resources. Is that one transaction, and if not, what does a half-finished archive look like to a reader?

Keep soft-deleted accounts from blocking re-registration

Easy · soft delete · unique constraints · engine differences

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

Approach

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

Follow-up

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

Explain why the owner filter ignores the listing index

Medium · composite index · query plans · sort elimination

The only index on resource is (tenant_id, status, updated_at DESC, resource_id DESC). A new endpoint returns one user's resources across all statuses, newest created first: WHERE tenant_id = $1 AND owner_user_id = $2 ORDER BY created_at DESC LIMIT 20. On a tenant with 2M rows it takes 900 ms and EXPLAIN shows a sort above a large scan. Explain precisely why the existing index cannot serve it, give the index that can, and state which of these the new index still will not help: owner_user_id alone across tenants; the same query ordered by updated_at. PostgreSQL 16.

Approach

  1. Separate the two jobs an index does. For filtering, a composite btree is seekable only on a left prefix, so with no predicate on status the scan can at best range over tenant_id and test owner_user_id per row; PostgreSQL 16 has no btree skip scan to jump the unconstrained column.
  2. For ordering, the index is sorted by (status, updated_at) within a tenant and not by created_at, so the LIMIT cannot stop early: every matching row is read and then sorted. That is the 'Sort Method: top-N heapsort' line, and it is why the plan reads 2M rows to answer with 20.
  3. Derive the replacement from the access path — equality, equality, then the ordering column: CREATE INDEX CONCURRENTLY ON resource (tenant_id, owner_user_id, created_at DESC). The scan seeks to the (tenant, owner) range and walks 20 entries in order, so the Sort node disappears along with the row-read.
  4. Treat INCLUDE (title, status) as conditional, not free. An index-only scan still visits the heap for any row whose page is not marked all-visible, so on a table taking 1.2k writes/second the win depends on autovacuum keeping the visibility map current, and the wider index costs more on every insert.

Follow-up

  • 90% of rows are status='active'. Would a partial index WHERE status = 'active' change your answer, and for which of the three queries?
  • A dashboard runs this for 40 owners in one page load. What changes about the design?

How do you ensure your code adheres to industry-standard coding practices?

Medium · Technical Proficiency and Best Practices

Approach

  1. Name the layers that make a standard enforce itself: a formatter and linter in the build (Spotless or Checkstyle for Java), static analysis for bug patterns (SpotBugs, PMD or Sonar), and a CI pipeline that blocks the merge when any of them fail. That way style is never argued about in review.
  2. Describe the test pyramid in Spring Boot terms: JUnit 5 and Mockito for service logic, slice tests such as @WebMvcTest and @DataJpaTest for the web and persistence layers, a few @SpringBootTest integration tests, and a JaCoCo coverage floor used as a minimum, never as the goal.
  3. Show what you check in review that tools miss: transaction boundaries, error paths, naming, and constructor injection over field injection so dependencies are explicit, final and easy to mock.
  4. Close with one real defect a rule or review caught before production. One concrete case shows the standard was used, not just written down.

Follow-up

  • How would you bring a legacy codebase up to standard without one huge reformatting commit?
  • When do you suppress a static-analysis finding, and how do you record why?
  • What do you do when a reviewer insists on a convention you think is wrong?

Can you explain the design patterns you have implemented in your recent projects?

Medium · Technical Proficiency and Best Practices

Approach

  1. Pick two or three patterns you actually shipped and give each one the same shape: the recurring problem, why the pattern beat the simpler option, and what it cost in indirection or extra classes.
  2. Strong Java and Spring examples: Strategy, with Spring injecting a List or Map of implementations so adding a variant needs no if/else edits; Adapter wrapping a third-party client behind your own interface; Builder for immutable objects with many optional fields; Observer through ApplicationEventPublisher and @TransactionalEventListener, which by default fires after commit.
  3. If you have worked with Flowable, a JavaDelegate per service task is a natural example: each task's logic sits behind one interface, and the BPMN model wires it in by class or by delegateExpression pointing at a Spring bean.
  4. Know the proxy pattern behind @Transactional: Spring wraps the bean in a proxy, so a call from one method to another inside the same class skips the proxy and starts no transaction.
  5. Name a case where you chose not to use a pattern, for example one implementation that did not need a Strategy interface yet. Knowing when a pattern is overkill matters as much as knowing it.

Follow-up

  • Where did a pattern make the code harder to change, and what did you do about it?
  • How did you unit test the strategy selection logic?
  • Why does a @Transactional method called from the same class not run in a transaction, and how would you fix it?

How do you document your code to ensure maintainability for future developers?

Medium · Technical Proficiency and Best Practices

Approach

  1. Separate the layers: clear names and small methods carry the 'what'; comments explain the 'why' (a workaround, a non-obvious constraint); Javadoc on public APIs states the contract, meaning parameters, return value, exceptions thrown, nullability and thread safety.
  2. Write service-level docs: a README covering build, run, configuration and ownership, plus short architecture decision records that say why a choice was made and which alternatives were rejected.
  3. Generate API docs from code so they cannot drift, for example OpenAPI through springdoc-openapi. For workflow code, the BPMN or DMN model is documentation in its own right, so give tasks, gateways and process variables meaningful names.
  4. Keep docs current through process, not good intentions: docs live in the same repo, review checks them in the same pull request as the code, and tests serve as runnable examples of intended behaviour.

Follow-up

  • How do you stop documentation from falling out of date?
  • When is a comment a sign that the code should be refactored instead?
  • What would a new developer on your service need on their first day?

Walk me through your career journey and the most challenging project you have delivered.

Medium · Experience and Project Deep-Dives

Approach

  1. Keep the career arc short: each move with one technical reason (a new stack, bigger scope, a harder domain), ending on why this role fits next.
  2. For the project, give the context in a couple of sentences, then the architecture (components, data flow, the stack and why it was chosen) and your own scope stated plainly: 'I owned the integration layer and the deployment pipeline'.
  3. Spend most of the answer on the hardest technical problem: the constraint, the options you weighed, the decision and its trade-off, and a measured outcome such as latency, error rate or delivery date.
  4. Candidates report that some interviewers ask detailed questions about the business side of past projects. Answer those briefly and accurately, then bring the answer back to the part you built.
  5. Be ready to go one level deeper on anything you mention. Every technology on your resume and in the story is fair game, so leave out anything you cannot explain.

Follow-up

  • What would you design differently if you started that project today?
  • Which part was your contribution and which was the team's?
  • How did you know the project succeeded?

Describe a situation where you had to balance technical requirements with business or time constraints.

Medium · Experience and Project Deep-Dives

Approach

  1. Pick a story with a real trade-off: a deadline or budget that forced a choice between scope, quality and time. Say what was at stake on each side.
  2. Show how you framed the options for the stakeholder: two or three choices, each with its cost and risk in their terms, and your recommendation. Do not present it as a yes-or-no on your preferred design.
  3. State what you would not cut (correctness, security, data integrity, the tests on the risky path) and what you deliberately deferred.
  4. Show that the debt was recorded and paid: a ticket, a follow-up release, or a metric you watched to know when the shortcut started to hurt.
  5. What sinks this answer: a story where the only lever was working overtime, or where tests or reviews were dropped quietly and never reported.

Follow-up

  • What did you refuse to compromise on, and how did you defend it?
  • Was the deferred work ever done? If not, what happened?
  • How do you push back when a requirement threatens the system's integrity?

How do you approach the integration of third-party services or components into your architecture?

Medium · Experience and Project Deep-Dives

Approach

  1. Assess the dependency before writing code: the API contract and versioning policy, rate limits, SLA, authentication (often OAuth2 client credentials), data handling requirements, and how hard it would be to replace the vendor.
  2. Isolate it behind your own interface (an adapter or anti-corruption layer) so vendor models and exceptions never leak into domain code. Test against stubbed responses with WireMock, including error and slow responses.
  3. Make every call resilient: connect and read timeouts, retries with exponential backoff and jitter only for idempotent calls or calls carrying an idempotency key, and a circuit breaker and bulkhead (Resilience4j) so one failing vendor cannot use up your threads.
  4. Make slow or unreliable calls asynchronous. In Flowable, an async service task becomes a job the job executor retries (three attempts by default) before moving it to the dead-letter jobs, where it can be inspected and retried.
  5. Make the integration observable: per-vendor latency and error-rate metrics, request ids logged on both sides, and credentials kept in a secrets store rather than in properties files.

Follow-up

  • The vendor timed out after you sent a payment request. How do you find out whether it went through?
  • How do you handle a breaking change in the vendor's API?
  • How would you test the integration in CI without calling the real service?

What is your approach to debugging complex issues in a production environment?

Medium · Technical Proficiency and Best Practices

Approach

  1. Limit the damage before finding the cause: measure who is affected, then roll back, switch off the feature flag or scale out. Root cause comes after users stop being hurt.
  2. Build a timeline of what changed when the symptom started (deploy, config, dependency version, traffic, data shape), then line up logs, metrics and traces on it. A correlation id in the SLF4J MDC lets you follow one request across services.
  3. Use the JVM tools that match the symptom: thread dumps (jcmd Thread.print or jstack) for hangs, deadlocks and pool exhaustion; a heap dump (jcmd GC.heap_dump) and an analyzer for memory growth; GC logs for latency spikes. Spring Boot Actuator's loggers endpoint can raise one package's log level at runtime without a redeploy.
  4. Turn each theory into a test that rules something out, reproduce it outside production with production-like data, then fix it and add a regression test.
  5. Finish with a blameless postmortem: the trigger, the underlying cause, why monitoring did not catch it sooner, and the follow-up actions with owners.

Follow-up

  • How do you debug an intermittent failure you cannot reproduce locally?
  • How would you tell a slow downstream service from an exhausted thread or connection pool?
  • What alert would have caught this issue earlier?

Suggested practice checklist

The plan starts with your own project history because every reported question draws on it. It then works through Java and Spring Boot error handling, Flowable and process modelling, patterns and documentation, production debugging, trade-offs and integrations, and ends with a full mock.

Day 1 — Build your project inventory and career walkthrough

  • List every technology and project on your resume, with one sentence on why it was used and one sentence on something that went wrong with it
  • Write an outline for the two or three projects you would defend in depth: problem, constraint, your scope, decision, rejected alternative, outcome
  • Write a spoken career walkthrough that ends on the most challenging project you delivered and say it aloud once

Deliverable: A resume inventory, three project outlines and a written career walkthrough you can say aloud.

Day 2 — Java and Spring Boot: edge cases and error handling

  • In a small Spring Boot sample or one of your own services, add Bean Validation and a @ControllerAdvice that returns one consistent error body
  • Write parameterized JUnit tests for boundary inputs: null, empty, maximum length, duplicates, repeated requests
  • Write the edge-case story as a concrete case, including one edge you missed and what you changed afterwards
  • Write down your own code-quality routine: reviews, static analysis, tests, CI

Deliverable: A working exception handler, a test class covering the boundaries, a written edge-case story and a code-quality checklist.

Day 3 — Flowable and process modelling

  • Model a small approval process in BPMN with a user task, a service task, an exclusive gateway and an error boundary event
  • Write one DMN decision table for a rule in that process, and note in a sentence when you would use a case model (CMMN) instead
  • Write out what happens in a Spring Boot application when the service task throws: retries, failed job, how an operator sees it

Deliverable: A BPMN diagram, a DMN decision table and a written explanation of the failure path.

Day 4 — Design patterns and documentation

  • Choose three patterns you really used and write, for each, the problem, the place in the code, the rejected alternative and the cost
  • Outline how you document a service: README, API description, decision records, and comments that explain why rather than what
  • Say each pattern write-up aloud as a concise answer to the design-patterns question

Deliverable: Three pattern write-ups and a documentation outline, each rehearsed aloud once.

Day 5 — Production debugging

  • Write your debugging sequence from alert to postmortem: impact, recent changes, logs, metrics and traces, narrowing down, mitigation, fix, verification
  • Choose one real incident and tell it using that sequence, including the dead end you hit
  • Solve the practice exercise on tracking a rolling failure rate per destination, which mirrors watching a flaky downstream dependency

Deliverable: A one-page debugging runbook, a spoken incident walkthrough and a working solution to the rolling failure-rate exercise.

Day 6 — Business trade-offs and third-party integration

  • Write the trade-off story: the requirement, the deadline or business pressure, what you cut, what you protected, how you told stakeholders
  • Write an integration checklist: contract and versioning, auth, timeouts, retries with backoff, idempotency, error mapping, adapter layer, contract tests, monitoring
  • Rehearse the practice behavioral prompt about arguing against a design and committing anyway, as extra material on disagreement

Deliverable: A written trade-off story, an integration checklist and a rehearsed answer on disagreeing with a decision.

Day 7 — Full mock and questions to ask

  • Run a mock in order: career walkthrough, one deep project dive, the edge-case question, the debugging question
  • Have the mock-interviewer press on business details of a project, and practise returning to your own scope
  • Write three questions to ask about the team's current technical challenges, and note the weakest answer to fix

Deliverable: A mock-interview recording or notes with the weakest answers marked, and three questions to ask.

Project stories and trade-off answers

The reported project and behavioral questions ask for your career path, your hardest delivery and a time you balanced engineering needs against business or time pressure. Candidates also report that you may need to explain technical details to stakeholders and keep to your own scope. Each story should show a decision you made, the constraint behind it and the result.

  1. Walk me through your career journey and the most challenging project you have delivered.
  2. Describe a situation where you had to balance technical requirements with business or time constraints.
  3. Tell me about a time a business requirement threatened the integrity of the design. How did you push back, and what was agreed?
  4. Describe a time you explained a technical decision to a stakeholder who was not an engineer. What did you leave out, and why?

How do you handle edge cases and error handling in your development process?

Medium · Technical Proficiency and Best Practices

Approach

  1. Open with one real case, not a philosophy. Name the feature or service, the input or failure you were guarding against, and your part in it. A list of habits such as 'I use try/catch and write unit tests' reads as rehearsed and gives the interviewer nothing to probe.
  2. Show the sequence. While reading the requirement, list boundary and hostile inputs: null or empty values, maximum sizes, duplicates, repeated or out-of-order requests, time zones, concurrent updates. Decide what the system does for each and confirm the ambiguous ones with the requirement owner before you write code.
  3. Describe the design of the error path. Validate at the boundary (for example Bean Validation in a Spring Boot controller), use specific exception types, map them centrally (a @ControllerAdvice with @ExceptionHandler methods) to one consistent error body, never swallow an exception silently, and log with a correlation id. Separate retryable failures such as timeouts from permanent ones such as invalid input, and put timeouts and idempotency on calls to external services.
  4. If you have workflow experience, say what happens when a step fails: the retry count, the error path or boundary error event, and how a stuck job becomes visible to an operator instead of disappearing.
  5. Prove it. Mention parameterized tests for each boundary, a test per defect you found, and tests that force the failure path. Close with a result you can verify, and with one edge case you missed and what you changed afterwards. Do not quote a metric you cannot defend.

Follow-up

  • Tell me about an edge case that still reached production. How did you find it and what changed afterwards?
  • When do you fail fast and when do you degrade gracefully, and how did you decide in this case?
  • How did you test the failure path, and how would you know in production that it was firing?

Argue against a design, lose, and commit anyway

Medium · disagreement · service boundaries · decision records

Describe a design you argued against and lost. State the failure you predicted as a named mechanism, not a feeling about complexity: two services that would need one transaction, a projection with no rebuild path, a write path with no idempotency key. Say what evidence you brought, what the decision maker weighed instead, and what you did after the decision was made: what you instrumented, what you wrote down, and whether the prediction came true. Five minutes.

Approach

  1. State the prediction in falsifiable form up front: the mechanism, the condition that triggers it, and the observable outcome. A prediction that cannot be checked also cannot be credited to you later.
  2. Show the evidence you had at the time and label each piece honestly as measured, analogous, or intuition. Keeping the intuition is fine; disguising it as data is the thing that erodes your standing in the next argument.
  3. Represent the opposing case at full strength, including the constraint you did not control: a fixed date, a team boundary, or the fact that the decision was cheap to reverse and yours was not.
  4. Make disagree-and-commit concrete. Name the artefact you left behind so the prediction could be settled without you: the alert and its threshold, the counter on the dashboard, the decision note that recorded the trade-off and the condition that would revisit it.

Follow-up

  • What threshold on that alert would have proved you right, and did anyone ever look at it?
  • If the same proposal arrived tomorrow with the same deadline, would you argue it the same way?

Unblock an engineer without taking the keyboard

Easy · mentoring · leases · at-least-once

A teammate has spent two days on a job handler that occasionally writes duplicate rows. They are certain the queue is delivering twice by mistake. You suspect a lease expiring under a slow handler, so the job is running concurrently with itself. Describe how you have unblocked someone in this position: what you asked before offering a hypothesis, what you showed them rather than told them, and what you left them owning. Then say what you would do if their theory turned out to be the right one.

Approach

  1. Ask before diagnosing, and ask for things answerable from data they already have: the attempt count on the job rows that produced duplicates, the handler's observed duration against its lease expiry, and whether the duplicate rows share a natural key that a unique constraint could have caught.
  2. Teach the shape rather than the answer. A lease cannot distinguish a dead worker from a slow one, so a handler that outruns its lease is running twice by design, and deploys deliver the other half by killing handlers mid-run on every rollout. Both of their candidate theories produce identical duplicate rows, which is why the evidence has to come from timings rather than from argument.
  3. Hand over a checklist they execute: a natural key on every write the handler performs so the second copy collides rather than appends, the record of intent written before any external effect, a lease heartbeat while running, and the metric that shows it working.
  4. Keep ownership with them deliberately. Pair on the first write, then step back; if you finish it yourself you have closed one ticket and left the same person stuck on the next redelivery.

Follow-up

  • How would you distinguish a genuine double-delivery from a lease expiry using only the data already stored?
  • Their handler calls an external endpoint before recording that it did. What do you tell them to change first?