cswork / libraryOpen practice workspace

Interview guides · AF Group

AF Group Software Engineer Interview Guide

AF Group Software Engineer interview guide: reported rounds, .NET, Azure/AWS and SQL Server questions, incident scenarios and a 7-day plan.

The 60-second brief

AF Group is an insurance company, and the role candidates describe sits on its application side. The platform named in the role is Guidewire PolicyCenter, alongside custom .NET applications that integrate with it. The listed work includes designing and configuring those integrations, writing C# and RESTful APIs, building JavaScript and AJAX front ends, modernising legacy workflows, connecting third-party applications and delivering on Azure or AWS with CI/CD pipelines. The engineer is described as the application owner: responsible for root cause analysis, performance across the database and server layers, and resiliency checks such as destructive testing scripts.

This guide is for engineers preparing for the AF Group Software Engineer loop, especially people coming from a C# and .NET background. It covers the four reported rounds, practice for each reported question theme (.NET and architecture, system design and cloud, troubleshooting and incident management, behavioral and leadership), and a seven-day plan. It does not go deep on Guidewire configuration, because candidates report that experience as an advantage rather than the core of the questions.

Candidates report four rounds over roughly 3-5 weeks: a Recruiter Screen, a Technical Phone Screen, a Virtual Onsite Interview and Final Rounds. Reported questions lean on .NET fundamentals, cloud design, production troubleshooting and leadership scenarios.

Focus areas

  • .NET
  • C#
  • JavaScript (including UI development)

Overview

The work described for this role is full-stack and operational. On the build side it is C#, ASP.NET MVC, REST or WCF services, Entity Framework over SQL Server, and a JavaScript, jQuery and AJAX front end. On the run side it is incident response, query and server tuning, and scripts that deliberately break non-production systems to prove they recover. Preparing for only one half leaves a gap, so your answers should move between code, database and production behaviour.

The reported questions fall into four themes. .NET and architecture covers .NET Framework versus .NET Core, dependency injection, the ASP.NET MVC request lifecycle, securing REST or WCF services, and Entity Framework versus ADO.NET or Dapper. System design and cloud covers an Azure quoting engine, distributed logging, caching for a read-heavy application, CI/CD design and moving on-premise data to AWS or Azure securely. Troubleshooting covers high-latency pages, SQL Server deadlocks, destructive testing, patch-versus-redesign trade-offs and slow JavaScript/AJAX screens. Behavioral questions cover product owners, code review, learning on the fly, mentoring and sprint pressure.

Candidates describe scenario questions about outages, API integrations and sprints rather than algorithm puzzles, and the requirements they describe list at least seven years of development and system design experience. That points to a preparation style: anchor every answer in a system you owned, name the numbers you measured, and be ready to explain a technical decision in business terms for the final rounds. Keep basic data structures warm, but spend most of your time on the database, the cloud design and your incident stories.

The AF Group interview process

Candidates describe four stages, from a recruiter conversation through a multi-round virtual panel to final rounds on communication. The order and content below are what candidates report, not a published process.

Recruiter Screen

Candidates report this opening stage as a conversation about your background, how well your technical stack lines up with the role, and cultural fit. Treat it as the point where your CV is checked against the listed stack: C#, .NET Framework and .NET Core, ASP.NET MVC, SQL Server, Entity Framework, JavaScript with jQuery and AJAX, and Azure or AWS. Have a short, structured account of each recent project and a straight answer about any Guidewire PolicyCenter exposure.

What to demonstrate

  • Match between your experience and the C#/.NET, SQL Server, front-end and cloud stack the role lists
  • Your background as you tell it, since this stage is reported to focus on it
  • Cultural fit, which candidates report as part of this screen

How to prepare

  • Build a table with one row per listed technology and one real project or incident of yours that proves it.
  • Prepare an honest statement of your Guidewire PolicyCenter and insurance exposure, plus the nearest equivalent such as configuring a vendor platform or building integrations around one.
  • Ask the recruiter to spell out the remaining rounds, and ask early whether any pay figure is an annual salary or a contract rate.

Technical Phone Screen

Candidates report a technical phone or video conversation with an engineering manager that covers past projects and core .NET concepts. Be ready to explain things verbally without an IDE: pick two projects where you shaped the design and can state the trade-offs. The .NET fundamentals questions in this guide (Framework versus Core, dependency injection, the MVC request lifecycle, securing REST or WCF services, Entity Framework versus ADO.NET or Dapper) are the practice material for the core .NET part.

What to demonstrate

  • Core .NET knowledge, which is the stated subject of this stage
  • How clearly you describe past projects: your role, the design and the trade-offs you made

How to prepare

  • Write a one-page summary per project: problem, architecture, your part, a decision you would revisit.
  • Explain, out loud, the .NET Framework versus .NET Core choice using a concrete project rather than a feature list.
  • Rehearse the ASP.NET MVC request path from routing to view rendering until you can say it without notes.

Virtual Onsite Interview

Candidates report a multi-round panel focused on system design, advanced .NET architecture and behavioral scenarios. This is where the design and cloud question types are practised (an Azure quoting engine, caching for a read-heavy application, CI/CD, on-premise to cloud data moves), along with architecture topics such as multi-tier design and REST versus WCF, and the behavioral stories. Clarify constraints first, draw every tier including the database, and name failure modes before you are asked.

What to demonstrate

  • System design reasoning under stated constraints
  • Advanced .NET and cloud architecture choices
  • Behavioral scenarios, which candidates report as part of this panel

How to prepare

  • Design the insurance quoting engine aloud, starting with questions on traffic volume, data sensitivity and read/write ratio before any diagram.
  • Prepare a defence of Entity Framework versus Dapper with a concrete query, the N+1 problem and when you would drop to raw SQL.
  • Review SOLID well enough to name which principle a flawed code snippet breaks, a tip candidates pass on.

Final Rounds

Final rounds are reported to test communication and how well you translate technical challenges into business impact. The role is described as working daily with product owners and with IT Security, so prepare to put trade-offs such as patching now versus redesigning, technical debt or a migration plan in terms of risk, cost and delivery. The behavioral prompts about product owners, sprints and mentoring are good rehearsal material for this stage as well.

What to demonstrate

  • Communication of technical topics to non-technical listeners
  • Ability to express a technical challenge as a business impact

How to prepare

  • Rewrite your two best incident stories so the first sentence states the business consequence, then the technical cause.
  • Rehearse explaining the patch-versus-redesign trade-off to a product owner without jargon.
  • Prepare questions about migration strategy, technical debt and their Guidewire implementation, a tip candidates pass on.

Where candidates lose points

Answering .NET Framework versus .NET Core as a feature list with no decision

Give the decision rule: default to .NET Core (modern .NET) for new work, and keep Framework where the app depends on Windows-only libraries or APIs that have not moved. Add what a migration would involve, and use a project of yours as the example.

Jumping to a fix when asked about a paged high-latency API or a SQL Server deadlock

State the sequence: scope the impact, check recent changes, find the slow tier from metrics, capture the query plan or deadlock graph (Profiler or Extended Events), fix, verify with numbers, then follow up on the root cause.

Drawing the quoting-engine or caching design around the middle tier only

Candidates warn against neglecting the database. Clarify traffic, data sensitivity and read/write ratio first, then show the SQL Server layer, cache invalidation, retries and what happens when a dependency is down.

Treating security as an afterthought in API and cloud-migration answers

Cover authentication and authorisation, TLS, input validation, secrets storage, encryption at rest and in transit and access auditing in the first pass, naming OWASP-style risks and secure cloud configuration for the insurance data involved.

Telling behavioral stories in plural pronouns with no personal action or measured result

For the product-owner, destructive-testing, UI-performance and sprint stories, say what you decided and did, and give a measured result in your own numbers.

Questions & practice

Canonicalise a request body into a stable idempotency fingerprint

Medium · parsing · canonicalisation · hashing

idempotency_key.request_fingerprint is a SHA-256 over the method, path and canonicalised body, and a retry whose fingerprint differs must be rejected with 422 rather than served the stored response. Write the canonicaliser. Bodies are JSON up to 256 KB nested at most 32 levels; clients vary key order, whitespace and unicode escaping, and some send 64-bit ids as JSON numbers. Produce a deterministic byte string such that semantically identical bodies match and any semantic difference does not. State your complexity and name two normalisations you refuse to perform.

Approach

  1. Parse once into a tree, then re-serialise under fixed rules: object keys sorted, array order preserved, one escaping convention, no insignificant whitespace. Parsing is O(n) and sorting keys is O(k log k) per object, so O(n log n) overall with O(depth) stack, and the 32-level cap is enforced during parsing because hostile nesting is how a canonicaliser becomes a stack overflow.
  2. Sort keys by their UTF-8 bytes and say why the obvious implementation is wrong in some runtimes: a default string comparison that orders by UTF-16 code units places surrogate pairs, meaning code points from U+10000 up, below U+E000 to U+FFFF, which is not UTF-8 byte order, so two services written in different languages disagree on the same document.
  3. Do not re-encode numbers through a double. IEEE-754 binary64 represents integers exactly only up to 2^53, so normalising a 19-digit id through a float changes it, and 1 against 1.0 cannot be reconciled without deciding whether they are the same value. Preserve the literal token, and require ids as strings at the API boundary if you want them comparable.
  4. Reject duplicate keys rather than picking one. JSON permits them and parsers disagree, most keeping the last, so any choice you make ties the fingerprint to a parser detail that the code handling the request does not necessarily share.

Follow-up

  • A client sends the same logical request with an extra field your API ignores. Same key, different fingerprint, so you return 422. Is that the right answer?
  • Where does the fingerprint get computed relative to request decompression and the body-size limit?

Find overlapping job attempts and peak concurrency from lease records

Medium · sweep line · intervals · leases

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?

Diff a projection against the primary without per-row point reads

Hard · reconciliation · range hashing · throttling

The listing projection has drifted and some rows show a stale version. The primary holds 40,000,000 resource rows across 12,000 tenants while serving 1,200 writes and 14,000 reads per second. The obvious repair, reading each resource row and comparing its version against the projection, is correct and would eventually finish. Explain precisely why it is unacceptable here, then give a diff that finds the differing rows, state its complexity, and make it safe to run against a live primary. Replication lag is usually under 100 ms and is not bounded.

Approach

  1. Quantify the naive cost rather than calling it slow: 40,000,000 point reads at even 0.5 ms each is over five hours serialised, and the only lever is concurrency, which is exactly what you cannot spend. The primary's pool is sized for the write path, and 40,000,000 random reads evict the buffer cache that sustains the 85 percent cache hit rate, so the audit degrades the system it is auditing.
  2. Replace random access with one ordered pass per side. Both sides can be read in (tenant_id, resource_id) order, which is a sequential scan on each and a merge join in O(n) time and O(1) memory. For a dense diff that is the whole answer, and it reads the primary once instead of 40,000,000 times.
  3. For the expected sparse case, compare range hashes instead of rows: partition the key space, compute per range an order-independent aggregate over hash(resource_id, version), compare aggregates, and descend only into ranges that differ. With d differing rows and branching factor B, at most d ranges mismatch per level, so the drill-down examines O(d log_B(n/d)) ranges and reads full rows only in mismatching leaves.
  4. Aggregate with a sum modulo 2^64 or a multiset hash, never XOR. XOR is order-independent but self-cancelling, so two rows wrong in the same way, or a row duplicated on one side, leave the range aggregate matching and the range is declared clean.

Follow-up

  • The diff reports 900 stale rows. How do you decide between patching those rows and rebuilding the projection from resource_revision?
  • Same job, but the projection lives in a search index that cannot be scanned in key order. What changes?

How do you use tools like MS SQL Studio or SQL Profiler to identify and fix deadlocks?

Medium · Troubleshooting & Incident Management

Approach

  1. Define it: a deadlock is a cycle of lock waits. SQL Server's lock monitor detects it, picks a victim and rolls that transaction back with error 1205. Blocking without a cycle is a different problem.
  2. Capture the graph. The built-in system_health Extended Events session already records xml_deadlock_report, which I read from its event file in SSMS. In SQL Profiler I use the Deadlock graph event, though Profiler is deprecated in favour of Extended Events. Trace flag 1222 writes the details to the error log.
  3. Read the graph: the processes and their statements, the resources (KEY, PAGE, OBJECT plus the index name), and which lock modes (S, U, X, IX) each process holds and waits for. That identifies the two code paths and the index they collide on.
  4. Fixes, in order of preference: access tables in the same order in every transaction, keep transactions short (no remote calls inside), add a covering index so updates and lookups touch fewer rows, use UPDLOCK for read-then-update patterns, and enable READ_COMMITTED_SNAPSHOT to remove reader-writer deadlocks.
  5. Check the isolation level the app actually uses, because TransactionScope defaults to Serializable. Make the data layer retry the victim transaction on 1205 with bounded backoff, since deadlocks can be reduced but not ruled out.

Follow-up

  • Why can a plain SELECT be one side of a deadlock?
  • What does READ_COMMITTED_SNAPSHOT cost, and where does that cost show up?
  • After a fix, how do you confirm deadlocks have actually dropped?

Denormalise tenant onto revisions and backfill it live

Hard · denormalisation · online migration · backfill

resource_revision (revision_id, resource_id, version, actor_user_id, change_kind, patch, request_id, created_at) has 400M rows and no tenant column; tenant_id lives only on resource. Two reads need it: a tenant-scoped audit feed ordered by created_at DESC, and an offboarding purge. Both join back to resource today. Justify adding tenant_id to resource_revision against those two reads, name the anomaly the copy introduces and the constraint that prevents it, then give the ordered migration for a live table taking 1.2k writes/second — the lock each step takes, how the backfill is batched, and where each step stops being reversible. PostgreSQL 16.

Approach

  1. Justify from the access path rather than from taste. Without the column, the audit feed either scans resource_revision by created_at and discards other tenants' rows, or resolves the tenant's resource_ids first and probes with them — both proportional to the tenant's whole history rather than to one page. With (tenant_id, created_at DESC, revision_id DESC) it is a seek that stops at 50 rows, and the purge becomes a ranged delete instead of a join.
  2. Name the cost exactly: a second copy of a fact can disagree with the first. Make the disagreement unwritable rather than documented — add UNIQUE (resource_id, tenant_id) on resource so it can serve as a foreign-key target, then FOREIGN KEY (resource_id, tenant_id) REFERENCES resource (resource_id, tenant_id) on the revision table. A revision can then only ever carry its parent's tenant.
  3. Step one, expand: ALTER TABLE resource_revision ADD COLUMN tenant_id BIGINT NULL, with no default, so it is a catalogue change and no rewrite. It still needs ACCESS EXCLUSIVE for an instant, and that instant queues behind the longest open transaction on the table while every later query queues behind it — set lock_timeout to 2s and retry rather than wait.
  4. Step two, dual-write: deploy the writer that populates tenant_id on every new revision while reads still use the join. Reversible by redeploying the previous build, because nothing reads the column yet.

Follow-up

  • The backfill is half finished and a rollback is required. What state is the table in, and what does the previous build do with a half-populated column?
  • How do you verify the backfill actually finished, given rows are still being inserted while it runs?

Explain the difference between.NET Framework and.NET Core. When would you choose one over the other for a new

Medium · .NET & Architecture Deep Dive

Explain the difference between.NET Framework and.NET Core. When would you choose one over the other for a new project?

Approach

  1. Separate the two runtimes. .NET Framework (last version 4.8.x) is Windows-only, installs into the OS and now only gets security and reliability fixes. .NET Core became the unified .NET 5+. It is cross-platform and open source, installs side by side or self-contained, and ships a release every year, with the even-numbered ones as LTS.
  2. Name what only Framework has: System.Web (Web Forms and classic MVC 5), server-side WCF, Windows Workflow, AppDomains and Remoting. Modern .NET replaces them with ASP.NET Core, Kestrel, built-in DI, appsettings.json configuration and a middleware pipeline.
  3. For a new project I choose modern .NET on the current LTS release. The exceptions are hard dependencies: a Framework-only vendor SDK, COM interop that must run in process, or an extension to an existing Web Forms or WCF host that is not yet being migrated.
  4. For code shared between both runtimes I target .NET Standard 2.0. For a migration I use the .NET Upgrade Assistant and move one project at a time, starting with the leaf libraries.
  5. Mention the trade-off of staying on Framework: no Linux containers, a smaller hiring pool and no new runtime performance work, against the cost and risk of a rewrite.

Follow-up

  • How would you migrate a large MVC 5 application without a big-bang cutover?
  • What do you do with an existing WCF SOAP service when the host moves to modern .NET?
  • When would you publish self-contained rather than framework-dependent, and what does that cost?

How does dependency injection work in.NET Core, and why is it beneficial?

Medium · .NET & Architecture Deep Dive

Approach

  1. Explain the mechanics. Services are registered on IServiceCollection (builder.Services.AddScoped<IQuoteRepository, SqlQuoteRepository>()), and the IServiceProvider builds constructor dependency graphs, including controllers and middleware.
  2. Define the three lifetimes and when to use each. Transient gives a new instance per resolve, Scoped one per request scope (DbContext belongs here) and Singleton one per application (it must be thread-safe). The container disposes the IDisposable instances it created.
  3. Name the captive dependency bug: a singleton that holds a scoped service keeps it alive forever. Scope validation is on by default in the Development environment and throws when it happens. In a BackgroundService I inject IServiceScopeFactory and create a scope per unit of work.
  4. Benefits: classes depend on interfaces, so unit tests swap in fakes, wiring sits in one place, and lifetimes are managed for you. Related built-ins worth naming are IOptions<T> for configuration, AddHttpClient (IHttpClientFactory) to avoid socket exhaustion, and keyed services in .NET 8.
  5. Anti-patterns: a service locator that injects IServiceProvider everywhere, and constructors with many parameters, which usually signal a class with too many responsibilities.

Follow-up

  • How do you use a scoped DbContext safely inside a hosted background service?
  • What happens at runtime if a singleton takes a scoped dependency, and how would you catch it in development?
  • When would you replace the built-in container with something like Autofac?

Can you explain the lifecycle of an ASP.NET MVC request?

Medium · .NET & Architecture Deep Dive

Approach

  1. Ask which stack is meant and cover the one asked. Classic MVC 5 on IIS: HttpApplication events (BeginRequest, AuthenticateRequest, AuthorizeRequest), then UrlRoutingModule matches a route, MvcRouteHandler hands off to MvcHandler, and the controller factory creates the controller.
  2. Walk the MVC 5 action invoker in order: authentication filters, authorization filters, model binding and validation, action filters (OnActionExecuting), the action returning an ActionResult, action filters (OnActionExecuted), result filters, then ExecuteResult. For a ViewResult, the Razor view engine locates and renders the view. Exception filters catch failures along the way.
  3. For ASP.NET Core: Kestrel (optionally behind IIS or a reverse proxy) feeds a middleware pipeline whose order is set in Program.cs. It runs exception handling, HTTPS redirection, static files, UseRouting, UseAuthentication, UseAuthorization, then the endpoint.
  4. Inside the endpoint the Core filter pipeline runs authorization filters, resource filters, model binding, action filters, the action, then result filters around result execution. Exception filters cover controller creation, model binding, action filters and the action.
  5. Close with where each concern belongs. Cross-cutting HTTP concerns such as correlation IDs and global error handling go in middleware. Concerns that need the action's arguments or model state go in filters.

Follow-up

  • Why must UseAuthentication come before UseAuthorization, and what breaks if they are swapped?
  • With [ApiController], what happens when model validation fails before the action runs?
  • Would you log request timings in middleware or an action filter, and why?

How do you implement and consume RESTful APIs securely using WCF or standard Web API?

Medium · .NET & Architecture Deep Dive

Approach

  1. Transport: HTTPS only, with HSTS and TLS 1.2 or later. In WCF, REST-style endpoints use webHttpBinding with security mode Transport and [WebGet]/[WebInvoke]. For new REST work I prefer ASP.NET Core Web API, because WCF's strength is SOAP.
  2. Authentication: OAuth 2.0 / OpenID Connect bearer tokens validated with AddJwtBearer, checking issuer, audience, signature and expiry. Service-to-service calls use the client credentials flow or mutual TLS, never a shared static key in config.
  3. Authorization goes beyond [Authorize]. I use policies or scopes per endpoint plus a resource-level check that the caller owns the record, which closes the broken object-level authorization hole (an ID changed in the URL). Request DTOs prevent over-posting, and input is validated.
  4. Hardening: a rate limiter, tight CORS origins, and ProblemDetails errors without stack traces. Logs exclude tokens and personal data. Secrets come from a vault, and certificate validation is never disabled.
  5. Consuming: typed clients from IHttpClientFactory with explicit timeouts. Retries with backoff go only on idempotent calls, or on calls that carry an idempotency key, and a circuit breaker stops a failing partner from tying up threads.

Follow-up

  • How do you rotate signing keys or client secrets without downtime?
  • How would you stop one caller from reading another customer's policy by changing an ID?
  • When would you keep a SOAP WCF endpoint rather than replace it with REST?

What are the pros and cons of using Entity Framework compared to raw ADO.NET or Dapper?

Medium · .NET & Architecture Deep Dive

Approach

  1. EF Core pros: LINQ queries, change tracking with SaveChanges as one transaction, migrations, and navigation properties. Cons: generated SQL you must inspect, N+1 queries from lazy loading, row explosion when several collection Includes are combined (AsSplitQuery helps), and tracking overhead on reads (use AsNoTracking).
  2. Dapper is a micro-ORM: extension methods on IDbConnection that run SQL you write and map the rows to objects, with performance close to raw ADO.NET. You get full control of the SQL and multi-mapping, but no change tracking, no migrations and no compile-time check of the SQL.
  3. Raw ADO.NET (SqlConnection, SqlCommand, SqlDataReader) gives the most control and the most boilerplate. I reach for it for SqlBulkCopy, table-valued parameters or streaming very large result sets.
  4. On security, all three are safe when parameterized and unsafe with string concatenation. In EF Core, FromSql and FromSqlInterpolated parameterize interpolated values; FromSqlRaw with an interpolated string does not.
  5. My usual answer is a mix. I use EF Core for transactional writes and domain logic, and Dapper or EF's raw SQL for read-heavy reporting queries. For set-based changes I use ExecuteUpdate and ExecuteDelete (EF Core 7+), and I decide by profiling the actual SQL Server plans, not by preference.

Follow-up

  • How would you find and fix an N+1 problem in an existing EF Core codebase?
  • How do you run an EF Core write and a Dapper query in the same transaction?
  • When does change tracking become a measurable cost, and what do you do about it?

Design an architecture for a high-volume insurance quoting engine using Azure services.

Medium · System Design & Cloud

Approach

  1. Clarify first: peak quotes per second, the latency target for an instant quote, which lines of business, whether some quotes go to an underwriter asynchronously, how often rate tables change, and how long quotes must stay auditable.
  2. Request path: Front Door or API Management for auth, throttling and versioning. Behind it, a stateless rating service on App Service, Container Apps or AKS that scales out. Versioned, immutable rate tables and rules are held in memory, with Azure Cache for Redis for shared reference data.
  3. Third-party enrichment (prior claims, credit and similar) goes behind timeouts, circuit breakers and per-applicant caching. Slow paths become asynchronous: the request lands on a Service Bus queue, workers (Functions or containers) price it, and the client polls or gets a callback. An idempotency key on submission stops duplicate quotes.
  4. Storage: Azure SQL Database for quotes, saving inputs, the rate-table version and outputs immutably so any premium can be reproduced later. Quote events go to Event Hubs or Service Bus for analytics. Managed identities and Key Vault hold credentials, and personal data is encrypted.
  5. Scale and failure: autoscale on CPU and queue depth, read replicas for lookups, and multi-region failover through Front Door. Rule changes ship as data with a version flag, so one state's rates can change without a code deploy.

Follow-up

  • How do you guarantee that a quote issued months ago reproduces the same premium today?
  • What happens to the quote flow when a third-party data vendor becomes slow or unavailable?
  • How would you roll out a new rate table to one state, and roll it back?

Explain how you would implement a caching strategy to improve the performance of a read-heavy application.

Medium · System Design & Cloud

Approach

  1. Measure before caching: find the hot reads, the acceptable staleness for each one and the current database load. Then pick the layer. HTTP caching (Cache-Control, ETag, CDN) suits public content, an in-process IMemoryCache suits tiny hot data, a distributed cache (Redis via IDistributedCache, or HybridCache in .NET 9) suits shared data, and read replicas take database load.
  2. Default pattern is cache-aside: read the cache, load from the database on a miss, and store with a TTL plus jitter. On writes I commit to the database first and then delete the key, rather than updating it, which narrows the race where a stale value overwrites a fresh one.
  3. Protect against stampedes with single-flight loading per key (HybridCache does this), stale-while-revalidate or early probabilistic refresh, so an expiring hot key does not send every request to SQL Server at once.
  4. Keys include a version and a tenant or user scope. Per-user sensitive data never lands in a shared cache key. Eviction is bounded (memory limits, an LRU policy), and multiple app instances with local caches either use short TTLs or a pub/sub invalidation message.
  5. Plan for cache failure: if Redis is down, fall back to the database through a circuit breaker and rate limit, and warm the critical keys after a failover so a cold cache does not cause an outage of its own.

Follow-up

  • The database write succeeds but the cache delete fails: what does a reader see, and how do you bound it?
  • How do you choose TTLs for data that changes rarely but must be correct when it does?
  • How would you stop a cold cache after a Redis failover from overwhelming the database?

What is your approach to designing a continuous integration and continuous deployment (CI/CD) pipeline?

Medium · System Design & Cloud

Approach

  1. CI on every pull request: restore, build, unit tests (dotnet test) with coverage, static analysis, dependency vulnerability scanning (dotnet list package --vulnerable) and secret scanning. Branch protection blocks merges until these pass.
  2. Build once, deploy many. The pipeline produces one versioned artifact (container image or package tagged with the commit SHA) and promotes that same artifact through dev, test, staging and production. Configuration is injected per environment, and secrets come from Key Vault or a secrets manager.
  3. Infrastructure as code (Bicep, ARM or Terraform) runs in the same pipeline, so environments do not drift. Integration, contract and smoke tests run against a deployed environment before promotion, and load or resilience tests run in a non-production stage.
  4. Database changes are backward-compatible expand-then-contract migrations, shipped as EF Core idempotent scripts or migration bundles. They run before the app deploy, so the old and new versions both work during rollout.
  5. Release safely with deployment slots and swap (blue-green), canary releases or feature flags, health checks and automatic rollback. Track lead time, deployment frequency, change failure rate and time to restore to show whether the pipeline helps.

Follow-up

  • How do you roll back a release that included a schema change?
  • The pipeline has become too slow to run on every PR: what do you change first?
  • Where in the pipeline do destructive or resilience tests belong, and against which environment?

How do you ensure data security and compliance when moving on-premise data to AWS or Azure?

Medium · System Design & Cloud

Approach

  1. Start with discovery and classification. Inventory the data, tag personal, health, financial and claims data, and map the obligations that apply (privacy laws, state insurance data security rules, PCI DSS for card data). Choose regions for residency, and state the shared responsibility split with the provider.
  2. In transit: private connectivity (ExpressRoute or Direct Connect, or a site-to-site VPN) and TLS 1.2 or later. For bulk volumes, encrypted offline transfer devices (Data Box, Snowball). Private endpoints keep databases and storage off the public internet.
  3. At rest: encryption with customer-managed keys in Key Vault or KMS, with rotation. TDE on SQL databases, and column-level protection (Always Encrypted, tokenisation) for fields like SSNs. Non-production copies are masked or synthetic, never raw production data.
  4. Identity: least-privilege RBAC/IAM, managed identities instead of stored keys, just-in-time admin access, and network segmentation. Policy-as-code (Azure Policy, AWS Config) blocks unencrypted or public resources by default.
  5. Prove it: reconcile row counts and checksums between source and target, enable audit logging (Azure Monitor/Activity Log, CloudTrail) with retention, run security posture tooling, and set a documented deletion plan for the on-premise copies once cutover is verified.

Follow-up

  • How would you show an auditor that the migrated data is complete and unaltered?
  • How do developers get realistic test data without production personal data?
  • Who controls the encryption keys, and what happens if a key is deleted?

Walk me through your exact steps when you are paged for a high-latency issue in a critical production API.

Medium · Troubleshooting & Incident Management

Approach

  1. Triage the impact first: which endpoints, p50 versus p99, error rate, how many users, and when it started. Correlate the start with recent deploys, config or feature-flag changes and traffic shifts. If a change lines up, roll back or switch the flag off before diagnosing further.
  2. Locate the time with distributed traces and per-dependency metrics (Application Insights or OpenTelemetry). Is it in my code, a downstream HTTP call or the database? Check whether one instance is the outlier or all of them are.
  3. Check app-level saturation: CPU, memory and GC pauses, thread pool starvation from sync-over-async (.Result or .Wait on async calls), and SqlClient connection pool exhaustion (default Max Pool Size is 100). High latency with low CPU often points to waiting, not computing.
  4. On SQL Server: top queries by duration and waits in Query Store or sys.dm_exec_requests, blocking chains via blocking_session_id, and plan regressions such as parameter sniffing. Query Store can force the last good plan as a mitigation.
  5. Mitigate, communicate and follow up: scale out, shed load or kill a blocking session, give stakeholders updates at a steady cadence, then write a blameless postmortem with the root cause, a regression test and a p99 alert so the next occurrence pages earlier.

Follow-up

  • Only one of several instances is slow: what do you check next?
  • CPU is low but latency is high: what are your top suspects?
  • How do you tell parameter sniffing apart from a missing index?

How do you balance the immediate need to patch a production bug with the long-term need to fix the underlying

Medium · Troubleshooting & Incident Management

How do you balance the immediate need to patch a production bug with the long-term need to fix the underlying architectural flaw?

Approach

  1. Stop the damage first with the smallest safe change: a guard clause, a config or feature-flag switch, or a data repair. It ships through the normal pipeline with review and a regression test, never as a manual hotfix on a server, and it has a rollback plan.
  2. In the postmortem, separate the trigger from the cause. I write the root cause down, explain why the patch only contains it, and add monitoring or an alert so a recurrence is visible rather than silent.
  3. Turn the architectural flaw into a costed backlog item linked to the patch. I state the cost in business terms (incidents, support hours, data or security exposure), which gives the Product Owner something concrete to prioritise against features.
  4. Decide urgency by risk. Data corruption, security exposure or frequent recurrence justify pulling the structural fix forward. A rare, contained failure can wait for a planned slot.
  5. Deliver the structural fix incrementally (strangler pattern, feature flags, parallel run with comparison) rather than as a big-bang rewrite, and remove the temporary patch once the new path is proven.

Follow-up

  • The Product Owner keeps deprioritising the structural fix: what do you do?
  • How do you stop a temporary patch from quietly becoming permanent?
  • When would you refuse to ship a quick patch at all?

One customer endpoint stalls deliveries to every other destination

Medium · bulkhead · timeouts · saturation

The egress service delivers about 1.5k webhooks/second across 40,000 destinations, with a per-destination concurrency cap of 4 and a 10-second connect-plus-read timeout. Throughput falls to 300/second, queue depth climbs, and p99 delivery latency for unaffected destinations goes from 200 ms to minutes, while the error rate barely moves. One tenant holds 900 destination rows whose URLs share a hostname that now answers in 9.5 seconds. Explain the mechanism with the arithmetic, then give the containment in the order you would apply it.

Approach

  1. Look at saturation before errors. A flat error rate with collapsing throughput says nothing is failing, things are waiting, so the first signal to pull is in-flight request count or pool wait time rather than the error counter. This is the distinction that decides the whole investigation.
  2. Group in-flight work by resolved host, not by destination id. The cap is keyed per destination row, so 900 rows sharing one hostname buy 3,600 concurrent slots against a single host, each held for 9.5 seconds. The bulkhead was never a bulkhead for that host, and grouping by the wrong dimension is why the dashboard looked healthy.
  3. Do the arithmetic in both directions. Required concurrency is arrival rate times latency, so 1.5k/second at 200 ms needs about 300 in flight, which is entirely consumed by 3,600 slow slots; conversely whatever concurrency is left sustains rate equals concurrency divided by 9.5 seconds, which is the 300/second you are seeing. Matching both numbers is what promotes this from a plausible story to the mechanism.
  4. Explain why the circuit breaker never helped. It opens on consecutive failures, and a 9.5-second response inside a 10-second timeout is a success. Slow is not failing, so an error-rate breaker cannot see this; you need a slow-call ratio, a deadline propagated from the caller's remaining budget, or a concurrency limiter.

Follow-up

  • The host recovers to 80 ms. How long does the queue take to drain, and what does the drain do to the recovered host?
  • Where should the 10-second timeout number actually come from?

Suggested practice checklist

Each day targets one cluster of the reported questions in this guide, ending with a spoken or written deliverable. The first days cover core .NET and data access, the middle days cover cloud design and incidents, and the last day rehearses the behavioral and final-round material.

Day 1 — Map the loop and your stack

  • List the four reported rounds and write what each one covers, then mark the one you are least ready for.
  • Build a table pairing each listed technology (C#, .NET Framework and Core, ASP.NET MVC, SQL Server, Entity Framework, JavaScript/jQuery/AJAX, Azure or AWS) with one project that proves it.
  • Write a short spoken summary of your background that ends on the role's stack, and note your honest Guidewire answer.

Deliverable: A one-page loop map, a technology-to-project table and a written background summary.

Day 2 — .NET fundamentals out loud

  • Write a decision table for .NET Framework versus .NET Core, with conditions for each choice.
  • Build a small ASP.NET Core sample that registers transient, scoped and singleton services and reproduces a captive-dependency bug.
  • Draw the ASP.NET MVC request lifecycle from routing through filters, action and view result.

Deliverable: A decision table, a working DI sample with the bug and its fix, and a lifecycle diagram.

Day 3 — APIs, data access and deadlocks

  • Write a security checklist for a REST API and a WCF service: authentication, authorisation, transport and input validation.
  • Write one query in Entity Framework, Dapper and ADO.NET, compare the generated SQL and reproduce an N+1 problem.
  • Reproduce a deadlock in SQL Server with two sessions and read the deadlock graph from Profiler or Extended Events.

Deliverable: A security checklist, a three-way data-access comparison, a deadlock write-up, and solved drills.

Day 4 — Quoting engine and caching design

  • List clarifying questions for the insurance quoting engine (traffic volume, data sensitivity, read/write ratio, latency target) and answer them with stated assumptions.
  • Draw the architecture on Azure or AWS (whichever you know), covering tiers, database, queue, cache and failure behaviour.
  • Write a caching plan for a read-heavy application: cache-aside, expiry, invalidation and protection against a stampede.

Deliverable: One annotated quoting-engine diagram and one caching plan, each explained aloud.

Day 5 — Pipelines, migration security and observability

  • Outline a CI/CD pipeline for a .NET service: build, unit tests, security scan, deploy to staging, smoke test, approval and rollback.
  • Write a security and compliance checklist for moving on-premise data to Azure or AWS.
  • Design the logging and monitoring setup for a multi-tier application using correlation IDs, structured logs, metrics and alerts.

Deliverable: A pipeline outline, a migration security checklist and an observability design.

Day 6 — Production incidents and destructive testing

  • Write your step-by-step runbook for a page about high latency in a production API, from scoping to post-incident review.
  • Write a one-page answer on patching a bug now while fixing the underlying design later.
  • Write STAR stories for destructive testing and for a slow JavaScript/AJAX screen, with real measurements.

Deliverable: A runbook, a patch-versus-redesign answer, two STAR stories and a solved debugging drill.

Day 7 — Behavioral stories and the final-round conversation

  • Write STAR outlines for the product-owner disagreement, code review, learning on the fly, community of practice and chaotic sprint prompts.
  • Record yourself explaining a technical trade-off to a product owner, then cut every piece of jargon.
  • Write your questions for the interviewers about migration strategy, technical debt and their Guidewire implementation, then do a full run of all four rounds.

Deliverable: Five STAR outlines, one recorded plain-language explanation and a list of questions to ask.

Incident, delivery and leadership stories

Candidates report behavioral scenarios in the virtual onsite and a final stage on communication and business impact. The reported prompts cover disagreeing with a product owner, code review, learning a technology quickly, mentoring and keeping a chaotic sprint on track. For a role described as application owner, pick stories where you made the decision, name your own actions and give a result you measured.

How do you handle distributed logging and monitoring across a multi-tier cloud application?

Medium · System Design & Cloud

Approach

  1. Frame it with three signals and what each answers: logs say what happened, metrics say how often and how slow, traces say where in the call chain the time went.
  2. Put a correlation or trace ID on every request at the edge, propagate it through the web tier, API, background workers and database calls (for example the W3C traceparent header), and write it into every structured log line.
  3. Ship structured JSON logs from every tier to one central store using the platform's native diagnostics on Azure or AWS, with a shared schema (timestamp, service, level, correlation ID) rather than reading files host by host.
  4. Keep sensitive data out: for insurance workloads mask policyholder identifiers and never log secrets, tokens or full payloads. Set retention and sampling to control cost.
  5. Alert on symptoms (error rate, p95 latency, queue depth, SQL waits and connection-pool saturation) with a runbook link, and keep per-tier dashboards for diagnosis. If asked for an experience, give a short STAR: the blind spot, what you added, the incident it later shortened.

Follow-up

  • How would you trace a request that crosses a message queue or a scheduled job?
  • What would you sample or drop to keep logging cost down, and what must never be sampled?
  • Which alerts page someone at night, and which only appear on a dashboard?

Describe a time you wrote custom scripts for destructive testing. What vulnerabilities did you uncover?

Medium · Troubleshooting & Incident Management

Approach

  1. Define the practice in your own words: scripts that deliberately break a non-production system (kill a process, cut the database connection, inject latency, send malformed or oversized payloads, fill a disk) to see whether it recovers.
  2. Open with the situation and the hypothesis you tested, such as 'the API should degrade, not hang, when SQL Server is unreachable'. Then describe the scripts, the isolated environment and how you guaranteed no real data or production traffic was touched.
  3. Be concrete about what you uncovered, for example missing timeouts, retry storms, exhausted connection pools, transactions left open, stack traces in error responses, or jobs that double-processed after a restart, and what you changed for each.
  4. Close with the durable result: the failure case became an automated regression test or a pipeline stage and the runbook was updated. If your experience is informal, say so and use the closest real equivalent such as fault injection in staging.

Follow-up

  • How did you make sure the test could not affect production or real customer data?
  • Which finding was the most serious, and how did you verify the fix?
  • How would you wire this kind of test into a CI/CD pipeline?

Tell me about a time you had to troubleshoot a complex UI performance issue involving JavaScript and AJAX.

Medium · Troubleshooting & Incident Management

Approach

  1. Say you measured before touching code: browser developer tools, the Network waterfall and Performance profile, to separate three suspects: slow server responses, too many or too large AJAX calls, and slow rendering on the client.
  2. Name the usual causes you looked for: sequential or chatty AJAX calls, requests fired on every keystroke without debouncing, large unpaginated payloads, big DOM tables rebuilt repeatedly with jQuery, synchronous requests, and repeated DOM queries inside loops.
  3. Describe fixes one at a time with a measurement after each: debounce and cancel in-flight requests, batch or paginate on the server, cache static lookups, trim payloads, render incrementally. If the profile pointed at the server, say you followed the call into the SQL query.
  4. State your own before and after numbers, and how you prevented regression, for example a performance budget or a test on the key page.

Follow-up

  • How did you decide whether the bottleneck was in the browser or on the server?
  • How would you handle a grid that has to show ten thousand rows?
  • What did you put in place so the slowdown did not return?

Describe a time you disagreed with a Product Owner about the technical feasibility of a user story. How did yo

Medium · Behavioral & Leadership

Describe a time you disagreed with a Product Owner about the technical feasibility of a user story. How did you resolve it?

Approach

  1. Choose a disagreement about feasibility (effort, risk, a platform limit), not taste, and describe the story's acceptance criteria and why you doubted they were achievable.
  2. Show you brought evidence rather than opinion: a short spike or prototype, a measured constraint, or an estimate with the unknowns named.
  3. Explain it in the product owner's terms (delivery risk, cost, what the user gets) and offer options instead of a flat no: reduce scope, phase delivery, or choose another approach.
  4. State the resolution and what changed in the process: the story was split or rewritten, acceptance criteria revised, and the Definition of Ready tightened. Avoid casting the product owner as the obstacle or yourself as having won.

Follow-up

  • What would you have done if the product owner still insisted on the original scope?
  • How did you tell stakeholders outside the team about the trade-off?
  • What would you do differently now?

How do you approach reviewing code from a peer who consistently ignores design patterns?

Medium · Behavioral & Leadership

Approach

  1. Begin by checking your own premise: is the pattern really required by an agreed team standard, or is it a preference? Point to documented conventions, and where possible to automated analyzer or lint rules in CI so the standard is not personal.
  2. Make the review comment specific and tied to a consequence, such as a controller that does data access and so cannot be unit-tested, and ask a question before prescribing a fix.
  3. If it repeats, talk privately or pair on one change instead of repeating comments on the pull request, and ask what is driving the choice, since there may be a good reason.
  4. Escalate to the tech lead only if the behaviour continues and affects delivery, and keep the focus on the code, not the person. Mention that you accept their approach when it is justified.

Follow-up

  • What if the peer is more senior than you?
  • How do you tell a real design problem from a matter of taste?
  • What do you do when the deadline is today and the review is blocking the release?

Tell me about a time you had to learn a completely new technology on the fly to deliver a project.

Medium · Behavioral & Leadership

Approach

  1. Pick a story with a real deadline and real unfamiliarity, such as a cloud service, a framework or a platform like Guidewire, not a small extension of what you already knew.
  2. Show a method: decide the minimum you needed to learn, read the official documentation, build a thin spike to retire the biggest risk, ask someone experienced a targeted question, and add tests to catch mistakes you could not yet see.
  3. Show risk handling: you told the team and product owner where the uncertainty was and adjusted the plan early.
  4. Give the outcome and one thing you got wrong and corrected, then say how you shared what you learned, for instance a short write-up or session, which links to community-of-practice work.

Follow-up

  • How did you decide what not to learn?
  • How did you check your work was correct without existing expertise?
  • What would you do now to get up to speed faster?

Give an example of how you have contributed to a "community of practice" or mentored junior developers.

Medium · Behavioral & Leadership

Approach

  1. Give specifics: the format (a recurring session, a shared guidelines repository, pair-programming slots), who joined, and the recurring problem that prompted it, such as async/await misuse or inefficient Entity Framework queries found in reviews.
  2. For mentoring, describe the person's starting point, the goal you agreed, the task you gave them to own, how you gave feedback in reviews, and how you stepped back as they improved.
  3. Back it with evidence: fewer review comments on the same issue, a mentee shipping a feature independently, or adoption of a shared practice.
  4. Avoid vague help-when-asked claims, taking credit for others' work, or controlling the mentee's work. Say what did not work and what you changed.

Follow-up

  • How did you handle a mentee who was not improving?
  • How did you keep the community of practice going after the first sessions?
  • How did you judge whether it was worth the time?

How do you ensure your team stays focused and delivers on time during a chaotic Agile sprint?

Medium · Behavioral & Leadership

Approach

  1. Define 'chaotic' with a real example: work added mid-sprint, stories blocked on another team, or a production incident taking people away from planned work.
  2. Describe the actions in order: re-triage with the product owner against the sprint goal, agree explicitly what moves out, make blockers visible in daily stand-up, swarm on the blocked item, and keep stories small and meeting the Definition of Ready.
  3. Show early communication: you told stakeholders about the revised forecast before the sprint review, not after it.
  4. Close with what shipped, what slipped and the retrospective change, such as a reserved allowance for support work or a rule for mid-sprint additions. Do not present overtime and heroics as the fix.

Follow-up

  • What do you do when a stakeholder insists on adding work mid-sprint?
  • How do you handle a production incident that lands in the middle of a sprint?
  • What did the retrospective actually change?