Skip to main content

Expert .NET Core Interview Questions

Curated Expert-level .NET Core interview questions for developers targeting expert positions. 40 questions available.

Last updated:

.NET Core Interview Questions & Answers

Skip to Questions

Welcome to our comprehensive collection of .NET Core interview questions and answers. This page contains expertly curated interview questions covering all aspects of .NET Core, from fundamental concepts to advanced topics. Whether you're preparing for an entry-level position or a senior role, you'll find questions tailored to your experience level.

Our .NET Core interview questions are designed to help you:

  • Understand core concepts and best practices in .NET Core
  • Prepare for technical interviews at all experience levels
  • Master both theoretical knowledge and practical application
  • Build confidence for your next .NET Core interview

Each question includes detailed answers and explanations to help you understand not just what the answer is, but why it's correct. We cover topics ranging from basic .NET Core concepts to advanced scenarios that you might encounter in senior-level interviews.

Use the filters below to find questions by difficulty level (Entry, Junior, Mid, Senior, Expert) or focus specifically on code challenges. Each question is carefully crafted to reflect real-world interview scenarios you'll encounter at top tech companies, startups, and MNCs.

Questions

40 questions
Q1:

Explain the .NET Memory Model and its effect on multi-threading.

Expert

Answer

The .NET Memory Model defines visibility, ordering, and synchronization rules. It allows reordering unless blocked by barriers. Volatile improves visibility; Interlocked and lock introduce memory fences. Handles tearing, cache coherency, ABA issues, and provides relaxed consistency similar but less strict than Java.'s model.

Quick Summary: The .NET memory model defines ordering guarantees between threads. Without synchronization, the CPU or compiler can reorder reads and writes — one thread might see stale values. lock adds full memory barriers (prevents reordering). volatile prevents caching. Interlocked provides atomic operations. Correct multi-threaded code needs explicit synchronization.
Q2:

How does CLR allocate memory for value types vs reference types?

Expert

Answer

Value types are stored inline (stack or within objects). Reference types always reside on the heap. Boxing allocates objects with headers and method table pointers. Inline struct fields avoid indirection, improving cache locality and performance.

Quick Summary: Value types (int, struct) on the stack are allocated in the current method's stack frame — no GC overhead. On the heap (as fields of a class), they're embedded directly in the object. Reference types always go on the managed heap with a GC header. Value types in arrays/objects are inlined; reference types store a pointer.
Q3:

Describe the internal layout of a .NET object.

Expert

Answer

A .NET object layout includes: Method Table pointer, Sync Block index, aligned fields with padding, and metadata references. The Method Table stores vtable, type hierarchy, and GC tracking info.

Quick Summary: Every .NET object has an object header (8 bytes on 64-bit): a SyncBlock index (for lock and GetHashCode) and a Method Table pointer (links to type info, vtable for virtual dispatch). After the header come the object's fields. This overhead means even a small object costs more memory than its fields alone.
Q4:

Explain GC Generations, LOH, and POH behavior.

Expert

Answer

Gen0 handles short-lived objects, Gen1 buffers promotions, and Gen2 manages long-lived objects. LOH (>=85 KB) is collected only during full GC. POH isolates pinned objects to avoid LOH fragmentation. GC modes include server, workstation, and background.

Quick Summary: Gen0 collects short-lived objects — collected frequently, fast. Gen1 is a buffer between Gen0 and Gen2. Gen2 collects long-lived objects — full GC, expensive. LOH (Large Object Heap, objects >= 85KB) collects during Gen2 and isn't compacted by default (fragmentation risk). POH (Pinned Object Heap, .NET 5+) stores objects pinned for native interop safely.
Q5:

What is Tiered Compilation in .NET and why is it important?

Expert

Answer

Tier 0 generates fast unoptimized code for quick startup; Tier 1 recompiles hot paths with optimizations. Tiered PGO enhances long-running performance. Together they balance startup speed and runtime throughput.

Quick Summary: Tiered compilation runs code at Tier 0 (minimal optimization, fast startup) first. After a method is called N times (hot path), it's recompiled at Tier 1 with full JIT optimizations. With PGO (Profile-Guided Optimization) in .NET 6+, Tier 1 uses actual runtime profile data to make even better optimization decisions.
Q6:

Difference between lock, Monitor, Mutex, Semaphore, SpinLock, and RWLockSlim.

Expert

Answer

lock/Monitor for lightweight mutual exclusion; Mutex for cross-process locks; Semaphore limits concurrency; SpinLock for low-contention busy waits; ReaderWriterLockSlim for read-heavy workloads. Each has different contention and fairness characteristics.

Quick Summary: lock/Monitor: process-local, reentrant, lightweight. Mutex: cross-process named mutex, heavier. Semaphore: limits N concurrent threads. SpinLock: busy-waits instead of blocking — zero context-switch overhead for very short critical sections. ReaderWriterLockSlim: multiple concurrent readers, exclusive write access — great for read-heavy shared data.
Q7:

How does async/await work internally?

Expert

Answer

Compiler rewrites async methods into state machines. Await posts continuations to SynchronizationContext or thread pool. Tasks represent operations and manage completion, cancellation, and exceptions. Avoid context capture for performance.

Quick Summary: The compiler transforms an async method into a state machine struct. Each await point is a state. When the awaited task completes, the continuation is posted to the captured SynchronizationContext (or thread pool). The thread is released during the await — no blocking. The async state machine struct avoids heap allocation for common cases.
Q8:

Explain String Interning and its risks.

Expert

Answer

Intern pool stores unique literals for lifetime of the process. Reduces duplication but increases memory pressure. Interning user input is dangerous due to unbounded growth.

Quick Summary: String interning stores one shared instance per unique string literal. string.Intern() can intern any string. Interned strings live in a process-wide pool and are never GC'd. Risk: interning dynamic strings (user input, random data) fills the intern pool permanently, causing memory growth that GC can't reclaim.
Q9:

Difference between Reflection, Reflection.Emit, Expression Trees, and Source Generators.

Expert

Answer

  • Reflection: runtime inspection, slow
  • Emit: dynamic IL generation
  • Expression Trees: compile to delegates for fast execution
  • Source Generators: compile-time code generation using Roslyn
Quick Summary: Reflection: runtime type inspection and invocation — slow, bypasses compile-time safety. Reflection.Emit: generates IL at runtime — used in proxies and ORMs. Expression Trees: represent code as data structures, compiled to delegates — used in LINQ providers. Source Generators: generate code at compile time — zero runtime cost, the modern preferred approach.
Q10:

How does .NET ThreadPool schedule work?

Expert

Answer

ThreadPool uses global/per-thread queues, work stealing, and hill-climbing to adjust worker counts. Long-running tasks should use LongRunning to avoid blocking worker threads.

Quick Summary: The ThreadPool maintains a global work-stealing queue and per-thread local queues. Threads steal from each other when idle. A hill-climbing algorithm adjusts thread count based on throughput (measured every ~15ms). For long-running CPU work (> ~500ms), use TaskCreationOptions.LongRunning to get a dedicated non-pool thread.
Q11:

Explain delegate types and internal representation.

Expert

Answer

Delegates may be open/closed static or instance methods. Multicast delegates contain invocation lists. Closures create hidden classes. Invocation chain length affects performance.

Quick Summary: A delegate stores a method pointer and a target instance (null for static methods). Lambdas that capture variables create a hidden compiler-generated closure class. Multicast delegates maintain an array of delegate instances — invocation iterates the array. The Invoke method calls them in order; exceptions in one delegate don't stop others unless you handle it manually.
Q12:

What is the role of Roslyn?

Expert

Answer

Roslyn provides syntax trees, semantic models, analyzers, refactoring, and code generation. It is compiler-as-a-service, powering tooling and source generators.

Quick Summary: Roslyn is the C# and VB compiler exposed as an API. It provides parse trees, semantic models, diagnostics, and code fixes that power Visual Studio IntelliSense, analyzers, and code generators. Source Generators hook into Roslyn to inspect your code at compile time and generate additional C# files before compilation finishes.
Q13:

Explain covariance and contravariance deeply.

Expert

Answer

Covariance (out) allows substituting derived for base. Contravariance (in) allows substituting base for derived. Applies to delegates, interfaces, and arrays (with runtime checks). Enables type-flexible APIs safely.

Quick Summary: Covariance (out T on IEnumerable): IEnumerable is assignable to IEnumerable — safe for read-only scenarios. Contravariance (in T on Action): Action is assignable to Action — safe for write-only scenarios. Applies to interfaces and delegates, not concrete classes. The in/out keywords express the variance direction.
Q14:

What are AppDomains and why removed in .NET Core?

Expert

Answer

AppDomains offered isolation and unloading but were heavy and complex. .NET Core replaced them with AssemblyLoadContext for lighter, flexible loading and unloading models.

Quick Summary: AppDomains in .NET Framework provided process-level isolation for loading and unloading assemblies independently. They were complex, platform-specific (Windows only), and rarely used correctly. .NET Core removed them for simplicity and cross-platform support. AssemblyLoadContext is the lightweight replacement for dynamic, isolated assembly loading in plugins.
Q15:

Explain IL, CIL, and MSIL.

Expert

Answer

IL, CIL, and MSIL refer to the same CPU-independent intermediate instruction set executed by the CLR before JIT compilation.

Quick Summary: IL (Intermediate Language), CIL (Common Intermediate Language), and MSIL (Microsoft IL) all refer to the same thing: the platform-independent bytecode that .NET compilers produce. CIL is the official ECMA standard name. MSIL is the old Microsoft name. IL is the everyday shorthand. The JIT converts IL to native machine code at runtime.
Q16:

Explain the CLR exception handling flow.

Expert

Answer

Exception handling involves stack unwinding, handler search, first/second chance exceptions, managed/unmanaged boundary transitions, and finally/fault execution. Throwing is expensive due to metadata lookup and stack analysis.

Quick Summary: When an exception is thrown, the CLR searches the call stack for a matching catch handler (walking up frame by frame). Finally blocks always run during unwinding. Unhandled exceptions terminate the process. First-chance exceptions are raised before any handler — useful for debuggers. The exception object captures the stack trace at throw time.
Q17:

What is metadata in assemblies and how does CLR use it?

Expert

Answer

Metadata includes type, method, field tables, attributes, signatures, and constraints. CLR uses it for JIT compilation, reflection, verification, and type loading.

Quick Summary: Assembly metadata describes every type, method, field, parameter, attribute, and generic constraint in the assembly. The CLR reads this during type loading to understand layout, method resolution, and reflection queries. It makes .NET assemblies self-describing — no header files needed, and tools like Visual Studio's IntelliSense read metadata at design time.
Q18:

Key performance traps senior engineers must avoid.

Expert

Answer

  • Excess allocations
  • Boxing
  • Heavy LINQ in hot paths
  • Lambdas capturing hidden allocations
  • Blocking async
  • Excessive locking
  • Exceptions for flow control
Quick Summary: Senior .NET performance traps: boxing value types in collections, sync-over-async (blocking .Result or .Wait()), capturing too-large closures in LINQ or lambdas, using string concatenation instead of StringBuilder in loops, large LOH allocations, excessive reflection, and not using Span or Memory for high-throughput buffer operations.
Q19:

What is ASP.NET Core and why was it created?

Expert

Answer

ASP.NET Core is a cross-platform, high-performance framework built to replace legacy ASP.NET limitations. It introduces modularity, DI, unified hosting, and lightweight request pipeline optimized for cloud and microservices.

Quick Summary: ASP.NET Core is the cross-platform, open-source rewrite of ASP.NET. It runs on Linux, macOS, and Windows. It's built for the cloud era — containerization-friendly, performance-optimized, and modular. The framework moved from IIS-coupled, Windows-only roots to a portable, middleware-based architecture with first-class support for Docker and microservices.
Q20:

Explain Middleware and the Request Pipeline.

Expert

Answer

Middleware executes sequentially and may process, modify, short-circuit, or delegate requests. Enables flexible, modular pipelines replacing old HttpModules/Handlers.

Quick Summary: The request pipeline is a chain of delegates (middleware). Each middleware can inspect and modify the HttpContext, call next() to continue, or short-circuit. Order is defined in Program.cs. The pipeline processes requests forward and responses backward — response-writing middleware sees the response after all downstream middleware have run.
Q21:

Why does middleware order matter?

Expert

Answer

Middleware runs exactly in registration order. Incorrect ordering breaks authentication, routing, exception handling, and static file behavior.

Quick Summary: Each middleware wraps subsequent ones. Wrong order causes real bugs: placing authorization before authentication means HttpContext.User is empty at auth check time. Placing routing after your endpoint handler means routes never match. Exception handling must wrap everything — placing it last means unhandled exceptions from early middleware aren't caught.
Q22:

Why is DI built-in to ASP.NET Core?

Expert

Answer

ASP.NET Core is designed around DI for clean structure, testability, separation of concerns, and consistent service creation across middleware, controllers, and background services.

Quick Summary: Built-in DI removes the need to manually instantiate services, manage their lifetimes, or pass dependencies through constructors manually. The container injects dependencies automatically. This enables: loose coupling (program to interfaces), testability (inject mocks), lifecycle management (scoped/transient/singleton), and framework integration (controllers get services injected automatically).
Q23:

Explain the ASP.NET Core configuration system.

Expert

Answer

Configuration is layered: appsettings.json, environment configs, secrets, environment variables, command-line args. Supports reload-on-change and strongly typed bindings.

Quick Summary: Multiple configuration sources layer together: JSON files, environment variables, User Secrets, Azure Key Vault. Values from later sources override earlier ones. IConfiguration provides the unified API. The system is composable — you can add custom providers for any config source. Strongly-typed options classes (IOptions) are the recommended way to consume configuration.
Q24:

What are IOptions, IOptionsSnapshot, and IOptionsMonitor?

Expert

Answer

IOptions: singleton read. Snapshot: per-request reload. Monitor: real-time change notifications for long-running services.

Quick Summary: Three interfaces for different needs: IOptions reads config once, never changes — use in singletons for static config. IOptionsSnapshot re-reads per request — use in scoped/transient services that need fresh config on every request. IOptionsMonitor reacts to live changes — use when the app must respond to config changes without restarting.
Q25:

What is Routing in ASP.NET Core?

Expert

Answer

Endpoint Routing maps URLs to endpoints with early matching, metadata support, and optimized execution. Supports attribute and conventional routes.

Quick Summary: Routing matches incoming requests to endpoints. Endpoint Routing (current model) matches routes in UseRouting() and executes them in UseEndpoints(). Convention routing: MapControllerRoute with a template. Attribute routing: [HttpGet("api/users/{id}")] on each action. Route parameters can have constraints: {id:int}, {name:alpha:length(5)}.
Q26:

How do Dependency Injection scopes affect Razor Views, Controllers, and Middleware differently?

Expert

Answer

Controllers use scoped services per request, Razor Views should avoid heavy scoped logic, and Middleware must avoid scoped services because middleware is created once and would turn scoped dependencies into singletons.

This scope behavior prevents state leakage, concurrency bugs, and lifecycle misalignment across pipeline components.

Quick Summary: Controllers receive Scoped services — fresh per request. Middleware registered as singletons (inline lambdas) must not capture Scoped services — inject them via IServiceProvider.CreateScope() instead. Razor Views can inject services via @inject and receive Scoped services correctly. The key rule: never store a Scoped service in a Singleton field.
Q27:

How does the Razor Compilation System work at runtime and what optimizations exist?

Expert

Answer

Razor parses .cshtml into C# classes, compiles them into temporary assemblies, and caches them. Runtime compilation is slower but flexible; precompiled views dramatically improve startup performance and CPU usage.

Quick Summary: In production, Razor views are precompiled by Roslyn at publish time — no .cshtml files needed. In development, Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation watches files and recompiles on change. The generated RazorPage class has an Execute() method that writes HTML chunks to a TextWriter using string pooling to minimize allocations.
Q28:

How does the View Engine pipeline work and how do multiple engines coexist?

Expert

Answer

View engines search for views, parse templates, generate executable output, and render HTML. Multiple engines coexist by being queried in order; the first match handles rendering.

Quick Summary: The view engine pipeline calls IViewEngine.FindView() on registered engines in order. RazorViewEngine searches by convention (/Views/{Controller}/{Action}.cshtml). You can register custom engines (Markdown, Handlebars) before or after Razor in MvcOptions.ViewEngines. The first engine that finds the view wins.
Q29:

What are Application Parts in ASP.NET Core and why are they important?

Expert

Answer

Application Parts let MVC discover controllers, views, pages, and Tag Helpers from assemblies or Razor Class Libraries. They enable modular architectures, plugin systems, and dynamic feature loading.

Quick Summary: Application Parts are registered with ApplicationPartManager and contribute controllers, views, tag helpers, and other MVC components to the app. By default, the entry assembly is an Application Part. Add external assemblies to load controllers from plugins: builder.Services.AddControllersFromApplication(typeof(PluginAssembly).Assembly).
Q30:

Why does ASP.NET Core enforce asynchronous patterns everywhere?

Expert

Answer

Async frees threads during I/O waits, prevents thread starvation, improves scalability, and avoids deadlocks. ASP.NET Core is designed for async performance from MVC to Razor to middleware.

Quick Summary: ASP.NET Core is built to handle thousands of concurrent requests per server. Synchronous I/O (blocking database calls, synchronous file reads) wastes threads waiting. Async I/O releases the thread to handle other requests. The thread pool scales to match load; blocking negates this. async Task everywhere is the correct default for all I/O-bound work.
Q31:

What is the role of Metadata Providers in MVC?

Expert

Answer

Metadata Providers supply display names, validation rules, formatting, and UI hints. They influence model binding, validation, scaffolding, and Tag Helpers, ensuring consistent UI rules across apps.

Quick Summary: Metadata Providers (IDisplayMetadataProvider, IValidationMetadataProvider) feed metadata about model properties to the view rendering pipeline — display names, data type hints, validation error messages. Tag helpers like asp-for use this metadata to generate correct HTML attributes. Implement a custom provider to centralize display/validation metadata outside DataAnnotations.
Q32:

What is the role of the Application Model in MVC and why do enterprises customize it?

Expert

Answer

The Application Model describes controllers, actions, parameters, routes, and filters. Enterprises customize it to enforce conventions, apply automatic routing, add versioning, or inject policies globally.

Quick Summary: The Application Model is an in-memory representation of all controllers, actions, and their attributes built at startup. IApplicationModelConvention implementations modify this model globally — add filters to all controllers, normalize route conventions, apply naming policies. This avoids repeating attributes across all controllers and enables reusable cross-cutting conventions.
Q33:

Why are View Components preferred over Partial Views in advanced architectures?

Expert

Answer

View Components include logic, support DI, run independently of controllers, and provide isolated UI modules. They are ideal for dynamic widgets, reusable dashboard blocks, and modular UI design.

Quick Summary: ViewComponents have InvokeAsync() with full DI support — they can query databases, consume services, run async logic. Partial Views just render a template with a passed model — no independent logic. ViewComponents are independently testable, reusable across different pages, and encapsulate their own data requirements. Use them for notification counts, sidebar widgets, shopping carts.
Q34:

How does ASP.NET Core protect against request body overconsumption?

Expert

Answer

ASP.NET Core enforces limits on request size, form size, field count, and upload sizes. It aborts oversized requests and streams bodies to prevent memory exhaustion.

Quick Summary: MaxRequestBodySize in Kestrel (default 30MB) and IIS limits prevent clients from sending oversized bodies. Per-action overrides: [RequestSizeLimit(bytes)] increases or [DisableRequestSizeLimit] removes the limit for specific actions. The body is also limited to not be buffered unless you explicitly enable request body buffering (EnableBuffering()).
Q35:

Why do large enterprises rely on Razor Class Libraries (RCLs)?

Expert

Answer

RCLs consolidate shared UI components, layouts, Tag Helpers, and styles across multiple applications. They support modular deployment, branding consistency, and reusable UI patterns.

Quick Summary: RCL packages Razor views, pages, components, and static files into a NuGet. The host app consumes the RCL and gets all its views automatically via the application part system. This enables shared UI — the same admin dashboard, the same login page — across 50 internal apps without copying code. Update the NuGet version to push UI changes everywhere.
Q36:

How does the Model Validation Pipeline work?

Expert

Answer

After model binding, validation attributes run, errors populate the ModelState dictionary, and filters may stop execution. This ensures invalid data never reaches application logic.

Quick Summary: After model binding: run DataAnnotation validators → run IValidatableObject.Validate() (cross-property rules) → run custom ValidationAttribute subclasses → populate ModelState. If FluentValidation is registered, its validators run instead of (or alongside) DataAnnotations. The pipeline is controlled via IObjectModelValidator. Check ModelState.IsValid before proceeding.
Q37:

What are Filters in MVC and how is their execution ordered?

Expert

Answer

Execution order: Authorization ? Resource ? Action ? Exception ? Result. Filters wrap different pipeline stages and are used for cross-cutting concerns like logging, auth, and caching.

Quick Summary: Filter execution order: Authorization filters (can short-circuit) → Resource filters (before/after model binding) → Action filters (before/after action execution) → Result filters (around result execution) → Exception filters (catch unhandled exceptions). Within each filter type, Global → Controller → Action scope order applies. IOrderedFilter controls ordering within same scope.
Q38:

What is the difference between Authentication and Authorization in ASP.NET Core?

Expert

Answer

Authentication verifies identity, while Authorization determines access rights. ASP.NET Core uses modular auth handlers and policy-based authorization for flexible security design.

Quick Summary: Authentication identifies who the user is — reads the cookie or JWT, validates it, and populates HttpContext.User with claims. Authorization decides what they can do — reads HttpContext.User's claims/roles against [Authorize] policies and requirements. Auth must always complete before authorization runs. A user can be authenticated but not authorized for a specific resource.
Q39:

How does Razor Layout Hierarchy work and how are nested layouts resolved?

Expert

Answer

Razor resolves the requested view, then the inner layout, then outer layouts, merging sections at each level. This supports multi-layered branding and UI composition.

Quick Summary: Each view declares Layout = "_Layout" (or inherits from _ViewStart.cshtml). Nested layouts: child layout sets its Layout to a parent layout. At render time, Razor renders the innermost view first, then wraps each layout around it. @RenderBody() injects the child's output. @RenderSection("Scripts", required: false) injects optional named sections from child views.
Q40:

How does ASP.NET Core support Localization and Globalization?

Expert

Answer

ASP.NET Core uses culture providers, resource-based translations, and formatting rules for dates and numbers. It detects culture via headers, route values, cookies, or query strings.

Quick Summary: UseRequestLocalization() middleware reads culture from URL segment, cookie, or Accept-Language header and sets CultureInfo.CurrentCulture. Resource files (.resx) store translated strings. IStringLocalizer injects into controllers/views to look up translations. Format: Resources/Controllers.HomeController.fr.resx for French translations of HomeController strings.

Curated Sets for .NET Core

No curated sets yet. Group questions into collections from the admin panel to feature them here.

Ready to level up? Start Practice