cswork / libraryOpen practice workspace

Interview guides · AKKODIS

AKKODIS Software Engineer Interview Guide

AKKODIS Software Engineer interview guide: the five reported rounds, OOP, algorithm, embedded and client-interview questions, plus a 7-day prep plan.

The 60-second brief

Candidates describe AKKODIS as a Smart Industry company that places software engineers on engineering projects in sectors such as automotive, aerospace and defense. Engineers are assigned either to internal initiatives or to client engineering environments. Reported project examples include flight warning logic and battery management software. Reports mention work from embedded and control software to web, test automation and data platforms. Day to day, the reports describe writing and reviewing code, building unit and integration tests, taking part in design reviews and working with systems, hardware and QA colleagues.

This guide is for candidates interviewing for a Software Engineer position at AKKODIS, whether the project is embedded, enterprise or test-automation work. It covers the five reported stages, the reported questions in four groups (object-oriented fundamentals, data structures and algorithms, embedded and real-time engineering, and consulting-style behavioral prompts), and a seven-day plan. The role's requirements name at least one of C, C++, Java, Python or C#, so pick the one you code in best and use it throughout.

Candidates report five stages over roughly 4-6 weeks: an HR screening call, a technical evaluation, an online or live coding assessment, a final interview with the end client, and an offer discussion. Which stages apply depends on the position and the client.

Focus areas

  • Problem Solving / Coding Challenges
  • Dynamic Programming (1D DP)
  • Object-Oriented Programming (OOP)

Overview

The reported questions fall into four groups, and the weight you give each depends on the project you are being matched to. Object-oriented fundamentals cover polymorphism, abstract classes versus interfaces, dependency injection, memory management and the software development lifecycle in a regulated setting. The algorithm group covers maximum subarray sum, 1D dynamic programming, hash table internals, tree and graph traversal for system dependencies, and a story about cutting a quadratic routine down. The embedded group covers RTOS determinism, communication buses (CAN, Ethernet, LIN, FlexRay), safety-critical risk analysis, automated testing and CI, and model-in-the-loop testing. The last group is consulting-style behavioral prompts.

Candidates say the domain questions in the embedded group depend on the client or project, for example automotive, defense or aerospace. Ask the recruiter in the first call which kind of project you are being considered for, then decide how many of your seven days go to the RTOS and bus material. Nobody can be strong in every area, so be honest about the buses and standards you have actually used and prepare to explain the ones you have only studied.

The strongest reported preparation signal is the resume. Candidates describe technical deep-dives that start from your thesis, capstone or previous assignments, and report that managers look at your trade-off reasoning. For two projects, write down the problem, the constraints, the alternatives you rejected, the test or verification approach and what you would change. Those notes feed the technical evaluation, the client interview and nearly every behavioral answer.

Because many placements put you in front of a client's engineering lead, practise explaining trade-offs in plain language, and keep a short list of questions about the project stack, the client domain and the team. Also settle remote versus on-site expectations early: candidates report that embedded, automotive and aerospace work often requires access to test benches or client sites.

The AKKODIS interview process

These are the five stages candidates describe, in the order they report them. Not every candidate sees every stage, and the coding stage is described as possible rather than guaranteed.

HR Screening Call

Candidates describe this first call as a conversation about your background, the kind of projects you want, how you communicate, and practical matters such as location flexibility, availability and compensation expectations. Recruiters use your resume to match you to open projects, so the call is mostly about whether your profile fits a vacancy. Treat it as a short pitch: your core language, the domains you have worked in and the project types you want next.

What to demonstrate

  • Your background and the projects on your resume
  • Which project types you prefer and whether they match open vacancies
  • Spoken communication
  • Logistics: location, availability and compensation expectations

How to prepare

  • Write a one-paragraph pitch naming your main language (C, C++, Java, Python or C#), your domains and two projects you can describe in depth.
  • Decide your location constraints, availability and compensation expectations before the call, and ask which type of project (embedded, enterprise, test automation) is on the table.
  • Ask the recruiter what the later stages will contain, including whether a coding assessment is part of the process for this position.

Technical Evaluation

Candidates describe this stage as a technical and business manager evaluation covering core software concepts and your previous engineering work. Reports say your resume is the baseline for technical deep-dives, including a master's thesis, capstone or earlier assignments. The fundamentals reported alongside it are OOP and polymorphism, abstract classes versus interfaces, dependency injection, memory management in lower-level or real-time settings, and the software development lifecycle in a regulated environment. Prepare a project walk-through that always explains why you made each choice.

What to demonstrate

  • Command of software fundamentals such as OOP, memory management and the lifecycle you follow
  • How well you explain past engineering work and the trade-offs behind it
  • Fit between your skills and the project types on offer

How to prepare

  • Build a fact sheet for two projects: problem, constraints, design alternatives, how you tested it, and what you would change.
  • Practise the fundamentals aloud in your main language: polymorphism with a real hierarchy from your work, abstract class versus interface, and constructor injection with a fake in a unit test.
  • Prepare a structured answer for debugging a memory leak or segmentation fault without relying only on an automated profiler.

Online Coding Assessment

The reports say an online coding assessment or a live coding exercise may be included, depending on the position and location, covering algorithms, OOP concepts and domain-specific logic. The reported examples are a 1D dynamic programming problem with a space optimization and a function that detects cycle dependencies in system initialization steps. Practise writing runnable code in your chosen language, stating complexity out loud and testing edge cases before you call it done.

What to demonstrate

  • Working code for arrays, hash tables, trees, graphs and 1D dynamic programming
  • Correct time and space complexity for your own solution
  • How clearly you explain your reasoning while you code

How to prepare

  • Solve maximum subarray sum with a single pass, then a minimum path cost problem with a rolling variable instead of a full table.
  • Write a cycle check for a dependency graph twice, once with depth-first search colouring and once with a topological sort using in-degree counts.
  • Implement a small hash table with chaining and explain resizing, load factor and worst-case lookup.
  • Do at least one exercise in an online editor without autocomplete, since an online assessment may not offer it.

Final Client Interview

For consulting and client-embedded positions, candidates report a final interview with the end client's engineering lead or project manager. The reports describe its purpose as confirming technical alignment between your skills and the client's operating environment. Prepare to explain your projects and trade-offs to someone who knows the client's system better than you do.

What to demonstrate

  • Technical alignment between your experience and the client's environment
  • How you present engineering trade-offs and verification choices from your past projects
  • Fit with a different organisation and way of working

How to prepare

  • Rehearse a three-part explanation of a past project (context, the decision with alternatives, the measured outcome) that a non-specialist could follow.
  • As advice for an embedded placement, review RTOS determinism, priority inversion, interrupt handling, CAN, LIN, FlexRay and Ethernet differences, and what model-in-the-loop testing catches early.
  • Write questions about the project stack, the client domain, the team structure and remote versus on-site expectations.

Offer Discussion

Candidates describe the last stage as a discussion with the business manager about the contract package and the onboarding timeline. As advice, treat it as a conversation rather than a technical test: be clear on what you want and get the details in writing. If remote or on-site expectations are still open, raise them here as well; the reports say to clarify them with the manager.

What to demonstrate

  • Contract package details
  • Onboarding timeline
  • Your questions about the role and next steps

How to prepare

  • Write down your priorities beforehand: start date, location or on-site requirements, project type and the terms you need confirmed.
  • Ask for the package and the onboarding timeline in writing, and confirm that remote or on-site expectations match what you discussed earlier.

Where candidates lose points

Reciting OOP definitions without a design from your own work

For polymorphism, abstract classes versus interfaces and dependency injection, bring one concrete hierarchy or module from a project. Say what the abstraction let you swap, and show how injecting a fake made a unit test possible.

Answering memory management with "use smart pointers" or "the garbage collector handles it"

Name the language's ownership model, stack versus heap, and where leaks come from. For real-time code, add allocation only at start-up or from fixed pools. Give a debugging sequence for a leak or segmentation fault that does not rely only on a profiler.

Overstating bus and standards experience such as CAN, LIN, FlexRay, ISO 26262 or DO-178C

State which buses or standards you used and what you did with them. For the rest, explain the difference you understand (for example how CAN arbitration and frame IDs work) and say plainly that your experience is study, not production.

Giving the maximum subarray or 1D dynamic programming solution without complexity or edge cases

State the recurrence, the base case and the time and space cost, then reduce space with rolling variables. Test the all-negative array, a single element, an empty input and ties before you say you are finished.

Treating the final client interview as another quiz and arriving with no questions

Prepare a plain-language account of one project's trade-offs and a short list of questions on the stack, the client domain, team structure and on-site or remote requirements. These are all worth asking.

Questions & practice

How do you handle memory management and prevent memory leaks in lower-level or real-time programming environme

Medium · Object-Oriented Design & Core Software F

How do you handle memory management and prevent memory leaks in lower-level or real-time programming environments?

Approach

  1. Lead with ownership: every allocation has exactly one owner that frees it. In C++ that means RAII (std::unique_ptr for single ownership, std::shared_ptr only when ownership is truly shared, never raw new/delete in application code); shared_ptr cycles still leak, so break them with weak_ptr.
  2. For real-time code, avoid heap allocation after initialisation: malloc/free have unbounded timing and fragment memory over long runs. Use static allocation, fixed-size block pools or per-task arenas sized at start-up; MISRA C:2012 Rule 21.3 forbids the stdlib allocation functions for this reason.
  3. In C, check every allocation's return value and use a single cleanup path per function (goto cleanup) so error branches cannot skip a free; document who frees each pointer at the API boundary.
  4. Detection on the host: AddressSanitizer/LeakSanitizer or Valgrind memcheck in the unit-test build. On target: wrap the allocator to count allocations and frees per call site, track heap and stack high-water marks (FreeRTOS uxTaskGetStackHighWaterMark), and watch the trend over long soak runs.
  5. In garbage-collected languages say what a leak really is there: objects kept reachable by static collections, caches without eviction or listeners that are never unregistered.

Follow-up

  • How would you find a leak or a segmentation fault in a large codebase without relying on an automated profiler?
  • What is memory fragmentation, and how does a fixed-size pool avoid it?
  • How do you detect a stack overflow on a microcontroller with no MMU?

Given an array of integers, how would you find the maximum subarray sum in optimal time complexity?

Medium · Data Structures & Algorithmic Logic

Approach

  1. Clarify first: can the subarray be empty, and can all values be negative? The answer changes the return value for an all-negative array.
  2. Name the baseline: all start and end pairs with a running sum is O(n^2); recomputing each sum from scratch is O(n^3).
  3. Give Kadane's algorithm as a 1D DP: cur is the best sum of a subarray ending at index i, so cur = max(a[i], cur + a[i]) and best = max(best, cur). O(n) time, O(1) extra space.
  4. Handle the edge cases: initialise cur and best to a[0], not 0, so an all-negative array returns its largest element; accumulate in a 64-bit type to avoid overflow; to return the indices, record a new start whenever cur restarts at a[i].
  5. Mention the divide-and-conquer O(n log n) alternative (best left, best right or best crossing the midpoint) and why Kadane beats it.

Follow-up

  • How does the answer change for a circular array?
  • Find the maximum product subarray instead: what extra state do you need, and why?
  • Extend it to the maximum-sum rectangle in a 2D matrix: what is the complexity?

Explain how you would approach solving a 1D dynamic programming problem, such as calculating minimum path cost

Medium · Data Structures & Algorithmic Logic

Explain how you would approach solving a 1D dynamic programming problem, such as calculating minimum path costs or resource allocation.

Approach

  1. Define the state in words before writing code, for example dp[i] = minimum cost to reach step i, then the recurrence (for minimum-cost stairs: dp[i] = cost[i] + min(dp[i-1], dp[i-2])) and the base cases.
  2. Choose top-down memoisation or bottom-up iteration; bottom-up avoids recursion depth limits. Complexity is states times transitions: O(n) with a constant number of transitions, O(n*k) when each state looks at k options (coin change over k coins).
  3. Optimise space: when the recurrence only reads the last k entries, keep k variables instead of the array (two variables for stairs, giving O(1) space).
  4. For resource allocation, use the 1D knapsack array dp[c] over capacity: iterate c downward for 0/1 knapsack so each item is used once, and upward for the unbounded version.
  5. Cover the edge cases: n = 0 or 1, unreachable states (initialise with an infinity sentinel and check it before returning), and path reconstruction, which needs a parent array and so conflicts with the space optimisation.

Follow-up

  • How would you return the actual path or the chosen items, not just the cost?
  • Why does the loop direction over capacity decide whether an item can be reused?
  • Why does greedy fail for coin change with coins {1, 3, 4} and amount 6, and how does the DP get it right?

Describe the internal workings of a Hash Table, including collision resolution strategies and time complexity

Medium · Data Structures & Algorithmic Logic

Describe the internal workings of a Hash Table, including collision resolution strategies and time complexity trade-offs.

Approach

  1. Explain the core: a hash function maps a key to a bucket index (hash mod capacity, or a bit mask when capacity is a power of two); equal keys must hash equally, which is why Java requires equals and hashCode to agree.
  2. Separate chaining: each bucket holds a list of entries. Java 8's HashMap turns a bucket into a red-black tree once it holds 8 entries and the table has at least 64 buckets, bounding worst-case lookup at O(log n).
  3. Open addressing: entries live in the array and collisions probe further, linearly (cache-friendly but clusters), quadratically or by double hashing; deletion needs tombstones, and Robin Hood hashing evens out probe lengths. CPython's dict uses open addressing.
  4. Load factor and resizing: Java's default load factor is 0.75 and capacity doubles. A resize rehashes everything in O(n), but inserts stay amortised O(1). Average lookup is O(1); the worst case is O(n) when keys collide. Two concrete defences: CPython randomises str hashes with SipHash, seeded per process, so an attacker cannot predict collisions; Java does not randomise and instead relies on treeified buckets, which keep the worst case at O(log n) per bucket.
  5. Add the real-time angle: a resize is a latency spike, so preallocate capacity or rehash incrementally when deadlines matter.

Follow-up

  • Implement an LRU cache: which structures do you combine, and what does each operation cost?
  • Why does a power-of-two table need a well-mixed hash, and what goes wrong without one?
  • What happens if you mutate a key's fields after inserting it into the map?

How do you implement and traverse tree and graph data structures when simulating system dependencies?

Medium · Data Structures & Algorithmic Logic

Approach

  1. Choose the representation: an adjacency list (a map from node to its dependencies) costs O(V + E) space and suits sparse dependency graphs; a matrix only pays off for dense graphs. A tree is the special case with one parent per node and no cycles.
  2. Traversal: DFS with an explicit stack (avoids recursion limits on deep chains and small embedded stacks) or BFS with a queue for level order; both run in O(V + E) with a visited set.
  3. For start-up order, use topological sort. Kahn's algorithm counts in-degrees and repeatedly emits nodes with in-degree zero; if fewer than V nodes come out, there is a cycle. The DFS alternative colours nodes white, grey and black, and an edge to a grey node is a cycle.
  4. Make the output useful: report the actual cycle path (keep parent pointers during DFS), and use Kahn's levels to show which components can start in parallel.
  5. Check the edge cases: disconnected components, self-loops, duplicate edges and dependencies on a node that was never declared.

Follow-up

  • Detect a cycle and print the exact components that form it.
  • With a start-up time on each component, how do you find the minimum total boot time (longest path in a DAG)?
  • How would you handle a dependency graph too large to load into memory at once?

Walk us through a scenario where you optimized a snippet of inefficient code from O(n2)O(n^2) to O(nlog⁡n)O(n \log n) or

Medium · Data Structures & Algorithmic Logic

Walk us through a scenario where you optimized a snippet of inefficient code from O(n2)O(n^2) to O(nlog⁡n)O(n \log n) or O(n)O(n).

Approach

  1. Pick a real case and quantify it: the input size, the measured time before, where the profiler or timing showed the hotspot, and the time after.
  2. Name the pattern you used. A nested loop doing membership lookups becomes a hash set or map (expected O(n)); pair or duplicate finding becomes sort plus two pointers (O(n log n)); repeated range sums become prefix sums; repeated front inserts or removals become a deque.
  3. State the trade-off you accepted: a hash structure costs O(n) extra memory and has an O(n) worst case; an in-place sort keeps memory flat but mutates or copies the input; for small n the constant factors can make the O(n^2) version faster.
  4. Show how you proved it correct: kept the old implementation as an oracle, compared outputs on randomised and edge-case inputs, and benchmarked at realistic sizes rather than toy inputs.

Follow-up

  • How did you confirm the algorithm was the bottleneck and not I/O or allocation?
  • What would you do if the memory budget ruled out the hash-based version?
  • Below what input size would you keep the quadratic version, and why?

How do you structure your work when project requirements are ambiguous or rapidly changing?

Medium · Behavioral & Client Consulting Alignment

Approach

  1. Turn ambiguity into a written list of open questions and explicit assumptions, confirm them with the stakeholder who owns the requirement, and record each decision where the team can find it.
  2. Deliver a thin end-to-end slice early so the client reacts to working software instead of a document, then build out the parts whose requirements have settled first.
  3. Isolate the volatile parts behind an interface or configuration so a likely change touches one module, without building a speculative framework for changes nobody has asked for.
  4. Treat each change as a change: estimate its impact on schedule, design and tests, agree the trade-off with the stakeholder, and in a regulated project update the requirement, its trace links and the affected tests before coding.
  5. Anchor the answer in one real story with its outcome. Two answers fall flat: coding before anything is clarified, or waiting for perfect requirements.

Follow-up

  • Tell me about a time a requirement changed late in a project: what did you change, and what did you push back on?
  • How do you decide what to build when the client cannot answer your questions in time?
  • How do you keep tests and documentation in step when requirements change often?

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 = 1ANDowneruserid=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?

Hold a per-tenant active cap against concurrent creates

Hard · write skew · isolation levels · constraints

A tenant on the standard plan may hold at most 50 resources with status='active'. The create handler runs SELECT count(*) FROM resource WHERE tenant_id = $1 AND status = 'active', compares to 50, then inserts. Two creates arrive 3 ms apart on different instances and the tenant lands at 51. Name the anomaly, say whether PostgreSQL 16 READ COMMITTED or REPEATABLE READ prevents it and why, then give an implementation that holds the cap at READ COMMITTED with the exact statements. Finally, say what changes when the cap is 'at most one running export per tenant' on job_run.

Approach

  1. Name it: write skew. The two transactions read an overlapping set and write disjoint rows, so there is no row-level conflict for the engine to detect and each commit is individually legal.
  2. Rule out the levels precisely. READ COMMITTED takes a fresh snapshot per statement and takes no lock on the counted rows, so both see 49. PostgreSQL's REPEATABLE READ is snapshot isolation: it removes non-repeatable reads and phantoms within the snapshot but still admits write skew, because the anomaly is not a re-read of a changed row, it is a read of a set that a concurrent transaction invalidates. Only SERIALIZABLE closes it, by tracking the read dependency and aborting one transaction with SQLSTATE 40001 — a guarantee that exists only if the application re-runs the whole transaction from the read.
  3. Convert the set predicate into a single-row conflict: keep tenant.active_resource_count and run UPDATE tenant SET active_resource_count = active_resource_count + 1 WHERE tenant_id = $1 AND active_resource_count < 50 in the same transaction as the INSERT. Zero affected rows is the cap, returned as 409. The row lock serialises the decision at any isolation level, and contention is bounded to one tenant's row — which is also the fair-scheduling unit, unlike a global counter that would convoy every tenant behind one row.
  4. State the cost you just took on: a counter is a second source of truth that can drift, so every path that changes status must adjust it inside the same transaction, and a periodic reconciliation has to exist, with resource_revision as the authority for what the count should have been.

Follow-up

  • A resource moves from archived back to active. Which statements change, and what breaks if the counter update and the status change land in different transactions?
  • The cap becomes plan-dependent and a plan can change mid-month. Where does the number 50 live, and who reads it?

Explain the primary principles of Object-Oriented Programming (OOP) and how you apply polymorphism in large-sc

Medium · Object-Oriented Design & Core Software F

Explain the primary principles of Object-Oriented Programming (OOP) and how you apply polymorphism in large-scale system design.

Approach

  1. Name the four principles and what each buys: encapsulation keeps an invariant behind methods, abstraction exposes only the operations a caller needs, inheritance reuses both the base class's interface and its implementation, and polymorphism lets one call site work with many concrete types.
  2. Separate the two kinds of polymorphism: runtime (virtual functions in C++, overridden methods in Java, dispatched through a vtable or equivalent) and compile-time (overloading, templates or generics).
  3. Give a system example: callers depend on a SensorSource interface with a CAN-backed and a simulated implementation, so adding a new source means adding a class rather than editing every switch on a type field (open/closed principle).
  4. State the trade-offs: inheriting the implementation couples a subclass to its base, which is why deep hierarchies are risky and composition is favoured. A virtual call is an indirect call that usually blocks inlining, which matters in hot loops on small targets; there, static polymorphism (templates, CRTP) removes the indirection.
  5. Mention the C++ trap: a polymorphic base class needs a virtual destructor, because deleting a derived object through a base pointer without one is undefined behaviour.

Follow-up

  • When would you choose templates over virtual functions, and what does each cost in binary size and flexibility?
  • What is the Liskov substitution principle, and can you give an example of a subclass that breaks it?
  • How does a vtable call actually work, and what does it cost compared with a direct call?

What is the difference between abstract classes and interfaces, and when would you choose one over the other?

Medium · Object-Oriented Design & Core Software F

Approach

  1. Start with Java, where the difference is explicit: an abstract class can hold instance fields, constructors and non-public members, and a class can extend only one; an interface can be implemented many times over, its fields are implicitly public static final, and since Java 8 it can carry default and static methods (private methods since Java 9).
  2. Map it to the other languages the role lists: C++ has no interface keyword, so an interface is a class of pure virtual functions plus a virtual destructor; Python uses abc.ABC with @abstractmethod, or typing.Protocol for structural typing; C# has interfaces with default members since C# 8.
  3. Give the decision rule: an interface for a capability shared by unrelated types (Comparable, a Logger, a bus driver contract) or when a type plays several roles; an abstract class when closely related types share state and a fixed skeleton (template method pattern).
  4. Name the evolution trade-off: adding a method to an interface breaks every implementor unless you give it a default, while an abstract class can gain a concrete method safely but couples its subclasses to one hierarchy.

Follow-up

  • Two interfaces supply the same default method: what does Java make you do, and how do you call one of them explicitly?
  • How would you express the same design in C++, and what does multiple inheritance add or risk there?
  • Show the template method pattern with an abstract class and explain why an interface alone would not enforce the step order.

Can you explain the software development lifecycle (SDLC) stages you follow when delivering features in a regu

Medium · Object-Oriented Design & Core Software F

Can you explain the software development lifecycle (SDLC) stages you follow when delivering features in a regulated engineering environment?

Approach

  1. Describe the V-model: requirements, system and architecture design, detailed design and implementation on the left, each paired with its verification level on the right (unit, integration, system and acceptance testing).
  2. Make traceability the spine: every requirement has an identifier and links forward to design elements, code and test cases and back again, so a reviewer can see each requirement is tested and each piece of code exists for a requirement.
  3. Name the standards the role lists and what they impose: ISO 26262 for automotive (ASIL A to D) and DO-178C for airborne software (levels A to E), where level A requires MC/DC structural coverage and more objectives require independent verification.
  4. Cover change control: configuration management with baselines, code review records, impact analysis before a requirement changes, and problem reports tracked to closure.
  5. Close with how agile fits: sprints can run inside the process, but each increment still produces the reviewed artifacts, and illustrate with one feature you actually delivered this way.

Follow-up

  • What is MC/DC coverage, and how is it stronger than branch coverage?
  • A requirement changes two weeks before a release: what do you update, and in what order?
  • How do you show an auditor that a given requirement is fully tested?

Explain the concept of dependency injection and how it impacts unit testing and code maintainability.

Medium · Object-Oriented Design & Core Software F

Approach

  1. Define it: a class receives its collaborators from outside (constructor, setter or method parameter) instead of constructing them itself, and depends on an abstraction rather than a concrete class (dependency inversion).
  2. Tie it to unit testing: inject a fake clock, an in-memory repository or a simulated bus driver, so tests are fast, deterministic and run without hardware or a network.
  3. Prefer constructor injection: dependencies are explicit, can be immutable and the object is never half-built; use setter injection only for optional collaborators. Wire everything in one composition root, by hand or with a container such as Spring, Guice or the .NET container.
  4. Give the maintainability effect and its costs: implementations swap without touching callers and hidden globals and singletons disappear, but there is more indirection, and a constructor with many parameters signals a class doing too much.
  5. Cover C and embedded code, where there is no container: inject through function-pointer tables, or substitute test doubles at link time.

Follow-up

  • How is dependency injection different from a service locator, and why is the locator often called an anti-pattern?
  • How would you unit-test code that reads the system time or a hardware register?
  • What is the difference between a mock, a stub and a fake, and when would you use each?

How do you address time-constraint requirements and determinism in real-time operating systems (RTOS)?

Medium · Domain & Systems Engineering (Embedded /

Approach

  1. Define determinism as a bounded worst case, not a fast average: classify deadlines as hard or soft, and measure or analyse the worst-case execution time (WCET) of each task.
  2. Scheduling: fixed-priority preemptive scheduling with rate-monotonic priorities (shorter period, higher priority). The Liu and Layland bound U <= n(2^(1/n) - 1), which tends to about 69%, is sufficient but not necessary; response-time analysis gives the exact test. EDF can schedule up to 100% utilisation on a single core.
  3. Priority inversion: a low-priority task holding a mutex blocks a high-priority one while a medium task runs. Fix it with priority inheritance or priority-ceiling mutexes; the 1997 Mars Pathfinder resets are the textbook case.
  4. Keep ISRs short: read the hardware, push to a queue or give a semaphore, and defer the processing to a task. Avoid heap allocation, unbounded loops and infinite blocking timeouts on time-critical paths.
  5. Verify timing: toggle GPIOs and measure with a logic analyser or trace tool, monitor stack high-water marks, and use a watchdog to catch missed deadlines in the field.

Follow-up

  • Walk through a priority inversion scenario step by step and how priority inheritance resolves it.
  • How would you measure or bound the WCET of a task on the target?
  • What goes in the interrupt handler and what goes in the task for a high-rate sensor input?

What protocols and communication buses (e.g., CAN, Ethernet, LIN, FlexRay) have you utilized in embedded softw

Medium · Domain & Systems Engineering (Embedded /

What protocols and communication buses (e.g., CAN, Ethernet, LIN, FlexRay) have you utilized in embedded software development?

Approach

  1. Answer from your own projects: for each bus you used, say what you built (a driver, signal packing and unpacking from a message database, diagnostics, gateway logic), which tools you used, and one fault you diagnosed. If you have only used SPI, I2C or UART, say so and explain how that experience transfers.
  2. Show you know CAN: multi-master with ID-based bitwise arbitration (dominant bits win, so the lower ID has priority and loses nothing), classic CAN carries up to 8 data bytes at up to 1 Mbit/s, CAN FD up to 64 bytes with a faster data phase; CRC, acknowledgement, error counters and bus-off recovery.
  3. Contrast the others: LIN is a single-master, low-cost bus up to 20 kbit/s for body electronics; FlexRay offers up to 10 Mbit/s per channel with a time-triggered static segment and dual channels for deterministic control; automotive Ethernet carries high-bandwidth traffic such as cameras.
  4. Cover non-blocking processing: the receive ISR copies frames from the mailbox into a ring buffer and signals a task, and hardware acceptance filters cut the interrupt load so the main execution path never waits on the bus.

Follow-up

  • Two nodes start transmitting at the same instant: what happens on a CAN bus, bit by bit?
  • How would you process time-critical CAN messages without blocking the main execution threads?
  • You decode a signal and the value is wrong by a large factor: which byte-order or scaling mistakes do you check first?

How do you conduct functional behavior analysis and risk assessment when designing safety-critical logic?

Medium · Domain & Systems Engineering (Embedded /

Approach

  1. Start from hazards, not code: in an ISO 26262 hazard analysis and risk assessment, rate each hazardous event by severity, exposure and controllability to get an ASIL, then derive safety goals and functional safety requirements.
  2. Combine the two classic analyses: FMEA works bottom-up (each component failure mode, its effect and how it is detected) and fault tree analysis works top-down from a hazard to the combinations of faults that cause it.
  3. Model the functional behaviour explicitly, usually as a state machine with defined states, transitions, timeouts and a safe state. Check every input combination, including stale, missing, out-of-range and contradictory signals, and the fault reaction time.
  4. Name the mechanisms: plausibility and range checks, redundancy or cross-checks between independent sources, watchdogs, debounce and hysteresis so a warning does not flicker, and a default to the safe state on signal loss.
  5. Close with verification: requirements-based tests traced to each safety requirement, fault-injection tests for every detected failure mode, and independent review at the levels the standard requires.

Follow-up

  • How are severity, exposure and controllability combined into an ASIL, and what changes between ASIL A and D?
  • When would you choose FTA over FMEA, and how do the two feed each other?
  • How would you write test scenarios for an automated flight warning that must not raise false alarms?

Describe your process for writing automated test cases, continuous integration pipelines, and validation repor

Medium · Domain & Systems Engineering (Embedded /

Describe your process for writing automated test cases, continuous integration pipelines, and validation reports for complex engineering deliverables.

Approach

  1. Design tests from requirements: each test case carries the requirement identifier it verifies, and inputs come from equivalence classes, boundary values and negative or fault cases rather than only the happy path.
  2. Layer the suite: unit tests (GoogleTest, pytest or JUnit) on every change, integration tests on the build, and longer SIL or HIL runs nightly or before a release, because bench time is scarce.
  3. Describe the CI pipeline on each merge request: a reproducible build (a Docker image pins the toolchain), static analysis and coding-standard checks, unit tests with coverage, and archived artifacts. A failed stage blocks the merge.
  4. Handle flakiness deliberately: fixed random seeds, isolated test data, and quarantining a flaky test with a ticket to fix it, so a red build always means something.
  5. Generate the validation report from CI output, not by hand: the exact software version and configuration, tool versions, test environment, pass or fail per requirement, coverage, deviations and open problem reports.

Follow-up

  • A HIL test fails one run in ten: how do you decide whether the software, the bench or the test is at fault?
  • How do you decide that coverage is sufficient for a release?
  • What must a validation report contain for someone else to reproduce the result a year later?

Explain the role of simulation tools and model-in-the-loop (MIL) testing in early-stage software verification.

Medium · Domain & Systems Engineering (Embedded /

Approach

  1. Place MIL in the x-in-the-loop chain: MIL runs the controller model against a plant model in simulation; SIL runs the generated or hand-written code compiled on the host; PIL runs it on the target processor; HIL runs the real ECU against a real-time plant simulator.
  2. Explain what MIL buys early: the algorithm and the requirements are checked before code or hardware exists, iterations are cheap and fast, and dangerous or rare scenarios (sensor failure, extreme conditions) can be exercised safely.
  3. Describe back-to-back testing: run the same test vectors at MIL and SIL, then compare the outputs within a tolerance to catch code-generation, fixed-point scaling and data-type errors.
  4. State the limits: results are only as good as the plant model, and MIL shows no real timing, interrupts, bus traffic or hardware faults, which is why SIL, PIL and HIL still follow.
  5. Reuse requirement-based test cases across all stages so one test suite gives traceable evidence from model to ECU.

Follow-up

  • What kinds of defects does back-to-back testing between MIL and SIL catch?
  • How do you decide a plant model is accurate enough to trust the MIL results?
  • Name a defect that only HIL testing would find.

Listing latency scales with page size, not with filters

Easy · n+1 · latency · query batching

The tenant listing endpoint reads resource filtered by tenant_id and status, ordered by updated_at DESC, and returns each row plus the owner's display name from app_user and the actor of that resource's latest resource_revision. p99 is 55 ms at 10 rows per page and 1.4 s at 200. Database telemetry shows 401 statements per request, each under 1 ms, and nothing in the slow-query log. Diagnose the cause and give the fix, stating the statement count per request and the p99 you expect afterwards.

Approach

  1. Read the counters before forming a theory. 401 statements for 200 rows is one driver query plus two per row, and sub-millisecond execution with an empty slow-query log rules out a bad plan. The time is round trips, which is why it is invisible in every per-query metric and scales with rows returned rather than with filter selectivity.
  2. Name the two per-row statements from their normalised text: a single-row app_user lookup by user_id, and a resource_revision lookup by resource_id ordered by version DESC LIMIT 1. Confirm by dropping those two response fields and watching the statement count fall to one. That locates the calls in the serialisation layer, not the repository.
  3. Check that the arithmetic accounts for the whole gap. Measure one round trip to the replica in isolation; 400 trips at roughly 3 ms of network plus 0.2 ms of execution is about 1.3 s on top of a 55 ms baseline, which matches. If the multiplication had fallen short, the N+1 would only be part of the story and you would keep looking.
  4. Batch both lookups. Collect owner_user_ids and resource_ids from the driver query, then issue WHERE tenant_id = 1ANDuserid=ANY(1 AND user_id = ANY(2) for the users, and PostgreSQL's SELECT DISTINCT ON (resource_id) ... WHERE resource_id = ANY($2) ORDER BY resource_id, version DESC for the latest revision, which the UNIQUE (resource_id, version) index serves directly. On an engine without DISTINCT ON, use a lateral join or a row_number window. Three statements per request at any page size.

Follow-up

  • The page size is capped at 200 today. What breaks first if it is raised to 2,000, and is it still this bug?
  • How do you stop the next N+1 from reaching production, given that no individual query is slow and the endpoint's tests pass?

Suggested practice checklist

The plan starts with your two project stories and the OOP fundamentals, moves through coding practice on the reported algorithm topics, and spends one day on embedded and verification material before rehearsing behavioral and client answers.

Day 1 — Map the loop and pick your project stories

  • List the five reported stages and note which ones likely apply to your position, then sort the reported questions into four groups: OOP fundamentals, algorithms, embedded and domain, and behavioral.
  • Choose two projects (thesis, capstone or work) and write a fact sheet for each: problem, constraints, design alternatives, how it was tested, what you would change.
  • Write a one-paragraph recruiter pitch naming your main language and the project types you want.

Deliverable: A one-page loop map, two project fact sheets and a written recruiter pitch.

Day 2 — OOP, polymorphism and dependency injection

  • Answer aloud the four OOP principles and show polymorphism with a hierarchy from your own project, not a textbook shape example.
  • Write a comparison of abstract classes and interfaces in your language, with one case where each is the right choice.
  • Write a small class that takes its dependency through the constructor, then test it with a hand-written fake, and note what changed for maintainability.

Deliverable: A one-page OOP cheat sheet and a small code sample with a unit test that uses a fake dependency.

Day 3 — Memory management, lifecycle and CI

  • Write and speak an answer on memory management for the language you use: ownership, stack versus heap, common leak causes, and what changes in real-time code.
  • Write a step-by-step debugging path for a leak or segmentation fault using logs, reasoning about ownership and, if available, sanitizers or a profiler as confirmation.
  • Outline the lifecycle stages you follow on a regulated project, from requirements through review, testing and validation reports, plus the CI stages that run on each commit.

Deliverable: Two recorded spoken answers (memory and lifecycle), a written leak and segmentation-fault debugging path, and a CI stage list tied to a real project.

Day 4 — Arrays, 1D dynamic programming and hash tables

  • Implement maximum subarray sum with a single pass, state the complexity and test the all-negative and single-element cases.
  • Solve a minimum path cost problem with a recurrence, then reduce the table to rolling variables and explain the space saving.
  • Implement a hash table with chaining, then explain open addressing, load factor, resizing and worst-case lookup.

Deliverable: Three working solutions in your chosen language, each with stated time and space complexity and an edge-case list.

Day 5 — Trees, graphs and complexity improvements

  • Implement a dependency graph with an adjacency list and traverse it with depth-first and breadth-first search.
  • Write a cycle detector for system initialization steps, once with depth-first colouring and once with Kahn's topological sort.
  • Prepare a true story of replacing an O(n^2) routine with a sort or hash-set approach, with the before and after measurements.

Deliverable: A cycle-detection function with tests and a written optimization story with numbers from your own work.

Day 6 — Real-time, buses and verification

  • Write a cheat sheet on RTOS scheduling, interrupt handling, priority inversion and how you would keep timing deterministic.
  • Compare CAN, LIN, FlexRay, Ethernet, SPI, I2C and UART by speed, topology and typical use, and mark which ones you have actually used.
  • Outline a test plan for a safety shutdown scenario, covering functional behavior analysis, risk assessment and the roles of model-in-the-loop, software-in-the-loop and hardware-in-the-loop testing.
  • If your target project is web or enterprise, shorten this day and repeat day 4 or 5 problems instead.

Deliverable: A one-page RTOS and bus cheat sheet and a written test-plan outline for a safety shutdown scenario.

Day 7 — Behavioral stories and the client conversation

  • Write STAR outlines for the career-direction, competing-priorities, new-stack and technical-conflict prompts, each with a measurable result.
  • Prepare an answer for how you structure work when requirements are ambiguous or changing, using one real project.
  • Run a mock client conversation: explain one project's trade-offs aloud, then ask your own questions about stack, domain, team and remote versus on-site.

Deliverable: Five STAR or structure outlines plus a written list of questions for the client and the business manager.

Consulting and client stories

The reported behavioral prompts focus on consulting-style situations: career direction, fixed deadlines with competing priorities, learning a new stack or client framework quickly, technical conflict with a lead or client stakeholder, and working through ambiguous requirements. Prepare each with a Situation, Task, Action, Result outline that states your own contribution and explains why you chose the approach, since the reports say managers look at your trade-off reasoning.

  1. How do you structure your work when project requirements are ambiguous or rapidly changing?

Where do you see your technical career progressing over the next 3 to 5 years?

Medium · Behavioral & Client Consulting Alignment

Approach

  1. Choose one direction you can defend, such as deepening in embedded and safety-critical software, moving toward technical lead, or broadening across industries, and say it in a single sentence.
  2. Back the direction with evidence that you already started: a certification, a standard you studied (ISO 26262 or DO-178C if relevant), a design you led, or a mentoring role.
  3. Give two or three concrete steps for the next stretch of years, such as owning a subsystem end to end, then leading a small team, rather than a title you want.
  4. Connect it to consulting work: varied projects and clients speed up exactly the skills you named, and say what you would want to learn from the first assignment.
  5. Stay consistent with your resume and with what you told the recruiter, and do not present the role as a stepping stone to leave.

Follow-up

  • Which skill gap would you close first, and how?
  • What kind of first project would move you toward that goal?
  • How would your plan change if your first placement were in a different industry?

How do you manage competing project priorities or resource constraints when deadlines are fixed?

Medium · Behavioral & Client Consulting Alignment

Approach

  1. Open with a real situation where deadlines were fixed and tasks competed, and state the number of items and what was at stake for each.
  2. Show the method: list everything, estimate effort, rank by cost of delay and dependency, and ask the stakeholder to confirm the ranking instead of guessing.
  3. Explain the levers you used: cut or defer scope, change sequencing, add help, or negotiate the date, and why you chose the lever you did.
  4. Make the trade-off visible in writing (a short status note or ticket update) so no one is surprised later, and protect testing and review rather than dropping them.
  5. End with the result and a lesson: what shipped, what slipped and how you communicated it. A story that is only about working longer hours sinks the answer.

Follow-up

  • What if two stakeholders each insisted their item was the top priority?
  • What did you drop, and how did that stakeholder react?
  • How did you track progress and give early warning that a deadline was at risk?

Tell me about a time you had to adapt quickly to a completely new technology stack or client framework.

Medium · Behavioral & Client Consulting Alignment

Approach

  1. Pick a story with a real stack or client framework switch, and state in two sentences what was new and what depended on you learning it.
  2. Describe a learning method rather than a feeling: read the client's code and conventions, build a thin end-to-end slice first, map concepts to the stack you already knew, and ask for review early.
  3. Show how you checked your understanding: tests that failed first, a pairing session, or a small change merged under review.
  4. Give the outcome with a concrete deliverable and one thing you got wrong initially, with how you corrected it.
  5. Avoid claiming you picked it up instantly or listing technology names without saying what you did with them.

Follow-up

  • What did you misunderstand at first, and how did you find out?
  • How did you handle a client convention that clashed with your habits?
  • How would you approach a stack you have never used if the project started next week?

Describe a situation where you experienced a technical conflict with a team lead or client stakeholder. How di

Medium · Behavioral & Client Consulting Alignment

Describe a situation where you experienced a technical conflict with a team lead or client stakeholder. How did you reach a resolution?

Approach

  1. Describe the conflict as two technical positions with a shared goal, for example a design choice, a test scope or a requirement interpretation, not as a personality clash.
  2. Say what you did to resolve it with evidence: a prototype or measurement, a pointer to the requirement or compliance rule, or a written comparison of options with costs.
  3. Show that you understood the other person's constraints, particularly with a client stakeholder whose environment, rules or deadlines you did not control.
  4. State who made the final decision and the result, including if you were overruled and committed anyway, or if the outcome proved you wrong.
  5. Do not cast the lead or client as the villain. Where safety or compliance was involved, add that you raised the concern in writing and on the right channel.

Follow-up

  • What would you have done if they still disagreed after the evidence?
  • How did your working relationship look afterwards?
  • How would you handle it if a client's requirement conflicted with a safety or standards rule?