Top .NET Interview Questions & Answers (3–7 Years) with Code & Real-Life Examples | SuryaTechCodex ...
Top .NET Interview Questions & Answers (3–7 Years) — With Code, Output & Real-Life Examples
By SuryaTechCodex • Updated:
If you’re preparing for a .NET interview with 3–7 years of experience, this guide gives you concise answers, clean code snippets, actual outputs, and real-life scenarios for C#, ASP.NET Core, EF Core, LINQ, SQL, and a coding round problem.
Tip: During interviews, pair each answer with a short story from your project—how you used it, why, and the impact.
Q1. Abstract Class vs Interface
Answer: An abstract class can have fields, constructors, concrete and abstract members; a class can inherit only one abstract class. An interface defines a contract; a class can implement multiple interfaces—ideal for cross-cutting behaviors.
// Abstract Class
public abstract class Shape
{
public abstract double Area();
public void Display() => Console.WriteLine("Shape Display");
}
// Interface
public interface IPrintable
{
void Print();
}
public class Circle : Shape, IPrintable
{
public double Radius { get; set; }
public Circle(double radius) { Radius = radius; }
public override double Area() => Math.PI * Radius * Radius;
public void Print() => Console.WriteLine($"Circle with radius {Radius}, Area = {Area()}");
}
public class Program
{
public static void Main()
{
IPrintable obj = new Circle(5);
obj.Print();
}
}
Real-Life Example: Use an abstract base like Vehicle for Cars/Bikes (shared defaults). Use IPrintable, IAuditable as behaviors across unrelated classes (e.g., Order, Report, Invoice all “Printable”).
Q2. async / await (How it really works)
Answer: async/await lets you write non-blocking code. The compiler rewrites your method into a state machine that pauses at await and resumes when the awaited task completes—great for I/O (DB calls, HTTP).
public class AsyncDemo
{
public async Task RunDemo()
{
Console.WriteLine("Task started...");
await Task.Delay(2000); // Simulates an I/O-bound operation
Console.WriteLine("Task finished!");
}
}
public class Program
{
public static async Task Main(string[] args)
{
await new AsyncDemo().RunDemo();
}
}
Real-Life Example: In an ASP.NET Core API, call EF Core and external services using await so Kestrel threads aren’t blocked; this increases throughput under load.
Q3. Middleware in ASP.NET Core
Answer: Middleware are components in the request pipeline (logging, auth, routing, exception handling). Each middleware can do work before/after calling the next component.
public class RequestLoggingMiddleware
{
private readonly RequestDelegate _next;
public RequestLoggingMiddleware(RequestDelegate next) => _next = next;
public async Task Invoke(HttpContext context)
{
Console.WriteLine($"Request: {context.Request.Path}");
await _next(context); // pass to next middleware
}
}
// In Program.cs or Startup.cs
app.UseMiddleware<RequestLoggingMiddleware>();
Real-Life Example: Implement a custom exception handling middleware to convert unhandled exceptions into consistent JSON with correlation IDs for observability.
Q4. Dependency Injection: Scoped, Transient, Singleton
Answer: Transient = new instance each time; Scoped = one per HTTP request; Singleton = one for the entire app lifetime.
public interface IMessageService
{
string GetMessage();
}
public class MessageService : IMessageService
{
public string GetMessage() => $"Message at {DateTime.Now:HH:mm:ss.fff}";
}
// Program.cs / Startup.cs
// Try AddTransient / AddScoped / AddSingleton to observe lifecycle
services.AddTransient<IMessageService, MessageService>();
public class HomeController : ControllerBase
{
private readonly IMessageService _svc;
public HomeController(IMessageService svc) => _svc = svc;
[HttpGet("/")]
public string Index() => _svc.GetMessage();
}
Real-Life Example: Use Singleton for ILogger/config; Scoped for DbContext; Transient for lightweight stateless utilities.
Q5. IQueryable vs IEnumerable
Answer: IQueryable builds an expression tree and executes on the database (deferred execution). IEnumerable operates in memory on materialized data.
// IQueryable (DB-side filtering)
var richFromDb = context.Employees
.Where(e => e.Salary > 50000); // translated to SQL
// IEnumerable (in-memory filtering)
var richInMemory = context.Employees
.ToList() // loads all rows first
.Where(e => e.Salary > 50000); // then filters in memory
Real-Life Example: For API endpoints with filters/sorts, keep queries as IQueryable until the very end to push work to SQL (less memory, faster).
Q6. SQL: Find the Second Highest Salary
SELECT MAX(Salary)
FROM Employees
WHERE Salary < (SELECT MAX(Salary) FROM Employees);
Alternative (handles duplicates, top-N):
SELECT Salary
FROM Employees
GROUP BY Salary
ORDER BY Salary DESC
OFFSET 1 ROW FETCH NEXT 1 ROW ONLY;
Real-Life Example: Reporting “runner-up” compensation, incentive slabs, or finding rank-based KPIs.
Q7. Coding: First Non-Repeating Character
Answer: Group characters and pick the first with count = 1.
using System;
using System.Linq;
public class Program
{
public static void Main()
{
string input = "swiss";
char result = input
.GroupBy(c => c)
.Where(g => g.Count() == 1)
.Select(g => g.Key)
.FirstOrDefault();
Console.WriteLine(result == default(char) ? '-' : result);
}
}
Real-Life Example: Useful for validation tools, editors, or analytics where uniqueness matters (e.g., detecting the first unique token in a stream).
Next Episode (Tomorrow): Career Growth Path for .NET Developers (3–7 Years) — skills, projects, certifications, and interview strategy.
Quick FAQs
- How should I answer design questions?
- State constraints, propose a simple baseline, then add performance, reliability, and security. Use trade-offs and numbers if you have them.
- What should I do if I forget syntax?
- Explain the concept clearly, then say “I’ll look up exact syntax in docs when implementing.” Interviewers value clarity and honesty.
