Agilité Solutions · Software Engineer
Updated · 2026-10-02

Agilité Solutions Software Engineer
Interview Guide

THE 60-SECOND BRIEF

Candidates describe the Software Engineer role as building, maintaining and scaling web applications that support the company's business operations. The reported stack is an ASP.NET Core Web API back end, an Angular front end and Entity Framework for data access, so the work is described as full stack. The responsibilities candidates list are feature development inside existing software, refactoring code to production standard, investigating bugs and performance bottlenecks, and giving stakeholders progress updates and clarifying requirements. No product names or customers are reported, so this guide prepares you for the stack and the engineering habits rather than for a specific product.

This guide is for engineers interviewing for the Software Engineer role at Agilité Solutions, especially those with .NET and Angular experience. It covers the four reported rounds, the five reported questions (three framework-concept questions, one hands-on Web API and Angular implementation, and the reduce-clone coding task), the behavioral preparation, and a seven-day plan that uses PracHub's practice library for SQL and behavioral drills.

Candidates report four rounds over roughly 3-5 weeks: Initial Screening, Hands-on Technical Validation, Behavioral Assessments and a Final HR Discussion. An initial assignment is also reported, and later technical conversation is said to build on it.

.NET / ASP.NET Core Web APIAngularEntity Framework

31 min read

Browse Software Engineer questions

See the practice prompts

12Practice promptsAcross five skill areas

The reported stack tells you where to spend your hours. A request in this role travels from an Angular component through a service call to an ASP.NET Core Web API controller, into Entity Framework, and back as a response the front end has to handle. Prepare one feature you can narrate along that whole path: the DTO shape, validation, the query that loads the data, the error response when something fails, and how the Angular side shows that error. Being able to describe a single vertical slice in detail is worth more than a shallow tour of every framework feature.

The reported questions split into clear groups. Three are framework-concept questions: the difference between lazy loading and eager loading, the difference between an abstract class and an interface and when to prefer each, and how to handle concurrency in Entity Framework. One is a hands-on implementation using ASP.NET Core Web API and Angular. One is a coding task: write your own version of the array reduce method. The concept questions reward answers that name the mechanism (Include, navigation properties, a row version column, DbUpdateConcurrencyException) and then give a trade-off, so rehearse each as a short spoken answer with one concrete example from code you have written.

Candidates also report an emphasis on production-ready code and on explaining the reasons behind technical choices. For preparation, that means treating every practice exercise as if it were going to be deployed: validate input, return meaningful errors, name things clearly, write at least one test, and be able to say why you picked a library or pattern over its alternatives. Since an initial assignment is reported and later discussion is said to build on it, keep your own decisions in it easy to defend: you should be able to explain what you would refactor for scale and what you left out on purpose.

01

Initial Screening

reported

Candidates describe this first stage as a screening to check fit for the role. The reported material does not list questions for it, so treat it as the place where your .NET and Angular background is summarised and the logistics of the rest of the loop are confirmed. Candidates also report that prompt, professional communication with the recruitment contact matters throughout, so this is where that starts.

What to demonstrate

  • Fit for the role as candidates describe it: full-stack work across ASP.NET Core Web API and Angular
  • How clearly you summarise your own experience with Entity Framework and production code
  • Responsiveness and professionalism in how you communicate

How to prepare

  • Write a two-minute account of your most relevant project that names the Web API, the Angular piece and the data access layer you used
  • Prepare a one-line answer for each reported stack item: ASP.NET Core Web API, Angular, Entity Framework
  • Ask what the initial assignment involves and how its results are used in later rounds
Agilité Solutions Software Engineer candidate reports ↗
02

Hands-on Technical Validation

reported

Candidates describe this as a technical validation of coding skills and problem solving. A hands-on stage is where the reported coding and implementation questions are practised: building something with ASP.NET Core Web API and Angular, and writing a clone of the reduce array method. The framework-concept questions on lazy versus eager loading, abstract class versus interface, and Entity Framework concurrency belong to the same technical preparation. Candidates are advised to talk through their reasoning while coding.

What to demonstrate

  • Working code for the hands-on implementation and the reduce clone
  • Problem solving explained out loud as you go
  • Depth in .NET, Entity Framework and Angular, including why you chose a pattern or library
  • Production-readiness: error handling, naming and testing

How to prepare

  • Build a small endpoint plus Angular screen end to end under a time limit, with a DTO, validation, an error response and one test on each side
  • Implement your own reduce in TypeScript and test it with and without an initial value, on an empty array, and with the index and array arguments
  • Rehearse spoken answers on lazy versus eager loading and on Entity Framework concurrency, each with a short code example
  • Practise narrating decisions while you type, since the reported advice is to explain your reasoning as you work
Agilité Solutions Software Engineer candidate reports ↗
03

Behavioral Assessments

reported

Candidates describe this stage as behavioral assessments focused on team compatibility and cultural fit. The role description candidates report stresses articulating technical concepts, professional accountability and keeping stakeholders informed, so the stories that fit best are about technical decisions you owned, requirements you had to clarify, and work you took from prototype to production.

What to demonstrate

  • Team compatibility and cultural fit, as candidates describe the stage
  • How you explain technical decisions to non-specialists and teammates
  • Accountability for outcomes and how you update stakeholders

How to prepare

  • Write three stories with a situation, your decision, the alternative you rejected and the result, using work on APIs, Angular screens or data access
  • Prepare a story about choosing between an interface and an abstract class, and one about speeding up a slow endpoint, since both appear as reported example scenarios
  • Prepare one story where you clarified unclear requirements with a stakeholder before building
Agilité Solutions Software Engineer candidate reports ↗
04

Final HR Discussion

reported

Candidates describe the final stage as a discussion with HR about the offer and next steps. Candidates also report that professional maturity, communication and alignment with the company's culture come up in the closing stages. Preparation here is practical rather than technical.

What to demonstrate

  • Professional maturity and clear communication
  • Alignment with the company, as candidates describe it
  • Readiness to discuss offer details and next steps

How to prepare

  • Write down your notice period, location constraints and compensation expectations so you can state them plainly
  • Prepare two or three questions about the team's day-to-day work with ASP.NET Core and Angular
  • Decide in advance how you will keep in touch with your recruiter while decisions are pending
Agilité Solutions Software Engineer candidate reports ↗

PracHub editorial advice for the preparation topics above.

01

Defining lazy loading and eager loading without saying what each does to the SQL that runs

Tie each term to the queries it produces. Show a loop over parent rows that triggers one extra query per row (the N+1 pattern), then fix it with Include and ThenInclude, a projection with Select, or a split query. Turn on EF query logging in practice so you can describe the actual statements, and mention explicit loading as the third option.

02

Answering abstract class versus interface as a list of syntax differences

Give the deciding trade-offs: a class can inherit one base but implement many interfaces, an abstract class can carry shared state and implementation, and interfaces suit dependency injection and mocking in tests. Close with a concrete case from your own code, because choosing between the two is also a reported example scenario for the technical rounds.

03

Saying concurrency in Entity Framework is handled with transactions or locks, with no mention of a concurrency token or DbUpdateConcurrencyException

Lead with optimistic concurrency, a rowversion column and the exception, then say what the API returns and what the user sees. Add the pessimistic option as a contrast, with its cost, rather than as the whole answer.

04

Writing a reduce clone that only handles the happy path

Cover the no-initial-value case (the first element becomes the accumulator and iteration starts at index 1), an empty array with no initial value (the built-in throws a TypeError), the callback receiving accumulator, current value, index and array, and skipping holes in sparse arrays. Do not mutate the input, and write the tests as you go.

05

Handing in working code that is not production-ready, or being unable to justify choices in it

Before submitting any assignment or exercise, check for input validation, consistent error responses, clear names, at least one test per layer, and a short README of decisions and known limits. Keep a one-sentence reason for every library and pattern you used, plus the alternative you rejected, since candidates report that follow-up questions go to those reasons.

Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.

9 technical prompts0 include a worked solution

Create a clone of the reduce array method.

medium
Problem Solving and Logic

Create a clone of the reduce array method.

Approach
  1. Restate the contract before writing code. The callback receives (accumulator, currentValue, index, array). With an initial value, iteration starts at index 0. Without one, the first present element becomes the accumulator and iteration starts after it. An empty array with no initial value throws a TypeError, and so does a callback that is not a function.
  2. Detect a missing initial value with arguments.length (or a rest parameter's length), never with initialValue === undefined, because undefined is a legal seed. Write it as a standalone function, or define it with Object.defineProperty as non-enumerable if it must sit on Array.prototype. Overwriting a built-in is a choice you should be ready to defend.
  3. Loop over indices from 0 to a length captured once at the start. Skip holes with i in arr, the way the built-in does for sparse arrays. Pass the original array as the fourth argument. That gives O(n) time and O(1) extra space beyond whatever the callback builds.
  4. Test the edges aloud: a sum with and without a seed, a single-element array with no seed (returns that element without calling the callback), an empty array with a seed (returns the seed), an empty array without one (throws), and a sparse array.
  5. If the screen is in C#, the equivalent is LINQ Aggregate. The overload without a seed throws InvalidOperationException on an empty sequence, and the seeded overload returns the seed. A generic signature such as reduce<T, U>(arr: T[], fn: (acc: U, cur: T, i: number, a: T[]) => U, init: U): U shows type thinking in TypeScript.
Follow-up
  • Implement map and filter using only your reduce.
  • How would you write reduceRight, or a version that awaits an async callback in sequence?
  • What happens if the callback pushes to or deletes from the array during iteration?

Find overlapping job attempts and peak concurrency from lease records

medium
sweep lineintervalsleases

A day of job_run history yields about 50,000,000 attempt records: (job_run_id, job_type, attempt, started_at, finished_at which is NULL when the worker died, lease_expires_at). Leases expire on a clock, so a job that outran its lease ran twice. Produce (a) every job_run_id whose attempts overlapped in wall-clock time and (b) the peak number of simultaneously running attempts per job_type with the minute it occurred. Target O(n log n). State how you treat a NULL finished_at and what clock skew does to your answer.

Approach
  1. Define the interval before sorting anything: an attempt occupies [started_at, COALESCE(finished_at, lease_expires_at)). finished_at is observed and lease_expires_at is only a promise, so every attempt without a finish contributes an estimate and the whole result is a lower bound on overlap rather than an exact count.
  2. For peak concurrency, sweep: emit 2n endpoints, sort by (timestamp, kind) with ends ordered before starts at equal timestamps, then walk the sequence maintaining a counter per job_type and record each type's maximum with its timestamp. O(n log n) dominated by the sort, O(n) space, or O(1) extra if the sort is external and the walk streams.
  3. For overlap detection, do not compare attempts pairwise. A single global sort by (job_run_id, started_at) gives both the grouping and the order; within a group, keep the maximum end seen so far and report an overlap exactly when the next start is less than that running maximum, which is one linear pass after the sort.
  4. Half-open intervals matter and are easy to get wrong: with closed intervals an attempt ending at the same millisecond another begins reads as concurrency two, and across 50,000,000 records that artefact swamps the real signal.
Follow-up
  • A handler is not idempotent and you have found 400 overlapping jobs. Which of them actually caused damage, and what would you query to find out?
  • Peak concurrency for one job_type is 4 against a configured cap of 4. Is the cap working, or is the data hiding attempts that never started?

Archive a resource graph without breaking live references or recursing

medium
graph traversaltopological ordertenant isolation

Resources reference other resources within a tenant; for the largest tenant the reference table holds up to 2,000,000 nodes and 8,000,000 edges. Archiving a resource must archive everything reachable from it that nothing outside the set still references, refuse when a live external referrer exists, and terminate when references form cycles, which they legitimately do. Produce the archive order and the refusal list, targeting O(V+E). Say what stops the traversal crossing a tenant boundary, and why recursion is the wrong control structure at this size.

Approach
  1. Load the subgraph with the tenant predicate on both endpoints of the edge, not only on the side you started from. Scoping the left table alone is the classic cross-tenant leak: one mis-entered edge then pulls another tenant's resources into the traversal and, worse, into the archive.
  2. Traverse iteratively with an explicit stack. A 2,000,000-node graph can hold a chain deep enough to exhaust a native stack in the low tens of thousands of frames, and that failure is a process crash rather than an error you can return.
  3. Treat cycles as data rather than corruption: compute strongly connected components with Tarjan in O(V+E) using its own explicit stack, then condense. The condensation is a DAG, so a topological order over it gives the archive order, and every member of a component archives in one transaction because no order within a cycle is valid.
  4. Decide refusals with reverse edges. A candidate is archivable only if every in-edge originates inside the candidate set, so build the transpose or count in-degrees restricted to the visited set, and emit each blocked resource with the id of the external referrer, which is the only part of the answer an operator can act on.
Follow-up
  • The graph is read in one query and the archive writes a minute later. What can change in between, and how do you make the write safe?
  • The candidate set is 400,000 resources. Is that one transaction, and if not, what does a half-finished archive look like to a reader?

The plan follows the reported loop: Entity Framework and concurrency first, then the language and coding questions, then a full Web API plus Angular build, behavioral stories, and a closing dry run. PracHub practice-library questions on SQL paging, indexing and behavioral decisions are pointed at where they support the stack.

Small steps. Visible outcomes.0 / 7 completed
ONE WEEK · YOUR PACE

Prepare, practise & reflect

One practical outcome each day. Spend longer where you need it.

0 / 7 done
01Map the loop and set up a vertical slice
  • Write the four reported rounds in order and note what you will need for each; mark the one you are least ready for
  • Create a small ASP.NET Core Web API project with one entity, an Entity Framework context and a controller, and an Angular app with one service and one component that call it
  • Write down the five reported questions and rate your confidence on each from 1 to 5

Deliverable: A one-page loop map, a running API plus Angular slice, and a ranked list of the five reported questions.

02Entity Framework: lazy versus eager loading
  • Add a parent-child relationship to your slice and turn on query logging
  • Reproduce an N+1 pattern with lazy loading, then fix it with Include, then with a Select projection, and compare the SQL each produces
  • Speak a two-minute answer on lazy versus eager loading, including explicit loading and when each is the right call

Deliverable: A before-and-after query log showing the N+1 fix, plus a recorded spoken answer.

Practice prompt ↗
03Entity Framework: concurrency
  • Add a rowversion column to the entity and trigger DbUpdateConcurrencyException by saving from two contexts
  • Write the handler: return 409 from the API with the current database values, and show a conflict message in Angular
  • Implement a database-wins and a client-wins resolution, then speak the answer including the pessimistic alternative

Deliverable: A working conflict scenario end to end, with both resolution strategies and a recorded spoken answer.

Practice prompt ↗
04Abstract class versus interface, and the reduce clone
  • Write a small example in C# where an interface and an abstract base class both make sense, and note which you would pick and why
  • Implement your own reduce in TypeScript, with tests for a missing initial value, an empty array, sparse arrays and the index and array arguments
  • Time yourself explaining your reduce implementation aloud while typing it from scratch

Deliverable: A C# example with a written trade-off paragraph, and a tested reduce clone you can rebuild from memory.

Practice prompt ↗Practice prompt ↗
05Hands-on Web API and Angular, plus query performance
  • Build one feature under a time limit: a validated create and list endpoint with a DTO, consistent error responses, an Angular form and list, and one test on each side
  • Review your code as if it were going to production and write the refactors you would make for scale
  • Work PracHub's practice questions on replacing offset paging with keyset paging and on why an owner filter ignores the listing index, then explain how you would apply them to a slow endpoint

Deliverable: A finished feature with tests, a written refactor list, and notes on how each of the two SQL practice questions applies to a slow API endpoint.

Practice prompt ↗Practice prompt ↗Practice prompt ↗
06Behavioral stories
  • Write three stories with your decision, the alternative you rejected and the result, drawn from API, Angular or data access work
  • Write a story about choosing between an interface and an abstract class, and one about optimizing a slow endpoint
  • Practise PracHub's behavioral questions on shipping under a deadline and on telling callers their integration will break, and speak each answer aloud

Deliverable: Three written stories and two spoken practice answers, each ending with a result.

Practice prompt ↗Practice prompt ↗
07Full dry run and HR logistics
  • Run a mock: rebuild the reduce clone and extend a Web API endpoint with an Angular change, narrating your reasoning throughout
  • Answer the concept questions on lazy versus eager loading, abstract class versus interface and concurrency from memory
  • Write your notice period, location constraints and expectations, and two questions about the team's work for the final discussion

Deliverable: A narrated mock, a pass or fail list of the concept answers, and a one-page HR sheet.

Practice prompt ↗Practice prompt ↗Practice prompt ↗Practice prompt ↗Practice prompt ↗

Expand any day for tasks and deliverables. Your progress is saved on this device.

Candidates describe the behavioral stage as an assessment of team compatibility and cultural fit, and the role description they report stresses explaining technical ideas clearly, accountability and keeping stakeholders informed. Prepare stories where you owned a technical decision on APIs, Angular screens or data access, and can state what you chose, what you rejected and what happened.

How do you handle concurrency in EntityFramework?

medium
Technical Foundations and Frameworks

How do you handle concurrency in EntityFramework?

Approach
  1. Name the problem first: two users load the same row, both edit it, and the second save silently overwrites the first (a lost update). Entity Framework Core uses optimistic concurrency, so it holds no lock between the read and the write; it detects the conflict at save time.
  2. Add a concurrency token. On SQL Server that is a rowversion column, mapped with [Timestamp] on a byte[] property or IsRowVersion() in the model builder; for non-rowversion databases mark chosen properties with [ConcurrencyCheck] or IsConcurrencyToken(). EF then adds the token to the WHERE clause of UPDATE and DELETE statements, and when zero rows match it throws DbUpdateConcurrencyException.
  3. Handle the exception with an explicit policy. Catch it, read entry.OriginalValues, entry.CurrentValues and await entry.GetDatabaseValuesAsync(), then choose database wins (reload and discard the edit), client wins (copy database values into OriginalValues and save again) or a field-by-field merge. In a Web API, return 409 Conflict (or 412 with an ETag and If-Match header) and let Angular show the user what changed.
  4. In a Web API the token must travel with the DTO to Angular and back, and you must assign it to the entity's OriginalValue before saving. If you reload the row fresh and save, the check compares the token against itself and never fires. Cover deletes, and use bounded retries only for merges that are safe to repeat.
  5. Know the pessimistic alternative and its cost: a transaction at Serializable or Snapshot isolation, or raw SQL with UPDLOCK, holds locks and risks blocking and deadlocks. For counters or stock, an atomic ExecuteUpdate such as SET Stock = Stock - 1 WHERE Stock > 0 avoids the conflict entirely. Optimistic suits low contention; pessimistic suits hot rows where retries would pile up.
Follow-up
  • Why must the row version be sent to the Angular client and returned with the update request?
  • When would you pick pessimistic locking or an atomic ExecuteUpdate over a concurrency token?
  • What goes wrong with an unbounded retry loop around DbUpdateConcurrencyException?

Ship under a deadline and bound the debt you chose

medium
paginationtechnical debttradeoffs

You have four days to ship a tenant-facing listing endpoint. The version you would defend uses keyset pagination over (tenant_id, status, updated_at DESC, resource_id DESC); the version you can finish uses LIMIT/OFFSET with no matching index. Describe a deadline call you actually made of this shape: what you shipped, what you knowingly deferred, how you bounded the damage with a mechanism rather than an intention, and the specific numeric condition that would force the follow-up. Name who you told and where you wrote it down.

Approach
  1. Name the deferred failure precisely instead of calling it slow. OFFSET n makes the database produce and discard n rows, so cost grows with page depth; without an index matching the sort, every matching row is read and sorted before the limit applies; and rows inserted between two page fetches shift across the boundary so items are skipped or repeated with nothing in the response to signal it.
  2. Bound the blast radius with something mechanical rather than a promise: cap maximum page depth, cap page size, restrict the endpoint to one internal caller, or keep it behind a flag. State which failure each cap removes and which it leaves standing.
  3. Attach a number to the trigger and wire it to an alarm: the first tenant crossing N resources, or the endpoint's p99 crossing its share of the 400 ms budget, so the debt announces itself instead of waiting to be remembered.
  4. Write it where the next engineer looks, which is the code and the ticket, not a chat message: what was deferred, why, the cap, and the trigger.
Follow-up
  • At what page depth does the offset version breach your latency budget, given your page size and row counts?
  • What breaks first when you switch to keyset pagination later, and what does a client holding an old page token see?

Tell callers you do not own that their integration breaks

medium
deprecationcompatibilitystakeholders

A field in a write endpoint's response must change shape. You own the endpoint; you do not own the four internal callers or the outbound webhook consumers who read it. Describe a deprecation you were responsible for: what you shipped first, how you established who was actually reading the field, the window you gave and what set its length, what you did about the consumer who never moved, and how you decided removal was safe. Name the signal you used, not the announcement you sent.

Approach
  1. Establish the reader set empirically rather than from a wiki of owners: per-field usage counters keyed by principal, or access logs attributed to a consumer. State the blind spot of whichever you pick, since a consumer that reads the field only on a monthly job will not appear in a week of logs.
  2. Ship additive first. Populate the new field alongside the old one so no reader is forced to move, which is also what keeps a rolling deploy safe, because old and new instances answer the same requests at the same time and a rollback must still find the old shape present.
  3. Set the window from the slowest legitimate consumer's release cadence, not from your calendar, and decide separately what to do for a consumer with no release process at all, such as an external webhook endpoint you can only email.
  4. Convert silence into evidence before you rely on it: a short, low-traffic removal window that makes a still-dependent consumer fail visibly and loudly while you are watching, rather than at three in the morning after you have moved on.
Follow-up
  • How would you detect a consumer that reads the field only during a monthly export?
  • One caller refuses to move and has a commercial relationship behind it. What changes in your plan and what does not?
  • 01

    How do you handle concurrency in EntityFramework?

  • 02

    Describe a scenario where you had to choose between an interface and an abstract class.

  • 03

    Explain how you would optimize a slow-performing API endpoint.

  • 04

    Tell me about a time you took code from a working prototype to something you were willing to deploy, and what you added.

  • 05

    Describe a time you had to clarify unclear requirements with a stakeholder before building, and what changed as a result.

  • 06

    Walk through a design pattern or library you chose in a past project or assignment, and the alternative you rejected.

PracHub preparation framework ↗
How long does the process typically take?

Candidates report four rounds spread over roughly 3-5 weeks, though the pace varies. Staying in prompt contact with your recruiter is the habit candidates mention, so reply quickly and ask what each step involves.

Agilité Solutions Software Engineer candidate reports ↗
Why do candidates report being turned down?

The reported reasons are struggling to explain the reasoning behind technical choices and not showing how code would be made production-ready. Prepare by giving a reason and a rejected alternative for each choice in your practice code, and by checking validation, error handling, naming and tests before you call anything finished.

Agilité Solutions Software Engineer candidate reports ↗
Is the process purely technical?

No. After the technical validation, candidates report behavioral assessments and a closing discussion with HR about the offer and next steps. Keep stories ready on accountability, communication with stakeholders and decisions you owned.

Agilité Solutions Software Engineer candidate reports ↗
Which topics should I study for the technical rounds?

The reported topics are .NET and ASP.NET Core Web API, Angular, Entity Framework, hands-on practical implementation and concurrency. The reported questions cover lazy versus eager loading, abstract class versus interface, Entity Framework concurrency, a Web API plus Angular implementation, and a clone of the reduce array method.

Agilité Solutions Software Engineer candidate reports ↗
Is there an assignment, and how should I treat it?

Candidates report an initial assignment and say later technical discussion builds on it. Ask the recruiter for the format, and build it as if it were going to production: error handling, clear names, documentation and tests. Be ready to explain why you used any pattern or library and what you would refactor for scale.

PracHub Software Engineer practice ↗
How should I prepare for the reduce clone?

Write it from scratch in TypeScript or JavaScript and test the edge cases: a missing initial value, an empty array with no initial value, the callback receiving the accumulator, current value, index and array, and sparse arrays. Then practise explaining each decision aloud while you type, since talking through your thinking is the reported advice for the technical rounds.

PracHub Software Engineer practice ↗
Sources & methodology 3 sources ↗

No official company page is cited. Rounds and questions come from candidate reports and PracHub editorial material; each source shows the date it was read.