cswork / libraryOpen practice workspace

Interview guides · AkzoNobel

AkzoNobel Software Engineer Interview Guide

AkzoNobel Software Engineer interview guide: four reported rounds, telemetry design, production debugging, project and behavioral questions, 7-day plan.

The 60-second brief

AkzoNobel makes paints and coatings. The role description candidates see places the Software Engineer on the digital side of that business, working on manufacturing execution systems, supply chain optimisation, automated production sites and data pipelines across the enterprise. The listed work includes microservices, cloud architecture and integrating IoT sensors from factory floors, with collaborators such as production managers, data scientists, infrastructure engineers, product managers and plant operators. Typical projects named in the description include internal web applications, enterprise resource planning integrations and data processing tools that track production efficiency.

This guide is for candidates interviewing for a Software Engineer position at AkzoNobel, from mid-level to senior as the requirements describe. It covers the four reported rounds, the topic mix candidates report (problem solving, business-case style scenarios, technical fundamentals, structured case answers, process safety), and the stack the role lists: Java, C#, Python or JavaScript, relational and non-relational databases, REST APIs, cloud platforms, Docker and Kubernetes. It also covers the three reported question groups: project and fundamentals questions, motivation and teamwork questions, and monitoring, debugging and prioritisation scenarios.

Candidates report four rounds over roughly three to five weeks: Initial Screening, Technical Assessment, Team Interviews and Final Discussion. Formats can differ between a local manufacturing site, a regional tech hub and a corporate digital office.

Focus areas

  • Problem-solving / reasoning
  • Business case / applied scenario analysis
  • Technical fundamentals

Overview

The reported work sits where application software meets production equipment. That shapes what a good answer looks like. Data from sensors and plant systems arrives late, duplicated, out of order or plainly wrong, and a service that fails on a Monday morning can affect a physical line. When you practise design and debugging questions, put those realities in your answer: how a reading is validated, where a bad record goes, how a replay works after a fix, what the system does when an upstream source goes quiet, and why software monitoring never replaces the plant's own safety interlocks.

Three question groups are reported. The first covers your past projects, troubleshooting of out-of-specification processes or data streams, database optimization, API design, architecture principles, and code quality and testing. The second covers motivation for the company, a team challenge, your greatest professional achievement, and working through ambiguity or changing scope. The third covers designing a monitoring system for a distributed manufacturing environment, a method for debugging a performance bottleneck in a production application, and prioritising competing engineering requests. Candidates also list example scenarios such as designing an ingestion pipeline for real-time factory telemetry, handling dependency injection and configuration in enterprise applications, tracing intermittent API timeouts, and deciding between refactoring legacy code and rewriting a service.

Preparation therefore splits three ways. Build two or three project stories you can defend decision by decision, since the reported questions ask about past projects and architecture principles. Rehearse two system walkthroughs out loud, one design (telemetry ingestion plus monitoring) and one diagnosis (intermittent timeouts or a slow endpoint), each starting with assumptions and ending with a trade-off. Then prepare behavioral answers with a plant-adjacent angle: working with non-engineers, changing requirements, and safety-minded handling of failure, since process safety appears in the reported topic mix. The role lists nice-to-have experience in manufacturing tech, IoT, industrial automation and supply chain systems. If you lack it, show that you reason well about unreliable inputs and operational consequences.

The AkzoNobel interview process

The four stages below are what candidates report, in the order they report them. Only the short stage descriptions come from candidate reports.

Initial Screening

The first stage, as candidates describe it, is a check of your application and qualifications against the role, and the general account of the process places a recruiter screen at the start. No technical content is reported for this stage. Use it to set up a clear story: what you have built, which of the listed languages and databases you have used, and why you want this role. Keep a short account of one project that touches data or integrations ready, since the role description centres on pipelines and enterprise systems, and know where you stand on location, because formats reportedly vary between plant-linked roles, regional tech hubs and corporate offices.

What to demonstrate

  • Your application and qualifications, which candidates report this stage reviews
  • A recruiter conversation, which the general process account places at the start

How to prepare

  • Write a short walk-through of your CV that ends with the project closest to data pipelines, integrations or operations software.
  • List which of Java, C#, Python, JavaScript, relational and non-relational databases, REST, cloud, Docker and Kubernetes you have used in production, with one concrete example each, so you can map your experience to the listed stack.
  • Write your answer to why AkzoNobel and this role using facts from the role description, not generic praise.

Technical Assessment

Candidates report that Technical Assessment consists of coding challenges and system design problems. Because the stack lists several languages, choose the one you are fastest in and write complete, tested solutions in it. For design practice, the reported pipeline and monitoring scenarios for factory data and the production debugging scenarios are good material, though candidates do not say which stage those questions come up in. Start each design answer with assumptions (message rate, number of sites, tolerance for lost or late readings), then draw ingestion, validation, storage and alerting, and finish with failure handling, the boundary with plant safety systems, and a trade-off you chose.

What to demonstrate

  • Coding challenges, as reported for this stage
  • System design problems, as reported for this stage

How to prepare

  • Rehearse a design for a telemetry ingestion pipeline: producer, buffer, validation with a quarantine path for bad readings, storage, alerts, and replay after a fix.
  • Write out your step-by-step diagnosis for intermittent API timeouts, ordered by what each check rules out.
  • Practise stating trade-offs between speed, cost, maintainability and scalability at the end of every design answer.

Team Interviews

Candidates report this stage as meetings with people who may become your teammates, focused on how you collaborate and how you fit culturally. Nothing more is reported about its format or questions. Preparation advice: the reported question set includes motivation, team challenges, achievements, ambiguity and past projects, and stories on those topics are the natural material for a collaboration-focused conversation. Bring stories where your own contribution is clear and where you worked with people outside engineering, such as operations staff, product managers or data engineers, since the role description lists them as collaborators.

What to demonstrate

  • Collaboration, as reported for this stage
  • Cultural fit, as reported for this stage

How to prepare

  • Write three stories in situation, action, result form: a team challenge, an achievement, and a change of scope; make sure each names a decision you personally made.
  • Prepare to explain one past architecture choice with the alternative you rejected and the reason, so your own decisions are easy to follow.
  • Practise explaining a technical constraint to a non-engineer in plain language, using a plant or supply chain scenario.

Final Discussion

Candidates report the last stage as a closing conversation with senior leadership that completes the evaluation. Its format and content are not reported further. Preparation advice: be ready for a wider-angle conversation covering your motivation, how your engineering judgment translates into business terms, and how you would work across a multi-site organisation. Keep concise answers for your greatest achievement, how you prioritise competing engineering requests and what you want from the role, plus a few questions of your own on team structure, technical debt and how software teams work with plant operations.

What to demonstrate

  • A conversation with senior leadership, as reported for this stage
  • The close of the evaluation, which candidates report this stage completes

How to prepare

  • Rehearse a prioritisation answer: how you rank competing requests by impact, risk and effort, and how you tell the people whose work you deferred.
  • Prepare a one-minute summary of your strongest project that a non-engineer could follow, with the outcome in business terms.
  • Prepare a short, specific answer on your motivation for this role and how you would communicate across functions.
  • Write three questions about how software teams work with production sites, technical debt and release practices.

Where candidates lose points

Designing the telemetry pipeline for clean data only

State assumptions about late, duplicated, out-of-order and invalid readings before drawing boxes. Include a quarantine path, an idempotent write or high-water mark per source, and a replay procedure after a fix. Say plainly that safety interlocks stay in the plant control layer, not in your pipeline.

Answering the production-timeout question with a list of possible causes

Give an ordered sequence: confirm the symptom in metrics, find what changed, split by endpoint and dependency, check slow queries and connection pools, then reproduce. Say what each step rules out and how you would confirm the cause, not just the trigger.

Describing a past project in team terms with no decision of your own

Pick projects where you made a call, name the alternative you rejected, and give the result with numbers you can defend. Use "I" for your decisions and name others' contributions separately.

Treating database, API and testing questions as buzzword lists

Bring one concrete case for each: a query plan you read and the index you changed (and why its column order fit the filter and sort), an API change that kept old clients working, a retry-safe write, and a test layer that caught a real bug.

Giving a refactor-versus-rewrite answer with a fixed preference

Argue from conditions: test coverage, how well the current behaviour is understood, how often the code changes, and whether it can be replaced piece by piece. Describe how you would migrate in slices and keep the old path running until the new one is verified.

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?

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

  1. 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.
  2. 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.
  3. 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.
  4. 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?

Identify the heaviest tenants in a five-minute window under memory pressure

Medium · top-k · heavy hitters · streaming

The edge service handles about 3,000 requests per second across roughly 50,000 tenants, peaking near 9,000. Expose the 50 heaviest tenants by request count over the trailing five minutes so limits can be tightened before one tenant's backfill starves the fleet. You may not retain five minutes of raw records. Give the exact solution and its memory, then the bounded-memory approximation with its error stated as a formula, and say which you would ship and at what tenant cardinality that choice changes.

Approach

  1. Do the exact version first, because it is affordable at this cardinality: a ring of 300 one-second counters per tenant, advanced lazily, is 1,200 bytes of counters per tenant and roughly 60 to 90 MB for 50,000 tenants with overhead. Carry a running total and subtract the bucket you overwrite so a window read is O(1) rather than 300 adds.
  2. Extract the top 50 with a size-k min-heap over the tenant sums: O(d log k) for d tenants, against O(d log d) to sort them all. Maintaining the heap continuously instead of on query requires a tenant-to-heap-index map, because incrementing a count already inside the heap means sifting from a known position, and without that map you rebuild the heap on every request.
  3. State the approximation precisely rather than gesturing at sketches. Misra-Gries with m counters retains every item whose true count exceeds N/(m+1), and each retained count underestimates the truth by at most N/(m+1). With m = 1,000 and N = 900,000 requests in the window the error is roughly 900 requests, which is fine for spotting a tenant sending 50,000 and useless for ranking two tenants 200 apart.
  4. Say what breaks when the window slides: Misra-Gries and Space-Saving are insert-only and cannot be decremented as records age out. The workable construction is one summary per sub-window, say ten seconds, with 30 summaries merged at query time, and the merged error is the sum of the per-summary errors, so the bound degrades linearly in the number of sub-windows.

Follow-up

  • The heaviest tenant is heavy because of one export job rather than user traffic. Should the limiter treat those as the same tenant?
  • Two tenants sit tied at the boundary of the top 50. Does your answer flap, and does the flapping matter?

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?

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?

Make resource creation safe for a client that retried a timeout

Medium · idempotency · retries · race conditions

POST /v1/resources creates a resource row and, in the same transaction, a resource_revision and an outbox_event. A partner's HTTP client times out at 2 seconds and retries twice; under load the first request is still executing when the retry arrives, and duplicate resources are appearing. Using idempotency_key (tenant_id, idempotency_key, request_fingerprint, state, response_status, response_body, resource_id, locked_until, expires_at), specify the whole contract: first call, concurrent retry, retry after completion, a key reused with a different body, and what the client does with each response.

Approach

  1. Name why the plain REST shape fails here. POST is not idempotent, a timeout leaves the client unable to distinguish a lost request from a lost response, so it must retry - and the retry is a second create. Checking whether the key exists and then inserting it is check-then-act: under exactly the concurrency that caused the timeout, both attempts look, both see nothing, both proceed.
  2. Let the unique constraint arbitrate instead. INSERT the key row with state 'in_flight' and locked_until set to now plus the request deadline, and commit that reservation on its own before any work is attempted - an uncommitted row is invisible to the concurrent retry, which is the entire point of writing it first. One caller wins the insert and proceeds; the other takes the unique violation and reads the row rather than falling through to the work.
  3. Branch the loser on what it found. 'succeeded' replays response_status and response_body verbatim, with a header marking it a replay. 'in_flight' with locked_until in the future returns 409 and a Retry-After - do not park a request thread waiting on another request, that is how a concurrency bound is consumed by retries. 'in_flight' past locked_until is reclaimable by a conditional UPDATE predicated on the old locked_until, so exactly one reclaimer wins. A fingerprint mismatch is 422 and never the stored response: a different body under the same key is a client defect, and serving the old response hides it forever.
  4. Commit the effect and the key's completion together - resource insert, revision row, outbox row, and the UPDATE of the reserved key to 'succeeded' with the stored response, in one transaction. That makes a crash binary: either all of it is durable and the key reads 'succeeded', or the transaction rolls back and the only durable trace is the reservation row, still 'in_flight', with no resource behind it. The reclaim branch finishes that case - once locked_until passes, one retry takes the row by conditional UPDATE and runs the work for the first time. Splitting the two commits is what creates the window with no recovery: the effect durable, the key still 'in_flight', and a reclaimer that cannot distinguish that from work never started, so it creates a second resource.

Follow-up

  • Response bodies are pruned at 24 hours but resource_id is kept. What do you return to a replay that arrives after pruning?
  • The endpoint now also sends a welcome email. Which part of this contract prevents a second send, and which part cannot?

Specify the outbound webhook contract a customer endpoint can verify

Medium · webhooks · hmac · at-least-once

Egress delivery sends resource.created, resource.updated and resource.archived to roughly 40k customer endpoints at about 1.5k deliveries/second, with a per-destination concurrency cap of 4 and a 10 second connect-plus-read timeout, at-least-once from the relay. The receiver is code you do not control, often behind a proxy that may re-encode JSON. Specify the payload envelope, how the receiver verifies authenticity and rejects replays, what ordering it may assume, how it deduplicates, which status codes it should return and what each means to us, and the retry, circuit and replay behaviour.

Approach

  1. Send the fact, not a pointer: event_id, event_type, aggregate_type, aggregate_id, aggregate_version, occurred_at and the payload copied from outbox_event. A receiver told only that resource 42 changed has to call back, and the call back returns a newer state than the event describes - that is precisely how a consumer applies changes out of order while believing it is following them.
  2. Sign the exact bytes on the wire: HMAC-SHA256 over the timestamp, a separator, and the raw body, in a header, compared in constant time before the body is parsed. Instruct receivers to verify the raw bytes, never a re-serialised copy, since a proxy that reorders keys or changes whitespace invalidates a signature computed over re-encoded JSON. Reject a timestamp outside a tolerance - five minutes is typical - and keep a short seen-set of event_ids, because a capture replayed inside the tolerance still verifies.
  3. Support key rotation by sending several signature values in one header during the overlap window and publishing that any one that verifies is sufficient. Without that rule a key rotation is a synchronised outage across every destination at once.
  4. State the guarantee as it actually is: at-least-once and unordered, including within a single aggregate_id. The outbox is ordered per aggregate at the source, but the relay holds up to 4 requests in flight per destination and backs off each retry independently, so a version 6 delivery that needs one retry lands after a version 7 that succeeded on its first attempt. Publishing per-aggregate ordering we do not enforce is worse than publishing none, because a receiver that trusts it overwrites new state with old. Receivers deduplicate on event_id and apply conditionally - UPDATE ... WHERE aggregate_version < :incoming, or the same comparison under a row lock on the aggregate - which discards stale redeliveries and stays correct when two deliveries for one aggregate are processed at the same time. A duplicate and an out-of-order delivery then have the same outcome: no-op.

Follow-up

  • A customer insists an event never arrived. What do you check, in order, and which table settles the argument?
  • A receiver cannot store a version and asks us to deliver their events in order. What would the relay have to give up to offer that, and what does one failing event then do to the rest of their stream?

These scenarios assess how you structure unstructured problems and deliver practical solutions. How would you

Medium · Problem-Solving and Case Studies

These scenarios assess how you structure unstructured problems and deliver practical solutions. How would you approach designing a monitoring system for a distributed manufacturing environment? Walk me through your methodology for debugging a performance bottleneck in a production application. How do you prioritize tasks when managing multiple competing engineering requests?

Approach

  1. Monitoring design: I start by asking how many sites, signals per site, sample rates and how fast an operational alarm must fire. Then I outline an edge gateway per site that timestamps readings at the source and buffers them locally (store-and-forward), so a WAN outage delays data instead of losing it. Gateways publish to a durable log partitioned by site and asset, and consumers write to a time-series store with downsampled rollups for dashboards and trend analysis.
  2. Safety boundary: I state up front that safety trips and interlocks belong to the PLC or safety-instrumented system, never to this pipeline. The edge gateway can raise operational alarms (drift, out-of-spec trends, a sensor gone stale) and it reports interlock and trip state as data, but if the pipeline goes down the plant must stay safe without it. Any write path back to the plant, such as a set point, goes through range limits, an approval step and change control.
  3. Monitoring correctness: I make writes idempotent on (sensor id, source timestamp) so redelivered or backfilled readings are not counted twice. I keep clocks synced (NTP, or PTP where sub-millisecond order matters), cap label cardinality in the metrics store, and add heartbeat or staleness alerts so a sensor that goes silent is caught. Alerts get hysteresis or a minimum duration so a reading hovering at a threshold does not flap.
  4. Performance bottleneck: I quantify it first (p50, p95 and p99 latency and throughput against a baseline) and find when it started and what changed: a deploy, config, traffic mix or data volume. I check utilisation, saturation and errors for CPU, memory, disk, network and connection pools, use traces to find the dominant span, then profile only that component (flame graph, GC logs, EXPLAIN ANALYZE). Usual culprits are N+1 queries, a missing index, lock contention, an exhausted pool or a slow dependency with no timeout; I change one thing at a time and compare the same percentile under load.
  5. Prioritising competing requests: I put every request on the same axes: safety or compliance risk, production downtime or scrap caused, how many users are affected, the deadline, effort and the cost of waiting. Safety issues and anything stopping production go first; the rest I rank by cost of delay divided by effort. I tell the requesters what was deferred and why, and write it down so the order can be challenged with data.

Follow-up

  • One site loses its WAN link for several hours. What happens to its readings and alarms, how do you backfill without double counting, and why does the plant stay safe in the meantime?
  • p99 latency doubled while CPU sits at 30 percent. Where do you look next, and what would each finding rule out?
  • Two production managers each say their request is the most urgent. How do you decide between them, and how do you tell the one who waits?

Suggested practice checklist

The plan follows the four reported rounds and the three reported question groups. Day two covers pipeline design and fail-safe behaviour, days three and four production debugging and timed coding, day five the project and fundamentals questions, day six the behavioral stories, and day seven a full rehearsal.

Day 1 — Map the loop and inventory your projects

  • Write the four reported rounds, Initial Screening, Technical Assessment, Team Interviews and Final Discussion, with one line on what each is reported to cover.
  • List the projects you could discuss in depth. For each, write the requirement, the architecture decision you made, the alternative you rejected, and a result.
  • Tick off the listed stack you have used: Java, C#, Python or JavaScript, relational and non-relational databases, REST, cloud, Docker, Kubernetes.

Deliverable: A one-page loop map plus a project inventory with a decision and a result for each project.

Day 2 — Design a factory telemetry pipeline that fails safe

  • Sketch a pipeline from plant sensors to dashboards and alerts: gateway, buffer, validation, storage, monitoring. State your assumptions first, including message rate, number of sites and tolerance for delay.
  • Write how you handle duplicate, late, out-of-order and invalid readings, including a quarantine path and a replay after a fix.
  • Define fail-safe defaults for a plant-connected service: what it does on stale data, lost connectivity or an out-of-range set point; why software monitoring never replaces PLC or safety-system interlocks; and how change control gates releases that reach plant systems.

Deliverable: A labelled pipeline diagram, a failure-handling and fail-safe list for it, and a passing solution to the redelivered-batch drill.

Day 3 — Debug a slow or timing-out production service

  • Write your step-by-step diagnosis for an API endpoint that times out intermittently, ordered by what each check rules out: metrics, recent changes, dependencies, slow queries, pool exhaustion, and reproduction.

Deliverable: A diagnosis checklist, a written explanation of the index problem with the fix, and a retry-safe creation design.

Day 4 — Timed coding in your strongest language

  • Solve the drill on finding the heaviest tenants in a window under memory pressure, then state its time and memory trade-off aloud.
  • Work the soft-delete re-registration SQL drill, covering a partial unique index and the edge cases it leaves.

Deliverable: Three working, tested solutions, each with a spoken explanation of complexity and edge cases.

Day 5 — Project, fundamentals and architecture answers

  • Answer aloud the project and fundamentals question: a past project, troubleshooting an out-of-specification data stream, database optimization, API design and testing. Use your day-one inventory.
  • Write a dependency injection and configuration answer that covers constructor injection so components can be tested with fakes, per-site and per-environment config kept outside the build artifact, secrets held in a vault rather than in config files, and validating config at startup so a bad value fails fast.
  • Write a refactor-versus-rewrite answer that argues from test coverage, change frequency and whether the service can be replaced in slices while the old path keeps running.

Deliverable: A recorded or written answer for each fundamentals topic, plus a completed webhook contract.

Day 6 — Behavioral stories

  • Write and rehearse answers on motivation for AkzoNobel, a significant team challenge, your greatest achievement, and ambiguity or changing scope.
  • Write the prioritisation answer: how you rank competing engineering requests, with safety and production-stopping issues first, and how you communicate what is deferred.

Deliverable: Four written story outlines and a prioritisation answer, each with a named personal decision and a result.

Day 7 — Full rehearsal and questions to ask

  • Run a full rehearsal in order: a spoken project answer, the telemetry design with its safety boundary, the timeout diagnosis, then two behavioral stories.
  • Mark the answer where you reached for a buzzword with no example, and replace it with a concrete case.
  • Write three questions for senior leadership about team structure, technical debt and how software teams work with production sites.

Deliverable: A tightened answer set with weak spots fixed and three prepared questions.

Project, teamwork and motivation stories

Candidates report that Team Interviews focus on collaboration and cultural fit. Separately, the reported question set includes motivation, team challenges, achievements and ambiguity, plus questions about past projects and troubleshooting that also call for story-form answers. Prepare stories where your own decision is visible, where you worked with people outside engineering, and where requirements changed.

  1. Why do you want to work for AkzoNobel, and what attracts you to this role?
  2. Tell me about a significant challenge in a team and how you resolved it.
  3. What is your greatest professional achievement so far?
  4. Tell me about a time you dealt with ambiguity or changing project scope.
  5. Walk me through a past project: the requirement, your architecture choices and what you would change.
  6. Describe how you handled an out-of-specification process or data stream, from detection to prevention.

These questions test your core engineering knowledge, computer science fundamentals, and your ability to reaso

Medium · Technical and Domain Fundamentals

These questions test your core engineering knowledge, computer science fundamentals, and your ability to reason through technical problems. Can you explain your experience with past projects and how you approached solution building for complex requirements? How do you handle troubleshooting and corrective actions when dealing with out-of-specification processes or data streams? What is your familiarity with database optimization, API design, and system architecture principles? How do you ensure code quality, testing rigor, and maintainability in fast-paced development cycles?

Approach

  1. Choose one project you can defend decision by decision and tell it in four steps: the requirement and constraints, the options you considered, what you chose and why, and the result you can point to. Say "I" for your own decisions and name the colleague or team for theirs. A list of technologies with no rejected alternative is the weak version of this answer.
  2. For out-of-specification processes or data streams, describe a full sequence: detect with validation at ingestion (range and unit checks, schema checks, stuck or flat-lining sensors, timestamp skew), quarantine suspect records to a dead-letter store rather than dropping or silently accepting them, alert with enough context to act, correct at the source, replay the quarantined data after the fix, then add a preventive check. Keep corrective and preventive action separate.
  3. For database optimization, work from the query plan. Know the equality-sort-range rule: for WHERE a = ? AND b > ? ORDER BY c, an index on (a, c, b) returns rows already in c order and avoids the sort but reads every row matching a, while (a, b, c) narrows the scan to the b range but still needs a sort, because after a range column the index is no longer ordered by the columns that follow. I choose between them from EXPLAIN ANALYZE (rows read versus sort cost, and whether a LIMIT makes the sort-free plan win), then report before and after numbers and name the write and storage cost of each index.
  4. For API design, cover resource naming, keyset pagination instead of offset, consistent error codes, versioning without breaking clients, and idempotency keys on retried writes. For architecture, state boundaries and failure modes: what happens when a dependency is down, and where you accepted coupling on purpose.
  5. For code quality, describe the layers you actually used: unit tests on business logic, integration tests against a real database or container, contract tests on API boundaries, a CI gate, small reviewed changes, and a policy for flaky tests. Under tight cycles, say what you would cut first and what you would never cut.

Follow-up

  • If the data volume grew tenfold, which part of that design would break first?
  • How did you prove the fix or index made the difference, and not a change in load?
  • How would you test that pipeline against malformed or missing sensor readings?

These inquiries evaluate your alignment with company values, teamwork style, and adaptability. Why do you want

Medium · Behavioral and Cultural Fit

These inquiries evaluate your alignment with company values, teamwork style, and adaptability. Why do you want to work specifically for AkzoNobel, and what attracts you to this role? Can you describe a time when you faced a significant challenge in a team and how you resolved it? What do you consider your greatest professional achievement so far? Tell me about a time when you had to deal with ambiguity or changing project scopes.

Approach

  1. For "why AkzoNobel and this role", connect your experience to what the role description lists: software for production, supply chain and data pipelines, with plant operators and data teams as collaborators. Name one thing about that work you want to do and one skill of yours that fits. Avoid praise you cannot back up, and avoid saying you want the brand name; a specific reason is more convincing.
  2. For a significant team challenge, use situation, action, result and pick a real disagreement or breakdown: conflicting technical approaches, a missed handoff, or unclear ownership. Show what you did to resolve it, such as a short written comparison of the options, a small experiment, or an agreed owner, and describe the state of the working relationship afterwards. Do not make a colleague the villain.
  3. For your greatest professional achievement, choose something with a measurable outcome and a scope you can state honestly: what you owned, what the team owned, what it cost, and what you would do differently. Prefer a project close to this role, such as a data pipeline, an integration or an operational tool, and finish with the result in terms a non-engineer would value.
  4. For ambiguity or changing scope, show a method: write down assumptions, ask the stakeholders to confirm the one or two that matter most, build a thin first slice, set a checkpoint to re-plan, and record each scope change with its effect on time and risk. The failure to avoid is either waiting for perfect requirements or building a large guess.

Follow-up

  • When scope changed mid-project, how did you keep operations or plant-side stakeholders informed, and what did you tell them first?
  • If the output of your greatest achievement had fed a production line directly, what would you have designed or tested differently?
  • How did you handle a stakeholder who disagreed with the decision?

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?