Microsoft .NET Full Stack Interview Questions & Answers
Curated interview practice questions with answers. These are practice scenarios, not a verified list of past interview questions.
About Microsoft hiring for .NET Full Stack roles
Microsoft builds software, cloud and hardware products including Windows, Microsoft 365, Azure, Dynamics, GitHub, LinkedIn and Xbox. The India Development Center in Hyderabad and Bengaluru is one of its largest engineering hubs outside the US. It hires for software engineers, data scientists, data and applied scientists, and engineers working on Azure data and quality.
For .NET Full Stack roles, this Microsoft practice set focuses most on Entity Framework Core (7), ASP.NET Core Web API (5), Angular and React Front End (4), Async Programming and Multithreading (4). It has 2 easy, 19 medium, 9 hard questions, so you can start easy and work up to the harder ones.
Company type
Product
Headquarters
Redmond, Washington, USA
Main India offices
Hyderabad, Bengaluru, Noida, Gurugram, Pune
Microsoft .NET Full Stack interview process
Online coding assessment
Technical round 1 (DSA)
Technical round 2 (DSA or design)
Hiring manager round
AA (As Appropriate) round
Typical pattern based on public candidate experiences. Rounds vary by role, team and year.
Solved for MicrosoftStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
✓ 3 questions free • Unlock the rest in seconds
01
Configure JWT bearer authentication in an ASP.NET Core API.
Lazy loading splits the app into chunks that download only when the user navigates to that route, so the initial bundle is smaller and the first page loads faster, especially on mobile data. In Angular use loadComponent or loadChildren with a dynamic import in the route config; in React use React.lazy with Suspense or the router's lazy option. Angular's @defer blocks can also delay heavy parts of a page.
03
Write custom middleware that logs how long each request takes.
public class TimingMiddleware(RequestDelegate next, ILogger<TimingMiddleware> logger)
{
public async Task InvokeAsync(HttpContext context)
{
var sw = Stopwatch.StartNew();
await next(context);
sw.Stop();
logger.LogInformation("{Method} {Path} -> {Status} in {Ms} ms",
context.Request.Method, context.Request.Path,
context.Response.StatusCode, sw.ElapsedMilliseconds);
}
}
// Program.cs
app.UseMiddleware<TimingMiddleware>();
Code before next runs on the request, code after it runs on the response.
04
What is the difference between a primary key and a unique key in SQL Server?
Both enforce uniqueness. A table can have only one primary key, it cannot contain NULLs, and by default SQL Server creates a clustered index for it. A table can have many unique constraints, each allowing a single NULL in SQL Server, and they create non-clustered indexes by default. Use the primary key for row identity, such as EmployeeId, and unique keys for business rules like a unique email or PAN.
public async IAsyncEnumerable<Order> GetOrdersAsync(
[EnumeratorCancellation] CancellationToken ct = default)
{
await foreach (var o in _db.Orders.AsNoTracking().AsAsyncEnumerable().WithCancellation(ct))
yield return o;
}
// consumer
await foreach (var order in service.GetOrdersAsync())
Console.WriteLine(order.Id);
Items are produced and consumed one at a time asynchronously. ASP.NET Core can stream an IAsyncEnumerable result as JSON without buffering the whole list.
06
What is the difference between Select and SelectMany?
Select projects each element to one result, so a list of customers mapped to their orders gives a list of lists. SelectMany projects each element to a sequence and flattens all sequences into one, so customers.SelectMany(c => c.Orders) gives a single list of all orders. In EF Core, SelectMany over a navigation collection translates to a SQL join, which is handy for reports.
07
Your security team objects to storing the JWT in localStorage in your Angular app. What are the options?
localStorage is readable by any JavaScript on the page, so an XSS bug can steal the token. A safer pattern is to keep the short-lived access token in memory and store the refresh token in an HttpOnly, Secure, SameSite cookie that scripts cannot read. Even better is the backend-for-frontend pattern, where ASP.NET Core holds tokens server-side and the browser uses a session cookie. Add CSRF protection when using cookies.
08
Your product API must handle a festive sale with 10 times normal traffic. How do you prepare it?
Make the API stateless so you can scale it horizontally behind a load balancer or Kubernetes autoscaler. Cache read-heavy data such as product details in Redis or HybridCache. Ensure all I/O is async and database queries are indexed, projected and paged. Move slow work like emails to queues. Add rate limiting, timeouts and circuit breakers to dependencies, then load test with k6 or JMeter and watch metrics.
09
Your multi-tenant SaaS app keeps all tenants in one database. How do you make sure EF Core queries never return another tenant's data?
Add a TenantId column to every tenant-owned entity and a global query filter such as HasQueryFilter(e => e.TenantId == _tenantId), where the tenant ID comes from a scoped provider that reads the authenticated user's claim. Set TenantId automatically in SaveChanges for new rows. Index TenantId, write integration tests that try cross-tenant access, audit every IgnoreQueryFilters call, and consider SQL Server row-level security as a second layer of defence.
10
A legacy ASP.NET MVC app on .NET Framework hangs when a controller calls GetDataAsync().Result. Why, and how do you fix it?
This is the classic sync-over-async deadlock. .Result blocks the request thread, which holds the ASP.NET synchronization context. When the awaited task completes, its continuation tries to resume on that same context, which is blocked, so neither can proceed. The real fix is async all the way: make the action async and await the call. Where that is impossible, ConfigureAwait(false) inside the library avoids capturing the context.
11
Show a class using a primary constructor with dependency injection.
public class OrderService(IOrderRepository repo, ILogger<OrderService> logger)
{
public async Task<Order?> GetAsync(int id)
{
logger.LogInformation("Fetching order {Id}", id);
return await repo.FindAsync(id);
}
}
Primary constructors on classes arrived in C# 12. Parameters are captured and usable in all members, removing boilerplate fields. They are not readonly, so assign to a readonly field if immutability matters.
12
A job matches 2 lakh uploaded records against 2 lakh existing IDs using list.Where(x => existingIds.Contains(x.Id)) and takes minutes. What is wrong?
existingIds is a List, so Contains is O(n) and the whole operation becomes O(n x m), around 40 billion comparisons. Convert the IDs to a HashSet<int> first, making each lookup O(1) and the job run in milliseconds. If you also need associated data, build a Dictionary keyed by ID. Always check data structure complexity before parallelising or adding hardware.
13
What is the difference between throw and throw ex inside a catch block?
throw rethrows the current exception and preserves the original stack trace, so logs show where the error really started. throw ex resets the stack trace to the catch block, hiding the real source. Always use throw when rethrowing. If you need more context, wrap it: throw new OrderException("Payment failed", ex), which keeps the original as InnerException. Also avoid catching Exception unless you log and rethrow.
14
Fetch products from an ASP.NET Core API in React with loading and error states.
DbContext already implements Repository and Unit of Work, so a thin generic repository with GetAll and Add often adds code while hiding useful features like Include, projections and AsNoTracking. I prefer either using DbContext directly in services, or specific repositories with meaningful methods like GetOverdueInvoicesAsync that encapsulate queries. For tests, use the SQLite in-memory provider or Testcontainers rather than mocking DbSet.
16
You need to add a new method to a widely implemented interface without breaking existing classes. How can you do it?
Since C# 8, an interface can provide a method body. Classes implementing the interface get that behaviour without writing it, though they can override it. The main use is evolving a published interface: you can add a new member without breaking every existing implementation. The default method is only callable through the interface type, not the class, and overusing it blurs the line with abstract classes.
17
Access tokens in your app expire in 15 minutes and users complain about being logged out. How do you implement refresh tokens securely?
Issue a short-lived JWT access token plus a long-lived, random refresh token stored hashed in the database with expiry and device info. When the access token expires, the client calls /refresh with the refresh token; the server validates it, revokes it and issues a new pair, which is rotation. Reuse of a revoked token signals theft, so revoke the whole chain. In browsers, store the refresh token in an HttpOnly, Secure, SameSite cookie.
18
A developer runs two EF Core queries in parallel with Task.WhenAll on the same DbContext and gets an InvalidOperationException. Why?
DbContext is not thread-safe and supports only one active operation at a time, so starting a second query before the first finishes throws 'A second operation was started on this context instance'. Either await the queries one after another, or create a separate context for each parallel query using IDbContextFactory. Usually sequential queries are fine; parallelism only helps when the queries are slow and independent.
19
Show the useState and useEffect hooks in a React component.
import { useState, useEffect } from 'react';
export function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const id = setInterval(() => setSeconds(s => s + 1), 1000);
return () => clearInterval(id); // cleanup on unmount
}, []); // empty array: run once
return <p>Elapsed: {seconds}s</p>;
}
useState stores state that triggers re-render; useEffect runs side effects after render, and its dependency array controls when it re-runs.
20
Write a stored procedure that transfers money between accounts with TRY-CATCH and a transaction.
CREATE OR ALTER PROCEDURE usp_Transfer @From INT, @To INT, @Amt DECIMAL(18,2)
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
BEGIN TRY
BEGIN TRAN;
UPDATE Accounts SET Balance = Balance - @Amt
WHERE Id = @From AND Balance >= @Amt;
IF @@ROWCOUNT = 0 THROW 50001, 'Insufficient balance', 1;
UPDATE Accounts SET Balance = Balance + @Amt WHERE Id = @To;
COMMIT;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 ROLLBACK;
THROW;
END CATCH
END
Disposing HttpClient does not immediately free the underlying socket; connections stay in TIME_WAIT, so thousands of short-lived clients exhaust ports. A single static client fixes that but misses DNS changes. The recommended fix is IHttpClientFactory: register builder.Services.AddHttpClient<PaymentClient>() and inject the typed client. The factory pools and rotates handlers, and you can add resilience with Microsoft.Extensions.Http.Resilience for retries and timeouts.
23
A stored procedure is fast for most customers but very slow for one large customer, and sometimes slow for everyone after a restart. What could cause this?
This is parameter sniffing. SQL Server compiles a plan using the first parameter values it sees and reuses it. A plan built for a small customer, using index seeks, can be terrible for a huge one, and vice versa. Fixes include OPTION (RECOMPILE) for that statement, OPTIMIZE FOR, splitting logic for skewed values, or Query Store plan forcing. SQL Server 2022 adds Parameter Sensitive Plan optimisation to keep multiple plans.
24
Write a BackgroundService that cleans expired OTPs every 5 minutes.
public class OtpCleanupService(IServiceScopeFactory scopes) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken ct)
{
using var timer = new PeriodicTimer(TimeSpan.FromMinutes(5));
while (await timer.WaitForNextTickAsync(ct))
{
using var scope = scopes.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
await db.Otps.Where(o => o.ExpiresAt < DateTime.UtcNow).ExecuteDeleteAsync(ct);
}
}
}
// builder.Services.AddHostedService<OtpCleanupService>();
A scope is created because DbContext is scoped while hosted services are singletons.
25
How do you use an explicit transaction in EF Core across multiple SaveChanges calls?
await using var tx = await db.Database.BeginTransactionAsync();
try
{
db.Orders.Add(order);
await db.SaveChangesAsync();
var stock = await db.Stocks.SingleAsync(s => s.ProductId == order.ProductId);
stock.Quantity -= order.Quantity;
await db.SaveChangesAsync();
await tx.CommitAsync();
}
catch
{
await tx.RollbackAsync();
throw;
}
A single SaveChanges is already transactional; explicit transactions are needed when you combine several saves or raw SQL into one unit.
26
A page listing 100 orders with customer names runs 101 SQL queries. What is the problem and how do you fix it?
This is the N+1 problem: one query loads the orders, then lazy loading fires a separate query for each order's Customer. Fix it by loading everything in one query, either with Include(o => o.Customer) or better with a projection: Select(o => new OrderListDto(o.Id, o.Total, o.Customer.Name)), which fetches only needed columns via a join. Turn on EF Core logging to spot such patterns early.
27
Several threads update an in-memory Dictionary cache in a singleton service and you see corrupted data and exceptions. What would you use instead?
System.Collections.Concurrent provides thread-safe collections: ConcurrentDictionary, ConcurrentQueue, ConcurrentStack, ConcurrentBag and BlockingCollection. They use fine-grained locking or lock-free techniques, so multiple threads can read and write without your own lock. Use ConcurrentDictionary for in-memory caches in singleton services. Note that GetOrAdd may run the value factory more than once under contention, so keep the factory side-effect free or wrap it in Lazy<T>.
28
You are designing a type to hold a 2D point used millions of times in a calculation. Struct or class?
A struct is a good fit because the point is small, logically a single value and created in huge numbers. Structs avoid heap allocation and GC pressure when stored in arrays or locals. Make it a readonly struct so it is immutable and avoids defensive copies. Choose a class instead if the type is large, needs inheritance, or is frequently boxed through interfaces, since copying and boxing remove the benefit.
Each request needs a thread from the thread pool. If a controller blocks while waiting for SQL Server or an external API, that thread sits idle and cannot serve other users, so under load the pool runs out and requests queue. With async I/O, the thread is released during the wait and reused, so the same server handles many more concurrent requests. It does not make a single request faster.
Tips to crack the Microsoft .NET Full Stack interview
Practise DSA on linked lists, trees and graphs, and be ready to write clean, compilable code with edge cases handled.
Learn basic Azure data services such as Azure SQL, Synapse and Data Factory if you are applying for data roles.
Prepare examples showing a growth mindset, which Microsoft highlights as a core part of its culture.
Keep a one-minute story ready for every project on your CV: problem, your part, tools, result.
Practise the hard questions on this page aloud; Microsoft interviewers usually ask follow-ups on your first answer.
Frequently asked questions
How many rounds are there in the Microsoft .NET Full Stack interview?
Candidates usually go through 5 stages: Online coding assessment; Technical round 1 (DSA); Technical round 2 (DSA or design); Hiring manager round; AA (As Appropriate) round. The exact rounds change with the role, team, location and your experience, so confirm the process with the recruiter.
Which topics should I prepare for the Microsoft .NET Full Stack interview?
This practice set leans on Entity Framework Core (7), ASP.NET Core Web API (5), Angular and React Front End (4), Async Programming and Multithreading (4). Revise those first, then practise explaining one or two of your own projects end to end, because most Microsoft interviewers ask you to walk through real work.
Are these the exact questions asked at Microsoft?
No. These are curated practice questions that match the skills and difficulty usually tested in product interviews like Microsoft's. They are not a leaked or verified list of past questions.
Where does Microsoft hire .NET Full Stack professionals in India?
Microsoft has large teams in Hyderabad, Bengaluru, Noida, Gurugram, Pune. Openings and locations change often, so check the Microsoft careers page and filter by city and experience.