Interview guides · Colruyt Group
Colruyt Group Software Engineer Interview Guide
Colruyt Group Software Engineer interview prep: assessment, technical and managerial rounds, Java, OOP, TCP vs UDP, system design and a 7-day plan.
The 60-second brief
Candidates describe Colruyt Group as a retail and service group. The engineering work they describe sits behind supply chain logistics, e-commerce platforms and internal operational tools. The Software Engineer role is listed as covering backend services, cloud infrastructure and integration projects, with Java or a similar object-oriented language as the main skill. The listed nice-to-haves are Azure or AWS, Agile/Scrum, and ServiceNow for specialised roles. Reported technical topics also include microservices, Docker, Kubernetes and CI/CD pipelines.
This guide is for candidates applying as a Software Engineer at Colruyt Group, from fresh graduates to experienced hires. It covers the three reported stages, the thirteen reported questions (Java and OOP, design patterns, networking, system design and behavioral prompts), and a 7-day plan that includes timed aptitude practice. Some roles ask for specific certifications or enterprise frameworks, so check your own job invite for the depth required.
Candidates report three stages over roughly 3-5 weeks: an Online Assessment, Technical Conversations and Managerial Conversations. The process can vary slightly by region and department.
Focus areas
- Data Structures & Algorithms (DSA)
- Software Engineering Fundamentals
- Aptitude Testing
Overview
The reported loop opens with an online assessment of logical and personality traits before you speak to an engineer. Candidates describe numerical reasoning, verbal ability and logical deduction, with pattern recognition and sequence puzzles as the typical format. Practise it as its own skill under time pressure, because Java knowledge does not help there.
The technical stage is reported as a series of conversations rather than one coding exam. The reported questions are mostly fundamentals you must explain and justify: OOP, interface versus abstract class, the Facade and Singleton patterns, Java Streams and Generics, TCP versus UDP, the OSI model, and how you would design a component for high-traffic retail data. Candidates also report being asked to walk through the architecture of their most recent project and to optimise a slow SQL query, so prepare those two as well as the listed topics.
The managerial stage is reported as a check on fit with the team and company. Candidates describe questions about technical disagreements, motivation for joining Colruyt Group, learning a tool under a deadline and juggling priorities. Prepare real stories with a decision, a trade-off and a result, and learn what the group does across retail, logistics and e-commerce so your motivation answer is specific.
Because every project on your resume can become a discussion topic, rehearse each one in the same shape: the problem, the design you chose, the alternative you rejected, how you tested and deployed it, and what changed for the people using it.
The Colruyt Group interview process
Candidates describe three stages, in this order. The first is an aptitude-style assessment; the other two are conversations.
Online Assessment
Candidates report an online assessment of logical and personality traits. The reported content is aptitude-style: numerical reasoning (reading data and patterns), verbal ability (analysing information and stating a conclusion) and logical deduction, with pattern recognition and sequence analysis as typical formats. It is a different skill from the technical conversations, so schedule separate practice for it and treat the personality part as a place to answer consistently and honestly.
What to demonstrate
- Logical reasoning through pattern and sequence puzzles
- Numerical reasoning: reading tables and spotting trends in data
- Verbal ability: extracting a conclusion from a passage
- Personality traits, as the assessment is reported to cover them
How to prepare
- Do timed pattern-recognition and number-sequence sets until you can name the rule types (arithmetic step, alternating, position-based) quickly.
- Practise reading a table or chart and answering percentage and ratio questions without a spreadsheet.
- Read short passages and write a one-sentence conclusion, then check which claims the text actually supports.
- Use a quiet space and a stable connection, and answer personality items from how you really work rather than guessing a profile.
Technical Conversations
Candidates report a series of technical conversations focused on deep-dive technical skills. The reported questions are fundamentals to explain and defend: OOP, interface versus abstract class, Facade and Singleton, Streams and Generics in Java, TCP versus UDP, the OSI model with network troubleshooting, high-traffic component design, decomposing a business requirement, and performance versus maintainability. Candidates also mention walking through the architecture of their latest project and optimising a slow SQL query. Practise explaining each with a concrete example from your own code.
What to demonstrate
- Java and object-oriented fundamentals, explained with applied examples
- Understanding of how services interact and scale
- Basic to intermediate data structures and algorithms
- Ability to talk through reasoning and troubleshooting, not only state an answer
How to prepare
- Write small Java examples for the Facade and a thread-safe Singleton, and an interface versus abstract class comparison you can say aloud.
- Prepare a layer-by-layer OSI troubleshooting sequence and a TCP versus UDP choice with two concrete use cases.
- Practise reading an execution plan and explaining why a slow SQL query is slow and what index or rewrite would fix it.
- Rehearse a 5-minute architecture walkthrough of your most recent project, including what you would change now.
Managerial Conversations
Candidates report interviews with managerial staff aimed at fit within the team and company culture, described as 'match and fit'. The behavioral questions reported for the loop are the technical disagreement, why Colruyt Group, learning a technology under a tight deadline, and managing several priorities. Candidates are also told to explain technical decisions in terms of added value rather than skills alone. Prepare four stories from your own work and a specific motivation answer.
What to demonstrate
- Fit with the team and company, as the round is reported to cover
- How you handle disagreement and team dynamics
- Career goals and motivation for this employer
- Ability to explain technical decisions and their impact in plain terms
How to prepare
- Write four stories, one per reported behavioral prompt, each with a situation, your decision, a measurable result and a lesson.
- Research the group's business areas (retail, supply chain logistics, e-commerce, internal tools) and pick one that connects to your experience.
- Practise explaining one technical decision to a non-technical listener in under a minute, without jargon.
- Prepare two questions about the team's projects, delivery process and collaboration with product owners.
Where candidates lose points
Reciting definitions for OOP, interface versus abstract class or design patterns with no example from your own code
For each, prepare one Java snippet or project example: say why you used an interface (a contract with multiple implementations), when an abstract class fits (shared state or partial behaviour), and what the pattern cost.
Presenting Singleton as simple and never mentioning thread safety, testability or hidden global state
Know a safe form (enum singleton or initialization-on-demand holder), explain why a naive lazy getInstance is broken under concurrency, and say when dependency injection is the better choice.
Answering the OSI and troubleshooting question by listing seven layers, with no diagnostic sequence
Walk up the stack with a tool per layer: link and IP reachability, then DNS resolution, TCP connect and TLS, then application status codes and logs. State what each check rules out in a distributed system.
Treating the online assessment as a formality and arriving without timed aptitude practice
Practise numerical, verbal and sequence items under a timer in the days before it. A strong technical background does not substitute for speed on pattern puzzles.
Describing past projects as lists of technologies with no reason or business effect, then giving a generic answer on why you want to join
For each project resume line, prepare the problem, your design decision, the alternative, the result and who benefited. Tie your motivation to one specific business area of the group.
Questions & practice
Archive a resource graph without breaking live references or recursing
Medium · graph traversal · topological order · tenant isolation
Resources reference other resources within a tenant; for the largest tenant the reference table holds up to 2,000,000 nodes and 8,000,000 edges. Archiving a resource must archive everything reachable from it that nothing outside the set still references, refuse when a live external referrer exists, and terminate when references form cycles, which they legitimately do. Produce the archive order and the refusal list, targeting O(V+E). Say what stops the traversal crossing a tenant boundary, and why recursion is the wrong control structure at this size.
Approach
- Load the subgraph with the tenant predicate on both endpoints of the edge, not only on the side you started from. Scoping the left table alone is the classic cross-tenant leak: one mis-entered edge then pulls another tenant's resources into the traversal and, worse, into the archive.
- Traverse iteratively with an explicit stack. A 2,000,000-node graph can hold a chain deep enough to exhaust a native stack in the low tens of thousands of frames, and that failure is a process crash rather than an error you can return.
- Treat cycles as data rather than corruption: compute strongly connected components with Tarjan in O(V+E) using its own explicit stack, then condense. The condensation is a DAG, so a topological order over it gives the archive order, and every member of a component archives in one transaction because no order within a cycle is valid.
- Decide refusals with reverse edges. A candidate is archivable only if every in-edge originates inside the candidate set, so build the transpose or count in-degrees restricted to the visited set, and emit each blocked resource with the id of the external referrer, which is the only part of the answer an operator can act on.
Follow-up
- The graph is read in one query and the archive writes a minute later. What can change in between, and how do you make the write safe?
- The candidate set is 400,000 resources. Is that one transaction, and if not, what does a half-finished archive look like to a reader?
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?
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?
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
- 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.
- 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.
- 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.
- 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?
Stop tag and share joins from fanning out a page
Medium · join fan-out · semi-joins · many-to-many
resource_tag is (resource_id, tag_id) with PK (resource_id, tag_id); resource_share is (resource_id, shared_with_user_id, permission). The tagged-and-shared listing inner-joins resource to both, filters tenant_id, tag_id = ANY($2) and shared_with_user_id = $3, orders by updated_at DESC and takes 50. Pages come back with fewer than 50 distinct resources and the total in the header is far too high. Explain the row multiplication, rewrite both the page query and the count query so each is correct, and name the index each one needs. PostgreSQL 16.
Approach
- Do the arithmetic against the predicates that are actually there. An inner join emits one row per matching child row, and both joins are filtered: tag_id = ANY($2) admits only the requested tags, shared_with_user_id = $3 admits one user's share rows. So a resource holding three of the requested tags and shared with $3 once yields three rows, not one — the multiplier is its count of matching tags times its share rows for that single user, and that second factor is 1 unless the table admits duplicate (resource_id, shared_with_user_id) pairs. LIMIT 50 then limits rows rather than resources, and COUNT(*) counts pairs — the header is the product, not the population.
- Reject DISTINCT as the fix. It deduplicates after the product has been built, so the planner must materialise and sort the fanned-out set before the LIMIT can apply, and it leaves any SUM or AVG in the same select list wrong.
- Rewrite both filters as semi-joins, keeping resource as the only row source: AND EXISTS (SELECT 1 FROM resource_tag rt WHERE rt.resource_id = r.resource_id AND rt.tag_id = ANY($2)) and the same shape against resource_share. A semi-join stops at the first match per resource and preserves the driving index order, so ORDER BY updated_at DESC, resource_id DESC LIMIT 50 still stops after 50 rows.
- Count with the same predicates and no join at all: SELECT count(*) FROM resource r WHERE r.tenant_id = $1 AND r.status = 'active' AND EXISTS (...) AND EXISTS (...). Nothing multiplies a resource, so the number is the population.
Follow-up
- The filter changes from 'any of these tags' to 'all of these tags'. Rewrite it and state what it costs relative to the ANY form.
- A resource can be shared with the same user twice under different permissions. Does your count change, and should it?
Can you explain the core concepts of Object-Oriented Programming (OOP) and how you apply them in your projects
Medium · Technical Foundations & Programming
Can you explain the core concepts of Object-Oriented Programming (OOP) and how you apply them in your projects?
Approach
- Name the four pillars and give each a one-line Java meaning: encapsulation (private fields, methods that guard invariants), abstraction (callers depend on an interface, not the implementation), inheritance (an is-a relationship reusing a base type), polymorphism (one call, behaviour picked by the runtime type).
- Separate the two kinds of polymorphism: overriding is resolved at runtime by dynamic dispatch, overloading is resolved at compile time from the declared argument types.
- Anchor each pillar in one real class from your own project, e.g. an Order whose status can only change through a transition method, so no caller can set an illegal state directly.
- Say when you prefer composition over inheritance: deep hierarchies create fragile base classes, and a subclass that breaks the parent's contract violates the Liskov substitution principle.
- Close with the trade-off: OOP structure pays off when behaviour varies by type; for plain data, a Java record or a simple class with no hierarchy is clearer.
Follow-up
- Give an example of a subclass that violates Liskov substitution and how you would restructure it.
- When did you replace inheritance with composition, and what did it change in your tests?
- How do the SOLID principles relate to the four pillars you just described?
How do you implement Design Patterns such as the Facade or Singleton patterns in your code?
Medium · Technical Foundations & Programming
Approach
- Define Facade as one simplified entry point over a subsystem: for example a CheckoutFacade that calls inventory, pricing and payment clients, so controllers depend on one class instead of three.
- Note that a Facade reduces coupling without hiding the subsystem: code that needs fine-grained control can still call the underlying classes, and the Facade should not grow into a god object.
- For Singleton in Java, name the safe implementations: an enum singleton (handles serialization and resists reflection), or the initialization-on-demand holder idiom (lazy and thread-safe through class initialization).
- If you show double-checked locking, the instance field must be volatile; without it another thread can see a partially constructed object.
- State the cost of Singleton: hidden global state and hard-to-mock dependencies. In practice I let a DI container manage one shared instance (Spring beans are singleton-scoped by default) and inject it.
Follow-up
- Why does double-checked locking need volatile, and what can go wrong without it?
- How would you unit test a class that calls a hand-written Singleton?
- What is the difference between a Facade and an Adapter?
Explain the difference between TCP and UDP and when you would choose one over the other.
Medium · Technical Foundations & Programming
Approach
- TCP is connection-oriented: a three-way handshake (SYN, SYN-ACK, ACK), then a reliable, ordered byte stream with acknowledgements, retransmission, flow control through the receive window, and congestion control.
- UDP is connectionless: independent datagrams with an 8-byte header, no ordering, no retransmission and no congestion control; message boundaries are preserved and it supports broadcast and multicast.
- Choose TCP when every byte must arrive in order: HTTP/1.1 and HTTP/2, database connections, file transfer, most service-to-service APIs.
- Choose UDP when a late packet is worthless or the application handles loss itself: voice and video, online games, most DNS queries, and QUIC, which HTTP/3 runs on and which adds reliability and encryption in user space.
- Mention the trade-off: TCP's in-order delivery causes head-of-line blocking after a loss, which is one reason QUIC uses independent streams over UDP.
Follow-up
- What does TCP do when a segment is lost (retransmission timeout, fast retransmit after three duplicate ACKs, congestion window reduction)?
- When does DNS fall back to TCP?
- How would you add reliability on top of UDP for your own protocol?
What are the primary differences between an Interface and an Abstract Class?
Medium · Technical Foundations & Programming
Approach
- A Java class can implement many interfaces but extend only one class, so interfaces describe capabilities (Comparable, Runnable) and abstract classes describe a shared base.
- Interfaces carry no instance state: their fields are implicitly public static final. Abstract classes can have instance fields, constructors, and protected or private members.
- Since Java 8 interfaces can have default and static methods, and since Java 9 private methods, so the gap is now mainly state and constructors, not behaviour.
- If two interfaces supply the same default method, the implementing class must override it and can delegate with InterfaceName.super.method().
- Rule of thumb I use: an interface for the contract callers depend on, an abstract class when subclasses share state or a template method that fixes the order of steps.
Follow-up
- How is a conflict between two default methods resolved?
- What is a functional interface, and how does it relate to lambdas?
- What do sealed interfaces (Java 17) add?
How would you design a scalable system component to handle high-traffic retail data?
Medium · System Design & Problem Solving
Approach
- Pin the workload first: which retail data (product catalogue reads, price or stock updates, order events), the read/write ratio, peak versus average load, and the freshness each consumer needs; do a quick back-of-envelope estimate of requests per second and storage.
- Read path: stateless services behind a load balancer that scale horizontally, a cache such as Redis in front of the database with a TTL or event-driven invalidation, and read replicas for heavy queries.
- Write path: put a durable log or queue (e.g. Kafka) between producers and the database to absorb bursts; partition by a key such as SKU or store id so updates for one key stay ordered; make consumers idempotent with a dedup key because delivery is at-least-once.
- Call out hot keys: a promoted product can concentrate traffic on one partition or cache entry; mitigate with replicated cache entries, request coalescing or splitting that key.
- State consistency per data type: displayed stock can be eventually consistent, but reserving the last unit needs a conditional update or optimistic locking (version column). Add metrics on consumer lag, cache hit rate and p99 latency.
Follow-up
- A single promotion sends 100 times normal traffic to one product: what breaks first and what do you change?
- The consumer falls hours behind the queue: how do you detect it and catch up?
- How do you avoid double-applying a stock update when a message is redelivered?
Given a specific business requirement, how do you break down a complex problem into manageable technical tasks
Medium · System Design & Problem Solving
Given a specific business requirement, how do you break down a complex problem into manageable technical tasks?
Approach
- Start by restating the requirement as an outcome with acceptance criteria: who uses it, what they can do afterwards, and how you know it works; ask about non-functional limits (volume, latency, security) and which existing systems it touches.
- Identify the unknowns and turn the riskiest into a short spike (e.g. whether an upstream system exposes the data you need) before estimating the rest.
- Split into vertical slices that each deliver something testable end to end (data access, API, UI, monitoring for one narrow case) rather than horizontal layers that only work when all are finished.
- Define interfaces and data contracts between slices early so work can run in parallel, then order tasks by dependency and risk; write each as a user story small enough to estimate (INVEST is a useful check).
- Attach a definition of done to every task: tests, code review, deployment and the metric or log that proves it works in production.
Follow-up
- The requirement changes halfway through the sprint: what do you do with the tasks already in progress?
- A task depends on another team's API that does not exist yet: how do you keep moving?
- How do you estimate a task you have never done before?
How do you ensure your code is optimized for performance and maintainability?
Medium · System Design & Problem Solving
Approach
- Performance: measure before changing anything. Profile with Java Flight Recorder or async-profiler, benchmark hot code with JMH (it handles JIT warm-up that naive timing loops get wrong), and fix a target such as a p99 latency.
- Fix the biggest cost first: algorithmic complexity (a nested loop lookup at O(n^2) becomes O(n) with a HashMap), N+1 database queries replaced by a join or batch fetch, missing indexes, and excess object allocation that drives GC pressure.
- For a slow SQL query, read the plan (EXPLAIN ANALYZE in PostgreSQL), index the filter and join columns, avoid wrapping indexed columns in functions, and select only the columns you need.
- Maintainability: small cohesive classes with clear names, unit and integration tests that pin behaviour, code review, and static analysis and tests running in CI on every change.
- State the trade-off: write the clear version first and optimise only hot paths with evidence; when an optimisation makes code harder to read, isolate it and record why with the benchmark result.
Follow-up
- How would you optimize a slow-running SQL query, step by step?
- When have you accepted less readable code for performance, and how did you contain it?
- How do you stop a performance regression from reaching production?
Explain the OSI Model and how you troubleshoot network-related issues in a distributed system.
Medium · System Design & Problem Solving
Approach
- List the seven layers bottom-up with an example each: Physical (cables, radio), Data Link (Ethernet frames, MAC), Network (IP, routing), Transport (TCP/UDP ports), Session, Presentation (encoding, TLS is often placed here), Application (HTTP, DNS); note that the TCP/IP model folds the top three into one.
- Troubleshoot by narrowing layer by layer: name resolution (dig or nslookup), reachability (ping, though ICMP may be blocked), path (traceroute or mtr), port (nc -vz host port), TLS (openssl s_client -connect host:443), then the request itself (curl -v).
- Read the failure mode: connection refused means the host answered but nothing listens on the port; a timeout usually means packets are dropped (firewall, security group, routing); a reset mid-request points at a proxy, load balancer or a crashing process.
- In a distributed system, first check what changed (deploy, firewall rule, DNS record, expired certificate), then follow one request through logs with a correlation id, and use tcpdump or Wireshark only once the failing hop is known.
- For intermittent errors, check whether they cluster on one instance behind the load balancer, on stale DNS caches, or on exhausted connection pools or ephemeral ports.
Follow-up
- What is the difference between a layer 4 and a layer 7 load balancer, and which errors does each produce?
- One percent of calls between two services time out: what do you check first?
- How would an MTU mismatch show up, and how would you confirm it?
Suggested practice checklist
The plan follows the three reported stages: aptitude practice first, then Java, design, networking and SQL fundamentals for the technical conversations, then stories for the managerial conversations. Candidates report 2-3 weeks of preparation as typical; this plan is the compressed version for one week.
Day 1 — Map the loop and start aptitude practice
- Write the three reported stages and, for each, the question types in this guide that belong to it.
- Do timed sets of number sequences, pattern puzzles and table-reading questions, and note which rule types slow you down.
- List every project on your resume and mark the two you could explain in most depth.
Deliverable: A one-page loop map, a log of your timed aptitude scores by puzzle type, and your two chosen projects.
Day 2 — Java and OOP fundamentals
- Write and say aloud a 2-minute explanation of the four OOP principles, each with a Java example from your own work.
- Write a table of interface versus abstract class, covering default methods, state, multiple inheritance and a case for each.
- Write one stream pipeline using groupingBy and toMap with a merge function, and one generic method using bounded types and a wildcard.
Deliverable: A spoken OOP answer, an interface versus abstract class table, and a compiled stream plus generics example.
Day 3 — Design patterns and code quality
- Implement a Facade over two or three service classes and describe what it hides and what it cannot.
- Implement a thread-safe Singleton in two ways (enum and holder idiom), and write why you would use dependency injection instead.
- Take one method of yours that is slow or hard to read, measure it, refactor it, and write the before and after reasoning.
Deliverable: A Facade example, two Singleton implementations with notes, and a measured refactor write-up.
Day 4 — Networking and troubleshooting
- Write a table of the OSI layers with one protocol and one diagnostic tool per layer.
- Write a TCP versus UDP comparison covering reliability, ordering, overhead and two real uses of each.
- Write a troubleshooting sequence for a service that times out between two microservices, including what each check rules out.
Deliverable: An OSI table, a TCP versus UDP answer and a written troubleshooting runbook.
Day 5 — Algorithms and SQL
- Solve the event-batch and projection-diff coding practice questions, writing time and space complexity for each.
- Write a short checklist for tuning a slow SQL query: plan, index, filter shape, join fan-out and row counts.
Deliverable: Two solved coding problems with complexity notes and a SQL tuning checklist applied to one query.
Day 6 — System design and requirement breakdown
- Outline a component that ingests high-traffic retail data: read path, write path, partitioning, caching, consistency and failure handling.
- Take one business requirement and break it into ordered technical tasks with dependencies and risks.
- Prepare a 5-minute architecture walkthrough of your most recent project, covering tests, deployment and CI/CD.
Deliverable: A one-page design outline, a task breakdown for one requirement and an architecture walkthrough you can deliver aloud.
Day 7 — Managerial conversations
- Write four stories using the situation, decision, result and lesson structure, one for each reported behavioral prompt.
- Write a motivation answer for Colruyt Group that names one business area and one project of yours.
- Say all four stories aloud, record them and cut anything that is background rather than decision.
Deliverable: Four written stories, a specific motivation answer and a recorded rehearsal.
Managerial conversation preparation
Candidates describe the managerial conversations as a check on team fit, company fit and career goals. The reported prompts ask for a technical disagreement, your motivation for joining, learning a tool under a deadline and managing priorities. Prepare each as a real story from your work with a decision, a trade-off and a result, and explain the technical parts in plain language.
- Walk me through the architecture of your most recent project.
How do you handle Streams and Generics in modern Java development?
Medium · Technical Foundations & Programming
Approach
- Streams: explain the pipeline as source, lazy intermediate operations (filter, map, flatMap, sorted) and one terminal operation (collect, reduce, forEach). Nothing runs until the terminal operation; a stream cannot be reused and throws IllegalStateException if you try.
- Show concrete usage: Collectors.groupingBy with a downstream counting() or summingInt(), toMap with a merge function so duplicate keys do not throw, and IntStream or mapToInt to avoid boxing in numeric work.
- Keep lambdas free of side effects and shared mutable state. Say when you prefer a plain loop (early exit, checked exceptions, complex state) and that parallel streams only help for large, CPU-bound, stateless work, since they share the common ForkJoinPool.
- Generics: they give compile-time type safety, but type erasure removes the type arguments at runtime, so you cannot do new T(), instanceof List<String> or create generic arrays. Use bounded types (<T extends Comparable<T>>) and generic methods.
- Wildcards by PECS: use ? extends T when a structure only produces values you read, and ? super T when it only consumes values you add. Avoid raw types because they let heap pollution and ClassCastException through.
Follow-up
- What is the difference between map and flatMap, and when does flatMap fix a Stream<List<T>>?
- Why can you not add an element to a List<? extends Number>?
- When would you not use a parallel stream, and what makes it slower or wrong?
Describe a time you faced a significant technical disagreement with a teammate; how did you resolve it?
Medium · Behavioral & Situational
Approach
- Pick a real disagreement about a technical choice (a data model, a framework, a testing approach) where the outcome mattered to the project, not a style quarrel.
- State the other person's position fairly and in their best form, then your own, in two or three sentences total. A story that makes the teammate look foolish signals poor collaboration.
- Spend most of the time on how it was resolved: what evidence you gathered (a prototype, a benchmark, a failure case, an architecture decision note), who else you consulted, and what criteria you both agreed on first.
- Give the result and what it cost, including the case where you changed your mind or the outcome was a compromise, and close with the working relationship afterwards.
Follow-up
- What if the teammate still disagreed after the evidence?
- Tell me about a time you turned out to be the one who was wrong.
- How do you handle a disagreement when a manager has already decided?
Why are you interested in joining Colruyt Group, and how do your career goals align with our mission?
Medium · Behavioral & Situational
Approach
- Build the answer from three parts: something specific you learned about the group (candidates describe retail, supply chain logistics, e-commerce platforms and internal operational tools), a link to your own experience, and a career direction the Software Engineer role serves.
- Choose one business area and say what engineering problem it implies, for example integration between systems, backend services or cloud work. Check your facts on the company's own pages first and do not claim a mission you cannot cite.
- Connect your goals to what the role lists: Java, backend or integration work, and possibly Azure or AWS. Say what you want to learn there, not only what you can give.
- Avoid answers that would fit any employer (large, stable, good reputation). Name a project of yours that shows you care about software for business operations.
Follow-up
- Which of the group's business areas interests you most, and why?
- What would you want to learn in your first year in this role?
- How do you see your career developing over the next few years?
Tell us about a project where you had to learn a new technology or tool under a tight deadline.
Medium · Behavioral & Situational
Approach
- Choose a project where the new tool was on the critical path of a delivery, and state the deadline and the tool in the first two sentences.
- Describe your learning method: read the official getting-started material, build the smallest end-to-end spike, learn only what the first release needed, and ask someone with experience when you were blocked.
- Show how you protected quality while learning: tests around the new code, a code review from someone who knew the tool, and a rollback plan or feature flag if the risk was high.
- Report the result honestly, including what you got wrong or left rough, and what you did afterwards to close the gap (documentation, refactor, follow-up learning).
Follow-up
- How did you decide what not to learn in that time?
- How did you verify your work was correct in a tool you did not know yet?
- What would you do differently if the same situation came up again?
How do you manage your time when balancing multiple technical priorities?
Medium · Behavioral & Situational
Approach
- Describe a concrete method: list every commitment, estimate each, and rank by deadline, business impact and who is blocked on you. Name a tool you actually use, such as a board or a written daily plan.
- Use a real case where two tasks collided, for example a production issue arriving during a feature deadline. State what you moved, what you dropped and who you told.
- Show that you negotiate scope with the product owner or manager early, with the trade-off stated (do A by Friday, B moves to next sprint), rather than silently working longer.
- Cover focus protection: timeboxed blocks, batching reviews and messages, and keeping unplanned work visible so planning stays honest. Finish with the outcome.
Follow-up
- Two stakeholders each say their task is the top priority. What do you do?
- How do you handle a deadline you realise you will miss?
- How do you handle a production incident in the middle of planned work?