FullStack.
Cafe - Kill Your Tech Interview
FullStack.Cafe - Kill Your Tech Interview
Q1: How can you create your own Scope for a Scoped object in
.NET? ☆☆☆
Topics: .NET Core ASP.NET Dependency Injection
Answer:
Scoped lifetime actually means that within a created “scope” objects will be the same instance. It just so
happens that within .Net Core, it wraps a request within a “scope”, but you can actually create scopes manually.
For example :
Consider:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IMyScopedService, MyScopedService>();
var serviceProvider = services.BuildServiceProvider();
var serviceScopeFactory = serviceProvider.GetRequiredService<IServiceScopeFactory>();
IMyScopedService scopedOne;
IMyScopedService scopedTwo;
using (var scope = serviceScopeFactory.CreateScope())
{
scopedOne = scope.ServiceProvider.GetService<IMyScopedService>();
}
using (var scope = serviceScopeFactory.CreateScope())
{
scopedTwo = scope.ServiceProvider.GetService<IMyScopedService>();
}
Debug.Assert(scopedOne != scopedTwo);
}
In this example, the two scoped objects aren’t the same because created each object within their own scope.
Q2: What are some benefits of using Options Pattern in ASP.NET
Core? ☆☆☆
Topics: .NET Core ASP.NET
Answer:
The options pattern uses classes to provide strongly typed access to groups of related settings. When
configuration settings are isolated by scenario into separate classes, the app adheres to two important software
engineering principles:
The Interface Segregation Principle (ISP) or Encapsulation: Scenarios (classes) that depend on configuration
settings depend only on the configuration settings that they use.
Separation of Concerns: Settings for different parts of the app aren't dependent or coupled to one another.
Q3: What officially replaces WCF in .Net Core? ☆☆☆
Page 1 of 9
FullStack.Cafe - Kill Your Tech Interview
Topics: .NET Core WCF
Answer:
You can use gRPC for hosting web services inside .NET core application.
1. gRPC is a high performance, open-source RPC framework initially developed by Google.
2. The framework is based on a client-server model of remote procedure calls. A client application can directly
call methods on a server application as if it was a local object.
Q4: What is the correct pattern to implement long running
background work in Asp.Net Core? ☆☆☆
Topics: .NET Core ASP.NET
Answer:
You should certainly not use Task.Run / StartNew / LongRunning - that approach has always been wrong.
Note that your long-running work may be shut down at any time, and that's normal. If you need a more
reliable solution, then you should have a separate background system outside of ASP.NET (e.g., Azure
functions / AWS lambdas).
Since .NET Core 2.0, the framework provides a new interface named IHostedService helping you to easily
implement hosted services. Hosted Services are services/logic that you host within your
host/application/microservice. The IHostedService background task execution is coordinated with the
lifetime of the application. When you register an IHostedService , .NET will call the StartAsync() and
StopAsync() methods of your IHostedService type during application start and stop respectively.
Q5: Explain the use of BackgroundService class in Asp.Net Core?
☆☆☆
Topics: .NET Core ASP.NET
Answer:
Since .NET Core 2.0, the framework provides a new interface named IHostedService helping you to easily
implement hosted services. The basic idea is that you can register multiple background tasks (hosted services)
Page 2 of 9
FullStack.Cafe - Kill Your Tech Interview
that run in the background while your web host or host is running.
Since most background tasks will have similar needs in regard to the cancellation tokens management and other
typical operations, there is a convenient abstract base class you can derive from, named BackgroundService
(available since .NET Core 2.1).
Consider the following simplified code which is polling a database and publishing integration events into the
Event Bus when needed.
public class GracePeriodManagerService : BackgroundService
{
private readonly ILogger<GracePeriodManagerService> _logger;
private readonly OrderingBackgroundSettings _settings;
private readonly IEventBus _eventBus;
public GracePeriodManagerService(IOptions<OrderingBackgroundSettings> settings,
IEventBus eventBus,
ILogger<GracePeriodManagerService> logger)
{
// Constructor's parameters validations...
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogDebug($"GracePeriodManagerService is starting.");
stoppingToken.Register(() =>
_logger.LogDebug($" GracePeriod background task is stopping."));
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogDebug($"GracePeriod task doing background work.");
// This eShopOnContainers method is querying a database table
// and publishing events into the Event Bus (RabbitMQ / ServiceBus)
CheckConfirmedGracePeriodOrders();
await Task.Delay(_settings.CheckUpdateTime, stoppingToken);
}
_logger.LogDebug($"GracePeriod background task is stopping.");
}
.../...
}
Page 3 of 9
FullStack.Cafe - Kill Your Tech Interview
Q6: What is the difference between .NET Framework/Core and .NET
Standard Class Library project types? ☆☆☆☆
Topics: .NET Core
Answer:
Use a .NET Standard library when you want to increase the number of apps that will be compatible with your
library, and you are okay with a decrease in the .NET API surface area your library can access.
Implementing a .Net Standard Library allows code sharing across all different flavours of .NET applications like
.NET Framework, .NET Core and Xamarin.
Q7: What's the difference between RyuJIT and Roslyn? ☆☆☆☆
Topics: .NET Core
Answer:
Roslyn is the compiler that compile your code (C# or VB) to IL.
RyuJIT is a Just In Time compiler that compile your IL to a native code.
Both of them are now open source.
Q8: Explain how does Asynchronous tasks Async/Await work in
.NET? ☆☆☆☆
Topics: .NET Core C#
Problem:
Consider:
private async Task<bool> TestFunction()
{
var x = await DoesSomethingExists();
var y = await DoesSomethingElseExists();
return y;
}
Does the second await statement get executed right away or after the first await returns?
Solution:
await pauses the method until the operation completes. So the second await would get executed after the first
await returns.
The purpose of await is that it will return the current thread to the thread pool while the awaited operation runs
off and does whatever.
This is particularly useful in high-performance environments, say a web server, where a given request is
processed on a given thread from the overall thread pool. If we don't await, then the given thread processing the
request (and all it's resources) remains "in use" while the db / service call completes. This might take a couple of
seconds or more especially for external service calls.
Page 4 of 9
FullStack.Cafe - Kill Your Tech Interview
Q9: What is the difference between AppDomain , Assembly , Process
and a Thread ? ☆☆☆☆
Topics: .NET Core
Answer:
An AppDomain is an isolation unit within a process. AppDomains can be created at runtime, loaded with
code, and unloaded. Its an isolation boundary designed to make .NET apps more reliable.
An assembly holds one or more modules, which hold compiled chunks of code. You will typically see an
assembly as an .EXE or a .DLL.
A process is an executing application (waaaay oversimplified).
A thread is an execution context. The operating system executes code within a thread. The operating
system switches between threads, allowing each to execute in turn, thus giving the impression that multiple
applications are running at the same time.
To put it all together (very simplified):
A program is executed.
A process is created by the operating system, and within its single thread it starts loading code to execute.
In a .NET application, a single AppDomain is created by the CLR.
The application's executing assembly (the .EXE) is loaded into this AppDomain and begins execution.
The application can spawn new processes, create AppDomains, load other assemblies into these domains,
and then create new Threads to execute code in any of these AppDomains.
Q10: What is the difference between CIL and MSIL (IL)? ☆☆☆☆
Topics: .NET Core
Answer:
CIL is the term used in the CLI Standard. MSIL is (I suppose) CIL created by MS tools. Effectively they are
synonymous.
CIL – Common Intermediate Language – is the term used in the International Standard.
MSIL – Microsoft Intermediate Language – is the product term for the Microsoft implementation of that
standard.
Q11: Why does .NET use a JIT compiler instead of just compiling
the code once on the target machine? ☆☆☆☆
Topics: .NET Core
Answer:
There are two things to be gained by using an intermediate format like .NET or Java:
1. You can run the program on any platform, exactly because the code is represented in an intermediate format
instead of native code. You just need to write an interpreter for the intermediate format.
2. It allows for some run-time optimizations which are not (easily) possible at compile-time: for example, you
can take advantage of special features on new CPUs, even if those CPUs didn't exist when you wrote your
program - only the JIT compiler needs to know about that.
Page 5 of 9
FullStack.Cafe - Kill Your Tech Interview
Q12: Explain Implicit Compilation process ☆☆☆☆
Topics: .NET Core
Answer:
Implicit Compilation is a two-steps process, and it requires a Virtual Machine to be able to execute your code.
The first step of the process is converting your program to a bytecode understandable by Virtual Machine.
.NET bytecode is called Common Intermediate Language or CIL. It is also known as Microsoft Intermediate
Language (MSIL) or just Intermediate Language (IL).
The second step is converting CIL code to a machine code running on metal. This is Virtual Machine’s task.
Common Language Runtime (.NET Virtual Machine) converts only executed CIL fragments into CPU
instructions at runtime. The .NET framework calls this compiler the JIT (Just-In-Time) compiler.
Q13: What are benefits of using JIT? ☆☆☆☆
Topics: .NET Core
Answer:
JIT can generate faster code, because it targets the current platform of execution. AOT compilation must
target the lowest common denominator among all possible execution platforms.
JIT can profile the application while it runs, and dynamically re-compile the code to deliver better
performance in the hot path (the most used functions).
Q14: Why does .NET Standard library exist? ☆☆☆☆
Topics: .NET Core
Answer:
The reason that .NET Standard exists is for portability; it defines a set of APIs that .NET platforms agree to
implement. Any platform that implements a .NET Standard is compatible with libraries that target that .NET
Standard. One of those compatible platforms is .NET Core.
The .NET Standard library templates exist to run on multiple runtimes (at the expense of API surface area).
Obversely, the .NET Core library templates exist to access more API surface area (at the expense of
compatibility) and to specify a platform against which to build an executable.
Q15: How to choose the target version of .NET Standard library?
☆☆☆☆
Topics: .NET Core
Answer:
When choosing a .NET Standard version, you should consider this trade-off:
1. The higher the version, the more APIs are available to you.
2. The lower the version, the more platforms implement it.
Page 6 of 9
FullStack.Cafe - Kill Your Tech Interview
It's recommended to target the lowest version of .NET Standard possible. So, after you find the highest .NET
Standard version you can target, follow these steps:
1. Target the next lower version of .NET Standard and build your project.
2. If your project builds successfully, repeat step 1. Otherwise, retarget to the next higher version and that's the
version you should use.
Q16: Does .NET support Multiple Inheritance? ☆☆☆☆
Topics: OOP .NET Core
Answer:
.NET does not support multiple inheritance directly because in .NET, a class cannot inherit from more than one
class. .NET supports multiple inheritance through interfaces.
Q17: Explain different types of Inheritance ☆☆☆☆
Topics: OOP .NET Core
Answer:
Inheritance in OOP is of four types:
Single inheritance - Contains one base class and one derived class
Hierarchical inheritance - Contains one base class and multiple derived classes of the same base class
Multilevel inheritance - Contains a class derived from a derived class
Multiple inheritance - Contains several base classes and a derived class
All .NET languages support single, hierarchical, and multilevel inheritance. They do not support multiple
inheritance because, in these languages, a derived class cannot have more than one base class. However, you
can implement multiple inheritance in .NET through interfaces.
Q18: When to use Transient vs Scoped vs Singleton DI service
lifetimes? ☆☆☆☆
Topics: .NET Core ASP.NET Dependency Injection
Answer:
Transient
they are created every time per code request
they will use more memory & Resources and can have a negative impact on performance
a new instance is provided every time a service instance is requested whether it is in the scope of the same
HTTP request or across different HTTP requests,
use this for the lightweight service with little or no state
if you're only doing computation, for instance, that can be transient scoped because you're not exhausting
anything by having multiple copies
use a transient scope unless you have a good, explicit reason to make it a singleton. That would be the
reasons like maintaining state, utilizing limited resources efficiently
Scoped
Page 7 of 9
FullStack.Cafe - Kill Your Tech Interview
a better option when you want to maintain the state within a request,
It is equivalent to a singleton in the current scope
in MVC it creates one instance for each HTTP request, but it uses the same instance in the other calls within
the same web request
normally we will use this for SQL connection, which means it will create and dispose the SQL connection per
request
Singleton
memory leaks in these services will build up over time,
also memory efficient as they are created once reused everywhere,
use you when need to maintain an application-wide state,
singletons are best when you're utilizing limited resources, like sockets and connections. If you end up having
to create a new socket every time the service is injected (transient), then you'll quickly run out of sockets
and then performance really will be impacted
If something needs to persist past one particular operation, then transient won't work, because you'll have
no state, because it will essentially start over each time it's injected
Application configuration or parameters, Logging Service caching of data is some of the examples where you can
use singletons.
Q19: When using DI in Controller shall I call IDisposable on any
injected service? ☆☆☆☆
Topics: .NET Core ASP.NET Dependency Injection
Problem:
Or will Autofac or other CoC Container Framework automatically know which objects in my call stack properly
need to be disposed?
Solution:
So even if your Controller depends on dependencies that need to be disposed of, your controller should not
dispose of them:
Because the consumer did not create such dependency, it has no idea what the expected lifetime of its
dependency is. It could be very well that the dependency should outlive the consumer. Letting the consumer
dispose of that dependency will in that case cause a bug in your application, because the next controller will
get an already disposed of dependency, and this will cause an ObjectDisposedException to be thrown.
Even if the lifestyle of the dependency equals that of the consumer, disposing is still a bad idea, because this
prevents you from easily replacing that component for one that might have a longer lifetime in the future.
Once you replace that component with a longer-lived component, you will have to go through all it
consumers, possibly causing sweeping changes throughout the application. In other words, you will be
violating the Open/closed principle by doing that–it should be possible to add or replace functionality without
making sweeping changes instead.
If your consumer is able to dispose of its dependency, this means that you implement IDisposable on that
abstraction. This means this abstraction is _leaking implementation details_–that’s a violation of the
Dependency Inversion Principle. You are leaking implementation details when implementing IDisposable on
an abstraction because it is very unlikely that every implementation of that abstraction needs deterministic
disposal and so you defined the abstraction with a certain implementation in mind. The consumer should not
have to know anything about the implementation, whether it needs deterministic disposal or not.
Letting that abstraction implement IDisposable also causes you to violate the Interface Segregation
Principle, because the abstraction now contains an extra method (i.e. Dispose ), that not all consumers need
to call. They might not need to call it, because –as I already mentioned– the resource might outlive the
consumer. Letting it implement IDisposable in that case is dangerous because anyone can call Dispose on it
Page 8 of 9
FullStack.Cafe - Kill Your Tech Interview
causing the application to break. If you are more strict about testing, this also means you will have to test a
consumer for not calling the Dispose method. This will cause extra test code. This is code that needs to be
written and maintained.
So instead, you should only let the implementation implement IDisposable . In case your DI container creates
this resource, it should also dispose it. DI Containers like Autofac will actually do this for you.
Q20: Why shouldn't I use the Repository Pattern with Entity
Framework? ☆☆☆☆
Topics: .NET Core Design Patterns Entity Framework
Answer:
The single best reason to not use the repository pattern with Entity Framework? Entity Framework already
implements a repository pattern. DbContext is your UoW (Unit of Work) and each DbSet is the repository.
Implementing another layer on top of this is not only redundant but makes maintenance harder.
In the case of the repository pattern, the purpose is to abstract away the low-level database querying logic. In
the old days of actually writing SQL statements in your code, the repository pattern was a way to move that SQL
out of individual methods scattered throughout your codebase and localize it in one place. Having an ORM like
Entity Framework, NHibernate, etc. is a replacement for this code abstraction, and as such, negates the need for
the pattern.
However, it's not a bad idea to create an abstraction on top of your ORM, just not anything as complex as the
UoW/repository. I'd go with a service pattern, where you construct an API that your application can use without
knowing or caring whether the data is coming from Entity Framework, NHibernate, or a Web API. This is much
simpler, as you merely add methods to your service class to return the data your application needs. The key
difference here is that a service is a thinner layer and is geared towards returning fully-baked data, rather than
something that you continue to query into, like with a repository.
Page 9 of 9