Interview guides · adorsys
adorsys Software Engineer Interview Guide
adorsys Software Engineer interview guide: 4 reported rounds, architecture, cloud and API design questions, behavioral stories and a 7-day prep plan.
The 60-second brief
Candidates describe adorsys engineers as working on client projects in three areas: cloud architecture, API enablement and fullstack development. Role titles candidates mention include Senior Fullstack-Entwickler, Knowledge-Engineer, Cloud Architect, Senior Lead Developer and Software-Architect. Day-to-day work is described as turning client requirements into maintainable code and connecting legacy business processes to modern interfaces through APIs, with code review and mentoring also mentioned.
This guide is for candidates applying as a Software Engineer at adorsys, from fullstack developer through architect-level profiles. It covers the four reported rounds, the architecture, cloud, API and fullstack topics candidates describe, the reported technical and behavioral questions with answer structures for the behavioral ones, and a 7-day plan. Candidates also mention that German and English communication is listed among the must-have skills, so rehearse in both languages if your application allows it.
Candidates report four rounds spread over roughly 3-5 weeks: Initial Screening, Technical Assessment, Cultural Alignment and Final Decision. Candidates report little about the format of each round, so the plan prepares you across topics rather than per round.
Focus areas
- Software Engineering (General)
- System Architecture
- Cloud Architecture
Overview
The reported questions fall into three groups. The technical group asks about choosing between technologies, availability and security in cloud-native applications, monolith versus microservices trade-offs and debugging a critical production issue in a distributed system. The design group covers a scalable API platform, migrating legacy systems to the cloud, consistency and performance in a distributed database, and an architecture you are proud of. The behavioral group covers stakeholder disagreements, mentoring, speed versus technical debt and pivoting on changing requirements.
Candidates are advised to explain their reasoning and the trade-offs rather than recite a single correct answer. So for every design topic, prepare the options, the cost of each, and the condition under which you would switch. Reported example scenarios include absorbing a sudden traffic spike on an API service, migrating data with zero downtime, tracing a request from the frontend through the backend to the database, and handling environment-specific configuration in a cloud setup.
The stack candidates mention is broad rather than deep in one tool: modern backend and frontend frameworks, Docker and Kubernetes, CI/CD pipelines, API design and integration patterns, and security built in at the architecture level. AWS, Azure or GCP knowledge and security-focused experience appear as nice-to-have. Pick two or three real projects from your own history and be ready to discuss what each tool did badly and how you worked around it.
Consulting is a theme in how candidates describe the role: advising clients, explaining technical choices to non-technical stakeholders, and acting as a bridge between legacy processes and new interfaces. That shapes preparation. Practise drawing a design on a whiteboard while narrating it in plain language, and write behavioral stories where your own decision, the alternatives and the measurable outcome are all visible.
The adorsys interview process
Candidates report four rounds over about 3-5 weeks. The descriptions below reflect what they say about each stage, and candidates report little about the format of each round.
Initial Screening
Candidates report initial screenings to assess candidate fit. No format or question list is reported for this stage, so use it to present your background and the role title you are aiming for. German and English communication is listed among the must-have skills, so prepare to talk about your work in both languages. Keep your account of each project concrete: your role, the stack, one trade-off you made and the outcome.
What to demonstrate
- Candidate fit, which is what initial screenings are reported to assess: how your background lines up with the Software Engineer role
- The must-have skills candidates see listed: backend and frontend stacks, cloud and distributed systems, API design, German and English
How to prepare
- Write a two-minute walkthrough of your career that names the stack of each project and one decision you owned
- Choose which role title you are aiming for (fullstack, cloud, architect, lead) and align your examples with it
- Prepare a short answer on why you want consulting-style client work, based on a project where you advised rather than only built
- Practise saying your project examples aloud in German and in English
Technical Assessment
Candidates report a technical stage with scenario-based questions. They list architectural design (scalability patterns, security by design, data consistency) and fullstack and cloud proficiency (modern frameworks, Docker and Kubernetes, CI/CD) as the evaluation areas, and they are advised to be ready to draw architecture on a whiteboard, in person or virtually. Prepare each design topic as options plus trade-offs, and practise the reported scenarios: a traffic spike on an API service, zero-downtime data migration, a request's path from frontend to database, and environment-specific configuration.
What to demonstrate
- Architectural design as candidates report it: scalability patterns, security by design, data consistency in distributed systems
- Fullstack and cloud proficiency: modern frameworks, containers and orchestration, CI/CD pipelines
- Candidates are advised to discuss the limitations of their tools and how they mitigate them in production
- Candidates are advised to be ready to draw their architecture ideas
How to prepare
- Rehearse the monolith versus microservices trade-offs for a high-traffic system and name the conditions where you would pick each
- Sketch an API platform for millions of requests per day: gateway, authentication, rate limiting, caching, horizontal scaling and a queue for spikes
- Write an expand-and-contract plan for a zero-downtime data migration, including how you would roll back
- Walk through one request from browser to database and say where configuration differs per environment
Cultural Alignment
Candidates report that this stage emphasizes cultural alignment and professional maturity. Behavioral and leadership questions are reported for the loop: technology choices, stakeholder disagreements, mentoring, balancing delivery against technical debt, and changing requirements. Explaining technical matters to non-technical people is a recurring theme in how candidates describe the consulting side of the role, so prepare stories where you did that.
What to demonstrate
- Cultural alignment and professional maturity, as candidates report for this stage
- Behavioral questions candidates report on stakeholder disagreement, mentoring, delivery versus technical debt and changing requirements
How to prepare
- Write five stories, one each for technology choice, stakeholder disagreement, mentoring, delivery versus debt and a pivot, each with a measurable result
- Rewrite every story in the first person singular, with your own action in the foreground
- Prepare one example of explaining a technical constraint to a non-technical person and what changed because of it
- Prepare two or three questions about client projects and how engineers grow technically
Final Decision
Candidates report that the process concludes with a final decision based on all earlier assessments. Little else is reported about its format, so prepare for a conversation that may revisit anything from the earlier rounds, and be able to restate your strongest trade-off example briefly.
What to demonstrate
- A decision based on all earlier assessments
- Your overall profile across the technical and behavioral stages that came before
How to prepare
- Review the answers you gave in earlier rounds and prepare to extend or correct any of them
- Prepare a short closing summary: the role you are aiming for, two projects that show it and why consulting-style work suits you
- Keep your questions about the team, projects and growth ready for this stage
- Rehearse the architecture you are proud of until you can give it in three minutes with its constraints and trade-offs
Where candidates lose points
Naming a tool as the answer without its limits, for example saying Kubernetes or microservices solves scaling
For each technology you mention, state its cost and a failure mode it brings, and the production measure you used to contain it. Candidates report being asked about the limitations of their tools, not only the benefits.
Answering the monolith versus microservices or API platform design question with a pattern list instead of a decision
Open with the load, the team size and the failure expectations, give two architectures, then say which you choose and the condition that would flip it. Keep the whiteboard diagram to a few labelled components and narrate each.
Treating the zero-downtime migration or the legacy-to-cloud question as a single cutover weekend
Describe a phased path: run both systems, expand-and-contract schema changes, copy data and verify it, shift traffic gradually and keep a tested rollback at each step.
Behavioral stories told in the first person plural, where your own decision and result cannot be found
Rewrite each story so that the sentences about what you decided and did come first, with a measurable result at the end. Cut the context to two sentences.
Explaining everything at one technical level, so a stakeholder disagreement or business-impact answer sounds like jargon
Practise giving the same design decision in two versions: one for an engineer and one for a client contact, using cost, risk and delivery date, and do it in both German and English if you can.
Questions & practice
Merge partitioned event streams into one ordered feed with bounded lateness
Hard · k-way merge · watermarks · out-of-order streams
The read-model service consumes 64 log partitions carrying about 4,000 events per second in total. Each partition is ordered within itself, but partitions drift by up to 30 seconds, and the activity feed must present a tenant's events in occurred_at order. Produce the merge. State its complexity, the buffer it requires in events and in bytes, what happens when one partition is idle, and what you do with an event that arrives after you have already emitted its position. Payloads average 1 KB.
Approach
- Merge with a min-heap over the 64 partition heads keyed on (occurred_at, event_id): O(log P) per event and O(n log P) overall. The tie-break on event_id is what makes the output deterministic when two partitions carry the same millisecond, which matters because the feed is paginated and a non-deterministic order reorders pages under the reader.
- Emitting the heap head is only correct once every partition has produced everything up to that timestamp, so the emit condition is a watermark: the minimum across partitions of the highest occurred_at seen, less the allowed lateness. Events are held until the watermark passes them, which is what turns individually ordered streams into a jointly ordered one.
- Size the buffer from the lateness rather than guessing: 4,000 events per second times 30 seconds is 120,000 buffered events, and at 1 KB each about 120 MB of heap. That number is the real price of the ordering guarantee and belongs in front of whoever asked for it.
- Handle the idle partition explicitly, because it fails the feed rather than corrupting it: a partition with no traffic never advances its own maximum, so the watermark freezes and output stops entirely. Either every partition emits a periodic idle marker carrying the broker's current time, or the watermark falls back to wall clock for a partition silent beyond a threshold.
Follow-up
- The lateness budget is raised to five minutes. What is the new buffer, and what besides memory changes?
- The consumer restarts. Where does it resume from, and what does the feed look like for the first 30 seconds?
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
- 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.
- 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.
- 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.
- 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?
Diff a projection against the primary without per-row point reads
Hard · reconciliation · range hashing · throttling
The listing projection has drifted and some rows show a stale version. The primary holds 40,000,000 resource rows across 12,000 tenants while serving 1,200 writes and 14,000 reads per second. The obvious repair, reading each resource row and comparing its version against the projection, is correct and would eventually finish. Explain precisely why it is unacceptable here, then give a diff that finds the differing rows, state its complexity, and make it safe to run against a live primary. Replication lag is usually under 100 ms and is not bounded.
Approach
- Quantify the naive cost rather than calling it slow: 40,000,000 point reads at even 0.5 ms each is over five hours serialised, and the only lever is concurrency, which is exactly what you cannot spend. The primary's pool is sized for the write path, and 40,000,000 random reads evict the buffer cache that sustains the 85 percent cache hit rate, so the audit degrades the system it is auditing.
- Replace random access with one ordered pass per side. Both sides can be read in (tenant_id, resource_id) order, which is a sequential scan on each and a merge join in O(n) time and O(1) memory. For a dense diff that is the whole answer, and it reads the primary once instead of 40,000,000 times.
- For the expected sparse case, compare range hashes instead of rows: partition the key space, compute per range an order-independent aggregate over hash(resource_id, version), compare aggregates, and descend only into ranges that differ. With d differing rows and branching factor B, at most d ranges mismatch per level, so the drill-down examines O(d log_B(n/d)) ranges and reads full rows only in mismatching leaves.
- Aggregate with a sum modulo 2^64 or a multiset hash, never XOR. XOR is order-independent but self-cancelling, so two rows wrong in the same way, or a row duplicated on one side, leave the range aggregate matching and the range is declared clean.
Follow-up
- The diff reports 900 stale rows. How do you decide between patching those rows and rebuilding the projection from resource_revision?
- Same job, but the projection lives in a search index that cannot be scanned in key order. What changes?
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?
Write the update path that detects a concurrent edit
Medium · optimistic concurrency · transactional outbox · audit history
resource carries version INT NOT NULL DEFAULT 1. resource_revision holds revision_id, resource_id, version, actor_user_id, change_kind, patch JSONB, request_id, created_at with UNIQUE (resource_id, version). outbox_event holds aggregate_type, aggregate_id, aggregate_version, event_type, payload, status. A PUT carries the version the client read. Write the exact statements for the single transaction that applies the edit, records the revision and enqueues 'resource.updated', and give the handler's branch on zero affected rows. Then say what PostgreSQL 16 does under READ COMMITTED when two of these updates hit one row at once.
Approach
- One transaction, three writes, no network call inside it: UPDATE resource SET title = $3, version = version + 1, updated_at = now() WHERE resource_id = $1 AND tenant_id = $4 AND version = $2; then INSERT the resource_revision row at version $2 + 1; then INSERT the outbox_event row at the same aggregate_version. The event goes to a table rather than a broker because no transaction spans both.
- Branch on the affected-row count before doing anything else. Zero has three causes — stale version, wrong tenant, row gone — so re-read once and map to 409 carrying the current version, or 404 for an id outside the caller's tenant, which also stops the endpoint confirming that another tenant's id exists.
- State the engine behaviour instead of assuming it. Under READ COMMITTED the second UPDATE blocks on the row lock, and when the first commits PostgreSQL re-evaluates the WHERE clause against the newly committed row, so the version predicate now fails and the statement reports zero rows. Under REPEATABLE READ the identical collision raises SQLSTATE 40001 instead, so the handler must fold both shapes into one conflict response.
- Keep UNIQUE (resource_id, version) even though the predicate already serialises writers. It is what makes a lost update unwritable if any other path ever reaches the revision table, and it converts a logic bug into 23505 rather than into a silently missing history row.
Follow-up
- A client sends the version it read ten minutes ago and the resource has moved three versions. What is in your 409 so it can resolve the conflict without a full re-fetch?
- Two editors, two disjoint fields, no overlap. Does your answer still refuse the second write, and should it?
How do you ensure high availability and security when designing cloud-native applications?
Medium · Technical & Domain Expertise
Approach
- Set the availability target first (an SLO such as 99.9% monthly, roughly 43 minutes of downtime) plus RTO and RPO. Those numbers decide whether multi-AZ is enough or multi-region is worth its cost and consistency problems.
- Availability: run stateless replicas spread across zones behind a load balancer. In Kubernetes, use readiness probes so traffic only reaches ready pods, liveness probes for stuck processes, PodDisruptionBudgets and topology spread constraints. Use a managed database with a synchronous standby in another zone.
- Failure handling between services: a timeout on every call, retries with exponential backoff and jitter only on idempotent operations, circuit breakers, and bulkheads (separate connection pools) so one slow dependency cannot exhaust the threads. Degrade gracefully, for example by serving cached data.
- Security by layer: least-privilege IAM per workload, secrets in a secrets manager instead of images or the repo, TLS on every hop (mTLS between services if a mesh is in place), default-deny network policies, and databases in private subnets with no public endpoint.
- Supply chain and runtime: scan dependencies and images in CI, run containers as non-root with read-only root filesystems, sign images and admit only signed ones. Close with how you test it: failover drills and restoring a backup before you actually need it.
Follow-up
- What does moving from multi-AZ to multi-region cost you in latency, data consistency and money?
- A credential leaks into a public repository. How do you rotate it without downtime?
- How do you prove the failover works before a real outage forces the test?
Explain the trade-offs between monolithic and microservices architectures in a high-traffic environment.
Medium · Technical & Domain Expertise
Approach
- Start from what is driving the decision: load profile, team count, release cadence. A stateless monolith also scales horizontally behind a load balancer. High traffic alone does not justify splitting it. Uneven load across components, or teams blocking each other's releases, does.
- Microservices benefits: you scale only the hot path, failures stay isolated per service, and teams deploy independently. Costs: every in-process call becomes a network hop with latency, serialization and partial failure, and you now need distributed tracing, contract versioning and a pipeline per service.
- Data is the hardest part. A monolith gets ACID transactions across modules from one database. Database-per-service means cross-service workflows rely on sagas with compensating actions and a transactional outbox for reliable events, so you accept eventual consistency.
- Name the anti-patterns. A distributed monolith (services sharing one schema or always deployed together) has the costs of both styles. Chatty synchronous call chains multiply tail latency, and an outage in one service cascades without timeouts and circuit breakers.
- Give a middle path. Start with a modular monolith that enforces module boundaries. Extract a service with the strangler fig pattern only when one component needs its own scaling, its own release cadence or stronger isolation, and measure before and after.
Follow-up
- Which component of a system you know would you extract first, and what metric would justify it?
- How do you keep an order and its payment consistent across two services without a distributed transaction?
- How do you version a service contract so consumers can upgrade on their own schedule?
How would you design a scalable API platform to handle millions of requests per day?
Medium · Architectural & System Design
Approach
- Estimate the load first: 10 million requests a day averages about 116 per second (10,000,000 / 86,400), so plan for a peak several times that. This tells you the core challenge is uneven traffic and per-client fairness, not raw throughput. Ask for the read/write ratio and the latency target.
- Request path: a CDN for cacheable GETs, an API gateway that validates OAuth2/JWT tokens and request schemas, stateless services that autoscale behind a load balancer, a cache-aside Redis layer, the database with read replicas, and a queue with async workers for slow work. Rate limit with a token bucket per API key kept in Redis so all gateway instances share the count, return 429 with a Retry-After header, and add quotas per consumer tier so one heavy client cannot starve the others.
- Tie it to API enablement, where a modern API sits in front of legacy business systems. Protect a slow or fragile legacy backend behind the platform with an adapter or anti-corruption layer that translates between the new API model and the legacy one, a bulkhead, a timeout, a cache in front of it, and a concurrency limit toward the backend that is separate from the per-client rate limits.
- Contract design: an OpenAPI spec as the source of truth, cursor-based pagination instead of OFFSET (OFFSET scans every skipped row and shifts results under concurrent inserts), idempotency keys on POST so retries do not create duplicates, one error format (RFC 9457 problem details), and an explicit versioning policy.
- Operations: metrics per consumer and per endpoint, SLOs on p99 latency and error rate, load tests at peak, and the failure mode for each dependency (for example, serve stale cache if the database read path degrades).
Follow-up
- How do you roll out a breaking v2 change while v1 clients keep working?
- One client suddenly sends half of all traffic. What protects everyone else, and what do you tell that client?
- The legacy system behind the API can only handle a fraction of the platform's peak. What do you put between them, and what do callers see when it is saturated?
What considerations do you prioritize when migrating legacy systems to a cloud-based infrastructure?
Medium · Architectural & System Design
Approach
- Inventory before you choose a path: every application, its dependencies (shared databases, file shares, batch jobs, hard-coded IPs), data volume, and compliance or data-residency limits. Then pick a strategy per workload: rehost, replatform, refactor, or retire. Not everything needs rewriting.
- Move incrementally with the strangler fig pattern. Put a routing facade in front of the legacy system, move one capability at a time to the cloud service, and keep the legacy system as the source of truth for anything not yet moved, so each step can be rolled back.
- Data migration: a bulk copy, then change data capture from the source database log to keep the target in sync. Verify with row counts and checksums, then cut over in a short write freeze or by flipping the source of truth. Avoid application dual writes, because a failure between the two writes leaves them diverged.
- Avoid downtime with expand-and-contract schema changes (add new columns or tables, backfill, switch reads, then remove the old ones), plus blue-green or canary cutover behind feature flags. Write down the rollback trigger and its steps before cutover day.
- Cover the non-functional side: network connectivity to what stays on-premises (VPN or private link, and the added latency on chatty calls), IAM and secrets, a cost model including data egress, and a baseline of current latency and error rates so you can show the migration did not make things worse.
Follow-up
- How would you migrate the main database with no downtime, and when exactly does the source of truth change?
- A nightly batch job reads files from a shared network drive on-premises. How do you move it?
- How do you decide whether a workload is worth refactoring or should just be rehosted?
How do you maintain consistency and performance in a distributed database environment?
Medium · Architectural & System Design
Approach
- Set the consistency requirement per operation, not per system. Balances, inventory and uniqueness checks need strong consistency. Feeds, counters and analytics can tolerate staleness. Frame the trade-off with PACELC: during a partition you choose consistency or availability, and otherwise latency or consistency.
- Replication: with leader-follower and asynchronous replicas, reads from a replica can be stale. Give read-your-writes by routing a user's reads to the leader for a short window after a write, or by having the replica wait until it has applied the write position the client saw. In quorum systems, W + R > N makes every read quorum overlap the most recent write quorum.
- Partitioning: choose a shard key that keeps common transactions on one shard (for example tenant ID in a multi-tenant system) and avoids hotspots from monotonically increasing keys. Cross-shard transactions need two-phase commit, which blocks if the coordinator fails, or a saga with compensations.
- Concurrent writes: optimistic locking with a version column (UPDATE ... WHERE id = ? AND version = ?; zero affected rows means someone else wrote first, so re-read and retry), or SELECT ... FOR UPDATE where contention is high. Know which anomalies each isolation level allows, such as lost updates and write skew below serializable.
- Performance: indexes that match the query patterns, connection pooling, batched writes, and cache-aside with TTLs plus explicit invalidation on writes. Remember that a cache is one more replica that can be stale, so keep strongly consistent reads out of it.
Follow-up
- How would you guarantee a user sees their own update right after saving when reads go to async replicas?
- Which shard key would you choose for a multi-tenant system with one tenant far larger than the rest?
- What actually goes wrong with two-phase commit when the coordinator crashes mid-protocol?
Describe an architecture you designed that you are particularly proud of; what were the primary constraints?
Medium · Architectural & System Design
Approach
- Pick a system where you made or owned the architectural decisions, and open with the constraints as numbers: traffic or data volume, latency or availability target, budget, team size, deadline, and any regulatory or security requirement.
- Draw it as you talk: the main components, where state lives, and how one request or event flows end to end. Keep it to what a whiteboard can hold, and use I for your own decisions rather than describing the team's work as yours.
- Walk through two or three key decisions, each with the alternative you rejected and why, such as a queue against a synchronous call, a managed database against self-hosting, or one service against several. Tie each decision back to a stated constraint.
- Show the outcome with evidence: measured latency, cost, incident counts or delivery speed before and after. Then name one thing that did not work as planned and how you corrected it.
- The answer falls apart when it lists technologies with no constraint behind them, or when it cannot say what would break first under heavier load. Prepare both before the interview.
Follow-up
- What breaks first if load grows tenfold, and what would you change?
- Knowing what you know now, which decision would you reverse?
- How did you validate the design before committing to it: a spike, a load test or a prototype?
How do you approach debugging a critical production issue in a distributed system?
Medium · Technical & Domain Expertise
Approach
- Mitigate before you diagnose. Size the blast radius from SLO dashboards (error rate, p99 latency, affected endpoints and tenants). If a recent deploy, config change or feature flag lines up with the start, roll it back or switch it off, then open an incident channel and post regular status updates.
- Narrow the scope by comparing dimensions: one region or all, one version or all, one instance, one client, one dependency. An issue confined to one pod points at local state or a bad node. One that appears everywhere at once points at a shared dependency or a config push.
- Follow a failing request with distributed traces and a correlation ID through the logs to find the span where latency or errors start. Check that the telemetry is trustworthy first, for example that sampling has not dropped the failures you are looking for.
- Check the common distributed causes: exhausted connection or thread pools, retry storms amplifying load on an already slow dependency, expired certificates, DNS changes, clock skew affecting token validation, and queue backlogs. Test one hypothesis at a time and change one thing at a time.
- Separate the trigger from the root cause, reproduce it in staging with the captured failing request, and write a blameless postmortem with concrete actions: a regression test, an alert on the earliest warning signal, a timeout or limit that would have contained it.
Follow-up
- Error rates are flat but p99 latency has doubled. Where do you look first, and what does each check rule out?
- How do you debug a failure that affects about 1% of requests and never reproduces locally?
- How do you add diagnostic logging during an incident without overloading the logging pipeline?
Suggested practice checklist
The seven days start from the reported evaluation areas (architecture, fullstack and cloud) and the three reported question groups, then end with behavioral rehearsal and a mixed run.
Day 1 — Map the loop and choose your stories
- Write the four reported rounds in order, and next to each the topics candidates report: architectural design, fullstack and cloud proficiency, cultural alignment.
- List the reported example scenarios (traffic spike on an API service, zero-downtime migration, request lifecycle, environment-specific configuration) and mark which you could not explain today.
- Pick two or three past projects that show architecture decisions, and write the constraints, the stack and the outcome for each.
Deliverable: A one-page loop map, a list of the scenarios you are weakest on and a summary line for each chosen project.
Day 2 — Monolith vs microservices and the API platform
- Write a table comparing a monolith and microservices for a high-traffic system: deployment, data ownership, failure isolation, team size, latency and operating cost.
- On paper, design an API platform for millions of requests per day, showing gateway, authentication, rate limiting, caching, a queue for spikes and horizontal scaling, and say what breaks first at ten times the load. Add the protection for a slow legacy backend behind it.
Deliverable: One trade-off table, one labelled API platform diagram with a ten-times-load note, and one solved circuit-decision exercise.
Day 3 — Cloud-native availability, security and the request path
- Write a checklist for availability (replicas across zones, health checks, autoscaling, graceful degradation) and for security (least privilege, secrets handling, transport encryption, input validation, dependency scanning).
- Trace one request from browser to database and note where authentication, caching and configuration apply, with environment-specific values kept out of the image. Include the frontend: where the token is stored in the browser, CORS, how the frontend gets its environment-specific API base URL at runtime rather than build time, and how frontend and backend releases stay compatible.
- Describe a CI/CD pipeline for a containerised service: build, test, scan, deploy to a staging environment, promote and roll back.
Deliverable: An availability and security checklist, a request-path diagram covering frontend and backend, and a pipeline outline you can explain in three minutes.
Day 4 — Distributed data and legacy migration
- Write how you would keep a distributed database consistent and fast: choose a partition key, decide where stale reads are acceptable, and explain replication and idempotent writes.
- Write an expand-and-contract migration plan for moving a legacy system to the cloud with zero downtime, including data verification and rollback.
Deliverable: A consistency decision note, a phased migration plan with rollback points and two solved database practice exercises.
Day 5 — Production debugging and your signature architecture
- Write a debugging sequence for a critical production issue in a distributed system: confirm the impact, find what changed, mitigate (roll back or turn off the flag), then check logs, metrics and traces, narrow down by bisection and find the root cause.
- Prepare the architecture you are proud of: constraints, the options you rejected, the main trade-off and what you would change today.
Deliverable: A debugging runbook of about ten steps, a three-minute architecture story with a diagram and one solved data-comparison exercise.
Day 6 — Behavioral stories
- Write five stories in the first person singular for the reported behavioral prompts: choosing between technologies, a stakeholder disagreement, mentoring a junior engineer, speed versus technical debt and a pivot.
- Add a measurable result and one lesson to each story, and cut the setting to two sentences.
- Say each story aloud, then restate the technology-choice and stakeholder stories in the other working language (German or English).
Deliverable: Five written stories with results, plus recordings or notes of two spoken versions.
Day 7 — Mixed rehearsal and closing questions
- Run a mixed session aloud: one design question on a whiteboard or paper, one migration question and two behavioral questions, with the answer's trade-offs spoken each time.
- Review the weakest answer of the week and rewrite it.
- Prepare three questions about client projects, the team and technical growth, and a closing summary of why the role fits your background.
Deliverable: A recorded mixed session, one corrected answer and a list of three questions for the interviewers.
Behavioural preparation
Candidates describe the cultural-alignment stage as concerned with professional maturity, and the reported behavioral questions are about decisions, disagreement, mentoring and change. For a client-facing engineering role, prepare stories where you reasoned about a trade-off, communicated it to non-technical people and measured the result.
Describe a time you had to choose between two competing technologies; what was your decision framework?
Medium · Technical & Domain Expertise
Approach
- Choose a decision you owned, with two real candidates on the table (for example two frameworks, two databases or build versus buy), and state the context in two sentences: the project, the deadline and what a wrong choice would cost.
- Show a framework as concrete criteria, not a feeling: team skills, maturity and community, operational burden, licence, lock-in, performance against the actual requirement, and how hard it is to reverse. Say which criteria you weighted most and why.
- Describe how you tested the riskiest assumption: a time-boxed spike or proof of concept against the hardest requirement, with a number you measured, such as latency under realistic load.
- Say how the decision was recorded and agreed, for example a short architecture decision record, and how you handled a teammate or client who preferred the other option.
- Close with the outcome and a lesson: what held up, what you would change, and what trigger would make you reverse the choice.
Follow-up
- What evidence would have changed your decision?
- How did you handle someone on the team who favoured the other technology?
- If the choice had been wrong, how expensive would it have been to switch?
How do you handle disagreements with stakeholders regarding technical requirements?
Medium · Behavioral & Leadership
Approach
- Pick a real disagreement about a requirement (scope, deadline, a feature that would damage performance or security) where you had to persuade rather than outrank, and describe the stakeholder's underlying goal before your objection.
- Show that you converted the technical concern into the stakeholder's terms: cost, delivery date, risk or user impact, ideally with a number such as expected load, an estimate or an incident risk.
- Lay out the options you offered (full request, reduced scope, phased delivery, workaround) with the trade-off of each, and say how the decision was made and who owned it.
- Report the result honestly, including a compromise or a case where you were overruled and how you recorded the risk and carried on.
- Avoid a story where you win by being right or blame the stakeholder; the story sinks when the other party is portrayed as ignorant.
Follow-up
- What would you have done if the stakeholder had insisted on their original requirement?
- How did you explain the technical issue to someone without a technical background?
- Tell me about a time you were the one who turned out to be wrong.
Can you describe a situation where you had to mentor a junior engineer to improve team output?
Medium · Behavioral & Leadership
Approach
- Name the junior engineer's situation without identifying them: the specific gap you diagnosed (for example weak test habits, oversized pull requests, unclear debugging process) and what team output looked like before.
- Describe the mechanisms you used, such as pairing sessions on real tasks, review comments that explain the principle rather than only the fix, a sequence of tasks with growing ownership and a short checklist for pull requests.
- Say how you measured the team effect with something checkable: review turnaround, rework in reviews, defects after release or how many tasks the person closed independently.
- Include the cost to you (time taken from your own work) and how you managed it, plus one adjustment you made when your first approach did not work.
- The common mistake is a story where you simply did their work or gave advice with no follow-through; show that their independence increased.
Follow-up
- What did you do when they did not respond to your feedback?
- How did you balance mentoring with your own deadlines?
- How do you give critical feedback on a pull request without discouraging someone?
How do you balance the need for rapid delivery with the necessity of technical debt reduction?
Medium · Behavioral & Leadership
Approach
- Start by making debt visible and classified: deliberate shortcuts versus accidental mess, and its interest, meaning how often it slows delivery or causes incidents. A named backlog item with an owner beats a vague complaint.
- Tell a story of a real trade-off: a deadline where you took a shortcut on purpose, wrote it down, agreed it with the product owner or client and scheduled the repayment.
- Describe the mechanisms that keep the balance: a fixed share of each iteration for debt, refactoring next to the feature you are already changing, and tests added around legacy code before you touch it.
- Argue for debt reduction in business terms, such as lead time, incident count or onboarding time, rather than code aesthetics, and avoid suggesting a full rewrite as the default fix.
- State where you refuse shortcuts, for example security, data integrity or the public API contract, because those are hard to repair later.
Follow-up
- How do you convince a product owner to spend time on debt?
- Which kinds of shortcut would you never take, and why?
- Describe debt you took on deliberately and how it was repaid.
Describe a time you had to pivot your strategy based on changing project requirements.
Medium · Behavioral & Leadership
Approach
- Choose a pivot with a clear trigger, such as a client changing priorities, a regulation or a discovered constraint, and say what the original plan was and what made it stop working.
- Show how you decided what to keep and what to discard: you separated sunk cost from reusable parts (data model, interfaces, tests) and re-planned from what the new goal needed.
- Explain how you communicated the effect on scope and timeline to the people involved, with options rather than only bad news.
- Describe an incremental step that reduced risk, for example delivering a thin slice first or isolating the volatile part behind an interface, and give the measurable result.
- The common mistake is a story about chaos that you merely survived; show a deliberate response and what you changed afterwards to make later changes cheaper.
Follow-up
- How did you decide which existing work to throw away?
- How did you tell the client or stakeholders about the delay?
- What would you build differently now so a similar change is cheaper?