Dependency Injection
Dependency Injection (DI) is one of the most commonly asked .NET Core interview questions.
What is Dependency Injection in .NET Core?
Dependency Injection (DI) is a design pattern where an object receives its dependencies from outside instead of creating them itself.
Without Dependency Injection (Bad Practice)
public class OrderService
{
private EmailService _emailService;
public OrderService()
{
_emailService = new EmailService(); // tightly coupled
}
public void PlaceOrder()
{
_emailService.SendEmail();
}
}
Problems here
-
Tight coupling
-
Hard to test
-
Hard to change implementation
-
Violates SOLID principles
With Dependency Injection (Good Practice)
public class OrderService
{
private readonly IEmailService _emailService;
public OrderService(IEmailService emailService)
{
_emailService = emailService;
}
public void PlaceOrder()
{
_emailService.SendEmail();
}
}
Now dependency is injected from outside.
Step-by-Step Simplest Example
Step 1: Create Interface
public interface IMessageService
{
void SendMessage();
}
Step 2: Create Implementation
public class EmailService : IMessageService
{
public void SendMessage()
{
Console.WriteLine("Email Sent");
}
}
Step 3: Register in Program.cs
(.NET 6 / .NET 7 / .NET 8)
builder.Services.AddScoped<IMessageService, EmailService>();
Step 4: Inject in Controller
public class HomeController : Controller
{
private readonly IMessageService _messageService;
public HomeController(IMessageService messageService)
{
_messageService = messageService;
}
public IActionResult Index()
{
_messageService.SendMessage();
return View();
}
}
That's it.
.NET Core automatically injects the dependency.
Types of Dependency Injection Lifetimes
This is very important for interviews 👇
1. Transient
New instance every time
builder.Services.AddTransient<IMessageService, EmailService>();
Use when:
-
Lightweight services
-
No shared state
2. Scoped
One instance per request (Most commonly used)
builder.Services.AddScoped<IMessageService, EmailService>();
Use when:
-
Database services
-
Business logic services
Example:
-
DbContext (Scoped)
3. Singleton
Single instance for entire application
builder.Services.AddSingleton<IMessageService, EmailService>();
Use when:
-
Caching
-
Configuration
-
Logging
Real World Example
public interface IUserRepository
{
List<string> GetUsers();
}
public class UserRepository : IUserRepository
{
public List<string> GetUsers()
{
return new List<string> { "John", "David" };
}
}
Register:
builder.Services.AddScoped<IUserRepository, UserRepository>();
Inject:
public class UserService
{
private readonly IUserRepository _repository;
public UserService(IUserRepository repository)
{
_repository = repository;
}
public void GetUsers()
{
var users = _repository.GetUsers();
}
}
Why Dependency Injection is Important
Interview-friendly points:
-
Loose coupling
-
Easy unit testing
-
Maintainable code
-
Better scalability
-
Follow SOLID principles
-
Easy to replace implementations
One Line Interview Answer
Dependency Injection is a design pattern where dependencies are provided to a class from outside instead of creating them inside the class, helping achieve loose coupling and better maintainability.
Constructor Injection vs Method Injection vs Property Injection
Most commonly used: Constructor Injection
Constructor Injection (Recommended)
public HomeController(IMessageService messageService)
Property Injection
public IMessageService MessageService { get; set; }
Method Injection
public void Send(IMessageService messageService)
Most Asked Interview Question
Q: Does .NET Core support DI by default?
Yes. .NET Core has built-in Dependency Injection container.
Short Real-Life Example
Think of Dependency Injection like:
You don't cook food yourself.
You order from restaurant.
Restaurant = Dependency
Your class doesn't create dependencies — they are injected.
What is a Delegate in C#?
Delegates are one of the most commonly asked C# interview topics.
What is a Delegate in C#?
A Delegate is a type-safe function pointer.
That means:
-
A delegate holds reference to a method
-
You can pass methods as parameters
-
You can call methods dynamically
Simple Definition (Interview Ready)
A delegate is a type-safe object that holds reference to a method and allows methods to be passed as parameters.
Basic Syntax
delegate returnType DelegateName(parameters);
Example:
delegate void MyDelegate();
This delegate can hold any method that:
-
returns
void -
has no parameters
Basic Example
using System;
delegate void MyDelegate();
class Program
{
static void Main()
{
MyDelegate del = ShowMessage;
del();
}
static void ShowMessage()
{
Console.WriteLine("Hello Delegates");
}
}
Output
Hello Delegates
Delegate With Parameters
delegate int MyDelegate(int a, int b);
class Program
{
static void Main()
{
MyDelegate del = Add;
int result = del(5, 3);
Console.WriteLine(result);
}
static int Add(int a, int b)
{
return a + b;
}
}
Output:
8
Why Delegates Are Used (Very Important for Interviews)
Delegates are used for:
-
Callbacks
-
Event handling
-
Passing methods as parameters
-
Loose coupling
-
LINQ
-
Func / Action / Predicate
Real Interview Example (Callback)
delegate void Notify();
class Process
{
public void StartProcess(Notify notify)
{
Console.WriteLine("Process Started...");
notify();
}
}
class Program
{
static void Main()
{
Process p = new Process();
p.StartProcess(ShowMessage);
}
static void ShowMessage()
{
Console.WriteLine("Process Completed");
}
}
Output:
Process Started...
Process Completed
This is callback using delegate.
Multicast Delegate (Very Important Interview Question)
A delegate can call multiple methods.
delegate void MyDelegate();
class Program
{
static void Main()
{
MyDelegate del = Method1;
del += Method2;
del += Method3;
del();
}
static void Method1()
{
Console.WriteLine("Method 1");
}
static void Method2()
{
Console.WriteLine("Method 2");
}
static void Method3()
{
Console.WriteLine("Method 3");
}
}
Output:
Method 1
Method 2
Method 3
Built-in Delegates (Very Important for Interviews)
C# provides built-in delegates:
1. Action
Used when method returns void
Action<string> action = Show;
action("Hello");
static void Show(string message)
{
Console.WriteLine(message);
}
2. Func
Used when method returns value
Func<int, int, int> func = Add;
Console.WriteLine(func(5,3));
static int Add(int a, int b)
{
return a + b;
}
3. Predicate
Used when method returns bool
Predicate<int> isEven = Check;
Console.WriteLine(isEven(4));
static bool Check(int number)
{
return number % 2 == 0;
}
Delegate vs Func vs Action (Interview Question)
| Delegate | Func | Action |
|---|---|---|
| Custom delegate | Built-in delegate | Built-in delegate |
| Can return value | Returns value | Returns void |
| More verbose | Short syntax | Short syntax |
Delegates with Lambda Expression (Modern C#)
Func<int, int, int> add = (a, b) => a + b;
Console.WriteLine(add(5, 3));
Output:
8
Delegates in Real Life Example (Sorting)
List<int> numbers = new List<int> {5,2,8,1};
numbers.Sort((a, b) => a.CompareTo(b));
numbers.ForEach(n => Console.WriteLine(n));
Delegates vs Events (Very Important Interview Question)
| Delegate | Event |
|---|---|
| Method reference | Wrapper around delegate |
| Can be invoked anywhere | Can only be invoked inside class |
| Used for callbacks | Used for event handling |
Most Asked Interview Questions
1. What is Delegate?
Type-safe function pointer.
2. What is Multicast Delegate?
Delegate calling multiple methods.
3. What is Action?
Delegate that returns void.
4. What is Func?
Delegate that returns value.
5. What is Predicate?
Delegate that returns bool.
6. Delegate vs Event?
Event is wrapper around delegate.
Short Interview Definition (Best Answer)
A delegate in C# is a type-safe function pointer that holds reference to one or more methods and allows methods to be passed as parameters.
What Are Generics in C#?
Generics in C# are one of the most frequently asked interview topics.
What Are Generics in C#?
Generics allow you to define classes, methods, interfaces, and delegates with a placeholder type.
Instead of writing separate code for each type (int, string, etc.), you write code once and reuse it for multiple types.
Without Generics
public class Box
{
public object Value { get; set; }
}
Usage:
Box box = new Box();
box.Value = 10;
int value = (int)box.Value; // Type casting required
Problems (Interview Point)
-
❌ No type safety
-
❌ Runtime errors possible
-
❌ Boxing & Unboxing (performance issue)
With Generics
public class Box<T>
{
public T Value { get; set; }
}
Usage:
Box<int> box = new Box<int>();
box.Value = 10;
int value = box.Value; // No casting required
Benefits (Very Important for Interviews)
-
✅ Type Safety
-
✅ No Casting
-
✅ Better Performance
-
✅ Code Reusability
Generic Class Example
public class Calculator<T>
{
public T Add(T a, T b)
{
dynamic x = a;
dynamic y = b;
return x + y;
}
}
Usage:
Calculator<int> calc = new Calculator<int>();
Console.WriteLine(calc.Add(5, 10));
Calculator<double> calc2 = new Calculator<double>();
Console.WriteLine(calc2.Add(5.5, 2.2));
Generic Method Example
You can also use generics only at method level
public class Utility
{
public static void Print<T>(T value)
{
Console.WriteLine(value);
}
}
Usage:
Utility.Print<int>(10);
Utility.Print<string>("Hello");
Utility.Print<double>(10.5);
Generic List Example (Real World Example)
This is the most common usage:
List<int> numbers = new List<int>();
numbers.Add(10);
numbers.Add(20);
Without Generics (Old Way)
ArrayList list = new ArrayList();
list.Add(10);
list.Add("Hello"); // Problem: mixed types
Generics solve this issue.
Generic Constraints (Very Important Interview Topic)
You can restrict generic types using constraints.
where T : class
public class MyClass<T> where T : class
{
}
Means T must be a reference type
where T : struct
public class MyStruct<T> where T : struct
{
}
Means T must be a value type
where T : new()
public class MyClass<T> where T : new()
{
public T Create()
{
return new T();
}
}
Means T must have parameterless constructor
Multiple Constraints
public class MyClass<T> where T : class, new()
{
}
Generic Interface Example
public interface IRepository<T>
{
void Add(T item);
List<T> GetAll();
}
Implementation:
public class Repository<T> : IRepository<T>
{
private List<T> items = new List<T>();
public void Add(T item)
{
items.Add(item);
}
public List<T> GetAll()
{
return items;
}
}
Generic Delegate Example
public delegate T MyDelegate<T>(T value);
Usage:
MyDelegate<int> del = x => x * 2;
Console.WriteLine(del(10));
Common Interview Questions
1. What are generics?
Generics allow defining classes, methods, interfaces with type parameters, improving type safety and performance.
2. Why generics are better than object type?
| Object | Generics |
|---|---|
| No type safety | Type safe |
| Casting required | No casting |
| Boxing/Unboxing | No boxing |
| Runtime errors | Compile-time safety |
3. What is T in Generics?
T is a type parameter placeholder
Example:
class MyClass<T>
T can be replaced with:
-
int
-
string
-
custom class
4. Can we use multiple generic types?
Yes:
public class MyClass<T, U>
{
public T First { get; set; }
public U Second { get; set; }
}
Usage:
MyClass<int, string> obj = new MyClass<int, string>();
Real World Example
Repository Pattern
public interface IRepository<T>
{
T GetById(int id);
void Add(T entity);
}
Now reuse for:
-
User
-
Product
-
Order
No need to write separate code.
Quick Interview Summary
Generics provide:
-
Type safety
-
Reusability
-
Performance
-
Clean code
Used in:
-
List
-
Dictionary<TKey, TValue>
-
Repository Pattern
-
LINQ
SOLID Principles in C#
SOLID Principles are 5 Object-Oriented Design principles that help you write clean, maintainable, scalable, and testable code. These are very commonly asked in C# interviews.
SOLID =
-
S → Single Responsibility Principle
-
O → Open/Closed Principle
-
L → Liskov Substitution Principle
-
I → Interface Segregation Principle
-
D → Dependency Inversion Principle
Let's go one by one with simple C# examples (Interview-Friendly) 👇
1. S — Single Responsibility Principle (SRP)
Single Responsibility Principle
Definition:
A class should have only one reason to change.
❌ Bad Example (Multiple Responsibilities)
public class Invoice
{
public void CalculateTotal() { }
public void PrintInvoice() { }
public void SaveToDatabase() { }
}
Problem:
This class is doing 3 things
-
Calculation
-
Printing
-
Database saving
If any of these changes → class must change.
✅ Good Example (SRP Followed)
public class Invoice
{
public void CalculateTotal() { }
}
public class InvoicePrinter
{
public void PrintInvoice() { }
}
public class InvoiceRepository
{
public void SaveToDatabase() { }
}
Now each class has one responsibility 👍
2. O — Open/Closed Principle (OCP)
Open Closed Principle
Definition:
Software should be open for extension but closed for modification.
❌ Bad Example
public class Discount
{
public double GetDiscount(string customerType)
{
if(customerType == "Regular")
return 10;
if(customerType == "Premium")
return 20;
return 0;
}
}
Problem:
If new type added → must modify existing code ❌
✅ Good Example
public interface ICustomer
{
double GetDiscount();
}
public class RegularCustomer : ICustomer
{
public double GetDiscount() => 10;
}
public class PremiumCustomer : ICustomer
{
public double GetDiscount() => 20;
}
Now you can add new customer without modifying existing code 👍
3. L — Liskov Substitution Principle (LSP)
Liskov Substitution Principle
Definition:
Derived class should be replaceable for base class without breaking functionality.
❌ Bad Example
public class Bird
{
public virtual void Fly()
{
Console.WriteLine("Flying");
}
}
public class Penguin : Bird
{
public override void Fly()
{
throw new Exception("Penguin can't fly");
}
}
Problem:
Penguin cannot substitute Bird ❌
✅ Good Example
public abstract class Bird
{
}
public interface IFlyable
{
void Fly();
}
public class Sparrow : Bird, IFlyable
{
public void Fly()
{
Console.WriteLine("Flying");
}
}
public class Penguin : Bird
{
}
Now no violation 👍
4. I — Interface Segregation Principle (ISP)
Interface Segregation Principle
Definition:
Clients should not be forced to implement methods they don't use
❌ Bad Example
public interface IWorker
{
void Work();
void Eat();
}
public class Robot : IWorker
{
public void Work() { }
public void Eat() // Robot doesn't eat
{
throw new Exception();
}
}
✅ Good Example
public interface IWork
{
void Work();
}
public interface IEat
{
void Eat();
}
public class Human : IWork, IEat
{
public void Work() { }
public void Eat() { }
}
public class Robot : IWork
{
public void Work() { }
}
Clean and flexible 👍
5. D — Dependency Inversion Principle (DIP)
Dependency Inversion Principle
Definition:
Depend on abstractions, not concrete classes
❌ Bad Example
public class EmailService
{
public void Send() { }
}
public class Notification
{
private EmailService _email = new EmailService();
public void Notify()
{
_email.Send();
}
}
Problem:
Tightly coupled ❌
✅ Good Example
public interface IMessageService
{
void Send();
}
public class EmailService : IMessageService
{
public void Send() { }
}
public class SMSService : IMessageService
{
public void Send() { }
}
public class Notification
{
private readonly IMessageService _message;
public Notification(IMessageService message)
{
_message = message;
}
public void Notify()
{
_message.Send();
}
}
Now easily extendable 👍
Interview One-Line Definitions (Very Important)
| Principle | One-Line Answer |
|---|---|
| SRP | One class should have one responsibility |
| OCP | Open for extension, closed for modification |
| LSP | Child class must replace parent class safely |
| ISP | Don't force classes to implement unused methods |
| DIP | Depend on abstraction, not concrete classes |
Real-World Example (Easy to Remember)
| Principle | Real Life Example |
|---|---|
| SRP | HR handles hiring only |
| OCP | Add new payment method without changing old code |
| LSP | Car → ElectricCar should behave like Car |
| ISP | Printer with only print vs print+scan |
| DIP | Switch works with any bulb |
Why SOLID is Important (Interview Answer)
-
Clean code
-
Maintainable code
-
Scalable system
-
Easy unit testing
-
Loose coupling
-
Better architecture
Factory Design Pattern in C#
The Factory Design Pattern is one of the most commonly asked Design Pattern interview questions.
Let’s understand it in a simple, interview-friendly way with real-world examples and C# code.
Factory Design Pattern in C#
What is Factory Design Pattern?
The Factory Design Pattern is used to create objects without exposing the object creation logic to the client.
Instead of using new everywhere, you delegate object creation to a factory class.
Simple Definition (Interview Ready)
Factory Pattern provides a way to create objects without specifying the exact class of object that will be created.
Why Do We Need Factory Pattern?
Problem Without Factory
var payment = new CreditCardPayment();
payment.Pay();
Later if you change to:
var payment = new UPIPayment();
You must change code everywhere — this violates Open/Closed Principle from SOLID.
Real World Example
Think of Vehicle Factory
You ask factory:
-
"Give me Car"
-
"Give me Bike"
Factory decides what object to create.
You don't care about creation logic.
Basic Structure
Factory Pattern has:
-
Product Interface
-
Concrete Products
-
Factory Class
-
Client
Example: Payment System
Step 1: Product Interface
public interface IPayment
{
void Pay();
}
Step 2: Concrete Classes
public class CreditCardPayment : IPayment
{
public void Pay()
{
Console.WriteLine("Paid using Credit Card");
}
}
public class UPIPayment : IPayment
{
public void Pay()
{
Console.WriteLine("Paid using UPI");
}
}
public class PayPalPayment : IPayment
{
public void Pay()
{
Console.WriteLine("Paid using PayPal");
}
}
Step 3: Factory Class
public class PaymentFactory
{
public static IPayment GetPayment(string paymentType)
{
switch (paymentType)
{
case "CreditCard":
return new CreditCardPayment();
case "UPI":
return new UPIPayment();
case "PayPal":
return new PayPalPayment();
default:
throw new ArgumentException("Invalid payment type");
}
}
}
Step 4: Client Code
class Program
{
static void Main()
{
IPayment payment = PaymentFactory.GetPayment("UPI");
payment.Pay();
}
}
Output
Paid using UPI
Advantages
1. Loose Coupling
Client doesn't know about concrete classes.
2. Easy to Extend
Add new payment method:
class CryptoPayment : IPayment
Just modify factory — no change to client.
3. Follows SOLID Principles
-
Open/Closed Principle
-
Dependency Inversion
Real-Time Use Cases
Factory Pattern is used in:
-
Logging frameworks
-
Database connections
-
Payment gateways
-
Notification systems
-
Document generators
Example: Logger Factory (Real-world)
public interface ILogger
{
void Log(string message);
}
Concrete classes:
public class FileLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine("File Log: " + message);
}
}
public class DatabaseLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine("Database Log: " + message);
}
}
Factory:
public class LoggerFactory
{
public static ILogger GetLogger(string type)
{
if (type == "File")
return new FileLogger();
return new DatabaseLogger();
}
}
Usage:
ILogger logger = LoggerFactory.GetLogger("File");
logger.Log("Hello");
Factory Pattern vs Simple Object Creation
Without Factory
new Car()
new Bike()
With Factory
VehicleFactory.Create("Car")
VehicleFactory.Create("Bike")
Cleaner and scalable.
Types of Factory Patterns (Interview Question)
There are 3 types:
1. Simple Factory (Most common)
-
One factory class
-
Uses switch/if
2. Factory Method
-
Uses inheritance
-
Factory created via subclasses
3. Abstract Factory
-
Factory of factories
-
Used for related object families
When To Use Factory Pattern
Use Factory Pattern when:
-
Object creation is complex
-
Multiple object types exist
-
You want loose coupling
-
You want scalable architecture
When NOT to Use
Don't use factory when:
-
Only one object type
-
No future changes expected
-
Simple code is enough
Interview Questions
What is Factory Pattern?
Creates objects without exposing creation logic.
What Problem Does It Solve?
Reduces tight coupling and improves scalability.
Difference Between Factory and Abstract Factory?
| Factory | Abstract Factory |
|---|---|
| Creates one product | Creates families of products |
| Simple | More complex |
Short Interview Example (Best Answer)
Factory Pattern is used to create objects without exposing creation logic.
It helps achieve loose coupling and follows SOLID principles.
A factory class decides which object to create based on input.
Real Interview Tip
If interviewer asks:
Where did you use Factory Pattern?
You can say:
-
Payment gateway selection
-
Notification service (Email/SMS)
-
Logger creation
-
Database provider selection
Summary
-
Factory Pattern creates objects
-
Hides creation logic
-
Reduces coupling
-
Easy to extend
-
Very common in real projects
Async and Await in C#
Async and Await in C# — Interview Guide
async and await are used in C# to write asynchronous, non-blocking code in a simple and readable way. They are heavily used in .NET applications like Web APIs, UI apps, and file/network operations.
1. Why Async/Await is Needed (Interview Answer)
Normally, when your code calls a slow operation (API call, DB query, file read):
-
Synchronous code → blocks the thread (bad for performance)
-
Asynchronous code → frees the thread while waiting (better performance)
Example (Synchronous — Bad)
public string GetData()
{
Thread.Sleep(5000); // Simulate long operation
return "Data received";
}
Problem:
-
Thread blocked for 5 seconds
-
Bad for UI apps and Web APIs
2. Async/Await Basic Example
Async Version
public async Task<string> GetDataAsync()
{
await Task.Delay(5000);
return "Data received";
}
Calling Method
public async Task CallMethod()
{
string data = await GetDataAsync();
Console.WriteLine(data);
}
What Happens Internally
-
GetDataAsync()starts -
await Task.Delay(5000)pauses method -
Thread is freed
-
After 5 seconds → method resumes
-
Result returned
3. Real-World Example (Web API)
This is a very common interview example.
public async Task<IActionResult> GetUsers()
{
var users = await _dbContext.Users.ToListAsync();
return Ok(users);
}
Why async?
-
Database call takes time
-
Thread shouldn't wait
-
Better scalability
4. Return Types in Async Methods (Important Interview Question)
| Return Type | When to Use |
|---|---|
Task |
No return value |
Task<T> |
Return value |
void |
Only for event handlers (avoid otherwise) |
Examples
Task
public async Task DoWorkAsync()
{
await Task.Delay(1000);
}
Task
public async Task<int> GetNumberAsync()
{
await Task.Delay(1000);
return 10;
}
async void (Avoid)
public async void Button_Click()
{
await Task.Delay(1000);
}
5. async vs await (Interview Question)
| Keyword | Purpose |
|---|---|
| async | Marks method as asynchronous |
| await | Waits for async operation without blocking |
Example:
public async Task Method()
{
await Task.Delay(1000);
}
6. Without async/await (Old Way)
Before async/await:
public Task<string> GetData()
{
return Task.Run(() =>
{
Thread.Sleep(5000);
return "Data";
});
}
Hard to read and maintain.
7. Multiple Async Calls (Important Interview Scenario)
Sequential Execution (Slow)
var data1 = await GetData1();
var data2 = await GetData2();
Parallel Execution (Fast)
var task1 = GetData1();
var task2 = GetData2();
await Task.WhenAll(task1, task2);
Interview Tip:
Use Task.WhenAll() for better performance.
8. Common Interview Questions
Q1: Does async create new thread?
Answer:
No.
Async does not create new thread. It uses existing thread efficiently.
Q2: Can we use await without async?
No.
Wrong:
public Task Method()
{
await Task.Delay(1000); // Error
}
Correct:
public async Task Method()
{
await Task.Delay(1000);
}
Q3: What happens if we don't use await?
GetDataAsync(); // Fire and forget
Problem:
-
Exceptions may be lost
-
Hard to debug
9. Exception Handling in Async
try
{
await GetDataAsync();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
Works same as synchronous code.
10. Real Interview Example
public async Task<string> DownloadDataAsync()
{
using(var client = new HttpClient())
{
var result = await client.GetStringAsync("https://example.com");
return result;
}
}
11. Best Practices (Interview Gold Points)
✔ Use async Task instead of async void
✔ Use await always unless necessary
✔ Use Task.WhenAll() for parallel calls
✔ Avoid .Result and .Wait() (deadlocks)
Bad:
var data = GetDataAsync().Result;
12. Async Await Flow (Simple Understanding)
Start method
↓
Hit await
↓
Method paused
↓
Thread released
↓
Task completes
↓
Method resumes
One-Line Interview Answer
"Async and await in C# are used to write non-blocking asynchronous code, improving performance and responsiveness by freeing the thread while waiting for long-running operations."
LINQ in C# — Interview Guide (With Examples)
LINQ in C# — Interview Guide (With Examples)
LINQ (Language INtegrated Query) is a feature in C# that allows you to query collections, databases, XML, APIs, etc. using SQL-like syntax directly inside code.
Instead of writing loops, you can write clean, readable queries.
1. Why LINQ? (Interview Answer)
Before LINQ:
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
List<int> evenNumbers = new List<int>();
foreach (var num in numbers)
{
if (num % 2 == 0)
{
evenNumbers.Add(num);
}
}
Using LINQ:
var evenNumbers = numbers.Where(x => x % 2 == 0).ToList();
✅ Cleaner
✅ Shorter
✅ More readable
2. Two Types of LINQ Syntax (Important Interview Question) ⭐
1. Method Syntax (Most Used)
var result = numbers.Where(x => x > 2);
2. Query Syntax (SQL Style)
var result = from n in numbers
where n > 2
select n;
👉 Both produce the same result
Interview Tip:
Method syntax is more commonly used in real projects
3. Basic LINQ Example
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
var result = numbers
.Where(x => x > 2)
.Select(x => x * 2);
foreach (var item in result)
{
Console.WriteLine(item);
}
Output:
6
8
10
4. Common LINQ Methods (Very Important for Interviews)
| Method | Purpose |
|---|---|
| Where | Filter data |
| Select | Transform data |
| OrderBy | Sort ascending |
| OrderByDescending | Sort descending |
| First / FirstOrDefault | Get first element |
| Single / SingleOrDefault | Get one element |
| Any | Check if exists |
| All | Check condition for all |
| Count | Count items |
| GroupBy | Group data |
| Join | Join collections |
5. Where Example
var even = numbers.Where(x => x % 2 == 0);
6. Select Example
var squares = numbers.Select(x => x * x);
7. OrderBy Example
var sorted = numbers.OrderBy(x => x);
Descending:
var sorted = numbers.OrderByDescending(x => x);
8. First vs FirstOrDefault (Interview Favorite) 🎯
First
Throws exception if no data
var result = numbers.First(x => x > 10);
FirstOrDefault
Returns default value if no data
var result = numbers.FirstOrDefault(x => x > 10);
Default values:
-
int → 0
-
string → null
-
object → null
9. Single vs First (Important Interview Question)
Single
-
Expects only one result
-
Throws error if multiple
var user = users.Single(x => x.Id == 1);
First
-
Returns first match
var user = users.First(x => x.Id == 1);
10. Any Example
bool exists = numbers.Any(x => x > 3);
Output:
true
11. Count Example
int count = numbers.Count(x => x > 2);
12. GroupBy Example (Important)
var grouped = numbers.GroupBy(x => x % 2);
foreach (var group in grouped)
{
Console.WriteLine(group.Key);
foreach (var item in group)
{
Console.WriteLine(item);
}
}
Output:
0 (even)
2
4
1 (odd)
1
3
5
13. LINQ with Objects Example
class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public int Salary { get; set; }
}
var employees = new List<Employee>
{
new Employee { Id = 1, Name = "John", Salary = 5000 },
new Employee { Id = 2, Name = "Sam", Salary = 7000 },
new Employee { Id = 3, Name = "David", Salary = 4000 }
};
var highSalary = employees
.Where(x => x.Salary > 5000)
.Select(x => x.Name);
Output:
Sam
14. Deferred Execution (Very Important Interview Question) ⚡
LINQ queries don't execute immediately.
They execute only when iterated.
Example:
var result = numbers.Where(x => x > 2);
numbers.Add(10);
foreach(var item in result)
{
Console.WriteLine(item);
}
Output:
3
4
5
10
Because LINQ executed after adding 10.
To execute immediately:
var result = numbers.Where(x => x > 2).ToList();
15. IEnumerable vs IQueryable (Advanced Interview Question)
| IEnumerable | IQueryable |
|---|---|
| Works in memory | Works in database |
| Slower for large data | Faster for large data |
| Used for collections | Used for EF Core |
Example:
IEnumerable<Employee> data
IQueryable<Employee> data
16. Select vs SelectMany (Interview Question)
Select
Returns nested collection
SelectMany
Flattens collection
Example:
var result = list.SelectMany(x => x.Items);
17. Join Example (Important)
var result = from emp in employees
join dept in departments
on emp.DeptId equals dept.Id
select new
{
emp.Name,
dept.DeptName
};
18. LINQ Advantages
✅ Readable
✅ Less code
✅ Strongly typed
✅ IntelliSense support
✅ Compile-time checking
19. Common Interview Questions
What is LINQ?
LINQ is used to query collections using SQL-like syntax in C#.
Types of LINQ
-
LINQ to Objects
-
LINQ to SQL
-
LINQ to XML
-
LINQ to Entities
When to use LINQ?
-
Filtering
-
Sorting
-
Grouping
-
Joining
20. Real-World Example (Very Useful)
You might use LINQ like this:
var shortlistedCandidates = candidates
.Where(x => x.Status == "Shortlisted")
.OrderByDescending(x => x.Experience)
.Take(10);
Perfect for:
-
Filtering candidates
-
Sorting by experience
-
Limiting results
21. Interview Tips
✔ Prefer method syntax
✔ Use FirstOrDefault safely
✔ Understand deferred execution
✔ Know IEnumerable vs IQueryable
✔ Practice GroupBy and Join
Encapsulation and Data Abstraction
Encapsulation and Data Abstraction are two fundamental Object-Oriented Programming (OOP) concepts and are very commonly asked in interviews. Let's understand them clearly with simple definitions, differences, and real-world examples.
1. Encapsulation
What is Encapsulation?
Encapsulation means wrapping data (variables) and methods (functions) together into a single unit (class) and restricting direct access to the data.
In simple words:
Encapsulation = Data hiding + Controlled access
Why Encapsulation?
-
Protect data from accidental changes
-
Improve maintainability
-
Control how data is accessed or modified
-
Improve security
Real-Life Example
Think of a Bank Account:
-
You cannot directly modify balance
-
You must use:
-
Deposit()
-
Withdraw()
-
This is Encapsulation.
C# Example
public class BankAccount
{
private decimal balance; // Private field
public void Deposit(decimal amount)
{
if (amount > 0)
{
balance += amount;
}
}
public decimal GetBalance()
{
return balance;
}
}
Usage
BankAccount account = new BankAccount();
account.Deposit(1000);
Console.WriteLine(account.GetBalance());
Another Example using Properties (Most Asked in Interviews)
public class Employee
{
private int age;
public int Age
{
get { return age; }
set
{
if (value > 18)
age = value;
}
}
}
Usage
Employee emp = new Employee();
emp.Age = 25;
Console.WriteLine(emp.Age);
Here:
-
ageis hidden -
Accessed using property
-
This is Encapsulation
Key Points (Interview Answers)
-
Encapsulation bundles data and methods together
-
Uses private fields
-
Uses public methods / properties
-
Provides controlled access to data
2. Data Abstraction
What is Data Abstraction?
Data Abstraction means hiding implementation details and showing only essential features.
In simple words:
Abstraction = Hide complexity, show only what is needed
Real-Life Example
Think of a Car:
You only use:
-
Start()
-
Stop()
-
Accelerate()
You don't know:
-
Engine logic
-
Fuel injection
-
Internal mechanisms
This is Abstraction.
C# Example using Abstract Class
public abstract class Shape
{
public abstract double GetArea();
}
Derived Classes:
public class Circle : Shape
{
public double Radius { get; set; }
public override double GetArea()
{
return Math.PI * Radius * Radius;
}
}
Usage:
Shape shape = new Circle() { Radius = 5 };
Console.WriteLine(shape.GetArea());
Here:
-
User only calls
GetArea() -
Implementation is hidden
-
This is Abstraction
Example Using Interface (Very Important for Interviews)
public interface IPayment
{
void Pay();
}
Implementations:
public class CreditCardPayment : IPayment
{
public void Pay()
{
Console.WriteLine("Paid using Credit Card");
}
}
public class UpiPayment : IPayment
{
public void Pay()
{
Console.WriteLine("Paid using UPI");
}
}
Usage:
IPayment payment = new UpiPayment();
payment.Pay();
User only knows:
payment.Pay()
Not how it works internally.
This is Abstraction.
Encapsulation vs Abstraction (Very Important Interview Question)
| Feature | Encapsulation | Abstraction |
|---|---|---|
| Purpose | Hide data | Hide implementation |
| Focus | Data protection | Simplify usage |
| Achieved using | Access modifiers | Abstract class / Interface |
| Example | Private variables | Interface / Abstract class |
| Level | Class level | Design level |
Short Interview Answer
Encapsulation:
Wrapping data and methods together and restricting direct access using access modifiers.
Abstraction:
Hiding implementation details and exposing only necessary functionality using interfaces or abstract classes.
One-Line Difference (Most Asked)
Encapsulation hides data, Abstraction hides implementation.
Interview Follow-up Questions
Interviewers may ask:
-
What is difference between abstraction and encapsulation?
-
How is abstraction achieved in C#?
-
What is real example of encapsulation?
-
Can abstraction exist without encapsulation? (Yes)
Tricky OOPS Interview Questions
Here are Tricky OOPS Interview Questions that are commonly asked and used to differentiate experienced developers 👇
1. Can we achieve Encapsulation without properties? 🤔
Answer: Yes.
Encapsulation is about restricting access, not about properties specifically.
public class Test
{
private int x;
public void SetX(int value)
{
x = value;
}
public int GetX()
{
return x;
}
}
Properties are just syntactic sugar.
2. Can a class be abstract and sealed at the same time? ❌
Answer: No.
-
abstract→ must be inherited -
sealed→ cannot be inherited
They contradict each other.
3. Difference between Method Overloading vs Overriding (Tricky version)
| Overloading | Overriding |
|---|---|
| Same class | Base + Child |
| No inheritance required | Requires inheritance |
| Compile-time | Runtime |
| Can change return type? ❌ | Same return type (mostly) |
4. Can we override a private method? ❌
Answer: No.
Because private methods are not visible in child class.
class A
{
private void Test() { }
}
class B : A
{
// cannot override
}
5. Can constructor be virtual? ❌
Answer: No.
Constructors cannot be inherited, so no polymorphism.
6. Can we override static method? ❌
Answer: No.
Static methods belong to class, not object.
But we can hide using new
class A
{
public static void Test()
{
Console.WriteLine("A");
}
}
class B : A
{
public new static void Test()
{
Console.WriteLine("B");
}
}
This is method hiding, not overriding.
7. What is difference between abstract class and interface (Tricky)
| Abstract Class | Interface |
|---|---|
| Can have constructor | Cannot |
| Can have fields | Cannot (traditionally) |
| Multiple inheritance ❌ | Multiple inheritance ✅ |
| Access modifiers allowed | Public by default |
8. Can interface contain method implementation?
Answer: Yes (C# 8+)
public interface ITest
{
void Method1()
{
Console.WriteLine("Default implementation");
}
}
This is a very tricky modern question.
9. What happens here? (Polymorphism trap)
class A
{
public virtual void Show()
{
Console.WriteLine("A");
}
}
class B : A
{
public override void Show()
{
Console.WriteLine("B");
}
}
A obj = new B();
obj.Show();
Answer: B
Because runtime decides → Runtime polymorphism
10. What happens if method is not virtual?
class A
{
public void Show()
{
Console.WriteLine("A");
}
}
class B : A
{
public void Show()
{
Console.WriteLine("B");
}
}
A obj = new B();
obj.Show();
Answer: A ❗
Because no polymorphism → method hiding
This question is very frequently asked.
11. Can we create object of abstract class? ❌
Answer: No.
But we can use reference:
Animal animal = new Dog();
12. Which OOPS concept is used here?
public void Print(object obj)
Answer: Polymorphism
Because object accepts any type
13. What is diamond problem? 💎
Multiple inheritance conflict:
A
/ \
B C
\ /
D
Interfaces solve this problem.
14. Is inheritance always good? ❌
Answer: No.
Prefer:
Composition over inheritance
This is senior-level answer.
15. What is method hiding vs overriding?
| Hiding | Overriding |
|---|---|
Uses new |
Uses override |
| Compile-time | Runtime |
| Not polymorphism | Polymorphism |
Most Important Tricky Questions (Top 5) ⭐
-
Can constructor be virtual?
-
Can we override static method?
-
Can interface have implementation?
-
Method hiding vs overriding?
-
What happens when base reference holds child object?
Best One-Line Interview Answer
OOPS tricky questions mainly test understanding of polymorphism, method overriding, method hiding, and abstraction behavior.
REST API Interview Questions
Here are REST API Interview Questions & Answers explained in a clear, interview-focused way with examples (especially .NET).
REST API Interview Questions (With Answers)
1. What is REST API?
REST (Representational State Transfer) is an architectural style used to build web services that communicate over HTTP.
A REST API uses:
-
HTTP Methods (GET, POST, PUT, DELETE)
-
URLs (Endpoints)
-
Stateless communication
-
JSON/XML responses
Example
GET /api/users/1
Response
{
"id": 1,
"name": "John"
}
2. What are HTTP Methods in REST?
| Method | Purpose | Example |
|---|---|---|
| GET | Get data | Get users |
| POST | Create data | Create user |
| PUT | Update entire record | Update user |
| PATCH | Partial update | Update email |
| DELETE | Delete record | Delete user |
Example (.NET)
[HttpGet]
public IActionResult GetUsers()
{
return Ok(users);
}
[HttpPost]
public IActionResult CreateUser(User user)
{
return Ok(user);
}
3. What is Stateless in REST?
Stateless means server does not store client state.
Each request must contain all information.
Example
❌ Bad (Stateful)
Login → Save session → Use session
✅ Good (Stateless)
Login → Send token → Use token every request
4. What is RESTful API?
RESTful API follows REST principles:
-
Stateless
-
Uses HTTP methods
-
Uses URLs for resources
-
Returns JSON/XML
Example:
GET /api/products
POST /api/products
DELETE /api/products/1
5. What is Resource in REST?
Resource = Object or Data
Examples:
/users
/products
/orders
Each resource has:
/users/1
6. What is Idempotent Method?
Idempotent = Same result even if called multiple times
| Method | Idempotent |
|---|---|
| GET | Yes |
| PUT | Yes |
| DELETE | Yes |
| POST | No |
Example
DELETE /users/1
DELETE /users/1
Still user deleted → Idempotent
7. What is Status Code?
HTTP response codes:
| Code | Meaning |
|---|---|
| 200 | OK |
| 201 | Created |
| 204 | No Content |
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 500 | Server Error |
Example
return NotFound();
return BadRequest();
return Ok(data);
8. What is PUT vs PATCH?
PUT
Update entire object
PUT /users/1
{
"name":"John",
"email":"john@gmail.com"
}
PATCH
Update partial object
PATCH /users/1
{
"email":"john@gmail.com"
}
9. What is REST API Endpoint?
Endpoint = URL where API is accessed
Examples:
GET /api/users
GET /api/users/1
POST /api/users
10. What is Query Parameter?
Used for filtering
Example:
GET /users?department=HR
GET /products?page=1
.NET Example:
[HttpGet]
public IActionResult GetUsers(string department)
{
return Ok();
}
11. What is Path Parameter?
Used to identify specific resource
GET /users/1
.NET Example:
[HttpGet("{id}")]
public IActionResult GetUser(int id)
{
return Ok();
}
12. What is Content Negotiation?
Client tells server what format it wants
Accept: application/json
Accept: application/xml
Server responds accordingly.
13. What is Versioning in REST API?
Used when API changes
URL Versioning
/api/v1/users
/api/v2/users
Header Versioning
Accept: application/vnd.company.v1+json
14. What is Pagination?
Used to load data in chunks
Example:
GET /users?page=1&pageSize=10
15. What is HATEOAS?
API returns links for next actions
Example:
{
"id":1,
"name":"John",
"links":[
{
"rel":"orders",
"href":"/users/1/orders"
}
]
}
(Not commonly used in real-world apps but asked in interviews)
16. What is Authentication in REST API?
Common methods:
-
JWT Token
-
OAuth
-
API Key
-
Basic Authentication
Example:
Authorization: Bearer token
17. What is REST vs SOAP?
| REST | SOAP |
|---|---|
| Lightweight | Heavy |
| JSON | XML |
| Fast | Slow |
| Easy | Complex |
REST is more commonly used.
18. What is Caching in REST?
Server can cache response
Example:
Cache-Control: max-age=3600
Improves performance.
19. What is 401 vs 403?
| Code | Meaning |
|---|---|
| 401 | Not authenticated |
| 403 | Not authorized |
Example:
-
401 → No login
-
403 → Logged in but no permission
20. What is Best Practice for REST URLs?
Good:
/users
/users/1
/users/1/orders
Bad:
/getUsers
/createUser
/deleteUser
Use nouns not verbs
Tricky REST Interview Questions
1. Can GET request have body?
Technically yes, but not recommended.
2. Is REST protocol?
No.
REST is architectural style, not protocol.
3. Can REST use only JSON?
No.
REST can use:
-
JSON
-
XML
-
Text
-
HTML
4. Is REST always HTTP?
Mostly yes, but technically REST can use other protocols.
Real Interview Questions
-
What is REST?
-
What is Stateless?
-
PUT vs PATCH?
-
Idempotent methods?
-
REST vs SOAP?
-
What is HATEOAS?
-
What is versioning?
-
What is pagination?
-
What are status codes?
-
What is resource?
JWT Token Authentication — Interview Guide
JWT Token Authentication — Interview Guide (With Examples)
JWT is one of the most commonly asked interview topics for backend developers, especially if you work with .NET / APIs / Angular / React.
Let's break it down in simple interview-friendly way 👇
1. What is JWT?
JWT (JSON Web Token) is a compact, secure way to authenticate users and transfer information between client and server.
A JWT token is:
✅ Stateless
✅ Secure
✅ Self-contained
✅ Widely used in REST APIs
JWT stands for JSON Web Token (JWT)
2. Why Do We Need JWT?
Before JWT:
-
Server creates Session
-
Stores session in memory/database
-
Client sends Session ID
Problems ❌
-
Hard to scale
-
Server memory usage
-
Load balancing issues
JWT solves this by:
✔ No server session
✔ Stateless authentication
✔ Easy scaling
3. Real World Example
When you login to:
-
Banking website
-
Gmail
-
Any API based system
Flow:
-
User logs in
-
Server validates credentials
-
Server generates JWT token
-
Client stores token
-
Client sends token in every request
-
Server validates token
4. JWT Structure
JWT has 3 parts
Header.Payload.Signature
Example:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlNhbXAiLCJpYXQiOjE1MTYyMzkwMjJ9
.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
5. JWT Structure Explained
1. Header
{
"alg": "HS256",
"typ": "JWT"
}
-
alg → Algorithm
-
typ → Token type
2. Payload
Contains user data (Claims)
{
"userId": 1,
"username": "Sampath",
"role": "Admin"
}
This data is called Claims
Types:
-
Registered Claims
-
Public Claims
-
Private Claims
Example:
sub → subject
exp → expiration
iat → issued at
3. Signature
Signature is created using:
Header + Payload + Secret Key
This ensures token is not modified
6. JWT Authentication Flow
Step-by-Step:
User → Login
↓
Server → Validate credentials
↓
Server → Generate JWT
↓
Client → Store token
↓
Client → Send token in header
↓
Server → Validate token
↓
Server → Return data
7. Example Request
Login Request
POST /login
Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
8. Sending JWT Token
Client sends token in Authorization header
Authorization: Bearer <token>
Example:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
9. JWT Example in C# (.NET)
Using ASP.NET Core
Generate Token
var claims = new[]
{
new Claim(ClaimTypes.Name, user.Username),
new Claim(ClaimTypes.Role, user.Role)
};
var key = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes("YourSecretKey"));
var creds = new SigningCredentials(
key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: "yourdomain.com",
audience: "yourdomain.com",
claims: claims,
expires: DateTime.Now.AddHours(1),
signingCredentials: creds
);
var jwt = new JwtSecurityTokenHandler().WriteToken(token);
10. Configure JWT Authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters =
new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true
};
});
11. Protect API Endpoint
[Authorize]
[HttpGet]
public IActionResult GetUsers()
{
return Ok();
}
Only authenticated users can access this endpoint.
12. Advantages of JWT
✅ Stateless
✅ Scalable
✅ Secure
✅ Works well with APIs
✅ Cross-platform
13. Disadvantages
❌ Cannot revoke easily
❌ Token size larger
❌ Must manage expiration
14. JWT vs Session Authentication
| Feature | JWT | Session |
|---|---|---|
| Stateless | Yes | No |
| Scalable | Yes | No |
| Server Memory | No | Yes |
| Mobile Friendly | Yes | No |
15. Interview Questions (Very Important)
Basic Questions
1. What is JWT?
JWT is a secure token used for authentication.
2. What are parts of JWT?
Header, Payload, Signature
3. Where is JWT stored?
-
LocalStorage
-
SessionStorage
-
Cookies
Intermediate Questions
4. What is Claim?
Claims are user data inside JWT.
Example:
UserId
Role
Email
5. What is Bearer Token?
Token sent in Authorization header.
Authorization: Bearer token
Advanced Questions
6. Is JWT secure?
Yes, when:
-
HTTPS used
-
Short expiration used
-
Secret key protected
7. Can JWT be revoked?
Not easily. Solutions:
-
Short expiry
-
Refresh tokens
-
Blacklist tokens
16. JWT with Refresh Token (Interview Favorite)
Flow:
Access Token → Short expiry (15 mins)
Refresh Token → Long expiry (7 days)
When token expires:
-
Client uses Refresh Token
-
Server generates new Access Token
17. JWT vs OAuth (Interview Question)
JWT = Token format
OAuth 2.0 = Authorization framework
They are different but often used together.
18. Best Practices
✅ Use HTTPS
✅ Short expiry
✅ Use refresh tokens
✅ Don't store sensitive data in payload
✅ Use strong secret key
19. Real Interview Answer (Perfect Short Answer)
JWT is a stateless authentication mechanism where server generates a token after user login. The client sends this token in Authorization header for each request. The server validates the token signature and allows access to protected resources.
Repository Pattern
The Repository Pattern is one of the most commonly asked design pattern interview questions, especially for .NET / backend developers.
What is Repository Pattern?
Repository Pattern is used to separate data access logic from business logic.
Instead of directly writing database code inside services/controllers, you create a Repository layer that handles CRUD operations.
Without Repository Pattern
Controller → Database directly ❌
With Repository Pattern
Controller → Service → Repository → Database ✅
This makes the application:
-
Clean
-
Maintainable
-
Testable
-
Scalable
Real World Example
Think of Amazon
You don't directly go to the warehouse.
You interact with:
Amazon App → Service → Warehouse
Here:
-
Warehouse = Database
-
Service = Business logic
-
Repository = Warehouse manager
Why Repository Pattern?
Interviewers love this question.
Advantages
✅ Separation of concerns
✅ Easy to test (Mock repository)
✅ Reusable code
✅ Maintainable
✅ Clean architecture
Example in C#
Let's say we have a User table.
Step 1 — Create Model
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
Step 2 — Create Repository Interface
This defines what operations are allowed.
public interface IUserRepository
{
IEnumerable<User> GetAll();
User GetById(int id);
void Add(User user);
void Update(User user);
void Delete(int id);
}
Step 3 — Implement Repository
Using Entity Framework Core
public class UserRepository : IUserRepository
{
private readonly AppDbContext _context;
public UserRepository(AppDbContext context)
{
_context = context;
}
public IEnumerable<User> GetAll()
{
return _context.Users.ToList();
}
public User GetById(int id)
{
return _context.Users.Find(id);
}
public void Add(User user)
{
_context.Users.Add(user);
_context.SaveChanges();
}
public void Update(User user)
{
_context.Users.Update(user);
_context.SaveChanges();
}
public void Delete(int id)
{
var user = _context.Users.Find(id);
_context.Users.Remove(user);
_context.SaveChanges();
}
}
Step 4 — Use Repository in Service
public class UserService
{
private readonly IUserRepository _repository;
public UserService(IUserRepository repository)
{
_repository = repository;
}
public IEnumerable<User> GetUsers()
{
return _repository.GetAll();
}
}
Step 5 — Register in Dependency Injection
In ASP.NET Core
builder.Services.AddScoped<IUserRepository, UserRepository>();
Controller Example
[ApiController]
[Route("api/users")]
public class UsersController : ControllerBase
{
private readonly UserService _service;
public UsersController(UserService service)
{
_service = service;
}
[HttpGet]
public IActionResult Get()
{
return Ok(_service.GetUsers());
}
}
Repository Pattern Flow
Controller
↓
Service
↓
Repository
↓
Database
Generic Repository Pattern (Very Popular Interview Question)
Instead of creating repository for every entity:
-
UserRepository
-
ProductRepository
-
OrderRepository
Create Generic Repository
Generic Repository Interface
public interface IRepository<T>
{
IEnumerable<T> GetAll();
T GetById(int id);
void Add(T entity);
void Update(T entity);
void Delete(int id);
}
Generic Repository Implementation
public class Repository<T> : IRepository<T> where T : class
{
private readonly DbContext _context;
private readonly DbSet<T> _dbSet;
public Repository(DbContext context)
{
_context = context;
_dbSet = context.Set<T>();
}
public IEnumerable<T> GetAll()
{
return _dbSet.ToList();
}
public T GetById(int id)
{
return _dbSet.Find(id);
}
public void Add(T entity)
{
_dbSet.Add(entity);
_context.SaveChanges();
}
public void Update(T entity)
{
_dbSet.Update(entity);
_context.SaveChanges();
}
public void Delete(int id)
{
var entity = _dbSet.Find(id);
_dbSet.Remove(entity);
_context.SaveChanges();
}
}
When Should You Use Repository Pattern?
Use when:
✅ Using Database
✅ Large applications
✅ Clean architecture
✅ Unit testing needed
✅ Multiple data sources
When NOT to Use
Sometimes Repository Pattern is unnecessary if using:
-
Simple CRUD app
-
Small project
-
Already using Entity Framework (EF already behaves like repository)
This is advanced interview discussion point ⭐
Interview Questions (Very Important)
1. What is Repository Pattern?
Repository Pattern separates data access logic from business logic.
2. What is Generic Repository?
A repository that works for all entities using generics.
3. Repository vs Service Pattern?
Repository → Data access
Service → Business logic
4. Repository vs Unit of Work?
Repository → Handles one entity
Unit of Work → Handles transactions across multiple repositories
Interview Tip
Best answer (short version):
Repository Pattern is used to separate data access logic from business logic. It improves maintainability, testability, and follows clean architecture principles.
Records in C#
Records in C# (Interview Guide)
Records in C# are reference types (by default) designed for immutable data models with value-based equality.
They were introduced in C# 9 and improved in C# 10 & C# 11.
1. Why Records? (Interview Answer)
Before Records, we used classes to store data:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
Problem with Classes:
-
Mutable (data can change)
-
Reference equality (not value equality)
-
More boilerplate code
Records solve this by:
-
Immutable by default
-
Value-based equality
-
Less code
-
Built-in
ToString(),Equals(),GetHashCode()
2. Basic Record Example
public record Person(string Name, int Age);
Usage:
var person1 = new Person("John", 30);
var person2 = new Person("John", 30);
Console.WriteLine(person1 == person2);
Output:
True
👉 Because Records compare values, not references.
3. Record vs Class (Important Interview Question)
Class Example
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
var p1 = new Person { Name = "John", Age = 30 };
var p2 = new Person { Name = "John", Age = 30 };
Console.WriteLine(p1 == p2);
Output:
False
Record Example
public record Person(string Name, int Age);
var p1 = new Person("John", 30);
var p2 = new Person("John", 30);
Console.WriteLine(p1 == p2);
Output:
True
4. Immutability in Records 🔒
Records are immutable by default
public record Person(string Name, int Age);
var person = new Person("John", 30);
// person.Name = "David"; ❌ Error
5. "with" Keyword (Very Important Interview Question)
Used to create a copy with modification
public record Person(string Name, int Age);
var person1 = new Person("John", 30);
var person2 = person1 with { Age = 35 };
Console.WriteLine(person1);
Console.WriteLine(person2);
Output:
Person { Name = John, Age = 30 }
Person { Name = John, Age = 35 }
👉 This is called Non-destructive mutation
6. Record with Properties
public record Person
{
public string Name { get; init; }
public int Age { get; init; }
}
Usage:
var person = new Person
{
Name = "John",
Age = 30
};
👉 init allows setting only during initialization
7. Record Inheritance
public record Person(string Name);
public record Employee(string Name, int Salary) : Person(Name);
Usage:
var emp = new Employee("John", 50000);
Console.WriteLine(emp);
8. Record Struct (C# 10)
Records can also be structs
public record struct Person(string Name, int Age);
Difference:
| Type | Memory |
|---|---|
| record | Reference Type |
| record struct | Value Type |
9. Positional Records
public record Person(string Name, int Age);
Equivalent to:
public record Person
{
public string Name { get; init; }
public int Age { get; init; }
public Person(string Name, int Age)
{
this.Name = Name;
this.Age = Age;
}
}
10. Deconstruction (Interview Favorite)
public record Person(string Name, int Age);
var person = new Person("John", 30);
var (name, age) = person;
Console.WriteLine(name);
Console.WriteLine(age);
11. When to Use Records (Interview Answer) ✅
Use Records when:
✔ Data models
✔ DTOs
✔ Immutable objects
✔ Value comparison needed
✔ Read-only objects
Example:
public record EmployeeDto(int Id, string Name);
12. When NOT to Use Records ❌
Avoid Records when:
❌ Mutable objects needed
❌ Heavy business logic
❌ Entity Framework entities (sometimes not recommended)
13. Real-World Example (Interview Ready)
public record Order(int Id, decimal Amount);
var order1 = new Order(1, 500);
var order2 = new Order(1, 500);
Console.WriteLine(order1 == order2);
Output:
True
14. Records vs Struct vs Class (Interview Table)
| Feature | Class | Struct | Record |
|---|---|---|---|
| Type | Reference | Value | Reference |
| Immutable | No | No | Yes |
| Equality | Reference | Value | Value |
| Boilerplate | More | Less | Very Less |
| Use Case | Business Logic | Small Data | DTO/Data Models |
15. Tricky Interview Questions
Q1: Are Records immutable?
👉 Yes, by default (using init)
Q2: Are Records reference types?
👉 Yes (unless using record struct)
Q3: Can Records inherit?
👉 Yes
Q4: Can Records have methods?
👉 Yes
public record Person(string Name, int Age)
{
public void Print()
{
Console.WriteLine(Name);
}
}
Q5: Can we modify record values?
👉 Yes using with
var p2 = p1 with { Age = 40 };
16. Most Important Interview One-Liner
Records are immutable reference types used for storing data with value-based equality.
Server-Side Session vs Cache
Server-Side Session vs Cache is a very common interview topic — especially for .NET / Web API / System Design roles.
Server-Side Session vs Cache (Interview Guide)
1. What is Server-Side Session?
Server-side session stores user-specific data on the server.
Each user gets a unique Session ID which is stored in:
-
Cookie (usually)
-
URL (rare)
Server uses that Session ID to retrieve user data.
Example
User logs into a website:
HttpContext.Session.SetString("UserName", "Sampath");
Later:
var name = HttpContext.Session.GetString("UserName");
What happens internally
Browser → sends Session ID
Server → finds session data
Server → returns user-specific data
When to Use Sessions
Use Session when storing:
✅ Logged-in user info
✅ User preferences
✅ Shopping cart items
✅ Temporary user state
Session Example (Real-world)
E-commerce website:
User adds items to cart:
Session["Cart"] = [Item1, Item2]
Each user has different cart
2. What is Cache?
Cache stores application-wide shared data to improve performance.
Cache is NOT user-specific
Example
_memoryCache.Set("Products", productsList);
Later:
var products = _memoryCache.Get("Products");
When to Use Cache
Use Cache when storing:
✅ Frequently accessed data
✅ Database query results
✅ Configuration data
✅ Static data (countries, cities)
Cache Example (Real-world)
Fetching countries from database:
Instead of hitting DB every time:
var countries = _memoryCache.Get("Countries");
if (countries == null)
{
countries = _repository.GetCountries();
_memoryCache.Set("Countries", countries);
}
Key Differences (Important for Interviews)
| Feature | Session | Cache |
|---|---|---|
| Data Type | User-specific | Application-wide |
| Performance | Slower | Faster |
| Scope | Per User | Shared |
| Lifetime | User session | Configurable |
| Example | Shopping cart | Countries list |
| Memory Usage | Higher | Optimized |
| Expiration | Session timeout | Absolute/Sliding |
Example to Understand Clearly
Session Example
User A:
Session["User"] = "Sampath"
User B:
Session["User"] = "Ravi"
Each user has different values
Cache Example
Cache:
Cache["Countries"] = India, USA, UK
All users share same data
Interview Question
Q: When should you use Session vs Cache?
Answer:
-
Use Session for user-specific data
-
Use Cache for shared application data
.NET Core Example (Side-by-Side)
Session
HttpContext.Session.SetString("User", "Sampath");
Cache
_memoryCache.Set("User", "Sampath");
Difference:
-
Session → per user
-
Cache → global
Interview Trick Question
Q: Can Session use Cache internally?
Answer: Yes
Session can use:
-
In-Memory
-
Redis
-
SQL Server
Same applies to cache.
Types of Cache (Interview Bonus)
1. In-Memory Cache
IMemoryCache
Stored in server memory
2. Distributed Cache
IDistributedCache
Stored in:
-
Redis
-
SQL Server
-
NCache
Best for load balanced systems
Session Types (.NET Core)
1. In-Memory Session
Stored in server memory
2. Distributed Session
Stored in:
-
Redis
-
SQL Server
Interview Question
Q: Why not use Session for everything?
Answer:
❌ Uses more memory
❌ Not scalable
❌ Slower in distributed systems
Use Cache instead when possible.
Performance Difference
Fastest → Cache
Slower → Session
Slowest → Database
Interview One-Line Answers
What is Session?
Session stores user-specific data on the server.
What is Cache?
Cache stores frequently accessed shared data for performance.
Real Interview Example
Login System:
Use Session:
UserId
UserRole
UserName
Use Cache:
Country List
Settings
Configuration
Pro Interview Tip
Good answer:
Session is user-specific while cache is shared across users. Sessions maintain user state whereas cache improves performance.
Multi-Threading in C#
Multi-Threading in C# (Interview Guide)
Multi-threading allows a program to run multiple tasks at the same time using multiple threads.
A Thread is the smallest unit of execution inside a process.
👉 Example:
-
Download file 📥
-
Show progress bar 📊
-
Allow user interaction 🖱️
All happening simultaneously using multi-threading.
Why Multi-Threading? (Interview Answer)
Multi-threading is used for:
-
Better performance ⚡
-
Responsive UI 🖥️
-
Parallel execution 🔄
-
Background processing 🔧
Process vs Thread (Important Interview Question)
| Process | Thread |
|---|---|
| Independent program | Part of a process |
| Heavyweight | Lightweight |
| Separate memory | Shared memory |
| Slower | Faster |
Example:
-
Browser = Process
-
Tabs = Threads
Example Without Multi-Threading
static void Main()
{
Method1();
Method2();
}
static void Method1()
{
for(int i = 0; i < 5; i++)
{
Console.WriteLine("Method1");
}
}
static void Method2()
{
for(int i = 0; i < 5; i++)
{
Console.WriteLine("Method2");
}
}
Output (Sequential)
Method1
Method1
Method1
Method1
Method1
Method2
Method2
Method2
Method2
Method2
This is Single Threaded.
Multi-Threading Example Using Thread Class
using System.Threading;
static void Main()
{
Thread t1 = new Thread(Method1);
Thread t2 = new Thread(Method2);
t1.Start();
t2.Start();
}
static void Method1()
{
for(int i = 0; i < 5; i++)
{
Console.WriteLine("Method1");
}
}
static void Method2()
{
for(int i = 0; i < 5; i++)
{
Console.WriteLine("Method2");
}
}
Output (Parallel)
Method1
Method2
Method1
Method2
Method1
Method2
Execution order is not guaranteed.
Task Parallel Library (Recommended in Modern C#)
using System.Threading.Tasks;
static void Main()
{
Task task1 = Task.Run(() => Method1());
Task task2 = Task.Run(() => Method2());
Task.WaitAll(task1, task2);
}
👉 Task is preferred over Thread in modern applications.
Thread.Sleep Example
static void Method1()
{
for(int i = 0; i < 5; i++)
{
Console.WriteLine("Method1");
Thread.Sleep(1000);
}
}
This pauses execution for 1 second ⏱️
Real-World Example 🏢
A Jobportal may do:
-
Send email 📧
-
Upload resume 📄
-
Save database 💾
All at same time using multi-threading.
Task.Run(() => SendEmail());
Task.Run(() => UploadResume());
Task.Run(() => SaveToDatabase());
This improves performance and user experience.
Thread vs Task (Interview Favorite Question)
| Thread | Task |
|---|---|
| Low-level | High-level |
| Hard to manage | Easy to manage |
| Manual control | Automatic |
| Slower | Faster |
👉 Always prefer Task in modern C#
Multi-Threading Problems
1. Race Condition
int counter = 0;
Parallel.For(0, 1000, i =>
{
counter++;
});
Expected: 1000
Actual: unpredictable ❌
Solution: Lock
lock(obj)
{
counter++;
}
Lock Example 🔐
static object obj = new object();
lock(obj)
{
Console.WriteLine("Thread Safe");
}
Parallel Programming Example
Parallel.For(0, 5, i =>
{
Console.WriteLine(i);
});
Runs in parallel ⚡
Interview Questions & Answers
1. What is Multi-Threading?
Running multiple threads simultaneously within a process.
2. What is Thread?
Smallest unit of execution.
3. Difference between Task and Thread?
Task is high-level and recommended.
4. What is Race Condition?
Multiple threads accessing shared resource simultaneously.
5. What is Deadlock?
Two threads waiting for each other forever.
Deadlock Example
lock(obj1)
{
lock(obj2)
{
}
}
Another thread:
lock(obj2)
{
lock(obj1)
{
}
}
This causes Deadlock.
When to Use Multi-Threading
Use when:
✅ File processing
✅ Background jobs
✅ Email sending
✅ API calls
✅ Parallel computation
Avoid when:
❌ Simple operations
❌ Shared resource heavy operations
Best Practices
✔ Use Task instead of Thread
✔ Avoid shared variables
✔ Use async/await when possible
✔ Use lock carefully
✔ Avoid deadlocks
Async vs Multi-Threading (Important Interview Question)
| Async | Multi-Threading |
|---|---|
| Non-blocking | Parallel execution |
| Single thread possible | Multiple threads |
| I/O operations | CPU operations |
Example:
await GetDataAsync();
No extra thread required.
Summary
-
Multi-Threading improves performance
-
Thread is low-level
-
Task is recommended
-
Watch for race conditions
-
Use lock carefully
Extension Methods in C# (Interview Guide)
Extension Methods in C# (Interview Guide)
Extension methods are a powerful feature in C# that allow you to add new methods to existing types without modifying their source code.
This is very commonly asked in interviews.
What are Extension Methods?
Definition:
Extension methods allow you to extend existing classes, structs, or interfaces by adding new methods without inheritance or modifying original class.
They are heavily used in LINQ.
Why Use Extension Methods?
Extension methods help when:
✅ You don't have access to source code
✅ You don't want to create derived classes
✅ You want cleaner and readable code
✅ You want to add utility/helper methods
Basic Syntax
Extension methods must:
-
Be inside static class
-
Be static method
-
First parameter must use this keyword
public static class ExtensionClass
{
public static returnType MethodName(this Type obj)
{
// logic
}
}
Simple Example
Let's add a method to string
public static class StringExtensions
{
public static bool IsLong(this string value)
{
return value.Length > 10;
}
}
Now you can use it like this:
string name = "Hello World";
bool result = name.IsLong();
Console.WriteLine(result);
Output
True
This looks like IsLong() is part of string class — but it's actually an extension method.
Real World Example (Very Important for Interviews)
public static class NumberExtensions
{
public static bool IsEven(this int number)
{
return number % 2 == 0;
}
}
Usage:
int num = 10;
Console.WriteLine(num.IsEven());
Output:
True
Example from LINQ (Most Common Example)
var numbers = new List<int> { 1, 2, 3, 4, 5 };
var evenNumbers = numbers.Where(x => x % 2 == 0);
Where() is actually an Extension Method.
How Extension Methods Work Internally
This:
num.IsEven();
Is converted internally to:
NumberExtensions.IsEven(num);
Rules for Extension Methods
✅ Must be static class
✅ Must be static method
✅ First parameter must use this
✅ Namespace must be included using using
Extension Method with Multiple Parameters
public static class MathExtensions
{
public static int Add(this int a, int b)
{
return a + b;
}
}
Usage:
int result = 5.Add(3);
Console.WriteLine(result);
Output:
8
Extension Methods vs Inheritance
| Extension Methods | Inheritance |
|---|---|
| No need to inherit | Requires inheritance |
| Cleaner syntax | More complex |
| Cannot override methods | Can override |
| Adds helper methods | Adds full functionality |
Interview Questions & Answers
1. What are Extension Methods?
Extension methods allow adding new methods to existing types without modifying them.
2. Where are Extension Methods used?
Mostly used in:
-
LINQ
-
Utility methods
-
String helpers
-
Collection helpers
3. Can Extension Methods access private members?
❌ No
They can only access public members
4. Can Extension Methods override existing methods?
❌ No
They only work if method doesn't already exist.
5. What is the advantage of Extension Methods?
-
Clean code
-
Reusability
-
No inheritance needed
-
Better readability
Advanced Example (Real Interview Level)
public static class DateTimeExtensions
{
public static bool IsWeekend(this DateTime date)
{
return date.DayOfWeek == DayOfWeek.Saturday
|| date.DayOfWeek == DayOfWeek.Sunday;
}
}
Usage:
DateTime today = DateTime.Now;
Console.WriteLine(today.IsWeekend());
When NOT to Use Extension Methods
Avoid when:
❌ You need to modify object state
❌ You need polymorphism
❌ You need method override
Best Practice
✔ Use Extension Methods for utility/helper methods
✔ Keep them small and readable
✔ Use meaningful naming
One-Line Interview Answer
Extension Methods allow adding new methods to existing types without modifying their source code using static methods and
thiskeyword.
Exception Handling — Interview Guide
Exception Handling is one of the most frequently asked interview topics — especially for C#, Java, .NET, and backend roles. Let's break it down in a simple, interview-focused way.
Exception Handling — Interview Guide
1. What is Exception Handling?
Exception Handling is a mechanism to handle runtime errors so that the application doesn't crash and can continue execution gracefully.
Example Without Exception Handling
int a = 10;
int b = 0;
int result = a / b; // Crash (DivideByZeroException)
This will crash the application.
2. Basic Exception Handling Syntax
try
{
// Risky code
}
catch (Exception ex)
{
// Handle exception
}
finally
{
// Always executes
}
3. Example (Most Common Interview Example)
try
{
int a = 10;
int b = 0;
int result = a / b;
}
catch (DivideByZeroException ex)
{
Console.WriteLine("Cannot divide by zero");
}
finally
{
Console.WriteLine("Execution completed");
}
Output
Cannot divide by zero
Execution completed
4. Try, Catch, Finally Explained
Try
Contains risky code
try
{
int x = int.Parse("abc");
}
Catch
Handles the exception
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
Finally
Always executes (even if exception occurs or not)
finally
{
Console.WriteLine("Cleanup code");
}
Used for:
-
Closing database connections
-
Closing files
-
Releasing memory
5. Multiple Catch Blocks (Important Interview Question)
try
{
int[] arr = new int[2];
arr[5] = 10;
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine("Index error");
}
catch (Exception ex)
{
Console.WriteLine("General exception");
}
Important Rule
Always place:
Specific Exception → First
General Exception → Last
Wrong Order (Compile Error):
catch (Exception ex)
catch (DivideByZeroException ex)
6. Finally Block Without Catch
Yes, it's allowed.
try
{
Console.WriteLine("Hello");
}
finally
{
Console.WriteLine("Finally executed");
}
7. Throw Keyword
Used to manually throw exceptions
int age = 15;
if(age < 18)
{
throw new Exception("Age must be above 18");
}
8. Throw vs Throw ex (Very Important Interview Question)
Wrong
catch(Exception ex)
{
throw ex;
}
Correct
catch(Exception ex)
{
throw;
}
Why?
throw; preserves original stack tracethrow ex; resets stack trace (bad for debugging)
Interview Tip:
Always use throw;
9. Custom Exception (Very Important for Senior Roles)
Create your own exception
public class AgeException : Exception
{
public AgeException(string message) : base(message)
{
}
}
Use it:
if(age < 18)
{
throw new AgeException("Invalid age");
}
10. Exception Handling Best Practices (Interview Gold)
1. Don't catch general exception unnecessarily
❌ Bad
catch(Exception ex)
{
}
✔ Good
catch(SqlException ex)
{
}
2. Don't use exceptions for normal flow
❌ Bad
try
{
int x = int.Parse(input);
}
catch
{
}
✔ Good
int.TryParse(input, out int x);
3. Always log exceptions
catch(Exception ex)
{
logger.LogError(ex.Message);
}
11. Common Built-in Exceptions (Interview Favorite)
| Exception | When It Occurs |
|---|---|
| NullReferenceException | Object is null |
| DivideByZeroException | Division by zero |
| IndexOutOfRangeException | Invalid index |
| FormatException | Invalid format |
| InvalidOperationException | Invalid operation |
| ArgumentException | Invalid argument |
12. Real World Example
try
{
using(var connection = new SqlConnection(connectionString))
{
connection.Open();
}
}
catch(SqlException ex)
{
Console.WriteLine("Database error");
}
finally
{
Console.WriteLine("Cleanup");
}
13. Interview Tricky Questions
Q1: Can try exist without catch?
✔ Yes (with finally)
Q2: Can catch exist without try?
❌ No
Q3: Can finally exist without catch?
✔ Yes
Q4: Does finally always execute?
✔ Yes (except: Environment.FailFast, process kill)
Q5: Can we have multiple finally?
❌ No
14. Exception Handling Flow
Try → Exception Occurs → Catch → Finally
If no exception:
Try → Finally
15. Global Exception Handling (.NET Core — Very Important)
app.UseExceptionHandler("/Home/Error");
OR
Middleware
app.UseMiddleware<ExceptionMiddleware>();
16. When Should You Use Exception Handling?
Use exceptions for:
✔ Database failures
✔ API failures
✔ File access issues
✔ Unexpected errors
Don't use for:
❌ Validations
❌ Business logic
❌ Normal flow
17. Best Interview Answer (Short Definition)
Exception Handling is a mechanism to handle runtime errors in an application so that the program can continue execution gracefully without crashing.
18. Senior-Level Interview Tip
Good exception handling:
✔ Specific exceptions
✔ Logging
✔ Meaningful message
✔ No silent catch
✔ Global handling
N + 1 Problem in EF Core (Interview Explanation)
N + 1 Problem in EF Core (Interview Explanation)
The N + 1 Problem is one of the most commonly asked interview questions in Entity Framework Core.
What is N + 1 Problem?
Definition:
The N + 1 problem occurs when:
-
1 query is executed to fetch parent data
-
N additional queries are executed to fetch child data
This results in multiple database calls, causing performance issues.
Simple Example
Suppose you have:
-
Orders (Parent)
-
OrderItems (Child)
Bad Code (N + 1 Problem)
var orders = context.Orders.ToList();
foreach (var order in orders)
{
var items = order.OrderItems.ToList();
}
What Happens Internally
If you have 5 orders, EF Core executes:
1 query → Get Orders
5 queries → Get OrderItems for each order
Total queries:
1 + 5 = 6 queries
This is called N + 1 Problem
Visual Explanation
Orders Query → 1
OrderItems Query → N (for each order)
Total = N + 1
Why is it Bad?
❌ Multiple database calls
❌ Slow performance
❌ High database load
❌ Bad scalability
This becomes very dangerous when:
-
100 orders → 101 queries
-
1000 orders → 1001 queries
Why Does This Happen?
Because of Lazy Loading.
EF Core loads related data only when accessed, which causes multiple queries.
How to Fix N + 1 Problem ✅
Use Eager Loading with Include()
Good Code
var orders = context.Orders
.Include(x => x.OrderItems)
.ToList();
Now EF Core executes:
1 query → Orders + OrderItems
Problem solved! 🎉
Even Better (Best Practice)
Use Select Projection (Best Performance)
var orders = context.Orders
.Select(o => new
{
o.Id,
Items = o.OrderItems
})
.ToList();
This improves performance further.
Real Interview Example
Bad:
var employees = context.Departments.ToList();
foreach(var dept in employees)
{
var emp = dept.Employees;
}
Good:
var employees = context.Departments
.Include(x => x.Employees)
.ToList();
Interview Questions & Answers 🎯
What is N + 1 Problem?
N + 1 problem occurs when one query is used to fetch parent data and multiple queries are used to fetch related child data, causing performance issues.
How to identify N + 1 Problem?
-
Multiple DB calls in logs
-
Slow performance
-
Lazy loading usage
How to solve N + 1 Problem?
✅ Use Include()
✅ Use Select() projection
✅ Disable Lazy Loading
✅ Use AsSplitQuery() (Advanced)
Advanced Solution (EF Core 5+)
Use AsSplitQuery() if needed:
var orders = context.Orders
.Include(x => x.OrderItems)
.AsSplitQuery()
.ToList();
One-Line Interview Answer
The N + 1 problem occurs when EF Core executes one query for parent data and N queries for related child data, causing performance issues.
Pro Interview Tip 💡
If interviewer asks:
"How do you detect N + 1 problem?"
Answer:
-
Enable SQL logging
-
Use profiler
-
Check EF Core generated queries
Difference between Use, Run, Map?
In .NET Core Middleware pipeline, Use, Run, and Map control how request flows through middleware.
Think of them like traffic controllers 🚦
1. Use() — Continue to Next Middleware
Use() can call next middleware in pipeline.
Example
app.Use(async (context, next) =>
{
Console.WriteLine("Middleware 1 - Before");
await next();
Console.WriteLine("Middleware 1 - After");
});
app.Use(async (context, next) =>
{
Console.WriteLine("Middleware 2");
await next();
});
Output
Middleware 1 - Before
Middleware 2
Middleware 1 - After
Key Points
✅ Can call next middleware
✅ Can modify request/response
✅ Most commonly used
2. Run() — Terminates Pipeline
Run() does NOT call next middleware
It ends the pipeline immediately 🛑
Example
app.Use(async (context, next) =>
{
Console.WriteLine("Middleware 1");
await next();
});
app.Run(async context =>
{
Console.WriteLine("Middleware 2 - Run");
});
Output
Middleware 1
Middleware 2 - Run
If you add middleware after Run():
app.Run(async context =>
{
Console.WriteLine("Run Middleware");
});
app.Use(async (context, next) =>
{
Console.WriteLine("This will never execute");
});
❌ This middleware will never execute
3. Map() — Branch the Pipeline
Map() creates a separate pipeline based on URL path 🔀
Example
app.Map("/admin", adminApp =>
{
adminApp.Run(async context =>
{
await context.Response.WriteAsync("Admin Page");
});
});
app.Run(async context =>
{
await context.Response.WriteAsync("Home Page");
});
Results
/admin → Admin Page
/home → Home Page
Visual Comparison
Use → Continue pipeline
Run → End pipeline
Map → Branch pipeline
Interview Table (Very Important)
| Feature | Use | Run | Map |
|---|---|---|---|
| Calls next middleware | ✅ Yes | ❌ No | Depends |
| Ends pipeline | ❌ No | ✅ Yes | Branch |
| Creates branch | ❌ No | ❌ No | ✅ Yes |
| Most common | ✅ Yes | ❌ No | ⚠️ Sometimes |
Interview Answer (Short Version)
Use() continues to next middleware.
Run() terminates the pipeline.
Map() creates branch pipeline based on URL path.
Real-world Example
app.UseAuthentication();
app.UseAuthorization();
app.Map("/admin", admin =>
{
admin.UseAuthorization();
});
app.Run();
Trick Interview Question
Q: Can we place Run() in middle?
👉 Yes, but everything after that won't execute
If you'd like, I can also explain:
-
UseWhen vs MapWhen (Very common interview question)
-
Middleware execution order
-
Real-world production middleware examples
Abstract Class vs Interface
In C#, Abstract Class and Interface are both used for abstraction, but they serve different purposes.
Quick Difference (Interview Answer)
-
Abstract Class → Used when classes share common behavior + base implementation
-
Interface → Used when classes share only contract (no implementation)
1. Abstract Class
An Abstract Class can have:
✅ Abstract methods
✅ Concrete methods
✅ Fields
✅ Constructors
✅ Properties
Example
public abstract class Animal
{
public void Eat()
{
Console.WriteLine("Animal is eating");
}
public abstract void MakeSound();
}
Child class:
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("Dog barks");
}
}
Usage
Dog dog = new Dog();
dog.Eat();
dog.MakeSound();
2. Interface
An Interface only defines contract (what to implement)
Example
public interface IAnimal
{
void Eat();
void MakeSound();
}
Child class:
public class Dog : IAnimal
{
public void Eat()
{
Console.WriteLine("Dog is eating");
}
public void MakeSound()
{
Console.WriteLine("Dog barks");
}
}
Key Differences Table
| Feature | Abstract Class | Interface |
|---|---|---|
| Methods with body | ✅ Yes | ⚠️ Yes (C# 8+) |
| Abstract methods | ✅ Yes | ✅ Yes |
| Fields | ✅ Yes | ❌ No |
| Constructors | ✅ Yes | ❌ No |
| Access Modifiers | ✅ Yes | ❌ No (Mostly public) |
| Multiple inheritance | ❌ No | ✅ Yes |
| When to use | Base class | Contract |
Important Interview Question
Multiple Inheritance
Abstract class ❌ Not allowed
class A {}
class B {}
class C : A, B // ❌ Not allowed
{
}
Interface ✅ Allowed
interface IA {}
interface IB {}
class C : IA, IB // ✅ Allowed
{
}
When to Use Abstract Class
Use Abstract Class when:
✅ Classes are closely related
✅ Want common functionality
✅ Need shared code
Example:
-
Animal → Dog, Cat
-
Employee → Manager, Developer
When to Use Interface
Use Interface when:
✅ Different classes share behavior
✅ Need multiple inheritance
✅ Want loose coupling
Example:
-
ILogger
-
IRepository
-
IEmailService
Real-World Example
interface ILogger
{
void Log(string message);
}
class FileLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine("File log");
}
}
class DbLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine("DB log");
}
}
Interview One-Line Answer
Abstract class provides partial implementation, while Interface provides only contract. Abstract class supports single inheritance, Interface supports multiple inheritance.
Trick Interview Question
Q: Can interface have implementation?
👉 Yes, after C# 8.0 (Default Interface Methods)
public interface ITest { void Test() { Console.WriteLine("Default implementation"); } }
Uses of using in C#
In C#, the using keyword is used for three different purposes. This is a very common interview question.
3 Uses of using in C#
-
Import Namespace
-
Dispose Resources Automatically
-
Using Alias
Let's go one by one 👇
1. Using for Namespace Import (Most Common)
We use using to import namespaces so we don't need to write full names.
Without using
System.Console.WriteLine("Hello");
With using
using System;
Console.WriteLine("Hello");
✅ Cleaner
✅ Easier to read
✅ Common usage
2. Using for Automatic Resource Disposal (Very Important)
We use using to automatically dispose resources like:
-
Files
-
Database connections
-
Streams
-
HttpClient
These objects implement IDisposable.
Example
using (StreamReader reader = new StreamReader("file.txt"))
{
string text = reader.ReadToEnd();
}
After block ends:
Dispose() is automatically called
Equivalent to:
StreamReader reader = new StreamReader("file.txt");
try
{
string text = reader.ReadToEnd();
}
finally
{
reader.Dispose();
}
✅ Prevents memory leaks
✅ Cleaner code
✅ Recommended practice
Modern C# (Using Declaration)
using StreamReader reader = new StreamReader("file.txt");
string text = reader.ReadToEnd();
Cleaner and modern approach 🚀
3. Using Alias
We use using to create alias names.
Example
using Project = MyCompany.Project.Module;
Now:
Project obj = new Project();
Useful when:
-
Namespace is long
-
Conflicting class names
Interview Summary
| Usage | Purpose |
|---|---|
| using namespace | Import namespace |
| using statement | Dispose resources |
| using alias | Short name |
Interview One-Line Answer
The using keyword in C# is used to import namespaces, automatically dispose resources, and create aliases.
What is Authentication and Authorization?
Authentication and Authorization are two fundamental security concepts in ASP.NET Core and most modern applications.
Many interviewers ask this question together.
Quick Interview Answer
-
Authentication → Who are you? 🔐
-
Authorization → What can you access? 🛡️
1. Authentication (Who are you?)
Authentication is the process of verifying the user's identity.
Example:
-
Username & Password
-
OTP
-
Fingerprint
-
Login with Google
When you log in to a website:
Enter username + password
System checks:
Is this user valid?
If yes → User is Authenticated ✅
Example
Login to Gmail
Username: sampath@gmail.com
Password: *****
System verifies → You are authenticated
2. Authorization (What can you access?)
After authentication, system checks what user is allowed to do.
Example:
| User | Access |
|---|---|
| Admin | Create users |
| HR | Add candidates |
| Employee | View profile |
This is Authorization.
Real Example
Suppose your ATS application (hiringbegins.com from your previous project):
User logs in:
Step 1 → Authentication
Is this user valid?
Step 2 → Authorization
Is user HR or Admin?
Then show features accordingly.
Example in Code (.NET Core)
Authentication
app.UseAuthentication();
Authorization
app.UseAuthorization();
Order matters
app.UseAuthentication();
app.UseAuthorization();
Visual Flow
User Login
↓
Authentication (Who are you?)
↓
Authorization (What can you access?)
↓
Access Granted
Real World Example
Bank ATM 💳
Authentication:
Insert card + PIN
Authorization:
Check account balance? ✅
Withdraw money? ✅
Close account? ❌
Interview Comparison Table
| Feature | Authentication | Authorization |
|---|---|---|
| Purpose | Verify identity | Check permissions |
| Happens first | ✅ Yes | ❌ No |
| Example | Login | Role-based access |
| Data used | Username/password | Roles/claims |
Common Authentication Methods
-
Cookies
-
JWT Token
-
OAuth
-
OpenID Connect
Examples:
-
JWT
-
OAuth 2.0
-
OpenID Connect
Interview One-Line Answer
Authentication verifies who the user is, while authorization determines what the user is allowed to access.
Authorization in ASP.NET Core
Authorization in ASP.NET Core is typically implemented in 4 common ways:
-
Role-Based Authorization
-
Policy-Based Authorization
-
Claims-Based Authorization
-
Custom Authorization Handler
Let's go step-by-step with real examples 👇
1. Role-Based Authorization (Most Common)
You restrict access based on user roles like:
-
Admin
-
HR
-
Employee
-
Manager
Example
[Authorize(Roles = "Admin")]
public IActionResult GetUsers()
{
return Ok("Only Admin can access");
}
Only Admin users can access this API.
Multiple Roles
[Authorize(Roles = "Admin,HR")]
public IActionResult GetCandidates()
{
return Ok("Admin or HR can access");
}
Now:
✅ Admin → Allowed
✅ HR → Allowed
❌ Employee → Not Allowed
2. Policy-Based Authorization (Recommended for Complex Rules)
First, define policy in Program.cs
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("HRPolicy",
policy => policy.RequireRole("HR"));
});
Use policy:
[Authorize(Policy = "HRPolicy")]
public IActionResult GetApplicants()
{
return Ok("Only HR");
}
Multiple Conditions Policy
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("ManagerPolicy", policy =>
policy.RequireRole("Manager")
.RequireClaim("Department", "IT"));
});
Now:
User must be:
✅ Manager
✅ Department = IT
3. Claims-Based Authorization
Claims are user information stored inside token
Example claims:
-
Role
-
Department
-
Age
-
Country
Example
[Authorize(Policy = "ITDepartment")]
public IActionResult GetITData()
{
return Ok();
}
Define policy:
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("ITDepartment",
policy => policy.RequireClaim("Department", "IT"));
});
Only users with Department = IT can access.
4. Custom Authorization (Advanced)
Create custom requirement:
public class MinimumAgeRequirement : IAuthorizationRequirement
{
public int Age { get; }
public MinimumAgeRequirement(int age)
{
Age = age;
}
}
Handler:
public class MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement>
{
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
MinimumAgeRequirement requirement)
{
var age = int.Parse(context.User.FindFirst("Age").Value);
if (age >= requirement.Age)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
Register:
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AgePolicy",
policy => policy.Requirements.Add(new MinimumAgeRequirement(18)));
});
Use:
[Authorize(Policy = "AgePolicy")] public IActionResult GetContent() { return Ok(); }
Middleware Order (Important Interview Question)
Always use:
app.UseAuthentication();
app.UseAuthorization();
Order matters!
Interview Summary
| Authorization Type | When to Use |
|---|---|
| Role Based | Simple access |
| Policy Based | Complex rules |
| Claims Based | Token-based access |
| Custom Handler | Advanced logic |
One-Line Interview Answer
Authorization in ASP.NET Core can be implemented using Role-based, Policy-based, Claims-based, or Custom authorization handlers.
