.NET Interview Questions & Answers

⚙️ .NET Core & ASP.NET Core

What is the difference between .NET Framework and .NET Core?
.NET Framework is a Windows-only framework released in 2002, while .NET Core is a cross-platform, open-source framework introduced in 2016. .NET Core is modular, lightweight, and supports Windows, Linux, and macOS. It has better performance and is designed for modern cloud-based applications. .NET Framework is used for legacy Windows applications, while .NET Core (now .NET 5+) is the future of .NET development.
What is the difference between .NET Core and .NET 5/6/7?
.NET Core was the initial cross-platform version (versions 1.0 through 3.1). Starting with .NET 5, Microsoft unified .NET Core and .NET Framework into a single platform simply called ".NET". .NET 5+ includes all .NET Core features plus additional capabilities from .NET Framework. The version numbers jumped from .NET Core 3.1 to .NET 5 to avoid confusion with .NET Framework 4.x. Each annual release brings performance improvements and new features.
Explain the middleware pipeline in ASP.NET Core.
The middleware pipeline is a series of components that handle HTTP requests and responses in sequence. Each middleware can process the request, pass it to the next component, and then process the response on the way back. Middleware is configured in Program.cs using Use, Map, or Run methods. Common middleware includes authentication, routing, static files, and exception handling. Order matters—middleware executes in the order it's registered.
What is dependency injection (DI) and how is it implemented in ASP.NET Core?
Dependency Injection is a design pattern where objects receive their dependencies from external sources rather than creating them internally. ASP.NET Core has built-in DI container configured in Program.cs using services.AddScoped/AddTransient/AddSingleton. Dependencies are injected via constructor injection, making code more testable and maintainable. DI promotes loose coupling by depending on abstractions (interfaces) rather than concrete implementations. It's fundamental to ASP.NET Core architecture.
What are the different lifetimes of services in ASP.NET Core?
Transient services are created each time they're requested, suitable for lightweight stateless services. Scoped services are created once per client request (HTTP request), ideal for operations within a single request like database contexts. Singleton services are created once and shared throughout the application lifetime, used for stateless services or configuration. Choosing the correct lifetime is crucial for performance and avoiding memory leaks or concurrency issues.
How do you handle exceptions globally in ASP.NET Core?
Use the built-in exception handling middleware by calling app.UseExceptionHandler() in Program.cs, which redirects to an error handling endpoint. Alternatively, create custom middleware using app.Use() to catch exceptions and return appropriate responses. For development, use app.UseDeveloperExceptionPage() to see detailed error information. You can also implement IExceptionFilter for MVC-specific exception handling. Global exception handling ensures consistent error responses and prevents application crashes.
What is the purpose of Startup.cs or Program.cs in .NET 6+?
In .NET 6+, Program.cs replaces Startup.cs and uses minimal hosting model with top-level statements. It configures services (dependency injection) and the HTTP request pipeline (middleware). The WebApplicationBuilder creates the application, services are registered using builder.Services, and middleware is configured using app.Use methods. It's the entry point where you set up authentication, routing, database contexts, and other application services.
What is configuration and how do you manage environment-specific settings in ASP.NET Core?
Configuration in ASP.NET Core comes from multiple sources: appsettings.json, environment variables, user secrets, and command-line arguments. Environment-specific settings use appsettings.{Environment}.json files (Development, Staging, Production). Access configuration via IConfiguration interface injected through DI. The ASPNETCORE_ENVIRONMENT variable determines which settings file to use. User secrets protect sensitive data during development without committing to source control.
What are filters in ASP.NET Core MVC?
Filters are attributes that run code before or after specific stages in the request processing pipeline. Types include Authorization (security), Resource (before model binding), Action (before/after action execution), Exception (handle errors), and Result (before/after result execution). They enable cross-cutting concerns like logging, caching, or validation. Filters can be applied globally, at controller level, or on individual actions. They provide a clean way to implement reusable behaviors.
How do you secure an ASP.NET Core Web API?
Use authentication middleware (JWT, OAuth, Cookie) to verify user identity and authorization to control access. Implement HTTPS using app.UseHttpsRedirection() and HSTS headers. Apply [Authorize] attributes to protect endpoints and use role/policy-based authorization for fine-grained control. Validate input to prevent injection attacks, implement CORS properly, and use API keys or rate limiting. Store secrets in Azure Key Vault or user secrets, never in code.
What is middleware? Can you write a custom middleware?
Middleware is software that sits between the web server and application, processing HTTP requests and responses. Custom middleware is created by implementing a class with Invoke/InvokeAsync method that takes HttpContext and RequestDelegate parameters. Register it using app.UseMiddleware() or create an extension method. Middleware can short-circuit the pipeline by not calling next() or transform request/response. Common uses include logging, authentication, or custom headers.
What's the difference between IActionResult and ActionResult?
IActionResult returns various response types (Ok, NotFound, BadRequest) but doesn't specify the return type, requiring manual documentation. ActionResult combines the flexibility of IActionResult with strong typing, automatically documenting the return type in Swagger/OpenAPI. It allows returning either T directly or IActionResult implementations. ActionResult provides better IntelliSense and compile-time checking. It's the preferred approach for modern ASP.NET Core APIs.
What are tag helpers in ASP.NET Core MVC?
Tag helpers are server-side components that enhance HTML elements with C# code in Razor views. They provide a natural HTML-like syntax compared to HTML helpers (e.g., ). Built-in tag helpers include form, input, label, select, and environment tag helpers. They're strongly typed, provide IntelliSense, and are more maintainable. Custom tag helpers can be created by inheriting from TagHelper class.
What are Razor Pages?
Razor Pages is a page-based programming model in ASP.NET Core that makes building web UI simpler and more productive than MVC. Each page has a .cshtml view file and a .cshtml.cs PageModel code-behind file. They're ideal for page-focused scenarios like forms and CRUD operations. Razor Pages use conventions for routing and organization, reducing boilerplate code. They support the same features as MVC (model binding, validation, filters) but with less ceremony.
How do you log information in ASP.NET Core?
ASP.NET Core has built-in logging via ILogger interface injected through DI. Configure logging providers (Console, Debug, EventSource, EventLog) in Program.cs using builder.Logging. Use log levels (Trace, Debug, Information, Warning, Error, Critical) to categorize messages. Third-party providers like Serilog, NLog, or Application Insights offer advanced features. Structured logging with message templates enables better querying and filtering of logs.
What are endpoints and routing in ASP.NET Core?
Routing maps incoming HTTP requests to executable endpoints (actions, Razor Pages, SignalR hubs). Endpoint routing separates route matching from endpoint execution for better performance. Configure routes using conventional routing (MapControllerRoute) or attribute routing ([Route] attributes). Route templates use parameters like {controller}/{action}/{id?}. Endpoint routing enables middleware to inspect the selected endpoint before execution, supporting features like authorization and CORS.
What is the difference between API Controller and MVC Controller?
API Controllers ([ApiController] attribute) are optimized for building HTTP APIs, automatically handling model validation and returning appropriate status codes. They infer binding sources ([FromBody], [FromRoute]) automatically and return JSON by default. MVC Controllers are designed for rendering views and returning HTML. API Controllers don't support views and focus on data serialization. API Controllers provide better developer experience with automatic 400 responses for validation errors.
What is CORS and how do you enable it?
Cross-Origin Resource Sharing (CORS) is a security feature that allows or restricts web applications from making requests to different domains. Enable CORS in ASP.NET Core by adding services.AddCors() with policies defining allowed origins, methods, and headers. Apply middleware with app.UseCors() before routing. Use [EnableCors] attribute on controllers/actions for granular control. CORS prevents unauthorized cross-domain requests while enabling legitimate scenarios like calling APIs from different frontend applications.
What are Data Annotations in ASP.NET Core?
Data Annotations are attributes applied to model properties for validation, display, and database schema definition. Common validation attributes include [Required], [StringLength], [Range], [EmailAddress], and [RegularExpression]. Display attributes like [Display] and [DisplayFormat] control UI rendering. EF Core uses annotations like [Key], [MaxLength], and [Column] for database mapping. They provide declarative validation that works on both client and server sides, reducing code duplication.
How do you host an ASP.NET Core app on IIS or Kestrel?
Kestrel is the cross-platform web server included with ASP.NET Core, suitable for production use. IIS acts as a reverse proxy forwarding requests to Kestrel on Windows servers. To host on IIS, install ASP.NET Core Hosting Bundle, configure web.config with processPath and arguments. Kestrel can run standalone behind a reverse proxy (Nginx, Apache) or directly exposed. Use Kestrel for cross-platform deployments and IIS integration for Windows-specific features like Windows Authentication.

💡 C# and Object-Oriented Programming

What are the four pillars of OOP?
Encapsulation bundles data and methods into classes, hiding internal details and exposing only necessary parts. Inheritance allows classes to inherit properties and methods from parent classes, promoting code reuse. Polymorphism enables objects to take multiple forms through method overriding and interfaces, allowing different implementations of the same interface. Abstraction hides complex implementation details and shows only essential features, using abstract classes and interfaces to define contracts.
Difference between an abstract class and an interface?
Abstract classes can have both abstract (no implementation) and concrete methods, constructors, and fields. Interfaces (pre-C# 8.0) only declare method signatures without implementation and support multiple inheritance. Abstract classes are used when classes share common behavior, while interfaces define contracts for unrelated classes. A class can implement multiple interfaces but inherit from only one abstract class. Modern C# interfaces support default implementations, narrowing the distinction.
What is the difference between const, readonly, and static in C#?
Const fields are compile-time constants, must be initialized at declaration, and their value cannot change—they're implicitly static. Readonly fields are runtime constants, can be initialized in declaration or constructor, and their value can differ per instance. Static members belong to the type rather than instances and are shared across all objects. Const is used for values that never change (like Math.PI), readonly for values set during construction, and static for shared data/methods.
What is the difference between value types and reference types?
Value types (int, struct, enum) store data directly and are allocated on the stack, making them faster but with limited size. Reference types (class, interface, delegate) store a reference to data allocated on the heap. Value types are copied by value, while reference types copy references. Value types cannot be null (unless nullable), while reference types can. Value types inherit from System.ValueType, reference types from System.Object.
Explain boxing and unboxing in C#.
Boxing converts a value type to object or interface type, wrapping it in a reference type container on the heap. Unboxing extracts the value type from the object back to its original type. Boxing happens implicitly, while unboxing requires explicit casting. These operations have performance overhead due to heap allocation and type checking. Modern C# with generics minimizes boxing by preserving type information, making collections more efficient.
What is a delegate?
A delegate is a type-safe function pointer that references methods with a specific signature. Delegates enable passing methods as parameters, implementing callback mechanisms, and event handling. They support multicast (invoking multiple methods), covariance, and contravariance. Common built-in delegates include Action (void return), Func (returns value), and Predicate (returns bool). Delegates are the foundation for events and lambda expressions in C#.
What is an event and how is it different from a delegate?
Events are a special type of delegate that implements the publisher-subscriber pattern for notification. While delegates can be invoked and reassigned by anyone, events can only be invoked by the declaring class and subscribers can only add/remove handlers. Events use += and -= operators for subscription, providing encapsulation and preventing external invocation. Events are commonly used for UI interactions, state changes, and message passing. They're declared using the event keyword with a delegate type.
What are generics and why are they useful?
Generics enable writing type-safe, reusable code that works with any data type without casting or boxing. They provide compile-time type checking, better performance than object-based code, and code reusability. Generic classes, methods, interfaces, and delegates use type parameters (T) that are specified at instantiation. Common examples include List, Dictionary, and custom repository patterns. Generics eliminate runtime type errors and reduce code duplication.
What is LINQ? Can you give an example query?
LINQ (Language Integrated Query) provides a consistent way to query collections, databases, XML, and other data sources using C# syntax. It offers two syntaxes: query syntax (SQL-like) and method syntax (using extension methods). Example: var adults = people.Where(p => p.Age >= 18).OrderBy(p => p.Name).Select(p => p.Name). LINQ queries are often deferred (lazy evaluation), executing only when enumerated. It supports filtering, projection, aggregation, grouping, and joining operations.
What's the difference between IEnumerable, IQueryable, and List?
IEnumerable is the base interface for iterating collections in-memory using foreach, with deferred execution. IQueryable extends IEnumerable for queryable data sources (like databases), translating expressions to queries (SQL) that execute on the data source. List is a concrete collection class with immediate execution and methods like Add, Remove, and indexed access. Use IEnumerable for in-memory operations, IQueryable for external data sources, and List when you need collection manipulation methods.
What is the difference between ref and out parameters?
Both ref and out pass parameters by reference, allowing methods to modify the original variable. Ref parameters must be initialized before passing, while out parameters must be assigned within the method before returning. Ref is bidirectional (input and output), while out is primarily for output. Out parameters are useful when returning multiple values from a method. Modern C# offers tuples as a cleaner alternative to out parameters in many scenarios.
What is async and await in C#?
Async and await enable asynchronous programming without blocking threads, improving scalability and responsiveness. The async keyword marks methods that contain await operations, while await suspends method execution until the awaited task completes. This frees up threads to handle other work while waiting for I/O operations. Async methods return Task or Task and use asynchronous APIs (HttpClient, database calls). It's essential for building scalable web applications and responsive UIs.
What's the difference between synchronous and asynchronous programming?
Synchronous programming executes operations sequentially, blocking until each operation completes before moving to the next. Asynchronous programming allows operations to run concurrently without blocking, improving application responsiveness and throughput. Synchronous code is simpler but wastes resources during I/O operations. Asynchronous code uses callbacks, promises, or async/await to handle completion. In web applications, async operations allow servers to handle more concurrent requests with fewer threads.
What is Task and ValueTask in C#?
Task represents an asynchronous operation that can be awaited and provides result access, cancellation, and continuation support. ValueTask is a value type alternative to Task designed for high-performance scenarios where the result is often synchronously available. ValueTask reduces heap allocations but has limitations (cannot await multiple times, more restrictive). Use Task for most scenarios and ValueTask only when profiling shows significant allocation overhead. Both support generic (Task, ValueTask) and non-generic versions.
Explain the var, dynamic, and object keywords.
Var uses implicit typing where the compiler infers the type at compile-time from the initializer, providing strong typing. Dynamic defers type checking to runtime, allowing operations that may not exist, useful for COM interop or dynamic languages. Object is the base type for all types but requires explicit casting. Var is compile-time sugar, dynamic disables compile-time checking, and object is explicit type boxing. Var is preferred for readability, dynamic for flexible scenarios, object for generic type handling.
What is encapsulation and how do you achieve it in C#?
Encapsulation bundles data and methods into a class while hiding internal implementation details, exposing only necessary interfaces. Achieve it using access modifiers (private, protected, public, internal) to control member visibility. Properties provide controlled access to private fields with get/set accessors. Encapsulation protects object integrity by preventing external code from directly modifying internal state. It promotes maintainability by allowing internal changes without affecting external code that uses the class.
What is the difference between method overloading and overriding?
Method overloading provides multiple methods with the same name but different parameters (number, types, or order) in the same class, determined at compile-time. Method overriding allows a derived class to provide a specific implementation of a method defined in the base class using virtual/override keywords, determined at runtime (polymorphism). Overloading is about different method signatures, while overriding is about changing inherited method behavior. Overloading is static binding, overriding is dynamic binding.
What is the difference between == and .Equals()?
The == operator checks reference equality for reference types (whether two references point to the same object) unless overloaded. Equals() is a virtual method that checks value equality by comparing object contents, and can be overridden for custom comparison logic. For value types, both compare values by default. For strings, both compare content because string overloads ==. Best practice: override Equals() and GetHashCode() together for custom types, and use == for reference comparison or types that override it.
What are extension methods in C#?
Extension methods allow adding new methods to existing types without modifying the original type or creating a derived type. They're static methods in static classes, with the first parameter using the this keyword to specify the extended type. Extension methods enable fluent APIs and extending sealed classes or types you don't control. LINQ methods (Where, Select, OrderBy) are implemented as extension methods on IEnumerable. They're resolved at compile-time and don't have access to private members.
What is a sealed class?
A sealed class cannot be inherited, preventing other classes from extending it. It's used to prevent further derivation when the class is fully implemented and inheritance would compromise design or security. Sealed classes offer performance benefits because the runtime doesn't need to search for overridden methods. Methods in sealed classes can also be sealed to prevent overriding in derived classes. Common examples include System.String and value types, which are implicitly sealed.

🧠 Data Access & SQL

What are stored procedures and why do we use them?
Stored procedures are precompiled SQL code stored in the database, executed with a single command. They improve performance through query plan caching, reduce network traffic by sending only procedure names, and enhance security by limiting direct table access. They enable encapsulating complex business logic in the database and provide a consistent interface for data operations. Stored procedures support parameters, variables, control flow, and error handling, making them ideal for complex data operations.
What are SQL triggers and when would you use one?
Triggers are special stored procedures that automatically execute in response to specific database events (INSERT, UPDATE, DELETE). They're used for enforcing business rules, maintaining audit trails, enforcing referential integrity, or performing cascading operations. Triggers have access to OLD and NEW row versions, enabling validation and logging changes. Use triggers cautiously as they add overhead and can cause unexpected side effects. They're hidden from application code, which can make debugging challenging.
What is the difference between INNER JOIN, LEFT JOIN, and RIGHT JOIN?
INNER JOIN returns only rows where there's a match in both tables based on the join condition. LEFT JOIN returns all rows from the left table plus matched rows from the right table, with NULLs for unmatched right rows. RIGHT JOIN returns all rows from the right table plus matched rows from the left table, with NULLs for unmatched left rows. Use INNER JOIN for required relationships, LEFT JOIN when the left table is primary, and RIGHT JOIN when the right table is primary.
What are indexes and how do they improve performance?
Indexes are database structures that improve query performance by creating ordered pointers to data, similar to a book's index. They speed up data retrieval but slow down INSERT, UPDATE, and DELETE operations because indexes must be maintained. Clustered indexes determine the physical order of data in a table (one per table), while non-clustered indexes create separate structures with pointers. Create indexes on columns frequently used in WHERE, JOIN, and ORDER BY clauses, balancing query performance against write overhead.
How would you optimize a slow SQL query?
Start by analyzing the execution plan to identify table scans, missing indexes, or inefficient joins. Add appropriate indexes on columns used in WHERE, JOIN, and ORDER BY clauses. Avoid SELECT *, use WHERE instead of HAVING where possible, and limit result sets. Replace subqueries with JOINs when appropriate and avoid functions on indexed columns in WHERE clauses. Consider partitioning large tables, updating statistics, and using query hints. Profile both query execution and database server performance metrics.
What are transactions and why are they important?
Transactions are units of work that execute as a single atomic operation, ensuring data integrity through ACID properties (Atomicity, Consistency, Isolation, Durability). They guarantee all operations complete successfully or none do, preventing partial updates. Transactions use BEGIN TRANSACTION, COMMIT (permanent changes), and ROLLBACK (undo changes) commands. They're crucial for maintaining data consistency in multi-step operations like fund transfers. Proper transaction management prevents data corruption and ensures business logic integrity.
What is normalization and denormalization?
Normalization organizes data to reduce redundancy and improve integrity by dividing large tables into smaller related tables (1NF, 2NF, 3NF). It eliminates data anomalies and ensures data consistency but can impact read performance due to joins. Denormalization intentionally introduces redundancy to improve read performance by reducing joins, at the cost of storage and update complexity. Use normalization for transactional systems (OLTP) requiring data integrity and denormalization for reporting systems (OLAP) prioritizing read speed.
What are views in SQL and when should you use them?
Views are virtual tables based on SQL queries that don't store data themselves but present data from underlying tables. They simplify complex queries, provide security by restricting access to specific columns/rows, and present data in different formats without affecting base tables. Views can be used in queries like regular tables and support most SELECT operations. Use them for frequently used complex joins, enforcing row-level security, or providing backward compatibility when table structures change.
How do you handle database migrations in .NET Core (EF Core)?
EF Core migrations track and apply database schema changes using code-first approach. Create migrations with "dotnet ef migrations add MigrationName" which generates migration files with Up/Down methods. Apply migrations using "dotnet ef database update" or programmatically using context.Database.Migrate(). Migrations support version control, enabling schema evolution across environments. Use migration bundles for production deployments, seed data in OnModelCreating, and test migrations on development databases before production. Maintain migration history for rollback capability.
What is the difference between Entity Framework and ADO.NET?
Entity Framework is an ORM (Object-Relational Mapper) that abstracts database operations using C# objects and LINQ, providing automatic SQL generation and change tracking. ADO.NET is a low-level data access technology requiring manual SQL commands, data readers, and connection management. EF Core offers productivity with less boilerplate code but has some performance overhead. ADO.NET provides fine