Group 1: C# Fundamentals
1. What is C#, and what are its main features?
C# is a modern, object-oriented, strongly typed programming language developed by Microsoft. It supports OOP, generics, LINQ, async/await, garbage collection, and cross-platform development through .NET.
2. What is the difference between C# and .NET?
C# is a programming language used to write applications. .NET is the development platform providing the runtime (CLR), libraries, and tools to build and execute applications.
3. What is CLR, and how does it execute C# code?
CLR (Common Language Runtime) manages execution, memory, garbage collection, and exceptions. C# code is compiled into IL, which is typically converted into native code by JIT compilation.
C# → Compiler → IL → CLR/JIT → Native Code
4. What is the difference between managed and unmanaged code?
Managed code executes under CLR supervision, benefiting from garbage collection and runtime services. Unmanaged code executes outside the CLR, requiring explicit resource management.
5. What is the difference between value types and reference types?
Value types store their data directly, while reference-type variables hold references to objects. Assigning a value type copies its value; assigning a reference type copies the reference.
6. What is boxing and unboxing?
Boxing converts a value type into an object or interface reference, usually involving heap allocation. Unboxing extracts the value type through explicit casting.
object obj = 10; // Boxing
int number = (int)obj; // Unboxing
7. What is the difference between var, dynamic, and object?
var uses compile-time type inference; dynamic resolves operations at runtime. object is the base type of all C# types and generally requires casting to access type-specific members.
8. What is the difference between const, readonly, and static readonly?
const is a compile-time constant; readonly is assigned during initialization or in an instance constructor. static readonly is shared across instances and initialized at declaration or in a static constructor.
9. What is the difference between ref, out, and in parameters?
ref passes an initialized variable by reference; out requires the called method to assign a value. in passes by reference but prevents reassignment through that parameter.
10. What is the difference between ==, Equals(), and ReferenceEquals()?
== compares values or references depending on the type and operator overload. Equals() checks defined equality, while ReferenceEquals() checks whether two references point to the same object.
11. What is the difference between implicit and explicit type conversion?
Implicit conversion occurs automatically when supported without requiring a cast. Explicit conversion requires casting and may lose data or fail at runtime.
long a = 100; // Implicit
int b = (int)a; // Explicit
12. What are nullable value types and nullable reference types?
Nullable value types (int?) allow value types to contain null. Nullable reference types (string?) express nullability intentions and enable compiler warnings when nullable analysis is enabled.
13. What is the difference between is, as, and explicit casting?
is checks type compatibility or matches a pattern; as performs a compatible reference/nullable conversion and returns null on failure. Explicit casting throws an exception for invalid runtime casts.
14. What are checked and unchecked operations?
checked enables overflow checking for supported integer arithmetic and conversions. unchecked permits wrapping or truncation according to the operation without throwing an overflow exception.
15. What is the difference between default, typeof, and nameof?
default returns a type's default value; typeof returns its System.Type metadata. nameof returns the compile-time name of a variable, type, or member as a string.
Group 2: Data Types, Variables & Operators
1. What are the different data types available in C#?
C# supports value types (int, bool, struct, enum) and reference types (class, string, array, interface, delegate). It also supports nullable types.
2. What is the difference between int, long, float, double, and decimal?
int (32-bit) and long (64-bit) store integers. float (32-bit) and double (64-bit) store floating-point values; decimal (128-bit) provides high-precision decimal arithmetic, commonly used for financial calculations.
3. What is the difference between string and char?
char stores one UTF-16 code unit and uses single quotes. string stores a sequence of UTF-16 code units and uses double quotes.
4. What is the difference between string, StringBuilder, and StringBuffer?
string is immutable, while StringBuilder is mutable and efficient for repeated modifications. C# does not provide Java's StringBuffer class.
5. Why are strings immutable in C#?
String immutability improves safety, supports string interning, and allows reliable sharing. Any operation that changes string content produces another string rather than modifying the original.
6. What are the different types of operators in C#?
C# supports arithmetic, relational, logical, assignment, bitwise, shift, conditional, null-coalescing, and type-testing operators.
7. What is the difference between && and &, and between || and |?
&& and || are short-circuit logical operators. With Boolean operands, & and | evaluate both operands; they also support bitwise operations on integral types.
8. What are ?? and ?. operators?
?? returns the left operand unless it is null, then returns the fallback. ?. safely accesses a member and produces null if the receiver is null.
string name = input ?? "Guest";
int? length = input?.Length;
9. What is the difference between prefix and postfix increment operators?
++i increments before producing the expression's value. i++ produces the previous value and then increments the variable.
10. What are bitwise and shift operators?
Bitwise operators (&, |, ^, ~) manipulate individual bits. Shift operators (<<, >>, >>>) shift bit patterns left or right.
11. What is the difference between Parse(), TryParse(), and Convert.ToInt32()?
Parse() throws an exception for invalid input; TryParse() returns a Boolean success result. Convert.ToInt32() handles null as zero for its string overload but throws for invalid numeric text.
Group 3: Control Statements & Loops
1. What is the difference between if-else, switch, and ternary?
if-else handles complex Boolean conditions. switch selects among patterns or values, while ternary (?:) returns one of two expressions based on a condition.
2. What is the difference between for, foreach, while, and do-while?
for is suitable for indexed iterations; foreach iterates over collections. while checks before execution, while do-while executes at least once.
3. What is the difference between break, continue, and return?
break exits the nearest loop or switch; continue skips to the next loop iteration. return exits the current method.
4. Can we modify a collection while iterating using foreach?
Modifying a List<T> structurally during foreach generally throws InvalidOperationException. Use RemoveAll(), an indexed loop, or a separate collection when removing items.
5. What are switch expressions and pattern matching?
Pattern matching checks values, types, and structures. Switch expressions provide concise syntax to return values based on matching patterns.
string result = score >= 50 ? "Pass" : "Fail";
string grade = score switch { >= 90 => "A", >= 50 => "Pass", _ => "Fail" };
6. What is the difference between return and yield return?
return exits the method and returns a result. yield return produces one element at a time from an iterator, preserving execution state between iterations.
7. What is the difference between yield return and yield break?
yield return produces the next element in an iterator. yield break terminates the iterator immediately.
Group 4: Object-Oriented Programming (OOP)
1. What is OOP, and what are its four main pillars?
OOP organizes software around objects containing data and behavior. Its four pillars are Encapsulation, Abstraction, Inheritance, and Polymorphism.
2. What is the difference between a class and an object?
A class defines properties and behavior; an object is an instance of that class. Multiple objects can be created from the same class.
3. What is encapsulation?
Encapsulation combines data and methods while controlling access using access modifiers. Private fields and public properties help protect object state.
4. What is abstraction?
Abstraction exposes essential functionality while hiding implementation details. It is commonly implemented using interfaces and abstract classes.
5. What is inheritance, and what types does C# support?
Inheritance allows a derived class to reuse and extend a base class. C# supports single, multilevel, and hierarchical class inheritance, but not multiple class inheritance.
6. What is polymorphism?
Polymorphism allows the same operation to behave differently based on the object or arguments. Compile-time polymorphism uses overloading; runtime polymorphism uses overriding.
7. What is the difference between method overloading and overriding?
Overloading uses the same method name with different parameter signatures. Overriding replaces an inherited virtual or abstract method implementation in a derived class.
8. What is the difference between an abstract class and an interface?
An abstract class can contain instance state, constructors, and implemented methods. An interface defines a contract and can also provide default implementations.
9. What is the difference between virtual, override, and new?
virtual allows a method to be overridden; override provides a derived implementation. new hides an inherited member instead of overriding its virtual dispatch.
10. What is the difference between inheritance and composition?
Inheritance represents an IS-A relationship, while composition represents a HAS-A relationship. Composition often provides better flexibility and lower coupling.
11. What are access modifiers in C#?
Access modifiers control member visibility: public, private, protected, internal, protected internal, and private protected. They support encapsulation and API design.
12. What is the difference between static, abstract, and sealed classes?
A static class cannot be instantiated and contains static members. An abstract class cannot be instantiated directly; a sealed class cannot be inherited.
13. What is the difference between association, aggregation, and composition?
Association is a general relationship between objects. Aggregation represents weak ownership, while composition represents strong ownership where the component's lifecycle depends on the owner.
14. What is constructor chaining?
Constructor chaining allows one constructor to call another using this() or a base constructor using base(). It reduces duplicate initialization logic.
15. What is the difference between shallow copy and deep copy?
A shallow copy duplicates the outer object but shares referenced objects. A deep copy also duplicates nested mutable objects as needed.
16. What is the difference between fields and properties?
Fields directly store data. Properties provide controlled access through get, set, or init, and can include validation or computed logic.
17. What is the difference between this and base?
this refers to the current instance. base accesses members or constructors of the immediate base class.
18. What is explicit interface implementation?
Explicit implementation defines an interface member using its qualified name. The member is normally accessible through the interface reference, not directly through the class reference.
19. Can interfaces contain default implementations?
Yes. Since C# 8, interfaces can provide default implementations for members, allowing interfaces to evolve while preserving compatibility in some cases.
20. What is the difference between class, struct, and record?
class is a reference type; struct is a value type. record emphasizes value-based equality and concise data models; records can be reference types or record struct value types.
Group 5: Constructors, Properties & Methods
1. What is a constructor, and what are its different types?
A constructor initializes an object when it is created. Common forms include parameterless, parameterized, copy-style, static, and private constructors.
2. What is the difference between static and instance constructors?
A static constructor initializes a type once before its first relevant use. An instance constructor initializes each new object.
3. Can constructors be overloaded or inherited?
Constructors can be overloaded using different parameter lists. Constructors are not inherited, but derived constructors can call base constructors.
4. What is the difference between static and instance methods?
Static methods belong to the type and do not require an object. Instance methods require an object and can access its instance state.
5. What are auto-implemented, read-only, and init properties?
Auto-properties use compiler-generated backing fields. Get-only properties restrict assignment, while init properties allow assignment during object initialization.
6. What is method overloading, and how does C# resolve it?
Method overloading defines multiple methods with the same name but different parameter signatures. The compiler selects the best applicable overload based on arguments and conversion rules.
7. What is constructor chaining using this() and base()?
this() invokes another constructor in the same class. base() invokes a constructor in the parent class.
8. What are expression-bodied members?
Expression-bodied members use => to implement simple methods, properties, or constructors concisely.
public int Square(int x) => x * x;
9. What are optional and named parameters?
Optional parameters define default argument values. Named parameters allow arguments to be supplied by parameter name, improving clarity.
10. What are extension methods?
Extension methods add callable methods to existing types without modifying their source code. They are commonly used in LINQ and reusable utility APIs.
11. What is the difference between a finalizer and Dispose()?
Dispose() supports deterministic resource cleanup when explicitly invoked. A finalizer provides nondeterministic cleanup by the GC for objects that implement one.
Group 6: Collections & Generics
1. What is the difference between an array and a collection?
An array has a fixed length and stores elements of a specified type. Collections provide different capabilities, such as dynamic resizing, key-based lookup, or uniqueness.
2. What is the difference between Array, ArrayList, and List?
Array has fixed length; ArrayList is a non-generic resizable collection storing objects. List<T> is generic, type-safe, and dynamically resizable.
3. What is the difference between List<T> and Dictionary<TKey,TValue>?
List<T> stores ordered elements accessed by index. Dictionary<TKey,TValue> stores key-value pairs and provides average O(1) key lookup.
4. What is the difference between IEnumerable, ICollection, and IList?
IEnumerable supports enumeration; ICollection adds collection operations and count. IList adds indexed access and positional modification.
5. What is the difference between IEnumerable<T> and IQueryable<T>?
IEnumerable<T> supports enumeration of objects, with LINQ-to-Objects operations performed locally. IQueryable<T> exposes expression trees that providers such as EF Core can translate into database queries.
6. What are generics, and why are they important?
Generics allow reusable classes and methods with type parameters. They provide compile-time type safety and avoid boxing for many value-type operations.
7. What is the difference between Dictionary and ConcurrentDictionary?
Dictionary<TKey,TValue> does not support concurrent writes safely without synchronization. ConcurrentDictionary<TKey,TValue> provides thread-safe concurrent operations.
8. What is the difference between HashSet<T> and List<T>?
HashSet<T> stores unique elements and offers average O(1) lookup. List<T> allows duplicates, maintains index order, and typically requires O(n) searching.
9. What is the difference between Queue<T> and Stack<T>?
Queue<T> follows FIFO (First In, First Out). Stack<T> follows LIFO (Last In, First Out).
10. What is the difference between IReadOnlyCollection<T> and IReadOnlyList<T>?
IReadOnlyCollection<T> provides enumeration and Count. IReadOnlyList<T> additionally provides read-only indexed access.
11. What are generic constraints?
Generic constraints restrict which types can be used as type arguments. Examples include where T : class, struct, new(), a base class, or an interface.
12. What are covariance and contravariance?
Covariance (out) allows more-derived types to be used in compatible output positions. Contravariance (in) supports compatible less-derived types in input positions.
13. What are immutable collections?
Immutable collections cannot be modified after creation. Operations return new collection versions, making shared state safer in concurrent applications.
14. How does Dictionary work internally?
Dictionary<TKey,TValue> uses hash codes and buckets to locate entries. Collisions are resolved through entry chains, with equality comparisons identifying matching keys.
Group 7: LINQ
1. What is LINQ, and what are its advantages?
LINQ (Language Integrated Query) provides a consistent way to query collections, databases, and other data sources. It supports filtering, sorting, grouping, joining, and projection with compile-time type checking.
2. What is the difference between query syntax and method syntax?
Query syntax uses SQL-like keywords such as from, where, and select. Method syntax uses extension methods such as Where(), Select(), and OrderBy().
3. What is the difference between Where() and Select()?
Where() filters elements based on a condition. Select() transforms or projects each element into another value or object.
var adults = employees.Where(x => x.Age >= 18);
var names = employees.Select(x => x.Name);
4. What is the difference between Select() and SelectMany()?
Select() projects each item and can produce nested collections. SelectMany() projects and flattens nested sequences into a single sequence.
5. What is the difference between First(), FirstOrDefault(), Single(), and SingleOrDefault()?
First() returns the first element; FirstOrDefault() returns a default if none exists. Single() requires exactly one element; SingleOrDefault() allows zero or one, but throws if multiple exist.
6. What is the difference between Any(), All(), and Count()?
Any() checks whether an element exists or matches a condition. All() verifies every element satisfies a condition; Count() returns the number of elements.
7. What is deferred execution versus immediate execution?
Deferred execution delays query evaluation until enumeration. Immediate execution evaluates the query when methods such as ToList(), Count(), or First() are called.
8. What is the difference between IEnumerable and IQueryable in LINQ?
IEnumerable<T> LINQ operations execute against enumerated objects. IQueryable<T> lets a provider translate supported query expressions, such as into SQL.
9. What is the difference between GroupBy() and ToLookup()?
GroupBy() groups elements and normally uses deferred execution in LINQ to Objects. ToLookup() immediately creates a reusable, read-only lookup structure.
10. How do you perform inner joins and left joins using LINQ?
An inner join uses Join() to return matching records. A left join uses GroupJoin() with DefaultIfEmpty(), or supported LeftJoin() APIs in newer .NET versions.
11. What is the difference between OrderBy() and ThenBy()?
OrderBy() performs primary sorting. ThenBy() performs secondary sorting while preserving the primary sort order.
12. What is the difference between Distinct(), Union(), Intersect(), and Except()?
Distinct() removes duplicates; Union() combines unique elements. Intersect() returns common elements, while Except() returns elements in the first sequence absent from the second.
13. What is the difference between ToList(), ToArray(), and AsEnumerable()?
ToList() materializes results into a resizable list; ToArray() materializes them into a fixed-length array. AsEnumerable() exposes an enumerable interface without materializing the sequence.
14. How do you improve LINQ query performance?
Filter early, select only required fields, avoid repeated enumeration, and use appropriate data structures. With EF Core, use AsNoTracking(), indexes, pagination, and inspect generated SQL.
15. What are expression trees, and how are they used by LINQ providers?
Expression trees represent code as structured data using Expression<TDelegate>. LINQ providers inspect these trees and translate supported expressions into queries such as SQL.
Group 8: Delegates, Events & Lambda Expressions
1. What is a delegate in C#?
A delegate is a type-safe reference to one or more methods with a compatible signature. It is used for callbacks, event handling, and passing behavior as parameters.
2. What is the difference between delegates and interfaces?
A delegate represents callable behavior through a method signature. An interface defines a broader contract containing members such as methods, properties, and events.
3. What is the difference between Func, Action, and Predicate?
Func represents a method that returns a value; Action returns void. Predicate<T> takes a T and returns bool.
4. What is a lambda expression?
A lambda expression is a concise way to define an anonymous function using =>. It is commonly used with LINQ, delegates, and event handlers.
Func<int, int> square = x => x * x;
5. What is the difference between anonymous methods and lambda expressions?
Anonymous methods use the delegate keyword, while lambdas use =>. Lambdas are more concise and can also be represented as expression trees.
6. What is an event, and how does it differ from a delegate?
A delegate represents a callable method reference. An event uses a delegate type but restricts external code to subscribing and unsubscribing, supporting controlled notifications.
7. What are multicast delegates?
Multicast delegates hold multiple method references in an invocation list. Invoking the delegate calls its registered methods in sequence.
8. What is the publisher-subscriber pattern?
The publisher raises notifications when something happens. Subscribers register handlers to respond, allowing loosely coupled communication.
9. What are closures in C#?
A closure occurs when a lambda or local function captures variables from its surrounding scope. Those captured variables can remain available after the original scope exits.
10. How can event subscriptions cause memory leaks?
A long-lived publisher may retain references to subscribers through event handlers, preventing garbage collection. Unsubscribe when appropriate or use weak-event patterns.
Group 9: Exception Handling
1. What is exception handling in C#?
Exception handling manages runtime errors using try, catch, finally, and throw. It allows applications to recover, log errors, or terminate operations safely.
2. What is the difference between throw and throw ex?
throw; rethrows the current exception while preserving its original stack trace. throw ex; resets the stack trace at the rethrow point, making debugging harder.
3. What is the purpose of try, catch, and finally?
try contains code that may throw exceptions; catch handles matching exceptions. finally runs cleanup code whether execution succeeds or fails, except in certain abnormal termination scenarios.
4. What is the difference between Exception and application-specific exceptions?
Exception is the general base class for exceptions. Application-specific exceptions represent meaningful domain or business errors, improving error classification and handling.
5. How do you create custom exceptions?
Create a class derived from Exception and provide appropriate constructors. Use custom exceptions when callers need to distinguish a specific failure condition.
public class BusinessException(string message) : Exception(message);
6. Can multiple catch blocks handle different exception types?
Yes. Multiple catch blocks can handle different exception types, with more specific exceptions placed before general exceptions.
7. What happens when an exception occurs inside a finally block?
The new exception propagates outward and can replace an exception already being propagated. Avoid throwing exceptions from cleanup logic.
8. What are exception filters using when?
Exception filters allow a catch block to handle an exception only when an additional condition is true.
catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { }
9. What is the difference between throw and ExceptionDispatchInfo.Throw()?
throw; rethrows an active exception within a catch block. ExceptionDispatchInfo.Throw() can rethrow a previously captured exception while preserving its original diagnostic stack information.
10. What are best practices for exception handling in enterprise applications?
Catch specific exceptions, preserve stack traces, log useful context, and avoid swallowing errors. Use centralized exception handling and return safe, standardized error responses.
Group 10: Asynchronous Programming (Async/Await)
1. What is asynchronous programming in C#?
Asynchronous programming allows operations to complete without blocking the calling thread while waiting. It is especially useful for I/O operations such as database queries and HTTP requests.
2. What is the difference between synchronous and asynchronous programming?
Synchronous code waits for each operation to finish before continuing. Asynchronous code can suspend execution while awaiting completion, improving scalability for I/O-bound workloads.
3. What are async and await, and how do they work internally?
async enables asynchronous methods, while await asynchronously waits for an awaitable operation. The compiler transforms async methods into state machines that manage suspension and continuation.
4. What is the difference between Task, Task<T>, and void?
Task represents an asynchronous operation without a result; Task<T> returns a result. void has no awaitable completion representation and should generally be avoided for async methods except event handlers.
5. What is the difference between Task.Run() and Task.Delay()?
Task.Run() schedules work on the thread pool, commonly for CPU-bound operations. Task.Delay() creates a non-blocking time delay without occupying a thread during the wait.
6. What is the difference between Task.WhenAll() and Task.WhenAny()?
Task.WhenAll() completes when all supplied tasks finish and aggregates failures. Task.WhenAny() completes when the first task finishes and returns that completed task.
7. What is the difference between Task.Wait() and await?
Task.Wait() synchronously blocks the calling thread until completion. await allows asynchronous suspension without blocking the thread while waiting.
8. What causes deadlocks in asynchronous code?
Deadlocks can occur when code synchronously blocks on async operations that need a captured context to continue. Use async all the way and avoid .Result or .Wait().
9. What is ConfigureAwait(false)?
ConfigureAwait(false) tells an await not to require continuation on the captured synchronization context. It is useful in reusable libraries but generally unnecessary for ASP.NET Core's default execution environment.
10. What is CancellationToken, and how is cancellation implemented?
CancellationToken supports cooperative cancellation of operations. Pass the token to async methods and check it or call ThrowIfCancellationRequested().
11. Can we use async/await without creating a new thread?
Yes. async/await does not automatically create a new thread. I/O-bound operations typically release the calling thread while waiting for completion.
12. What is the difference between Task and ValueTask?
Task is a reference type representing asynchronous completion. ValueTask is a value type that can reduce allocations when operations frequently complete synchronously, but has more usage restrictions.
13. What are asynchronous streams using IAsyncEnumerable<T>?
IAsyncEnumerable<T> allows values to be produced asynchronously over time. Consumers use await foreach to process items as they become available.
14. How do exceptions propagate in async methods?
Exceptions from async Task methods are stored in the returned task and rethrown when awaited. Exceptions from async void methods propagate through the synchronization context or runtime.
15. What happens when an async method is called without awaiting it?
The method begins execution, but the caller does not wait for completion. Exceptions may go unobserved, and dependent operations may run before the task finishes.
Group 11: Multithreading & Parallel Programming
1. What is the difference between a process and a thread?
A process is an isolated execution environment with its own resources and address space. A thread is an execution path within a process and shares its process memory.
2. What is the difference between multithreading and asynchronous programming?
Multithreading uses multiple threads to execute work concurrently. Asynchronous programming avoids blocking during waits and does not necessarily require multiple threads.
3. What is the difference between Thread, ThreadPool, and Task?
Thread represents a dedicated execution thread; ThreadPool manages reusable worker threads. Task represents an operation and may execute on the thread pool or complete without a dedicated thread.
4. What is the difference between concurrency and parallelism?
Concurrency means multiple operations make progress during overlapping periods. Parallelism means multiple operations execute simultaneously, typically on different CPU cores.
5. What is a race condition, and how do you prevent it?
A race condition occurs when results depend on unpredictable execution timing between threads. Prevent it using locks, atomic operations, immutable data, or thread-safe collections.
6. What is the lock keyword?
lock provides mutual exclusion so only one thread executes a protected critical section at a time. It protects shared mutable data from concurrent access.
7. What is the difference between lock, Monitor, Mutex, and SemaphoreSlim?
lock is convenient mutual exclusion built on synchronization primitives such as Monitor. Mutex supports cross-process synchronization; SemaphoreSlim limits concurrent access and supports asynchronous waiting.
8. What is thread safety?
Thread safety means code behaves correctly when accessed concurrently by multiple threads. It is achieved through synchronization, immutability, or thread-safe designs.
9. What is the difference between Parallel.ForEach() and normal foreach?
foreach processes elements sequentially. Parallel.ForEach() distributes iterations across threads, potentially improving performance for independent CPU-bound operations.
10. What is Interlocked, and when should it be used?
Interlocked provides atomic operations such as increment, decrement, exchange, and compare-exchange. It is efficient for simple shared-variable updates.
11. What is the volatile keyword?
volatile provides specific memory visibility and ordering guarantees for field accesses across threads. It does not make compound operations such as increment atomic.
12. What is a deadlock, and how can you prevent it?
A deadlock occurs when operations wait indefinitely for resources held by one another. Prevent it using consistent lock ordering, reduced lock scope, and avoiding blocking while holding locks.
13. What is the difference between Thread.Sleep() and Task.Delay()?
Thread.Sleep() blocks the current thread for a duration. Task.Delay() returns an awaitable delay that does not block a thread while waiting.
14. What are Channel<T> and producer-consumer patterns?
Channel<T> provides thread-safe asynchronous communication between producers and consumers. Producers write data while consumers read and process it, optionally with bounded capacity.
Group 12: Memory Management & Garbage Collection
1. What is garbage collection in .NET?
Garbage collection automatically reclaims managed heap memory occupied by unreachable objects. It reduces the need for manual memory deallocation.
2. How does the Garbage Collector work?
The GC identifies reachable objects, reclaims memory from unreachable objects, and may compact surviving objects. It uses generational collection to optimize performance.
3. What are Generation 0, Generation 1, and Generation 2?
Gen 0 contains newly allocated objects; Gen 1 is an intermediate generation. Gen 2 contains longer-lived objects and is generally collected less frequently.
4. What is the difference between stack and heap memory?
The stack stores method call frames and certain local data. The managed heap stores objects, with their lifetimes controlled by garbage collection.
5. What is the difference between managed and unmanaged resources?
Managed resources are objects whose memory is managed by the CLR. Unmanaged resources include OS handles, native allocations, and other resources requiring explicit cleanup.
6. What is the difference between Dispose() and a finalizer?
Dispose() enables explicit, timely resource cleanup. A finalizer runs nondeterministically during garbage collection and serves as a fallback for certain unmanaged resources.
7. What is the purpose of IDisposable and using?
IDisposable defines the Dispose() method for resource cleanup. The using statement automatically calls Dispose() when the scope exits.
8. What causes memory leaks in .NET applications?
Memory leaks occur when unused objects remain reachable through references. Common causes include static collections, event subscriptions, unbounded caches, and long-lived object references.
9. What is the Large Object Heap (LOH)?
The LOH stores large managed objects, typically allocations of approximately 85,000 bytes or more. Excessive large allocations can increase GC pressure and fragmentation.
10. What is the difference between GC.Collect() and automatic garbage collection?
Automatic GC decides when collection is appropriate based on runtime conditions. GC.Collect() forces a collection request and is generally discouraged without a measured need.
11. What are weak references?
Weak references refer to objects without preventing garbage collection. They are useful when an object may be reused but should not be kept alive unnecessarily.
12. What are Span<T> and Memory<T>?
Span<T> provides allocation-free access to contiguous memory and is restricted to stack-safe usage. Memory<T> represents similar memory and can be stored and used across async boundaries.
13. What is object pooling, and when is it useful?
Object pooling reuses expensive or frequently allocated objects instead of repeatedly creating them. It can reduce allocations and GC overhead in high-throughput applications.
Group 13: SOLID Principles & Design Patterns
1. What are the SOLID principles?
SOLID represents five design principles: Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, and Dependency Inversion. They improve maintainability, extensibility, and testability.
2. What is the Single Responsibility Principle (SRP)?
A class should have one primary responsibility and one reason to change. Example: Separate order processing from email notification logic.
3. What is the Open/Closed Principle (OCP)?
Software components should be open for extension but closed for modification. Use interfaces and polymorphism to introduce new behavior without changing existing code.
4. What is the Liskov Substitution Principle (LSP)?
Derived classes should be usable wherever their base classes are expected without violating expected behavior. Subclasses must preserve the base contract.
5. What is the Interface Segregation Principle (ISP)?
Clients should not depend on methods they do not use. Prefer smaller, focused interfaces over large interfaces containing unrelated operations.
6. What is the Dependency Inversion Principle (DIP)?
High-level modules should depend on abstractions rather than concrete implementations. Both high-level and low-level modules should depend on suitable abstractions.
7. What is the difference between Dependency Injection and Dependency Inversion?
Dependency Inversion is a design principle that encourages depending on abstractions. Dependency Injection is a technique for supplying dependencies externally, often through constructors.
8. What is the Repository Pattern?
The Repository Pattern abstracts data access operations behind a collection-like interface. It separates business logic from persistence details such as SQL or EF Core.
9. What is the Factory Pattern?
The Factory Pattern encapsulates object creation logic. It is useful when object creation depends on conditions, configuration, or different implementations.
10. What is the Strategy Pattern?
The Strategy Pattern defines interchangeable algorithms behind a common interface. Example: Selecting different payment or discount calculation strategies at runtime.
11. What is the Singleton Pattern?
The Singleton Pattern ensures one instance of a class within a defined scope. In C#, Lazy<T> provides a convenient thread-safe initialization mechanism.
private static readonly Lazy<MyService> instance = new(() => new MyService());
public static MyService Instance => instance.Value;
12. What is the Unit of Work Pattern?
Unit of Work coordinates changes across multiple repositories within one transaction or persistence operation. EF Core's DbContext already implements many Unit of Work responsibilities.
13. What is the Decorator Pattern?
The Decorator Pattern adds behavior to an object without changing its original implementation. Common examples include logging, caching, and validation wrappers.
14. What is the Adapter Pattern?
The Adapter Pattern converts one interface into another interface expected by a client. It is useful when integrating legacy systems or third-party services.
15. What is the Observer Pattern?
The Observer Pattern allows multiple subscribers to receive notifications when an object's state changes. C# events are a common implementation.
16. What is the Builder Pattern?
The Builder Pattern constructs complex objects step by step. It is useful when object creation involves many optional configurations or validation steps.
17. What is the difference between Factory Method and Abstract Factory?
Factory Method defines a method for creating a product, allowing subclasses to determine its concrete type. Abstract Factory creates families of related objects through a common interface.
18. Why is composition often preferred over inheritance?
Composition reduces tight coupling and allows behavior to be changed by replacing dependencies. Inheritance creates stronger relationships between base and derived classes.
Group 14: Modern C# Features
1. What are records, and how do they differ from classes?
Records are designed for data-centric models and provide value-based equality and convenient copying. Regular classes use reference equality by default unless overridden.
2. What are nullable reference types?
Nullable reference types distinguish potentially nullable references (string?) from non-nullable references (string). They enable compiler warnings to help prevent null-reference errors.
3. What is pattern matching in C#?
Pattern matching checks an object's type, value, or structure using patterns. It simplifies conditional logic with is, switch, and property patterns.
4. What are switch expressions?
Switch expressions provide concise syntax for returning values based on matching patterns. They reduce lengthy conditional statements.
string result = age >= 18 ? "Adult" : "Minor";
5. What are init-only properties?
init properties allow values to be assigned during object initialization but not through normal assignment afterward. They support immutable object designs.
6. What is the required keyword?
The required modifier indicates that callers must initialize a member when creating an object, unless a constructor satisfies the requirement.
7. What are primary constructors?
Primary constructors allow constructor parameters to be declared directly in the type declaration. They reduce boilerplate for dependency injection and initialization.
public class UserService(IUserRepository repository) { }
8. What are collection expressions?
Collection expressions, introduced in C# 12, use [] syntax to create supported collection types concisely.
List<int> numbers = [1, 2, 3];
9. What are file-scoped namespaces?
File-scoped namespaces use a semicolon instead of braces. They reduce indentation and improve code readability.
10. What are global using directives?
global using makes a namespace available across all files in a project. It reduces repeated using statements.
11. What are target-typed new expressions?
Target-typed new allows the compiler to infer the type from the assignment or surrounding context.
List<string> names = new();
12. What are tuples and deconstruction?
Tuples group multiple values without creating a separate class. Deconstruction extracts tuple elements into individual variables.
13. What are local functions?
Local functions are methods declared inside another method. They help organize reusable logic that is needed only within the enclosing method.
14. What are record struct and readonly struct?
record struct is a value type with generated value-equality functionality. readonly struct prevents modification of instance fields after construction and helps enforce immutability.
15. What are raw string literals?
Raw string literals use three or more double quotes to represent strings with minimal escaping. They are useful for JSON, SQL, and multiline text.
16. What are generic math and static abstract interface members?
Generic math allows numeric algorithms to work across multiple numeric types. Static abstract interface members let interfaces define required static operations such as arithmetic operators.
Group 15: Reflection, Attributes & Serialization
1. What is reflection in C#, and when is it used?
Reflection allows runtime inspection of types, properties, methods, and metadata. It is commonly used in dependency injection frameworks, serializers, and plugin systems.
2. What are attributes in C#?
Attributes provide declarative metadata for types, methods, properties, and other program elements. Examples include [Obsolete], [Required], and [Authorize].
3. How do you create custom attributes?
Create a class derived from System.Attribute and apply it using square brackets.
public class AuditAttribute : Attribute { }
[Audit] public class OrderService { }
4. What is serialization and deserialization?
Serialization converts objects into formats such as JSON or XML. Deserialization converts serialized data back into objects.
5. What is the difference between System.Text.Json and Newtonsoft.Json?
System.Text.Json is Microsoft's built-in JSON library, optimized for modern .NET performance. Newtonsoft.Json is a mature third-party library offering extensive features and customization.
6. What is the difference between reflection and expression trees?
Reflection inspects types and members at runtime. Expression trees represent code as structured data that can be inspected, transformed, compiled, or translated.
7. What are assemblies, namespaces, and metadata?
An assembly is a compiled deployment unit such as a DLL or EXE. A namespace organizes types logically, while metadata describes types, members, and references.
8. What is the difference between early binding and late binding?
Early binding resolves member access at compile time and provides compile-time checking. Late binding resolves members at runtime, commonly using reflection or dynamic.
9. How do you exclude or rename properties during JSON serialization?
Use [JsonIgnore] to exclude a property and [JsonPropertyName] to rename it when using System.Text.Json.
[JsonIgnore] public string? Password { get; set; }
[JsonPropertyName("user_name")] public string? Name { get; set; }
10. What is source-generated JSON serialization?
Source-generated serialization creates JSON serialization metadata or code at compile time. It can reduce reflection overhead, improve startup performance, and support Native AOT.
Group 16: File Handling & I/O
1. How do you read and write files in C#?
Use File.ReadAllText() and File.WriteAllText() for simple text operations. Use streams or asynchronous APIs for large files and scalable I/O.
File.WriteAllText("test.txt", "Hello");
string content = File.ReadAllText("test.txt");
2. What is the difference between File, FileInfo, StreamReader, and StreamWriter?
File provides static file operations; FileInfo provides instance-based file operations and metadata. StreamReader reads text from streams, while StreamWriter writes text.
3. What is the difference between synchronous and asynchronous file operations?
Synchronous file operations block the calling thread until completion. Asynchronous operations allow the thread to perform other work while I/O is pending.
4. What is a stream in C#?
A stream represents a sequence of bytes used for reading or writing data. Examples include FileStream, MemoryStream, and NetworkStream.
5. What is the difference between FileStream and MemoryStream?
FileStream reads and writes data through files. MemoryStream stores data in memory and is useful for temporary processing without disk access.
6. How do you process large files without loading them entirely into memory?
Use StreamReader, FileStream, or File.ReadLines() to process data incrementally. This reduces memory consumption compared with reading the entire file.
7. How do you handle file access exceptions and resource disposal?
Use try-catch to handle exceptions such as IOException and UnauthorizedAccessException. Use using or await using to release file handles reliably.
Group 17: C# Performance Optimization
1. How do you identify and improve C# application performance?
Use profiling, logging, metrics, and benchmarking to identify bottlenecks. Optimize slow database queries, excessive allocations, blocking operations, and inefficient algorithms.
2. Why is StringBuilder better for repeated string concatenation?
Strings are immutable, so repeated concatenation may create many temporary objects. StringBuilder uses a mutable buffer, reducing allocations during repeated modifications.
3. How do boxing and unboxing affect performance?
Boxing generally allocates an object and copies the value; unboxing requires type checking and copying. Frequent boxing increases allocations and garbage collection overhead.
4. How can LINQ cause performance issues?
LINQ can cause repeated enumeration, unnecessary allocations, and inefficient queries. In EF Core, poorly structured LINQ may generate expensive SQL or multiple database round trips.
5. How do unnecessary allocations affect garbage collection?
Excessive allocations increase GC frequency and memory pressure. This can reduce throughput and increase application latency.
6. What is the difference between IEnumerable and IQueryable from a performance perspective?
IEnumerable<T> operations using LINQ to Objects execute locally. IQueryable<T> allows supported filtering and projection to execute at the data source, reducing transferred data.
7. What is the difference between Span<T> and arrays?
An array owns a fixed-length managed storage allocation. Span<T> provides a lightweight view over contiguous memory, allowing slicing without copying data.
8. When should you use ValueTask instead of Task?
Use ValueTask in measured performance-sensitive scenarios where operations frequently complete synchronously. Prefer Task by default because it is simpler and more flexible.
9. What are allocation-free programming techniques?
Use Span<T>, stackalloc, object pooling, and reusable buffers where appropriate. Avoid unnecessary boxing, temporary collections, and string allocations.
10. How do you investigate high CPU and memory usage in a .NET application?
Use tools such as Visual Studio Profiler, dotnet-counters, dotnet-trace, and memory dumps. Analyze CPU hotspots, GC activity, allocation rates, retained objects, and thread contention.