Interview guides · Be Management Consulting
Be Management Consulting Software Engineer Interview Guide
Be Management Consulting Software Engineer interview guide with reported questions, test formats, a 7-day plan and answer approaches.
The 60-second brief
Be Management Consulting is a management consulting firm. Candidates describe the Software Engineer role as building the software behind its consulting operations, its client-facing tools and its internal platforms, working with project managers, data analysts and senior leaders. Reports of the role also mention CAD, the Teamcenter PLM tool and manufacturing settings as relevant experience, so the work appears to touch engineering-design material as well as conventional application code.
This guide is for software engineering candidates preparing for Be Management Consulting. It covers the five questions candidates report (an architecture walkthrough, scalability and maintainability, CAD and design-tool experience, debugging a system that misses its specification, and a heavy-lift system design), the test formats reported by team, and a plan for rehearsing them. No coding-problem list has been reported, so the guide concentrates on explaining your own work and on engineering reasoning.
Candidates report a phone screen, then in-depth interviews that often involve panels of managers and peers, with site tours for onsite visits. Some teams add written, CAD or aptitude tests, and reported timelines run from 4 to 8 weeks.
Focus areas
- Technical problem-solving (engineering reasoning)
- Mechanical design fundamentals (force/torque analysis)
- Safety engineering for actuators (fail-safe behavior)
Overview
The reported question list is short but unusual. Three questions are classic software-engineer material: walk through the architecture of a past project, explain how you keep code scalable and maintainable in production, and describe how you debug a system that is not meeting its specification. The other two sit nearer to engineering design: your experience with CAD or design-related tools, and the technical considerations in designing a system that transports or lifts heavy materials. Candidates also report topic areas such as force and torque analysis, fail-safe behaviour for actuators, and limit switches and actuation cutoffs.
The role description candidates give lists a few requirements: fluency in the languages of the team's stack, version control, and a working grasp of software development lifecycle methods. Experience with CAD or specialised design software, familiarity with Teamcenter or similar PLM tools, and exposure to manufacturing or consulting settings appear as nice-to-haves. No specific language, framework or cloud platform is reported, so prepare to discuss whichever you used most and be exact about it.
Preparation therefore splits into three streams. First, a portfolio of two or three projects you can explain down to individual decisions, because candidates describe bringing a portfolio or show-and-tell book as helpful. Second, short, structured answers for the debugging, maintainability and heavy-lift questions, where a repeatable method matters more than a memorised answer. Third, an honest inventory of your CAD, PLM and design-tool exposure, since written, CAD and logic-based aptitude tests are reported for some teams. The seven-day plan below gives each stream its own days and ends with a full spoken run-through.
Where to focus your preparation
The reported process is a single preparation stream rather than a fixed round-by-round sequence, so confirm the exact stages and any tests with your recruiter.
Preparation focus
Candidates report a phone screen first, followed by several in-depth interviews that often involve panels of managers and peers. Onsite visits are reported to include a site tour. Depending on the team, candidates also describe written tests, CAD assessments and logic-based aptitude tests, with the whole process running about 4 to 8 weeks. Approach it as three kinds of conversation: explaining your own projects in detail, reasoning aloud through an engineering or debugging scenario, and showing real, specific experience with design tools. Ask the recruiter which stages and tests apply to your team, then prepare the matching material rather than everything at once.
What to demonstrate
- How well you can explain a past project: architecture, languages, trade-offs between performance, cost and complexity
- Engineering reasoning on the topics candidates report: force and torque, fail-safe actuators, limit switches and cutoffs
- Hands-on familiarity with CAD or design tools, and basics such as drawing views, where a test is used
- Clarity when explaining technical choices to managers, peers and non-technical stakeholders
How to prepare
- Write a one-page summary for two or three projects: a component diagram, the languages used, two decisions with the alternatives you rejected, and one thing you would change
- Rehearse aloud the five reported questions: architecture walkthrough, scalability and maintainability, CAD experience, debugging to specification, and the heavy-lift system
- Refresh drawing views and basic engineering principles, and open a CAD tool from your resume to confirm you can still use it
- Assemble a portfolio or show-and-tell book of tangible work, and ask the recruiter which tests and site visits apply to your team
Where candidates lose points
Answering the architecture walkthrough by listing languages and frameworks, with no reasons
Prepare each project as components, data flow and two or three decisions, each with the alternative you rejected and the trade-off in performance, cost or complexity. Finish with one thing you would change today.
Claiming CAD, Teamcenter or other design-tool experience you cannot back up
List only tools you have used and state what you produced with each. For anything you have only seen, say that and describe how you would learn it. If a CAD assessment or drawing-views test appears, an exact inventory protects you.
Treating the heavy-lift design question as pure software, or as pure mechanics, and leaving out the safe state
Cover load and torque, the actuator and its limits, what the controller does when a sensor or limit switch fails, and the fail-safe default (for example, brakes engaging on loss of power). Then add monitoring, logging and testing.
Answering the debugging question with a guess at the cause rather than a method
Start from the specification and the measured gap, check that the measurement itself can be trusted, find what changed, then bisect the system and fix the cause rather than the symptom. Finish with a regression test and a monitor.
Giving generic scalability and maintainability answers ("clean code, tests, microservices") with no project evidence
Anchor each claim in your own system: the bottleneck you measured, the test coverage or review practice you used, how you paid down technical debt, and how the next engineer would find their way around.
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
- 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.
- 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.
- 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.
- 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?
Canonicalise a request body into a stable idempotency fingerprint
Medium · parsing · canonicalisation · hashing
idempotency_key.request_fingerprint is a SHA-256 over the method, path and canonicalised body, and a retry whose fingerprint differs must be rejected with 422 rather than served the stored response. Write the canonicaliser. Bodies are JSON up to 256 KB nested at most 32 levels; clients vary key order, whitespace and unicode escaping, and some send 64-bit ids as JSON numbers. Produce a deterministic byte string such that semantically identical bodies match and any semantic difference does not. State your complexity and name two normalisations you refuse to perform.
Approach
- Parse once into a tree, then re-serialise under fixed rules: object keys sorted, array order preserved, one escaping convention, no insignificant whitespace. Parsing is O(n) and sorting keys is O(k log k) per object, so O(n log n) overall with O(depth) stack, and the 32-level cap is enforced during parsing because hostile nesting is how a canonicaliser becomes a stack overflow.
- Sort keys by their UTF-8 bytes and say why the obvious implementation is wrong in some runtimes: a default string comparison that orders by UTF-16 code units places surrogate pairs, meaning code points from U+10000 up, below U+E000 to U+FFFF, which is not UTF-8 byte order, so two services written in different languages disagree on the same document.
- Do not re-encode numbers through a double. IEEE-754 binary64 represents integers exactly only up to 2^53, so normalising a 19-digit id through a float changes it, and 1 against 1.0 cannot be reconciled without deciding whether they are the same value. Preserve the literal token, and require ids as strings at the API boundary if you want them comparable.
- Reject duplicate keys rather than picking one. JSON permits them and parsers disagree, most keeping the last, so any choice you make ties the fingerprint to a parser detail that the code handling the request does not necessarily share.
Follow-up
- A client sends the same logical request with an extra field your API ignores. Same key, different fingerprint, so you return 422. Is that the right answer?
- Where does the fingerprint get computed relative to request decompression and the body-size limit?
Find overlapping job attempts and peak concurrency from lease records
Medium · sweep line · intervals · leases
A day of job_run history yields about 50,000,000 attempt records: (job_run_id, job_type, attempt, started_at, finished_at which is NULL when the worker died, lease_expires_at). Leases expire on a clock, so a job that outran its lease ran twice. Produce (a) every job_run_id whose attempts overlapped in wall-clock time and (b) the peak number of simultaneously running attempts per job_type with the minute it occurred. Target O(n log n). State how you treat a NULL finished_at and what clock skew does to your answer.
Approach
- Define the interval before sorting anything: an attempt occupies [started_at, COALESCE(finished_at, lease_expires_at)). finished_at is observed and lease_expires_at is only a promise, so every attempt without a finish contributes an estimate and the whole result is a lower bound on overlap rather than an exact count.
- For peak concurrency, sweep: emit 2n endpoints, sort by (timestamp, kind) with ends ordered before starts at equal timestamps, then walk the sequence maintaining a counter per job_type and record each type's maximum with its timestamp. O(n log n) dominated by the sort, O(n) space, or O(1) extra if the sort is external and the walk streams.
- For overlap detection, do not compare attempts pairwise. A single global sort by (job_run_id, started_at) gives both the grouping and the order; within a group, keep the maximum end seen so far and report an overlap exactly when the next start is less than that running maximum, which is one linear pass after the sort.
- Half-open intervals matter and are easy to get wrong: with closed intervals an attempt ending at the same millisecond another begins reads as concurrency two, and across 50,000,000 records that artefact swamps the real signal.
Follow-up
- A handler is not idempotent and you have found 400 overlapping jobs. Which of them actually caused damage, and what would you query to find out?
- Peak concurrency for one job_type is 4 against a configured cap of 4. Is the cap working, or is the data hiding attempts that never started?
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
- 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.
- 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.
- 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.
- 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?
Keep soft-deleted accounts from blocking re-registration
Easy · soft delete · unique constraints · engine differences
app_user holds user_id, tenant_id, email CITEXT, password_hash (NULL for SSO principals), email_verified_at, auth_version, status ('invited','active','suspended','deactivated'), created_at, updated_at, deleted_at. Two live accounts for one address inside a tenant must be impossible, but an address freed by a soft delete must be reusable, and the same tenant may delete and re-register it repeatedly. Write the uniqueness DDL for PostgreSQL 16, then the equivalent for MySQL 8 where partial indexes do not exist, and say what each permits once three deleted rows already hold that address.
Approach
- Start from what is actually unique: not (tenant_id, email), but (tenant_id, email) among live rows. PostgreSQL says that directly — CREATE UNIQUE INDEX app_user_live_email ON app_user (tenant_id, email) WHERE deleted_at IS NULL. A full constraint over the same two columns burns the address permanently the first time someone deletes an account.
- Keep case-insensitivity in the type or the index, never in the application: CITEXT as given, or UNIQUE (tenant_id, lower(email)) as an expression index where the extension is unavailable. A case-sensitive unique column is exactly how two accounts for one human appear.
- For MySQL 8 the predicate has to move inside the key: add a discriminator column that is a constant 0 while the row is live and is set to user_id on delete, with UNIQUE (tenant_id, email, deleted_marker). Live rows share the constant and still collide; deleted rows differ from each other and stop colliding.
- State the NULL variant and its dependency: leaving the marker NULL for deleted rows also works, because a unique index treats NULLs as distinct — true in MySQL, and true in PostgreSQL only under the default NULLS DISTINCT, which PostgreSQL 15 lets you reverse. Check the polarity against the three existing deleted rows: constant-on-live is what preserves the collision you want, and reversing it silently admits duplicate live accounts.
Follow-up
- A deleted account re-registers with the same address the next day. Do the old resource rows follow the new user_id, and how does the API keep the two principals apart?
- How do you honour an erasure request while resource_revision.actor_user_id still references this table?
Can you walk me through the architecture of a past project and the programming languages you utilized?
Medium · Technical and Domain Expertise
Approach
- Open with one sentence on the problem and its constraints (users, data volume, latency or cost limits), then walk the request path end to end: client, API layer, services, storage, background jobs and external integrations. A whiteboard box diagram keeps the walkthrough ordered.
- Name each language and framework next to the component it ran in and give the reason it was chosen (existing team skills, library support, performance, hosting), plus the alternative you rejected and why.
- Separate your own contribution from the team's: say which component you designed or owned, and use "I" only for that part.
- Pick one trade-off and quantify it, for example a cache that cut read latency at the cost of stale data for a stated window, or a relational database chosen over a document store because the data needed joins and transactions.
- Close with the main bottleneck you hit, how you measured it, how you resolved it, and what you would change in the architecture today.
Follow-up
- Why that language or database rather than the obvious alternative, and what would have made you choose differently?
- Which component would fail first if load grew tenfold, and how would you know?
- How did you handle technical debt or a system limitation you inherited on that project?
How do you ensure your code is scalable and maintainable in a production environment?
Medium · Technical and Domain Expertise
Approach
- Scalability: keep services stateless so instances can be added behind a load balancer, keep state in the database or a cache, and move slow work (reports, emails, file processing) to a queue with background workers.
- Find the real hot path before optimising: profile it, know the time complexity of the core loops, and remove N+1 query patterns by batching or joining; read the query plan (EXPLAIN ANALYZE in PostgreSQL) and add an index only where it removes a scan.
- Maintainability: small modules with clear interfaces, configuration outside the code, consistent naming and linting, and code review on every change so at least two people understand each part.
- Automated tests at unit and integration level run in CI on every merge, with a regression test added for each fixed bug; deploy in small increments behind feature flags so a change can be turned off without a rollback.
- Observability in production: structured logs, latency and error-rate metrics with alerts, and tracked technical debt items with a stated cost, so refactoring is scheduled rather than deferred indefinitely.
Follow-up
- Describe an N+1 query or similar performance problem you found in production. How did you detect it and what did the fix change?
- How do you decide whether to refactor a messy module now or ship the feature first?
- How would you roll out a risky change to a system that many users depend on?
Explain the technical considerations you would make when designing a system to transport or lift heavy materia
Medium · Technical and Domain Expertise
Explain the technical considerations you would make when designing a system to transport or lift heavy materials.
Approach
- Clarify requirements first: maximum load mass and centre of gravity, travel path, distance and speed, duty cycle, environment, and whether people work near the load. Size from the worst case: static force W = m·g, and F = m(g + a) while accelerating upward, then apply a design factor between working load and the rated capacity of hooks, slings, cables and structure.
- Work the force and torque chain: for a hoist drum of radius r, load torque T = F·r; motor torque is about T/(N·η) for gear ratio N and efficiency η; power P = F·v. For a cart or conveyor add rolling resistance and the incline component m·g·sinθ.
- Check stability and structure: the restoring moment about the tipping edge must exceed the overturning moment, including a swinging or offset load; check beam deflection, and fatigue because the load cycles repeatedly.
- Design for fail-safe behaviour: a spring-applied, power-released brake so a power loss holds the load; limit switches at both travel ends that cut actuation, plus an independent overtravel limit wired into the power circuit rather than only into software; an emergency stop; load sensing that blocks lifts above rated capacity.
- For the control software: interlocks in the controller, normally-closed sensor contacts so a broken wire reads as tripped, a watchdog that stops motion on a control fault, and acceleration ramps to limit dynamic load and swing. Verify with a proof-load test and by injecting faults such as disconnecting a sensor.
Follow-up
- Power fails halfway through a lift. Walk through what happens to the load in your design.
- Roughly what drum torque does a 500 kg load on a 0.1 m drum radius need, before gearing? (About 500 x 9.81 x 0.1, so roughly 490 N·m.)
- Why should a safety limit switch use normally-closed contacts, and why should it not rely only on software?
How do you approach debugging a system that is not performing to specifications?
Medium · Technical and Domain Expertise
Approach
- Turn "not performing to spec" into a measurable gap: which metric (throughput, p50 or p99 latency, error rate, accuracy), under what load and inputs, against what target. Then reproduce it, ideally with a repeatable test or load script.
- Ask what changed and when: deploys, configuration, dependency versions, data volume, traffic shape, infrastructure. If a code change is suspected, bisect the commits (git bisect) between the last good and first bad version.
- Measure instead of guessing: check resource saturation (CPU, memory, disk and network I/O, connection or thread pools), then use a profiler, distributed traces or slow-query logs and query plans to find where the time is actually spent.
- Change one variable at a time, and re-run the same measurement after each change so the improvement is attributable; a fix that is not measured against the original spec is not finished.
- Close the loop: add a regression test or benchmark and an alert on the metric, and write a short root-cause note separating the trigger (for example, a traffic spike) from the underlying cause (for example, a missing index).
Follow-up
- The p50 latency is fine but the p99 is far outside spec. What does that pattern suggest, and where would you look first?
- You cannot reproduce the problem locally. What would you do next?
- How would you tell a real cause from a change that merely happened at the same time?
Suggested practice checklist
The plan follows the three streams in the reported question list: project storytelling, engineering and debugging reasoning, and design-tool experience. Each day produces something you can bring to the interview or say aloud.
Day 1 — Confirm the format and inventory your experience
- Ask the recruiter which stages apply to your team and whether you should expect a written, CAD or logic-based aptitude test, and whether an onsite visit is planned.
- List every project, language and design tool on your resume, and for each write the technical decisions you made and one measurable result.
Deliverable: A recruiter reply about the stages and tests, plus a one-page project and tool inventory.
Day 2 — Architecture walkthrough of a past project
- Pick your strongest project and write a walkthrough: purpose, components, data flow, languages, and two decisions with the alternatives you rejected.
- Redraw the architecture as a one-page diagram and say the walkthrough aloud, cutting anything that does not explain a decision.
Deliverable: A one-page diagram and a spoken walkthrough of that project, plus a list of the questions it invites.
Day 3 — Scalable and maintainable in production
- Write an evidence list from your own work: a bottleneck you measured and fixed, how you structured tests and reviews, and a piece of technical debt you handled.
- Prepare a two-minute answer that moves from how you design for growth to how you keep the codebase readable, with one example each.
Deliverable: A two-minute spoken answer backed by three concrete examples from your projects.
Day 4 — Debugging a system that misses its specification
- Write your debugging sequence: restate the spec and the measured gap, validate the measurement, find what changed, bisect, confirm the cause, fix, add a regression test.
- Apply it to one real incident from your history and to one hypothetical, such as an actuator that overshoots its target position.
Deliverable: A one-page debugging checklist and two worked cases, one real and one hypothetical.
Day 5 — Heavy-lift system design and engineering basics
- Work a force and torque example: for a 500 kg load, the weight force is about 4,905 N, so a drum of 0.1 m radius needs roughly 490 N·m before efficiency losses and a safety factor.
- Write the safety layer for the same system: limit switches, an actuation cutoff, brake behaviour on power loss, and what the controller does on a sensor fault.
- Refresh drawing views and basic engineering principles, since written and CAD tests are reported for some teams.
Deliverable: A worked load calculation, a safety and fail-safe design sheet, and a drawing-views refresher note.
Day 6 — Design-tool experience and behavioral stories
- Write the CAD or design-tool answer in STAR form, naming tools, artefacts produced and one verifiable result, and add an honest line about anything you have not used.
- Prepare two stories: your most challenging technical project and how you resolved its main bottleneck, and a time you explained a technical trade-off to a non-technical stakeholder.
Deliverable: Three written STAR stories and a portfolio set containing at least one tangible design or project artefact.
Day 7 — Full spoken dry run
- Run all five reported questions aloud in one sitting with your portfolio in hand, and record yourself.
- Write the questions you will ask at the end, about the team's current challenges, how it is organised and how the role may change over two years.
Deliverable: A recorded run-through with a list of weak spots to fix, and your questions for the interviewers.
Project stories and design-tool experience
Behavioral conversations for this role are reported as centred on your past projects and your fit with a collaborative, professional team. The reported scenarios ask for your most challenging technical project, how you handled technical debt, and how you ensured a design met safety and efficiency requirements in a manufacturing setting. Prepare stories where you made the decision, can name the trade-off, and can show a result. Keep a portfolio of tangible work to support them, and say what you do not know instead of bluffing.
- Explain the most challenging technical project you have worked on and how you resolved the primary bottleneck.
- How do you ensure your design meets the safety and efficiency requirements of a manufacturing environment?
- Describe a time you inherited technical debt or a system limitation and how you decided what to fix and what to live with.
- Tell me about a time you explained a technical trade-off to a manager or non-technical stakeholder and how you knew they understood it.
What is your experience with CAD or design-related software tools?
Medium · Technical and Domain Expertise
Approach
- Answer with the tools you have actually used, by name and version if you can: for example a CAD package, a diagramming or UI design tool, or a PLM system such as Teamcenter. Overstating is the main way this answer fails, because a CAD assessment or a request to describe drawing views will expose it quickly.
- Use a short STAR shape. Situation and task in two sentences (what was being designed and for whom), then spend most of the time on your actions: the model, drawing or design artefact you produced, how you handled revisions and file versions, and how it fed the software or the build.
- Show the link between the design artefact and the software. Examples: reading a drawing to set requirements or tolerances for code, generating or parsing design data with a script, or keeping design files under revision control the way you keep source code.
- Close with a result you can verify, such as fewer rework cycles, a faster hand-off or a defect caught before build. If your CAD exposure is thin, say so plainly, name the closest tool you have used, and describe how you would get productive on the team's tool.
- The mistake that sinks it is a vague list of software names with no artefact, decision or outcome attached. Bring one drawing, model or screenshot to the portfolio so the story is backed by something concrete.
Follow-up
- How did you manage revisions and sharing of design files across a team, and what went wrong when you did not?
- Which part of that tool did you find hardest, and how did you get past it?
- How would you get up to speed on a CAD or PLM tool you have never used?
Tell callers you do not own that their integration breaks
Medium · deprecation · compatibility · stakeholders
A field in a write endpoint's response must change shape. You own the endpoint; you do not own the four internal callers or the outbound webhook consumers who read it. Describe a deprecation you were responsible for: what you shipped first, how you established who was actually reading the field, the window you gave and what set its length, what you did about the consumer who never moved, and how you decided removal was safe. Name the signal you used, not the announcement you sent.
Approach
- Establish the reader set empirically rather than from a wiki of owners: per-field usage counters keyed by principal, or access logs attributed to a consumer. State the blind spot of whichever you pick, since a consumer that reads the field only on a monthly job will not appear in a week of logs.
- Ship additive first. Populate the new field alongside the old one so no reader is forced to move, which is also what keeps a rolling deploy safe, because old and new instances answer the same requests at the same time and a rollback must still find the old shape present.
- Set the window from the slowest legitimate consumer's release cadence, not from your calendar, and decide separately what to do for a consumer with no release process at all, such as an external webhook endpoint you can only email.
- Convert silence into evidence before you rely on it: a short, low-traffic removal window that makes a still-dependent consumer fail visibly and loudly while you are watching, rather than at three in the morning after you have moved on.
Follow-up
- How would you detect a consumer that reads the field only during a monthly export?
- One caller refuses to move and has a commercial relationship behind it. What changes in your plan and what does not?
Estimate work you have never done and defend the range
Hard · estimation · backfills · expand-contract
You are asked to estimate a change you have never attempted: add a column to a 100-million-row table, populate it, move reads across, and drop the old shape. Give a range with the assumptions that generate it, including batch size, the signal your backfill throttles on, and wall-clock hours, and name the three unknowns that would move the number most. Then describe a real estimate you gave under comparable ignorance: how you expressed its uncertainty, what you committed to, and how wrong you turned out to be.
Approach
- Decompose into independently deployable steps before estimating anything: add the column nullable, write both shapes, backfill in batches, verify, move reads, stop writing the old shape, drop it. That is four deploys spread over days, and the calendar estimate is dominated by them rather than by the loop's runtime.
- Do the arithmetic aloud for the part that has arithmetic in it: batch size times number of batches times per-batch duration, at a write rate the primary can absorb alongside roughly 1.2k writes per second of production traffic. The loop is throttled by replication lag and lock waits, not by how fast it can issue statements.
- Price the schema step by its lock rather than its statement duration. In PostgreSQL an ALTER TABLE taking ACCESS EXCLUSIVE waits for every open transaction on that table while later queries queue behind it, so a millisecond change issued during a thirty-second analytics query stalls that table for thirty seconds. Adding a nullable column with a non-volatile default avoids a rewrite from version 11; a new index wants CREATE INDEX CONCURRENTLY, which cannot run inside a transaction block and leaves an invalid index behind if it fails.
- Express the answer as a range whose endpoints each trace to a stated assumption, then name the cheapest experiment that collapses it, which is almost always running one real batch against the real table and multiplying.
Follow-up
- How do you verify the backfill genuinely finished, given rows written by production traffic while it ran?
- Where does the backfill resume from after a worker is killed mid-batch, and what makes that resume point trustworthy?