cswork / libraryOpen practice workspace

Interview guides · Americaneagle

Americaneagle Software Engineer Interview Guide

Americaneagle Software Engineer interview guide: 3 reported rounds, C#/.NET, SQL Server, Next.js and Sitecore questions, plus a 7-day prep plan.

The 60-second brief

Americaneagle (Americaneagle.com) is described by candidates as a digital agency. Its engineers build custom websites, enterprise web applications and e-commerce sites for client organizations in a range of industries. The reported back-end stack is C#, .NET Core and ASP.NET MVC with SQL Server, though the role listing also names PHP and MySQL. On the front end it is React and Next.js. Engineers also work with content and commerce platforms: Sitecore (including XM Cloud and Sitecore AI), Sitefinity, Kentico, BigCommerce and WordPress. Listed responsibilities that candidates describe include writing SQL queries and stored procedures, converting Figma designs into responsive pages, helping with builds and deployments (Azure DevOps, AWS or GitHub Actions) and communicating trade-offs to project managers and client teams. The work is reported to range from migrating older ASP.NET MVC sites to headless, composable builds, and candidates describe breadth across stacks rather than a single internal product.

This guide is for Software Engineer candidates preparing for Americaneagle, whether your specialization is a .NET back end, a React or Next.js front end, or Sitecore and other CMS work. It covers the three reported rounds, the nineteen reported questions grouped by topic (.NET and C#, SQL Server, front end and CMS, project experience), a seven-day plan and behavioral preparation. Requirements candidates describe run from junior roles (about a year of programming, or a strong academic portfolio in C#, PHP and SQL) to mid-senior roles (four to five years, ownership of features or mentoring, and agency or client-facing work).

Candidates report three rounds: an HR Phone Screen, a Technical Assignment and Technical and Management Interviews. Elapsed time is quoted as 3-5 weeks in one set of reports and 2-4 weeks in another. The stages are what candidates describe, not a published process.

Focus areas

  • C# (.NET)
  • Coding Skills (hands-on programming)
  • LINQ

Overview

The loop is short and practical. Candidates describe a recruiter call, then a take-home project or skills test, then a final stage with technical managers and executives who go back over your test and your past projects. Reported difficulty is average, and candidates report practical engineering questions, not algorithm puzzles. Preparation therefore means being able to produce working code in your main stack and to explain every choice in it.

The nineteen reported questions fall into four groups. The .NET group covers the MVC request flow, LINQ and Entity Framework, SOLID in a .NET solution, custom validation controls, and consuming REST and SOAP services from C#. The SQL Server group covers clustered versus non-clustered indexes, joins with GROUP BY for data grids, designing a schema from a business scenario, diagnosing slow queries, and views or stored procedures versus inline queries. The front-end and CMS group covers SSR, SSG and ISR in Next.js, client versus server components, Sitecore AI, XM Cloud and Content Hub experience, fetch and AJAX clients, and state and bundle management. The project group covers a project you are proud of, the architecture of a feature you built from scratch, performance monitoring with New Relic or AppDynamics, and Git with Gitflow.

Candidates report that database fundamentals, indexing and joins above all, come up repeatedly in the early technical stages. Give those the most time: be able to read an execution plan, say why a query scans instead of seeks, and explain what a non-clustered index costs on writes. Next, rehearse the one stack you would be hired for in enough depth to write code from memory (model binding and validation in ASP.NET, EF query shapes, rendering modes in Next.js). Finally, prepare two project stories you can demo from a working repository, because the final stage is reported to revolve around your test and your earlier work.

The Americaneagle interview process

Candidates describe three stages: a recruiter call, a technical assignment (a take-home project or a skills test), and final interviews with technical managers and executives. Each stage below lists what candidates describe and how to prepare for it.

HR Phone Screen

Candidates describe this as a phone call with HR or a recruiter that goes over your background, your compensation expectations and the projects you have worked on. It is the first filter, so treat it as a short, rehearsed pitch: a career narrative that lands on the stack you want to work in, plus one project told in a few sentences with your role, the technologies and one hard problem. The role is reported to vary by specialization (.NET, front end, or Sitecore), so say which one you are targeting and be accurate about where you are strongest.

What to demonstrate

  • Your background and the projects you have delivered
  • Your compensation expectations
  • Which specialization you fit: .NET back end, front end or CMS work

How to prepare

  • Write a short career narrative that ends on the stack you are applying for, and a one-paragraph summary of your best project that names your role, the stack and one implementation challenge.
  • List your real experience level in each reported technology (C#/.NET Core, SQL Server, React/Next.js, Sitecore, Azure DevOps) so you can answer honestly without overselling.
  • Decide your compensation range and location constraints before the call so you can state them plainly.

Technical Assignment

Candidates report either a take-home project or a written or online skills test. Reports say it can touch C#, writing database queries, integrating a web service and front-end implementation, with tasks that feel like client work around validation, joins and API calls. Candidates also report that a submission with broken package dependencies or unhandled database exceptions counts against you. The reviewers go back over this work in the final stage, so keep your code explainable.

What to demonstrate

  • Working code in your main stack that builds and runs
  • Query writing: joins, grouping and efficient SQL
  • Web service integration with sensible error handling
  • Clear structure you can defend later

How to prepare

  • Build a small practice app: an ASP.NET MVC or .NET Core form with a custom validation attribute, an EF Core query joined and grouped into a table view, and an HttpClient call to an external API, then rerun it from a fresh clone to confirm restore and database setup work.
  • Wrap database and HTTP calls so failures return a handled result instead of a stack trace; write a few tests for the validation rule and the query.
  • Practise the SQL by hand: an inner join plus a LEFT JOIN with GROUP BY and HAVING, then check the plan for scans versus seeks.
  • Because this stage can be a written or online test, do a timed session: write C# snippets and SQL queries from memory without an IDE, then answer short conceptual questions such as IEnumerable vs IQueryable and clustered vs non-clustered indexes.

Technical and Management Interviews

Candidates describe final interviews with technical managers, project leaders and executive leadership (a CTO or directors are mentioned), held over Microsoft Teams or in person. They go through your technical test, ask you to present past work, and include deep-dive architecture and situational questions. No reported question is tied to a specific round: the project questions (a project you are proud of, a feature built from scratch, performance monitoring, Git and Gitflow) are reported across the process, and this stage is where candidates describe presenting past work.

What to demonstrate

  • Your reasoning about your own technical test
  • Depth in projects you can walk through or demo
  • Architecture and situational judgment
  • Clear communication of trade-offs to technical and non-technical people

How to prepare

  • Reread your assignment submission and list what you would change with more time, plus the trade-offs you made on purpose.
  • Keep a clean, runnable repository or demo link for one past project and rehearse a walkthrough: goal, your role, architecture, one hard problem, the result.
  • Prepare an architecture story for a feature built from scratch and a performance-monitoring story with real before-and-after numbers from your own work, plus a two-sentence explanation of your Gitflow and pull request habits.
  • Practise explaining one decision in both technical and business terms.

Where candidates lose points

Submitting a take-home that does not build from a clean clone, or that lets database exceptions bubble up unhandled

Clone your own submission into a new folder before sending it and run restore, database setup and the app. Keep connection strings in configuration, catch and handle failures at the data and HTTP boundaries, and include a short README with run steps.

Describing clustered versus non-clustered indexes as 'one is faster' without the structure behind it

Say that a table has one clustered index whose leaf level is the data rows in key order, and that a non-clustered index is a separate B-tree holding key columns plus a row locator. Mention key lookups, covering indexes with INCLUDE columns, and the extra write cost of each additional index, with a case where a new index hurts.

Answering the LINQ and Entity Framework question without saying when the query runs

Contrast IEnumerable (in-memory, pulls rows first) with IQueryable (translated to SQL). Show an N+1 pattern, fix it with Include or a Select projection, use AsNoTracking for read-only queries, and say you check the generated SQL.

Telling a project story that lists technologies but none of your own decisions, or having no working demo

Structure it as your role, the problem, one decision with the alternative you rejected, the result and what you would change. Keep the repository or demo link runnable before the final stage, since past work and the test are what get reviewed.

Treating SSR, SSG and ISR, or Sitecore experience, as vocabulary to recite or claim

Give a decision rule: SSR for per-request or personalised data, SSG for content that rarely changes, ISR for many pages that change occasionally and can be regenerated on a schedule or on demand. For Sitecore, XM Cloud or Content Hub, say exactly what you have built, and if it is nothing, describe the headless concept and the Helix layers you do know.

Questions & practice

How do you construct complex queries using inner/outer joins and GROUP BY clauses for data grids?

Medium · Relational Databases & SQL Server Perfor

Approach

  1. Start from the grain of one grid row (one row per region, per store or per customer) and pick the driving table at that grain. Join outward to the detail tables and GROUP BY every non-aggregated column in the SELECT.
  2. Choose INNER or LEFT JOIN on purpose. If the grid must show regions with no sales, use LEFT JOIN plus COALESCE(SUM(o.Total), 0). Put filters on the right-hand table (date range, status) in the ON clause: in WHERE they discard the NULL rows and turn the LEFT JOIN back into an inner join. With outer joins, COUNT(o.OrderId) counts matches, while COUNT(*) counts a NULL-extended row as 1.
  3. Guard against fan-out. Joining two one-to-many tables (orders and returns) to the same parent multiplies rows and inflates the SUMs. Aggregate each child in a subquery or CTE at the parent grain, then join the results. WHERE filters rows before grouping; HAVING filters groups after.
  4. Make it grid-ready. Page on the server with ORDER BY plus a unique tiebreaker and OFFSET @skip ROWS FETCH NEXT @take ROWS ONLY. Get the total row count from COUNT(*) OVER() or a separate count query. Map user-selected sort columns through a whitelist instead of concatenating them, and pass every filter as a parameter.
  5. Back the query with indexes on the join and filter columns, for example Orders(StoreId, OrderDate) INCLUDE (Total). Check the totals against a hand count on a small dataset before you trust the query.

Follow-up

  • The grid has to show every region, including ones with no stores yet. What changes in the joins?
  • Paging gets slow on page 5,000. Why does OFFSET degrade, and how would keyset pagination fix it?
  • How would you add a column showing each region's share of total sales?

When would you use database views or stored procedures over inline raw queries?

Medium · Relational Databases & SQL Server Perfor

Approach

  1. Views: use one to name a reusable join or filter (an active-customers view), to grant read access on the view instead of the base tables, and to shield reports from schema changes. A plain view stores no data; it is expanded into the calling query. An indexed view (WITH SCHEMABINDING plus a unique clustered index) materialises its results but adds cost to every write on the base tables.
  2. Stored procedures: use them for multi-statement logic that must run in one transaction, for set-based batch work close to the data, to cut round trips, and to grant EXECUTE instead of table permissions. Do not oversell plan caching: parameterised ad hoc queries run through sp_executesql reuse cached plans too.
  3. Inline or ORM queries keep logic in application code, where it is versioned, reviewed, refactored and unit tested with everything else, and LINQ queries compose. They are safe as long as values go in as parameters and are never concatenated.
  4. State the trade-offs. Procedures need their own deployment and versioning (migration scripts) and can split business rules across two places. Parameter sniffing affects any cached parameterised plan, including sp_executesql and EF-generated queries, so it is not a reason to prefer inline queries. ORM-generated SQL can be inefficient for complex reporting, which is a good case for a view or procedure called from EF.
  5. End with a rule of thumb you can defend: CRUD and simple reads through the ORM, complex reporting or bulk operations in a view or procedure, and a written record of the choice so the next developer knows where the logic lives.

Follow-up

  • Is a stored procedure automatically safe from SQL injection? What about dynamic SQL inside it?
  • How do you call a stored procedure from Entity Framework and map its result set?
  • How do you keep stored procedure changes in source control and deploy them with the application?

Collapse a redelivered event batch into per-aggregate high-water marks

Easy · hashing · at-least-once · aggregation

You drain a batch of up to 5,000,000 events, each (aggregate_id BIGINT, aggregate_version INT, event_type, payload). The log guarantees order within one aggregate only; the batch merges 64 partitions, and a relay failover has redelivered a range, so an older version for an aggregate can appear after a newer one. Given a map of last_applied_version per aggregate, produce the events worth applying, at most one per (aggregate_id, version), plus the count discarded. Target O(n) time. State the memory for 2,000,000 distinct aggregates and what you do when it does not fit.

Approach

  1. One pass, one hash map from aggregate_id to the highest version kept, and a discard counter. An event whose version is at or below last_applied_version for its aggregate is dropped without further work, which is the whole reason the event carries its version rather than a delta. O(n) expected time, O(d) space in distinct aggregates.
  2. Keep the maximum, never the last occurrence. The redelivered range means the final appearance of an aggregate in the batch can be an older version than one seen earlier in the same batch, so last-wins applies stale state over newer state and the projection regresses with no error anywhere.
  3. Cost the memory instead of calling it large: an 8-byte key plus a 4-byte version is 12 bytes of payload, and an open-addressed table held at a 0.7 load factor costs roughly 17 bytes per entry before per-slot metadata, so 2,000,000 aggregates is tens of megabytes in a native layout and several times that in a runtime that boxes both key and value.
  4. If the distinct set exceeds memory, partition on hash(aggregate_id) mod P and reduce each partition independently. Every event for one aggregate hashes to the same partition, so the per-partition result is exact and the merge is concatenation rather than a second reduction.

Follow-up

  • The payload is a patch rather than a snapshot, so applying only the highest version loses the intermediate changes. What changes in your reduction?
  • How do you detect that version 7 arrived while version 6 was never delivered, and what should the consumer do about the gap?

What is the difference between a Clustered Index and a Non-Clustered Index in SQL Server?

Medium · Relational Databases & SQL Server Perfor

Approach

  1. Clustered index: the table's data rows are stored in the leaf level of a B-tree ordered by the clustered key, so a table can have only one. A table without one is a heap. A PRIMARY KEY constraint creates a clustered index by default if the table has none.
  2. Non-clustered index: a separate B-tree whose leaf rows hold the index key plus a row locator. The locator is the clustered key, or a RID when the table is a heap. A table can have many (up to 999). When a query needs columns the index lacks, SQL Server does a key lookup per row (a RID lookup on a heap).
  3. Covering: add the extra columns with INCLUDE so the index alone answers the query and the lookup disappears from the plan. When many rows match, the optimizer may choose a scan over thousands of lookups.
  4. Choosing the clustered key: narrow, unique, static and ever-increasing (INT or BIGINT IDENTITY), because the key is copied into every non-clustered index. A random NEWID() GUID causes page splits and fragmentation on insert. NEWSEQUENTIALID() or a separate identity key avoids that.
  5. Costs and misconceptions: every non-clustered index adds work to INSERT, UPDATE and DELETE, plus storage. A clustered index does not guarantee the order of results; only ORDER BY does.

Follow-up

  • When would adding a non-clustered index make performance worse?
  • A query filters on LastName and returns Email. What index would you create, and what would the plan show before and after?
  • Why is a random GUID a poor clustered key, and what would you use instead?

How do you diagnose and optimize slow-running SQL database queries?

Medium · Relational Databases & SQL Server Perfor

Approach

  1. Reproduce and measure before you change anything. Capture the exact query and its parameter values, run it with SET STATISTICS IO, TIME ON and the actual execution plan, and record logical reads and elapsed time as the baseline. To find the queries that matter most, use Query Store or sys.dm_exec_query_stats ordered by total CPU or logical reads.
  2. Read the plan for the usual causes: scans where you expect a seek, key lookups repeated thousands of times, and large gaps between estimated and actual rows (stale statistics or parameter sniffing). Also look for sort or hash spills to tempdb and CONVERT_IMPLICIT warnings from a parameter type that does not match the column (NVARCHAR against VARCHAR).
  3. Fix the cause the plan shows. Make predicates sargable (OrderDate >= @start AND OrderDate < @end instead of YEAR(OrderDate) = 2024), add or widen an index with INCLUDE columns, and update statistics. Select only the columns you need instead of SELECT *, and replace cursors or row-by-row scalar functions with set-based logic.
  4. Check causes outside the query text. Look for blocking (blocking_session_id and wait types in sys.dm_exec_requests). Parameter sniffing means one cached plan suits only some values; OPTION (RECOMPILE) or OPTIMIZE FOR are targeted fixes. N+1 patterns from an ORM can run a fast query thousands of times.
  5. Prove the fix. Rerun with the same parameters, compare logical reads and duration against the baseline, check that the new index does not slow the write path, and keep the before and after plans or Query Store data.

Follow-up

  • The query is fast in SSMS but slow from the application. What could explain that?
  • Adding an index made one report faster and checkout slower. How do you decide what to keep?
  • How would you stop a slow-query regression from reaching production next time?

Explain the MVC architecture and how request processing flows through the controller to the view.

Medium · .NET, C#, and Object-Oriented Frameworks

Approach

  1. Trace one request from start to finish. In ASP.NET Core it enters the middleware pipeline (classic ASP.NET MVC uses HttpModules and the MvcHandler), routing matches the URL to a controller and action, the controller is created through dependency injection, and the action method runs.
  2. Explain model binding and validation before the action runs. Values come from route data, the query string, form fields or the body and are bound to parameters or a view model. Validation attributes fill ModelState, so the action checks ModelState.IsValid before it acts.
  3. Name the filter pipeline and say where cross-cutting code belongs. The order is authorization filters, then resource filters, then model binding, then action filters around the action, with result filters around the result and exception filters catching unhandled errors. Logging that every request needs can be middleware. Logic that needs the action context belongs in a filter.
  4. Finish on the view side. The action returns an IActionResult such as ViewResult, and the Razor view engine finds the view by convention (Views/{Controller}/{Action}.cshtml, then Views/Shared). It renders the view with its layout and partial views against a strongly typed model and writes the HTML response. An API controller returns JSON and never touches a view.
  5. State the separation of concerns. The model holds data and rules, the view only displays, and the controller stays thin by handing work to services. A controller that queries the database and builds HTML strings itself is the usual anti-pattern.

Follow-up

  • What is the difference between ViewData, ViewBag and TempData, and when does TempData survive a redirect?
  • Would you put request logging in middleware or in an action filter, and why?
  • How does attribute routing differ from conventional routing, and what happens when two routes match the same URL?

How do you configure and execute database interactions using LINQ and Entity Framework?

Medium · .NET, C#, and Object-Oriented Frameworks

Approach

  1. Configuration: define entity classes and a DbContext with DbSet properties, then register it with services.AddDbContext<AppDbContext>(o => o.UseSqlServer(connectionString)), which gives it a scoped (per-request) lifetime. Shape the mapping with conventions, data annotations or the Fluent API in OnModelCreating (keys, relationships, column types, indexes).
  2. Put schema changes through migrations. Run dotnet ef migrations add and review the generated code. Then apply it with dotnet ef database update locally, or with a generated SQL script for shared environments, so the schema stays in version control next to the model.
  3. Reads: a LINQ query on a DbSet is an IQueryable. EF translates it to SQL and runs it only when it is enumerated (ToList, First, Count, foreach). Filter and project with Where and Select before you materialise, so SQL Server does the work and returns only the columns you need. Add AsNoTracking to read-only queries to skip change tracking.
  4. Avoid N+1. With lazy loading, touching a navigation property inside a loop fires one query per row. Load related data with Include/ThenInclude or project into a DTO. Use AsSplitQuery when several collection Includes would multiply rows into a cartesian explosion.
  5. Writes: Add, Update or Remove entities, then call SaveChanges, which by default sends the changes inside one transaction. LINQ sends values as parameters. For raw SQL, use FromSql/FromSqlInterpolated or explicit bind parameters, never string concatenation into FromSqlRaw, so the query is not open to SQL injection.

Follow-up

  • What changes if you call ToList() before Where() on a large table, and how does IEnumerable differ from IQueryable here?
  • Two users edit the same record at once. How do you detect it with a rowversion concurrency token and handle DbUpdateConcurrencyException?
  • Why is it a problem to share one DbContext across threads or register it as a singleton?

What are the SOLID design principles, and how do you apply them in a.NET solution?

Medium · .NET, C#, and Object-Oriented Frameworks

Approach

  1. Define each principle with a .NET example. Single Responsibility means a class has one reason to change, so an OrderController that validates, saves and sends email gets split into a validator, an IOrderRepository and an INotificationService.
  2. Open/Closed and Liskov: add a new payment or shipping provider by writing a new class behind an IPaymentProvider interface instead of growing a switch statement. Every implementation must honour the interface's contract. ReadOnlyCollection<T> throwing NotSupportedException from ICollection<T>.Add is a well-known .NET case where substituting one implementation for another surprises callers.
  3. Interface Segregation and Dependency Inversion: prefer small role interfaces (an IProductReader for a page that only reads) over one wide repository interface. High-level services depend on abstractions, which the ASP.NET Core container supplies through constructor injection (AddTransient, AddScoped, AddSingleton).
  4. Show the payoff. Because dependencies arrive as interfaces, a service can be unit tested with a fake or a mocking library such as Moq. You can also swap SQL Server for an external API behind the same interface without touching any caller.
  5. Name the cost. An interface for every class that has one implementation, or extra layers over a small CRUD page, adds indirection with no benefit. Also watch DI lifetimes: a singleton that captures a scoped service such as a DbContext keeps it alive after its request ends.

Follow-up

  • Explain transient, scoped and singleton lifetimes, and what goes wrong when a singleton depends on a scoped service.
  • Show me a place in a past project where you broke one of these principles on purpose, and why.
  • How does the Dependency Inversion principle differ from dependency injection?

What are custom validation controls in ASP.NET, and how do you build and bind them?

Medium · .NET, C#, and Object-Oriented Frameworks

Approach

  1. First, clarify which ASP.NET. In Web Forms, a custom validation control is a CustomValidator (or a class derived from BaseValidator) attached to an input through ControlToValidate. In MVC and ASP.NET Core, the equivalent is a custom validation attribute on the model. Cover the one the role uses and mention the other.
  2. Web Forms: handle the ServerValidate event and set args.IsValid from your rule. Add a ClientValidationFunction for the JavaScript check, group related validators with ValidationGroup, and check Page.IsValid in the postback handler. A CustomValidator skips empty input unless ValidateEmptyText is true, so pair it with a RequiredFieldValidator.
  3. MVC / Core: derive from ValidationAttribute and override IsValid(object value, ValidationContext context) to return ValidationResult.Success or an error. For rules that span fields (end date after start date), use IValidatableObject or a class-level attribute. Model binding runs the attribute and fills ModelState. The action checks ModelState.IsValid, and [ApiController] returns 400 automatically.
  4. Client side: implement IClientModelValidator to emit data-val-* attributes and register a matching jQuery unobtrusive validation adapter. Always keep the server check too, because a direct POST bypasses client-side validation.
  5. Edge cases: null and whitespace input, culture-specific number and date formats, and rules that need the database (such as a unique email). Database rules belong in a service or a Remote attribute call, not in a pure attribute. Unit test the attribute with Validator.TryValidateObject and validateAllProperties set to true.

Follow-up

  • How would you validate that an end date falls after a start date, both on the server and in the browser?
  • A rule needs a database lookup, such as a unique username. Where do you put it, and how do you avoid a race between the check and the insert?
  • How do you show validation messages next to the right field and keep the user's input after a failed post?

How do you interact with and consume external REST/SOAP web services in a C# application?

Medium · .NET, C#, and Object-Oriented Frameworks

Approach

  1. REST: use HttpClient through IHttpClientFactory, as a named or typed client registered with AddHttpClient. Creating a new HttpClient per call can exhaust sockets, and a single static instance can miss DNS changes unless PooledConnectionLifetime is set. Keep the base address, headers and auth in configuration.
  2. Stay async from end to end: await GetAsync or PostAsJsonAsync and pass a CancellationToken. Never use .Result or .Wait(): they can deadlock under classic ASP.NET's synchronization context and block threads anywhere. Check the status code before deserialising into DTOs with System.Text.Json or Newtonsoft.Json, and map 4xx and 5xx responses to distinct application errors.
  3. Resilience: set an explicit timeout (HttpClient defaults to 100 seconds). Retry only transient failures (5xx, 408, 429, network errors) with exponential backoff and jitter, honour Retry-After on a 429, and add a circuit breaker. Polly or Microsoft.Extensions.Http.Resilience adds these as handlers on the client. Retry a POST only if the API accepts an idempotency key.
  4. SOAP: generate a client proxy from the WSDL with Add Service Reference or dotnet-svcutil, then configure the binding, endpoint and security (for example BasicHttpBinding with transport security). Wrap the generated client behind your own interface so the rest of the code never sees SOAP types.
  5. Isolate and test. Put the integration behind an interface such as IInventoryClient and unit test it with a stub HttpMessageHandler. Log a correlation ID and the latency of each call. Keep credentials in configuration or a key vault, never in source.

Follow-up

  • The API rate-limits you and you have a large batch of records to sync. How do you throttle the job and resume it after a failure?
  • How do you unit test code that calls HttpClient without hitting the real service?
  • The vendor renames a response field without notice. How does your code fail, and how would you find out?

Design a relational database schema from scratch based on a provided business domain scenario.

Medium · Relational Databases & SQL Server Perfor

Approach

  1. Read the scenario for nouns and verbs before drawing tables. List the entities (for an online store: Customer, Address, Product, Category, Order, OrderLine), their key attributes and every relationship with its cardinality. Ask about rules the text leaves open, such as whether a customer can have several addresses.
  2. Normalise to third normal form: atomic columns and no repeating groups (1NF), every non-key column depending on the whole key (2NF), and no non-key column depending on another non-key column (3NF). Resolve many-to-many relationships with a junction table such as ProductCategory(ProductId, CategoryId) that has a composite primary key.
  3. Keys and integrity: surrogate INT IDENTITY primary keys and UNIQUE constraints on natural keys (Email, SKU). Give each foreign key a delete rule you chose on purpose (restrict for orders, cascade only for dependent rows where it is safe). Add NOT NULL where required and CHECK constraints (Quantity > 0), store money as DECIMAL rather than FLOAT, and use datetime2 for timestamps.
  4. Denormalise only on purpose, and say why. OrderLine stores the UnitPrice at the time of purchase, because product prices change and an order is a historical record. A reporting rollup table is fine if you explain how it stays in sync.
  5. Close with access patterns. Name the main queries the screens need, index the foreign key columns (SQL Server does not index them automatically), and add audit columns (CreatedAt, UpdatedAt) or a soft-delete flag only if the scenario needs history.

Follow-up

  • Products now come in sizes and colours with different prices and stock. How does the schema change?
  • A customer deletes their account, but their orders must be kept for accounting. How do you model that?
  • Which of these tables would you denormalise for a reporting dashboard, and how would you keep it consistent?

What are the primary differences between Server-Side Rendering (SSR), Static Site Generation (SSG), and Increm

Medium · Modern Front-End Frameworks & CMS Ecosys

What are the primary differences between Server-Side Rendering (SSR), Static Site Generation (SSG), and Incremental Static Regeneration (ISR) in Next.js?

Approach

  1. SSG builds the HTML at build time (getStaticProps in the Pages Router, default static rendering in the App Router) and serves it from a CDN. Responses are the fastest and server cost is lowest, but content stays as built until the next build.
  2. SSR renders on every request: getServerSideProps in the Pages Router. In the App Router a route becomes dynamic when it reads cookies() or headers(), uses fetch with cache: 'no-store', or sets dynamic = 'force-dynamic'. Pages are always fresh and can be personalised, at the cost of higher time to first byte and server work on every hit.
  3. ISR serves a static page and regenerates it in the background after a revalidate window: return revalidate: 60 from getStaticProps, or in the App Router use export const revalidate = 60 or fetch with next: { revalidate }. The first request after the window gets the stale page and triggers regeneration; later requests get the new one. If regeneration throws, Next.js keeps serving the last good version.
  4. With a headless CMS, add on-demand revalidation: a publish webhook from the CMS calls a route that runs revalidatePath or revalidateTag (res.revalidate in the Pages Router), so editors do not wait for the timer or a rebuild. For pages created after the build, use getStaticPaths with fallback: 'blocking', or dynamicParams in the App Router.
  5. Decide page by page. Marketing and content pages: SSG or ISR. Product and listing pages: ISR with on-demand revalidation. Cart, account and anything user-specific: SSR or client-side fetching. For each page, say how much staleness it can tolerate.

Follow-up

  • An editor publishes a price change that must appear within seconds. How do you set that up?
  • What happens to an ISR page if the CMS is down when regeneration runs?
  • Which parts of a product page would you render on the server, and which would you fetch on the client?

How do client components differ from server components in modern React frameworks?

Medium · Modern Front-End Frameworks & CMS Ecosys

Approach

  1. In the Next.js App Router, a component is a server component unless its file starts with the 'use client' directive or is imported from such a file. Server components run only on the server. They can be async, read from a database or a CMS API with secrets, and their code never ships in the browser bundle.
  2. Client components can use state, effects, event handlers and browser APIs (useState, useEffect, onClick, window). They are still prerendered to HTML on the server and then hydrated in the browser, and everything they import joins the client bundle.
  3. Boundary rules: props passed from a server component to a client component must be serialisable, so no functions except Server Actions and no custom class instances. A client component cannot import a server component, but it can render one passed in as children or another prop. That is how a client-side provider wraps server-rendered content.
  4. Design choice: keep 'use client' at the leaves, for example a small AddToCartButton inside a server-rendered product page, so data fetching stays on the server and the bundle stays small. Import 'server-only' in modules that hold secrets, so an accidental client import fails the build.
  5. Contrast with the Pages Router and plain client-side React: there every component ships to the browser, and server data arrives through getServerSideProps, getStaticProps or client-side fetching.

Follow-up

  • How would you share a cart count between a client-side header and server-rendered pages?
  • What causes a hydration mismatch error, and how do you fix one?
  • Can a server component use React context? If not, how do you provide a theme to the tree?

Do you have experience working with Sitecore AI, XM Cloud, or Content Hub architecture?

Medium · Modern Front-End Frameworks & CMS Ecosys

Approach

  1. Answer the yes-or-no part honestly in your first sentence, then back it up: which product (XM Cloud, Content Hub or Sitecore AI), which version, your role on the project, and one concrete thing you built, such as a component with its data template and rendering.
  2. If you have used XM Cloud, show you know the headless shape. Content is authored in the CMS and published to Experience Edge, and a Next.js rendering host reads it over GraphQL through Sitecore's JavaScript SDK (JSS). Say how editors previewed changes and how deployments ran.
  3. Show structural knowledge where it applies: templates and standard values, renderings with datasource items, SXA for site scaffolding, and Helix's Foundation, Feature and Project layers. Be ready to explain why Feature modules should not depend on each other.
  4. If you have not used these products, bridge from what you have: another CMS (Kentico, Sitefinity, WordPress or a headless CMS) and the shared concepts behind it (content modelling, mapping components to content, GraphQL or REST delivery APIs, caching, publish workflows). Then say exactly how you would ramp up, such as building a small XM Cloud site from Sitecore's developer documentation.
  5. Avoid vague claims. Naming a module you cannot describe hurts more than admitting a gap, so prepare one technical detail you can defend for every product you list.

Follow-up

  • How would you model a reusable hero banner so editors can share its content across pages?
  • In a headless Sitecore setup, how does content reach the Next.js front end, and where would you cache it?
  • What would you check first if published content does not appear on the live site?

How do you consume web services or APIs using AJAX or modern JavaScript fetch clients?

Medium · Modern Front-End Frameworks & CMS Ecosys

Approach

  1. Show fetch with its real semantics. The Promise rejects only on a network failure, so a 404 or 500 still resolves. Check response.ok (or the status) before calling response.json(), and turn non-2xx responses into errors the UI can display.
  2. For writes, set the method, a 'Content-Type': 'application/json' header and body: JSON.stringify(payload). jQuery $.ajax and XMLHttpRequest do the same job in older code. axios rejects on non-2xx responses by default, which is one reason teams use it.
  3. Timeouts and cancellation: fetch has no timeout of its own, so use AbortController or AbortSignal.timeout(ms). For search-as-you-type, debounce the input and abort the previous request, so a slow, stale response cannot overwrite a newer one.
  4. Cross-origin calls: the API must send Access-Control-Allow-Origin, and a JSON POST triggers a preflight OPTIONS request. Sending cookies needs credentials: 'include', plus Access-Control-Allow-Credentials and a specific (non-wildcard) origin. Never put a secret API key in browser code; call your own server route that holds the key.
  5. UI states: render loading, empty, error and success explicitly. Disable the submit button while a request is in flight to prevent double submits, and retry only idempotent GETs automatically.

Follow-up

  • Two responses for the same search box arrive out of order. How do you make sure the screen shows the latest one?
  • The API needs a secret key. How do you call it from a React page without exposing the key?
  • How do you handle a 401 when the user's session expires mid-form?

How do you manage component state and bundle optimization in client-side applications?

Medium · Modern Front-End Frameworks & CMS Ecosys

Approach

  1. Classify state before you choose a tool. Local UI state goes in useState or useReducer. State shared by a few components is lifted to their common parent. Server data is cached with a library such as React Query or SWR rather than copied into a global store. Filters and page numbers live in the URL query string. A global store (Redux Toolkit, Zustand) is only for state the whole app needs.
  2. Avoid needless re-renders. Do not store values you can derive. Every consumer of a Context re-renders when its value changes, so split contexts or memoise the value. Add React.memo, useMemo or useCallback where the React Profiler shows a cost, not by default.
  3. Measure the bundle first with a bundle analyzer (@next/bundle-analyzer, webpack-bundle-analyzer or source-map-explorer) and Lighthouse, then go after the largest chunks. Code-split heavy or below-the-fold components with dynamic import(), React.lazy or next/dynamic, and load route code per page.
  4. Shrink dependencies. Use ES module imports that tree-shake (named lodash-es imports instead of all of lodash) and replace heavy libraries (moment with date-fns or Day.js). In Next.js, keep components that only render data as server components so their code stays off the client.
  5. Back the change with numbers. Compare bundle size and Core Web Vitals (LCP, INP, CLS) before and after on a throttled mobile profile.

Follow-up

  • A Context provider at the root makes the whole app re-render on every keystroke. How do you fix it?
  • When is memoisation a waste, or even slower?
  • How do you keep a bundle-size regression from merging unnoticed?

Walk me through a project you are most proud of: what was your role, tech stack, and implementation challenge?

Medium · Project Experience & Technical Architect

Approach

  1. Pick a project you can explain down to the code: shipped, recent, with a hard technical problem you solved yourself, and ideally on a stack close to the role (C#/.NET, SQL Server, React or Next.js, a CMS). Candidates report being asked to demo or walk through past work, so have a working repository or live link ready to share.
  2. Structure the answer. Give the problem and who used it in a sentence or two, then your exact role in the first person ('I built the import service; a teammate owned the UI'), the stack and why it was chosen, and a quick sketch of the components and data flow.
  3. Spend most of your time on one implementation challenge, in technical detail: what broke or was slow, how you diagnosed it (execution plan, profiler, logs), the options you weighed and the one you chose.
  4. End with a measured result (page load, import time, error rate before and after) and one thing you would change now. That shows judgement without disowning the work.
  5. Avoid the two common failures: describing what the team did without separating out your own part, and listing technologies without saying why any of them was chosen.

Follow-up

  • Why that stack and not an alternative you considered?
  • What part of the code would you refactor first if you had a week?
  • Show me where in the repository the hardest part lives and walk me through it.

Explain the architecture of a complex feature you built from scratch.

Medium · Project Experience & Technical Architect

Approach

  1. Open with the requirement and its constraints in a few sentences: who used the feature, what it had to do, data volumes, deadlines and the systems it had to integrate with.
  2. Draw the architecture as boxes and arrows you can defend: UI, API endpoints, services, the data model (key tables and relationships), external integrations, and any background jobs or queues. Then walk one request or job through it.
  3. Explain two or three design decisions, each with the alternative you rejected and why. For example: processing a large import in a background job instead of the web request, or caching a CMS response instead of fetching it on every request.
  4. Cover failure handling and correctness: what happens on a timeout, a duplicate submission or a half-finished batch (transactions, idempotency keys, retries with backoff), and how you logged and monitored it in production.
  5. Finish with testing and rollout (unit and integration tests, a feature flag or staged release, a reversible database migration), the measured outcome, and the part you would design differently now.

Follow-up

  • Where is the single point of failure in this design?
  • What breaks first if usage grows ten times?
  • How did you test the integration with the external system?

How do you organize repository branching and handle pull requests using Git and Gitflow?

Medium · Project Experience & Technical Architect

Approach

  1. Lay out Gitflow's branches. main holds released code, tagged per version. develop is the integration branch. feature/* branches start from develop and merge back into it. release/* branches are cut from develop for stabilisation, then merge into main and back into develop. hotfix/* branches start from main and merge into main and develop, or into the open release branch if one exists.
  2. Name the trade-off. Gitflow suits versioned, scheduled releases where several versions need support. Its long-lived branches cause merge conflicts and slow integration, so teams that deploy continuously often prefer trunk-based development or GitHub flow, with short-lived branches and feature flags.
  3. Pull requests: keep them small and single-purpose. Describe what changed, why, and how it was tested, and link the work item. Resolve conflicts locally by rebasing on or merging from the target branch, and once review has started, answer comments with new commits rather than force-pushes.
  4. Protect the branches. Set policies in Azure DevOps or GitHub that require at least one reviewer, a passing CI build and resolved comments, and block direct pushes to main and develop. Choose a merge strategy deliberately: squash for a tidy history, merge commits to keep branch context, rebase for a linear history.
  5. Hygiene: rebase only branches nobody else has pulled, use git push --force-with-lease instead of --force on your own branch, and delete merged branches. If a secret is ever committed, rotate it first, because rewriting history does not remove copies already cloned.

Follow-up

  • A production bug appears while a release branch is being stabilised. Walk me through the hotfix branches and merges.
  • Squash, merge commit or rebase: which would you pick for this team, and why?
  • Two features touch the same file and the pull request has conflicts. How do you resolve them safely?

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 = $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 follows the three reported rounds: day 1 for the recruiter call, days 2 to 5 for the technical topics in the order the questions group (.NET, data access, SQL Server, front end and CMS), day 6 for project walkthroughs, and day 7 for a full assignment rehearsal.

Day 1 — Recruiter call and project pitch

  • Write a short career narrative that finishes on your target stack (.NET, front end or Sitecore).
  • Write a one-paragraph pitch of your best project: role, stack, one implementation challenge.
  • List your honest experience level in each technology the role names, and your compensation and location answers.

Deliverable: A career narrative, a project pitch and a stack self-assessment sheet, ready for the first call.

Day 2 — MVC, SOLID and validation in .NET

  • Sketch the MVC request path from routing through controller selection, model binding, validation, the action and the view result, and say what each step can reject.
  • Build a custom validation attribute for a form field and bind it so the message shows next to the input on the server side; note how the Web Forms CustomValidator control differs.
  • Write one SOLID example each for single responsibility and dependency inversion using constructor injection, and register the services in the .NET Core container with the right lifetimes.

Deliverable: A working validation example, a request-flow diagram and two SOLID snippets explained aloud.

Day 3 — Entity Framework, LINQ and web service calls

  • Write an EF Core query, then a version with a deliberate N+1 and its fix with Include or a projection, and compare the generated SQL.
  • Explain IEnumerable, IQueryable and IList with one example each of where the filter runs.
  • Write an HttpClient wrapper through IHttpClientFactory with a timeout, retry with backoff, and handling of HTTP 429 and Retry-After; note what changes when the service is SOAP.

Deliverable: An N+1 before-and-after, plus a tested service-client class that handles failures and rate limits.

Day 4 — SQL Server indexes, joins and tuning

  • Create a table with and without a clustered index, run queries in SQL Server, and read the plans to find a seek, a scan and a key lookup; then add a covering index with INCLUDE and compare.
  • Write an aggregation joining three tables with a LEFT JOIN, GROUP BY and HAVING that feeds a grid with paging (OFFSET/FETCH).
  • Design a schema for a business scenario of your choice to third normal form with keys and constraints, and decide where a view or stored procedure beats an inline query.

Deliverable: Saved plans with before-and-after notes, a join/GROUP BY query, a schema diagram, and a written list of slow-query checks.

Day 5 — Next.js, React and CMS answers

  • Build one Next.js page in three ways (SSR, SSG, ISR with a revalidate interval) and write the decision rule for choosing among them.
  • Write the difference between server and client components, and move one interactive piece to a client component while keeping the rest on the server.
  • Implement a fetch client with error states and cancellation; then reduce a bundle with a dynamic import and check the result with a bundle analyzer.
  • Write an honest answer about Sitecore, XM Cloud or Content Hub: what you have done, and the headless and Helix concepts you can explain.

Deliverable: A three-mode demo page, a server/client component note, a fetch client, and a Sitecore answer you can say aloud.

Day 6 — Project walkthroughs, monitoring, Gitflow and pipelines

  • Write the architecture story of a feature you built from scratch: components, data flow, one trade-off, one thing you would change.
  • Write a performance-monitoring story with the metric, the trace that located the cause, your fix and the before-and-after numbers.
  • Describe your Gitflow practice (main, develop, feature, release and hotfix branches) and how you review and merge pull requests. Then sketch a YAML build-and-deploy pipeline for a .NET or Next.js app (restore, build, test, publish artifact, deploy to an Azure App Service slot) so you can discuss it, since Azure DevOps pipelines are a listed responsibility.

Deliverable: Two written project stories, a monitoring story with numbers, a short Gitflow explanation and a pipeline sketch.

Day 7 — Assignment rehearsal and panel run-through

  • Build a small assignment-style app from an empty folder: a form with custom validation, an EF query shown as a grid, and one external API call.
  • Clone it fresh, run it, add tests and error handling, and fix whatever breaks.
  • Present it aloud as if to a technical manager, covering your choices, trade-offs and what you would do next, then repeat the summary in business terms for an executive.

Deliverable: A runnable repository with tests and a README, plus a recorded or written walkthrough at two levels of detail.

Behavioural preparation

Candidates describe the final stage as a conversation with technical managers and executives about your test, your past projects and situational scenarios. For this agency role, prepare stories that show your own decisions, how you explained them to non-technical people, and how you picked up a new platform or stack when a project needed it. Reported prompts come first, followed by prompts to rehearse around them.

  1. Walk me through a project you are most proud of: what was your role, tech stack, and implementation challenge?
  2. Explain the architecture of a complex feature you built from scratch.
  3. Describe a time you had to learn an unfamiliar platform or framework quickly to deliver for a client.
  4. Tell me about a late requirement change from a client or project manager and how you handled it.
  5. Describe a technical trade-off you explained to a non-technical stakeholder, and what they decided.

How do you handle performance monitoring using tools like New Relic or AppDynamics?

Medium · Project Experience & Technical Architect

Approach

  1. Open with one real case rather than a tool tour: name the application, the tool you used (New Relic or AppDynamics, or the nearest equivalent if you have not used those, and say so honestly), and the symptom, for example slow pages after a release or a rising error rate.
  2. Describe the diagnostic sequence. Start from a baseline of response-time percentiles (p95 and p99 as well as the average, which hides tail latency), throughput and error rate. Open a slow transaction trace to see where time goes: database calls, external service calls, application code or the front end. Then drill into the slice, such as a repeated query pattern like an N+1 from Entity Framework, a missing index, or a third-party API timeout.
  3. Explain how you keep it ongoing and not a one-off: alerts on symptoms (error rate, p95 latency) with thresholds taken from the baseline rather than on every CPU spike, deployment markers so a regression lines up with a release, and a dashboard the project team can read.
  4. Close the loop with evidence: the change you made, the same metric before and after under comparable traffic, and how you ruled out coincidence. The story fails if you only watched a dashboard or cannot say what you personally decided.
  5. Add the agency angle: how you reported the finding to a project manager or client in plain terms (what was slow, why, what changed, what is still open).

Follow-up

  • How did you know your fix caused the improvement and not a drop in traffic or a cache warm-up?
  • What would you alert on for a new site, and how would you set the thresholds to avoid alert fatigue?
  • The trace shows the time inside the database but the query is fast when you run it by hand. What do you check next?

Ship under a deadline and bound the debt you chose

Medium · pagination · technical debt · tradeoffs

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?

Reverse your own decision and price the reversal

Medium · reversibility · measurement · migrations

Describe a technical decision you made and later reversed. Pick one that cost something: a service you split and merged back, a cache you added and removed, an index you created that pushed the planner onto a worse plan, a projection you rebuilt from scratch. State what you believed when you decided, the measurement that changed your mind, how long the wrong version ran in production, and what the reversal cost in migrations, dual writes, and a deprecation window for callers you did not own.

Approach

  1. State the original rationale without irony, in the version you would still defend given what was known then. If it is not defensible, the story is about carelessness rather than judgement, and a different example serves you better.
  2. Give the measurement that moved with a before and after: the p99 that did not improve, the cache hit rate that sat at 40%, the plan that flipped to a sequential scan once the table passed a size you can name.
  3. Cost the reversal in steps, not adjectives: expand-and-contract deploys, the dual-write window, the callers who had to be notified, the rows already written in the wrong shape that had to be backfilled or abandoned.
  4. Distinguish reversal from rewrite by naming what you kept. Most good reversals preserve the schema or the interface and undo one decision inside it, which is also why they were affordable.

Follow-up

  • What in that decision was irreversible, and did you know it was irreversible when you made it?
  • How did you tell the people who had already built on top of the original decision?