Q1. Your ASP.NET Core Web API is slow in production. How would you investigate and improve its performance?

Investigation

Start with observability:

Measure:

Common Bottlenecks

Slow SQL Queries

N+1 Queries

Blocking Calls (.Result/.Wait())

Large Payloads

ThreadPool Starvation

Excessive Logging

Improvements

✅ Use async/await

✅ Add database indexes

✅ Cache frequently accessed data

✅ Use pagination

✅ Response compression

✅ Optimize EF Core queries

✅ Use CDN for static files

✅ Reduce serialization overhead

Example

Code
var customers = await _dbContext.Customers
 .AsNoTracking()

 .ToListAsync();

Q2. Your application needs to call an external API that sometimes fails or responds slowly. How would you make the integration resilient?

Use resilience patterns.

Retry

Code
builder.Services.AddHttpClient("Orders")
 .AddPolicyHandler(

 Policy.Handle<HttpRequestException>()

 .WaitAndRetryAsync(3,

 retry => TimeSpan.FromSeconds(

 Math.Pow(2, retry))));

Additional Patterns

✅ Retry

✅ Circuit Breaker

✅ Timeout

✅ Bulkhead Isolation

✅ Fallback

Example Flow

API Fails

↓

Retry

↓

Still Fails

↓

Circuit Opens

↓

Fallback Response

Q3. Users occasionally submit the same payment request multiple times. How would you prevent duplicate processing?

Implement Idempotency.

Example

POST /payment

Idempotency-Key: ABC123

Store the key.

Request Received

↓

Has Key Been Processed?

↓

Yes → Return Existing Result

No → Process Payment

Database table:

IdempotencyKey

RequestId

Response

This prevents duplicate charges.

Q4. A background task takes several minutes to complete and should not block the API response. How would you design it in .NET?

API

Code
[HttpPost]
public IActionResult GenerateReport()
{
 _backgroundQueue.QueueJob(...);
 return Accepted();
}

Response:

202 Accepted

Background Processing

Use:

BackgroundService

IHostedService

Azure Service Bus

RabbitMQ

Hangfire

Architecture:

API

↓

Queue

↓

Background Worker

↓

Process Job

Q5. Your application is consuming too much memory in production. How would you identify and fix the issue?

Investigation

Tools:

dotnet-gcdump

dotnet-dump

Visual Studio Profiler

Application Insights

Check:

✅ Large object allocations

✅ Memory leaks

✅ Static collections

✅ Cache growth

✅ Unreleased resources

Fixes

Code
await using var stream =
 File.OpenRead(path);

Use:

IDisposable

IAsyncDisposable

Limit:

Cache Size

Queue Length

Buffer Size

Q6. You need different implementations of the same service for different customers or business conditions. How would you design this using dependency injection?

Registration

Code
builder.Services.AddScoped<INotifier,
 EmailNotifier>();

builder.Services.AddScoped<INotifier,

 SmsNotifier>();

Inject All

Code
public NotificationService(
 IEnumerable<INotifier> notifiers)
{
}

Strategy Pattern

Code
public interface IPricingStrategy
{
 decimal Calculate ();
}

Choose implementation dynamically.

Common patterns:

✅ Strategy Pattern

✅ Factory Pattern

✅ Keyed Services (.NET 8)

Q7. Two users update the same database record at the same time. How would you handle concurrency in Entity Framework Core?

Use Optimistic Concurrency.

Entity

Code
public class Product
{
 public int Id { get; set; }
 [Timestamp]
 public byte[] RowVersion { get; set; }
}

Save

EF generates:

Code
WHERE RowVersion = @OldVersion

If another user already modified the row:

Code
DbUpdateConcurrencyException

Handle:

Code
catch (DbUpdateConcurrencyException)
{
}

Q8. A production error is occurring, but you cannot reproduce it locally. How would you diagnose it?

Collect Evidence

✅ Structured logs

✅ Correlation IDs

✅ Distributed tracing

✅ Application Insights

Example

Code
_logger.LogError(ex,
 "Error processing Order {OrderId}",
 orderId);

Track:

Request

↓

API

↓

Database

↓

External Services

Look at:

Q9. Your API must handle thousands of requests per minute. What changes would you make to improve scalability?

Application Layer

✅ async/await everywhere

✅ Avoid .Result/.Wait()

✅ Connection pooling

✅ Response caching

✅ Distributed caching

IDistributedCache

Database Layer

✅ Indexing

✅ Read replicas

✅ Query optimization

Infrastructure

✅ Horizontal scaling

✅ Load balancing

✅ CDN

✅ Queue-based processing

Architecture:

Load Balancer

↓

API Instances

↓

Redis Cache

↓

SQL Database

Q10. You need to split a large .NET monolith into microservices. How would you decide service boundaries and migrate safely?

Don't Start With Technology

Start with business capabilities.

Examples:

Customer

Order

Inventory

Payment

Shipping

Not:

Database Tables

Use Domain-Driven Design

Identify:

Bounded Contexts

Example:

Order Service

Inventory Service

Payment Service

Safe Migration Strategy

Step 1

Identify one domain.

Order Module

Step 2

Extract into service.

Step 3

Use APIs/events.

Monolith

↓

Order Service

Step 4

Apply Strangler Fig Pattern.

New Requests

↓

Microservice

Old Requests

↓

Monolith

Gradually migrate functionality.

Architecture

API Gateway

↓

Customer Service

Order Service

Inventory Service

Payment Service