Interview guides · ACENSI
ACENSI Software Engineer Interview Guide
ACENSI Software Engineer interview guide: the four reported rounds, OOP, SQL and live-coding prep, behavioral answers and a 7-day plan.
The 60-second brief
Candidates describe ACENSI as a consulting firm that places software engineers on missions for its clients. The reported role covers backend work, full-stack development and architectural design, and follows a project from design and development through deployment and maintenance. Because the stack depends on the client mission, the languages candidates mention (Java, .NET and Python, with SQL and Git alongside) are a baseline rather than a fixed product stack. Engineers are also described as the person clients deal with directly, so explaining your work to non-engineers is part of the job.
This guide is for candidates interviewing for a Software Engineer position at ACENSI. It covers the four stages candidates report (HR Screening, Technical Assessment, Managerial Interview, Senior Leadership Meeting), the ten questions reported for this loop, and the example scenarios candidates mention: an inheritance class that counts its instances, a slow SQL query, a small service built from scratch, and a production performance bottleneck. It also gives you a seven-day plan that mixes your own language, SQL, OOP and live-coding practice with spoken behavioral answers.
Candidates report four stages over roughly 3-5 weeks: an HR Screening, a Technical Assessment, a Managerial Interview and, for some roles, a Senior Leadership Meeting that can include an introduction to clients. Some accounts also describe a faster process.
Focus areas
- Python
- Object-Oriented Programming (OOP)
- SQL
Overview
The reported loop splits cleanly into a technical half and a communication half. On the technical side, candidates mention automated coding tests (CodingGame is the platform named) and live coding, with Python, OOP, SQL, .NET/C# and Java as the topics that come up. The example scenarios are practical rather than exotic: a class structure that uses inheritance and tracks how many instances exist, a SQL query to speed up on a large dataset, a small service to architect from scratch, and the first steps when production slows down. Prepare these as things you can build, run and explain, not as definitions.
The questions reported for this loop come in two groups. The technical group asks about TDD versus BDD, asynchronous programming in your preferred language, SQL versus NoSQL, dependency injection or inheritance, and query optimisation. These are broad, so the winning move is to choose one language you can speak about in depth and anchor every answer in code you have actually written. Candidates are also told to expect follow-up questions on why you chose a given approach, so for each answer have the alternative you rejected and the reason ready.
The behavioral group is shaped by the consulting setting: explaining a technical issue to a non-technical stakeholder, working to a tight deadline, handling disagreement from a lead or a client, balancing work and personal life, and why a consulting firm rather than a product company. Candidates describe the role as client-facing, with sprint stand-ups, delivery against client deadlines and documentation for other people. Build stories that show that environment: a client or stakeholder who was not an engineer, a deadline you did not control, and a decision you explained rather than just made.
Logistics deserve a little preparation too. Candidates mention that scheduling communication has sometimes been inconsistent, so ask for interview times in writing and keep a record of what was agreed. Ask in advance whether a stage involves live coding and what the environment requirements are, keep your IDE and tooling ready, and keep your skills dossier (the "dossier de compétences" some candidates are asked for) consistent with your CV. If a stage is a client meeting, ask what the mission is.
The ACENSI interview process
These are the four stages candidates describe, in the order they report them; the exact content varies by role and by client mission.
HR Screening
Candidates describe this first stage as a conversation with HR about your background and qualifications. No technical questions are reported for it, so treat it as the stage where your CV, your stack and the logistics of the rest of the loop get settled. Candidates also say communication around scheduling can be inconsistent, which makes this the moment to ask for the remaining steps and dates in writing and to find out whether later stages involve live coding.
What to demonstrate
- How your background and qualifications line up with the role
- Whether your experience matches the languages and tools the role lists (Java, .NET or Python, SQL, Git)
- How clearly you describe your own work
How to prepare
- Prepare a short walk through your CV that names the languages, databases and tools you used on each project, so it matches the skills the role lists.
- Update your skills dossier (the "dossier de compétences") and check that it agrees with your CV.
- Ask in writing for the sequence of stages, the interview times, and whether a coding test or live coding is involved, and keep the replies.
- Write your answer to why a consulting firm rather than a product company, since it is a reported question and HR is the natural place to hear it.
Technical Assessment
Candidates describe this stage as coding challenges or assessments of your technical skills. They name CodingGame as an example of the automated tests and mention live coding sessions elsewhere in the technical evaluation. The reported topic areas are Python, Java, .NET/C#, OOP and SQL, plus time and space complexity and debugging. Work in the language you know best, say your reasoning aloud when someone is watching, and make the code readable, because candidates are told clean, maintainable code is expected.
What to demonstrate
- Working code for standard algorithmic problems
- Command of one primary language or framework and of OOP concepts (inheritance, polymorphism, encapsulation)
- SQL query writing and tuning
- Time and space complexity analysis and debugging in a live setting
How to prepare
- Do timed algorithm problems on a CodingGame-style platform in your primary language, then state the time and space complexity of each solution.
- Build the reported OOP scenario: a base class and a subclass with a class-level counter that tracks instances, then explain the inheritance and encapsulation choices.
- Write and tune SQL by hand: joins, grouping, indexes, and reading an execution plan for a slow query.
- Set up your IDE, runtime and test runner before any live session, and ask what environment the session expects.
Managerial Interview
Candidates describe an interview with managerial staff that mixes technical and interpersonal questions. The reported example scenarios include architecting a small service from scratch and naming your first steps when production performance degrades, and candidates are told to expect to defend the reasons behind their technical decisions. Alongside those sit the behavioral questions about deadlines, explaining issues to non-technical people, and feedback from a lead or client. Use the whole stage to show how you reason, not only what you chose.
What to demonstrate
- Technical judgement and the reasons behind design decisions
- Interpersonal skills and communication with non-engineers
- How you work with leads, project managers and clients under delivery pressure
How to prepare
- Rehearse an outline for a small service: requirements, data model, API surface, persistence, tests, deployment, monitoring. Say what you would defer and why.
- Memorise a debugging sequence for a production slowdown: confirm and scope the symptom, check recent changes, look at metrics and logs, find the bottleneck, fix it, add monitoring.
- Prepare stories for the stakeholder-explanation, tight-deadline and disagreement questions, each with a measurable outcome.
- Prepare the SQL versus NoSQL and query-optimisation answers with a real example from your own work.
Senior Leadership Meeting
Candidates describe this stage as a possible meeting with senior leadership or, for certain roles, an introduction to clients. Not everyone gets it. If you do, it works like a conversation about fit with a team and a mission rather than a technical test, so plan to explain what you have delivered in plain language and to ask what the mission and team look like.
What to demonstrate
- Whether you can come across as a dependable representative in front of leadership or a client
- How you fit into a new team or mission
- How well you explain your work to a non-technical audience
How to prepare
- Rehearse a plain-language summary of your most relevant project: the problem, what you built, and the result for the people who used it.
- Prepare questions about the mission, the client's team, the stack and how you would be supported in the first weeks.
- Have a concise answer for work-life balance and for handling a client who disagrees with you, since both are reported questions.
- Prepare one example of picking up an unfamiliar codebase or technology quickly.
Where candidates lose points
Answering the TDD versus BDD, asynchronous programming or dependency injection questions with textbook definitions and no example from code you wrote
For each reported technical question, prepare one concrete case in your main language: the test you wrote first, the asynchronous call you made concurrent, the dependency you injected. Include the alternative you rejected and why.
Giving an SQL versus NoSQL answer as a list of features and ending with a preference
Answer with the access pattern and consistency needs of a specific system, and say what you would pick for it. Be able to cover joins, transactions, schema flexibility and scaling reads and writes.
Saying 'I would add an index' for the query optimisation question without checking why the query is slow
Describe the order: capture the slow query, read its execution plan, check the filter, join and sort columns against indexes, fix the query shape, then measure again. Mention when an index will not help.
Writing code silently in a live session, or leaving the code unreadable and untested
Narrate the plan and the complexity, use clear names, handle empty and boundary input, and run a test case. Set up your IDE and runtime before the session and ask about the environment in advance.
Telling consulting stories in which you are the only actor, with no client, stakeholder or lead in them
Choose stories that include a non-engineer, a deadline someone else set, or a disagreement over your implementation, and show how you communicated and what you agreed. Prepare a specific reason for choosing consulting over a product company.
Questions & practice
Track a rolling failure rate per destination for circuit decisions
Easy · sliding window · ring buffer · circuit breaker
The egress service delivers about 1,500 webhooks per second across roughly 40,000 destinations, each call bounded by a 10 second timeout. Maintain, per destination, the failure rate over the trailing 60 seconds so a caller can ask before dispatch whether the circuit should open. Attempts arrive as (destination_id, finished_at_ms, outcome). Requirement: amortised O(1) per attempt, with total memory bounded by the destination count rather than by traffic. Give the structure, its exact memory, and the rule that stops a destination with three attempts from opening a circuit.
Approach
- Name the exact-deque version and then reject it as the default. Holding timestamps and advancing a tail pointer past anything older than now minus 60 seconds is a correct two-pointer window at amortised O(1) per attempt, but its memory tracks in-window traffic, so one destination in a retry storm holds hundreds of thousands of entries while thousands of quiet destinations hold none.
- Use a ring of 60 one-second buckets per destination, each bucket a pair of counters for attempts and failures. On an attempt, advance the ring by the elapsed whole seconds, zeroing at most min(elapsed, 60) buckets, then increment the head. That is amortised O(1) with a fixed footprint per destination.
- State the footprint: 60 buckets times two 4-byte counters is 480 bytes of payload per destination, so 40,000 destinations is roughly 20 to 25 MB with per-entry overhead, bounded by the catalogue rather than by the rate. The cost is granularity, since the oldest bucket ages out in whole seconds, which is far tighter than the decision needs.
- Require a minimum sample before the circuit may open. A destination with three attempts and three failures reads as 100 percent and is not evidence; a floor of roughly 20 attempts in the window makes the ratio meaningful, and below that floor use a run of consecutive failures as the trigger instead.
Follow-up
- The fleet is 30 instances and each sees roughly a thirtieth of a destination's traffic. Where does the rate actually live, and what does a per-instance answer get wrong?
- A destination answers in 9.5 seconds and succeeds. It is not failing but it is consuming your per-destination concurrency. What signal should open the circuit here?
Merge partitioned event streams into one ordered feed with bounded lateness
Hard · k-way merge · watermarks · out-of-order streams
The read-model service consumes 64 log partitions carrying about 4,000 events per second in total. Each partition is ordered within itself, but partitions drift by up to 30 seconds, and the activity feed must present a tenant's events in occurred_at order. Produce the merge. State its complexity, the buffer it requires in events and in bytes, what happens when one partition is idle, and what you do with an event that arrives after you have already emitted its position. Payloads average 1 KB.
Approach
- Merge with a min-heap over the 64 partition heads keyed on (occurred_at, event_id): O(log P) per event and O(n log P) overall. The tie-break on event_id is what makes the output deterministic when two partitions carry the same millisecond, which matters because the feed is paginated and a non-deterministic order reorders pages under the reader.
- Emitting the heap head is only correct once every partition has produced everything up to that timestamp, so the emit condition is a watermark: the minimum across partitions of the highest occurred_at seen, less the allowed lateness. Events are held until the watermark passes them, which is what turns individually ordered streams into a jointly ordered one.
- Size the buffer from the lateness rather than guessing: 4,000 events per second times 30 seconds is 120,000 buffered events, and at 1 KB each about 120 MB of heap. That number is the real price of the ordering guarantee and belongs in front of whoever asked for it.
- Handle the idle partition explicitly, because it fails the feed rather than corrupting it: a partition with no traffic never advances its own maximum, so the watermark freezes and output stops entirely. Either every partition emits a periodic idle marker carrying the broker's current time, or the watermark falls back to wall clock for a partition silent beyond a threshold.
Follow-up
- The lateness budget is raised to five minutes. What is the new buffer, and what besides memory changes?
- The consumer restarts. Where does it resume from, and what does the feed look like for the first 30 seconds?
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?
What are the key differences between SQL and NoSQL databases, and when would you choose one over the other?
Medium · Technical and Domain Knowledge
Approach
- Contrast the models. Relational databases have a fixed schema, normalised tables, joins, and ACID transactions spanning many rows and tables. NoSQL is several families, each modelled around access patterns rather than entities: document (MongoDB), key-value (Redis, DynamoDB), wide-column (Cassandra) and graph (Neo4j).
- Contrast scaling and consistency. Relational systems usually scale up and add read replicas, and sharding them takes real work. Many NoSQL stores partition horizontally by key and offer tunable or eventual consistency: DynamoDB reads are eventually consistent unless you request strongly consistent ones, and Cassandra sets the level per query. Under a network partition (CAP), a system gives up either consistency or availability.
- Say the line has blurred. PostgreSQL stores and indexes semi-structured data in JSONB, and MongoDB has supported multi-document transactions since 4.0. The choice is about the dominant workload, not which features exist.
- Give a decision rule with examples. Pick relational when integrity rules and ad-hoc reporting matter (orders, payments, anything joined many ways). Pick a key-value or document store when access is by a known key at high write volume or the shape varies per record (sessions, caches, event logs, a catalogue with varying attributes). Many systems run both.
- Name the cost of denormalising: duplicated data has to be updated in several places, and a query you did not model up front becomes a scan or a new copy of the data.
Follow-up
- How would you model an order with its line items in a document store, and what changes when you need a report across all orders?
- Would PostgreSQL with a JSONB column cover this case instead of adding a second database?
- What consistency problem appears when the same data lives in a relational database and a cache or search index?
Why do you want to join a consulting firm like ACENSI as opposed to a product company?
Medium · Behavioral and Culture Fit
Approach
- Treat this as a motivation question, not a technical one. Give two or three reasons, each backed by something you have done: ramping up quickly on an unfamiliar codebase, working directly with business users, or enjoying a change of domain. A reason with no evidence behind it sounds rehearsed.
- Tie the reasons to what candidates report about this firm: consultants are placed on client missions, technical stacks vary from one mission to the next, and some candidates are presented to a client. Say why that suits you, for example: "I learn fastest when I have to ship in a new stack under real constraints."
- Show you know the trade-offs and how you would handle them: switching context between missions, adapting to each client's tools and rules, and owning one product for less time. Say what you would do to stay productive and keep growing your skills across missions.
- Say what a client gets from you, not only what you get: explaining technical constraints to non-technical people, delivering against a client's deadline, writing documentation the next person can use.
- Avoid the two answers that sink this question: criticising product companies, and saying 'variety' with nothing behind it. End on the kind of mission you would like first and the stack you are strongest in (Java, .NET or Python).
Follow-up
- What would you do if you were placed on a mission using a stack you have never worked with?
- How would you handle a mission that turns out to be less interesting than you hoped?
- Do you see yourself becoming a specialist in one stack or staying broad across missions?
Can you explain the difference between TDD and BDD in your development workflow?
Medium · Technical and Domain Knowledge
Approach
- Define TDD as a developer-facing loop: write one failing unit test (red), write the least code that passes it (green), then refactor with the test as a safety net. The tests describe units, and the loop pushes the design toward small classes with injectable dependencies.
- Define BDD as TDD applied to behaviour in domain language: scenarios written as Given/When/Then (Gherkin) that a product owner or client can read, bound to code through step definitions. Name a tool in your stack: Cucumber for Java, SpecFlow or its successor Reqnroll for .NET, behave or pytest-bdd for Python.
- Say they combine rather than compete: a BDD acceptance scenario forms the outer loop for a feature, and TDD unit tests form the inner loop while you build it. Then describe your own workflow on a real ticket in the first person, from the scenario down to the last unit test.
- Give the trade-offs: BDD only pays off when non-developers actually read or write the scenarios, otherwise the step-definition layer is maintenance with no audience. Scenarios that script UI clicks instead of business rules break on every layout change. In TDD, over-mocking ties tests to the implementation, so refactors break tests without changing behaviour.
Follow-up
- When would you not write the test first, for example on a spike or exploratory code?
- How do you keep a growing Gherkin suite from becoming slow and brittle?
- How do you unit-test a class that calls an external API or a database?
How do you manage dependency injection or inheritance in your code?
Medium · Technical and Domain Knowledge
Approach
- Explain dependency injection as handing a class its collaborators, usually through the constructor, instead of having it create them with new. It should depend on an interface, so a test can pass a fake. Constructor injection keeps dependencies explicit and immutable; field injection hides them and makes them harder to test.
- Name the container in your stack. Spring wires beans in Java. In .NET, Microsoft.Extensions.DependencyInjection uses Transient, Scoped and Singleton lifetimes, and a singleton that captures a scoped service (a captive dependency) is a classic bug. ASP.NET Core's scope validation catches it in Development. In Python, plain constructor arguments usually do the job.
- Keep inheritance for genuine is-a relationships where a subclass can stand in for its parent (Liskov substitution). Otherwise prefer composition: deep hierarchies create the fragile base class problem, where a change to the parent silently breaks its subclasses.
- Candidates report an exercise on a class structure that shows inheritance and tracks instance counts. In Python, Base.count += 1 in the base init keeps one shared total. type(self).count += 1 silently creates a separate attribute on each subclass, seeded from the parent's current value. In Java, use a static field, and an AtomicInteger if instances are created from several threads.
- Show encapsulation and polymorphism in the same answer: keep the counter private behind a getter or class method, and override one method in the subclass to show dynamic dispatch.
Follow-up
- How would you test a class that opens its own database connection inside a method?
- When would you choose an abstract class over an interface?
- What goes wrong when a singleton service depends on a scoped one, and how would you spot it?
Explain how you optimize database queries for performance.
Medium · Technical and Domain Knowledge
Approach
- Measure before changing anything. Find the slow statements with the slow-query log, pg_stat_statements or SQL Server Query Store. Then get the real plan: EXPLAIN ANALYZE in PostgreSQL (and in MySQL 8.0.18+), or the actual execution plan in SQL Server.
- Read the plan for specific problems: a full scan of a large table under a selective filter, estimated rows far from actual rows (refresh statistics with ANALYZE or UPDATE STATISTICS), a nested loop over many rows, or a sort or hash spilling to disk.
- Fix access paths with indexes. In a composite index, put the equality columns first and then the range or sort column. Use a covering index (INCLUDE in PostgreSQL 11+ and SQL Server) to get index-only reads. Keep predicates sargable: wrapping the column in a function (YEAR(created_at) = 2024), an implicit type cast, or LIKE with a pattern starting with % blocks a B-tree seek, so rewrite as a range.
- Fix the query shape. Select only the columns you need, replace an ORM N+1 loop with a join or batched fetch, and use keyset pagination (WHERE id > last_id ORDER BY id LIMIT n) instead of a large OFFSET, which still reads and discards the skipped rows.
- State the costs and check the result. Each index slows inserts and updates and takes storage. Beyond the query itself the options are caching, read replicas, materialised views or partitioning. Re-run the plan and compare latency before and after, not just one execution.
Follow-up
- You added an index and the plan still does not use it. What are the likely reasons?
- How do you find and fix an N+1 problem coming from an ORM such as Hibernate or Entity Framework?
- When would you denormalise or add a materialised view instead of another index?
Edge instances grow 400 MB per hour until the nightly restart
Hard · memory leak · heap analysis · metric cardinality
Edge API instances start at 700 MB resident and grow about 400 MB/hour; a nightly rolling restart has hidden it for weeks. Growth continues unchanged when request rate halves overnight, p99 degrades in the last hours before an instance is recycled, and heap used immediately after a forced full GC rises monotonically. The service holds no product state. Name the discriminating measurement that separates the plausible causes, give the most likely cause, and give the fix and how you would verify it.
Approach
- Separate resident memory from live heap first, because they fail differently. Resident size can grow from fragmentation, native buffers or thread stacks while the heap is flat; heap used after a full GC rising monotonically is the measurement that says objects are reachable and not being released. You already have it, so this is retention, not fragmentation, and that closes off half the candidate list.
- Use the rate's independence from traffic as the discriminator. Growth that continues at half the request rate rules out per-request objects that are merely slow to collect and points at a structure that grows with distinct values observed rather than with call volume. Write the candidates that have that property: a metrics registry keyed on a high-cardinality label, an unevicted cache, an interner, a per-key lock map.
- Take two heap snapshots an hour apart and diff by retained size, reading the dominator tree, not by allocation count or instance count. Expect one root holding a map with millions of entries, then follow the reference chain to the code that inserts and never removes. Allocation profilers point at churn, which is the wrong signal here.
- The candidate that fits this service is an observability label carrying an identifier, such as a request path recorded before templating so that /v1/resources/48213 becomes its own metric series. That grows with distinct ids seen, is independent of rate, and explains the late p99 degradation, since GC cost rises with the size of the live set.
Follow-up
- Post-GC heap is now flat but resident size still creeps. What are you looking at, and does it matter?
- How would you have detected this before an OOM, given the nightly restart masked the trend?
Suggested practice checklist
The plan follows the four reported stages: day 1 sets up the logistics, days 2 to 5 cover the OOP, SQL, asynchronous and live-coding material candidates report, and days 6 and 7 move to spoken behavioral answers and a full run-through.
Day 1 — Set up the loop and your primary language
- Choose the language you will use in every technical answer (Python, Java or C#) and list the projects where you used it.
- Write the four reported stages as a checklist, with the questions to ask HR: sequence, dates in writing, whether live coding is involved and what environment it needs.
- Update your skills dossier and CV so they list the same languages, SQL and Git experience.
Deliverable: A one-page loop checklist, a chosen primary language with three supporting projects, and an updated skills dossier.
Day 2 — OOP, inheritance and dependency injection
- Write a base class and subclasses that demonstrate inheritance and polymorphism, with a class-level counter that tracks the number of instances, and test it, including what happens when a subclass is created.
- Rewrite one class so its dependency is passed in through the constructor instead of created inside, and write a test that uses a fake.
- Practise the answer on dependency injection versus inheritance: when to prefer composition and why.
Deliverable: A working class hierarchy with an instance counter, a constructor-injected version with a test, and a spoken answer on inheritance versus dependency injection.
Day 3 — SQL, schema design and query optimisation
- Create a table of a few hundred thousand rows, write a slow query with a join and a filter, read its execution plan and improve it with an index or a rewrite.
- Write a one-minute comparison of SQL and NoSQL for a specific system, covering joins, transactions, schema flexibility and scale.
- Write the query-optimisation sequence as an ordered list you can say aloud.
Deliverable: Before-and-after execution plans for one query, plus written SQL-versus-NoSQL and query-optimisation answers.
Day 4 — Testing approach and asynchronous programming
- Write a small feature test-first (TDD), then write the same behaviour as a plain-language scenario (BDD style), and note the difference in what each gives you.
- In your main language, write a function that fetches several inputs concurrently with a concurrency limit, a timeout and error handling.
- Practise the asynchronous programming answer: concurrency versus parallelism, blocking calls, cancellation.
Deliverable: A test-first example, a BDD scenario for the same behaviour, a working concurrent fetch with a limit, and spoken answers to both questions.
Day 5 — Live coding and debugging under conditions
- Do timed algorithm problems on a CodingGame-style platform in your language, saying your reasoning aloud and stating the complexity afterwards.
- Practise the reported production-slowdown scenario with the practice debugging question on memory growth, and write the first steps you would take.
Deliverable: Several timed solutions with stated complexity, notes on the data structures used and a written first-steps list for a performance problem.
Day 6 — Behavioral stories for a client-facing role
- Write STAR outlines for the stakeholder-explanation, tight-deadline and disagreement stories, each with a concrete result.
- Write a straightforward answer on work-life balance and a specific answer on why a consulting firm rather than a product company.
- Say each answer aloud and cut anything that is a slogan with no example.
Deliverable: Four STAR outlines plus spoken answers on work-life balance and on choosing consulting.
Day 7 — Full run-through and client-meeting readiness
- Run a mock loop: an HR conversation, a coding task in your own environment, a technical discussion that includes architecting a small service, and a managerial conversation.
- Prepare a plain-language summary of your best project and a set of questions for a senior or client meeting, such as the mission, the team and the stack.
- Check your logistics: confirmed times in writing, working IDE and a quiet space.
Deliverable: A completed mock with notes on weak answers, a plain-language project summary and a list of questions to ask.
Behavioural preparation
The behavioral questions reported for ACENSI are shaped by consulting work: translating technical issues for non-technical people, delivering against client deadlines, taking feedback from leads and clients, and explaining why you chose consulting. Candidates report that Managerial and leadership conversations mix technical and interpersonal questions, so each story should name the people involved and what you decided.
- Why do you want to join a consulting firm like ACENSI as opposed to a product company?
- Tell me about a time you had to get productive quickly in a codebase or technology you did not know.
How do you handle asynchronous programming in your preferred language?
Medium · Technical and Domain Knowledge
Approach
- Pick the language you know best (Python, Java or C#) and answer for that one. Start with the distinction: asynchronous code lets one thread make progress on other work while I/O waits, which is different from running work in parallel on several cores.
- Python: explain async/await on an asyncio event loop. Coroutines yield at await points; asyncio.gather or TaskGroup runs I/O-bound tasks concurrently. CPU-bound work does not benefit because of the GIL, so I send it to a process pool or run_in_executor. Java: CompletableFuture chains or an ExecutorService (virtual threads where available). C#: Task with async/await, where the cost of blocking with .Result is a possible deadlock.
- Name the failure modes: a blocking call such as a synchronous HTTP client or file read inside a coroutine stalls the whole event loop; unhandled exceptions in background tasks vanish unless awaited or collected; shared mutable state still needs a lock or a queue.
- Cover control: timeouts and cancellation, a semaphore to cap concurrent calls so a downstream service or database pool is not flooded, and retries with backoff only on idempotent operations.
- Give one concrete example from your own work, such as fanning out N API calls with a concurrency limit, and say how you tested it (an async test runner, a fake clock or a mocked client).
Follow-up
- What happens if you call a blocking function inside an async function, and how would you find it?
- How do you limit concurrency when fetching a thousand URLs?
- When would you choose threads or processes over async/await?
Tell me about a time you had to explain a complex technical issue to a non-technical stakeholder.
Medium · Behavioral and Culture Fit
Approach
- Choose a real issue where the other person had to make a decision, such as a data inconsistency, an outage cause or a trade-off between cost and delivery. State it briefly, then spend most of the answer on how you translated it.
- Translate by impact, not mechanism: say what it meant for them in terms of time, money, risk or customers, and offer two or three options with a recommendation. Use an analogy only if it is accurate, and avoid jargon or define it once in plain words.
- Check understanding by asking them to restate the decision or the risk in their own words, and adjust if they cannot. Follow up in writing with a short summary so the decision is on record.
- Close with the result: the decision they made, what changed afterwards and what you would do differently. The story fails if it is a technical explanation with the stakeholder as a bystander, or if it casts them as slow to understand.
Follow-up
- How did you know they understood you?
- What did you leave out on purpose, and why?
- What would you have done if they had insisted on the risky option?
How do you balance professional responsibilities with your personal life?
Medium · Behavioral and Culture Fit
Approach
- Answer honestly and concretely rather than with a slogan. Describe the habits that keep your work sustainable: a clear end to the working day, time off that is actually off, exercise or other commitments you protect, and a practice of raising capacity problems early.
- Tie it to delivery work: when a client deadline compresses a sprint, you prioritise with your lead, say what can move, and accept a temporary stretch with an agreed end rather than an open-ended one.
- Give a short example of a busy period you handled, what you did to prevent burnout (negotiated scope, handed off a task, moved a meeting) and how you recovered afterwards.
- Avoid two extremes: claiming you never need balance, which sounds unreliable, and giving rigid limits that suggest you will not respond to a real client incident. Show that you can flex when it matters and push back when it does not.
Follow-up
- What do you do when a client asks for work outside normal hours?
- How do you tell your lead you are at capacity?
- Tell me about a time your balance slipped and what you changed afterwards.
Describe a situation where you had to work under a tight deadline. How did you prioritize your tasks?
Medium · Behavioral and Culture Fit
Approach
- Use a STAR story where the deadline was fixed and the scope was too large for it. Give the situation in two sentences: what was due, to whom, and what was at stake.
- Show the prioritisation method: list every task, rank by value to the deadline and by risk or dependencies, do the blocking and highest-risk items first, and split the work into must-have now and later.
- Show that you negotiated scope instead of only working harder. Say what you cut or deferred, who agreed, and how you communicated progress and risk early.
- Protect quality on the critical path: tests on the paths that matter, a short review, and a written note of what was deferred so it did not become hidden debt. Finish with the outcome and what you changed for next time.
- The mistake that sinks this answer is a story of long hours and heroics with no prioritisation, or one that blames other people for the squeeze.
Follow-up
- What did you cut, and who signed off?
- What would you have done if nothing could be cut?
- How did you deal with what you deferred afterwards?
How do you handle feedback from a lead or a client if they disagree with your implementation?
Medium · Behavioral and Culture Fit
Approach
- Pick a real disagreement about an implementation, ideally with a lead or client whose view you did not share at first. Begin with listening: ask what requirement or concern sits behind the feedback and restate it until they confirm you have it.
- Test your approach and theirs on evidence: a short prototype, a benchmark, a cost or maintenance comparison, or a risk list. Be willing to adopt their suggestion when it holds up, and say so.
- If you still think it is wrong, explain the trade-off in their terms (delivery date, cost, risk to users), offer an option that meets their goal, and record the decision and its consequences. If they decide against you after that, commit and deliver it well.
- Show the outcome and what you learned, including a case where you turned out to be wrong. The story fails if you simply gave in without raising the risk, or if you present it as a win over the client.
Follow-up
- What would you do if the client insisted on an approach you thought would cause outages?
- Tell me about a time the feedback was right and you were wrong.
- How do you document a decision that you disagreed with?