.NET Interview Questions and Answers: 800+ Questions for Beginners, Seniors & Architects
Hello, my name is Artem Polishchuk, and I've been working with C# and .NET since 2012. Over the years, I have participated in and conducted hundreds of technical interviews. This guide brings together the most common questions, topics, and discussion points I have encountered from both sides of the interview table.
The goal of this article is to help developers prepare for interviews covering modern C#, .NET, ASP.NET Core, databases, distributed systems, cloud architecture, testing, AI, and many other topics. Whether you're preparing for a Junior, Middle, Senior, Tech Lead, Architect, or Engineering Manager role, you'll find both fundamental and advanced subjects collected in one place.
If you're an interviewer, I would recommend using this list as inspiration rather than a ready-made interview script, since many candidates use resources like this as part of their preparation.
The answers throughout the guide are divided into three levels:
- 👼 Junior: Core concepts and fundamentals
- 🎓 Middle: Practical experience and common real-world scenarios
- 👑 Senior: Advanced topics, trade-offs, architecture, and design decisions
.NET and C# Fundamentals

The detailed answers with diagrams and explanations of what Junior/Middle/Senior should know for the questions below, can be found in our separate article: C# / .NET Interview Questions and Answers: Part 1 – Core Language & Platform Fundamentals.
- What is C#? How does it differ from languages like C or C++?
Short answer
C# is a modern, managed, type-safe language for the .NET platform, designed for productivity, safety, and application development. Unlike C and C++, it normally runs under a managed runtime with garbage collection, while C/C++ give lower-level memory and hardware control.
- NET Framework vs .NET Core vs .NET 5+: What You Need to Know?
Short answer
.NET Framework is the older Windows-only runtime used mainly for legacy desktop and ASP.NET apps. .NET Core became the cross-platform, open-source line, and .NET 5+ unified it into the modern .NET platform for Windows, Linux, macOS, cloud, web, desktop, and mobile workloads.
- What is the Common Language Runtime (CLR)?
Short answer
The Common Language Runtime (CLR) is the runtime environment for .NET applications, and it is responsible for managing the execution of programs written in languages like C#. It provides essential services such as memory management, security enforcement, exception handling, and garbage collection.
- What is the Common Type System (CTS)?
Short answer
The Common Type System (CTS) defines how types are declared, used, and managed in the .NET runtime. By providing a common framework for type definitions and operations, the CTS ensures interoperability between languages.
- What is the Common Language Specification (CLS)?
Short answer
The Common Language Specification (CLS) is a set of rules and constraints that languages must adhere to to be compatible with the .NET framework. It ensures that code written in one language can be interoperated with any language supported by .NET.
- What is a Just-In-Time (JIT) compilation in .NET?
Short answer
Just-In-Time (JIT) compilation is the process by which the Common Language Runtime (CLR) or CoreCLR converts Intermediate Language (IL) code into native machine code specific to the operating system and CPU architecture at runtime, just before execution.
- Explain the Native AOT (Ahead-of-Time)
Short answer
Native AOT (Ahead-of-Time) Compilation in .NET 8+ allows applications to be compiled directly to native machine code before execution, bypassing the Just-In-Time (JIT) compilation traditionally performed at runtime.
- What are assemblies in .NET? Explain the Global Assembly Cache (GAC).
Short answer
An assembly is a compiled .NET unit, usually a DLL or EXE, containing IL, metadata, resources, and dependency information. The Global Assembly Cache (GAC) is the machine-wide store for strongly named shared assemblies in .NET Framework; modern .NET mostly uses app-local and NuGet-based deployment instead.
- What is the Difference Between Managed and Unmanaged Code?
Short answer
Managed code runs under the CLR/CoreCLR, which provides garbage collection, type safety, exception handling, and runtime services. Unmanaged code runs directly outside the CLR, so the developer or native runtime is responsible for memory, lifetime, and low-level resource management.
- Explain the difference between Value Types and Reference Types in .NET.
Short answer
Value types store data directly and are typically allocated on the stack, including types like int, double, and structs. Reference types store references to the actual data, which is allocated on the heap, including types like class, interface, and delegate.
- What is Garbage Collection in .NET, and how does it work?
Short answer
Garbage Collection (GC) in .NET is an automatic memory management feature that reclaims memory occupied by objects no longer in use, preventing memory leaks and simplifying development. It operates on a generational approach, categorizing objects based on lifespan to optimize performance.
- What is the difference between an Abstract Class and an Interface in C#?
Short answer
An abstract class can provide both abstract (unimplemented) and concrete (implemented) methods, enabling shared code among related classes while preventing instantiation. An interface defines a contract with methods, properties, events, or indexers that implementing classes must fulfill.
- Explain the concept of Boxing and Unboxing in C#
Short answer
Boxing converts a value type (e.g., int, double) to a reference type (object), while unboxing is the reverse process, converting a reference type back to a value type. Boxing wraps the value inside an object, and unboxing extracts the value from the object.
- What is the difference between const and readonly in C#?
Short answer
const values are compile-time constants and are substituted into consuming assemblies, so they are best for values that truly never change. readonly fields are assigned at declaration or in a constructor and are evaluated at runtime, so they are safer for values that may vary per instance or version.
- What is the purpose of the using statement in C#?
Short answer
The using statement serves two purposes: it allows for the inclusion of namespaces, enabling access to classes and methods within those namespaces, and it provides a means to ensure the correct use of IDisposable objects by automatically disposing of them when they are no longer needed, thus managing unmanaged resources efficiently.
- What is Exception Handling in C#, and how is it implemented?
Short answer
Exception handling in C# is a mechanism for handling runtime errors, ensuring the application's normal flow is maintained. It is implemented using try, catch, finally, and throw keywords.
- What is the difference between throw and throw ex in C#?
Short answer
Using throw rethrows the current exception while preserving the original stack trace, which is crucial for debugging. Using throw ex resets the stack trace, making it appear as though the exception from the throw ex statement, which can obscure the original error location.
- What is the difference between finalize and dispose methods in .NET?
Short answer
Finalize is a non-deterministic cleanup hook run by the garbage collector before reclaiming an object, mainly as a last resort for unmanaged resources. Dispose is deterministic cleanup called explicitly or by using/await using, and it should release unmanaged resources promptly.
- What are extension methods in C#, and how are they used?
Short answer
Extension methods in C# allow you to "extend" an existing class with new methods without altering its source code or creating a derived class. This feature is useful for adding functionality to third-party libraries or built-in types.
- Describe how Source Generators work in C#
Short answer
Source Generators, introduced in C# 9 and .NET 5, are compile-time components that inspect user code and generate additional source code during compilation. They enable metaprogramming by analyzing existing code to produce new code, enhancing performance by reducing or eliminating runtime reflection and minimizing boilerplate.
- What is reflection in C#, and what are its typical use cases?
Short answer
Reflection in C# allows inspection of assemblies, types, methods, properties, and fields at runtime, enabling dynamic instantiation of types, method invocation, or attribute access without compile-time knowledge.
- Explain the concept of delegates and events in C#
Short answer
Delegates in C# represent method references, enabling methods to be passed as parameters and invoked indirectly. Events are built on delegates and allow classes to notify subscribers about occurrences or state changes.
- What is the difference between early binding and late binding in C#?
Short answer
Early binding resolves members at compile time, giving type safety, IntelliSense, and better performance. Late binding resolves members at runtime, commonly through dynamic or reflection, which is more flexible but slower and less safe.
- What is the difference between ref and out parameters in C#?
Short answer
ref parameters must be definitely assigned before the call and may be read and written by the called method. out parameters do not need an initial value before the call, but the method must assign them before returning.
- What is the purpose of the params keyword in C#?
Short answer
The params keyword allows a method to accept a variable number of arguments as a single parameter, simplifying the method call when the exact number of arguments is unknown or variable. The parameters are passed to the method as an array.
- What is the purpose of the static keyword in C#?
Short answer
The static keyword in C# denotes that a member (method, property, field) or a class belongs to the type rather than any specific instance. This means static members are shared across all instances and can be accessed without creating an object of the class.
- Explain the concepts of Covariance and Contravariance in .NET.
Short answer
Covariance lets code use a more derived output type where a base type is expected, such as IEnumerable<string> as IEnumerable<object>. Contravariance works in the opposite direction for inputs, such as using an Action<object> where an Action<string> is needed.
- What is Dependency Injection (DI), and why is it essential in .NET?
Short answer
Dependency Injection (DI) is a design pattern that implements Inversion of Control (IoC). It allows an object's dependencies to be injected at runtime rather than hardcoded, promoting loose coupling, enhancing testability, and improving maintainability.
- Explain immutability in C# and how record help achieve it.
Short answer
Immutability means an object cannot be changed after construction, which makes code easier to reason about and safer for concurrency. Records help by providing value-based equality, init-only properties, and with-expressions for creating modified copies instead of mutating the original.
- What is Pattern Matching in C#, and where is it used?
Short answer
Pattern matching in C# enhances the ability to inspect and deconstruct data types, enabling more expressive and concise code. Introduced in C# 7.0 and expanded in later versions, pattern matching allows for checking an object's shape and extracting data from it.
- What are Primary Constructors in C# 12, and how do they differ from traditional constructors?
Short answer
Primary constructors in C# 12 allow developers to define constructor parameters directly within the class or struct declaration, streamlining initialization and reducing boilerplate code. This feature was previously limited to record types but is now extended to all classes and structs.
- Explain the Collection Expressions introduced in C# 12. How do they simplify collection initialization?
Short answer
Collection expressions in C# 12 introduce concise syntax for initializing collections, allowing developers to create lists, arrays, and other collection types in a more readable, succinct format.
- Describe the enhancements made to Pattern Matching in C# 12
Short answer
Pattern matching lets C# test an object against a shape and extract values directly in is expressions and switch expressions. List patterns were introduced in C# 11, while later versions continued refining pattern-related syntax and compiler support.
- What is the purpose of the new 'field' keyword introduced in C# 12?
Short answer
The field contextual keyword lets a property accessor refer to the compiler-generated backing field of an auto-property. It reduces boilerplate when you need validation or normalization in an accessor without manually declaring a private field.
- What are the new LINQ methods CountBy and AggregateBy in .NET 9, and how do they enhance data querying?
Short answer
CountBy groups elements by a key and returns each key with its count without writing a full GroupBy expression. AggregateBy groups by a key and applies a custom accumulator per group, making common aggregation queries shorter and clearer.
- What new cryptographic features have been added in .NET 9?
Short answer
.NET 9 added cryptography improvements around modern algorithms and platform support, including better one-shot hashing/MAC APIs and broader post-quantum/hybrid cryptography preparation in the platform. The practical benefit is safer, faster, and more consistent crypto code across operating systems.
- How do you implement monitoring and logging mechanisms in C# to track program operation and detect problems?
Short answer
Implementing custom monitoring and logging in C# involves using the built-in ILogger interface or creating custom logging providers to record application behavior, which aids in tracking operations and diagnosing issues.
- How does the Equals method work?
Short answer
The Equals method in C# determines whether two object instances are considered equal. The default implementation checks for reference equality but can be overridden to provide value-based equality.
- How do we dynamically use type indexing in C# to create objects and call methods at runtime?
Short answer
Type indexing refers to dynamically accessing types, creating instances, and invoking methods at runtime using reflection. This technique is beneficial when the types or methods are unknown at compile time.
- What are Dynamic Types in C#?
Short answer
Dynamic types in C# allow developers to bypass compile-time type checking using the dynamic keyword, with type resolution occurring at runtime. This enables flexible coding scenarios, such as interacting with dynamic languages or COM objects, but introduces performance overhead due to runtime binding.
- What is the Dynamic Language Runtime (DLR)?
Short answer
The Dynamic Language Runtime (DLR) is a set of libraries in .NET that provides infrastructure for dynamic typing and execution, enabling features like the dynamic keyword in C# and interoperability with dynamic languages such as Python and JavaScript.
- What are symbolic links in .NET? How do you create symbolic links in .NET?
Short answer
Symbolic links are advanced shortcuts. When you create a symbolic link to an individual file or folder, Windows will perceive it as the same file or folder—even though it's just a link pointing at the file or folder.
- What are the required members in C#, and why were they introduced?
Short answer
required is a modifier introduced in C# 11 that forces callers to set a property or field during object initialization. If you forget to set it, the compiler will give errors.
- What is trimming in .NET, and why is it important for modern cloud-native applications?
Short answer
Trimming is a publish-time optimization that removes unused code from your application. The .NET SDK analyzes which types, methods, and assemblies your app actually uses, then strips everything else from the output.
- How does ReadyToRun (R2R) differ from JIT and Native AOT?
Short answer
JIT compiles IL to native code at runtime, giving good peak optimization but adding startup cost. ReadyToRun precompiles much of the app to improve startup while still allowing JIT fallback, whereas Native AOT produces a self-contained native binary with faster startup and smaller deployment trade-offs but more reflection/dynamic-code limits.
- What is Profile Guided Optimization (PGO), and how does it improve .NET performance?
Short answer
Profile Guided Optimization uses runtime or training-profile data to optimize hot paths instead of treating all code equally. In modern .NET, Dynamic PGO lets the JIT use live execution data to improve inlining, devirtualization, and code layout while the app runs.
- What are the new File-Based Apps introduced in .NET 10?
Short answer
.NET 10 lets you write a complete app in a single .cs file with no project file, no Program.cs, no .csproj. Run it directly with dotnet run app.cs.
- What are Extension Members in C# 14, and how do they differ from Extension Methods?
Short answer
Extension methods add instance-style methods to existing types through static methods with a this parameter. C# 14 extension members generalize the idea with extension blocks that can add methods, properties, operators, and static extensions in a more natural syntax.
- What is the new null-conditional assignment operator in C# 14?
Short answer
??= assigns only when the target is null. C# 14 adds null-conditional assignment, such as customer?.Name = value, which performs the assignment only when the receiver is not null.
- What are partial properties and partial events in C# 14?
Short answer
Partial properties and partial events split a member declaration from its implementation across partial type declarations. They are mainly useful for source generators, where handwritten code declares the API and generated code supplies the implementation.
Types and Type Features

The detailed answers with diagrams and explanations of what Junior/Middle/Senior should know for the questions below, can be found in our separate article: C# / .NET Interview Questions and Answers: Part 2 – Types and Type Features
- What is the purpose of the dynamic keyword in C#, and how does it differ from var?
Short answer
var is statically typed: the compiler infers the type once, then checks all member access at compile time. dynamic defers binding until runtime, which is useful for COM, reflection-like, or dynamic data scenarios but loses compile-time safety and adds overhead.
- What are Tuples in C#, and what is their use case?
Short answer
In C#, a tuple is a data structure that groups multiple elements, potentially of different types, into a single object. This allows for the convenient handling of related data without defining a separate class or structure.
- How does the Span<T> type improve performance in C#?
Short answer
Span<T> provides a safe, efficient way to work with slices of data without copying them. It represents a contiguous region of memory (stack, heap, or unmanaged) and enables high-performance operations, such as parsing, slicing, and processing, without requiring allocations.
- Explain the role of the default literal in C# and its use cases.
Short answer
The default literal (default) was introduced in C# 7.1. Instead of writing default(T) (verbose), you can write default, and the compiler infers the type.
- What is an Expression Tree?
Short answer
An expression tree in C# is a data structure that represents code in a tree-like format, where each node denotes an expression, such as a method call, binary operation, or constant value.
- What are records in C#, and how do they simplify immutable type design?
Short answer
Records in C# provide a concise syntax for creating immutable reference types or value types with built-in support for value-based equality. They simplify the definition of data-centric classes by automatically implementing methods like equality checks (Equals), hashing (GetHashCode), and readable output (ToString).
- What are ref locals and ref returns in C#, and how do they differ from regular variables?
Short answer
ref locals and ref returns store or return a reference to existing storage instead of copying the value. Regular variables hold their own value or object reference, while ref variables can mutate the original variable, array element, or struct field directly.
- What is a readonly struct, and how does it differ from a regular struct?
Short answer
A readonly struct in C# explicitly prevents modification after construction by enforcing immutability. It guarantees that all instance members do not modify the state, thereby helping to improve performance and reduce bugs related to accidental state changes.
- Explain the concept of nullable reference types introduced in C# 8.0.
Short answer
Nullable reference types, introduced in C# 8.0, enhance code safety by allowing developers to explicitly specify whether a reference type variable may be null, helping to catch potential null-related issues at compile time and reducing runtime NullReferenceException errors.
- What are nullable value types, and how are they used?
Short answer
Nullable value types, written T?, let value types such as int, bool, or DateTime also represent null. They are used when a value may be missing, optional, or unknown, while still keeping the underlying value-type semantics when a value exists.
- What are generics in C#, and what problems do they solve?
Short answer
Generics enable the creation of classes, methods, and interfaces with a placeholder for the data type, promoting code reusability, type safety, and performance by eliminating the need for type casting and boxing.
- What are anonymous types, and when would you use them?
Short answer
Anonymous types are unnamed classes created on the fly using the new keyword with object initializers. They are typically used for encapsulating a set of read-only properties into a single object without explicitly defining a type, often in LINQ queries.
- What is the difference between struct and class in C#?
Short answer
In C#, a struct is a value type, while a class is a reference type. This core difference influences how they are stored in memory, their performance characteristics, and their behavior during assignment and method calls.
- What are enums, and how do you use them?
Short answer
An enum (enumeration) defines a set of named constants, improving code readability and type safety when working with a fixed set of related values.
- What are attributes in C#, and how are they applied?
Short answer
Attributes in C# are metadata annotations that provide additional information about code elements (classes, methods, properties, etc.). They can influence program behavior at runtime or during compilation.
- What is the purpose of the sealed keyword?
Short answer
The sealed keyword in C# is used to prevent a class from being inherited or a method from being overridden, enhancing security and performance.
- What are partial types, and what are their benefits?
Short answer
A partial type lets a single class, struct, or interface be split across multiple files using the partial keyword, with the compiler merging them into one type. The main benefit is separating generated code (designers, source generators) from hand-written code so neither overwrites the other.
- What is the difference between as and explicit casting?
Short answer
as returns null when a reference or nullable conversion fails, so it is useful for safe probing without exceptions. Explicit casts throw InvalidCastException on failure and also support conversions that as cannot use, such as numeric casts and user-defined conversions.
- What are type constraints in generics?
Short answer
Type constraints in generics restrict what types can be used with a generic class, method, or interface. They allow you to enforce requirements like "must be a class," "must have a parameterless constructor," or "must inherit from a specific base type.".
- Why is it important to override Equals() and GetHashCode() for value types?
Short answer
By default, value types in C# compare by value, but when you customize equality (e.g., in a struct used in dictionaries or sets), You should override Equals() and GetHashCode() to ensure correct comparisons and performance.
- What are the benefits and Use Cases of the init accessor introduced in C# 9.0?
Short answer
The init accessor, introduced in C# 9.0, allows properties to be assigned during object initialization but makes them immutable, preventing modifications after construction. This feature simplifies the creation of immutable types by enabling concise object initialization while ensuring data integrity.
- What is stackalloc, and how does it optimize memory allocation?
Short answer
stackalloc allocates a block of memory on the stack instead of the heap. Stack memory is much faster to allocate and deallocate compared to heap memory because it follows a simple LIFO (Last-In, First-Out) model.
- How do with expressions simplify creating modified copies of immutable objects?
Short answer
A with expression allows creating a new object based on an existing one, copying all properties except those you want to change.
- What is a target-typed new expression, and when should you use it?
Short answer
Target-typed new lets you omit repeating the type on the right-hand side when the type is already known from the left-hand side.
- What is the fixed statement in C#, and when would you use it?
Short answer
The fixed statement pins an object in memory, preventing the garbage collector from moving it. It’s used when you need to work with unsafe code, like interacting with native APIs or pointers.
- How can you suppress nullable warnings using the null-forgiving operator !?
Short answer
The null-forgiving operator (!) tells the compiler "I know this value isn't null" even if its type says it could be.
- What is the difference between float, double, and decimal in C#?
Short answer
float is a 32-bit binary floating-point type, double is a 64-bit binary floating-point type, and both are suited to scientific or approximate calculations. decimal is a 128-bit base-10 type with higher decimal precision, making it the usual choice for money and financial values.
- What are nint and nuint types in C#, and when are they useful?
Short answer
nint (native int) and nuint (native unsigned int) are integer types whose size depends on the platform.
- What is a ref struct in C#, and why are they restricted to the stack?
Short answer
A ref struct is a structure that must live on the stack, not the heap. They are designed for high-performance scenarios where memory safety and no garbage collection (GC) pressure are required.
- What is the purpose of the unmanaged constraint in generics?
Short answer
The unmanaged constraint ensures that a generic type parameter is a blittable type — a type that can be copied directly in memory without transformation. Useful for interop, unsafe code, and low-level memory operations.
- What are function pointers (delegate*) in C#, and when would you use them?
Short answer
Function pointers (delegate*) allow you to call functions via raw pointers instead of using Delegate objects. Introduced in C# 9 for maximum performance and interop.
- What are static abstract interface members, and how do they enable Generic Math in .NET?
Short answer
Static abstract (and static virtual) interface members let an interface declare static operations — such as operators or factory methods — that implementing types must provide. This is what powers Generic Math, allowing generic code to constrain a type parameter to interfaces like INumber<T> and call +, -, or * on it.
- What problem does Generic Math solve in .NET?
Short answer
Generic Math solves the long-standing inability to write numeric algorithms once and reuse them across int, double, decimal, and other numeric types. By constraining a generic parameter to interfaces like INumber<T>, you can call arithmetic operators generically instead of duplicating code per type.
- What is the difference between shallow immutability and deep immutability?
Short answer
Shallow immutability means a type's own fields cannot be reassigned, but objects they reference may still be mutated. Deep immutability means the entire object graph is unchangeable, which requires every referenced type to also be immutable.
- What is the difference between EqualityComparer<T>.Default, Equals(), and ReferenceEquals()?
Short answer
Equals() performs the type's defined equality (value-based when overridden), while ReferenceEquals() always checks whether two references point to the same object. EqualityComparer<T>.Default provides the runtime's default comparer for a type — honoring IEquatable<T> and avoiding boxing — and is what generic collections use internally.
Collections and Data Structures

The detailed answers with diagrams and explanations of what Junior/Middle/Senior should know for the questions below, can be found in our separate article: C# / .NET Interview Questions and Answers: Part 3 – Collections and Data Structures
- What Is Big O Notation, and Why Is It Important in C# Collections?
Short answer
Big O Notation is a mathematical concept used to describe the efficiency of algorithms, particularly in terms of time and space complexity. It provides a high-level understanding of how an algorithm's performance scales with the size of the input data.
- Can you explain and compare the efficiency of .NET collections?
Short answer
Collection efficiency is compared with Big O for common operations: List<T> gives O(1) indexed access but O(n) inserts/removals in the middle, Dictionary<TKey,TValue> and HashSet<T> give amortized O(1) lookups, and LinkedList<T> gives O(1) insert/remove given a node but O(n) search. Choosing the right collection means matching these complexities to your access pattern.
- Explain the difference between a one-dimensional and a multidimensional array in C#
Short answer
A one-dimensional array stores a single sequence of elements indexed by one value, while a multidimensional array (int[,]) stores a rectangular grid indexed by two or more values. Multidimensional arrays differ from jagged arrays (int[][]), which are arrays of arrays whose rows can have different lengths.
- What are Inline Arrays in C# 12, and what advantages do they offer?
Short answer
C# 12.0 enables us to define data types that support array syntax but work like normal value types in that they don't need to have their own dedicated heap objects. We can use inline array types as local variables or fields, enabling more efficient memory usage than might be possible with ordinary arrays.
- What is the difference between jagged and multidimensional arrays in C#?
Short answer
A jagged array is an array of arrays, so each inner array can have a different length and is accessed like data[i][j]. A multidimensional array is one rectangular block indexed like data[i, j], which is simpler for fixed grids but less flexible for uneven rows.
- What is ArrayPool<T> in C#, and how does it optimize array memory usage?
Short answer
ArrayPool<T> is a high-performance, thread-safe mechanism introduced in .NET Core to minimize heap allocations by reusing arrays. It’s especially beneficial in scenarios involving frequent, short-lived array allocations, such as processing large data streams or handling numerous requests in web applications.
- What is array covariance in C#, and its potential pitfalls?
Short answer
Array covariance in C# allows an array of a derived type to be assigned to an array of its base type.
- Why are strings immutable in C#, and what are the implications for collections?
Short answer
In C#, string is immutable, meaning its value cannot be changed once created. Every operation like Replace(), ToUpper(), or Substring() Returns a new string, not a modified one.
- What is the difference between String and StringBuilder in C#?
Short answer
In C#, String is immutable, meaning any modification creates a new instance, which can be inefficient for frequent changes. StringBuilder is mutable, designed for scenarios requiring numerous modifications to the string content, offering better performance by minimizing memory allocations.
- What is string interning in C#, and when should you use String.Intern()?
Short answer
String.Intern() stores only one copy of each unique string literal in memory. If two strings have duplicate content, they can share the same reference, reducing memory usage.
- What are the differences between List<T> and arrays in C#?
Short answer
Arrays have a fixed length and minimal overhead, making them good for stable-size data and interop scenarios. List<T> wraps a resizable array, adds convenient methods like Add and Remove, and is usually preferred when the number of items changes.
- What is LinkedList<T>, and how does it differ from List<T>?
Short answer
LinkedList<T> is a doubly linked list where each element points to the next and previous elements. In contrast, List<T> is a dynamic array that stores elements contiguously in memory.
- When would you choose LinkedList<T> over List<T> based on performance?
Short answer
Use LinkedList<T> when: Frequent insertions/deletions in the middle or ends are needed (O(1) If you have a reference. Constant-time additions to the start (AddFirst) or removal without shifting elements.
- What are the primary differences between a stack and a queue?
Short answer
A stack is LIFO: the last item pushed is the first item popped. A queue is FIFO: the first item enqueued is the first item dequeued.
- What is PriorityQueue<TElement, TPriority> collection, and how does it work?
Short answer
PriorityQueue<TElement, TPriority> is a collection introduced in .NET 6. It lets you store elements with an associated priority, always dequeuing the element with the smallest priority value first.
- What is a Dictionary, and when should we use it?
Short answer
A Dictionary<TKey, TValue> in C#, a hash-based collection stores key-value pairs, allowing fast access to values via their unique keys. It’s part of System.Collections.Generic.
- What is SortedDictionary<TKey, TValue>, and how does it differ from Dictionary<TKey, TValue>?
Short answer
SortedDictionary<TKey,TValue> stores key-value pairs ordered by key and gives O(log n) lookup, insert, and remove. Dictionary<TKey,TValue> is hash-based, usually O(1), but it does not maintain sorted key order.
- What is SortedSet<T>, and how does it differ from HashSet<T>?
Short answer
If you’ve ever used a HashSet<T> in C#, you already know it’s great for checking whether something exists — fast, efficient, no duplicates. But it doesn't care about order.
- How do you implement a custom key type for a Dictionary<TKey, TValue>?
Short answer
Using your class or struct as a dictionary key in C# is valid but comes with a catch. The dictionary needs a way to compare keys and compute hash codes.
- What is a binary search tree, and how would you implement one in C#?
Short answer
A binary search tree (BST) is a tree where each node has up to two children. The key rule: for any node, values in the left subtree are smaller, and values in the right subtree are larger.
- What are the differences between IEnumerable<T>, ICollection<T>, and IList<T> interfaces?
Short answer
IEnumerable<T> only supports iteration, ICollection<T> adds Count and basic add/remove/contains operations, and IList<T> adds index-based access and insertion. Choose the smallest interface that exposes the behavior the caller actually needs.
- What is IReadOnlyCollection<T>, and when would you use it?
Short answer
IReadOnlyCollection<T> is a read-only interface that represents a collection you can iterate over and count — but not modify.
- What is IReadOnlyList<T>, and how does it differ from IReadOnlyCollection<T>?
Short answer
IReadOnlyCollection<T> exposes Count and enumeration only. IReadOnlyList<T> adds index-based access, so use it when callers need stable positional lookup without mutation.
- How does managing List<T> initial capacity improve performance?
Short answer
Setting an initial capacity List<T> can prevent hidden performance traps in high-throughput or memory-sensitive scenarios.
- What is HashSet<T>, and when would you choose it over List<T>?
Short answer
HashSet<T> is a collection that stores unique elements and offers fast lookups. A hash table backs it, so Add, Remove, and Contains operations are typically O(1) — much faster than searching in a List<T>, which is O(n).
- How does Dictionary<TKey, TValue> handle key collisions??
Short answer
When two keys produce the same hash code (a hash collision), Dictionary<TKey, TValue> handles it behind the scenes using chaining — essentially, it stores multiple entries in the same bucket.
- What is ImmutableList<T>, and when should you use it in C#?
Short answer
ImmutableList
is a collection that never changes after it’s created. Every operation that would normally modify the list, such as Add, Remove, or Insert, instead returns a new list with the change applied. - What is ObservableCollection<T>, and how does it differ from List<T> in the UI applications?
Short answer
ObservableCollection<T> is like List<T>, but with a "superpower": it notifies UI frameworks (like WPF or MAUI) when its contents change. Add, remove, or move an item — the UI instantly knows about it.
- What is ConcurrentDictionary<TKey, TValue>, and how does it differ from Dictionary<TKey, TValue>?
Short answer
ConcurrentDictionary<TKey, TValue> is a thread-safe alternative to Dictionary<TKey, TValue>. It's designed for concurrent access, meaning multiple threads can read and write to it safely, without needing external locks.
- How do atomic operations like GetOrAdd work in ConcurrentDictionary<TKey, TValue>?
Short answer
One of the biggest headaches in multi-threaded code is race conditions — two threads checking and adding the same key simultaneously. That’s where atomic methods like GetOrAdd come in.
- What is ConcurrentQueue<T>, and when would you use it in multi-threaded scenarios?
Short answer
ConcurrentQueue<T> is a thread-safe, FIFO (first-in, first-out) queue built for multi-threaded applications. It lets multiple threads enqueue and dequeue items safely, without needing locks.
- What is ImmutableArray<T>, and how does it differ from List<T>?
Short answer
ImmutableArray<T> It is a fixed-size, read-only array that can’t be changed after creation. Unlike List<T>, which you can grow, shrink, or modify freely, ImmutableArray<T> is all about predictability, safety, and performance — especially in multi-threaded or functional-style code.
- What is ReadOnlyCollection<T>, and what are its limitations?
Short answer
ReadOnlyCollection<T> is a wrapper around an existing list that prevents modification through its public API. It’s useful when you want to expose a collection as read-only, but still keep full control internally.
- How does LINQ interact with collections, and what are common performance pitfalls?
Short answer
LINQ (Language Integrated Query) provides a clean way to query and transform collections in C#. It works with any type that implements IEnumerable<T> or IQueryable<T>.
- What is Memory<T>, and how does it enhance collection performance?
Short answer
Memory<T> is a powerful .NET type that lets you work with slices of data without copying it. It’s like Span<T>, but with one big difference: it’s safe to use asynchronously and can be stored in fields, returned from methods, and awaited across calls.
- What are the implications of value vs. reference types in collection performance?
Short answer
In C#, value types (struct) and reference types (class) behave very differently, especially when used in collections. These differences affect memory layout, CPU usage, GC pressure, and comparisons.
- What are FrozenDictionary<TKey,TValue> and FrozenSet<T>, and when should you use them?
Short answer
FrozenDictionary and FrozenSet are immutable collections introduced in .NET 8 that are optimized at construction time for extremely fast, read-only lookups. Use them for data built once and read many times — such as lookup tables or caches — where the higher creation cost pays off in faster reads.
- FrozenDictionary vs Dictionary vs ImmutableDictionary vs ReadOnlyDictionary. When should you choose each?
Short answer
Use Dictionary for general read/write data, ReadOnlyDictionary to expose an existing dictionary as a read-only view, and ImmutableDictionary when you need safe, persistent snapshots with cheap copy-on-write updates. Choose FrozenDictionary for write-once data read very frequently, where the one-time build cost buys the fastest lookups.
- What is Lookup<TKey,TElement>, and how does it differ from Dictionary<TKey,List<T>>?
Short answer
Lookup<TKey,TElement> is an immutable, one-to-many collection (built via ToLookup) that maps each key to a sequence of values. Unlike Dictionary<TKey,List<T>>, it is read-only after creation and safely returns an empty sequence for a missing key instead of throwing.
Async & parallel

The detailed answers with diagrams and explanations of what Junior/Middle/Senior should know for the questions below, can be found in our separate article: C# / .NET Interview Questions and Answers: Part 4 – Async & Parallel Programming
- What is Runtime Async in .NET 11, and how does it differ from the traditional async/await implementation?
Short answer
Runtime Async moves async method transformation from a compiler-generated state machine into the runtime itself, letting the JIT and runtime handle suspension and resumption directly. Compared to the traditional compiler-generated state machine, it aims to reduce allocations and overhead and to make async a first-class runtime concept.
- What is the difference between asynchronous programming using async/await and traditional multithreading?
Short answer
Async/await frees the calling thread while waiting on I/O (network, disk, database) by letting the runtime resume the method later via a continuation, often without using any extra thread at all. Traditional multithreading creates and manages separate threads to run CPU-bound work in parallel, which incurs higher memory and context-switching costs. Use async/await for I/O-bound work and multithreading (or Task.Run with parallelism) for CPU-bound work.
- What is the relationship between a Task and the .NET ThreadPool?
Short answer
A Task represents an asynchronous operation that may or may not execute on a thread. When tasks involve CPU-bound operations, they typically run on the .NET ThreadPool.
- How does the C# compiler transform an async method under the hood (state-machine generation, captured context, etc.)?
Short answer
The C# compiler converts async methods into a state machine behind the scenes. Each await becomes a checkpoint within this state machine, capturing the method's state and the synchronization context, allowing execution to pause and resume seamlessly without blocking the calling thread.
- Explain the purpose of SynchronizationContext and how it affects continuation scheduling in async/await
Short answer
SynchronizationContext represents an environment that controls where continuations run, such as a UI thread in WPF/WinForms or a request context in older ASP.NET. By default, await captures it and resumes there; ConfigureAwait(false) avoids that capture when the continuation does not need the original context.
- What problems can arise if you mix synchronous blocking (Task.Wait, .Result) with asynchronous code, and how do you avoid them?
Short answer
Mixing them risks deadlocks, since .Wait()/.Result blocks the calling thread while it waits for the async method to complete, but in contexts with a synchronization context (like older ASP.NET or WPF/UI threads) the continuation needs that same thread to resume, so neither side can proceed. It can also cause thread pool starvation, as blocked threads sit idle while waiting rather than being returned to the pool. Avoid this by using async/await all the way down, and if you must bridge sync and async code, use ConfigureAwait(false) or call Task.Run to offload the blocking call.
- How does TaskCompletionSource let you wrap callback-based APIs as tasks, and what pitfalls should you watch for?
Short answer
TaskCompletionSource lets callback-, event-, or thread-based APIs expose a Task by manually completing, canceling, or faulting it. Watch for completing it twice, forgetting to propagate exceptions/cancellation, and running continuations inline unless RunContinuationsAsynchronously is used.
- What are fire-and-forget tasks, why are they risky, and how can you safely monitor/handle their failures?
Short answer
A fire-and-forget task is an asynchronous operation started without awaiting or monitoring its completion. This pattern can seem convenient when results aren't immediately needed, but it introduces risks such as unhandled exceptions.
- What is the difference between Task and ValueTask in asynchronous programming, and when should you prefer one over the other?
Short answer
Task is a reference type and is the default choice for most asynchronous APIs, especially when the operation usually completes asynchronously. ValueTask can avoid allocations when results are often already available, but it is harder to consume correctly and should be used only on hot paths where measurement shows a benefit.
- How do you cancel an asynchronous operation in .NET, and what are the best practices for using cancellation tokens?
Short answer
Use a CancellationTokenSource to create a token, pass it to async methods, and check it with the token.ThrowIfCancellationRequested() or by passing it to cancelable APIs (like Task.Delay, HTTP calls, EF Core queries). Best practices: always accept CancellationToken as the last parameter, propagate it through the whole call chain rather than swallowing it, dispose the CancellationTokenSource, and avoid catching OperationCanceledException silently unless cancellation is expected behavior at that boundary.
- Describe how IAsyncDisposable works and when you would implement it.
Short answer
IAsyncDisposable is an interface in .NET introduced in C# 8.0 that allows objects holding unmanaged or asynchronous resources to be disposed asynchronously. It's useful when cleanup tasks involve asynchronous operations, such as network streams, database connections, or files, where synchronous disposal could cause performance issues.
- How does an async iterator (IAsyncEnumerable<T>) differ from a synchronous iterator
Short answer
IAsyncEnumerable<T> allows elements to be produced and consumed asynchronously, whereas a synchronous iterator (IEnumerable<T>) blocks the calling thread while producing elements. Async iterators are particularly useful for streaming data from slow or latency-prone sources, such as network APIs, databases, or file systems.
- What are the methods of thread synchronization?
Short answer
Common synchronization mechanisms include lock/Monitor, Mutex, Semaphore/SemaphoreSlim, ReaderWriterLockSlim, ManualResetEvent, AutoResetEvent, Interlocked, and concurrent collections. Choose based on whether you need mutual exclusion, signaling, throttling, atomic updates, or reader/writer coordination.
- How does the lock work? Can structures be used inside a lock expression?
Short answer
lock enters a monitor for a reference object so only one thread can execute the protected block at a time. You cannot lock on a struct directly because boxing would create different objects; use a private readonly reference object or the newer Lock type instead.
- What is a race condition, and how can you detect and prevent it?
Short answer
A race condition occurs when two or more threads access shared data concurrently, and the outcome depends on the timing of their execution. This leads to unpredictable behavior, as the sequence of operations affects the program's correctness and reliability.
- What is the difference between Semaphore and SemaphoreSlim?
Short answer
Semaphore is a wrapper around a kernel-level OS synchronization object, so it can be used for cross-process synchronization (named semaphores), but it has higher per-call overhead. SemaphoreSlim is a lightweight, purely in-process (managed) construct optimized for fast, intra-process synchronization, with lower overhead and native support for async waiting via WaitAsync(). Use SemaphoreSlim for almost all in-app concurrency limiting, and Semaphore only when you need cross-process coordination.
- Compare ReaderWriterLockSlim with a simple lock (monitor) for protecting shared data.
Short answer
lock is simplest and fastest when every access is exclusive and the critical section is short. ReaderWriterLockSlim can help when reads are frequent, writes are rare, and the protected work is large enough to justify its extra complexity and overhead.
- When would you choose a ManualResetEventSlim over a SemaphoreSlim, and what are the memory/performance trade-offs?
Short answer
Use ManualResetEventSlim when one signal should release one or many waiting threads, such as a start gate or readiness flag. Use SemaphoreSlim when you need to limit concurrent access to N operations; ManualResetEventSlim can spin briefly for speed, which may waste CPU if waits are long.
- Explain how CountdownEvent and Barrier Coordinate multi-stage work and provide a use case for each.
Short answer
CountdownEvent blocks waiters until its count is signaled down to zero, ideal for waiting until a fixed number of parallel tasks finish before continuing. Barrier synchronizes a set of threads that must all reach a point before any proceed, repeating across phases; ideal for multi-stage parallel computations, such as iterative simulations.
- How do deadlocks manifest in asynchronous code, and what techniques help you avoid them?
Short answer
Async deadlocks often happen when code blocks with .Result or .Wait() while the awaited continuation needs the same UI, WinForms/WPF, or legacy ASP.NET context to resume. Avoid them by using async all the way, awaiting instead of blocking, and using ConfigureAwait(false) in library code that does not need the captured context.
- How does Parallel.ForEachAsync improves over Parallel.ForEach, and what caveats exist for I/O-bound vs. CPU-bound loops?
Short answer
Parallel.ForEachAsync lets each loop body run async work natively, avoiding the sync-over-async trap of wrapping Tasks inside Parallel.ForEach with .Wait() or .Result. It accepts a ParallelOptions.MaxDegreeOfParallelism and a CancellationToken, making it a good fit for I/O-bound loops, such as batches of HTTP calls or DB queries. Caveat: for I/O-bound work, set MaxDegreeOfParallelism high since threads aren't blocked while awaiting; for CPU-bound work, keep it near Environment.ProcessorCount, since oversubscribing just adds context-switch overhead without real parallel gain.
- Explain PLINQ (AsParallel) merge options and how they impact ordering and throughput.
Short answer
PLINQ merge options control how worker results are buffered and returned to the consumer. NotBuffered streams results fastest, AutoBuffered balances throughput and latency, and FullyBuffered waits for all results and is often needed when preserving order with AsOrdered.
- What is a partitioner, and why is custom partitioning important for load balancing in parallel loops?
Short answer
A partitioner splits input data into chunks so parallel loops or PLINQ workers can process them concurrently. Custom partitioning improves load balancing when work items have uneven cost, avoiding idle threads while one partition still has expensive work left.
- Compare Parallel.Invoke with manually creating multiple Tasks joined by Task.WhenAll.
Short answer
Parallel.Invoke runs a fixed set of independent actions in parallel and blocks the calling thread until all complete, it's synchronous, simple, and good for a small known number of CPU-bound actions with no need to await or compose with other async work. Manually creating Tasks and joining with Task.WhenAll is asynchronous, non-blocking, lets you await the result, supports CancellationToken and exception aggregation via the awaited Task, and composes naturally with other async code. Use Parallel.Invoke for synchronous, CPU-bound fan-out in a non-async context, and Task.WhenAll when you're already in an async method or need cancellation, return values, or async work mixed in.
- What are the advantages and disadvantages of using value-type locals inside a highly parallel loop?
Short answer
Using value-type locals (i.e., structs like int, double, Span<T>) inside highly parallel loops, such as those with Parallel.For, Parallel.ForEach, or PLINQ—can improve performance, but also comes with trade-offs. Whether they help or hurt depends on their usage pattern and mutability.
- What is a Channel<T> in C#, and why should you use it?
Short answer
Channel<T> is a high-performance, thread-safe messaging primitive for asynchronous producer-consumer scenarios. Think of it as a pipeline one or more producers write messages into the channel, and one or more consumers read from it, without locks, queues, or blocking threads.
- When to use Channel<T>
Short answer
Use Channel<T> for async-compatible producer-consumer queues where you need back-pressure and controlled throughput, such as pipeline-style architectures or streaming data flows. It fits microservices, background jobs, logging pipelines, and event-processing systems well.
- When would you choose Channel<T> over other concurrency constructs?
Short answer
Choose Channel<T> when producers and consumers should communicate asynchronously with back-pressure, cancellation, and non-blocking reads/writes. It is a better fit than raw locks, ConcurrentQueue, or BlockingCollection for modern async pipelines and background processing.
- Compare System.Threading.Channels with BlockingCollection<T> for implementing producer-consumer patterns.
Short answer
Channel<T> is async-first, supports back-pressure, and avoids blocking threads while producers and consumers wait. BlockingCollection<T> is older and blocking-oriented, so it mainly fits synchronous producer-consumer code or legacy Thread/Task patterns.
- How do bounded vs. unbounded channels control memory growth, and when should you choose one over the other?
Short answer
Unbounded channels have no capacity limit, so the buffer grows as fast as producers write, which is simple, but a slow consumer can cause memory to spike and crash the app. Bounded channels cap capacity and apply back-pressure (writers wait, or items are dropped per the full-mode policy), so choose them whenever consumer speed varies, or memory must stay controlled.
- How do you gracefully shut down a channel-based pipeline without losing data?
Short answer
Call writer.Complete() on the producer side once no more items will be written (optionally passing an exception if shutting down due to an error). This signals to the channel that no more writes will happen, but lets consumers drain all items already buffered in the channel via await foreach over reader.ReadAllAsync(), which completes naturally once the channel is empty and marked complete. For multi-stage pipelines, propagate completion stage by stage: each stage waits for its upstream reader to complete, finishes its in-flight work, then calls Complete() on its own writer so the next stage knows to drain and stop.
- What are System.IO.Pipelines in .NET, and when would you use them instead of streams or channels?
Short answer
System.IO.Pipelines is a modern API designed for high-performance asynchronous streaming of binary data, particularly useful in scenarios involving low-level IO operations, network protocol implementations, or real-time data processing.
Design Patterns

The detailed answers with diagrams and explanations of what Junior/Middle/Senior should know for the questions below, can be found in our separate article: Part 5: Design Patterns – C# / .NET Interview Questions and Answers
- How do you detect and fix a God Object in a legacy .NET codebase?
Short answer
A God Object is a class that knows too much or does too much. It ends up being a dumping ground for logic, data, and side effects.
- Explain YAGNI ("You Aren't Gonna Need It") with an example from your past projects.
Short answer
YAGNI means not building functionality before it is actually needed, even if it might be useful later. For example, avoid creating a generic plugin architecture for a feature that currently has only one implementation; build the simple version first and extract abstractions only when a second real use case appears.
- What .NET engineers should know about YAGNI:
Short answer
👼 Junior: Should know what YAGNI means and avoid it where possible.
- What's the difference between DRY and the Single Responsibility Principle, and when might they conflict?
Short answer
DRY is about removing duplicated knowledge or logic, while SRP is about giving a module one reason to change. They conflict when deduplication merges concepts that only look similar but change for different business reasons.
- How can Low Coupling and High Cohesion from GRASP be measured or evaluated in a C# class design?
Short answer
Low coupling can be evaluated by counting a class's dependencies on other types (constructor parameters, references, and using directives), and high cohesion by checking that a class's members all serve one focused responsibility. Metrics such as efferent/afferent coupling and LCOM, available in tools like Visual Studio code metrics, help quantify both.
- How do Protected Variations and Pure Fabrication support extensible and decoupled architectures?
Short answer
Protected Variations shields the system from change by wrapping unstable points behind stable interfaces, so variation is absorbed without rippling through callers. Pure Fabrication introduces a convenient invented class (like a repository or service) that holds behavior for cohesion and decoupling when no domain concept fits, keeping responsibilities clean.
- Describe an instance of the Service Locator anti-pattern, and how you would convert it to Dependency Injection.
Short answer
The Service Locator hides dependencies by retrieving them from a container within the class. This makes the code harder to understand and test, because you can’t easily tell what the class depends on.
- What code smells indicate GRASP principle violations, and how did you refactor them?
Short answer
GRASP violations often show up as god classes, feature envy, service locator usage in domain logic, and large type-checking switch statements. Refactor by moving behavior to the information expert, introducing controllers/coordinators for use-case flow, and replacing type switches with polymorphism when appropriate.
- Can you explain what the SOLID principles are in practice?
Short answer
S – Single Responsibility Principle A class should have only one reason to change. For instance, if a class is responsible for both saving data to a file and validating input, it has taken on two responsibilities.
- How do you balance the Open/Closed Principle with frequent business changes in agile teams?
Short answer
The Open/Closed Principle (OCP) states that your code should be open for extension but closed for modification. In theory, this sounds great.
- What's the difference between an Anemic Domain Model and a strong Rich Domain Model? How can you prevent accidentally using the weaker one?
Short answer
An anemic domain model occurs when your domain classes are merely data containers with no behavior or logic. All the business logic resides elsewhere, typically in services.
- Can you explain the Richardson Maturity Model and how to evaluate the maturity of your APIs
Short answer
The Richardson Maturity Model (RMM) helps evaluate how "RESTful" your API is. It categorizes REST into four levels of maturity, ranging from basic HTTP usage to full hypermedia.
- How do you ensure thread safety in a Singleton implementation without compromising performance?
Short answer
In .NET, the safest and most performant way to implement a Singleton is to use the lazy initialization pattern with the help of the Lazy<T> type or a static constructor.
- Explain why Object Pool is helpful in .NET, and how to implement it.
Short answer
Object Pooling helps you reuse objects that are expensive to create or allocate, like buffers, StringBuilder, HttpClient or custom data processors.
- How do Decorator and Adapter interact in layered .NET microservices?
Short answer
They solve different problems and often stack together at a service boundary. Adapter translates one interface into another your code expects, for example wrapping a third-party SDK or legacy service client behind your own interface so the rest of the app isn't coupled to its shape. Decorator wraps an existing implementation of an interface to add behavior, like logging, caching, retry, or metrics, without changing its contract or the original class.
- Describe applying Composite in UI rendering or building tree-structured data.
Short answer
The Composite pattern allows you to treat individual objects and groups of objects uniformly. It’s perfect for UI trees, menus, or any structure with nested elements.
- Give a case for using a Facade over a direct service approach.
Short answer
A Facade is useful when you want to provide a simplified, unified interface to a complex system. Instead of calling multiple services directly from your controller or UI, you group them behind a facade.
- How can Flyweight be used in C#? Can you provide examples of implementation from the .NET?
Short answer
The Flyweight pattern is all about sharing memory-heavy objects that don’t change often. In C#, it helps when you have a lot of similar objects and want to avoid repeating the same data in memory.
- Which pattern is used under the hood for Middleware in ASP.NET Core?
Short answer
ASP.NET Core middleware is built using the Chain of Responsibility pattern.
- Where is Prototype dangerous in C# due to mutable state trees?
Short answer
Prototype's danger is shallow cloning: MemberwiseClone() copies only top-level fields, so nested collections and objects stay shared references between the clone and original. Mutating the clone's nested state silently mutates the original too. Avoid this by deep cloning nested mutable state explicitly, or favor immutable value objects in the tree.
- Compare Lazy Singleton with IOptionsMonitor for dynamic config scenarios.
Short answer
Lazy Singleton (via Lazy
or static field) creates one instance once and holds it for the app's lifetime, it's not designed to react to config changes, so any update requires an app restart or manual reset logic. IOptionsMonitor is built for dynamic config: it watches the underlying config source (like appsettings.json with reload-on-change, or Azure App Configuration) and pushes updates via OnChange, so consumers always get the current value without restarting. Use Lazy Singleton for expensive, truly static state; use IOptionsMonitor whenever config might change at runtime and code needs to react to it. - How to select when to use Abstract Factory vs DI and Func<T>?
Short answer
Abstract Factory fits when you need to create families of related objects whose concrete types vary together (e.g., swapping a whole set of UI controls or DB providers based on context), and that variation isn't naturally expressed through DI's single-object resolution. DI with Func
fits when you just need to defer or repeat creation of a single service at runtime, especially when the dependency has per-call state or a shorter lifetime than its consumer (e.g., creating a new DbContext per unit of work inside a singleton). Inject Func and DI resolves a fresh instance each call. - How could you implement Sidecar proxies for logging/security next to a .NET service?
Short answer
A Sidecar proxy is a small helper process that runs alongside your leading .NET service. Usually in the same container or pod, and handles cross-cutting concerns, such as logging, security, or traffic routing, without modifying your app code.
- When would you choose Database-per-Service, and how do you coordinate consistency?
Short answer
Database-per-Service is a microservice architecture pattern in which each service owns its database. This promotes autonomy and firm service boundaries, but also introduces challenges to data consistency.
- Describe in which scenarios it makes sense to implement the Event Sourcing pattern.
Short answer
Event Sourcing is a pattern where state is not stored as the latest snapshot, but instead as a sequence of domain events. The current state is rebuilt by replaying these events in order.
- Which patterns could be used for decomposing a monolith into macro/micro services?
Short answer
The goal of splitting a monolith into macro and microservices is to reduce risk, isolate responsibilities, and allow services to evolve independently.
- Have you had experience with Service Discovery (e.g., via Consul)?
Short answer
Service Discovery solves the problem of locating services dynamically in distributed systems, allowing services to communicate with each other without hardcoding IP addresses or URLs.
- How would you design a Rate Limiter pipeline using ASP.NET Core's RateLimiter middleware?
Short answer
ASP.NET Core provides built-in RateLimiter middleware to help protect your APIs from overuse, abuse, or accidental overload. You can configure fine-grained rate limits at the endpoint or pipeline level, without relying on external tools.
- Compare Sidecar vs Service Mesh. When does complexity pay off?
Short answer
A sidecar is a companion process deployed with one service instance to handle concerns such as proxying, logging, or configuration. A service mesh coordinates many sidecars with a control plane, and its complexity pays off only when cross-service traffic policy, mTLS, retries, and observability need consistent platform-level governance.
- Which type of project structure do you use to organize a .NET project?
Short answer
Each structure solves different problems. Choose based on domain complexity, team size, and delivery goals.
- Compare Vertical Slice Architecture with Feature-Folder
Short answer
Feature folders group files by feature but may still keep layered architecture inside each folder. Vertical Slice Architecture goes further by organizing each use case end-to-end, often with its request, handler, validation, and data access kept together to reduce cross-feature coupling.
- In a green-field project, when is a monolith preferable to microservices, and what hard limits eventually force a split?
Short answer
Starting with a monolith is often the better choice for a new project. It’s simpler to build and deploy when the team is small and the domain is still in its early stages of development.
- How to handle the request/reply pattern in EDA architecture?
Short answer
Event-Driven Architecture (EDA) is well-suited for decoupling and scalability. Still, it’s not naturally designed for request/reply (i.e., synchronous, where one service asks another and waits for a response).
- What are the pros and cons of combining UnitOfWork + Repository + CQRS?
Short answer
Combining Unit of Work, Repository, and CQRS patterns is common in .NET apps, but it’s essential to know when and how to apply them.
- Can you describe the "Outbox Pattern" and the problem it solves
Short answer
The Outbox Pattern solves a classic problem in distributed systems: ensuring data consistency between your database and a message broker (such as RabbitMQ, Kafka, or Service Bus).
ASP.NET Core

The detailed answers with diagrams and explanations of what Junior/Middle/Senior should know for the questions below, can be found in our separate article: Part 6: ASP.NET Core Interview Questions and Answers
- What is ASP.NET Core, and how does it differ from the old ASP.NET (Framework)?
Short answer
ASP.NET Core is a modern, cross-platform, open-source web framework that’s part of the unified .NET platform. Unlike ASP.NET (Framework), which is primarily hosted on IIS and is tied to Windows, ASP.NET Core runs on Kestrel across Windows, Linux, and macOS—often behind a reverse proxy (IIS/NGINX/Apache) in production.
- What is Kestrel, and can ASP.NET Core run without IIS?
Short answer
Kestrel is the default cross-platform web server for ASP.NET Core. It’s a lightweight, high-performance HTTP server built into the framework.
- How does the ASP.NET Core request processing pipeline work, and what is middleware?
Short answer
In ASP.NET Core, HTTP requests flow through a sequence of middleware components, which together form the request pipeline. Each middleware can handle the request and/or response, and then optionally pass control to the next middleware in the pipeline.
- How do you create a custom middleware in ASP.NET Core?
Short answer
Creating your middleware in ASP.NET Core enables you to plug custom logic into the request pipeline, such as logging, timing, headers, or metrics.
- What's the difference between app.Use(), app.Run(), and app.Map() in the middleware pipeline?
Short answer
app.Use adds middleware that can run code before and after the next component by calling next(). app.Run adds terminal middleware that does not call next, while app.Map branches the pipeline for matching paths or conditions.
- What is routing in ASP.NET Core, and how is it configured?
Short answer
Routing in ASP.NET Core is the system that maps incoming HTTP requests to the correct endpoint — usually a controller action, Razor page, or minimal API.
- How to host and deploy ASP.NET Core cross-platform?
Short answer
ASP.NET Core runs on Windows, Linux, and macOS, giving you multiple hosting options.
- How to implement global error handling, and why prefer UseExceptionHandler middleware over exception filters?
Short answer
Global error handling should sit in the middleware pipeline so it catches exceptions from any endpoint (such as minimal APIs, MVC, Razor Pages, static files, gRPC negotiations, etc.).
- How to serve static files in ASP.NET Core and configure caching headers for them?
Short answer
Kestrel serves static files (JS, CSS, images) via the static-file middleware. By default, it serves from the wwwroot folder.
- What is endpoint routing, and how does it improve performance compared to the old routing system?
Short answer
Endpoint routing centralizes routing so that the framework selects the endpoint early in the middleware pipeline and attaches it to the HttpContext. This means middleware later in the pipeline already knows which endpoint will run and can make decisions accordingly.
- What is the "minimal hosting model" introduced in .NET 6, and how does it differ from the previous Startup.cs model?
Short answer
The minimal hosting model combines Program.cs and Startup.cs setup into a single, simpler Program.cs using WebApplicationBuilder and WebApplication. The old model separated host building, service registration, and middleware setup across Program.cs and Startup.cs.
- How do you configure services and the HTTP request pipeline in ASP.NET Core?
Short answer
In ASP.NET Core, there are two phases in application startup: Configure Services – this is where you register dependencies. Configure the HTTP request pipeline – this is where you define how the app handles incoming requests (via middleware).
- What is the difference between a Generic Host and a Web Host in ASP.NET Core?
Short answer
The Generic Host (Host.CreateDefaultBuilder) is the unified hosting model introduced in ASP.NET Core 2.1+ that can host any .NET app — web apps, background services, worker services, etc. The Web Host (WebHost.CreateDefaultBuilder) was the original host for ASP.NET Core web apps only, and it’s now considered legacy for new apps.
- What are IHostedService and BackgroundService, and when should you use them?
Short answer
IHostedService is the ASP.NET Core abstraction for long-running background tasks that start with the app and stop on shutdown. BackgroundService is an abstract base class implementing IHostedService that gives you a dedicated ExecuteAsync method, making it more straightforward to write background loops without boilerplate.
- IHostedService vs BackgroundService vs schedulers — when to choose what?
Short answer
IHostedService is the low-level contract for starting and stopping background work with the host, while BackgroundService is a base class that simplifies writing a long-running loop via ExecuteAsync. Use a scheduler (Hangfire, Quartz.NET, or hosted cron) when you need persisted jobs, cron timing, retries, or distributed coordination beyond a simple in-process loop.
- How does built-in Dependency Injection (DI) work in ASP.NET Core, and what are service lifetimes?
Short answer
ASP.NET Core has built-in dependency injection (DI) — no need for third-party containers. It’s how you manage object creation and pass dependencies automatically where needed.
- Which DI antipatterns do you know in ASP.NET Core?
Short answer
Common DI antipatterns include the Service Locator (resolving dependencies from the container by hand instead of injecting them), captive dependencies (a singleton holding a scoped or transient service), and overusing the container for things that are not dependencies. Injecting too many dependencies into one type is also a smell that the class is doing too much.
- Can you describe use cases for [FromKeyedServices] attribute in DI?
Short answer
[FromKeyedServices] is a feature in .NET 8 that lets you inject named (keyed) services into minimal APIs, controllers, or other endpoints.
- How is configuration handled in ASP.NET Core?
Short answer
ASP.NET Core has a flexible configuration system that loads settings from multiple sources — JSON files, environment variables, command-line args, and secrets, then merges them into a single configuration object.
- What advanced DI features exist (TryAdd, Replace, Remove), and when should you use them?
Short answer
ASP.NET Core’s DI container includes handy “extensibility” helpers for safe defaults, swapping implementations, and pruning registrations.
- How does the Options pattern work (IOptions, IOptionsSnapshot, IOptionsMonitor), and when to use each?
Short answer
The Options pattern binds configuration to typed POCOs and injects them via DI.
- What configuration providers are available (Azure Key Vault, AWS Secrets Manager, database)?
Short answer
ASP.NET Core configuration is provider-based — each provider reads key/value pairs from a source and merges them into a single configuration tree. Beyond built-ins (JSON, INI, environment variables, command-line args), you can plug in cloud secret stores or databases.
- What pitfalls exist when using scoped services in async background tasks?
Short answer
Background workers (BackgroundService / IHostedService) are singletons. Injecting scoped services (e.g., EF Core DbContext) directly into them creates lifetime mismatches and disposal bugs.
- What are Minimal APIs in ASP.NET Core, and how do they differ from using Controllers (MVC)?
Short answer
Minimal APIs define endpoints directly with methods like MapGet and MapPost, making small HTTP services concise and low ceremony. Controllers use MVC conventions, attributes, filters, model binding patterns, and organization that often fit larger APIs better.
- What is model binding and model validation in ASP.NET Core MVC?
Short answer
Model binding is the process where ASP.NET Core automatically takes incoming HTTP request data — from route values, query strings, form fields, headers, or JSON body — and maps it to method parameters or model objects in your controller or minimal API.
- What is model validation in ASP.NET Core MVC?
Short answer
Model Validation occurs after binding. If you have validation attributes on your model properties (like [Required], [Range], [EmailAddress], etc.), the framework will automatically validate the model and record any errors.
- What are filters in ASP.NET Core, and how do they differ from middleware?
Short answer
Middleware runs for every matching HTTP request early in the ASP.NET Core pipeline and can affect routing, authentication, static files, and endpoints. Filters run inside MVC/Razor Pages around action execution, model validation, results, or exceptions, so they are scoped to MVC-style endpoints.
- What is the difference between Razor Pages and MVC in ASP.NET Core, and when might you use Razor Pages?
Short answer
Razor Pages is page-focused — each page has its UI (.cshtml) and logic (PageModel) together. MVC splits logic into controllers and views, offering more flexibility but more boilerplate.
- What is Blazor, and how do Blazor WebAssembly and Blazor Server differ?
Short answer
Blazor is a framework for building interactive web UIs using C# instead of JavaScript. It runs .NET code directly in the browser (WebAssembly) or on the server (SignalR).
- How to implement API versioning in ASP.NET Core (URL, query, header)?
Short answer
API versioning in ASP.NET Core is handled via the Microsoft.AspNetCore.Mvc.Versioning package.
- How to handle file uploads and large requests in ASP.NET Core?
Short answer
ASP.NET Core supports file uploads via IFormFile (in-memory) or streaming to disk/other storage to avoid memory spikes. For large requests, increase MaxRequestBodySize and use streaming to prevent loading the whole file into memory.
- How does content negotiation work, and how do you customize response formatting?
Short answer
Content negotiation in ASP.NET Core picks the best response format (JSON, XML, plain text) based on the request’s Accept header and available formatters. By default, it uses JSON with System.Text.Json.
- What is gRPC in ASP.NET Core, and when should you use it over REST?
Short answer
gRPC is a high-performance, contract-based RPC framework using HTTP/2 and Protocol Buffers. It’s great for internal service-to-service calls because it’s faster, strongly typed, and supports streaming.
- What are common approaches to authentication in ASP.NET Core (cookie-based auth vs JWT bearer tokens)?
Short answer
Cookie authentication stores the user session in an encrypted browser cookie and is common for server-rendered web apps. JWT bearer authentication sends a signed token in the Authorization header and is common for APIs, SPAs, mobile apps, and service-to-service calls.
- What is policy-based authorization in ASP.NET Core, and how is it different from role-based authorization?
Short answer
Role-based authorization checks if a user belongs to a specific role (e.g., Admin). Policy-based authorization lets you define richer rules (policies) that can check claims, values, or custom logic — roles can be part of a policy, but policies aren’t limited to roles.
- What is CORS, and how to configure CORS in an ASP.NET Core application?
Short answer
CORS (Cross-Origin Resource Sharing) is a browser security feature that blocks requests to your API from different origins unless explicitly allowed. It’s essential when your frontend and backend run on other domains, ports, or protocols.
- What is ASP.NET Core Identity, and when should you use it?
Short answer
ASP.NET Core Identity is a membership system for handling authentication, authorization, and user management (registration, login, roles, claims). It’s useful when you need built-in, customizable auth with minimal setup, without building everything from scratch.
- What is the Data Protection API, and how does ASP.NET Core handle key management?
Short answer
The Data Protection API in ASP.NET Core provides cryptographic services for encrypting and decrypting data (e.g., auth cookies, CSRF tokens). It uses a key ring to store and rotate encryption keys automatically.
- How to implement CSRF protection in ASP.NET Core?
Short answer
ASP.NET Core automatically adds CSRF (anti-forgery) protection to Razor Pages and MVC by validating an anti-forgery token sent with each form POST. You generate the token with @Html.AntiForgeryToken() and validate it with [ValidateAntiForgeryToken] on actions.
- What is the SameSite cookie setting, and why does it matter for cross-domain scenarios?
Short answer
The SameSite cookie setting controls whether a browser sends cookies with cross-site requests.
- What OWASP-recommended security features should be enabled in ASP.NET Core?
Short answer
ASP.NET Core includes many built-in features that align with OWASP Top 10 recommendations.
- What logging capabilities does ASP.NET Core provide, and how do you configure logging?
Short answer
ASP.NET Core ships a unified logging abstraction (ILogger) with structured logging, scopes, filtering, and pluggable providers (Console, Debug, EventSource/EventLog, Azure App Insights, Serilog, etc.).
- How do you implement caching in ASP.NET Core, and what are the different types of caching available (in-memory, distributed, response/output caching)?
Short answer
Caching is a key performance feature, and ASP.NET Core supports several kinds.
- What is the rate-limiting middleware in ASP.NET Core, and why is it useful?
Short answer
Rate-limiting middleware in ASP.NET Core controls how many requests a client can make in a given time window, protecting APIs from abuse, preventing resource exhaustion, and ensuring fair usage across clients. Introduced in .NET 7, it supports fixed window, sliding window, token bucket, and concurrency limiting.
- How would you implement health checks in ASP.NET Core, and what are they used for?
Short answer
Health checks expose simple endpoints that report app and dependency health. They’re used by load balancers and orchestrators (Kubernetes liveness/readiness probes) to route traffic, restart stuck instances, and fail fast when a dependency is down.
- Why is using HttpClientFactory recommended for making HTTP calls in ASP.NET Core?
Short answer
IHttpClientFactory manages HttpClient lifetimes and configuration. Creating HttpClient with new can cause socket exhaustion (too many ephemeral TCP ports in TIME_WAIT) or DNS stale entries because connections aren’t appropriately reused.
- How can you run background tasks or scheduled jobs in ASP.NET Core?
Short answer
ASP.NET Core offers two main paths: built-in hosted services for in-process work, and external schedulers for durable, cron-style jobs.
- What is SignalR in ASP.NET Core, and what are its typical use cases?
Short answer
SignalR is a real-time communication library that lets server and client push messages instantly without polling. It uses WebSockets when possible, falling back to Server-Sent Events or Long Polling.
- What is the OutputCache middleware (.NET 7+), and how is it different from ResponseCaching?
Short answer
OutputCache (introduced in .NET 7) It is the next-generation server-side response caching middleware. It stores generated responses in memory (or other stores in the future) and serves them directly on subsequent requests without re-executing the endpoint.
- How to enable response compression in ASP.NET Core?
Short answer
ASP.NET Core supports Gzip, Brotli, and custom compression providers to reduce payload size and improve performance. You add the compression middleware and configure supported MIME types.
- How to integrate OpenTelemetry for distributed tracing and metrics in ASP.NET Core?
Short answer
OpenTelemetry lets you collect traces, metrics, and logs across distributed systems. You install OpenTelemetry.Extensions.Hosting and configure tracing/metrics exporters (Jaeger, Zipkin, OTLP).
- How to scale SignalR with Redis backplane or Azure SignalR Service
Short answer
SignalR works typically in a single server’s memory, so in multi-server setups, messages won’t reach all clients.
- How to add Polly resilience policies (retry, circuit breaker) with HttpClientFactory?
Short answer
ASP.NET Core integrates IHttpClientFactory With Polly, you can add retries, circuit breakers, and more directly to your HTTP clients.
- How to benchmark and profile ASP.NET Core apps?
Short answer
Its exist two common ways to measure benchmarks for .NET projects: dotnet-counters — real-time performance metrics (CPU, GC, requests/sec) for a running app. BenchmarkDotNet — a micro-benchmarking framework for measuring the performance of specific code paths.
- How to test ASP.NET Core apps with WebApplicationFactory for integration testing?
Short answer
WebApplicationFactory<TEntryPoint> from Microsoft.AspNetCore.Mvc.Testing spins up a real in-memory server so you can test endpoints without deploying the app. It’s often used with HttpClient for end-to-end integration tests.
- What are the best practices for deploying ASP.NET Core apps cross-platform?
Short answer
ASP.NET Core runs on Windows, Linux, and macOS, so deployment is flexible.
- How to make ASP.NET Core apps scalable and cloud-ready?
Short answer
For scalability in the cloud, design your app to handle multiple instances without depending on local state.
- How to implement localization and globalization in ASP.NET Core (IStringLocalizer)?
Short answer
Localization lets your app display content in multiple languages, while globalization ensures it works with different cultures (dates, numbers, currencies). IStringLocalizer retrieves localized strings from .resx files without hardcoding them.
SQL Database

The detailed answers with diagrams and explanations of what Junior/Middle/Senior should know for the questions below, can be found in our separate article: SQL Database Interview Questions and Answers
- What is normalization, and when would you denormalize your schema?
Short answer
Database normalization organizes data into related tables to reduce duplication and maintain consistency.
- How would you explain the ACID properties to a junior developer, and why are they important?
Short answer
ACID defines the guarantees that a transactional database provides to ensure data correctness and reliability.
- What does SARGability mean in SQL?
Short answer
SARGability (Search ARGument Able) describes whether a query condition can efficiently use an index.
- What's the difference between a WHERE clause and a HAVING clause? Can you give a practical example of when you'd need HAVING?
Short answer
WHERE filters rows before grouping and aggregation, such as orders placed in 2025. HAVING filters groups after aggregation, such as customers with COUNT(*) greater than 5 or SUM(total) above a threshold.
- What's the difference between INNER JOIN, LEFT JOIN, RIGHT JOIN, and FULL OUTER JOIN?
Short answer
Joins define how rows from two tables are combined. They determine which rows are included when there’s no matching data between the tables.
- Let's say you have a table for Posts and Comments. How would you model the database to retrieve a post along with all its associated comments efficiently?
Short answer
The classic way is a one-to-many relationship: A Posts table with a primary key (PostId). A Comments table with a foreign key (PostId) pointing to Posts.
- How would you model a "self-referencing" relationship, like an employee-manager hierarchy, in a SQL table?
Short answer
A self-referencing relationship means a table’s rows relate to other rows in the same table.
- What's the difference between a Primary Key, Unique Key, and Foreign Key?
Short answer
A primary key uniquely identifies each row and cannot be null; a unique key also enforces uniqueness but is not the table identity and may allow nullable values depending on the database. A foreign key links rows to another table and enforces referential integrity.
- How do foreign keys affect data integrity and performance?
Short answer
A foreign key enforces a relationship between two tables. It ensures that the value in one table (the child) matches an existing value in another (the parent), thereby maintaining referential integrity.
- When would you use a junction table in a many-to-many relationship?
Short answer
A junction table (or bridge table) links two tables in a many-to-many relationship. Each record in one table can relate to many in the other, and vice versa.
- How would you return all users and their last order date, even if some users have no orders?
Short answer
You’d join the Users table with the Orders table using a LEFT JOIN, so users without orders still appear.
- How does a subquery differ from a JOIN?
Short answer
A JOIN combines data from multiple tables into one result set by linking rows that share a related key. A subquery runs a nested query first, then uses its result in the outer query often as a filter or computed value.
- What is a Common Table Expression (CTE) and how does it differ from a temporary table?
Short answer
A CTE is a named result set scoped to a single SQL statement, useful for readability, recursion, and query composition. A temporary table is materialized in temp storage and can be indexed, reused across multiple statements, and populated step by step.
- What are window functions (ROW_NUMBER, RANK, DENSE_RANK, etc.), and where are they useful?
Short answer
Window functions perform calculations across a set of rows related to the current row without collapsing them like GROUP BY does. They’re used for ranking, running totals, moving averages, and comparing rows within partitions.
- You have a query that needs to filter on a column that can contain NULL values. What are some pitfalls to avoid?
Short answer
In SQL, NULL means unknown, not “empty,” which affects comparisons, filters, and even indexes. SQL uses three-valued logic: TRUE, FALSE, and UNKNOWN.
- How do you decide between using a JOIN in the database versus handling the relationship in your application code?
Short answer
Prefer a database JOIN when filtering, aggregation, and relationship traversal can be done close to the data with indexes and set-based execution. Use application-side composition only when data comes from different systems, the join would be too expensive, or business logic cannot reasonably live in SQL.
- What is the difference between COUNT(*) and COUNT(column_name)?
Short answer
COUNT(*) counts all rows in the result set — including those with NULL values. COUNT(column_name) counts only rows where the column is not NULL.
- How can you pivot or unpivot data in SQL?
Short answer
Pivoting converts rows into columns, summarizing data (e.g., totals by quarter).
- How do you find duplicates in a table?
Short answer
To find duplicates, group rows by the columns that define “uniqueness” and filter with HAVING COUNT(*) > 1.
- What's the difference between UNION and UNION ALL?
Short answer
UNION combines result sets and removes duplicates, which adds a distinct/sort or hash step. UNION ALL simply appends results and keeps duplicates, so it is faster when duplicates are acceptable or impossible.
- What's the difference between a clustered and a non-clustered index?
Short answer
A clustered index defines the physical/logical row order of the table data, so a table usually has only one. A non-clustered index is a separate structure that stores keys plus row locators or included columns, and a table can have many.
- Can you explain what a composite index is and why the order of columns in it matters?
Short answer
A composite index (or multi-column index) is built on two or more columns of a table.
- What are the different types of indexes available in SQL databases?
Short answer
Indexes come in several flavors, each optimized for a different kind of query or storage strategy. Think of them like various kinds of maps; each one helps you find data faster, but in its own way.
- How would you debug a slow query, and what tools would you use?
Short answer
When a query is slow, start by verifying where the delay is coming from: app logic, the ORM, or the database itself.
- What is parameter sniffing, and how can it cause performance issues?
Short answer
Parameter sniffing occurs when the database engine caches an execution plan for a query or stored procedure based on the first parameter values it receives and then reuses that plan for all subsequent executions, even when parameter values vary drastically.
- How does indexing improve read performance but slow down writes?
Short answer
Indexes speed up reads, but each index adds maintenance work to writes.
- Could you explain what a covering index is and how it can enhance performance?
Short answer
A covering index (also called a covering or cover index) is an index that contains all the columns needed to satisfy a query, both for filtering and for returning data.
- What are the best practices for indexing large tables?
Short answer
Indexing large tables is all about striking a balance, speeding up queries without compromising inserts, updates, and storage. Done right, indexes make reads lightning-fast; done wrong, they can cripple write performance and bloat your database.
- How do database statistics affect query performance?
Short answer
Statistics tell the query optimizer how data is distributed in a table — things like row counts, distinct values, and data ranges.
- What is the purpose of the NOLOCK hint in SQL Server, and what are the serious risks of using it?
Short answer
The NOLOCK table hint tells SQL Server to read data without acquiring shared locks, meaning it doesn’t wait for ongoing transactions.
- What is a CHECK constraint, and when would you use it?
Short answer
A CHECK constraint enforces a rule on column values. It ensures that only valid data gets stored in the table.
- When would you consider using a database view, and what are its limitations?
Short answer
A view is a saved SQL query that acts like a virtual table. It doesn’t store data; it just stores the definition of a query that runs when you select from it.
- What's the difference between views and materialized views?
Short answer
A view is a saved query definition; its data is read from the underlying tables when queried. A materialized view stores the query result physically and can improve read performance, but it must be refreshed or maintained when source data changes.
- What are the pros and cons of using stored procedures?
Short answer
Stored procedures are precompiled SQL scripts stored in the database. They can encapsulate logic, improve performance, and simplify maintenance, but they can also make versioning, testing, and scaling more complex.
- How do you efficiently pass a list of values to a stored procedure in SQL Server versus PostgreSQL?
Short answer
In SQL Server, use table-valued parameters for strongly typed lists, or JSON/string splitting when TVPs are not practical. In PostgreSQL, pass arrays, JSONB, or use unnest() to turn a list parameter into rows.
- What's the difference between temporary tables and table variables?
Short answer
Temporary tables are real tempdb tables that can have indexes, statistics, and multiple statements using them, which helps for larger intermediate results. Table variables are scoped variables with lighter syntax, but they can produce weaker optimization choices and are better for small sets.
- How would you enforce a business rule like "a user can only have one active subscription" at the database level?
Short answer
You can enforce it directly in the database using a filtered unique index or a trigger, depending on your database's capabilities.
- What are some strategies for efficiently paginating through a huge result set, as opposed to using OFFSET/FETCH?
Short answer
OFFSET/FETCH (or LIMIT/OFFSET) works fine for small pages, but it gets slower as the offset grows, the database still scans all skipped rows. For large datasets, you need smarter paging.
- What is a trigger, and when should it be avoided?
Short answer
A trigger is a special stored procedure that runs automatically in response to certain database events, such as INSERT, UPDATE, or DELETE. Triggers are useful for enforcing rules or auditing changes, but they can make logic hard to trace, debug, and maintain, especially when multiple triggers chain together.
- How can you implement audit logging using SQL features?
Short answer
Audit logging tracks who changed what and when in your database.
- How can you use SQL window functions to calculate rolling averages or cumulative totals?
Short answer
You can use window functions like AVG() or SUM() with the OVER() clause to calculate rolling averages or running totals without collapsing rows like GROUP BY does. They let you look “across” rows related to the current one, often within a defined time or ordering window.
- ORM vs Raw SQL Query — When to Use What
Short answer
Both approaches have their strengths; the key is knowing when each is most suitable. Think of it like this: EF Core (ORM) is your daily driver, while raw SQL is your race car — more control, but more work.
- How would you explain the difference between the DB isolation levels?
Short answer
Isolation levels define how much one transaction can “see” from another before it’s committed. The stricter the level, the safer your data, but the slower your system.
- What's the difference between pessimistic and optimistic locking?
Short answer
Pessimistic locking locks data before or while it is being edited, preventing conflicting writes but reducing concurrency. Optimistic locking allows concurrent work and detects conflicts at save time, usually with a row version or timestamp.
- How do you detect and prevent deadlocks?
Short answer
A deadlock occurs when two or more transactions block each other, each holding a lock that the other needs. SQL Server detects the situation and kills one transaction (the “victim”) with error 1205.
- How would you design a retry policy for failed transactions?
Short answer
A retry policy helps your system recover from temporary issues, such as deadlocks, timeouts, or network hiccups — without requiring user intervention.
- What's the difference between OLTP and OLAP systems?
Short answer
OLTP systems handle many small, real-time business transactions such as inserts, updates, and order processing. OLAP systems support analytical queries over large historical datasets, usually optimized for reads, aggregations, and reporting.
- What is table bloat in PostgreSQL, and how does the autovacuum process help manage it?
Short answer
In PostgreSQL, table bloat occurs when a table or index contains a large number of dead tuples — old row versions that remain after updates or deletes.
- What are database partitions, and when should you use them?
Short answer
Partitioning splits a large table or index into smaller, more manageable pieces while keeping them logically as one table.
- How would you archive old records without affecting query performance?
Short answer
Archiving means moving old, rarely accessed data out of your main tables to keep them small and fast.
- How would you secure sensitive data at rest and in transit?
Short answer
Data security comes down to two layers: At rest: protecting stored data (in files, databases, backups). In transit: protecting data while it’s moving over the network.
- How would you design a reporting database separate from the OLTP database?
Short answer
I’d start by separating the operational and analytical workloads. The OLTP database should handle fast inserts and updates, while the reporting database focuses on heavy read and aggregation queries.
- What is "Sharding" and what are the biggest challenges when implementing it?
Short answer
Sharding is a technique for horizontally scaling a database by splitting data across multiple servers (called shards). Each shard holds only a portion of the total data, for example, users A–M on one server, N–Z on another.
- How would you configure high availability and disaster recovery for a critical SQL Server database?
Short answer
High availability (HA) and disaster recovery (DR) both aim to keep your database online, but they solve different problems.
- How can you reduce locking contention in a high-write environment?
Short answer
Reduce contention by shortening transactions, accessing rows in a consistent order, using appropriate isolation levels (such as RCSI/snapshot to avoid reader-writer blocking), and keeping hot rows from becoming bottlenecks. Techniques like partitioning, batching, optimistic concurrency, and finer-grained locks further spread writes and cut lock waits.
- Can you define a transaction and give an example of a business operation that absolutely needs to be wrapped in one?
Short answer
A transaction is a unit of work in a database that involves multiple operations, which either succeed or fail as a whole. If one step fails, everything rolls back, so your data isn’t left in a broken or partial state.
- A page in your application is loading slowly. How would you systematically determine if the problem is a database query?
Short answer
If you suspect the database, you can narrow it down step by step: Measure total request time — add timing logs at the start and end of your controller or service. Log query durations — most ORMs, such as EF Core, can log SQL commands and execution times.
- How does database connection pooling work in .NET, and what are some common mistakes that can break it?
Short answer
Connection pooling in .NET is a mechanism that allows for the reuse of existing database connections, rather than opening and closing new ones each time your code executes a query. Opening a database connection is expensive; pooling makes it fast and efficient by keeping a small pool of ready-to-use connections in memory.
- If you had to improve the performance of a large DELETE or UPDATE operation, what strategies would you consider?
Short answer
Big DELETE or UPDATE queries can lock tables and fill logs. The trick is to do it in smaller batches and reduce overhead.
- How would you handle a situation where a necessary query is just inherently slow due to the volume of data it needs to process?
Short answer
Sometimes a query is slow, not because it’s poorly written — it’s just doing a lot of work. When that’s the case, the goal isn’t to make it instant, but to make it manageable — by controlling when, how often, and how much data it touches.
- What's the purpose of the STRING_AGG or FOR XML PATH techniques in SQL? Can you think of a use case?
Short answer
Both STRING_AGG (modern approach) and FOR XML PATH (older workaround) are used to combine multiple row values into a single string a process often called string aggregation or grouped concatenation.
- What are the trade-offs of using AsNoTracking() in EF Core?
Short answer
AsNoTracking() tells Entity Framework Core not to track changes for the returned entities. Usually, EF keeps a copy of every loaded entity in its change tracker — so if you modify it later, EF knows how to generate an UPDATE.
- You need to insert 100,000 records. What's wrong with using a simple loop with SaveChanges(), and what would you do instead?
Short answer
Calling SaveChanges() inside a loop is one of the most common performance mistakes when inserting large datasets. Each call sends a separate transaction and round-trip to the database, meaning 100,000 inserts = 100,000 transactions.
- How can you use projections in EF Core to optimize a query that only needs a few fields?
Short answer
By default, EF Core maps entire entities, all columns — even if you only use a few of them later. That means extra data is fetched, tracked, and stored in memory unnecessarily.
- What exactly is the "N+1 query problem," and how have you solved it in EF Core?
Short answer
The N+1 query problem happens when your code runs one main query to fetch a list of items (the “1”), and then executes a new query for each item to load its related data (the “N”).
- How would you explain the Unit of Work and Repository patterns to someone just starting with EF Core? Does the DbContext itself implement these?
Short answer
The Repository and Unit of Work patterns are classic ways to organize data access in an application.
- How do you manage the lifetime of your DbContext in a modern ASP.NET Core application? Why shouldn't it be a singleton?
Short answer
In ASP.NET Core, the DbContext is designed to be short-lived and scoped to a single request. That means a new instance is created for each incoming HTTP request and disposed automatically when the request ends.
- Let's say you have a complex, pre-tuned SQL query. How do you execute it and get the results back into your .NET code using EF Core?
Short answer
Sometimes you already have a hand-optimized SQL query — maybe from a DBA or profiler, and you want to reuse it in your .NET app.
- How does EF Core handle concurrency conflicts? Can you describe a scenario where you've had to implement this?
Short answer
EF Core handles concurrency conflicts using optimistic concurrency control. The idea is simple: multiple users can read and modify the same data, but when saving, EF Core checks if the data has changed since it was read.
- How do you seed reference data (like a list of countries or product categories) using EF Core migrations?
Short answer
In EF Core, you can seed reference data using the HasData() method in your OnModelCreating() configuration. When you add a migration, EF Core generates INSERT statements for that data.
- What are owned entities in EF Core, and when would you use them?
Short answer
Owned entities in EF Core let you group related fields into a value object that doesn’t have its own identity or table. They’re helpful when you want to logically separate parts of an entity — like an address or a money type — but still keep them stored in the same table as the owner.
- How do you configure a many-to-many relationship in EF Core?
Short answer
In EF Core, many-to-many relationships are easy to set up starting from EF Core 5. You can define them directly without creating a separate join entity class — EF Core automatically builds a join table under the hood.
- What are global query filters, and what's a practical use case for them?
Short answer
Global query filters in EF Core let you automatically apply a WHERE condition to all queries for a specific entity type. They’re great for scenarios like soft deletes, multi-tenancy, or filtering archived data — so you don’t have to repeat the same condition in every query.
- Can you explain what a shadow property is in EF Core?
Short answer
A shadow property in EF Core is a field that exists in the model but not in your entity class. It’s managed by EF Core internally — you can query, filter, and store values for it, even though it’s not part of your C# object.
- How does EF Core decide whether to issue an INSERT or an UPDATE when you call SaveChanges()?
Short answer
When you call SaveChanges() in Entity Framework Core, the framework looks at the state of each tracked entity in the DbContext to decide what SQL command to send. It’s all about change tracking — EF Core keeps track of each entity’s lifecycle from when you load or attach it until you save.
NoSQL Databases

The detailed answers with diagrams and explanations of what Junior/Middle/Senior should know for the questions below, can be found in our separate article: NoSQL Interview Questions and Answers for .NET Developers
- What are the main categories of NoSQL databases?
Short answer
NoSQL databases fall into four main categories: key-value stores (Redis), document stores (MongoDB), wide-column stores (Cassandra), and graph databases (Neo4j). Each is optimized for a different data shape and access pattern.
- How do you decide between SQL and NoSQL for a new feature?
Short answer
Choose SQL when the feature needs strong consistency, relational integrity, joins, transactions, and well-structured data. Choose NoSQL when the data model is flexible, access patterns are key/document/graph oriented, or horizontal scale and high write throughput matter more than relational querying.
- What are common read/write patterns in NoSQL (GetByID, fan-out, time-series, append-only)?
Short answer
That's a great question about NoSQL design. Unlike relational databases, NoSQL designs are access-pattern-driven, meaning the data structure is optimized for the specific read and write operations your application performs.
- How do ACID and BASE principles differ in the context of NoSQL?
Short answer
ACID and BASE are two ways to handle data reliability. ACID is strict.
- How does the CAP theorem influence database architecture design?
Short answer
The CAP theorem says that in a distributed database, you can only guarantee two out of three things at the same time.
- What are typical consistency models?
Short answer
Consistency models define how up-to-date and synchronized data is across replicas in a distributed system.
- What are polyglot persistence patterns, and when are they appropriate?
Short answer
Polyglot persistence refers to using multiple database types within the same system — each chosen for its specific strengths. Instead of forcing a single database to handle every workload, you mix technologies such as SQL, NoSQL, and search engines to optimize performance, scalability, and cost.
- How would you model relationships in NoSQL systems that don't support joins?
Short answer
In NoSQL, there are no traditional SQL joins. Therefore, you must design relationships based on how data is accessed, rather than how it’s normalized.
- What are common anti-patterns in NoSQL data modeling?
Short answer
The most significant anti-pattern is treating NoSQL databases as if they were relational databases. If you normalize everything and rely on joins, performance drops fast.
- What's the difference between schema-on-write and schema-on-read?
Short answer
Schema-on-write means you validate and shape the data before saving it. If the data doesn’t match the structure, it won’t get in.
- How do you handle data versioning and schema evolution in NoSQL systems?
Short answer
The typical pattern is to add new fields, retain the old ones for a while, and let the application handle both versions. Most teams use version fields, migration scripts, or lazy migrations when reading documents.
- How do you implement referential integrity or constraints in a NoSQL world?
Short answer
NoSQL won’t enforce foreign keys, so the service owns all relationship rules. You validate references on write, clearly structure ownership, and use events to keep dependent data in sync.
- If you were designing a blog post with comments, would you embed comments or use a separate collection?
Short answer
It depends on how the data will be read, written, and scaled.
- What are the trade-offs between MongoDB's flexible schema and the rigid schema of a relational database?
Short answer
MongoDB’s flexible schema lets you store documents with different structures in the same collection. That’s powerful, but it comes with trade-offs in consistency, validation, and long-term maintainability.
- How does MongoDB handle transactions, and what are the differences between its approach and that of a relational database?
Short answer
MongoDB initially supported atomic operations only at the single-document level. Starting from MongoDB 4.0, it introduced multi-document ACID transactions, making it behave more like a traditional relational database when needed — but with some key differences.
- How do you approach indexing in a document database like MongoDB compared to a relational database?
Short answer
In both MongoDB and relational databases, indexes speed up queries — but the way you design and think about them is slightly different because of how data is stored and accessed.
- How does the aggregation pipeline work, and when would you use it?
Short answer
The aggregation pipeline is MongoDB’s way to process data step by step, like a mini ETL inside the database. Each stage transforms the documents: filter, group, sort, join, reshape, compute fields, and more, as needed.
- What's the difference between replica sets and sharded clusters?
Short answer
A replica set keeps multiple copies of the same data for high availability and failover, but every node holds the full dataset. A sharded cluster horizontally partitions data across shards so each holds only a subset, enabling the dataset and write throughput to scale beyond one machine — and each shard is typically itself a replica set.
- How does MongoDB achieve horizontal scalability?
Short answer
MongoDB scales horizontally through sharding. Sharding splits a big collection into smaller chunks and spreads them across multiple machines.
- How do you identify and fix slow queries?
Short answer
You start by checking what MongoDB is actually doing under the hood. Slow queries almost always come from missing indexes, bad filters, or scatter-gather queries in sharded setups.
- How do you enforce schema validation with JSON Schema?
Short answer
We enforce schema validation at the collection level using the $jsonSchema operator. While MongoDB is fundamentally schema-less, this feature allows us to apply database-side rules that reject documents failing validation, preventing garbage data from entering the system.
- What's your approach to managing extensive collections or time-series data?
Short answer
For extensive collections, the architectural core is Sharding. We distribute data across multiple servers/shards to scale writes and manage the working set size.
- How does Azure Cosmos DB differ from MongoDB and DynamoDB?
Short answer
Azure Cosmos DB is a globally distributed, multi-model database with turnkey replication, tunable consistency, SLAs, and several APIs including NoSQL and MongoDB-compatible APIs. MongoDB is primarily a document database you operate or consume as Atlas, while DynamoDB is AWS-native key-value/document storage optimized around partition-key access patterns.
- What is a partition key in Cosmos DB, and what happens if you pick a bad one?
Short answer
In Cosmos DB, the partition key determines how data is distributed across physical partitions. Each unique key value group relates items together.
- What is the change feed in Cosmos DB, and what are some cool things you can build with it?
Short answer
The change feed in Cosmos DB is akin to a real-time event log of everything that occurs in your container. Whenever a document is created or updated, the change feed captures the change in order, so your app can respond to it rather than constantly polling the database.
- How would you explain the different consistency levels in Cosmos DB, and when would you choose one over another?
Short answer
Cosmos DB offers Strong, Bounded Staleness, Session, Consistent Prefix, and Eventual consistency. Choose stronger levels when correctness and read-your-writes matter more, and weaker levels when lower latency, higher availability, and throughput matter more.
- How does Cosmos DB charge based on Request Units (RUs), and how can you optimize costs?
Short answer
Cosmos DB uses Request Units (RUs) as a unified performance and pricing currency. They abstract the underlying system resources—CPU, memory, and IOPS—consumed by any database operation.
- How do you design for multi-region writes and geo-replication?
Short answer
It's a two-part approach: Enabling Replication and designing for Conflict Resolution.
- How would you model time-series data in Cosmos DB?
Short answer
Since Cosmos DB doesn't have native time-series collections, we use the Bucketing (or Binning) Pattern to optimize for high-speed sequential writes and efficient time-range queries.
- What is DynamoDB, and how is it different from MongoDB?
Short answer
DynamoDB is AWS’s fully managed, key-value/document store built for predictable performance at massive scale. MongoDB is a flexible document database that you model like traditional collections.
- What is the primary key structure in DynamoDB (partition key vs. sort key)?
Short answer
The DynamoDB primary key (PK) is the core mechanism for both data distribution and querying. It must be unique and is composed of one or two attributes: the Partition Key and the optional Sort Key.
- How do Global Secondary Indexes (GSI) and Local Secondary Indexes (LSI) differ?
Short answer
An LSI uses the same partition key as the base DynamoDB table but a different sort key, and it must be created with the table. A GSI can use a different partition key and sort key, is managed separately, and is used for access patterns that do not fit the base table key.
- What are best practices for choosing a partition key in DynamoDB?
Short answer
The partition key decides how DynamoDB spreads your data and load. If it’s bad, one hot partition will kill your performance.
- How would you design a one-to-many or many-to-many relationship in DynamoDB?
Short answer
In DynamoDB, you do not join. You design keys so that one query returns the slice of data you need.
- How do you model access patterns before designing your tables in DynamoDB?
Short answer
We use Access Pattern Driven Design, which is the inverse of relational modeling. We prioritize query performance over storage normalization, focusing on eliminating expensive Scan operations.
- What is DynamoDB Streams, and how can it be used with AWS Lambda?
Short answer
DynamoDB Streams is a time-ordered sequence of changes (a log) to the data in a DynamoDB table. It captures every Create, Update, and Delete operation in near real-time.
- How do you handle pagination and query filters efficiently in DynamoDB?
Short answer
Efficient pagination and filtering in DynamoDB are handled using Query with Limit and ExclusiveStartKey for paging, and by optimizing the Sort Key for filtering. So, we need to minimize the use of non-key filters.
- How would you implement optimistic concurrency control in DynamoDB?
Short answer
I would implement optimistic concurrency control (OCC) in DynamoDB using a Version Number attribute and Conditional Writes. This ensures that an update only succeeds if another client hasn't changed the item's version since it was last read.
- What are the limitations of transactions in DynamoDB?
Short answer
DynamoDB's transaction model (TransactWriteItems and TransactGetItems) provides full ACID properties, but it has several limitations that impact scale, cost, and design flexibility compared to standard single-item operations.
- Let's talk about caching. How would you use Redis in a .NET app to take load off your primary database?
Short answer
Redis is ideal for reducing database load by caching frequently accessed or computationally expensive data in memory. Instead of hitting your SQL or Cosmos DB every time, you can read data directly from Redis.
- What are strategies for data synchronization between Redis and the primary data source?
Short answer
Common strategies are cache-aside (the app loads from the database on a miss and populates Redis), write-through (writes go to the cache and database together), and write-behind (the cache absorbs writes and flushes to the database asynchronously). Each trades off consistency, latency, and complexity, and TTLs or explicit invalidation keep cached data from going stale.
- What is the Redis data type you'd use to implement a leaderboard, and why?
Short answer
For a leaderboard — where you rank players by score — the best Redis data type is a Sorted Set (ZSET).
- Can you describe a scenario where you would use Redis Pub/Sub?
Short answer
Redis Pub/Sub (Publish/Subscribe) lets services publish and subscribe to real-time messages via Redis channels. It’s perfect for lightweight, event-driven communication — when you want multiple subscribers to react instantly to something happening in another part of the system.
- How do you choose between RDB and AOF persistence?
Short answer
RDB creates point-in-time snapshots, so recovery is compact and fast but you can lose changes since the last snapshot. AOF logs each write operation for better durability, but files can be larger and recovery may take longer unless rewrite/compaction is managed.
- What's the difference between Redis Cluster and Sentinel?
Short answer
Redis Sentinel monitors a primary-replica setup and performs failover, but it does not shard data. Redis Cluster partitions data across multiple masters for horizontal scale and also provides failover within the cluster.
- Can you describe use cases when Redis will be a bad choice?
Short answer
Redis is speedy, but its primary nature as an in-memory, single-threaded key-value store creates specific anti-patterns, making it a poor architectural fit compared to a dedicated database or message broker.
- How does Elasticsearch differ from a traditional database in structure and purpose?
Short answer
Elasticsearch is a search engine, not a general-purpose database. It’s built for fast full-text search, relevance ranking, and analytics over extensive semi-structured data.
- What's the role of index, shard, and replica in Elasticsearch?
Short answer
An index is a logical collection of related documents, which is split into shards — the physical Lucene units that let the index scale horizontally and search in parallel. Replicas are copies of shards that provide high availability and increase read throughput.
- How does Elasticsearch achieve near real-time search?
Short answer
Elasticsearch is “near real-time” because writes don’t become instantly searchable. Documents are written to a transaction log and an in-memory buffer, then refreshed into a Lucene segment.
- What are analyzers, tokenizers, and filters, and why are they important?
Short answer
Analyzers, tokenizers, and filters are the components of the analysis process in Elasticsearch. This process converts unstructured text into the structured format (tokens) needed to build the Inverted Index, enabling fast, relevant search.
- What's the difference between term and match queries?
Short answer
A term query searches for the exact indexed term and is best for keyword, ID, status, and other structured fields. A match query analyzes the input text first, so it is used for full-text search where tokenization, stemming, or relevance scoring matters.
- How do you troubleshoot shard imbalance and optimize query latency?
Short answer
Shard imbalance happens when some nodes carry more shard data or traffic than others. This leads to slow queries, hot nodes, and unpredictable latency.
- What's the typical architecture of an ELK (Elasticsearch + Logstash + Kibana) stack?
Short answer
ELK is a pipeline: Logstash ingests and transforms data, Elasticsearch stores and indexes it, and Kibana visualizes it.
- What is a Parquet file, and why is it efficient for analytical workloads?
Short answer
Parquet is a columnar storage format. Instead of storing data row-by-row, it stores it column-by-column.
- How do columnar storage formats improve query performance?
Short answer
The primary way columnar storage formats improve query performance is by enabling data engines to read less data from disk, which directly translates to lower I/O costs and faster processing speeds, especially for analytical workloads (OLAP).
- What's the difference between Parquet, Avro, and ORC?
Short answer
Parquet and ORC are columnar formats optimized for analytical scans, compression, and reading selected columns. Avro is row-oriented and schema-based, making it strong for streaming, serialization, and write-heavy data exchange.
- How do you handle schema evolution in Parquet?
Short answer
Parquet supports schema evolution, but only in additive and compatible ways.
- What is Delta Lake, and how does it enhance Parquet?
Short answer
Delta Lake is a storage layer built on top of Parquet that adds ACID transactions, versioning, schema enforcement, and time travel. Parquet by itself is just files on disk.
- How would you optimize data partitioning in Parquet for large-scale queries?
Short answer
Good Parquet partitioning means fewer files scanned, fewer I/O operations, and much faster queries. Bad partitioning means tiny files, too many folders, and engines scanning everything anyway.
- What is a graph database, and how is it different from other NoSQL databases?
Short answer
Graph databases store relationships alongside data using nodes (entities), edges (relationships), and properties (metadata). Unlike document or key-value databases, they make traversals first-class operations.
- When should you use a graph database over SQL or document databases?
Short answer
Use graphs when you need multi-hop traversal, dynamic relationship depth, or pathfinding (e.g., social graphs, access graphs).
- What is Cypher, and how does it work in Neo4j?
Short answer
Cypher is Neo4j's declarative query language for property graphs, using an ASCII-art pattern syntax like (a)-[:KNOWS]->(b) to match nodes and relationships. You describe the graph pattern you want and Cypher handles traversal, with clauses such as MATCH, WHERE, and RETURN shaping the result.
- What is Gremlin, and how is it different from Cypher?
Short answer
Gremlin is an imperative traversal language used with Cosmos DB and others.
- How do you model 1:1, 1:N, and N:N relationships in Graph DB?
Short answer
Use edges to express cardinality. For N:N, avoid duplication and add edge metadata.
- How do you handle query performance in graph databases?
Short answer
Apply node labels, indexes, traversal depth limits, and precompute paths where necessary.
- What's the difference between property graphs and RDF?
Short answer
Property graphs (used by Neo4j) attach key-value properties directly to nodes and relationships and have a flexible, developer-friendly model. RDF represents data as subject-predicate-object triples built for standardized, interoperable semantic-web queries with SPARQL, trading ease of use for formal interoperability.
- What are common anti-patterns of Graph databases?
Short answer
Common anti-patterns include overloading nodes with too many types or properties, modeling data as a graph when it is really tabular, and creating super-nodes with millions of relationships that wreck traversal performance. Storing large blobs on nodes and ignoring indexing for entry-point lookups are also frequent mistakes.
- How do you manage the scaling of Graph databases?
Short answer
Graph databases scale reads through replicas and caching, but scaling writes is harder because traversals span the whole graph and arbitrary sharding can split connected data across machines. Strategies include domain-aware partitioning, read replicas, and engines with native distributed graph support (such as Neo4j Fabric or clustered graph stores).
- How do you secure data in a graph database?
Short answer
Secure a graph database with authentication, role-based access control, and encryption in transit and at rest, the same as any datastore. For fine-grained control, attach roles or ACL metadata to nodes and relationships so traversals only expose data the caller is allowed to see.
- What is a knowledge graph?
Short answer
A graph that uses ontologies, schemas, and reasoning (often RDF-based). Popular in search, NLP, and identity resolution.
- How do you benchmark graph query performance?
Short answer
Benchmark with standardized datasets and workloads such as LDBC or Graph500, measuring traversal latency, throughput, and how queries scale with graph size and depth. Profile real query plans (for example, Cypher PROFILE/EXPLAIN) and test under realistic concurrency rather than single-query timings alone.
- What are the limitations of graph databases?
Short answer
Graph databases are not ideal for heavy tabular analytics or aggregations, where columnar or relational stores perform better. They can also be harder to scale horizontally because traversals span connected data, and they bring a steeper learning curve and smaller tooling ecosystem.
- What is a vector database, and how does it differ from traditional databases?
Short answer
A vector database stores embeddings (float arrays) and performs similarity search on them. Instead of looking for exact matches, it finds “closest” vectors — meaning the most semantically similar items.
- How do vector databases store and search vectors?
Short answer
Vector databases store and search vectors using specialized indexing structures, primarily Approximate Nearest Neighbor (ANN) algorithms, which optimize for speed rather than perfect accuracy in high-dimensional space.
- When would you choose a Vector DB instead of Elasticsearch or SQL full-text?
Short answer
Choose a Vector DB when you need semantic search or similarity — not exact keyword matching.
- What are the trade-offs between storing vectors inside your SQL/NoSQL database vs using a dedicated vector DB?
Short answer
You can store embeddings in PostgreSQL with pgvector, SQL Server, MongoDB Atlas Vector Search, Elasticsearch, or Redis. It works fine until the scale or latency requirements grow.
- How do embeddings represent meaning in text, images, or audio?
Short answer
Embeddings turn raw data into numbers that capture meaning, not just structure.
- What is cosine similarity, and why is it used for semantic search?
Short answer
Cosine Similarity measures the cosine of the angle between two non-zero vectors in an inner product space. It quantifies how similar the vectors are in direction, regardless of their magnitudes.
- What is the difference between ANN search and exact search, and when do you need exact search?
Short answer
Exact search compares your query vector against every vector — perfect accuracy, terrible speed at scale. ANN (Approximate Nearest Neighbor) skips most of the space using smart indexes like HNSW or IVF — much faster, but not 100% accurate.
- How do you scale vector databases (sharding, replication, partitioning)?
Short answer
Vector databases scale using a combination of sharding and replication to handle both massive datasets and high query throughput. The core challenge is distributing the complex, graph-based Approximate Nearest Neighbor (ANN) index itself.
- How do you secure a vector DB API (metadata leaks, embedding inference risks)?
Short answer
Vector DBs look harmless, but embeddings can leak meaning and metadata if you expose them directly.
Microservices and Distributed Systems

The detailed answers with diagrams and explanations of what Junior/Middle/Senior should know for the questions below, can be found in our separate article: Microservices And Distributed Systems Interview Questions and Answers for .NET Developers
- When does it make sense to isolate background processing into a separate microservice?
Short answer
Isolating background processing makes sense when async work has different scaling, reliability, or lifecycle needs than the main request path. The goal is to protect user-facing flows and let background work evolve independently.
- How do you decide between a modular monolith and microservices?
Short answer
A modular monolith is one deployable unit with well-defined internal boundaries. Microservices split the system into independently deployed services.
- What is the Strangler Fig pattern, and how do you use it to migrate a legacy system?
Short answer
The Strangler Fig pattern is a gradual migration approach where you build new functionality around a legacy system and slowly “strangle” the old parts until they disappear. Instead of a risky, significant rewrite, the old system and the new one run side by side.
- How do you define service boundaries using DDD Bounded Contexts?
Short answer
Bounded Contexts are a core idea in Domain-Driven Design. They describe clear, consistent “language zones” inside your domain.
- What is Backends-for-Frontends (BFF), and where does it help?
Short answer
Backends-for-Frontends (BFF) is an architectural pattern in which each frontend has its own dedicated backend. Instead of a single generic API serving all clients, you create a backend tailored to the needs of a specific UI, such as web, mobile, or admin.
- What is the difference between a Domain Event and an Integration Event in a microservices architecture?
Short answer
A domain event represents something important that happened inside a bounded context and is mainly used within that domain model or service. An integration event is published outside the service boundary so other services can react, so it must be stable, versioned, and designed as an external contract.
- What architectural smells appear when teams split a monolith into services?
Short answer
When a monolith is split into services without clear domain boundaries, the same problems reappear. They move across the network.
- Compare Saga orchestration vs choreography for distributed transactions.
Short answer
The Saga design pattern helps maintain data consistency in distributed systems by coordinating transactions across multiple services to ensure data integrity. A saga is a sequence of local transactions in which each service performs its operation and initiates the next step via events or messages.
- What is Event-Carried State Transfer, and how does it reduce temporal coupling?
Short answer
Temporal coupling occurs when Service B can process a message only if Service A is available at the same time. This usually appears when events contain only IDs and force consumers to make follow-up calls.
- What is service discovery, and how do client-side and server-side discovery differ?
Short answer
Service discovery is the mechanism that enables services to find and communicate with each other without hardcoding network addresses. In dynamic environments like containers or cloud platforms, service instances come and go, so IPs and ports cannot be assumed to be static.
- Why is DNS discovery not ideal in dynamic systems?
Short answer
In dynamic systems like microservices, DNS isn't ideal because caching and TTLs can cause stale records and traffic to dead instances; there's no native health-aware load balancing (just round-robin); changes propagate slowly; and there's no app-level health checks, leading to black-holed requests.
- When is a service mesh worth the complexity?
Short answer
A service mesh adds infrastructure for traffic, security, and observability in microservices. Use when: chatty calls cause latency/failures; need retries/circuit breakers without code; mTLS for secure comms; high tracing needs; mixed protocols (REST / gRPC).
- What is a sidecar, and how is it used in distributed systems?
Short answer
A sidecar is a design pattern in which a helper component runs alongside a service instance and extends its behavior without changing the service's code. The service and the sidecar are deployed, scaled, and restarted together, but they have separate responsibilities.
- What role does an API Gateway play in microservices?
Short answer
An API Gateway acts as a single entry point (a "front door") for all external client requests. Instead of a mobile app or web browser calling dozens of individual microservices directly, they call the Gateway.
- How do feature flags influence deployments and testing?
Short answer
Feature flags decouple deployment from release. Deployment becomes a low-risk technical event (moving code to production), while release becomes a controlled business decision (turning code on for users).
- What is a control plane vs a data plane in distributed systems?
Short answer
The control plane and data plane split responsibilities between decision-making and execution. This separation helps systems scale, stay reliable, and evolve without changing business code.
- What is the difference between synchronous and asynchronous service communication?
Short answer
Synchronous communication waits for an immediate response, which is simple but tightly couples availability, latency, and failure between services. Asynchronous communication uses messages or events so services can be decoupled in time, but it adds eventual consistency and operational complexity.
- When do you choose REST, gRPC, or messaging?
Short answer
Choose REST (HTTP + JSON) for broad compatibility and public APIs, gRPC for low-latency, strongly-typed, high-throughput service-to-service calls, and messaging (queues or buses) for asynchronous, decoupled, event-driven communication. The decision turns on coupling, latency, and whether the caller needs an immediate response.
- When should you use gRPC streaming?
Short answer
Use gRPC streaming when data is continuous, incremental, or long-lived, and you want to avoid repeated request–response calls.
- Why are message brokers used in distributed systems?
Short answer
message brokers are used to decouple services, improve reliability, and handle asynchronous work. They let services communicate without needing to be online or fast simultaneously.
- What are at-least-once, at-most-once, and exactly-once delivery semantics?
Short answer
This is a core concept in distributed systems and message queuing. Delivery semantics define the guarantee a message system provides about how many times a message will be delivered to a consumer, particularly in the presence of failures.
- How do you ensure idempotency in a .NET message consumer?
Short answer
Idempotency means that processing the same message multiple times produces the same result. This is required because most brokers use at least one delivery.
- What is the Competing Consumers pattern, and when is it useful?
Short answer
The Competing Consumers pattern involves multiple instances of the same service (consumers) listening to a single message queue. When a message arrives, the broker ensures that only one consumer receives and processes it.
- What is a Dead Letter Queue, and how do you design reprocessing logic?
Short answer
A Dead Letter Queue (DLQ) is a special queue where messages are sent when they cannot be processed successfully. Instead of blocking the main flow or losing data, failed messages are isolated for later analysis and recovery.
- What is the Outbox pattern, and why do distributed systems rely on it?
Short answer
The Outbox pattern is a reliability pattern that guarantees messages or events are published only after the local database transaction commits. It solves the classic problem where data is saved successfully, but the message meant to notify other services is lost.
- What is the Inbox pattern, and how does it support end-to-end consistency?
Short answer
Inbox pattern ensures that a message received by a consumer service is processed and recorded atomically with the consumer's state change, preventing message loss or duplicate processing.
- How do you handle validation of API/Contract changes across microservices?
Short answer
API and contract changes are one of the main failure points in microservices. Services are deployed independently, so you must assume that producers and consumers will run different versions simultaneously.
- How do MassTransit or NServiceBus simplify messaging compared to raw clients?
Short answer
MassTransit and NServiceBus sit on top of raw brokers like Azure Service Bus or RabbitMQ. Instead of working with low-level queues and messages, you work with typed messages and consumers, with most reliability concerns handled for you.
- How do you avoid temporal coupling between producers and consumers?
Short answer
Temporal coupling happens when a producer and a consumer must be available at the same time for the system to work. If one side is down or slow, the whole flow breaks.
- Why is 2PC avoided in microservices, and what are the alternatives?
Short answer
Two-Phase Commit (2PC) is a distributed transaction protocol that tries to guarantee atomicity across multiple services or databases. In microservices, it is usually avoided because it creates tight coupling, hurts availability, and does not scale well.
- How do you implement a saga, and how do compensating steps work?
Short answer
A Saga is a sequence of local transactions where each service performs its task and then publishes an event to trigger the next service. If any step fails, the Saga executes Compensating Transactions to undo the previous successful steps, ensuring eventual consistency.
- When would you avoid event sourcing in enterprise systems?
Short answer
While Event Sourcing (storing every state change as a sequence of events) is powerful for auditing and complex domains, it introduces significant complexity that can derail an enterprise project if misapplied.
- How do you choose distributed IDs, and which IDs are best?
Short answer
Distributed IDs must be unique across services, generated without coordination, and safe under scale. The wrong choice causes collisions, hot partitions, or performance problems.
- What is eventual consistency, and how do you communicate its impact to the business?
Short answer
Eventual consistency means that data does not become consistent everywhere immediately. After a change, different parts of the system may temporarily show different states, but over time, they converge to the same correct result.
- What is the difference between logical clocks and physical clocks?
Short answer
A physical clock is a device that indicates the time. A distributed system can have many physical clocks, and in general, they will not agree.
- What is write-skew, and how does it appear in distributed systems?
Short answer
Write-skew is a consistency anomaly in which two concurrent operations read the same data, make independent decisions, and then write updates that, together, violate a business rule. Each write is valid on its own, but the final combined state is wrong.
- What is monotonic read consistency, and why does it matter?
Short answer
Monotonic read consistency is a guarantee in distributed systems that once a process has read a specific version of a data item, any subsequent reads by that same process will never return an "older" version of that data.
- What is a distributed deadlock, and how does it occur?
Short answer
A distributed deadlock occurs when multiple services or nodes in a distributed system wait for each other indefinitely, preventing any of them from making progress. Each participant is blocked, waiting for another to release a resource, respond, or complete an action.
- What is split-brain, and how do systems avoid it?
Short answer
Split-brain is a failure scenario in which a distributed system is divided into multiple partitions, and each partition believes it is the only active or “leader” partition. As a result, numerous nodes simultaneously make conflicting decisions.
- How do you design safe retry strategies across multiple services?
Short answer
Safe retry strategies prevent retries from worsening failures. In distributed systems, poorly designed retries can amplify load, cause cascading failures, and turn minor incidents into outages.
- What is a circuit breaker, and when do you need one?
Short answer
A circuit breaker is a resilience pattern that protects a system from repeatedly calling a failing dependency. Instead of retrying endlessly, it temporarily stops requests and allows the system to recover.
- How does Bulkhead isolation in .NET protect against cascading failures in microservices?
Short answer
Bulkhead isolation is a resilience pattern that limits the number of resources (threads, tasks, or connections) a part of your system can use. It prevents failures in one area from spreading and crashing everything else, just as watertight compartments on a ship.
- What is backpressure, and how do you apply it to message processing?
Short answer
Backpressure is a mechanism that prevents a fast producer from overwhelming a slow consumer.
- How do you handle poison messages that repeatedly crash consumers?
Short answer
A Poison Message is a specific type of message that contains data the consumer cannot process (e.g., malformed JSON, a divide-by-zero scenario, or an edge case not handled in code). Because the message itself is "bad," retrying it simply causes the consumer to crash or fail again, creating an infinite loop.
- What patterns help with long-running workflows or batch jobs?
Short answer
Long-running workflows and batch jobs cannot rely on synchronous calls or single transactions. They must survive restarts, partial failures, retries, and long delays.
- What RED and USE metrics should you instrument?
Short answer
RED and USE are two complementary metric sets. RED focuses on user-facing services.
- How do you authenticate and authorize between microservices?
Short answer
In a microservices architecture, authentication and authorization are typically handled through a combination of centralized and decentralized patterns to ensure both security and performance.
- What is a token exchange, and when is it used?
Short answer
A token exchange is a security pattern in which one token is exchanged for another with a different scope, audience, or trust level. It is commonly used when a service needs to call another service on behalf of a user or another service, without reusing the original token directly.
- Why is secret rotation important in distributed systems?
Short answer
In distributed systems, secret rotation is the periodic rotation of credentials (such as API keys, database passwords, and encryption keys) to reduce the risk of unauthorized access.
- How do you secure internal service communication in Kubernetes?
Short answer
In a Kubernetes environment, securing internal service communication requires a multi-layered approach that addresses encryption, identity, and network-level access control.
- What is zero-trust networking, and why is it growing in popularity?
Short answer
Zero-trust networking is a security model built on the principle of "never trust, always verify". Unlike traditional perimeter-based security—which assumes everything inside a corporate network is safe—zero-trust treats every request as a potential threat, regardless of its origin.
- How can you reuse a user token across multiple microservices for authorization?
Short answer
In .NET microservices, securely reusing a user token across multiple services requires balancing architectural simplicity with robust security principles like Least Privilege and Zero Trust.
- What is the difference between latency and throughput?
Short answer
Latency is the time one request or operation takes from start to finish. Throughput is how many requests or units of work the system can complete per unit of time.
- Why does chatty communication break performance in microservices?
Short answer
Chatty communication happens when a single user request triggers many synchronous calls between services. Each call may be fast on its own, but together they create latency, fragility, and poor scalability.
- How do you design services that scale horizontally?
Short answer
Designing services for horizontal scaling—adding more instances of a service to handle increased load—requires a shift away from stateful monoliths toward stateless, decoupled architectures. In a .NET microservices environment, this is achieved through the following strategies.
- What is load shedding, and when should you apply it?
Short answer
Load shedding is a deliberate strategy to drop or reject some requests when a system is overloaded. Instead of trying to handle everything and failing unpredictably, the system fails fast for a subset of traffic to protect overall stability.
- How do you reduce the cost of cross-region traffic?
Short answer
To reduce cross-region traffic costs in .NET microservices, focus on data volume and locality.
- What is the Tail-at-Scale problem, and how do you mitigate it?
Short answer
The Tail-at-Scale problem describes a situation where a small percentage of very slow requests dominates overall system latency. Even if most calls are fast, the slowest ones (the tail, often p95, p99, p99.9) determine user experience and system stability.
- What is a distributed scheduler, and how do you handle fault-tolerant recurring jobs?
Short answer
A distributed scheduler coordinates recurring or delayed jobs across multiple nodes so that each job runs once, even when services scale horizontally or nodes fail. Unlike a local cron, it must handle leader election, locking, retries, and recovery.
- How do you detect memory leaks in .NET microservices?
Short answer
In .NET, most “memory leaks” are not classic leaks. The GC works fine.
- What is .NET Aspire, and what problems does it solve for cloud-native apps?
Short answer
.NET Aspire is a cloud-native application stack for .NET that helps developers build, run, and manage distributed applications more easily. It combines tools, templates, and curated NuGet packages so you don’t start from scratch wiring up observability, resiliency, service discovery, and deployment concerns every time.
- How do Aspire resources differ from normal DI registrations?
Short answer
Aspire resources describe application topology: services, containers, databases, caches, queues, and their relationships for local orchestration and deployment metadata. DI registrations describe objects available inside one process, so they do not model external infrastructure or cross-service dependencies.
- What is Aspire service discovery, and how does it connect distributed components?
Short answer
.NET Aspire service discovery is a built-in mechanism that lets services find and communicate with each other by name rather than hard-coded addresses. In distributed systems, services move, scale, and change URLs or ports frequently.
- How does Aspire handle configuration for distributed systems?
Short answer
In a distributed application, you usually juggle a bunch of settings: connection strings, ports, environment differences, secrets, and custom configs for every service and backing resource. .NET Aspire treats configuration as part of the application model rather than as a set of scattered files.
- What are the limits of Aspire today, and when should you avoid it?
Short answer
Aspire helps build and run cloud-native .NET apps, but it isn’t mature enough to replace all infra tools yet. It works best for projects that start distributed and can live within Aspire’s app model.
- What is YARP, and when would you build your own gateway?
Short answer
YARP (Yet Another Reverse Proxy) is a high-performance, highly customizable reverse proxy library for .NET. It lets you build proxy servers or API gateways inside ASP.NET Core apps.
- What is Dapr, and how do its building blocks differ from usual SDKs?
Short answer
Dapr (Distributed Application Runtime) is an open-source, portable runtime that makes it easier to build distributed, cloud-native applications. It runs as a sidecar process alongside your service and exposes a set of standardized APIs, called building blocks, over HTTP or gRPC.
- What are the trade-offs of containers vs serverless for .NET workloads?
Short answer
Containers give more control over runtime, networking, dependencies, and long-running workloads, but require more platform and scaling management. Serverless reduces infrastructure work and scales to zero, but brings cold starts, execution limits, and less control over the hosting environment.
- How does .NET Native AOT improve cold starts in serverless scenarios?
Short answer
.NET Native AOT (Ahead-of-Time compilation) compiles your .NET app into a native machine binary at publish time instead of shipping IL code that the runtime must JIT compile on startup.
- Why do stateless services scale more easily than stateful ones?
Short answer
Stateless services treat every request independently. They don’t hold session data in memory so that any instance can handle any request without coordination.
- How do you optimize microservices for Native AOT without losing flexibility?
Short answer
Native AOT gives you faster startup and smaller binaries, which helps microservices and cloud functions. But it also imposes limitations, such as restricted reflection and no dynamic assembly loading, so you need to strike a balance between optimization and flexibility.
- What is the Orleans virtual actor model, and how does it differ from classic actor systems?
Short answer
Orleans virtual actors, called grains, are logical actors whose activation, placement, persistence, and lifecycle are managed by the runtime. Classic actor systems usually make actor creation, supervision, and placement more explicit, giving more control but requiring more infrastructure decisions from developers.
- What are grains, and how do they achieve location transparency?
Short answer
Grains are the core building blocks in Orleans. A grain is a virtual actor that combines state and behavior and is addressed by a stable logical identity (for example, OrderId = 123).
- How does Orleans handle distributed state without explicit locks?
Short answer
Orleans avoids locks by design. Each grain processes one request at a time, so its state is never accessed concurrently.
- What are Orleans Streams, and when should you prefer them to message brokers?
Short answer
Orleans Streams are a built-in, asynchronous messaging abstraction inside Orleans. They let grains publish and consume events without tight coupling, while keeping the Orleans programming model: virtual actors, location transparency, and single-threaded execution per grain.
- What is the Orleans Silo, and how does clustering work?
Short answer
An Orleans Silo is a runtime host process that runs grains. Think of a silo as a node in the Orleans cluster.
- How do you scale grains across a clustered environment?
Short answer
Scaling Grains in an Orleans cluster is handled automatically by the runtime through a process called Placement. Unlike traditional microservices, where you manually balance traffic via a Load Balancer, Orleans distributes individual Grain instances across available "Silos" (servers) using configurable strategies.
- How does Orleans differ from Dapr actors?
Short answer
Both Orleans and Dapr implement the "Virtual Actor" model—a concept in which actors exist conceptually and are automatically managed by the runtime. However, their architecture and design goals are fundamentally different.
- What are the main Orleans failure modes, and how do you mitigate them?
Short answer
Orleans hides many distributed-system problems, but failures still happen. The key is knowing where they occur and how Orleans expects you to handle them.
- How do you handle grain versioning and schema evolution?
Short answer
In Orleans, grains can be reactivated at any time, so state versioning and schema evolution must be safe by default. The core idea is simple: make the old state readable by the new code and evolve gradually.
- How do you integrate Orleans with ASP.NET Core for request-driven scenarios?
Short answer
Integrating Orleans with ASP.NET Core allows you to build a responsive, request-driven frontend (API) that leverages the stateful power of Grains on the backend. In modern .NET (Orleans 7.0+), the integration is seamless because both frameworks share the same Generic Host and Dependency Injection container.
Testing

The detailed answers with diagrams and explanations of what Junior/Middle/Senior should know for the questions below, can be found in our separate article: C# Testing Interview Questions and Answers
- What makes a test a "unit test" in C#, and what is usually mislabeled as unit?
Short answer
A unit test checks a single unit of behavior in isolation. In C#, that usually means a single class or method, executed without touching the real infrastructure.
- What do you test: behavior, state, or interactions, and why?
Short answer
Behavior testing focuses on observable results. You verify inputs and outputs regardless of the internal implementation.
- Dummy vs Mock vs Stub vs Fake vs Spy: what is the difference, and when to use each?
Short answer
A Dummy is a placeholder passed but never used; a Stub returns canned data to drive a path; a Fake is a working but lightweight implementation (like an in-memory repository); a Mock verifies that expected interactions happened; and a Spy is a real object that records how it was called. Use stubs/fakes for state-based tests and mocks/spies when the behavior under test is the interaction itself.
- How do you avoid testing implementation details while still getting confidence?
Short answer
To avoid testing implementation details, you must shift your focus from how the code works to what the code achieves. This is often called Behavior-Based or Outcome-Based testing.
- What are the most common test smells in .NET codebases, and how do you fix them?
Short answer
In .NET, "test smells," or antipatterns, are signs that your test suite is becoming a liability rather than an asset.
- How do you structure tests for readability?
Short answer
Give tests a consistent shape — typically Arrange-Act-Assert — with descriptive names that state the scenario and expected outcome. Keep one logical assertion per test and hide noisy setup behind builders or helpers so the test reads as a clear specification of behavior.
- How do you test cancellation and verify cancellation is actually honored?
Short answer
Make cancellation observable. The code under test should either throw OperationCanceledException, return a canceled Task, or stop producing side effects when the token is canceled.
- How do you test time and scheduling deterministically (timeouts, delays, cron-like logic)?
Short answer
Testing time-based logic is notoriously difficult because standard system clocks are non-deterministic. To test them reliably, you must decouple your code from the real-time clock.
- If code is hard to test, what do you refactor first to make it testable?
Short answer
Separate logic from side effects. Pull pure business rules out of controllers, handlers, and background services into small classes or functions.
- How do you test EF Core migrations and schema changes?
Short answer
EF Core migrations are code that modifies production databases — they deserve the same test coverage as application logic.
- What do you consider an integration test in .NET, and what is still unit-level?
Short answer
In .NET, the line between unit and integration testing isn't about the tool (both use xUnit/NUnit) or the language, but about boundaries.
- What do you run "real" in integration tests (DB, cache, queue), and what do you fake?
Short answer
Run real components where behavior, configuration, or contracts matter, and mocks would lie.
- Why is an in-memory DB often a bad choice compared to a real database for integration testing?
Short answer
While the EF Core In-Memory provider or SQLite In-Memory are tempting because they are fast and require zero setup, they often create a "false sense of security." They are not true databases; they are collections of objects in memory that happen to share a similar API.
- How do you seed data for integration tests without making tests slow and coupled?
Short answer
Seeding data is the "Goldilocks" problem of integration testing: too little data and you aren't testing real scenarios; too much data and your tests become slow and "brittle" (where changing one test breaks ten others).
- How do you isolate the state between tests?
Short answer
Isolating the state is the hardest part of integration testing. If tests leak data into one another, you get "flaky" results where tests pass individually but fail when run in a different order.
- How do you use Testcontainers.NET for SQL Server/Postgres/Redis/Kafka in tests?
Short answer
To use Testcontainers for .NET, you leverage the Docker API to spin up real infrastructure instances as part of your test lifecycle. It replaces "In-Memory" fakes with actual binaries running in lightweight containers.
- What are the challenges of running test containers on Windows agents?
Short answer
Most official images used in tests are Linux-based. On Windows agents, you either need Linux containers support or you are forced into Windows container images, which are fewer, heavier, and sometimes behave differently.
- How do you test file upload/download endpoints?
Short answer
File upload and download endpoints have a different failure surface than JSON APIs — content-type negotiation, multipart boundary parsing, stream handling, size limits, and storage backend integration all sit outside what unit tests reach.
- How do you test ASP.NET Core endpoints without duplicating implementation logic in tests?
Short answer
The recommended approach is to use WebApplicationFactory<T> from the Microsoft.AspNetCore.Mvc.Testing package. It spins up your real application in-memory — with the actual middleware pipeline, routing, dependency injection, and configuration — and exposes an HttpClient to make requests against it.
- How do you test authentication and authorization policies reliably?
Short answer
Testing authentication and authorization in ASP.NET Core is best done at two levels. First, you test the policy logic itself in isolation — verifying that a given policy behaves correctly for specific claims, roles, or requirements.
- How do you test middleware behavior?
Short answer
Middleware testing in ASP.NET Core can be approached at two levels. The first is testing the middleware in complete isolation using TestServer or a minimal RequestDelegate pipeline — useful when the middleware has no dependency on the rest of the application.
- How do you test versioning behavior (URL/header/query) and deprecation responses?
Short answer
API versioning has three failure modes worth testing: the wrong version resolves to the wrong handler, an unsupported version returns the wrong status code, and a deprecated version stops returning deprecation signals.
- How do you integration-test a gRPC service in .NET without going "full E2E"?
Short answer
gRPC services in .NET can be integration-tested in-memory using the same WebApplicationFactory<T> approach used for REST APIs, combined with a gRPC channel configured to communicate over the in-memory test server rather than a real network socket.
- How do you test gRPC status codes and error details?
Short answer
In gRPC, errors are not HTTP status codes — they are RpcException instances carrying a StatusCode enum value and an optional detail message. Testing them means asserting that the right StatusCode is thrown for the right scenario, and optionally that the Status.Detail message contains meaningful information for the caller.
- How do you validate metadata/headers in gRPC calls?
Short answer
In gRPC, HTTP headers are called metadata — key/value pairs sent alongside a request via the Metadata class.
- How do you test deadlines and cancellation in gRPC?
Short answer
gRPC has first-class support for two related but distinct cancellation concepts. A deadline is set by the client and tells the server "complete this call before this point in time or I will stop waiting." A cancellation is an explicit signal — either from the client abandoning the call or from the server deciding to stop processing.
- How do you test streaming gRPC methods (server streaming, client streaming, duplex)?
Short answer
Streaming gRPC methods are more complex to test than unary calls because you need to drive the stream from both ends — writing messages, completing the stream, and reading responses — all in a controlled, sequential way.
- How do you test retry behavior safely for gRPC calls?
Short answer
Retry testing has two distinct concerns that are easy to conflate. The first is verifying that your retry policy actually triggers — that a transient failure causes the client to retry the correct number of times with the correct backoff.
- How do you test the backward compatibility of protobuf contracts?
Short answer
Protobuf backward compatibility is one of those things that feels fine until it suddenly breaks a production client that you forgot was still running an older version. The core rule is simple: never change or reuse field numbers, never rename fields if you rely on JSON serialization, and never change a field's type.
- How do you test gRPC JSON transcoding (if you expose REST endpoints over gRPC services)?
Short answer
gRPC JSON transcoding allows a single gRPC service implementation to be exposed simultaneously as a REST/JSON API by annotating .proto methods with HTTP bindings via google.api.http.
- How do you test interceptor behavior (logging, auth, retries) without making tests brittle?
Short answer
Test interceptors through observable effects rather than internal implementation details: whether the call was blocked, retried, logged, authorized, or decorated as expected. Keep assertions stable by using fake downstream handlers, test log sinks, and controlled policies instead of checking private fields or exact log wording.
- What is consumer-driven contract testing, and when should you use it?
Short answer
Consumer-driven contract testing inverts the normal relationship between integration testing and the consumer.
- How do you test event/message contracts in event-driven architectures?
Short answer
Event contracts are harder to protect than HTTP contracts because there is no request-response handshake — a producer publishes an event, and consumers process it asynchronously, often across team boundaries. A producer that renames a field or changes an enum value silently breaks every consumer without any immediate error.
- What is contract testing, and when is it better than integration testing?
Short answer
Contract testing verifies that a service meets its consumers' expectations without actually calling the real service.
- How would you write contract tests between a BFF and its downstream services (REST and gRPC)?
Short answer
Write consumer-driven contract tests for the BFF expectations against REST schemas and gRPC protobuf contracts. Verify both sides: the BFF can consume downstream responses correctly, and downstream services still satisfy the contracts before deployment.
- How do you evolve contracts safely (versioning, compatibility, provider verification)?
Short answer
Evolving a contract means changing it without breaking existing consumers. The challenge is that consumers may deploy at different times than providers, so any change must work in both directions: a new provider with an old consumer, and an old provider with a new consumer.
- What do contract tests miss, and how do you cover those gaps?
Short answer
Contract tests verify that two services agree on the shape of their communication — the structure of requests and responses — but they deliberately ignore everything else.
- How do you test systems where each service can fail independently?
Short answer
Distributed systems fail in ways monoliths do not — services crash mid-request, networks partition, dependencies become slow or unavailable, and load balancers route traffic to unhealthy instances.
- How do you test idempotency in message consumers (duplicate delivery, out-of-order, replay)?
Short answer
Message-based systems guarantee at-least-once delivery, which means the same message can arrive multiple times — due to retries, network issues, or broker failovers.
- How do you test message replay safely, including side effects (emails, payments, DB writes)?
Short answer
Replaying messages in a distributed system is necessary to recover from failures, debug production issues, or rebuild projections in event-sourced systems. The danger is that replay can trigger real side effects — sending duplicate emails, charging customers twice, or corrupting databases.
- How do you test poison messages and DLQ flow,s including reprocessing logic?
Short answer
A poisoned message repeatedly fails to process and can block the entire queue if not handled correctly. Modern message brokers move these to a Dead Letter Queue (DLQ) after exhausting retries.
- How do you validate message schema compatibility across versions?
Short answer
Message schema compatibility ensures old consumers can read new messages and new consumers can read old messages, preventing runtime deserialization errors when services deploy at different times. The core rule is additive evolution: adding optional fields is safe; removing or renaming fields breaks compatibility.
- Describe the testing strategy for Saga workflows (orchestration vs choreography).
Short answer
Saga workflows coordinate long-running transactions across multiple services by breaking them into steps that can each be independently committed and compensated if the workflow fails. There are two patterns: orchestration (a central coordinator sends commands and tracks state) and choreography (services react to events autonomously).
- How do you test long-running workflows without waiting minutes in tests?
Short answer
Long-running workflows often involve delays, polling intervals, scheduled tasks, or waiting for external events. Running these at real speed makes tests unbearably slow.
- Describe the testing strategy for Event Sourced workflows.
Short answer
Event Sourcing stores state as a sequence of events rather than a current snapshot. Testing event-sourced workflows means verifying three things: that commands produce the correct events, that replaying events rebuilds state correctly, and that projections/read models remain consistent with the event stream.
- How do you test projections/read models and eventual consistency without sleeps?
Short answer
Eventual consistency means the read model updates asynchronously after writes, creating a timing gap in which the write succeeds but the projection has not yet caught up.
- How do you test microservices with shadow traffic or dark reads, and what do you compare?
Short answer
Shadow traffic sends a copy of production requests to the new service while users still receive responses from the current service. Compare status codes, normalized response bodies, side effects, latency, errors, and resource usage, while ensuring the shadow path cannot mutate production state unexpectedly.
- How do end-to-end integration tests work when an API Gateway is in front?
Short answer
Yes, they work, but the strategy shifts. When an API Gateway (like Ocelot, YARP, Kong, or Azure API Management) is in the mix, you have to decide whether you are testing the Internal Microservice or the User-Facing Product.
- How do you cover policy-enforced code paths in sidecar/proxy logic (auth, routing, rate limits)?
Short answer
Policy-enforced paths in sidecar/proxy logic — auth middleware, rate limiters, routing rules — are undertested because they sit at infrastructure boundaries rather than inside application logic.
- How do you test request/response transformations (headers, claims, body rewriting) without brittle assertions?
Short answer
Testing transformations means verifying that the logic correctly alters the state of a request or response without creating tests that break on every minor change to a JSON property. Brittle assertions often occur when tests check the entire serialized string or exact header counts.
- How do you validate observability propagation across the gateway and services (trace headers, correlation IDs)?
Short answer
Observability propagation — W3C traceparent, X-Correlation-Id, baggage headers — is easy to implement and easy to silently break. A middleware refactor or a missing HttpClient factory registration, can drop trace context entirely, and no functional test will catch it because the feature still works.
- How do you test "policy as code" changes so that a config tweak doesn't break production?
Short answer
Policy as code — OPA rules, ASP.NET Core authorization policies, rate-limit configs, and routing rules defined in YAML or JSON — creates a specific failure mode: a one-line config change silently alters who can access what, which routes resolve where, or which requests get dropped.
- How do you mock or test Polly-based policies and circuit-breakers?
Short answer
Testing resilience policies means verifying that your application responds correctly to state changes such as a circuit opening or a retry sequence exhausting, without necessarily testing Polly's internal logic. Testing ensures that your configuration (retry counts, break durations) aligns with business requirements.
- How do you test concurrency limits and bulkheads in request pipelines?
Short answer
Concurrency limits are only “tested” when the test proves two things: the pipeline never exceeds MaxConcurrentRequests, and overflow requests are rejected or queued exactly as designed.
- What is chaos engineering, and what failures can it uncover that normal tests miss?
Short answer
Chaos engineering is the discipline of experimenting with a system to build confidence in its ability to withstand turbulent conditions in production.
- What's the difference between E2E UI tests and API-level E2E tests, and when do you pick each?
Short answer
E2E UI tests exercise the full stack through the browser: UI > API > DB > external services. They verify that the user can actually complete a workflow.
- When do you choose Playwright over Selenium, and why?
Short answer
Choose Playwright for most modern web apps because it has strong auto-waiting, multi-browser support, tracing, isolation, and fast developer feedback. Choose Selenium when you need its older ecosystem, unusual browser/grid integrations, or compatibility with an existing large Selenium suite.
- How do you design selectors to avoid brittleness (roles, accessible names, data-testid)?
Short answer
Brittle selectors are the primary reason UI test suites become unmaintainable. A selector that targets div.container > ul:nth-child(2) > li:first-child > span.label breaks on every CSS refactor, every layout change, every component library upgrade — none of which change application behavior.
- How do you handle dynamic UI (spinners, async rendering) without sleeps?
Short answer
Playwright's auto-wait is the first line of defense. Every ClickAsync, FillAsync, and Expect call automatically waits for the target element to be attached, visible, stable, and enabled before acting.
- How do you structure E2E tests (page objects vs screenplay vs raw flows), and what trade-offs exist?
Short answer
Structuring E2E tests means choosing a design pattern that balances code reuse with readability. Page Objects (POM) is the classic industry standard; it encapsulates the UI of a specific page (selectors and actions) into a class, shielding tests from DOM changes.
- How do you test accessibility (keyboard nav, focus order, screen-reader-friendly names) as part of E2E?
Short answer
Accessibility testing (a11y) in E2E sits at the intersection of functional correctness and inclusive design.
- Load vs stress vs soak: what does each prove?
Short answer
Load testing checks behavior under expected or peak expected traffic. Stress testing pushes beyond capacity to find breaking points, while soak testing runs for a long duration to expose leaks, degradation, and stability issues.
- What do you measure besides averages (p95/p99, error rate, saturation, queue depth)?
Short answer
Averages are the most misleading metric in performance testing. A p50 latency of 200ms looks healthy, while a p99 of 8 seconds means one in a hundred users waits 8 seconds — and in high-traffic systems, that is thousands of users per hour.
- How do you handle flaky tests operationally?
Short answer
Handling flaky tests means treating "non-deterministic" failures as a specialized form of technical debt. If a test fails 1 out of 10 times without a code change, it erodes the team's trust in the CI/CD pipeline.
Desktop Development

The detailed answers with diagrams and explanations of what Junior/Middle/Senior should know for the questions below, can be found in our separate article: C# Desktop Development Interview Questions and Answers
- What is WinUI 3, and how does it differ from UWP and WPF?
Short answer
WinUI 3 is Microsoft’s modern UI framework for building native Windows desktop applications. It is part of the Windows App SDK and provides the latest Windows UI controls, Fluent Design styling, and modern windowing APIs while running as a regular desktop application.
- How do you implement drag-and-drop between your desktop app and the OS in WinUI 3 or WPF?
Short answer
Drag-and-drop between a desktop app and the OS works through the OLE drag-and-drop protocol on Windows, the same mechanism used by File Explorer, Office, and every other Windows app. Both WPF and WinUI 3 wrap this protocol in XAML properties and events, but their API surfaces differ.
- What is the Windows App SDK, and what problems does it solve over the classic Win32/UWP split?
Short answer
The Windows App SDK is a set of libraries, frameworks, and APIs that Microsoft ships independently from the OS, giving desktop developers access to modern Windows platform features without being locked to a specific Windows version or app model.
- How does the WinUI 3 threading model work, and how do you marshal UI updates from background threads?
Short answer
WinUI 3 follows a Single-Threaded Apartment (STA) UI model — all UI elements are owned by the thread that created them and are backed by a DispatcherQueue tied to that thread. Attempting to update a control from a background thread throws an exception.
- What is the XAML Islands feature, and when would you use it to migrate a WPF/WinForms app?
Short answer
XAML Islands is a technology that lets you host modern WinUI controls inside a classic WPF or WinForms application. Instead of rewriting an entire legacy app to adopt WinUI 3, you embed individual modern controls — like InkCanvas, MapControl, or custom WinUI components — as islands within the existing app shell.
- How do you handle packaging and deployment in WinUI 3?
Short answer
WinUI 3 apps can ship in two deployment modes: packaged (MSIX) or unpackaged. Packaged apps are wrapped in an MSIX container — a modern Windows installer format that provides clean install/uninstall, automatic updates, sandboxed storage, and package identity.
- How does WinUI 3 integrate with the Windows notification and lifecycle system?
Short answer
WinUI 3 apps integrate with Windows notifications through the AppNotificationManager API from the Windows App SDK, which replaced the older ToastNotificationManager from WinRT. For packaged apps, registration is automatic via the app's package identity.
- What is .NET MAUI, and how does it differ from Xamarin.Forms?
Short answer
.NET MAUI (Multi-platform App UI) is the evolution of Xamarin.Forms. It is a cross-platform framework for creating native mobile and desktop apps with C# and XAML.
- How does the .NET MAUI single project structure work across Android, iOS, Windows, and macOS?
Short answer
The MAUI single project is a multi-targeted .csproj that compiles to different native runtimes depending on the target platform.
- What are MAUI Handlers, and how do they replace Xamarin.Forms Renderers?
Short answer
MAUI Handlers are the mechanism .NET MAUI uses to connect cross-platform UI controls to the underlying native platform controls. They replace the Renderer architecture used in Xamarin.Forms.
- How does .NET MAUI implement dependency injection, and what is the MauiAppBuilder lifecycle?
Short answer
MAUI uses the same Microsoft.Extensions.DependencyInjection container as ASP.NET Core, making the DI pattern consistent across the entire .NET ecosystem. Services, pages, and ViewModels are registered in MauiProgram.cs via MauiAppBuilder, which acts as the single composition root before the app launches.
- What is the Shell navigation model in MAUI, and how does it compare to manual navigation stacks?
Short answer
MAUI Shell provides a top-level navigation host that handles routing, flyout menus, tab bars, and URI-based navigation in one unified structure. Instead of manually pushing and popping pages on a NavigationPage stack, Shell lets you define the app's navigation hierarchy declaratively in XAML and navigate by route string.
- How do you handle platform-specific code in MAUI using partial classes and platform folders?
Short answer
MAUI offers two clean mechanisms for platform-specific code: the Platforms folder for fully platform-scoped files, and partial classes for splitting a shared interface from its platform implementations. Files inside Platforms/Android, Platforms/iOS etc.
- What are MAUI Essentials, and what categories of native device APIs do they expose?
Short answer
MAUI Essentials is a set of cross-platform APIs built directly into .NET MAUI that expose native device capabilities through a unified interface. Unlike Xamarin.Essentials which was a separate NuGet package, MAUI Essentials ships as part of the framework — no extra installation needed.
- How does .NET MAUI handle hot reload, and what are its current limitations?
Short answer
MAUI supports two reload mechanisms: XAML Hot Reload and .NET Hot Reload. XAML Hot Reload updates UI layout and styles instantly on the running app when XAML files are saved — no recompile needed, changes appear on the device or emulator in seconds.
- How do you optimize MAUI app startup time and reduce cold-launch latency?
Short answer
Cold-launch latency in MAUI comes from several compounding costs: the .NET runtime initializing, the DI container building, XAML parsing the first page, and platform-specific bootstrapping. Optimizing startup means attacking each layer independently rather than treating it as one monolithic problem.
- What strategies exist for sharing code between MAUI and a web/API project in the same solution?
Short answer
Share code by moving business logic, DTOs, validation, API clients, and persistence abstractions into .NET class libraries used by both MAUI and web/API projects. Keep UI, platform services, and hosting concerns separate so shared projects stay testable and platform-neutral.
- What is Avalonia UI, and what makes it a viable cross-platform desktop alternative to WPF?
Short answer
Avalonia UI is an open-source, cross-platform XAML-based UI framework that runs on Windows, Linux, macOS, iOS, Android, and WebAssembly.
- How does Avalonia's rendering pipeline differ from WPF and WinUI 3?
Short answer
Avalonia owns its cross-platform rendering pipeline and draws through Skia or platform backends, giving consistent UI across Windows, Linux, and macOS. WPF relies on Windows-only DirectX-based rendering, while WinUI 3 uses the Windows App SDK and native Windows composition stack.
- What is the Avalonia MVVM toolkit, and how does it integrate with ReactiveUI or CommunityToolkit.Mvvm?
Short answer
Avalonia has no mandatory MVVM framework — it's MVVM-friendly by design but ships without one baked in. The two dominant choices are ReactiveUI and CommunityToolkit.Mvvm.
- How does Avalonia handle theming and styling compared to WPF resource dictionaries?
Short answer
Avalonia's styling system is CSS-inspired rather than WPF's resource dictionary lookup model. In WPF, styles are keyed resources resolved through a static tree walk — StaticResource vs DynamicResource being a constant source of ordering bugs.
- How do you test Avalonia UI components in headless mode?
Short answer
Avalonia ships a headless testing platform via Avalonia.Headless that runs the full UI stack — layout, rendering, input, and visual tree — without a real window or display.
- What problems does MVVM solve, and when does it become over-engineering?
Short answer
MVVM solves three concrete problems: testability, separation of UI logic from business logic, and designer-developer collaboration. By binding the View to a ViewModel that knows nothing about UI controls, you can unit test all presentation logic — state transitions, command enabling, validation — without spinning up a window.
- How do you integrate Win32/native APIs into modern .NET desktop apps?
Short answer
Win32 integration in .NET means calling into native Windows DLLs — user32.dll, kernel32.dll, dwmapi.dll and others — through P/Invoke or the newer LibraryImport source generator.
- How does the CommunityToolkit.Mvvm library simplify MVVM implementation in modern desktop apps?
Short answer
CommunityToolkit.Mvvm (often called the MVVM Toolkit) is a source-generator-based MVVM library from Microsoft that eliminates boilerplate without runtime overhead.
- What is the difference between RelayCommand and AsyncRelayCommand in CommunityToolkit.Mvvm?
Short answer
RelayCommand wraps synchronous actions and is best for work that completes immediately. AsyncRelayCommand wraps Task-returning operations, exposes async execution state, and avoids blocking the UI thread during awaited work.
- How do you implement navigation as a service in MVVM desktop applications?
Short answer
Navigation as a service means ViewModels trigger navigation without knowing anything about the UI layer — no references to Frame, NavigationService, or Shell.Current inside the ViewModel code. Instead, an INavigationService abstraction is defined in the shared layer, implemented by the UI layer, and injected into ViewModels via DI.
- How do you handle dialog and overlay coordination in MVVM without code-behind?
Short answer
Dialogs are a classic MVVM pain point — showing a dialog is inherently a UI concern, but the decision to show it is a ViewModel concern. The clean solution is an IDialogService abstraction injected into ViewModels, identical in principle to navigation as a service.
- What are source generators in CommunityToolkit.Mvvm and what boilerplate do they eliminate?
Short answer
Source generators are a C# compiler feature that runs during compilation and produces additional C# code based on what it finds in your source.
- How do you manage application state across views in a desktop MVVM application?
Short answer
Application state management is about deciding where data lives, who owns it, and how changes propagate to interested ViewModels. The core problem: when two views need the same data — a user profile shown in a sidebar and an editor page — who holds the truth, and how does a change in one reflect in the other.
- How do you manage multi-window applications in WinUI 3 or WPF, and how do you handle DPI awareness across monitors?
Short answer
Multi-window management in WinUI 3 means each window is an independent Microsoft.UI.Xaml.Window instance with its own DispatcherQueue and compositor. Unlike WPF where windows share a single Application.Current.Windows collection, WinUI 3 has no built-in window registry — you track windows yourself.
- How do you diagnose and fix UI performance issues in WPF/WinUI?
Short answer
UI performance issues in WPF and WinUI 3 fall into three categories: layout thrashing, render bottlenecks, and UI thread overload. Diagnosing which category applies before optimizing is essential — applying the wrong fix wastes time and can introduce new issues.
- How do you virtualize large lists and data grids in modern desktop frameworks?
Short answer
Virtualization means only creating and rendering the UI elements currently visible in the viewport — not one control per data item. Without it, a list of 100,000 items creates 100,000 controls in memory, making the UI slow to load and expensive to scroll.
- What is composition-based rendering, and how does it improve animation performance in WinUI 3?
Short answer
Composition-based rendering means UI elements are broken into independent layers — called visuals — that the GPU composites together rather than the CPU redrawing the entire scene on every frame.
- How do you profile and diagnose UI thread jank in desktop applications?
Short answer
UI thread jank — missed frames, stuttering animations, unresponsive input — almost always comes from one root cause: synchronous work on the UI thread that takes longer than one frame budget (16ms at 60fps). Diagnosing it means identifying what's running on the UI thread that shouldn't be, which requires a profiler rather than guesswork.
- What is ahead-of-time (AOT) compilation, and how does it affect desktop app startup and size?
Short answer
AOT compilation converts .NET IL bytecode to native machine code at publish time rather than at runtime via the JIT compiler. The result is an executable that contains native code ready to run immediately — no JIT warmup, no runtime IL interpretation.
- How do you design a desktop app that works offline and syncs later?
Short answer
Offline-first design means the app is fully functional without a network connection — reads come from local storage, writes go to local storage first, and sync to the remote is a background concern the user shouldn't need to think about. This is an architectural commitment, not a feature added later.
- How do you use SQLite with EF Core in a desktop application for local-first data storage?
Short answer
SQLite via EF Core is the standard local-first storage solution for desktop apps — it's embedded, zero-configuration, and ships as a NuGet package. The database is a single file on disk, making it trivially portable and easy to back up or sync.
- How do you integrate REST or gRPC service calls into a desktop app without blocking the UI thread?
Short answer
REST and gRPC calls in desktop apps follow the same non-blocking rule as any I/O — all network calls go through async/await on background threads, results are applied to the UI thread, and the ViewModel exposes loading and error state so the UI reflects what's happening.
- How do you handle secure credential storage in desktop applications across platforms?
Short answer
Secure credential storage means never writing passwords, tokens, or API keys to plain files, app settings, or registry strings. Each platform provides a native secure store backed by OS-level encryption: Windows Credential Manager, macOS Keychain, and Linux Secret Service (via libsecret).
- How do you implement background sync between local storage and a remote API in a desktop app?
Short answer
Background sync means keeping local SQLite data consistent with a remote API without blocking the UI or requiring the user to manually refresh. The pattern combines a local-first read model — the UI always reads from SQLite — with a background worker that pushes local changes up and pulls remote changes down on a schedule or trigger.
- What are the options for auto-updating a desktop application, and how do you implement them in .NET?
Short answer
Auto-update in desktop apps comes down to three approaches: platform-managed updates via the Microsoft Store (MSIX), self-managed updates via a dedicated update framework, or custom update logic built on raw HTTP.
- How does MSIX packaging affect installation, updates, and sandboxing on Windows?
Short answer
MSIX is a container format that fundamentally changes how Windows apps install, run, and update compared to classic MSI or xcopy deployment. Installation is atomic — either the full package installs successfully or nothing changes on the system, eliminating the partial-install failures common with legacy installers.
- What is the difference between packaged and unpackaged WinUI 3 deployment, and what capabilities does each unlock?
Short answer
Packaged deployment wraps the app in an MSIX container giving it a package identity — a cryptographically verified name, publisher, and version tuple that Windows uses to gate access to protected APIs. Unpackaged deployment is a plain Win32 executable with no identity, deployed like a classic desktop app.
- What are the real-world limitations of MSIX, and when would you avoid it?
Short answer
MSIX's constraints are real and frequently underestimated. The sandboxing model that makes it clean to install is the same mechanism that breaks legacy code — filesystem virtualization, registry redirection, and capability-gated API access are architectural constraints, not configuration switches.
Mobile Development

The detailed answers with diagrams and explanations of what Junior/Middle/Senior should know for the questions below, can be found in our separate article: C# Mobile Development Interview Questions and Answers
- How do native MAUI UI, BlazorWebView, HybridWebView, and WebView differ in 2026?
Short answer
Native MAUI UI renders platform-native controls through handlers and is best for native look, performance, and device integration. BlazorWebView hosts Razor components in-process, HybridWebView bridges web UI with native code, and WebView simply displays web content with less .NET integration.
- How do you migrate a Xamarin.Forms app to .NET MAUI?
Short answer
Migrating from Xamarin.Forms to MAUI is a meaningful refactor, not a simple upgrade. The project structure, namespace changes, startup model, renderer architecture, and NuGet ecosystem all changed.
- How do .NET MAUI handlers differ from Xamarin.Forms renderers?
Short answer
Xamarin.Forms renderers subclassed platform controls and owned much of the control lifecycle, which made customization powerful but heavy. .NET MAUI handlers map cross-platform controls to native views through smaller mapper-based adapters, reducing coupling and improving startup and customization paths.
- How do you customize MAUI controls with handler mappers?
Short answer
.NET MAUI controls are customized through handlers. A handler maps a cross-platform MAUI control, like Entry or Button, to its native platform control.
- How do you structure MVVM with CommunityToolkit.Mvvm in MAUI?
Short answer
In .NET MAUI, MVVM usually separates UI, state, and behavior into three parts: the Page contains XAML, the ViewModel exposes bindable state and commands, and services handle external work like APIs, storage, or navigation. CommunityToolkit.Mvvm reduces boilerplate with source generators such as [ObservableProperty] and [RelayCommand].
- How should dependency injection lifetimes be used in MAUI apps?
Short answer
Dependency injection lifetimes in MAUI follow the same three options as ASP.NET Core — Singleton, Transient, and Scoped — but the absence of a request scope in a desktop/mobile app means Scoped behaves differently and is rarely the right choice.
- How do you build reusable UI with ContentView, custom controls, behaviors, triggers, and converters?
Short answer
A reusable UI in .NET MAUI usually starts with a ContentView. It works well for repeated screen fragments: cards, headers, empty states, form sections, or small composed widgets.
- How do MAUI app icons, splash screens, fonts, and icon fonts work in single-project apps?
Short answer
In .NET MAUI single-project apps, platform assets like app icons, splash screens, images, and fonts are defined once in the shared project and then automatically transformed into platform-specific resources during build.
- Describe the .NET MAUI mobile app lifecycle. What are the key execution states, and how do you handle backgrounding, resuming, and termination?
Short answer
.NET MAUI apps use the cross-platform Window lifecycle as the modern framing for mobile state. The main events are Created, Activated, Deactivated, Stopped, Resumed, Destroying, and Backgrounding on iOS and Mac Catalyst.
- How do you handle state preservation during app lifecycle events? Why is relying on the Window instance persistence unreliable?
Short answer
Relying on a Window, page, or ViewModel instance to survive app backgrounding is unreliable because each platform can reclaim the process while it is stopped. Persist the state you need to recover: navigation route, form draft data, selected IDs, sync checkpoints, and small user preferences.
- What Shell navigation and which navigation options exist?
Short answer
.NET MAUI Shell provides URI-based routing for moving between pages, tabs, flyout items, and registered detail pages. Use GoToAsync("route") for forward navigation, GoToAsync(".") for back navigation, and absolute routes such as //home when resetting the navigation stack.
- Compare Shell navigation vs NavigationPage in .NET MAUI. When would you choose one over the other?
Short answer
Shell provides URI routing, flyout and tab structure, deep-link-friendly navigation, search handlers, and route-based parameter passing. NavigationPage provides a traditional stack with PushAsync and PopAsync and can be useful for simple flows or migration scenarios that already depend on stack navigation.
- How do you pass data between pages in .NET MAUI Shell navigation?
Short answer
In .NET MAUI Shell, pass simple route values as URI query parameters and pass complex objects with object-based navigation data. Use URI query strings for stable identifiers such as details?id=5; avoid putting sensitive values or large object graphs into the URI because they can be logged, bookmarked, or reused from deep links.
- How do you implement push notifications in a .NET MAUI app for both Android and iOS?
Short answer
.NET MAUI does not include a single built-in push notification API. Production apps usually integrate platform push services through Firebase Cloud Messaging for Android, APNs for iOS, Azure Notification Hubs, or a maintained plugin such as Plugin.Firebase.
- How do you implement local notifications in .NET MAUI?
Short answer
Local notifications are scheduled by the app on the device and are useful for reminders, calendar-like events, and local status alerts. MAUI apps typically expose a shared notification interface and provide per-platform implementations, or use a maintained plugin when its platform coverage matches the product requirements.
- How would you implement deep linking / app links in a .NET MAUI application?
Short answer
Deep linking lets an app respond to external URIs and navigate to specific content. Use Android App Links or intent filters, iOS Universal Links, and optional custom URI schemes when appropriate.
- What should you know about SafeAreaEdges, gestures, CollectionView, and CarouselView in .NET 10?
Short answer
These are core UI building blocks in modern MAUI apps, and in .NET 10, they continue to shape how production mobile UIs are built.
- What gesture recognizers does .NET MAUI support, and how do you handle complex touch interactions?
Short answer
.NET MAUI provides a set of built-in gesture recognizers that cover the most common mobile and desktop interactions. For more complex scenarios, such as drawing or multi-touch tracking, you must go beyond these and use platform-specific events or specialized effects.
- How do you implement pull-to-refresh and swipe actions in .NET MAUI?
Short answer
Pull-to-refresh: Wrap a CollectionView in RefreshView: Set IsRefreshing = false in a finally block so failed refreshes do not leave the spinner running. Swipe actions on list items: Use SwipeView inside CollectionView.ItemTemplate: Supports LeftItems, RightItems, TopItems, BottomItems.
- Compare CollectionView vs. ListView in .NET MAUI. What are the key performance differences?
Short answer
While both controls are used to display lists of data, CollectionView is the modern, more flexible successor to the legacy ListView. In fact, as of .NET 10, ListView and its related cell types are officially marked as obsolete, making CollectionView the primary choice for all new development.
- How do you build responsive layouts for different mobile screen sizes in .NET MAUI?
Short answer
Multiple techniques work together. Use Grid with proportional (*) sizing and FlexLayout for wrapping.
- How do you implement MAUI Graphics for custom drawing on mobile?
Short answer
MAUI Graphics (Microsoft.Maui.Graphics) is a cross-platform drawing API that abstracts Skia, CoreGraphics, Direct2D, and Canvas2D behind a unified ICanvas interface. Custom drawing is implemented by creating a class that implements IDrawable, then hosting it in a GraphicsView control in XAML.
- How do you implement mobile accessibility (a11y) in .NET MAUI?
Short answer
Accessibility in .NET MAUI is primarily handled through Semantic Properties, which map cross-platform XAML attributes to native accessibility APIs like TalkBack (Android) and VoiceOver (iOS). Instead of building platform-specific logic, developers use a unified set of properties to describe UI intent.
- How do localization, globalization, and right-to-left layouts work in MAUI?
Short answer
Localization in MAUI uses the standard .NET resource file approach — .resx files per language, accessed through a generated strongly-typed class. Globalization covers number, date, and currency formatting using CultureInfo.
- How does .NET MAUI handle app permissions? What are the best practices?
Short answer
The Permissions class in Microsoft.Maui.ApplicationModel provides cross-platform permission handling.
- How do you access the camera and GPS in .NET MAUI?
Short answer
In .NET MAUI, hardware features like the camera and GPS are accessed through platform-integration APIs such as MediaPicker and Geolocation. They provide a cross-platform surface, but permissions and platform manifest declarations still matter.
- How do you implement biometric authentication (Face ID, Touch ID, fingerprint) in .NET MAUI?
Short answer
No built-in API exists. In .NET MAUI, biometric authentication is typically implemented via a Plugin .Fingerprint or Plugin.Maui.Biometric NuGet packages.
- How do you implement background work in MAUI across Android, iOS, and Windows?
Short answer
Background work in .NET MAUI is not truly cross-platform via a single API. MAUI gives the shared app model, but background execution is controlled by each operating system.
- Explain SecureStorage in .NET MAUI. How does it differ across iOS and Android?
Short answer
SecureStorage is a .NET MAUI API for storing sensitive key/value pairs (such as access tokens, passwords, or secrets) using the device's native secure storage mechanisms. Unlike the standard Preferences API, which stores data in plain text, SecureStorage ensures that data is encrypted at rest.
- How do you implement an offline-first architecture in a .NET MAUI mobile app?
Short answer
Implementing an offline-first architecture in .NET MAUI involves shifting from a "Network-First" approach to a Local-First model. In this setup, the UI interacts exclusively with a local database, while a background process synchronizes that data with a remote server.
- How does SQLite work in .NET MAUI, and what are the file system differences between iOS and Android?
Short answer
SQLite in MAUI is an embedded database stored as a local file, commonly accessed through sqlite-net, EF Core, or raw SQLite APIs. iOS stores app data inside its sandboxed container with backup rules, while Android uses app-specific internal storage paths and different lifecycle/backup behavior.
- How do you configure HttpClient and platform network handlers in MAUI?
Short answer
In .NET MAUI, HttpClient is usually registered via dependency injection and consumed by services, rather than created directly in pages or ViewModels. This keeps the networking testable and avoids socket exhaustion caused by creating many short-lived HttpClient instances.
- How do you optimize .NET MAUI mobile app startup time?
Short answer
Start by measuring startup on real devices, then remove avoidable work from the startup path. Defer network calls, database warmup, and expensive service creation until the first screen actually needs them.
- What strategies optimize memory and battery on mobile MAUI apps?
Short answer
To keep a MAUI app efficient, focus on UI rendering cost, object lifetime, native resource usage, and measured platform behavior rather than enabling every optimization switch by default.
- Why is AOT compilation required on iOS for .NET apps, and how does Native AOT work?
Short answer
AOT matters on iOS because Apple restricts apps from generating and executing new machine code at runtime. Standard .NET MAUI Release builds for iOS normally use the Mono runtime with Mono AOT, not Native AOT.
- Describe deploying a .NET MAUI app to the App Store and Google Play.
Short answer
Deploying a .NET MAUI app requires navigating two distinct ecosystems: the Google Play Console for Android and App Store Connect for iOS. While the code is shared, the packaging, signing, and submission workflows differ significantly.
- What should you know about Play App Signing, upload keys, package formats, and app size optimization?
Short answer
Publishing Android apps from MAUI involves more than just generating an APK. Modern Play Store deployment typically uses Play App Signing, in which Google manages the production signing key and the development team signs uploads with a separate upload key.
- How do you set up CI/CD for .NET MAUI mobile apps?
Short answer
Setting up CI/CD for .NET MAUI means orchestrating SDK installation, MAUI workloads, platform-specific runners, signing assets, Release publishing, artifact retention, and store or tester distribution.
- How do you handle crash reporting and analytics in .NET MAUI?
Short answer
Crash reporting and analytics should be initialized early, attach enough context to diagnose failures, and avoid sending personally identifiable information.
- What are the key mobile testing strategies for .NET MAUI apps?
Short answer
MAUI app testing splits into three layers: unit testing ViewModels, and services in isolation, integration testing of platform behavior with a MAUI test host, and UI automation testing of end-to-end flows on real devices or emulators.
- What is BlazorWebView in .NET MAUI, and how does its architecture work?
Short answer
BlazorWebView is a .NET MAUI control that hosts Blazor web UI components inside a native app. Razor components run natively in the .NET process — not in the browser and not via WebAssembly.
- When should you choose Blazor Hybrid vs. native MAUI UI?
Short answer
Choose Blazor Hybrid when you want to reuse Razor components, web skills, and shared UI between web and mobile/desktop. Choose native MAUI UI when platform-native behavior, startup performance, accessibility, and deep device integration matter more than web UI reuse.
- How do you share Razor components between a Blazor Web App and a Blazor Hybrid MAUI app?
Short answer
Sharing Razor components between Blazor Web and Blazor Hybrid works through a Razor Class Library (RCL) — a separate project that contains all shared components, pages, CSS, and static assets. Both the Blazor Web App and the MAUI Blazor Hybrid app reference the RCL and host the same components in their respective runtimes.
- How does JavaScript interop work in Blazor Hybrid apps, and what differs from Blazor Web?
Short answer
JS interop uses IJSRuntime injected into Razor components, calling JavaScript in the embedded WebView.
- Explain how BlazorWebView.TryDispatchAsync works, and when you would use it.
Short answer
TryDispatchAsync is a method on BlazorWebView that marshals a delegate onto the Blazor renderer's synchronization context from outside the Blazor component tree. In Blazor Hybrid, the Blazor renderer runs on its own synchronization context inside the native WebView — it's neither the .NET MAUI UI thread nor a standard thread pool thread.
- What are the performance considerations for Blazor Hybrid apps on mobile devices?
Short answer
Blazor Hybrid on mobile runs the .NET runtime natively but renders UI inside a WebView — this means performance is constrained by two distinct layers: .NET execution cost and WebView rendering cost.
- What are the key limitations of Blazor Hybrid on mobile?
Short answer
Blazor Hybrid sits between native and web application models. Razor components run in the native .NET process, but UI still renders through a platform WebView, so the app inherits WebView rendering, debugging, and automation constraints while still needing native MAUI code for device capabilities.
- How does navigation work in Blazor Hybrid compared to native MAUI navigation?
Short answer
Blazor Hybrid navigation combines two independent navigation systems that don't natively know about each other. Inside the BlazorWebView, Blazor manages its own router — NavigationManager handles component-level navigation within the WebView's HTML context using the same URL-based routing as Blazor Web.
- How do you access native device features from Blazor Hybrid components?
Short answer
Blazor Hybrid components cannot access native device features directly — they run inside a WebView with no direct path to platform APIs.
- What are iOS Entitlements and Provisioning Profiles, and how do they work together?
Short answer
Entitlements and provisioning profiles are Apple's mechanism for controlling which capabilities an app can use and which devices it can run on.
- What is App Transport Security (ATS) and how do you configure it in .NET MAUI for iOS?
Short answer
App Transport Security is Apple's network security policy, enforced at the OS level on iOS and macOS, that requires all HTTP connections to use HTTPS with TLS 1.2 or higher, forward-secret cipher suites, and SHA-256 or stronger certificates. ATS is enabled by default for all apps.
- What role does R8 play in .NET Android builds?
Short answer
R8 is Google's Android code shrinker, obfuscator, and optimizer that processes Java and Kotlin bytecode in the Android build pipeline. In .NET Android builds, R8 operates on the Java interop layer — the Java stubs and Android bindings that the .NET Android SDK generates to bridge managed .NET code with the Android runtime.
- Describe Android-specific memory management in .NET MAUI apps.
Short answer
.NET MAUI on Android has a dual-runtime memory model: managed heap (Mono/.NET GC) for C# objects and Java/ART heap for Java objects.
- Compare the approaches for writing platform-specific code in .NET MAUI.
Short answer
MAUI provides four distinct mechanisms for platform-specific code, each with different trade-offs in readability, testability, and scope. Choosing the right one depends on how much of the codebase needs the platform behavior and whether the platform logic needs to be tested or swapped independently.
- How do you create binding projects for native iOS and Android libraries in .NET MAUI?
Short answer
Binding projects are .NET class libraries that wrap native iOS (Objective-C/Swift) or Android (Java/Kotlin) libraries and expose them as strongly-typed C# APIs. When a native SDK has no official .NET NuGet package, a binding project is the mechanism for consuming it.
AI

The detailed answers with diagrams and explanations of what Junior/Middle/Senior should know for the questions below, can be found in our separate article: C# AI Interview Questions and Answers
- What is an LLM?
Short answer
An LLM (Large Language Model) is an AI model trained on massive amounts of text data. It learns patterns in language and uses them to generate text responses.
- What is the difference between traditional ML, LLMs, and generative AI, and where does each fit in a typical .NET product?
Short answer
Traditional ML predicts or classifies from structured signals: churn risk, fraud score, recommendation ranking, anomaly detection. In a .NET product, this often lives behind a service, a background job, or an ML.NET or Azure ML endpoint that returns a number, label, or decision-support signal.
- What are tokens and context windows, and how do they constrain cost, latency, and prompt design in production?
Short answer
LLMs do not read text as full words or sentences. They process tokens.
- How do temperature and top-p interact, and why is true determinism still hard even at temperature 0?
Short answer
LLMs generate text by predicting the probability of the next token.
- What are hallucination and grounding, and how are they actually different concepts?
Short answer
Hallucination is when the model generates something confidently wrong. It is not lying.
- What are reasoning models and SLMs, and when does each make sense over a general chat model?
Short answer
There are three model types you need to know. General chat models, reasoning models, and small language models (SLMs).
- What should and should not appear in a system prompt, and how do system, developer, and user instructions interact in modern chat APIs?
Short answer
A system or developer prompt should contain stable behavior: product role, tone, safety boundaries, output format, tool-use rules, refusal rules, and what to do when information is missing. Keep it short enough that engineers can review it like code.
- Where should prompts live and how do you version them: code, configuration, database, or a dedicated prompt store?
Short answer
This is an architectural decision most teams get wrong by not thinking about it early enough. Where your prompts live determines how fast you iterate, how safely you deploy, and how well you debug production issues.
- What is Microsoft.Extensions.AI, what is IChatClient, and how do they enable provider-agnostic code?
Short answer
Microsoft.Extensions.AI is a set of .NET abstractions and helpers for common AI building blocks: chat, embeddings, images, tools, caching, telemetry, and middleware-style client pipelines. It does not replace every vendor SDK; it gives your app a common surface over them.
- How do you configure IChatClient in ASP.NET Core DI, and how do you add middleware for retry, caching, and telemetry?
Short answer
Register provider clients in DI at the edge of the application, then expose them as IChatClient services to the rest of the app.
- How do you stream model responses through SSE or SignalR, and how do you handle CancellationToken correctly?
Short answer
IChatClient.GetStreamingResponseAsync returns IAsyncEnumerable<ChatResponseUpdate>. In an HTTP endpoint, enumerate it with the request CancellationToken, write each update as an SSE event, flush after each chunk, and stop as soon as the client disconnects.
- How do you count tokens client-side in .NET for cost estimation and context-window budgeting?
Short answer
Token counting means estimating how many tokens your request will send to the model before you call the API.
- How do you manage conversation history at scale: full replay, sliding window, summary buffer, or vector recall, and what are the trade-offs?
Short answer
Full replay sends the entire history (most faithful but quickly exceeds the context window and cost), a sliding window keeps only the most recent turns (cheap but forgets older context), a summary buffer compresses older turns into a running summary (balances memory and cost with some fidelity loss), and vector recall retrieves only the semantically relevant past messages from a store. Production systems usually combine a sliding window with summarization and vector recall.
- When would you choose Semantic Kernel, Microsoft Agent Framework, Microsoft.Extensions.AI directly, or a vendor SDK, and on what criteria?
Short answer
Use Microsoft.Extensions.AI for a thin, provider-agnostic abstraction over chat and embeddings; Semantic Kernel when you want orchestration, plugins, memory, and planning; and Microsoft Agent Framework for multi-agent collaboration and workflows. Reach for a vendor SDK when you need provider-specific features early, weighing portability against access to the latest capabilities.
- What is Microsoft Agent Framework, and what is the difference between agents and workflows in its model?
Short answer
Microsoft Agent Framework is the multi-agent layer of the Microsoft AI stack. It grew out of the AutoGen research project and provides primitives for building systems in which multiple AI agents collaborate to complete work that a single model call cannot reliably accomplish.
- When are multi-agent patterns useful in a .NET enterprise app, and when are they over-engineering?
Short answer
Multi-agent systems add real value in one specific situation: the task is too complex, too long, or too risky to hand to a single model call. Outside that situation, they add cost and complexity for no gain.
- How do you persist agent state, implement human-in-the-loop approval, bind an agent's tool surface, and stop unsafe actions?
Short answer
Persist state outside the model: conversation, plan, tool calls, approvals, documents used, and final outcome. Use your normal durable store, queue, or workflow state, depending on the run's length and criticality.
- How do you test and evaluate agent behavior given that runs are non-deterministic?
Short answer
Because outputs vary, you evaluate with datasets and scoring (LLM-as-judge, assertions on tool calls, and rubric-based metrics) rather than exact-match assertions, running many samples to measure pass rates. Pin temperature and seeds where possible, mock tools for deterministic unit tests, and track quality with offline eval suites plus production tracing.
- What is the Model Context Protocol? What problem does it solve?
Short answer
Model Context Protocol is an open protocol for connecting AI apps to tools, resources, prompts, and external context. It solves the repeated integration problem where every IDE, agent, and data source used to need custom glue.
- What are the MCP primitives?
Short answer
Every MCP server exposes its capabilities through five primitives.
- How do you build an MCP server in C# using the official SDK?
Short answer
Three steps: install the SDK, define your primitives, pick a transport. Done.
- What are the known MCP security risks, and how do you mitigate them?
Short answer
MCP servers talk to AI models with elevated trust. That trust is the attack surface.
- How would you design an AI-powered feature inside ASP.NET Core?
Short answer
.NET Aspire helps you orchestrate distributed applications locally and in production. For AI systems, this is especially useful because modern AI apps rarely consist of a single component.
- How do you add retry, timeout, and circuit breaker policies to AI provider calls, and what does graceful degradation look like?
Short answer
AI provider APIs fail. They rate-limit, timeout, and go down.
- How do you architect AI features for multi-tenant SaaS so prompts, data, and vector indices are isolated per tenant?
Short answer
Tenant isolation in AI systems has three layers: prompt isolation, data isolation, and vector index isolation. Miss any one of them, and tenants bleed into each other.
- How do you design an input/output guardrails layer (PII redaction, jailbreak detection, output validation), and where does it sit in the request pipeline?
Short answer
Guardrails are checks that run before the model sees user input and after the model produces output. They stop bad things from going in and bad things from coming out.
- What are the main techniques for reducing AI latency and cost, and how do you version prompts and models safely in production?
Short answer
Cut latency and cost by choosing right-sized models, caching (including prompt caching), streaming responses, trimming context, and batching where possible. Version prompts and models like code — stored in source control or a prompt store, rolled out behind flags with A/B evaluation and the ability to roll back — so model or prompt changes are measured before full release.
- What are the main security risks in LLM applications, and what is the difference between direct and indirect prompt injection?
Short answer
The OWASP Top 10 for LLM applications covers the main risks. Four of them come up in almost every enterprise AI audit.
- How do you prevent data exfiltration through an AI assistant, including the "render this image" and "follow this link" patterns?
Short answer
Prevent exfiltration by controlling what the assistant can read and where it can send data. Do not let a model freely fetch URLs, render remote images, call webhooks, send email, or pass secrets into tools.
- How do you detect and redact PII before sending content to a model, and how do you handle PII in logs, telemetry, and tool results?
Short answer
Detect PII with a mix of deterministic rules, classifiers, and domain-specific validators. Redact or tokenize data before sending it to a model unless the use case truly requires the raw value.
- How do you secure AI-generated SQL, code, or shell commands so they never execute unchecked?
Short answer
Treat generated SQL, code, and shell commands as untrusted text. They can be shown to a user, linted, explained, or proposed as a patch, but they should not run directly in production.
- What is red-teaming for AI features, and how do you handle user consent, data retention, and deletion (including embeddings derived from deleted source data)?
Short answer
AI red-teaming is structured adversarial testing against prompts, retrieval, tools, policies, and data boundaries. It tries to make the system leak data, ignore instructions, call unsafe tools, or produce harmful output.
- Why is testing AI features fundamentally different from testing deterministic code? What do you mock, what uses real model calls, and how do you keep CI cost bounded?
Short answer
AI tests are different because output can vary even when the code is unchanged. You still unit-test your C# deterministically, but model behavior requires evals that accept valid variation.
- How do you build a golden dataset and run eval regression tests, and how do you avoid over-trusting LLM-as-judge?
Short answer
A golden dataset contains real questions, expected source documents, acceptable answer criteria, and examples of bad answers. It should include normal, edge, and adversarial cases, as well as recent production failures.
- What do Azure AI Foundry Evaluations and PromptFlow add to a .NET CI pipeline, and how do you compare two models or prompt versions before migration (offline eval, shadow traffic, A/B)?
Short answer
Azure AI Foundry Evaluations and PromptFlow help define, run, and track evaluations for prompts, RAG flows, and model variants. In a .NET pipeline, they add repeatable quality gates around behavior that normal unit tests cannot cover.
- How do you trace an AI request end-to-end with OpenTelemetry, and what metrics matter most in production?
Short answer
Use one trace from the incoming ASP.NET Core request through retrieval, model calls, tool calls, database calls, and background jobs. Add correlation IDs, tenant IDs where safe, prompt version, model deployment, and tool names.
- How do you detect cost spikes, runaway agent loops, and context-window blowups in production, and how do you audit tool calls and agent decisions for compliance?
Short answer
Set budgets and limits at every level: tokens per request, maximum context size, maximum tool calls, maximum agent turns, maximum retries, and maximum spend per tenant. Alert on spikes before the monthly bill tells you.
- How do you decide between better prompts, RAG, and fine-tuning, and why is fine-tuning rarely the first answer for enterprise knowledge Q&A?
Short answer
Use better prompts when the model already has the needed information but needs clearer instructions. Use RAG when the answer depends on private, current, or source-backed knowledge.
- What is the practical difference between supervised fine-tuning, RLHF, DPO, and instruction tuning, and what is model distillation?
Short answer
Supervised fine-tuning trains on input and ideal output examples. Instruction tuning is a form of supervised training that teaches a model to follow instructions across tasks.
- What is quantization, and how does it affect quality, size, and latency?
Short answer
Quantization reduces the numerical precision of a model's weights. A full-precision model stores each weight as a 32-bit float.
- When would you run a local LLM (Ollama, llama.cpp, ONNX Runtime GenAI) instead of a hosted API, and how does that integrate through Microsoft.Extensions.AI?
Short answer
Run locally when: Data cannot leave your network. Healthcare, legal, and financial data often fall under GDPR, HIPAA, or internal data residency policies that prohibit sending it to a third-party API.
- What is the difference between autocomplete, chat, edit (multi-file), and agent modes in these tools, and when does each actually save time versus create rework?
Short answer
Autocomplete finishes the code you are already writing. Chat explains, searches, or proposes changes.
- How do you structure a .NET repository so an AI coding agent works well in it, folder layout, naming conventions, README discoverability, and what to put at the solution root?
Short answer
A coding agent works better in a boring, discoverable repo. Put the solution file, README, build and test commands, architecture notes, docs, and scripts at predictable locations.
- What is CLAUDE.md (or .cursorrules / copilot-instructions.md), what should a .NET project put in it, and what should it avoid?
Short answer
CLAUDE.md, .cursorrules, and copilot-instructions.md serve the same purpose: they give the AI agent persistent context about your project. Without them, the agent guesses your conventions from file contents alone.
- What are Claude Code Skills and Cursor Rules, how do they differ from CLAUDE.md, and when should you create a project-specific skill?
Short answer
CLAUDE.md and similar files give general project context. Skills and rules are more reusable, scoped instructions for workflows or conventions, such as EF Core migrations, MediatR handler patterns, API tests, or release notes.
- How do you prevent an AI coding agent from reading or committing secrets, config files, and customer data?
Short answer
First, do normal secret hygiene: keep secrets out of git, use user-secrets or a vault, and scan commits. Then configure the AI tool so sensitive files are denied or ignored, especially .env, certificates, dumps, logs, and production appsettings.
- How do you review AI-generated pull requests differently from human PRs, and what specific failure modes do you look for (subtle logic errors, fabricated APIs, security regressions, license issues)?
Short answer
Review AI-generated PRs with extra suspicion around correctness, not style. They often look polished while hiding wrong assumptions, missing edge cases, fabricated APIs, weak tests, or broad unrelated edits.
- What are the IP, licensing, and compliance considerations for AI coding tools, and how do you compare Copilot, Cursor, and Claude Code on those grounds?
Short answer
For proprietary code, check whether prompts and code are used for training, what retention applies, where data is processed, whether enterprise policy controls exist, and what indemnity or contractual protections the vendor offers. Also, check how customer data can be entered into prompts, logs, and support channels.
Agile & Scrum

The detailed answers with diagrams and explanations of what Junior/Middle/Senior should know for the questions below, can be found in our separate article: Agile & Scrum Interview Questions and Answers
- What is Agile, and how is it different from traditional Waterfall delivery?
Short answer
Agile is an iterative approach to software delivery that emphasizes flexibility, collaboration, and frequent feedback. Work is broken into short cycles (sprints or iterations), delivering working software incrementally.
- What are the core values and principles of the Agile Manifesto?
Short answer
The four values: Individuals and interactions over processes and tools. Working software over comprehensive documentation.
- What is the difference between Agile, Scrum, Kanban, and Lean?
Short answer
Agile is a mindset and set of values for adaptive delivery. Scrum is a sprint-based Agile framework, Kanban is a flow-based method, and Lean focuses on reducing waste and optimizing value flow.
- What problems does Agile try to solve in software delivery?
Short answer
Late delivery of value, building the wrong thing, inability to respond to change, poor visibility into progress, lack of customer involvement, and the high cost of fixing defects discovered late. Agile addresses these by shortening feedback loops, involving stakeholders continuously, and delivering working software frequently.
- What are the most common misconceptions about Agile?
Short answer
Agile means no planning or documentation. Agile means no deadlines.
- What is iterative development, and why does Agile prefer short delivery cycles?
Short answer
Iterative development means repeatedly refining and improving the product in cycles. Short cycles (1–4 weeks) reduce risk by making feedback frequent, catching wrong assumptions early, and reducing the cost of change.
- What is incremental delivery, and how is it different from iterative delivery?
Short answer
Incremental delivery adds new pieces of functionality to a working product over time. Iterative delivery revisits and refines existing functionality.
- What does "customer collaboration" mean in real Agile teams?
Short answer
It means the customer or business representative (Product Owner) is actively involved throughout delivery — attending reviews, refining backlog, providing feedback on working software — not just signing off on requirements at the start and testing at the end. Real collaboration means shared ownership of the outcome.
- What is the difference between output and outcome in Agile delivery?
Short answer
Output is what you deliver — features, code, releases. Outcome is the result that matters — user behavior change, business value, revenue impact.
- Why do some companies fail when adopting Agile?
Short answer
Common causes: Agile theater — following ceremonies without the mindset. Management retaining command-and-control over teams.
- What is a burndown chart?
Short answer
A burndown chart shows how much work remains in a sprint or release over time. The Y-axis is remaining work (story points or tasks), the X-axis is time.
- What is a burnup chart?
Short answer
A burnup chart shows completed work over time and the total scope of work. Unlike burndown, it makes scope changes visible — if the total line rises, scope was added.
- What is a cumulative flow diagram (CFD)?
Short answer
A CFD shows how many items are in each workflow stage over time (e.g., To Do, In Progress, Done). Wide bands in "In Progress" indicate accumulation of WIP or bottlenecks.
- How do Agile metrics become toxic?
Short answer
When they're used to evaluate individuals or compare teams, people optimize for the metric instead of the outcome. A team that hits 50 points/sprint but ships bugs constantly is worse than one hitting 30 points with stable production.
- What is DORA, and why does it matter?
Short answer
DORA (DevOps Research and Assessment) is a research program that identified four key metrics strongly correlated with software delivery performance and organizational outcomes. These metrics are empirically validated across thousands of teams and distinguish elite performers from low performers.
- What are the four DORA metrics?
Short answer
Deployment Frequency — how often you deploy to production. Lead Time for Changes — time from commit to production.
- How do you measure delivery predictability?
Short answer
Track cycle time distribution — if most tickets finish within a consistent range, delivery is predictable. Use percentiles (85th percentile cycle time) for forecasting.
- What is Scrum, and when does Scrum work well?
Short answer
Scrum is an Agile framework using fixed-length sprints (1–4 weeks), defined roles (Product Owner, Scrum Master, Developers), and ceremonies (Planning, Daily Scrum, Review, Retrospective). Works well when requirements are evolving, the team is stable and co-located, and the business can provide an engaged Product Owner.
- What are the Scrum roles and responsibilities?
Short answer
Product Owner: owns the backlog, prioritizes work, represents business/user needs. Scrum Master: coaches the team, removes impediments, facilitates ceremonies, protects the team.
- What is the difference between Product Owner, Project Manager, and Scrum Master?
Short answer
A Product Owner owns product value, backlog ordering, and what should be built. A Scrum Master improves the Scrum process and removes impediments, while a traditional Project Manager focuses on timelines, budget, coordination, and delivery governance.
- What makes a good Product Owner?
Short answer
Availability (engages daily, not quarterly). Clear vision with ability to say no.
- What makes a good Scrum Master?
Short answer
Serves the team, not manages them. Understands Agile deeply enough to coach, not just facilitate.
- What is a cross-functional team?
Short answer
A team that has all the skills needed to deliver working software without depending on external teams — typically including development, testing, UX, and sometimes ops/DevOps. Reduces handoffs, increases accountability, and enables end-to-end ownership of delivery.
- What is a self-organizing team?
Short answer
A team that decides how to accomplish its work without being told step-by-step. They pull tasks, decide on technical approach, identify impediments, and improve their own process.
- What is the purpose of a Sprint?
Short answer
To create a timebox within which a team delivers a potentially shippable product increment toward the Sprint Goal. The fixed duration creates rhythm, forces prioritization, and generates regular feedback opportunities.
- What is the recommended Scrum team size, and why?
Short answer
3–9 developers (excluding PO and SM). Too small: insufficient skills coverage.
- What is the Definition of Done (DoD)?
Short answer
A shared team agreement on what "done" means for any increment — typically: code reviewed, automated tests written and passing, deployed to staging, documentation updated, no known critical bugs. DoD prevents the "it's done but not tested" trap and ensures quality is built in, not bolted on.
- What is the Definition of Ready (DoR)?
Short answer
A checklist for when a backlog item is ready to be pulled into a sprint: story is written, acceptance criteria defined, dependencies identified, estimated, and small enough to complete in one sprint. DoR prevents teams from starting work they can't finish because of unclear requirements.
- What happens during Sprint Planning?
Short answer
The team selects items from the top of the backlog, agrees on a Sprint Goal, and breaks selected stories into tasks. The PO clarifies requirements; the team estimates and commits to what's achievable.
- What makes Sprint Planning ineffective?
Short answer
Items aren't ready (no acceptance criteria, unclear scope). PO is absent or can't make decisions.
- What is Daily Scrum, and what is its real purpose?
Short answer
A 15-minute daily synchronization for the development team to inspect progress toward the Sprint Goal and adapt the plan for the next 24 hours. Its purpose is not status reporting to management — it's team coordination.
- What is a Sprint Review, and who should attend?
Short answer
Sprint Review is a demonstration of working software to stakeholders at the end of a sprint to inspect the increment and gather feedback. Stakeholders (users, business owners, leadership) should attend, not just the team.
- What is a Sprint Retrospective, and why is it important?
Short answer
A ceremony where the team reflects on how they worked together — what went well, what didn't, and what to improve. It's the team's primary mechanism for continuous improvement.
- How do you run effective retrospectives?
Short answer
Rotate formats to avoid staleness (Start/Stop/Continue, 4Ls, Mad/Sad/Glad, sailboat). Ensure psychological safety — no blame, focus on systems not people.
- What anti-patterns appear in Scrum ceremonies?
Short answer
Sprint Planning without a Goal. Daily Scrum as a status report to managers.
- What are Story Points, and why do Agile teams use them?
Short answer
Story points are a relative unit of estimation representing complexity, effort, and uncertainty — not hours. Teams use them because humans are better at comparing complexity (this is twice as hard as that) than predicting absolute duration.
- What is velocity, and why is it often misused?
Short answer
Velocity is the average story points completed per sprint over recent sprints. It's useful for a team's own capacity planning.
- What is sprint capacity planning?
Short answer
Calculating how much work a team can realistically take on in a sprint, accounting for team member availability (holidays, meetings, PTO), typical overhead, and historical velocity. Capacity planning prevents overcommitment and is separate from estimation — it's about availability, not complexity.
- What is the difference between estimation and commitment?
Short answer
An estimate is a probabilistic forecast of effort — it comes with uncertainty. A commitment is a promise to deliver.
- What estimation techniques exist in Agile teams?
Short answer
Planning Poker (consensus-based story point estimation). T-shirt sizing (S/M/L/XL for rough ordering).
- Why do estimates often fail in software projects?
Short answer
Estimates assume perfect understanding of a problem that isn't yet solved. Unknown dependencies, changing requirements, technical debt surprises, optimism bias, and pressure to give low numbers.
- What is technical debt, and how should Agile teams manage it?
Short answer
Technical debt is the accumulated cost of shortcuts, poor design decisions, and deferred refactoring that slows future development.
- How do Agile teams balance feature work and refactoring?
Short answer
Common approaches: allocate a fixed percentage of sprint capacity to tech debt (10–20%). Use the Boy Scout Rule — leave code better than you found it.
- What is a Product Backlog?
Short answer
An ordered list of everything that might be done by the team — features, bug fixes, technical work, experiments. It's owned by the Product Owner, continuously refined, and ordered by value.
- What makes a good backlog item?
Short answer
Clear: the team understands what it is. Valuable: it delivers benefit to user or business.
- What is backlog refinement?
Short answer
An ongoing activity (not a fixed ceremony in Scrum, though often scheduled) where the team and PO review upcoming backlog items — clarifying requirements, splitting large stories, estimating, and ordering. Goal: ensure the top of the backlog is always sprint-ready.
- What is a user story?
Short answer
A short description of a feature from the user's perspective: "As a [type of user], I want [action] so that [benefit]." It's a placeholder for a conversation, not a complete specification. The story captures who needs something and why — the how is discovered in conversation with the team.
- What is the difference between epic, feature, story, and task?
Short answer
An epic is a large body of work, a feature is a meaningful product capability, and a story is a user-centered slice of value that can fit in an iteration. A task is implementation work needed to complete a story but is not usually valuable by itself.
- What is INVEST in Agile?
Short answer
A checklist for quality user stories: Independent (can be developed in any order), Negotiable (details can change through conversation), Valuable (delivers benefit), Estimable (team can size it), Small (fits in a sprint), Testable (acceptance criteria exist). Violating INVEST usually signals a story needs splitting or more refinement.
- What makes a good user story?
Short answer
It follows INVEST (Independent, Negotiable, Valuable, Estimable, Small, Testable). Has clear acceptance criteria.
- What are acceptance criteria?
Short answer
Specific conditions that must be met for a story to be accepted as done. Written by the PO, often with dev input.
- How do Agile teams handle changing requirements?
Short answer
By welcoming them — the Agile Manifesto explicitly values responding to change. In practice: new requirements go into the backlog and get prioritized.
- How do you prioritize backlog items?
Short answer
A good user story expresses user value clearly, is small enough to deliver, and has acceptance criteria that make completion testable. It should follow INVEST: Independent, Negotiable, Valuable, Estimable, Small, and Testable.
- Which prioritization techniques are you choosing for which situation?
Short answer
Use MoSCoW for stakeholder-facing scope agreement, WSJF (cost of delay over job size) for economic sequencing in scaled backlogs, and the Kano model when balancing must-have versus delighter features. Simple value-versus-effort or RICE scoring works well for quick, data-light backlog ordering.
- What is Kanban, and how does it differ from Scrum?
Short answer
Kanban is a flow-based method that visualizes work, limits work in progress, and optimizes cycle time without requiring fixed sprints. Scrum works in timeboxed sprints with defined roles, events, and sprint commitments.
- What is continuous delivery in Kanban?
Short answer
Items are delivered whenever they're done — there's no sprint boundary or release gate. Work flows from "To Do" to "Done" and can be deployed at any point.
- What are WIP limits, and why are they important?
Short answer
WIP (Work In Progress) limits cap the number of items allowed in each workflow stage simultaneously. They prevent multitasking, expose bottlenecks, and force teams to finish work before starting new work.
- What is cycle time?
Short answer
The time from when work starts (team picks it up) to when it's done. Cycle time measures team execution speed and is the primary metric for forecasting how long new work will take.
- What is lead time?
Short answer
The time from when work is requested (enters the backlog) to when it's delivered. Lead time includes queue time before work starts, plus cycle time.
- What is throughput in Kanban?
Short answer
The number of items completed per unit of time (e.g., 8 stories per week). Throughput is a flow metric useful for forecasting: if you consistently complete 8 items/week, you can estimate when a set of backlog items will be done.
- What is flow efficiency?
Short answer
The ratio of active work time to total lead time. If a ticket takes 10 days but is only being actively worked on for 2 days, flow efficiency is 20%.
- What are bottlenecks, and how do you identify them?
Short answer
A bottleneck is a stage where work accumulates faster than it's processed, slowing the entire system. Identify them via CFD (wide bands in one stage), by observing where tickets pile up, or by measuring queue sizes at each step.
- What metrics matter most in Kanban teams?
Short answer
Cycle time (how fast you execute), Lead time (how fast customers get value), Throughput (how much you deliver), WIP (are you overloaded?), and Flow Efficiency (how much is wait vs. work).
- What anti-patterns exist in Kanban adoption?
Short answer
Common Kanban anti-patterns include ignoring WIP limits, treating the board as a status display instead of a flow system, and letting everything sit in "in progress." Another warning sign is optimizing local stages while overall lead time keeps getting worse.
- What is risk management in software projects?
Short answer
The systematic process of identifying, assessing, and responding to potential threats to project success. It's proactive — identifying what could go wrong before it does.
- What is the difference between risk, issue, blocker, and dependency?
Short answer
Risk is a future uncertainty that may hurt delivery; an issue is a problem that has already happened. A blocker prevents current progress, while a dependency is work or a decision needed from another person, team, or system.
- What are the most common risks in software projects?
Short answer
Unclear or changing requirements. Underestimated technical complexity.
- What is risk probability vs impact?
Short answer
Probability: how likely is this risk to occur (low/medium/high or 1–5). Impact: how severe would the consequences be if it does occur.
- What is a risk matrix?
Short answer
A 2x2 or 5x5 grid plotting risks by probability (Y-axis) and impact (X-axis), creating a visual map of risk priority. High probability + high impact = must address immediately.
- What is risk mitigation?
Short answer
Actions taken to reduce the probability or impact of a risk before it occurs. Examples: writing automated tests mitigates deployment risk.
- What is risk acceptance?
Short answer
A conscious decision to acknowledge a risk and take no action — either because the cost of mitigation exceeds the potential impact, or the probability is acceptably low. Risk acceptance must be explicit and documented, not the result of ignoring the risk.
- What is contingency planning?
Short answer
Defining in advance what you'll do if a risk materializes into an issue. "If the third-party API goes down, we'll switch to cached responses for 24 hours." Contingency planning ensures you're not improvising under pressure.
- What is residual risk?
Short answer
The risk that remains after mitigation measures are applied. You rarely eliminate risk entirely — mitigation reduces it to an acceptable level.
- What is risk appetite in organizations?
Short answer
The level of risk an organization is willing to accept in pursuit of its goals. A startup may accept high technical risk to move fast.
- How do you identify architectural risks early?
Short answer
Architecture Decision Records document important design choices, alternatives considered, and consequences so risks are visible early. Combine ADRs with spikes, proof-of-concepts, threat modeling, and performance tests for decisions with high uncertainty.
- What delivery risks appear in Agile projects?
Short answer
Sprint scope creep. Incomplete Definition of Done leading to hidden work.
- What risks appear during cloud migration projects?
Short answer
Common cloud migration risks include underestimated data migration complexity, identity and networking gaps, cost overruns, and performance regressions from latency between systems. Reduce them with migration rehearsals, rollback plans, observability, and phased cutovers.
- What risks appear in microservices adoption?
Short answer
Distributed system complexity replacing simpler monolith problems. Service proliferation without governance.
- What risks appear in AI and LLM projects?
Short answer
Non-deterministic outputs making testing difficult. Hallucination in production systems.
- How do dependencies between teams create delivery risks?
Short answer
Shared APIs not ready on time. API contract changes breaking consumers.
- What risks appear from poor requirements quality?
Short answer
Teams build the wrong thing. Rework discovered late (expensive).
- What risks appear from weak observability and monitoring?
Short answer
Incidents go undetected until users report them. MTTR increases dramatically when you can't diagnose without access to logs.
- How do you reduce deployment risks in production systems?
Short answer
Feature flags for gradual rollout. Blue-green or canary deployments.
- What risks appear in remote or distributed teams?
Short answer
Communication delays slowing decisions. Timezone gaps creating async bottlenecks.
- What risks appear when scaling engineering teams?
Short answer
Coordination overhead grows super-linearly. Knowledge concentration in founding team members.
- How does poor communication create delivery risks?
Short answer
Poor communication lets requirements be misunderstood and blockers go unraised until they are expensive to fix, causing rework and missed expectations. It also erodes trust and shared understanding, so teams build the wrong thing or discover integration problems too late.
- What is bus factor risk?
Short answer
The number of team members who could leave (get "hit by a bus") before the team loses critical knowledge or capability. A bus factor of 1 means the entire system depends on one person — extremely high risk.
- What risks appear from key-person dependency?
Short answer
Single person owns critical system knowledge. Their absence (vacation, illness, attrition) causes delivery to stop.
- What risks appear from unrealistic deadlines?
Short answer
Quality shortcuts taken to meet dates. Technical debt accelerates.
- How do organizational politics affect project risks?
Short answer
Prioritization driven by stakeholder influence rather than value. Critical risks not raised because it's "career limiting" to deliver bad news.
- How do you communicate risks to leadership?
Short answer
Use business language: impact on timeline, cost, user experience, or compliance — not technical detail. Be specific: "This dependency on Team X puts our Q3 launch at risk unless we align by June 1." Offer options with trade-offs.
- What makes risk reporting ineffective?
Short answer
Risks listed as vague technical concerns leadership can't act on. Status always Green when reality is Yellow or Red.
- How do experienced architects think about risks differently from junior engineers?
Short answer
Juniors see technical risks in isolation. Architects see systemic risks — how one failure cascades, how org decisions create technical risk, and how today's shortcut creates tomorrow's incident.
- What challenges appear when scaling Agile across multiple teams?
Short answer
Dependency management between teams. Aligning sprint cadences.
- What is SAFe?
Short answer
SAFe (Scaled Agile Framework) is a framework for applying Agile and Lean practices across many teams in large organizations, coordinating them through constructs like Agile Release Trains and Program Increment planning. It adds portfolio, program, and team layers to align dozens of teams, at the cost of more process and roles than single-team Scrum.
- What is Scrum of Scrums?
Short answer
A coordination technique where representatives from multiple Scrum teams meet regularly (often daily or weekly) to synchronize, raise cross-team impediments, and manage dependencies. One member from each team participates.
- What coordination problems appear in large Agile organizations?
Short answer
Teams with misaligned priorities. Dependencies not surfaced until they become blockers.
- What is dependency management between Agile teams?
Short answer
The practice of identifying, tracking, and resolving work that one team needs from another. Tools: dependency boards, inter-team backlog items, shared planning sessions (PI Planning in SAFe).
- What is release train planning?
Short answer
A planning event (e.g., PI Planning in SAFe) where multiple teams align on goals, identify dependencies, and plan delivery for the next program increment (typically 8–12 weeks). Creates shared commitment across teams.
- Why do enterprise Agile transformations often fail?
Short answer
Agile imposed top-down without team input. Ceremonies adopted without mindset change.
- What is "Agile theater"?
Short answer
Performing the motions of Agile (standups, sprints, retrospectives) without the underlying values or benefits. Teams hold standups where nobody raises real blockers.
- How do you keep Agile lightweight in enterprise environments?
Short answer
Start with principles, not frameworks. Add process only when a problem requires it.
- What is the difference between being Agile and doing Agile?
Short answer
Doing Agile: following the ceremonies, roles, and artifacts. Being Agile: embodying the values — welcoming change, collaborating with customers, trusting teams, delivering continuously.
- Why are CI/CD practices critical for Agile delivery?
Short answer
Agile requires frequent delivery of working software. Without CI/CD, integration happens manually and rarely — creating large, risky releases.
- What is trunk-based development?
Short answer
A branching strategy where all developers commit to a single main branch (trunk) multiple times per day. Short-lived feature branches (less than a day) are acceptable, but long-lived branches are not.
- What is feature flagging?
Short answer
A technique to deploy code to production while keeping features disabled for users until ready. Flags can be toggled per user, percentage of traffic, or environment.
- Why do long-lived branches hurt Agile teams?
Short answer
They delay integration, hiding merge conflicts that compound over time. They prevent CI — code isn't actually integrated until the branch merges.
- What engineering anti-patterns slow Agile teams down?
Short answer
Long-lived feature branches, manual deployment steps, missing automated tests, and big-bang integrations all delay feedback and make change risky. These practices undermine continuous integration and turn small changes into slow, error-prone releases.
- How do architecture decisions affect Agile delivery speed?
Short answer
Good architecture enables independent deployment of components — teams can ship without coordinating with other teams. Poor architecture creates tight coupling — every change requires multi-team coordination and big-bang releases.