C# Interview Related

Reference vs. value types

Objects that store references to the actual Data = Reference. Classes, Interfaces, and Delegates are examples

Value types actually Hold values...assigning one value type to another COPIES the values. ENUMS, Bools, etc...

Each data-type in c# is a class or structure

structures are value types (int, bools)

classes are reference types

Delegates are function pointers

Object that knows how to call a method(s)

Reference to a function

Func is a delegate that represents a method that returns a value. Func can be used to store a reference to a method that gets an argument of type float, and returns a float.

"Not Extensible"...meaning developer has to build and Re-Deploy your code. (Interfaces help solve this)

"Extensible"...Developer don't have to rely on you

System.Action (one Generic T) one Non-Generic

System.Func ... points to method that returns a-value

Interface or Delegate?

Use delegate when: an Eventing design pattern issued...The caller doesn't need to access other properties or methods

Events

events are mechanisms for communicating between objects

EVENT - Sender => EVENT - Receiver

(EVENT sender knows nothign about EVENT Receiver

Events example

Interfaces

are used to specify methods and properties that a derived class will have access to.

Like a contract...if a class implements an interface...then the interface guarantees the class has access to that method.

Doesn't contain Code or Data nor method implementations

all start w/ I.

no access modifiers

no body on methods

are always public

Big role in Abstraction and Styles

Used to specify related behaviors that may be common across unrelated classes

can extend a class and implement an interface at the same time

can only extend one class but may implement many interfaces

Icomparer T, Compare(T,T)

Interfaces != for Multiple Inheritances...

...No code reusability...Just-Conforming to a Contract

interface merely declares a contract or a behavior that implementing classes should have.

It may declare only properties, methods, and events with no access modifiers.

All the declared members must be implemented.

abstract classes

similar to interfaces BUT can't be instantiated. Frequently partially or never implemented

abstract classes cannot be instantiated

Can contain code or data

A class can inherit from only one abstract class (but can implement multiple interfaces)

Can specify methods as virtual to force a derived class to implement their own definition.

If you have classes that will have a lot of the same code/methods...go with abtract class instead of interfaces

Containing Class doesn't hold implementation (derived classes do that)

Derived classes must implement all derived methods.

Example: A Person abstract class that has a PrintName() method in addition to some data such as default value for an age.

should-be used to collect and specify behavior by related classes.

can inherit traits from the class without any objects from that class being created

you IMPLEMENT an interface while you EXTEND an abstract class

Sealed Modifier prevents it from derived or overriding of methods

Sealed can only be applied to methods that are overriding "virtual" methods of the base class.

slightly faster because of run-time optimizations

abstract class provides a partial implementation for a functionality and some abstract/virtual members that must be implemented by the inheriting entities.

abstract class can declare fields too (use for classes that have common functionality).

Neither interfaces nor abstract classes can be instantiated

static class

Used to create data or functions that don't need to be instantiated

only contain static members

inherently sealed

Can't be instantiated

static methods

a method should be static when it does not refer to any isntance fields of the containing class

virtual methods

must be marked as 'virtual' to override

method signatures must be exactly the same (names of)...and return types same...and types and number of input parameters as well

static variable is-shared between all instances of the class

Generics

allow you to enforce Type Safety by letting you tailor a method or class to a precise data-type

example: Array Class to store list of users or products and then when you use them you can use them as Users or Products (don't have to do any unboxing)

System.Collections.Generic

can put Generic method inside non-generic class

rare to have to create Generic classes or methods

4 Pillars of O.O.P.

  • Abstraction
  • Polymorphism
  • Inheritance
  • Encapsulation

Abstraction

abstraction allows making relevant information visible

are usually implemented as Abstract classes or Interfaces

Polymorphism

Allows for objects of different types to be used in the same way

...when classes have different functionality while sharing the same interface

Blue Ray Disc player(is the interface) able to play DVD(object) or CD(object)

Employee class...another class inherits from it(contractor)..then a permanent Employee class...SO they have different CalculateSalary classes (polymorphic)

Overloading with your methods is also a form of polymorphism

creating multiple methods in a class with same name but different parameters and types is called method overloading...is an example of compile time polymorhpism which is done at compile time.

Run Time polymorphism would be Method overriding

Encapsulation

Bundling of related data & behaviors that operate on that data

achieved through the use of objects

keeping behavior limited to where it matters (that class)

Related features

Encapsulation prevents access to implementation details.

encapsulation ex: setting stuff as private inside classes

Inheritance

when an object or class is based on a parent class (taking on its characteristics)

polymorphic, code Re-Use

Composition

Allows one class to contain another (Car has an Engine)

looser coupling than Inheritance

Any Inheritance can be built into Composition

protected ONLY accessible from its class and derived classes. (AVOID if can...use private instead)

What is .NET?

  • managed execution environment to manage and build applications
  • CLR + FCL (common language run time + framework class library)

CLR Common Language Run-Time...offers security, memory management, exception handling

FCL (framework class library) sits on top of the CLR

C# compilers create Managed code - garbage collecting, references etc...

Unmanaged code compiles straight to machine code...

...Not portable

...Not managed by the CLR

Boxing vs. Unboxing

Boxing is the process of converting a value type to the type object (integer into an object). Boxing is implicit.

Boxed values use more memory and require memory lookups to access.

Unboxing extracts the value from the object. Unboxing is explicit.

Dependency Injection

allows your class to no longer be responsible for instantiating its own dependencies

helps to develop loosely coupled code

3 ways - method, constructor,

Derives from the concept of Inversion of Control

Gang of Four

Authors of "Elements of Reusable Object-Oriented Software"

Repository Pattern

Allows applications to perform with CRUD type operations

Provides an obstraction of data so that

Unit of Work

Maintains in-memory updates

sends in-memory updates as one transaction to the database

often used with Repository Pattern...similar to how transactions in database are done which can be rolled back.

    Monolithic Pros:

  • The major advantage of the monolithic architecture is that most apps typically have a large number of cross-cutting concerns, such as logging, rate limiting, and security features such audit trails and DOS protection. When everything is running through the same app, it’s easy to hook up components to those cross-cutting concerns.
  • There can also be performance advantages, since shared-memory access is faster than inter-process communication (IPC).

    Monolithic Cons:

  • Monolithic app services tend to get tightly coupled and entangled as the application evolves, making it difficult to isolate services for purposes such as independent scaling or code maintainability.
  • Monolithic architectures are also much harder to understand, because there may be dependencies, side-effects, and magic which are not obvious when you’re looking at a particular service or controller.

    Microservice Pros:

  • Microservice architectures are typically better organized, since each microservice has a very specific job, and is not concerned with the jobs of other components.
  • Decoupled services are also easier to recompose and reconfigure to serve the purposes of different apps (for example, serving both the web clients and public API).
  • They can also have performance advantages depending on how they’re organized because it’s possible to isolate hot services and scale them independent of the rest of the app.

    Microservice Cons:

  • As you’re building a new microservice architecture, you’re likely to discover lots of cross-cutting concerns that you did not anticipate at design time. A monolithic app could establish shared magic helpers or middleware to handle such cross-cutting concerns without much effort.
  • In a microservice architecture, you’ll either need to incur the overhead of separate modules for each cross-cutting concern, or encapsulate cross-cutting concerns in another service layer that all traffic gets routed through.
  • Eventually, even monolthic architectures tend to route traffic through an outer service layer for cross-cutting concerns, but with a monolithic architecture, it’s possible to delay the cost of that work until the project is much more mature.
  • Microservices are frequently deployed on their own virtual machines or containers, causing a proliferation of VM wrangling work. These tasks are frequently automated with container fleet management tools.

Positive attitudes toward microservices, despite the higher initial cost vs monolthic apps. Aware that microservices tend to perform and scale better in the long run.

Structure the app so that services are independent from each other at the code level, but easy to bundle together as a monolithic app in the beginning. Microservice overhead costs can be delayed until it becomes more practical to pay the price.

Lambda Expressions

anonymous method

No access modifier

No name

no return statement

conveniance (readable)

args goes to expression

args => expression

number => number * number

lambda expression example

Extension methods

Allow us to add methods to a class without:

changing its source code (or)

creating a new class that inherits from it

essentially static methods (class and method marked static). C# still allows us to use it on an instance object

No access modifier

No name

no return statement

conveniance (readable)

args goes to expression

args => expression

number => number * number

extension methods example

Nullable Types

value types cannot be null

No access modifier

No name

no return statement

conveniance (readable)

args goes to expression

args => expression

number => number * number

nullable types example

Dynamic in c#

statically typed = c#, JAVA, apex (compile-time feedback).

Dynamically typed = Ruby, JS, Python (faster but need more unit tests)

w/ Dynamic have to use Reflection

C.L.R. to machine-Code @ Run-Time

D.L.R. (sits on top of the CLR)

dynamic name = "Bob"; name = 10; (this compiles!!)

Decimal vs. Double

Decimal are slower than Double performance wise

Float is single precision(32 bit)

double is Double precision (64 bit)

decimal is (128bit)

Lists vs. Arrays

Arrays are 0-based indexed

In general, it's better to use lists in c# because lists are far more easily sorted, searched through, and manipulated in c# than arrays are because of all of the built-in list functionalities in the language.

Lists are used far more often in c# than arrays are, but there are some instances where arrays can (or should) be used, including if your data is unlikely to grow very much or if you're dealing with a relatively large amount of data that will need to be indexed into often.

variables

the c# var keyword is used to declare implicit type variables in c#

c# allows variables to be declared as explicit type or implicit type.

Implicitly typed local variables are strongly typed just as if you had declared the type yourself, but the compiler determines the type at run time depending on the value stored in them.

Implicit the compiler is doing something for you...(like with var)

Explicit = casting

class vs. object

class is the definition of an object and an object is instance of a class

can look at the class as a template of the object: it describes all the properties, methods, states and behaviors that the implementing object will have.

An object is an instance of a class, and a class does not become an object until it's instantiated. There can be more instances of objects based on the one class, each with different properties.

difference between managed and unmanaged code

Managed code is code created by the .Net compiler.

Managed code does not depend on the architecture of the target machine because it is executed by the CLR (Common Language Run Time) and not by the operating system itself.

CLR and managed code offers developers few benefits: like garbage collection, type checking, and exceptions handling.

Unmanaged code is directly compiled to native machine code and depends on the architecture of the target machine.

Unmanaged code is executed directly by the operating system.

in unmanaged code the developer has to make sure he is dealing with memory usage and allocation (especially because of memory leaks), type safety, and exceptions manually

in .NET, Visual Basic and C# compiler creates managed code. To get unamanged code, the application has to be written in C or C++.

garbage collection

Garbage collection is a low-priority process that serves as an automatic memory manager which managed the allocation and release of memory for the applications.

Each time a new object is created, the CLR allocates memory for that object from the Managed Heap. As long as free memory space is available in the managed Heap, the runtime continues to allocate space for new objects...

...However, memory is not infinite, and once an application fills the Heap memory space, garbage collection comes into play to free some memory.

When the Garbage collector performs a collection, it checks for objects in the managed Heap that are no longer being used by the application and performs the necessary operations to reclaim the memory.

Garbage collection will stop all the running threads, it will find all objects in the Heap that are not being accessed by the main program and delete them... It will then reorganize all the objects left in the Heap to make space and adjust all the Pointers to these objects in both the Stack and the Heap

System.GC.Collect() to enforce garbage collection manually.

Explain the difference between the STACK and HEAP

in the STACK are stored value types (types inherited from System.ValueType).

in the HEAP are stored reference types (types inherited from System.Object)

We can say the STACK is responsible for keeping track of what is actually executing and where each executing thread is (each thread has its own Stack)...while the Heap on the other hand, is responsible for keeping track of the data, or more precise objects.

objects in both the Stack and the Heap

System.GC.Collect() to enforce garbage collection manually.

.Net Framework

Operating System

CLR

Base-Class Library

Application-Class Library

Common Language Specification

Languages