In part 2, I am going to continue with answers to the questions. This time we get to the section “Mid-Level .NET Developer“.
== Describe the difference between Interface-oriented, Object-oriented and Aspect-oriented programming ==
Interface-oriented programming is based on contracts for interaction between objects. None of the cooperating objects care about how and what exactly others do as long as they can expect the contracts to be satisfied and they themselves satisfy the contracts.
Object-oriented programming is based on the Object Oriented mechanisms such as encapsulation, polymorphism and inheritance. That means that certain objects can rely on their parents (their base classes) to provide certain functionality. The other way around is true as well, that is the base classes can rely on their derived classes to perform certain activities and provide data. As such interaction may involve sharing the same member variables, they may care about how the other parts perform their actions.
Aspect-oriented programming allows for centralizing common functionality into modules (referred to as aspects) and reuse them in multiple places within the application without unnecessarily cluttering our code base with repeated code. Examples include logging on entering and leaving a method call. Two primary ways of introducing AOP is by using:
- Interceptors
- IL Code Weaving
How does intercepting work? We use IoC containers to perform the following work: 1) find the concrete type for the requested interface, 2) determine if the type needs to be wrapped in a proxy decorator, if it does then request the concrete type to be wrapped into a decorator implementing the requested interface and return the decorator.
IL Code Weaving consists in adding pieces of additional code after the code has been built into the Intermediate Language (IL). The IL code weaving is a post-build process.
Examples of uses for aspect oriented programming: logging, securing calls and anything else that is repetitive and violates the DRY principle in a way.
== Describe what an Interface is and how it’s different from a Class. ==
An interface constitutes a contract that provides a name for a method, what to provide and what to expect returned. In other words, it describes the behaviour, but typically (although languages such as Kotlin allow to provide optional implementation bodies) does not provide the behaviour. The behaviour is provided by a class that implements the interface. By using interfaces we can abstract away the implementation details provided by classes and concentrate on the behaviours that need to occur between objects.
== What is Reflection? ==
It is an ability of a computer program to examine and be able to modify its own structure and behaviour at runtime.
With reflection the code can examine itself, report on itself and invoke other code.
Reflection is particularly useful when serializing and deserializing objects. It is also useful during logging. Reflection helps while mocking objects for unit testing purposes.
== What is the difference between XML Web Services using ASMX and .NET Remoting using SOAP? ==
XML Web Services allow for request-reply communication based on messages. By the way, ASMX stands for Active Server Method in XML Web Services.
.NET Remoting allows for working on objects that in fact are remote to the code that executes methods on them.
Both technologies allow for inter-process and inter-machines communication and both are deprecated.
WCF replaced the XML Web Services with WCF Services.
== Are the type system represented by XmlSchema and the CLS isomorphic? ==
No, they are not isomorphic (corresponding or similar in form).
== Conceptually, what is the difference between early-binding and late-binding? ==
The difference is between the times the binding takes place. In early binding (also referred to as static binding) the binding takes place during compile time, while in late binding (also referred to as dynamic binding) the binding takes place at runtime, which means that in the latter’s case, the binding may fail and result in error if coded incorrectly.
== Is using Assembly.Load a static reference or dynamic reference? ==
Personally I think that asking questions about specific methods (or worse, their arguments) is not a good way to measure somebody’s seniority. Anyway…
Assembly.Load allows for loading any assembly from a raw stream or GAC and it loads an assembly as a dynamic reference.
== When would using Assembly.LoadFrom or Assembly.LoadFile be appropriate? ==
If you care about a single instance of a particular version of an assembly then use Assembly.LoadFrom. If you care about an assembly from a particular path, even though a similar with the same version might already have been loaded then use Assembly.LoadFile.
== What is an Assembly Qualified Name? Is it a filename? How is it different? ==
An Assembly Qualified Name consists of the display name of the assembly, its version, culture, public key token and the processor architecture – all combined uniquely identify the assembly. No, it is not a file name. Multiple assemblies can have similar file names, but they will get identified using their Assembly Qualified Names.
== Is this valid? Assembly.Load(“foo.dll”); ==
No, as the method expects a string that contains a long form of the assembly name, e.g.
system, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
== How is a strongly-named assembly different from one that isn’t strongly-named? ==
A strongly-named assembly has its PublicKeyToken different than null. A strongly-named assembly is permitted to be registered in the GAC, while a non strongly-named assembly cannot be registered in the GAC.
Strong-naming of an assembly is only for versioning and not for security purposes. For security purposes the assembly has to be signed and used with a certificate.
== Can DateTimes be null? ==
The type DateTime is a struct (a value type). Value types cannot be null. They can have their default values instead. Just like int has a 0, bool has a false, a DateTime has a DateTime.MinValue.
To make the type nullable, one could declare Nullable<DateTime> or DateTime? (as a syntactic sugar).
== What is the JIT? What is NGEN? What are limitations and benefits of each? ==
JIT is Just-In-Time compilation, which transforms the method’s IL code into the machine code only when the method is invoked – just in time. Any subsequent calls of the same method get routed to the already compiled code.
NGEN (ngen.exe) precompiles all the code into the machine code (creates a native image). It also marks the code pages as shareable, which allows for the code reuse by multiple application instances running by multiple users. For example, frameworks, libraries usually benefit from being NGENed, as their load/start-up time is faster then. The disadvantage is that NGENed applications are bigger in size on disk than their IL assemblies.
== How does the generational garbage collector in the .NET CLR manage object lifetime? What is non-deterministic finalization? ==
Objects are segregated into 3 generations. New objects always start in Gen0. After they have survived the garbage collection they are promoted to Gen1. If they again survive then they are promoted to Gen2 and stay there. The collection in Gen0 happens the most frequently and the frequency is lower in the higher generations.
Non-deterministic finalization means that the object’s finalizer (the object’s destructor) is called when the GC decides to collect the object – when it will happen exactly is unknown. The destructor (finalizer), unlike in C++, is not called when the object gets out of scope. Each object that contains a finalizer gets a corresponding entry in the Finalize queue, which is used by the GC to determine if the object that is about to get destroyed needs to, first, perform a clean-up.
== What is the difference between Finalize() and Dispose()? ==
Dispose belongs to the Dispose pattern in .NET, which makes sure any managed and unmanaged resources are cleaned up.
Dispose method belongs to the IDisposable interface.
Finalize contains code from the “destructor” of the C# class. The “destructor” does not work in the same way as in C++, meaning that it is not called when the object gets out of scope, but rather is called only when the GC determines it is time to clean up the object.
Finalize will be called on an object before it is deallocated as long as the GC.SuppressFinalize(this) has not been called earlier in the Dispose method. If GC.SuppressFinalize(this) is called then the object will not be placed into the Finalize queue (processed in a Finalizer thread separate to the GC thread) and will get immediately deallocated.
Finalize is for making sure that any unmanaged resources get properly freed. Without this mechanism, the CLR may not know how to clean up the unmanaged resources and the disposed CLR object may leave some unmanaged objects cluttering the OS memory (e.g. not “freed” COM objects might stay in the memory until the OS is restarted).
== How is the using() pattern useful? What is IDisposable? How does it support deterministic finalization? ==
The using pattern is a syntactic sugar for try .. finalize clause, where in the finalize clause the Dispose method gets called on an IDisposable object.
IDisposable is an interface belonging to the Dispose pattern.
The using pattern helps to make sure the resources get disposed of as soon as the using scope finishes, which allows the disposal to be deterministic. What still remains undeterministic is the deallocation of the disposed object.
== What does this useful command line do? tasklist /m “mscor*” ==
It lists all processes that have the modules (dlls) starting with mscor loaded into their process memory space.
== What is the difference between in-proc and out-of-proc? ==
in-proc denotes an in-process operation such as a call of a function in a dll loaded into the process memory space
out-of-proc denotes an out of process operation such as a call that is marshalled into a separate process
== What technology enables out-of-proc communication in .NET? ==
For example WCF.