.
NET Core Interview Questions
1. What are the key differences between .NET Core and .NET Framework?
Detailed Answer:
Explanation:
.NET Core (now .NET) and .NET Framework are Microsoft’s runtime environments, but
they differ in design, scope, and usage.
1. Cross-Platform:
o .NET Core: Runs on Windows, macOS, and Linux.
o .NET Framework: Windows-only.
2. Architecture:
o .NET Core: Modular, open-source, lightweight, built for cloud and
microservices.
o .NET Framework: Monolithic, closed-source, designed for Windows
desktop/server apps.
3. Versioning:
o .NET Core: Unified versioning (e.g., .NET 6), frequent releases.
o .NET Framework: Tied to Windows (e.g., 4.8), slower updates.
4. Performance:
o .NET Core: Optimized for speed (e.g., Span<T>, Kestrel).
o .NET Framework: Slower due to legacy overhead.
5. API Support:
o .NET Core: Subset of APIs, modernized (e.g., no Windows Forms).
o .NET Framework: Broader legacy support (e.g., WCF server-side).
Practical Insight:
I migrated a legacy .NET Framework app to .NET Core to deploy on Linux Docker
containers, reducing hosting costs by 40% and leveraging cross-platform CI/CD
pipelines.
Additional Considerations:
Migration: Assess API compatibility before moving.
EOL: .NET Framework 4.8 is the last version; .NET Core is the future.
Leadership Role: I’d guide teams to adopt .NET Core for new projects,
planning phased migrations for legacy systems.
2. Explain the [Link] Core request pipeline and middleware.
Detailed Answer:
Explanation:
The [Link] Core request pipeline processes HTTP requests via a sequence of
middleware components, configured in Startup or Program.
1. Core Concept:
o Middleware are classes/functions that handle requests and responses.
o Executed in order of registration, forming a chain (request in, response
out).
o Each component can short-circuit or pass to the next.
2. Key Middleware:
o UseRouting: Matches endpoints.
o UseAuthentication: Validates user identity.
o UseAuthorization: Checks permissions.
o UseEndpoints: Executes controllers or Razor Pages.
3. Configuration:
o Defined in Configure method ([Link] 6) or [Link] (.NET 6+).
o Uses IApplicationBuilder to add middleware.
Practical Insight:
In an API, I configured middleware to log requests, authenticate via JWT, and handle
errors, ensuring a robust pipeline that processed 10K requests/sec with minimal
latency.
Coding Example (.NET 6):
csharp
CollapseWrapCopy
var builder = [Link](args);
[Link]();
var app = [Link]();
[Link]();
[Link]();
[Link]();
[Link](async (context, next) =>
{
[Link]($"Request: {[Link]}");
await next(context); // Pass to next middleware
});
[Link]();
[Link]();
Additional Considerations:
Order Matters: Authentication must precede Authorization.
Custom Middleware: Write reusable components for cross-cutting concerns.
Leadership Role: I’d design pipelines for scalability, reviewing order and
performance impacts.
3. How does Dependency Injection (DI) work in .NET Core?
Detailed Answer:
Explanation:
Dependency Injection (DI) in .NET Core manages object creation and lifetime,
promoting loose coupling and testability.
1. Core Concept:
o Dependencies are injected via constructors or properties.
o Built-in DI container (IServiceProvider) resolves services.
2. Service Registration:
o Configured in [Link] or [Link].
o Lifetimes: Transient (new instance per request), Scoped (per HTTP
request), Singleton (shared instance).
3. How It Works:
o Services are registered with Add{Type} methods (e.g., AddScoped).
o Container resolves dependencies recursively at runtime.
Practical Insight:
In a microservice, I registered a DbContext as Scoped and a ILogger as Singleton,
ensuring efficient resource use and consistent logging across requests.
Coding Example:
csharp
CollapseWrapCopy
public interface IMyService { void DoWork(); }
public class MyService : IMyService { public void DoWork() =>
[Link]("Working"); }
var builder = [Link](args);
[Link]<IMyService, MyService>(); // Register service
var app = [Link]();
[Link]("/", (IMyService service) => // Injected here
{
[Link]();
return "Done";
});
[Link]();
Additional Considerations:
Third-Party Containers: Replace with Autofac or SimpleInjector if needed.
Lifetime Pitfalls: Avoid Scoped in Singleton to prevent captive dependencies.
Leadership Role: I’d enforce DI patterns, review lifetime choices, and train on
testability benefits.
4. What are the different hosting models available in .NET Core?
Detailed Answer:
Explanation:
.NET Core supports multiple hosting models for running applications, each suited to
different scenarios.
1. In-Process Hosting:
o Runs within IIS or another web server’s process.
o Uses [Link].
o Benefits: Leverages IIS features (e.g., process management).
2. Out-of-Process Hosting:
o Runs as a separate process (e.g., Kestrel), proxied by a web server (e.g.,
IIS, Nginx).
o Default for standalone apps or Docker.
o Benefits: Isolation, cross-platform compatibility.
3. Console Hosting:
o Runs as a console app without a web server (e.g., worker services).
o Uses [Link].
o Benefits: Simple, lightweight for background tasks.
Practical Insight:
For a web API, I used Out-of-Process with Kestrel behind Nginx in Docker for scalability,
switching to In-Process with IIS for a legacy Windows deployment to reuse existing
infrastructure.
Coding Example (Out-of-Process):
csharp
CollapseWrapCopy
var builder = [Link](args);
[Link]();
var app = [Link]();
[Link]("/", () => "Hello from Kestrel");
[Link]();
Additional Considerations:
Performance: In-Process is slightly faster due to no proxying.
Deployment: Out-of-Process suits cloud-native setups.
Leadership Role: I’d select models based on environment, ensuring team
understands trade-offs.
5. How do you implement API versioning in .NET Core Web API?
Detailed Answer:
Explanation:
API versioning in .NET Core ensures backward compatibility as APIs evolve, using
attributes, headers, or query strings.
1. Approaches:
o URL Path: /api/v1/users (most common).
o Query String: /api/users?api-version=1.0.
o Header: Custom header (e.g., X-API-Version: 1.0).
2. Implementation:
o Use [Link] NuGet package.
o Configure in Startup or [Link].
o Apply [ApiVersion] to controllers.
Practical Insight:
In a customer API, I implemented URL-based versioning (/v1/customers,
/v2/customers) to introduce breaking changes (e.g., new fields), maintaining v1 for
existing clients.
Coding Example:
csharp
CollapseWrapCopy
var builder = [Link](args);
[Link]();
[Link](options =>
{
[Link] = true;
[Link] = new ApiVersion(1, 0);
[Link] = true; // Adds version header
});
var app = [Link]();
[Link]();
[Link]();
[Link]();
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("1.0")]
public class CustomersController : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok("Version 1");
}
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("2.0")]
public class CustomersV2Controller : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok("Version 2");
}
Additional Considerations:
Deprecation: Use Deprecated attribute to phase out old versions.
Clients: Document versions clearly.
Leadership Role: I’d enforce versioning standards, review for consistency, and
plan sunset strategies.
6. What are the benefits of using Kestrel as a web server?
Detailed Answer:
Explanation:
Kestrel is .NET Core’s cross-platform, high-performance web server, designed for
[Link] Core apps.
1. Benefits:
o Cross-Platform: Runs on Windows, Linux, macOS.
o Performance: Lightweight, optimized for throughput (e.g., non-blocking
I/O).
o Flexibility: Works standalone or behind reverse proxies (e.g., Nginx).
o Extensibility: Supports custom middleware and HTTPS.
o Open-Source: Community-driven improvements.
Practical Insight:
In a microservices architecture, I used Kestrel in Docker containers behind Nginx,
achieving 50K requests/sec with low latency, leveraging its async capabilities over
IIS’s heavier footprint.
Additional Considerations:
Proxying: Pair with Nginx/IIS for load balancing and SSL termination.
Limitations: Lacks advanced features (e.g., IIS’s Windows auth); use a proxy
for those.
Leadership Role: I’d advocate Kestrel for modern apps, ensuring proper proxy
setup and performance tuning.
7. How do you handle exceptions globally in .NET Core?
Detailed Answer:
Explanation:
Global exception handling in .NET Core centralizes error management using
middleware, ensuring consistent responses.
1. Approach:
o Use UseExceptionHandler middleware to catch unhandled exceptions.
o Return standardized error responses (e.g., JSON with status codes).
2. Implementation:
o Configure in [Link].
o Log exceptions and customize responses.
Practical Insight:
In an API, I implemented global handling to log errors to Application Insights and
return 500s with a correlation ID, reducing debugging time by 50% during outages.
Coding Example:
csharp
CollapseWrapCopy
var builder = [Link](args);
[Link]();
var app = [Link]();
[Link](errorApp =>
{
[Link](async context =>
{
var exception = [Link]<IExceptionHandlerFeature>()?.Error;
[Link]($"Error: {exception?.Message}"); // Log
[Link] = 500;
await [Link](new { error = "Internal Server
Error" });
});
});
[Link]();
[Link]();
[Link]();
[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
[HttpGet]
public IActionResult Get() => throw new Exception("Test error");
}
Additional Considerations:
Custom Middleware: Extend for specific exception types (e.g.,
NotFoundException).
Logging: Integrate with ILogger or external tools.
Leadership Role: I’d enforce global handling, review for consistency, and
ensure proper logging.
8. How does .NET Core implement authentication and authorization?
Detailed Answer:
Explanation:
.NET Core provides a robust framework for authentication (identity) and authorization
(permissions) via middleware and policies.
1. Authentication:
o Middleware: UseAuthentication validates credentials (e.g., JWT, cookies).
o Schemes: JWT, OAuth, Identity.
o Sets [Link].
2. Authorization:
o Middleware: UseAuthorization enforces access rules.
o Attributes: [Authorize], policies (e.g., RequireRole).
o Checks ClaimsPrincipal from authentication.
Practical Insight:
In a multi-tenant API, I used JWT authentication with role-based authorization,
restricting endpoints to admins, validated via policies for fine-grained control.
Coding Example:
csharp
CollapseWrapCopy
var builder = [Link](args);
[Link]();
[Link]("Bearer")
.AddJwtBearer(options =>
{
[Link] = new()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "issuer",
ValidAudience = "audience",
IssuerSigningKey = new
SymmetricSecurityKey([Link]("secret-key-long-enough"))
};
});
[Link](options =>
{
[Link]("AdminOnly", policy => [Link]("Admin"));
});
var app = [Link]();
[Link]();
[Link]();
[Link]();
[Link]();
[Link]();
[ApiController]
[Route("[controller]")]
[Authorize(Policy = "AdminOnly")]
public class AdminController : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok("Admin access granted");
}
Additional Considerations:
Scalability: Use external providers (e.g., IdentityServer) for large systems.
Security: Rotate keys, use HTTPS.
Leadership Role: I’d implement secure auth flows, review policies, and enforce
best practices.
9. Explain the importance of IHostedService in .NET Core applications.
Detailed Answer:
Explanation:
IHostedService runs long-running background tasks within a .NET Core app, managed
by the host lifecycle.
1. Core Concept:
o Implements StartAsync and StopAsync for startup/shutdown logic.
o Registered with AddHostedService.
o Runs alongside web or console apps.
2. Importance:
o Background Tasks: Executes recurring jobs (e.g., timers, queues).
o Graceful Shutdown: Ensures cleanup on app stop.
o Host Integration: Leverages DI and configuration.
Practical Insight:
In a notification service, I used IHostedService to poll a queue every 5 seconds,
sending emails asynchronously, ensuring reliable operation without blocking the web
pipeline.
Coding Example:
csharp
CollapseWrapCopy
public class MyBackgroundService : IHostedService, IDisposable
{
private Timer _timer;
public Task StartAsync(CancellationToken cancellationToken)
{
_timer = new Timer(DoWork, null, [Link], [Link](5));
return [Link];
}
private void DoWork(object state) => [Link]("Background task
running");
public Task StopAsync(CancellationToken cancellationToken)
{
_timer?.Change([Link], 0);
return [Link];
}
public void Dispose() => _timer?.Dispose();
}
var builder = [Link](args)
.ConfigureServices(services =>
[Link]<MyBackgroundService>());
var host = [Link]();
await [Link]();
Additional Considerations:
Alternatives: Use BackgroundService for simpler inheritance.
Scalability: Offload heavy tasks to worker services.
Leadership Role: I’d use IHostedService for app-specific tasks, ensuring team
manages lifetimes properly.
10. How do you optimize performance in a .NET Core Web API?
Detailed Answer:
Explanation:
Optimizing a .NET Core Web API improves throughput, latency, and resource usage
through targeted techniques.
1. Techniques:
o Async/Await: Use for I/O-bound operations (e.g., DB calls).
o Caching: Implement in-memory (IMemoryCache) or distributed (Redis)
caching.
o Response Compression: Enable Gzip/Brotli via middleware.
o Minimize Allocations: Use Span<T>/Memory<T> for string operations.
o Load Balancing: Deploy behind a reverse proxy (e.g., Nginx).
2. Monitoring:
o Profile with tools like Application Insights or BenchmarkDotNet.
o Optimize hot paths identified in production.
Practical Insight:
In a high-traffic API, I reduced latency from 200ms to 50ms by caching frequent
queries, using async controllers, and enabling compression, validated via load tests.
Coding Example:
csharp
CollapseWrapCopy
var builder = [Link](args);
[Link]();
[Link](options => [Link] =
true);
[Link]();
var app = [Link]();
[Link]();
[Link]();
[Link]();
[ApiController]
[Route("[controller]")]
public class DataController : ControllerBase
{
private readonly IMemoryCache _cache;
public DataController(IMemoryCache cache) => _cache = cache;
[HttpGet]
public async Task<IActionResult> GetAsync()
{
if (!_cache.TryGetValue("data", out string data))
{
data = await [Link](() => "Expensive data"); // Simulate async work
_cache.Set("data", data, [Link](5));
}
return Ok(data);
}
}
Additional Considerations:
Scalability: Use minimal APIs for lightweight endpoints.
Metrics: Track response times and GC pressure.
Leadership Role: I’d enforce optimization best practices, review performance
metrics, and plan scalability tests.
11. What are gRPC services, and how do they compare to REST APIs?
Detailed Answer:
Explanation:
gRPC is a high-performance RPC framework using HTTP/2 and Protocol Buffers
(protobuf), contrasting with REST’s HTTP/1.1 and JSON.
1. gRPC Overview:
o Protocol: HTTP/2 with binary serialization (protobuf).
o Features: Bidirectional streaming, strong typing, code generation.
o Use Case: Microservices, low-latency systems.
2. Comparison to REST:
o Performance: gRPC is faster (binary vs. text, multiplexing).
o Payload: Smaller (protobuf vs. JSON).
o Streaming: Native support vs. REST’s limited WebSocket reliance.
o Ease of Use: REST is simpler; gRPC requires schema definition.
o Browser Support: REST is universal; gRPC needs proxies (e.g., gRPC-
Web).
Practical Insight:
In a telemetry system, I used gRPC for device-to-server communication, reducing
bandwidth by 70% and latency by 50% compared to REST, leveraging streaming for
real-time updates.
Coding Example (gRPC Server):
proto
CollapseWrapCopy
// proto file: [Link]
syntax = "proto3";
service Telemetry {
rpc SendData (DataRequest) returns (DataResponse);
}
message DataRequest { string value = 1; }
message DataResponse { string status = 1; }
csharp
CollapseWrapCopy
public class TelemetryService : [Link]
{
public override Task<DataResponse> SendData(DataRequest request,
ServerCallContext context)
{
return [Link](new DataResponse { Status = $"Received:
{[Link]}" });
}
}
var builder = [Link](args);
[Link]();
var app = [Link]();
[Link]<TelemetryService>();
[Link]();
Additional Considerations:
Learning Curve: Requires protobuf knowledge.
Interoperability: REST is more widely adopted.
Leadership Role: I’d use gRPC for internal services, ensuring team training
and REST for public APIs.
12. How does .NET Core implement background tasks and worker services?
Detailed Answer:
Explanation:
.NET Core supports background tasks via IHostedService and dedicated Worker
Services for long-running processes.
1. Background Tasks:
o Use IHostedService or BackgroundService within a web app.
o Examples: Timers, queue polling.
2. Worker Services:
o Standalone apps using [Link].
o Ideal for microservices or cron-like tasks.
Practical Insight:
In a payment processor, I implemented a Worker Service to retry failed transactions
every minute, isolating it from the web API for better fault tolerance.
Coding Example (Worker Service):
csharp
CollapseWrapCopy
public class Worker : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (![Link])
{
[Link]("Worker running");
await [Link](1000, stoppingToken);
}
}
}
var builder = [Link](args)
.ConfigureServices(services => [Link]<Worker>());
var host = [Link]();
await [Link]();
Additional Considerations:
Scaling: Deploy workers separately for load distribution.
Monitoring: Use ILogger or external tools.
Leadership Role: I’d architect task separation, review for reliability, and
ensure graceful shutdowns.
13. What is the difference between IConfiguration and IOptions in .NET
Core?
Detailed Answer:
Explanation:
IConfiguration and IOptions manage configuration data in .NET Core, differing in
purpose and usage.
1. IConfiguration:
o Definition: Raw access to configuration sources (e.g., [Link],
env vars).
o Features: Key-value pair lookup (e.g., config["Key"]).
o Use Case: Direct, flexible access.
2. IOptions:
o Definition: Strongly-typed configuration binding with DI.
o Features: Maps config sections to classes (e.g., IOptions<MySettings>).
o Use Case: Structured, injectable settings.
Practical Insight:
In an API, I used IConfiguration for quick feature flags and IOptions to bind database
settings into a DbSettings class, improving type safety and readability.
Coding Example:
csharp
CollapseWrapCopy
public class DbSettings
{
public string ConnectionString { get; set; }
}
var builder = [Link](args);
[Link]<DbSettings>([Link]("DbSettings
"));
[Link]<MyService>();
var app = [Link]();
[Link]("/", (IConfiguration config, IOptions<DbSettings> options) =>
{
var rawValue = config["DbSettings:ConnectionString"]; // IConfiguration
var typedValue = [Link]; // IOptions
return $"Raw: {rawValue}, Typed: {typedValue}";
});
[Link]();
public class MyService
{
public MyService(IOptions<DbSettings> options)
{
[Link]($"Service: {[Link]}");
}
}
// [Link]
{
"DbSettings": {
"ConnectionString": "Server=localhost;Database=test"
}
}
Additional Considerations:
Reloading: Use IOptionsSnapshot for dynamic updates.
Validation: Use IOptions<>.Validate for checks.
Leadership Role: I’d standardize on IOptions for typed configs, reviewing for
consistency.
14. How do you secure sensitive data in [Link]?
Detailed Answer:
Explanation:
Securing sensitive data (e.g., API keys, connection strings) in [Link] involves
externalizing or encrypting it.
1. Techniques:
o User Secrets: Store locally during dev (via [Link]).
o Environment Variables: Override config in production.
o Azure Key Vault: Centralized secret management.
o Encryption: Encrypt sections (custom or third-party).
2. Implementation:
o Use Manage User Secrets in Visual Studio.
o Integrate [Link].
Practical Insight:
In a cloud app, I moved secrets from [Link] to Azure Key Vault, reducing
exposure risks and simplifying key rotation, validated via security audits.
Coding Example (User Secrets):
csharp
CollapseWrapCopy
var builder = [Link](args);
[Link]<Program>();
var app = [Link]();
[Link]("/", (IConfiguration config) =>
{
var secret = config["MySecret"];
return $"Secret: {secret}";
});
[Link]();
// [Link] (via dotnet user-secrets set "MySecret" "value")
{
"MySecret": "value"
}
Additional Considerations:
CI/CD: Inject secrets via pipelines (e.g., GitHub Actions).
Auditing: Track secret access.
Leadership Role: I’d enforce secret management policies, review configs, and
train on secure practices.
15. Explain the Circuit Breaker pattern and how it can be implemented
in .NET Core using Polly.
Detailed Answer:
Explanation:
The Circuit Breaker pattern prevents cascading failures by stopping calls to a failing
service, allowing recovery time.
1. Core Concept:
o States: Closed (normal), Open (blocked), Half-Open (testing).
o Trips to Open after X failures, resets after a timeout.
o Fallbacks handle failures gracefully.
2. Implementation with Polly:
o Polly is a .NET resilience library.
o Use CircuitBreakerPolicy to configure.
Practical Insight:
In a payment API calling an unreliable gateway, I used Polly’s Circuit Breaker to halt
requests after 5 failures, falling back to a retry queue, reducing downtime impact by
80%.
Coding Example:
csharp
CollapseWrapCopy
using Polly;
var builder = [Link](args);
[Link]("PaymentGateway")
.AddPolicyHandler(Policy
.Handle<HttpRequestException>()
.CircuitBreakerAsync(
exceptionsAllowedBeforeBreaking: 5,
durationOfBreak: [Link](30),
onBreak: (ex, timespan) => [Link]($"Circuit broken for
{timespan}"),
onReset: () => [Link]("Circuit reset")
));
var app = [Link]();
[Link]("/", async (IHttpClientFactory clientFactory) =>
{
var client = [Link]("PaymentGateway");
try
{
return await [Link]("[Link]
}
catch (Exception ex)
{
return $"Fallback: {[Link]}";
}
});
[Link]();
Additional Considerations:
Tuning: Adjust thresholds based on service SLAs.
Combining Policies: Pair with Retry or Timeout.
Leadership Role: I’d architect resilient systems with Polly, review policies, and
ensure fallback strategies.