By the time you reach the second round of a .NET interview, the tone changes.
They’ve already tested whether you understand APIs, load balancers, and databases.
Now they want to see how you think when things break.
This round isn’t about memorizing patterns. It’s about proving that you can build, debug, and fix systems under pressure — and that you understand why each decision matters.
I’ve sat on both sides of that table. I’ve watched developers panic when asked why their EF Core query took 5 seconds. And I’ve seen quiet candidates shine because they could explain how they’d trace a timeout in App Insights.
This post is about helping you become that second kind of developer.
Think of it as a conversation — not a tutorial.
1. The API Round: When “Hello World” Isn’t Enough
In your first interview, they might have asked, “How do you design an API?”
In the second, they’ll ask, “Your API’s login endpoint takes 3 seconds for some users. What would you check first?”
That’s when your understanding of Auth0, JWT, and rate limiting suddenly matters.
My Usual Setup
When I design secure APIs, I start with Auth0 or Azure AD. Both work great with JWT tokens.
Here’s what I’d say in an interview:
“I’d use JWT-based authentication with a short-lived access token and a refresh token. Validation happens in middleware, and only verified tokens reach the controller.”
And if you want to back it up with real code:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "https://mytenant.auth0.com/";
options.Audience = "https://api.myapp.com";
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = ctx =>
{
Console.WriteLine($"Token error: {ctx.Exception.Message}");
return Task.CompletedTask;
}
};
});
That snippet shows you’ve built one, not just read about it.
Handling API Errors Gracefully
In production, you don’t want to send raw exceptions back to users.
A small middleware can make your API feel much more professional.
app.UseExceptionHandler(appError =>
{
appError.Run(async context =>
{
var feature = context.Features.Get<IExceptionHandlerFeature>();
context.Response.StatusCode = 500;
await context.Response.WriteAsJsonAsync(new
{
Error = "Something went wrong.",
Detail = feature?.Error.Message
});
});
});
That’s all it takes to show that you understand fault tolerance — a trait every interviewer loves.
2. Performance and Query Troubleshooting
I once got a call at 2 a.m. because an API endpoint suddenly slowed to a crawl. The reason?
A missing AsNoTracking() in Entity Framework.
That’s not something you forget.
EF Core Tracking
Every time EF fetches entities, it tracks them for changes. That’s great when you’re updating data, but terrible when you’re just reading.
var users = await _db.Users
.AsNoTracking()
.Where(u => u.IsActive)
.ToListAsync();
I always mention this in interviews:
“When a query is read-only, I disable tracking. It cuts overhead and saves memory.”
You don’t have to sound like a textbook — just show that you’ve seen this problem in the wild.
Compiled Queries for Heavy Load
In high-traffic systems, I use compiled queries for repeated lookups.
private static readonly Func<AppDbContext, bool, Task<List<User>>> ActiveUsersQuery =
EF.CompileAsyncQuery((AppDbContext db, bool active) =>
db.Users.Where(u => u.IsActive == active).ToList());
That one line tells your interviewer you know performance tuning in EF Core.
Indexing and Caching
A good rule: if the same API hits the database repeatedly, it deserves a cache.
var key = "active_users";
var json = await _cache.GetStringAsync(key);
if (json == null)
{
var data = await _db.Users.Where(x => x.IsActive).ToListAsync();
await _cache.SetStringAsync(key, JsonSerializer.Serialize(data));
}
Mention you’d use Redis for distributed caching and App Insights for query tracing.
These are the small details that make you sound like someone who’s lived through performance fires.
3. Concurrency and Thread Safety
If the interviewer smiles and asks, “What happens if two users update the same record at once?”, they’re checking how deep you understand concurrency.
Here’s the real-world version of that question:
Your update endpoint overwrites someone else’s change because both users hit “save” at the same time.
The Fix — Concurrency Tokens
In EF Core, you can add a simple [Timestamp] attribute to detect such conflicts.
public class User
{
public Guid Id { get; set; }
public string Name { get; set; }
[Timestamp]
public byte[] RowVersion { get; set; }
}
When a conflict occurs, EF throws a DbUpdateConcurrencyException.
I’d catch it and show a message like “Data was updated by another user. Please refresh.”
Optimistic vs Pessimistic Locking
When you explain this in an interview, keep it simple:
“Optimistic locking assumes conflicts are rare. It retries on failure. Pessimistic locking holds database locks, which can hurt performance.”
If you’ve worked with stored procedures, mention you’ve seen deadlocks and solved them using retry logic with Polly.
4. Messaging and Reliability
The second round often brings a scenario like this:
“You have an order system. Sometimes messages are processed twice, sometimes they’re lost. What would you do?”
If you’ve used RabbitMQ, Kafka, or Azure Service Bus, this is your moment.
I usually describe my setup like this:
“Each message has a unique ID. Before processing, I check if it’s already in the database. If it is, I skip it.”
That’s called idempotency, and it’s critical for reliable systems.
Example
if (!_db.ProcessedMessages.Any(m => m.Id == message.Id))
{
_db.ProcessedMessages.Add(message);
await _db.SaveChangesAsync();
}
Handling Failures
If a message fails after multiple retries, I send it to a Dead Letter Queue (DLQ).
var processor = client.CreateProcessor("orders", new ServiceBusProcessorOptions());
processor.ProcessErrorAsync += async args =>
{
await deadLetterClient.SendMessageAsync(new ServiceBusMessage(args.Exception.ToString()));
};
That’s the kind of detail interviewers look for — you don’t panic, you build systems that recover gracefully.
5. Scaling Sessions with Distributed Cache
A real interview question I once asked:
“Your .NET app is load-balanced across 3 servers, but users get logged out randomly. What’s happening?”
Most candidates miss this one. The session is stored in-memory, so each request might hit a different server.
The fix? Move sessions to a distributed cache, like Redis.
services.AddDistributedRedisCache(options =>
{
options.Configuration = "localhost:6379";
});
services.AddSession();
And don’t forget the middleware:
app.UseSession();
If you mention this and add,
“For single-instance apps, I’d just use in-memory cache for simplicity,”
you’ll sound practical — and that’s what second rounds are about.
6. Monitoring, Tracing, and Diagnosing Production Bugs
If there’s one area that separates juniors from seniors, it’s monitoring.
When a system crashes at midnight, no one wants a theory — they want evidence.
I live inside Application Insights. That’s where I find dependency bottlenecks, slow queries, and failing endpoints.
Logging with Context
Log.Information("User {UserId} created order {OrderId}", user.Id, order.Id);
I always use structured logging. It helps me trace one user’s entire journey across microservices.
Distributed Tracing with OpenTelemetry
OpenTelemetry is like a breadcrumb trail for your APIs.
services.AddOpenTelemetry()
.WithTracing(builder =>
{
builder.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddConsoleExporter();
});
In an interview, you can say:
“If a request touches multiple services, I use correlation IDs to trace it end-to-end.”
That one line shows maturity.
7. Putting It All Together — Real Architecture Scenarios
Here’s what an interviewer might say:
“Design a system that sends notifications when a user uploads a file.”
Here’s how I’d outline it:
- API: ASP.NET Core Web API (for file upload).
- Storage: Azure Blob Storage.
- Queue: Azure Service Bus (to trigger notification).
- Worker Service: .NET BackgroundService that listens to queue.
- Cache: Redis for metadata lookups.
- CDN: Azure Front Door for public file delivery.
Every part ties back to the topics from Round 1 and Round 2.
8. Mock Q&A — Round Two Highlights
Q1. Your API slows down during peak hours. What’s your first step?
A1. Check logs and App Insights dependencies. Identify slow database calls. If confirmed, cache heavy queries or add read replicas.
Q2. You deployed a microservice update. Half the requests now fail.
A2. I’d roll back using blue-green deployment. Check schema compatibility. If schema drift caused it, add versioned endpoints.
Q3. A message queue is growing faster than consumers can process.
A3. Add consumer scaling logic. If using Azure Service Bus, increase MaxConcurrentCalls. For Kafka, expand consumer groups.
Q4. How do you debug cross-service errors?
A4. Add X-Correlation-ID in all services. Pass it along in headers. Use Serilog Enrichers to log it everywhere.
Q5. How do you handle timeouts in distributed systems?
A5. Use Polly for retry + circuit breaker. Add exponential backoff and clear logs to trace retries.
9. What Interviewers Really Test
At this stage, they’re not grading you on buzzwords. They’re judging your thinking process.
When you explain how you’d handle failure, scaling, or debugging — be specific.
Say things like:
- “I’d use Redis to store sessions because my app is load-balanced.”
- “I’d track correlation IDs through logs to trace user requests.”
- “I’d enable EF Core logging to identify slow SQL queries.”
These are the things that make interviewers lean forward and listen.
Final Words
If the first round was about knowing what to build, the second is about knowing how to keep it alive.
I’ve learned that real-world systems rarely break in one big explosion.
They fail quietly — one timeout here, one retry there — until a customer emails saying, “The app feels slow.”
That’s when all of this knowledge matters: caching, logging, messaging, scaling.
Not because it sounds good in interviews, but because it’s what we do every day to keep our systems breathing.
So, when you walk into your second-round interview, don’t worry about perfect answers.
Speak like someone who’s built and fixed things.
That’s what they’re looking for.


















