InterviewPitch
.NET Core interview questions

.NET Core Interview Questions with Answers

Most Asked .NET Core Interview Questions for Backend and Full‑Stack Developers

100+ QuestionsDetailed AnswersCode ExamplesUpdated for 2026

Introduction

.NET Core is a modern, cross‑platform framework for building web, cloud, and desktop applications. This page covers the most frequently asked .NET Core interview questions – from basics like data types and OOP to advanced topics like multithreading, algorithms, and design patterns – essential for any .NET developer.

Why .NET Core?

  • Cross‑platform – runs on Windows, Linux, and macOS
  • Open source with strong community support
  • High performance and scalability
  • Rich ecosystem with libraries and tools
  • Used in enterprise and cloud applications

Most Asked .NET Core Interview Questions

Beginner
1. What is .NET Core and what are its key features?

.NET Core is a cross-platform, open-source framework developed by Microsoft for building modern applications. It's the successor to .NET Framework.

  • Cross-Platform: Runs on Windows, Linux, and macOS
  • Open Source: Available on GitHub
  • High Performance: Optimized for speed
  • Modular: Use only what you need
  • Unified: Single framework for all app types
.NET Core Overview
// .NET Core is a cross-platform, open-source framework
// Key features:
// - Cross-platform (Windows, Linux, macOS)
// - Open source (GitHub)
// - High performance
// - Modular
// - Unified framework for all app types

Console.WriteLine("Hello .NET Core!");
Beginner
2. What are Data Types in .NET Core?

.NET Core provides a rich set of built-in data types including value types and reference types. All types inherit from the base System.Object type.

  • Value Types: int, double, bool, char, decimal, struct
  • Reference Types: string, object, class, interface, delegate, array
  • Nullable Types: int?, bool? for handling null values
  • Dynamic Type: dynamic for runtime type resolution
  • Type Inference: var for implicit typing
Data Types Example
// Value types
int age = 30;
double price = 19.99;
bool isActive = true;
char grade = 'A';
decimal salary = 55000.50m;

// Reference types
string name = "John";
object obj = new object();
int[] numbers = { 1, 2, 3 };

// Nullable types
int? nullableInt = null;
bool? nullableBool = true;

// Dynamic type
dynamic dynamicValue = "Hello";
dynamicValue = 42;
Beginner
3. What are Variables, Constants, and Readonly in .NET Core?

.NET Core uses const for compile-time constants, readonly for runtime constants, and var for type inference. Understanding these helps in writing efficient and maintainable code.

  • var — Type-inferred variable (compile-time)
  • const — Compile-time constant (must be assigned at declaration)
  • readonly — Runtime constant (can be assigned in constructor)
  • static readonly — Class-level runtime constant
  • dynamic — Runtime type resolution
Variables, Constants, Readonly
// var – compile-time type inference
var message = "Hello"; // string

// const – compile-time constant
const double Pi = 3.14159;

// readonly – runtime constant
public class Circle
{
    public readonly double Radius;
    public Circle(double radius) => Radius = radius;
}

// static readonly – class-level runtime constant
public static readonly string AppName = "MyApp";

// dynamic – runtime type resolution
dynamic value = 10;
value = "Now a string";
Beginner
4. How do Classes and Objects work in .NET Core?

A class in .NET Core encapsulates data and behavior. Objects are instances of classes created using the new keyword. Classes support properties, methods, constructors, and events.

  • class — Defines a class
  • new — Creates an instance
  • Properties: get and set accessors
  • Constructors: Initialize objects
  • Methods: Define behavior
Class and Object
public class Person
{
    // Properties
    public string Name { get; set; }
    public int Age { get; set; }

    // Constructor
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }

    // Method
    public void Introduce()
    {
        Console.WriteLine($"Hi, I'm {Name} and I'm {Age} years old.");
    }
}

// Creating an object
var person = new Person("Alice", 25);
person.Introduce();
Beginner
5. What are Constructors in .NET Core?

Constructors initialize class instances. .NET Core supports default, parameterized, copy, static, and private constructors for various initialization scenarios.

  • Default Constructor: No parameters
  • Parameterized Constructor: Accepts parameters
  • Copy Constructor: Creates from another instance
  • Static Constructor: Initializes static members
  • Private Constructor: Used in Singleton pattern
Constructors
public class Product
{
    // Default constructor
    public Product() { }

    // Parameterized constructor
    public Product(string name, decimal price)
    {
        Name = name;
        Price = price;
    }

    // Copy constructor
    public Product(Product other)
    {
        Name = other.Name;
        Price = other.Price;
    }

    // Static constructor (called once)
    static Product()
    {
        Category = "Electronics";
    }

    // Private constructor (for Singleton)
    private Product(string id) { }

    public string Name { get; set; }
    public decimal Price { get; set; }
    public static string Category { get; }
}
Beginner
6. How does Inheritance work in .NET Core?

Inheritance allows classes to reuse and extend behavior. .NET Core supports single inheritance with the : syntax, and interfaces for multiple contracts.

  • : BaseClass — Single inheritance
  • base — Access parent members
  • override — Override virtual methods
  • virtual — Allow overriding
  • sealed — Prevent inheritance
Inheritance
public class Animal
{
    public virtual void Speak() => Console.WriteLine("Animal speaks");
}

public class Dog : Animal
{
    public override void Speak() => Console.WriteLine("Woof!");
}

public class Cat : Animal
{
    public override void Speak() => Console.WriteLine("Meow!");
}

// Usage
Animal myDog = new Dog();
myDog.Speak(); // Woof!
Intermediate
7. What is Polymorphism and how do Abstract Classes work in .NET Core?

Polymorphism allows objects of different types to be treated uniformly. Abstract classes define contracts that derived classes must implement, enabling flexible and extensible code.

  • abstract class — Cannot be instantiated
  • abstract method — Must be implemented by derived classes
  • override — Implements abstract/virtual methods
  • Runtime Polymorphism: Dynamic method dispatch
  • Interface Segregation: Define clear contracts
Abstract Class
public abstract class Shape
{
    public abstract double Area();
    public virtual string Description() => "A shape";
}

public class Circle : Shape
{
    public double Radius { get; set; }
    public override double Area() => Math.PI * Radius * Radius;
    public override string Description() => $"Circle with radius {Radius}";
}

// Usage
Shape shape = new Circle { Radius = 5 };
Console.WriteLine($"Area: {shape.Area()}");
Intermediate
8. What is Operator Overloading in .NET Core?

Operator Overloading allows defining custom behavior for operators on user-defined types, making code more intuitive and readable.

  • operator + — Addition operator
  • operator - — Subtraction operator
  • operator * — Multiplication operator
  • operator == — Equality comparison
  • Equals() and GetHashCode() — Must be overridden with ==
Operator Overloading
public class Vector
{
    public double X { get; set; }
    public double Y { get; set; }

    public Vector(double x, double y) => (X, Y) = (x, y);

    // Operator overloading
    public static Vector operator +(Vector a, Vector b) =>
        new Vector(a.X + b.X, a.Y + b.Y);

    public static Vector operator -(Vector a, Vector b) =>
        new Vector(a.X - b.X, a.Y - b.Y);

    public static bool operator ==(Vector a, Vector b) =>
        a.X == b.X && a.Y == b.Y;

    public static bool operator !=(Vector a, Vector b) => !(a == b);

    public override bool Equals(object obj) => obj is Vector v && this == v;
    public override int GetHashCode() => (X, Y).GetHashCode();
}

// Usage
var v1 = new Vector(1, 2);
var v2 = new Vector(3, 4);
var sum = v1 + v2; // (4, 6)
Intermediate
9. How do Generics work in .NET Core?

Generics provide type safety and code reuse by parameterizing types. They enable writing flexible, reusable code while maintaining compile-time type checking.

  • class Stack<T> — Generic class
  • T — Type parameter
  • where T : new() — Type constraints
  • List<int> — Generic collection
  • Type Safety: Compile-time checking
Generics
public class Stack<T>
{
    private List<T> _items = new List<T>();

    public void Push(T item) => _items.Add(item);
    public T Pop()
    {
        if (_items.Count == 0) throw new InvalidOperationException();
        var item = _items[^1];
        _items.RemoveAt(_items.Count - 1);
        return item;
    }
    public T Peek() => _items[^1];
    public int Count => _items.Count;
}

// Usage with constraints
public class Repository<T> where T : new()
{
    public T Create() => new T();
}
Intermediate
10. What are Collections (Lists) in .NET Core?

Lists are ordered collections of elements. .NET Core provides extensive list operations including sorting, filtering, mapping, and functional transformations.

  • List<T> — Generic list
  • Add(), Insert() — Element operations
  • Where(), Select() — LINQ operations
  • Sort() — Sorting elements
  • Count, Capacity — List properties
Lists
using System.Collections.Generic;
using System.Linq;

var numbers = new List<int> { 5, 2, 8, 1, 9 };

// Basic operations
numbers.Add(3);
numbers.Insert(0, 0);
numbers.Remove(2);
numbers.Sort();

// LINQ
var evens = numbers.Where(n => n % 2 == 0).ToList();
var doubled = numbers.Select(n => n * 2).ToList();
var sum = numbers.Sum();
var firstEven = numbers.FirstOrDefault(n => n % 2 == 0);

Console.WriteLine($"Sum: {sum}");
Intermediate
11. How do Dictionary and HashSet collections work in .NET Core?

Dictionary is a key-value pair collection providing O(1) lookups. HashSet stores unique elements with O(1) add, remove, and lookup operations.

  • Dictionary<K,V> — Key-value dictionary
  • HashSet<T> — Unique elements
  • ContainsKey() — Key existence
  • Add(), Remove() — Operations
  • SortedDictionary — Sorted key-value pairs
Dictionary & HashSet
using System.Collections.Generic;

// Dictionary
var dict = new Dictionary<string, int>
{
    { "Apple", 5 },
    { "Banana", 3 },
    { "Orange", 7 }
};
dict["Apple"] = 10;
dict.Remove("Banana");
if (dict.ContainsKey("Orange")) Console.WriteLine(dict["Orange"]);

// HashSet
var set = new HashSet<int> { 1, 2, 3, 4, 4 };
set.Add(5);
set.Remove(2);
Console.WriteLine($"Set contains 3: {set.Contains(3)}");
Intermediate
12. What are Stack, Queue, and PriorityQueue in .NET Core?

Stack (LIFO), Queue (FIFO), and PriorityQueue are specialized collections for specific use cases with different ordering semantics.

  • Stack: LIFO with Push() and Pop()
  • Queue: FIFO with Enqueue() and Dequeue()
  • PriorityQueue: Ordered by priority (.NET 6+)
  • Peek() — View without removing
  • Count — Number of elements
Stack, Queue, PriorityQueue
using System.Collections.Generic;

// Stack (LIFO)
var stack = new Stack<string>();
stack.Push("first");
stack.Push("second");
var top = stack.Pop(); // "second"
var peek = stack.Peek(); // "first"

// Queue (FIFO)
var queue = new Queue<string>();
queue.Enqueue("first");
queue.Enqueue("second");
var first = queue.Dequeue(); // "first"

// PriorityQueue (requires .NET 6+)
var pq = new PriorityQueue<string, int>();
pq.Enqueue("low", 5);
pq.Enqueue("high", 1);
var high = pq.Dequeue(); // "high"
Intermediate
13. How does Exception Handling work in .NET Core?

Exception Handling provides robust error management with try-catch-finally blocks and custom exception types for specific error scenarios.

  • try-catch — Exception handling
  • throw — Raise exceptions
  • finally — Cleanup code
  • catch with filters — Specific exception handling
  • Custom Exceptions: Extend Exception class
Exception Handling
try
{
    int result = Divide(10, 0);
}
catch (DivideByZeroException ex)
{
    Console.WriteLine($"Divide by zero: {ex.Message}");
}
catch (Exception ex)
{
    Console.WriteLine($"General error: {ex.Message}");
}
finally
{
    Console.WriteLine("Cleanup code runs always");
}

// Custom exception
public class InsufficientFundsException : Exception
{
    public InsufficientFundsException(string message) : base(message) { }
}

int Divide(int a, int b) => a / b;
Intermediate
14. How does IDisposable and Resource Management work in .NET Core?

IDisposable ensures proper cleanup of resources like file handles, database connections, and network sockets using the dispose pattern.

  • IDisposable — Interface for resource cleanup
  • using statement — Automatic disposal
  • Dispose() — Release unmanaged resources
  • Dispose Pattern: Dispose(bool disposing)
  • GC.SuppressFinalize() — Optimize GC
IDisposable
public class Resource : IDisposable
{
    private bool _disposed;

    public void Use() => Console.WriteLine("Using resource");

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                // Release managed resources
            }
            // Release unmanaged resources
            _disposed = true;
        }
    }

    ~Resource() => Dispose(false);
}

// Using statement ensures disposal
using (var res = new Resource())
{
    res.Use();
}
Intermediate
15. What are Lambdas and Functional Programming in .NET Core?

Lambdas and Functional Programming enable concise, declarative code with functions as first-class citizens and LINQ query capabilities.

  • () => — Lambda expression syntax
  • Higher-order Functions: Functions that take functions
  • Closures: Functions with captured variables
  • Func<T, TResult> — Delegate types
  • Action<T> — Void delegate
Lambdas
// Lambda expressions
Func<int, int> square = x => x * x;
Console.WriteLine(square(5)); // 25

// Higher-order functions
Func<int, int, int> add = (a, b) => a + b;
Func<int, int> apply = (x) => x + 10;

// Closure
int multiplier = 3;
Func<int, int> multiply = x => x * multiplier;
Console.WriteLine(multiply(5)); // 15

// Built-in delegates
Action<string> log = msg => Console.WriteLine(msg);
log("Hello");

Func<int, bool> isEven = n => n % 2 == 0;
Intermediate
16. How do Async/Await and Tasks work in .NET Core?

Async/Await and Tasks provide asynchronous programming capabilities for non-blocking operations, improving application responsiveness and scalability.

  • Task<T> — Asynchronous result
  • async — Asynchronous function
  • await — Wait for Task
  • Task.WhenAll() — Parallel operations
  • Error Handling: Try-catch with async
Async/Await
using System.Threading.Tasks;

public async Task<int> FetchDataAsync()
{
    // Simulate async I/O
    await Task.Delay(1000);
    return 42;
}

public async Task ProcessAsync()
{
    try
    {
        int result = await FetchDataAsync();
        Console.WriteLine(result);

        // Parallel operations
        var tasks = new[] { FetchDataAsync(), FetchDataAsync() };
        int[] results = await Task.WhenAll(tasks);
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error: {ex.Message}");
    }
}
Intermediate
17. How does File I/O work in .NET Core?

File I/O operations enable reading from and writing to files, directories, and streams in .NET Core applications using System.IO namespace.

  • File — Static file operations
  • FileInfo — Instance file operations
  • ReadAllText() — Reading files
  • WriteAllText() — Writing files
  • Directory — Directory operations
File I/O
using System.IO;

// Writing to a file
File.WriteAllText("example.txt", "Hello, World!");

// Reading from a file
string content = File.ReadAllText("example.txt");
Console.WriteLine(content);

// Working with file info
var fileInfo = new FileInfo("example.txt");
Console.WriteLine($"Size: {fileInfo.Length} bytes");
Console.WriteLine($"Last modified: {fileInfo.LastWriteTime}");

// Directory operations
Directory.CreateDirectory("MyFolder");
var files = Directory.GetFiles(".");
Intermediate
18. What are LINQ and Functional Programming operations in .NET Core?

LINQ (Language Integrated Query) provides query operations for data transformation and aggregation with SQL-like syntax and functional methods.

  • Select() — Transform elements
  • Where() — Filter elements
  • Aggregate() — Aggregate values
  • GroupBy() — Group elements
  • OrderBy() — Sort elements
LINQ
using System.Linq;

var numbers = new[] { 1, 2, 3, 4, 5, 6 };

// Filtering
var evens = numbers.Where(n => n % 2 == 0);

// Projection
var squares = numbers.Select(n => n * n);

// Aggregation
var sum = numbers.Aggregate((acc, n) => acc + n);

// Grouping
var groups = numbers.GroupBy(n => n % 2 == 0 ? "Even" : "Odd");

// Ordering
var sorted = numbers.OrderByDescending(n => n);

// Complex query
var result = numbers
    .Where(n => n > 2)
    .Select(n => n * 2)
    .OrderBy(n => n)
    .ToList();
Intermediate
19. How do you implement a LinkedList in .NET Core?

LinkedList is a fundamental data structure for dynamic data storage with efficient insertion and deletion operations at both ends.

  • Doubly-linked: Forward and backward traversal
  • AddFirst() — Insert at beginning
  • AddLast() — Insert at end
  • RemoveFirst() — Remove from beginning
  • RemoveLast() — Remove from end
LinkedList
public class Node<T>
{
    public T Value { get; set; }
    public Node<T> Next { get; set; }
    public Node<T> Prev { get; set; }

    public Node(T value) => Value = value;
}

public class LinkedList<T>
{
    private Node<T> _head;
    private Node<T> _tail;

    public void AddFirst(T value)
    {
        var node = new Node<T>(value);
        if (_head == null) _head = _tail = node;
        else { node.Next = _head; _head.Prev = node; _head = node; }
    }

    public void AddLast(T value)
    {
        var node = new Node<T>(value);
        if (_tail == null) _head = _tail = node;
        else { _tail.Next = node; node.Prev = _tail; _tail = node; }
    }

    public T RemoveFirst()
    {
        if (_head == null) throw new InvalidOperationException();
        var value = _head.Value;
        _head = _head.Next;
        if (_head != null) _head.Prev = null;
        else _tail = null;
        return value;
    }
}
Intermediate
20. How do Binary Search and Sorting work in .NET Core?

Binary Search efficiently finds elements in sorted arrays. Sorting arranges elements in a specific order using built-in or custom algorithms.

  • Binary Search: O(log n) search
  • Sort() — Built-in sorting (QuickSort/IntroSort)
  • BinarySearch() — Built-in binary search
  • Find(), FindAll() — Search methods
  • Custom Comparers: IComparer<T>
Binary Search & Sorting
var arr = new int[] { 1, 3, 5, 7, 9, 11 };

// Binary search (returns index or negative if not found)
int index = Array.BinarySearch(arr, 7); // 3
Console.WriteLine(index);

// Sorting
Array.Sort(arr); // now sorted

// Find
int found = Array.Find(arr, n => n > 5); // 7
int[] foundAll = Array.FindAll(arr, n => n % 2 == 0);

// Custom binary search with IComparer
class MyComparer : IComparer<int> { ... }
Intermediate
21. What is Recursion in .NET Core?

Recursion is a technique where a function calls itself to solve smaller instances of the same problem, useful for tree traversal and divide-and-conquer algorithms.

  • Base Case: Stopping condition
  • Recursive Case: Self-call with smaller input
  • Stack Overflow: Risk of deep recursion
  • Tail Recursion: Optimization technique
  • Recursive Algorithms: Factorial, Fibonacci, Hanoi
Recursion
// Factorial using recursion
public static int Factorial(int n)
{
    // Base case
    if (n <= 1) return 1;
    // Recursive case
    return n * Factorial(n - 1);
}

// Fibonacci
public static int Fib(int n)
{
    if (n <= 1) return n;
    return Fib(n - 1) + Fib(n - 2);
}

// Tree traversal (DFS)
void Traverse(TreeNode node)
{
    if (node == null) return;
    Console.WriteLine(node.Value);
    Traverse(node.Left);
    Traverse(node.Right);
}
Intermediate
22. What are Sorting Algorithms in .NET Core?

Sorting Algorithms like Bubble Sort, Merge Sort, and built-in sort provide different performance characteristics for various use cases.

  • Bubble Sort: O(n²), simple but slow
  • Merge Sort: O(n log n), stable and efficient
  • Built-in Sort: Optimized IntroSort implementation
  • Custom Comparators: Flexible sorting
  • Descending Order: Sort((a,b) => b.CompareTo(a))
Sorting Algorithms
// Built-in sort uses IntroSort (QuickSort + HeapSort)
var nums = new int[] { 5, 2, 8, 1, 3 };
Array.Sort(nums); // ascending

// Descending
Array.Sort(nums, (a, b) => b.CompareTo(a));

// Bubble Sort (O(n²))
void BubbleSort(int[] arr)
{
    for (int i = 0; i < arr.Length - 1; i++)
        for (int j = 0; j < arr.Length - i - 1; j++)
            if (arr[j] > arr[j + 1])
                (arr[j], arr[j + 1]) = (arr[j + 1], arr[j]);
}

// Merge Sort (O(n log n))
void MergeSort(int[] arr) { ... }
Intermediate
23. How does Dynamic Memory and Garbage Collection work in .NET Core?

Dynamic Memory and Garbage Collection manage memory allocation and deallocation automatically, with generational GC for optimal performance.

  • Heap Memory: Dynamically allocated objects
  • Garbage Collector: Automatic memory reclamation
  • Generations: 0, 1, 2 for performance
  • GC Modes: Workstation, Server
  • Memory Leaks: Prevention and detection
Garbage Collection
// Garbage Collection
// GC works in generations (0, 1, 2)
// Short-lived objects are collected in Gen0
// Large Object Heap (>85KB) is separate

// Forcing a collection (not recommended)
GC.Collect();

// Getting memory info
Console.WriteLine($"Total memory: {GC.GetTotalMemory(false)}");
Console.WriteLine($"Gen0 collections: {GC.CollectionCount(0)}");

// Dispose pattern helps with unmanaged resources
public class ResourceHolder : IDisposable { ... }

// WeakReference allows object to be collected
var weak = new WeakReference(new MyClass());
if (weak.IsAlive) ((MyClass)weak.Target).Use();
Intermediate
24. What are String Operations in .NET Core?

String Operations provide comprehensive text manipulation including concatenation, interpolation, and transformation in .NET Core.

  • Concatenation: + operator or StringBuilder
  • Interpolation: $"Hello {name}"
  • Case Conversion: ToLower(), ToUpper()
  • Split/Join: Split(), Join()
  • StringBuilder: Mutable string for performance
String Operations
string name = "John";
int age = 30;

// Concatenation
string message = "Hello, " + name + "!";

// Interpolation
string greeting = $"Hello, {name}! You are {age} years old.";

// StringBuilder (for performance)
var sb = new System.Text.StringBuilder();
sb.Append("Hello");
sb.Append(", ");
sb.Append(name);
string result = sb.ToString();

// Splitting
string csv = "apple,banana,orange";
string[] fruits = csv.Split(',');

// Joining
string joined = string.Join(", ", fruits);

// Case conversion
string upper = name.ToUpper();
string lower = name.ToLower();

// Substring
string sub = name.Substring(1, 2); // "oh"
Intermediate
25. What are Interfaces in .NET Core?

Interfaces define contracts for classes to implement, enabling polymorphism and code organization with multiple inheritance of behavior.

  • interface — Defines a contract
  • implements — Implement multiple interfaces
  • Interface Segregation: Focused interfaces
  • Default Implementation: Default interface methods (C# 8+)
  • Dependency Injection: Interface-based DI
Interfaces
public interface IRepository<T>
{
    void Add(T item);
    T Get(int id);
    IEnumerable<T> GetAll();
}

public class CustomerRepository : IRepository<Customer>
{
    private List<Customer> _customers = new List<Customer>();

    public void Add(Customer item) => _customers.Add(item);
    public Customer Get(int id) => _customers.FirstOrDefault(c => c.Id == id);
    public IEnumerable<Customer> GetAll() => _customers;
}

// Usage
IRepository<Customer> repo = new CustomerRepository();
repo.Add(new Customer { Id = 1, Name = "Alice" });
var customer = repo.Get(1);
Intermediate
26. How does Multiple Inheritance work via Interfaces in .NET Core?

Interfaces provide a way to implement multiple contracts in a class, enabling flexible composition without the diamond problem.

  • Multiple Interfaces: Implement multiple contracts
  • Composition: Combine multiple behaviors
  • Default Interface Methods: Common implementations
  • Explicit Implementation: Resolve conflicts
  • Dependency Inversion: Program to interfaces
Multiple Interfaces
public interface ICanFly { void Fly(); }
public interface ICanSwim { void Swim(); }

public class Duck : ICanFly, ICanSwim
{
    public void Fly() => Console.WriteLine("Duck flying");
    public void Swim() => Console.WriteLine("Duck swimming");
}

public class Penguin : ICanSwim
{
    public void Swim() => Console.WriteLine("Penguin swimming");
}

// Multiple interface usage
void DoActions(ICanSwim swimmer) => swimmer.Swim();

Duck duck = new Duck();
DoActions(duck); // Duck swimming
(duck as ICanFly)?.Fly(); // Duck flying
Intermediate
27. What are Extension Methods in .NET Core?

Extension Methods allow adding new functionality to existing types without modifying their source code, enhancing code readability and capability.

  • static class — Hosts extension methods
  • this — First parameter for extended type
  • Method Chaining: Fluent interface design
  • Type Extension: Add methods to any type
  • LINQ: Built using extension methods
Extension Methods
public static class StringExtensions
{
    public static bool IsPalindrome(this string str)
    {
        if (string.IsNullOrEmpty(str)) return true;
        int i = 0, j = str.Length - 1;
        while (i < j)
        {
            if (str[i] != str[j]) return false;
            i++; j--;
        }
        return true;
    }

    public static string Reverse(this string str)
        => new string(str.Reverse().ToArray());
}

// Usage
string s = "radar";
Console.WriteLine(s.IsPalindrome()); // True
Console.WriteLine(s.Reverse()); // "radar"
Advanced
28. What are Design Patterns - Singleton and Factory in .NET Core?

Singleton ensures a class has only one instance. Factory provides an interface for creating objects without specifying concrete classes.

  • Singleton: Global instance access with thread safety
  • Factory: Object creation encapsulation
  • Lazy Initialization: Lazy<T> for thread-safe creation
  • Abstract Factory: Family of related objects
  • Dependency Injection: Built-in DI container
Singleton & Factory
// Singleton (thread-safe, lazy)
public sealed class Singleton
{
    private static readonly Lazy<Singleton> _instance =
        new Lazy<Singleton>(() => new Singleton());

    public static Singleton Instance => _instance.Value;

    private Singleton() { }

    public void DoWork() => Console.WriteLine("Singleton work");
}

// Factory
public interface IProduct { void Use(); }
public class ProductA : IProduct { public void Use() => Console.WriteLine("A"); }
public class ProductB : IProduct { public void Use() => Console.WriteLine("B"); }

public static class ProductFactory
{
    public static IProduct Create(string type) => type switch
    {
        "A" => new ProductA(),
        "B" => new ProductB(),
        _ => throw new ArgumentException()
    };
}
Advanced
29. How do Namespaces and Libraries work in .NET Core?

Namespaces organize code into logical groups. Libraries are reusable code packages distributed via NuGet or as project references.

  • namespace — Organizes code
  • using — Import namespaces
  • NuGet: Package manager for libraries
  • Project References: Local library dependencies
  • Global Usings: Implicit namespace imports
Namespaces & Libraries
// Using System namespace
using System;
using System.Collections.Generic;
using System.Linq;

// Custom namespace
namespace MyApp.Models
{
    public class User { }
}

// Using alias
using Project = MyApp.Models;

// Global using (in a separate file)
global using System.Text;

// Package reference via NuGet
// <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />

// Usage
Newtonsoft.Json.JsonConvert.SerializeObject(new { Name = "Test" });
Advanced
30. How do you solve the Two Sum Problem in .NET Core?

Two Sum is a classic algorithm problem that finds pairs in an array that sum to a target value using hash maps or two-pointer technique.

  • Hash Map Approach: O(n) time, O(n) space
  • Two Pointer: O(n log n) with sorting
  • Trade-offs: Time vs Space
  • Edge Cases: Duplicates, unsorted input
  • Tuple Returns: Return multiple values
Two Sum
public int[] TwoSum(int[] nums, int target)
{
    var map = new Dictionary<int, int>();
    for (int i = 0; i < nums.Length; i++)
    {
        int complement = target - nums[i];
        if (map.ContainsKey(complement))
            return new int[] { map[complement], i };
        map[nums[i]] = i;
    }
    return Array.Empty<int>();
}

// Two-pointer approach (if sorted)
public int[] TwoSumSorted(int[] nums, int target)
{
    int left = 0, right = nums.Length - 1;
    while (left < right)
    {
        int sum = nums[left] + nums[right];
        if (sum == target) return new int[] { left, right };
        if (sum < target) left++;
        else right--;
    }
    return Array.Empty<int>();
}
Advanced
31. How does Kadane's Algorithm work in .NET Core?

Kadane's Algorithm finds the maximum subarray sum in O(n) time using dynamic programming to track current and maximum sums.

  • Dynamic Programming: Track current max
  • O(n) Time: Single pass algorithm
  • Negative Numbers: Handle all-negative arrays
  • Subarray Tracking: Find start and end indices
Kadane's Algorithm
public int MaxSubArray(int[] nums)
{
    int currentMax = nums[0];
    int globalMax = nums[0];
    for (int i = 1; i < nums.Length; i++)
    {
        currentMax = Math.Max(nums[i], currentMax + nums[i]);
        globalMax = Math.Max(globalMax, currentMax);
    }
    return globalMax;
}

// Usage: MaxSubArray(new int[]{-2,1,-3,4,-1,2,1,-5,4}) -> 6
Advanced
32. How do you implement a Binary Tree in .NET Core?

Binary Tree is a hierarchical data structure where each node has at most two children, enabling efficient search and traversal.

  • Node Structure: Value, left, right
  • Tree Traversal: Inorder, Preorder, Postorder
  • Insertion: Level-order insertion
  • Height Calculation: Recursive depth measurement
Binary Tree
public class TreeNode
{
    public int Value { get; set; }
    public TreeNode Left { get; set; }
    public TreeNode Right { get; set; }

    public TreeNode(int value) => Value = value;
}

public class BinaryTree
{
    public TreeNode Root { get; set; }

    // Insert level-order
    public void Insert(int value)
    {
        if (Root == null) { Root = new TreeNode(value); return; }
        var queue = new Queue<TreeNode>();
        queue.Enqueue(Root);
        while (queue.Count > 0)
        {
            var node = queue.Dequeue();
            if (node.Left == null) { node.Left = new TreeNode(value); return; }
            else queue.Enqueue(node.Left);
            if (node.Right == null) { node.Right = new TreeNode(value); return; }
            else queue.Enqueue(node.Right);
        }
    }

    // Inorder traversal
    public void Inorder(TreeNode node)
    {
        if (node == null) return;
        Inorder(node.Left);
        Console.Write(node.Value + " ");
        Inorder(node.Right);
    }
}
Advanced
33. How do you implement a Binary Search Tree in .NET Core?

Binary Search Tree (BST) maintains sorted order with O(log n) average time for search, insert, and delete operations.

  • BST Property: Left < parent < right
  • Insertion: Recursive placement
  • Search: Binary search on tree
  • Traversal: Inorder gives sorted order
Binary Search Tree
public class BSTNode
{
    public int Value { get; set; }
    public BSTNode Left { get; set; }
    public BSTNode Right { get; set; }
    public BSTNode(int value) => Value = value;
}

public class BinarySearchTree
{
    public BSTNode Root { get; private set; }

    public void Insert(int value)
    {
        Root = InsertRec(Root, value);
    }

    private BSTNode InsertRec(BSTNode node, int value)
    {
        if (node == null) return new BSTNode(value);
        if (value < node.Value)
            node.Left = InsertRec(node.Left, value);
        else if (value > node.Value)
            node.Right = InsertRec(node.Right, value);
        return node;
    }

    public bool Search(int value)
    {
        var current = Root;
        while (current != null)
        {
            if (value == current.Value) return true;
            if (value < current.Value) current = current.Left;
            else current = current.Right;
        }
        return false;
    }
}
Advanced
34. How do Graph BFS and DFS work in .NET Core?

BFS (Breadth-First Search) explores level by level. DFS (Depth-First Search) explores as far as possible before backtracking.

  • BFS: Queue-based level-order traversal
  • DFS: Stack/recursive depth traversal
  • Visited Tracking: Prevent infinite loops
  • Applications: Shortest path, connected components
Graph BFS & DFS
public class Graph
{
    private Dictionary<int, List<int>> _adj = new();

    public void AddEdge(int u, int v)
    {
        if (!_adj.ContainsKey(u)) _adj[u] = new List<int>();
        if (!_adj.ContainsKey(v)) _adj[v] = new List<int>();
        _adj[u].Add(v);
        _adj[v].Add(u); // for undirected
    }

    public void BFS(int start)
    {
        var visited = new HashSet<int>();
        var queue = new Queue<int>();
        queue.Enqueue(start);
        visited.Add(start);
        while (queue.Count > 0)
        {
            int node = queue.Dequeue();
            Console.WriteLine(node);
            foreach (int neighbor in _adj[node])
                if (!visited.Contains(neighbor))
                {
                    visited.Add(neighbor);
                    queue.Enqueue(neighbor);
                }
        }
    }

    public void DFS(int start)
    {
        var visited = new HashSet<int>();
        DFSUtil(start, visited);
    }

    private void DFSUtil(int node, HashSet<int> visited)
    {
        visited.Add(node);
        Console.WriteLine(node);
        foreach (int neighbor in _adj[node])
            if (!visited.Contains(neighbor))
                DFSUtil(neighbor, visited);
    }
}
Advanced
35. How does Dijkstra's Algorithm work in .NET Core?

Dijkstra's Algorithm finds the shortest path from a source to all vertices in a weighted graph with non-negative edges.

  • Shortest Path: Single source, all destinations
  • Priority Queue: Efficient minimum selection
  • Edge Relaxation: Update distances
  • Limitations: No negative edges
Dijkstra
public int[] Dijkstra(int[,] graph, int src, int V)
{
    int[] dist = new int[V];
    bool[] visited = new bool[V];
    for (int i = 0; i < V; i++) dist[i] = int.MaxValue;
    dist[src] = 0;

    for (int count = 0; count < V - 1; count++)
    {
        int u = MinDistance(dist, visited, V);
        visited[u] = true;
        for (int v = 0; v < V; v++)
            if (!visited[v] && graph[u, v] != 0 && dist[u] != int.MaxValue &&
                dist[u] + graph[u, v] < dist[v])
                dist[v] = dist[u] + graph[u, v];
    }
    return dist;
}

private int MinDistance(int[] dist, bool[] visited, int V)
{
    int min = int.MaxValue, minIndex = -1;
    for (int v = 0; v < V; v++)
        if (!visited[v] && dist[v] <= min)
        { min = dist[v]; minIndex = v; }
    return minIndex;
}
Advanced
36. What are Dynamic Programming problems like Knapsack and LCS?

Dynamic Programming solves optimization problems by breaking them into overlapping subproblems and storing results.

  • 0/1 Knapsack: Maximize value with weight constraint
  • LCS: Longest Common Subsequence
  • Optimal Substructure: Build from subproblems
  • Memoization: Cache computed results
DP – Knapsack & LCS
// 0/1 Knapsack (DP)
public int Knapsack(int[] weights, int[] values, int capacity)
{
    int n = weights.Length;
    int[,] dp = new int[n + 1, capacity + 1];
    for (int i = 1; i <= n; i++)
        for (int w = 1; w <= capacity; w++)
            if (weights[i - 1] <= w)
                dp[i, w] = Math.Max(values[i - 1] + dp[i - 1, w - weights[i - 1]],
                                    dp[i - 1, w]);
            else
                dp[i, w] = dp[i - 1, w];
    return dp[n, capacity];
}

// Longest Common Subsequence (LCS)
public int LCS(string s1, string s2)
{
    int m = s1.Length, n = s2.Length;
    int[,] dp = new int[m + 1, n + 1];
    for (int i = 1; i <= m; i++)
        for (int j = 1; j <= n; j++)
            if (s1[i - 1] == s2[j - 1])
                dp[i, j] = 1 + dp[i - 1, j - 1];
            else
                dp[i, j] = Math.Max(dp[i - 1, j], dp[i, j - 1]);
    return dp[m, n];
}
Advanced
37. How do you implement a custom Hash Map in .NET Core?

Hash Map implementation involves creating buckets, handling collisions, and providing efficient key-value operations.

  • Hash Function: Map keys to bucket indices
  • Collision Handling: Chaining with lists
  • Operations: Put, Get, Remove
  • Load Factor: Performance optimization
Custom HashMap
public class MyHashMap<K, V>
{
    private class Node
    {
        public K Key;
        public V Value;
        public Node Next;
        public Node(K key, V value) { Key = key; Value = value; }
    }

    private Node[] _buckets;
    private int _capacity = 16;

    public MyHashMap()
    {
        _buckets = new Node[_capacity];
    }

    private int GetHash(K key) => Math.Abs(key.GetHashCode()) % _capacity;

    public void Put(K key, V value)
    {
        int index = GetHash(key);
        var head = _buckets[index];
        if (head == null) _buckets[index] = new Node(key, value);
        else
        {
            var current = head;
            while (current != null)
            {
                if (current.Key.Equals(key))
                {
                    current.Value = value;
                    return;
                }
                if (current.Next == null) break;
                current = current.Next;
            }
            current.Next = new Node(key, value);
        }
    }

    public V Get(K key)
    {
        int index = GetHash(key);
        var current = _buckets[index];
        while (current != null)
        {
            if (current.Key.Equals(key)) return current.Value;
            current = current.Next;
        }
        return default(V);
    }
}
Advanced
38. What are Heap and Priority Queue in .NET Core?

Heap and Priority Queue provide efficient priority-based operations with O(log n) insertion and removal.

  • Min-Heap/Max-Heap: Priority ordering
  • K-Largest Elements: Heap-based selection
  • Merge Sorted Arrays: Efficient merging
  • Custom Comparators: Flexible ordering
Heap & Priority Queue
public class PriorityQueue<T> where T : IComparable<T>
{
    private List<T> _heap = new List<T>();

    public int Count => _heap.Count;

    public void Enqueue(T item)
    {
        _heap.Add(item);
        int i = _heap.Count - 1;
        while (i > 0)
        {
            int parent = (i - 1) / 2;
            if (_heap[parent].CompareTo(_heap[i]) <= 0) break;
            Swap(i, parent);
            i = parent;
        }
    }

    public T Dequeue()
    {
        if (_heap.Count == 0) throw new InvalidOperationException();
        T item = _heap[0];
        int last = _heap.Count - 1;
        _heap[0] = _heap[last];
        _heap.RemoveAt(last);
        Heapify(0);
        return item;
    }

    private void Heapify(int i)
    {
        int left = i * 2 + 1, right = i * 2 + 2, smallest = i;
        if (left < _heap.Count && _heap[left].CompareTo(_heap[smallest]) < 0) smallest = left;
        if (right < _heap.Count && _heap[right].CompareTo(_heap[smallest]) < 0) smallest = right;
        if (smallest != i) { Swap(i, smallest); Heapify(smallest); }
    }

    private void Swap(int i, int j) => (_heap[i], _heap[j]) = (_heap[j], _heap[i]);
}
Advanced
39. How does a Trie Data Structure work in .NET Core?

Trie (Prefix Tree) enables efficient prefix-based operations like autocomplete, dictionary search, and pattern matching.

  • Node Structure: Children map, end marker
  • Insertion: Build tree character by character
  • Search: Exact word or prefix
  • Applications: Autocomplete, spell checking
Trie
public class TrieNode
{
    public Dictionary<char, TrieNode> Children = new();
    public bool IsEndOfWord = false;
}

public class Trie
{
    private TrieNode _root = new TrieNode();

    public void Insert(string word)
    {
        var node = _root;
        foreach (char c in word)
        {
            if (!node.Children.ContainsKey(c))
                node.Children[c] = new TrieNode();
            node = node.Children[c];
        }
        node.IsEndOfWord = true;
    }

    public bool Search(string word)
    {
        var node = _root;
        foreach (char c in word)
        {
            if (!node.Children.ContainsKey(c)) return false;
            node = node.Children[c];
        }
        return node.IsEndOfWord;
    }

    public bool StartsWith(string prefix)
    {
        var node = _root;
        foreach (char c in prefix)
        {
            if (!node.Children.ContainsKey(c)) return false;
            node = node.Children[c];
        }
        return true;
    }
}
Advanced
40. How do you implement a Segment Tree in .NET Core?

Segment Tree efficiently answers range queries and supports point updates on arrays with O(log n) time complexity.

  • Range Queries: Sum, min, max
  • Point Updates: Modify single element
  • Build Time: O(n) construction
  • Applications: RMQ, prefix sums
Segment Tree
public class SegmentTree
{
    private int[] _tree;
    private int _n;

    public SegmentTree(int[] arr)
    {
        _n = arr.Length;
        _tree = new int[4 * _n];
        Build(arr, 0, 0, _n - 1);
    }

    private void Build(int[] arr, int node, int left, int right)
    {
        if (left == right) _tree[node] = arr[left];
        else
        {
            int mid = (left + right) / 2;
            Build(arr, node * 2 + 1, left, mid);
            Build(arr, node * 2 + 2, mid + 1, right);
            _tree[node] = _tree[node * 2 + 1] + _tree[node * 2 + 2];
        }
    }

    public int Query(int ql, int qr) => Query(0, 0, _n - 1, ql, qr);

    private int Query(int node, int left, int right, int ql, int qr)
    {
        if (ql <= left && right <= qr) return _tree[node];
        if (right < ql || left > qr) return 0;
        int mid = (left + right) / 2;
        return Query(node * 2 + 1, left, mid, ql, qr) +
               Query(node * 2 + 2, mid + 1, right, ql, qr);
    }

    public void Update(int idx, int value) => Update(0, 0, _n - 1, idx, value);

    private void Update(int node, int left, int right, int idx, int value)
    {
        if (left == right) _tree[node] = value;
        else
        {
            int mid = (left + right) / 2;
            if (idx <= mid) Update(node * 2 + 1, left, mid, idx, value);
            else Update(node * 2 + 2, mid + 1, right, idx, value);
            _tree[node] = _tree[node * 2 + 1] + _tree[node * 2 + 2];
        }
    }
}
Advanced
41. How does Union-Find (Disjoint Set) work in .NET Core?

Union-Find efficiently manages disjoint sets with union and find operations, using path compression and union by rank.

  • Find Operation: Locate set representative
  • Union Operation: Merge two sets
  • Path Compression: Optimize find
  • Union by Rank: Efficient merging
Union-Find
public class UnionFind
{
    private int[] _parent;
    private int[] _rank;

    public UnionFind(int n)
    {
        _parent = new int[n];
        _rank = new int[n];
        for (int i = 0; i < n; i++) _parent[i] = i;
    }

    public int Find(int x)
    {
        if (_parent[x] != x)
            _parent[x] = Find(_parent[x]); // path compression
        return _parent[x];
    }

    public void Union(int x, int y)
    {
        int rx = Find(x), ry = Find(y);
        if (rx == ry) return;
        if (_rank[rx] < _rank[ry]) _parent[rx] = ry;
        else if (_rank[rx] > _rank[ry]) _parent[ry] = rx;
        else { _parent[ry] = rx; _rank[rx]++; }
    }

    public bool Connected(int x, int y) => Find(x) == Find(y);
}
Advanced
42. What is Sliding Window Maximum in .NET Core?

Sliding Window Maximum finds the maximum in each sliding window of size k using a deque for efficient processing.

  • Deque Approach: O(n) time complexity
  • Window Tracking: Maintain indices
  • Remove Out-of-Window: Keep valid elements
  • Applications: Streaming data, time-series
Sliding Window Maximum
public int[] SlidingWindowMaximum(int[] nums, int k)
{
    if (nums.Length == 0 || k == 0) return new int[0];
    var result = new int[nums.Length - k + 1];
    var deque = new LinkedList<int>(); // store indices

    for (int i = 0; i < nums.Length; i++)
    {
        // remove indices out of window
        if (deque.Count > 0 && deque.First.Value <= i - k)
            deque.RemoveFirst();

        // maintain decreasing order
        while (deque.Count > 0 && nums[deque.Last.Value] <= nums[i])
            deque.RemoveLast();

        deque.AddLast(i);

        // start recording results when window is full
        if (i >= k - 1)
            result[i - k + 1] = nums[deque.First.Value];
    }
    return result;
}
Advanced
43. How does KMP String Matching work in .NET Core?

KMP (Knuth-Morris-Pratt) is an efficient string matching algorithm using a partial match table to avoid unnecessary comparisons.

  • LPS Array: Longest proper prefix suffix
  • Pattern Preprocessing: Build LPS table
  • Efficient Search: O(n) time complexity
  • Applications: Pattern matching, text search
KMP
public int KMP(string text, string pattern)
{
    int[] lps = BuildLPS(pattern);
    int i = 0, j = 0;
    while (i < text.Length)
    {
        if (text[i] == pattern[j])
        { i++; j++; if (j == pattern.Length) return i - j; }
        else if (j > 0) j = lps[j - 1];
        else i++;
    }
    return -1;
}

private int[] BuildLPS(string pattern)
{
    int[] lps = new int[pattern.Length];
    int len = 0, i = 1;
    while (i < pattern.Length)
    {
        if (pattern[i] == pattern[len]) lps[i++] = ++len;
        else if (len > 0) len = lps[len - 1];
        else lps[i++] = 0;
    }
    return lps;
}
Advanced
44. How do you solve the N-Queens problem in .NET Core?

N-Queens is a classic backtracking problem that places N queens on an N×N chessboard where no two queens attack each other.

  • Backtracking: Systematic trial and error
  • Column Placement: One queen per column
  • Safety Check: Row and diagonal conflicts
  • Solution Counting: Total valid configurations
N-Queens
public bool SolveNQueens(int n, int col, int[] board)
{
    if (col >= n) return true;
    for (int row = 0; row < n; row++)
    {
        if (IsSafe(board, col, row))
        {
            board[col] = row;
            if (SolveNQueens(n, col + 1, board)) return true;
            board[col] = -1; // backtrack
        }
    }
    return false;
}

private bool IsSafe(int[] board, int col, int row)
{
    for (int i = 0; i < col; i++)
    {
        if (board[i] == row) return false;
        if (Math.Abs(board[i] - row) == Math.Abs(i - col)) return false;
    }
    return true;
}
Advanced
45. How does LRU Cache work in .NET Core?

LRU Cache (Least Recently Used) maintains a fixed-size cache, evicting the least recently used items when capacity is exceeded.

  • LinkedHashMap: Maintains insertion order
  • Get Operation: Access moves to most recent
  • Put Operation: Update or add with eviction
  • Cache Management: Capacity and eviction policy
LRU Cache
public class LRUCache<K, V>
{
    private readonly int _capacity;
    private readonly Dictionary<K, LinkedListNode<(K, V)>> _map;
    private readonly LinkedList<(K, V)> _list;

    public LRUCache(int capacity)
    {
        _capacity = capacity;
        _map = new Dictionary<K, LinkedListNode<(K, V)>>();
        _list = new LinkedList<(K, V)>();
    }

    public V Get(K key)
    {
        if (!_map.ContainsKey(key)) return default(V);
        var node = _map[key];
        _list.Remove(node);
        _list.AddFirst(node);
        return node.Value.Item2;
    }

    public void Put(K key, V value)
    {
        if (_map.ContainsKey(key))
        {
            var node = _map[key];
            _list.Remove(node);
            node.Value = (key, value);
            _list.AddFirst(node);
        }
        else
        {
            if (_map.Count >= _capacity)
            {
                var last = _list.Last;
                _map.Remove(last.Value.Item1);
                _list.RemoveLast();
            }
            var newNode = new LinkedListNode<(K, V)>((key, value));
            _list.AddFirst(newNode);
            _map[key] = newNode;
        }
    }
}
Advanced
46. How does Topological Sort work in .NET Core?

Topological Sort orders vertices in a directed acyclic graph (DAG) such that for every edge u→v, u comes before v.

  • Kahn's Algorithm: Queue-based approach
  • Indegree Tracking: Count incoming edges
  • Applications: Task scheduling, dependency resolution
  • Cycle Detection: DAG verification
Topological Sort
public int[] TopologicalSort(int vertices, int[,] edges)
{
    int[] indegree = new int[vertices];
    var graph = new Dictionary<int, List<int>>();
    for (int i = 0; i < vertices; i++) graph[i] = new List<int>();

    for (int i = 0; i < edges.GetLength(0); i++)
    {
        int u = edges[i, 0], v = edges[i, 1];
        graph[u].Add(v);
        indegree[v]++;
    }

    var queue = new Queue<int>();
    for (int i = 0; i < vertices; i++)
        if (indegree[i] == 0) queue.Enqueue(i);

    var result = new List<int>();
    while (queue.Count > 0)
    {
        int u = queue.Dequeue();
        result.Add(u);
        foreach (int v in graph[u])
            if (--indegree[v] == 0) queue.Enqueue(v);
    }
    return result.Count == vertices ? result.ToArray() : new int[0];
}
Advanced
47. What is Bit Manipulation in .NET Core?

Bit Manipulation uses bitwise operations for efficient programming, including checking, setting, and toggling bits.

  • Bitwise Operators: &, |, ^, ~, <<, >>
  • Bit Checking: Test if bit is set
  • Counting Bits: Efficient population count
  • Power of 2: Check using bit magic
Bit Manipulation
int num = 42;

// Check if bit at position pos is set
bool IsBitSet(int n, int pos) => (n & (1 << pos)) != 0;

// Set bit
int SetBit(int n, int pos) => n | (1 << pos);

// Clear bit
int ClearBit(int n, int pos) => n & ~(1 << pos);

// Toggle bit
int ToggleBit(int n, int pos) => n ^ (1 << pos);

// Count set bits (Brian Kernighan)
int CountSetBits(int n)
{
    int count = 0;
    while (n > 0) { n &= (n - 1); count++; }
    return count;
}

// Check if power of two
bool IsPowerOfTwo(int n) => n > 0 && (n & (n - 1)) == 0;

// Swap without temp
int a = 5, b = 10;
a ^= b; b ^= a; a ^= b;
Advanced
48. What is Number Theory in .NET Core?

Number Theory includes algorithms for GCD, LCM, prime numbers, sieve, and modular exponentiation.

  • GCD/LCM: Euclidean algorithm
  • Prime Detection: Trial division, sieve
  • Modular Arithmetic: Modular exponentiation
  • Applications: Cryptography, number theory
Number Theory
int Gcd(int a, int b) => b == 0 ? a : Gcd(b, a % b);
int Lcm(int a, int b) => a / Gcd(a, b) * b;

bool IsPrime(int n)
{
    if (n < 2) return false;
    for (int i = 2; i * i <= n; i++)
        if (n % i == 0) return false;
    return true;
}

// Sieve of Eratosthenes
bool[] Sieve(int n)
{
    bool[] isPrime = new bool[n + 1];
    Array.Fill(isPrime, true);
    isPrime[0] = isPrime[1] = false;
    for (int i = 2; i * i <= n; i++)
        if (isPrime[i])
            for (int j = i * i; j <= n; j += i)
                isPrime[j] = false;
    return isPrime;
}

// Modular exponentiation
long ModPow(long a, long b, long mod)
{
    long result = 1;
    a %= mod;
    while (b > 0)
    {
        if ((b & 1) == 1) result = (result * a) % mod;
        a = (a * a) % mod;
        b >>= 1;
    }
    return result;
}
Advanced
49. How do Tuples work in .NET Core?

Tuples provide a way to group multiple values into a single object with named or unnamed fields.

  • ValueTuple: Lightweight tuple type
  • Named Tuples: Access by field name
  • Deconstruction: Pattern matching
  • Return Values: Multiple return values
Tuples
// ValueTuple
var person = (Name: "John", Age: 30);
Console.WriteLine($"{person.Name} is {person.Age}");

// Deconstruction
(string name, int age) = person;
Console.WriteLine($"{name} is {age}");

// Return multiple values
public (int Sum, int Product) Calculate(int a, int b)
{
    return (a + b, a * b);
}

var result = Calculate(3, 4);
Console.WriteLine($"Sum: {result.Sum}, Product: {result.Product}");

// Tuple as parameter
void Process((int X, int Y) point)
{
    Console.WriteLine($"({point.X}, {point.Y})");
}
Advanced
50. What is the Two Pointers Technique in .NET Core?

Two Pointers technique efficiently solves array problems like container with most water and three-sum using two converging pointers.

  • Container with Most Water: Maximize area
  • Three-Sum: Find triplets summing to zero
  • Pointer Movement: Conditional advancement
  • Applications: Array problems, palindrome checking
Two Pointers
// Container With Most Water
public int MaxArea(int[] height)
{
    int left = 0, right = height.Length - 1, maxArea = 0;
    while (left < right)
    {
        int area = Math.Min(height[left], height[right]) * (right - left);
        maxArea = Math.Max(maxArea, area);
        if (height[left] < height[right]) left++;
        else right--;
    }
    return maxArea;
}

// Three-Sum (find triplets sum to zero)
public IList<IList<int>> ThreeSum(int[] nums)
{
    Array.Sort(nums);
    var result = new List<IList<int>>();
    for (int i = 0; i < nums.Length - 2; i++)
    {
        if (i > 0 && nums[i] == nums[i - 1]) continue;
        int left = i + 1, right = nums.Length - 1;
        while (left < right)
        {
            int sum = nums[i] + nums[left] + nums[right];
            if (sum == 0) { result.Add(new List<int> { nums[i], nums[left], nums[right] }); 
                            while (left < right && nums[left] == nums[left + 1]) left++;
                            while (left < right && nums[right] == nums[right - 1]) right--;
                            left++; right--; }
            else if (sum < 0) left++;
            else right--;
        }
    }
    return result;
}
Advanced
51. How does Backtracking work in .NET Core?

Backtracking is an algorithmic technique for solving problems by trying possibilities and undoing choices when they lead to dead ends.

  • Subset Generation: Generate all subsets
  • Permutations: All possible arrangements
  • State Management: Track current state
  • Applications: Combinatorial problems
Backtracking
// Generate all subsets
public IList<IList<int>> Subsets(int[] nums)
{
    var result = new List<IList<int>>();
    Backtrack(result, new List<int>(), nums, 0);
    return result;
}

private void Backtrack(IList<IList<int>> result, List<int> current, int[] nums, int start)
{
    result.Add(new List<int>(current));
    for (int i = start; i < nums.Length; i++)
    {
        current.Add(nums[i]);
        Backtrack(result, current, nums, i + 1);
        current.RemoveAt(current.Count - 1);
    }
}

// Permutations
public IList<IList<int>> Permute(int[] nums)
{
    var result = new List<IList<int>>();
    PermuteRec(nums, 0, result);
    return result;
}

private void PermuteRec(int[] nums, int start, IList<IList<int>> result)
{
    if (start == nums.Length) { result.Add(new List<int>(nums)); return; }
    for (int i = start; i < nums.Length; i++)
    {
        (nums[start], nums[i]) = (nums[i], nums[start]);
        PermuteRec(nums, start + 1, result);
        (nums[start], nums[i]) = (nums[i], nums[start]);
    }
}
Advanced
52. What are Greedy Algorithms in .NET Core?

Greedy Algorithms make locally optimal choices at each step to find a global optimum for certain problems.

  • Activity Selection: Maximize non-overlapping activities
  • Fractional Knapsack: Fractional item selection
  • Optimal Substructure: Greedy choice property
  • Applications: Scheduling, resource allocation
Greedy Algorithms
// Activity Selection
public int ActivitySelection(int[] start, int[] finish)
{
    int n = start.Length;
    var activities = new (int s, int f)[n];
    for (int i = 0; i < n; i++) activities[i] = (start[i], finish[i]);
    Array.Sort(activities, (a, b) => a.f.CompareTo(b.f));

    int count = 1;
    int lastFinish = activities[0].f;
    for (int i = 1; i < n; i++)
        if (activities[i].s >= lastFinish)
        {
            count++;
            lastFinish = activities[i].f;
        }
    return count;
}

// Fractional Knapsack (greedy)
public double FractionalKnapsack(int[] weights, int[] values, int capacity)
{
    var items = new (int w, int v, double ratio)[weights.Length];
    for (int i = 0; i < weights.Length; i++)
        items[i] = (weights[i], values[i], (double)values[i] / weights[i]);
    Array.Sort(items, (a, b) => b.ratio.CompareTo(a.ratio));

    double totalValue = 0;
    int remaining = capacity;
    foreach (var item in items)
    {
        if (remaining <= 0) break;
        if (item.w <= remaining) { totalValue += item.v; remaining -= item.w; }
        else { totalValue += item.ratio * remaining; remaining = 0; }
    }
    return totalValue;
}
Advanced
53. How do Events and Delegates work in .NET Core?

Events and Delegates implement the observer pattern, enabling loose coupling between components through event subscription and handling.

  • Event Handlers: Function delegates
  • Event Arguments: Carry event data
  • Subscription Management: Add/remove handlers
  • Observer Pattern: Push notifications
Events & Delegates
public class Button
{
    public event EventHandler<EventArgs> Clicked;

    public void Click()
    {
        Clicked?.Invoke(this, EventArgs.Empty);
    }
}

public class Window
{
    public void OnButtonClicked(object sender, EventArgs e)
    {
        Console.WriteLine("Button was clicked");
    }
}

// Usage
Button button = new Button();
Window window = new Window();
button.Clicked += window.OnButtonClicked;
button.Click();

// Custom event args
public class MessageEventArgs : EventArgs
{
    public string Message { get; set; }
}

// Event with custom args
public event EventHandler<MessageEventArgs> MessageReceived;
Advanced
54. How does IDisposable and Resource Management work in .NET Core?

IDisposable ensures proper cleanup of resources like file handles, database connections, and network sockets.

  • Resource Acquisition: Open/initialize resources
  • Resource Release: Close/cleanup properly
  • Using Statement: Guaranteed cleanup
  • Dispose Pattern: IDisposable implementation
IDisposable
public class ResourceManager : IDisposable
{
    private FileStream _fileStream;
    private SqlConnection _dbConnection;

    public void OpenResources()
    {
        _fileStream = File.Open("data.txt", FileMode.OpenOrCreate);
        _dbConnection = new SqlConnection("...");
        _dbConnection.Open();
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            _fileStream?.Dispose();
            _dbConnection?.Dispose();
        }
    }
}

// Using statement
using (var manager = new ResourceManager())
{
    manager.OpenResources();
    // use resources
}
Advanced
55. How does Async and Parallel Programming work in .NET Core?

Async and Parallel programming uses tasks and threads for parallel execution and async/await for non-blocking operations.

  • Tasks: Unit of work
  • Async/Await: Non-blocking operations
  • Parallel Processing: Task parallel library
  • Cancellation: Using CancellationToken
Async & Parallel
using System.Threading.Tasks;

// Async/await
public async Task<string> FetchDataAsync()
{
    await Task.Delay(1000);
    return "Data";
}

// Parallel processing
public void ParallelSum(int[] numbers)
{
    long total = 0;
    Parallel.For(0, numbers.Length, i =>
    {
        Interlocked.Add(ref total, numbers[i]);
    });
    Console.WriteLine(total);
}

// PLINQ
var result = numbers.AsParallel()
                    .Where(n => n % 2 == 0)
                    .Select(n => n * 2)
                    .OrderBy(n => n)
                    .ToList();

// CancellationToken
public async Task ProcessWithCancel(CancellationToken token)
{
    while (!token.IsCancellationRequested)
    {
        await Task.Delay(100);
        // do work
    }
}
Advanced
56. What are Regular Expressions in .NET Core?

Regular Expressions provide powerful pattern matching for text validation, search, and replacement operations.

  • Pattern Matching: Validate input formats
  • Search/Replace: Text manipulation
  • Groups: Capture matched parts
  • Named Groups: Readable pattern parts
Regular Expressions
using System.Text.RegularExpressions;

string pattern = @"^d{3}-d{2}-d{4}$";
string input = "123-45-6789";
bool isValid = Regex.IsMatch(input, pattern);

// Search
string text = "The quick brown fox jumps over the lazy dog.";
Match match = Regex.Match(text, @"w{4,}");
while (match.Success)
{
    Console.WriteLine(match.Value);
    match = match.NextMatch();
}

// Replace
string result = Regex.Replace(text, @"s+", " "); // compress spaces

// Groups
string pattern2 = @"(w+)@(w+).(w+)";
string email = "test@example.com";
var groups = Regex.Match(email, pattern2);
Console.WriteLine($"Username: {groups.Groups[1].Value}");
Advanced
57. What are Attributes and Reflection in .NET Core?

Attributes add metadata to code. Reflection enables runtime type inspection and dynamic method invocation.

  • Custom Attributes: Metadata on classes/methods
  • Reflection: Runtime type inspection
  • Type Information: Inspect at runtime
  • Dynamic Invocation: Call methods by name
Attributes & Reflection
using System.Reflection;

// Custom attribute
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class MyAttribute : Attribute
{
    public string Description { get; set; }
    public MyAttribute(string desc) => Description = desc;
}

[MyAttribute("This is a test class")]
public class TestClass
{
    [MyAttribute("This is a test method")]
    public void TestMethod() { }
}

// Reflection
Type type = typeof(TestClass);
var attributes = type.GetCustomAttributes(true);
foreach (var attr in attributes) Console.WriteLine(attr);

MethodInfo method = type.GetMethod("TestMethod");
var methodAttrs = method.GetCustomAttributes(true);

// Invoke dynamically
object instance = Activator.CreateInstance(type);
method.Invoke(instance, null);
Advanced
58. What are Observer and Command Design Patterns in .NET Core?

Observer Pattern enables one-to-many notification. Command Pattern encapsulates requests as objects for queuing and undo.

  • Observer: Subject-observer relationship
  • Command: Action encapsulation with undo
  • Loose Coupling: Components remain independent
  • Undo/Redo: Command history support
Observer & Command
// Observer pattern using events (see Q53)
// Command pattern
public interface ICommand
{
    void Execute();
    void Undo();
}

public class Light
{
    public void On() => Console.WriteLine("Light ON");
    public void Off() => Console.WriteLine("Light OFF");
}

public class LightOnCommand : ICommand
{
    private Light _light;
    public LightOnCommand(Light light) => _light = light;
    public void Execute() => _light.On();
    public void Undo() => _light.Off();
}

// Invoker
public class RemoteControl
{
    private ICommand _command;
    public void SetCommand(ICommand command) => _command = command;
    public void PressButton() => _command.Execute();
    public void PressUndo() => _command.Undo();
}
Advanced
59. What is Functional Programming in .NET Core?

Functional Programming uses pure functions, immutable data, and function composition for declarative code.

  • LINQ: Language Integrated Query
  • Higher-order Functions: Functions as parameters
  • Function Composition: Combine functions
  • Immutability: Immutable data structures
Functional Programming
// Higher-order functions
Func<int, int, int> add = (x, y) => x + y;
Func<int, int, int> multiply = (x, y) => x * y;

Func<int, int, int> combine(Func<int, int, int> f, Func<int, int, int> g)
{
    return (x, y) => f(g(x, y), y);
}

var result = combine(add, multiply)(2, 3); // (2*3) + 3 = 9

// Immutability with records
public record Person(string Name, int Age);
var p1 = new Person("John", 30);
var p2 = p1 with { Age = 31 }; // new instance with Age changed

// Function composition
Func<int, int> square = x => x * x;
Func<int, int> increment = x => x + 1;
Func<int, int> composed = x => increment(square(x));
Console.WriteLine(composed(5)); // 26
Advanced
60. What are Advanced Generics and Constraints in .NET Core?

Advanced Generics provide type safety with constraints, bounded types, and generic interfaces for flexible code.

  • Type Constraints: where T : new()
  • Generic Classes: Type parameter classes
  • Generic Methods: Type-safe methods
  • Repository Pattern: Generic data access
Advanced Generics
// Generic class with constraints
public class Repository<T> where T : class, new()
{
    public T CreateNew() => new T();
    public void Save(T entity) => Console.WriteLine($"Saving {entity}");
}

// Generic method with constraints
public T GetMax<T>(T a, T b) where T : IComparable<T>
{
    return a.CompareTo(b) > 0 ? a : b;
}

// Multiple constraints
public class DataStore<T> where T : struct, IComparable
{
    public void Add(T item) { /* ... */ }
}

// Covariance and Contravariance
IEnumerable<object> items = new List<string>(); // covariant
Action<object> action = (obj) => Console.WriteLine(obj);
Action<string> stringAction = action; // contravariant
Advanced
61. What are Matrix Operations in .NET Core?

Matrix Operations include multiplication, transposition, rotation, and other linear algebra operations.

  • Matrix Multiplication: Complex operation
  • Transposition: Flip rows/columns
  • Rotation: 90-degree rotation
  • Applications: Graphics, physics, ML
Matrix Operations
// Matrix multiplication
public int[,] Multiply(int[,] a, int[,] b)
{
    int rows = a.GetLength(0), cols = b.GetLength(1);
    int inner = a.GetLength(1);
    int[,] result = new int[rows, cols];
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < cols; j++)
        {
            int sum = 0;
            for (int k = 0; k < inner; k++)
                sum += a[i, k] * b[k, j];
            result[i, j] = sum;
        }
    return result;
}

// Transpose
public int[,] Transpose(int[,] matrix)
{
    int rows = matrix.GetLength(0), cols = matrix.GetLength(1);
    int[,] transposed = new int[cols, rows];
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < cols; j++)
            transposed[j, i] = matrix[i, j];
    return transposed;
}

// Rotate 90 degrees clockwise
public void Rotate(int[,] matrix)
{
    int n = matrix.GetLength(0);
    for (int layer = 0; layer < n / 2; layer++)
    {
        int first = layer, last = n - 1 - layer;
        for (int i = first; i < last; i++)
        {
            int offset = i - first;
            // Save top
            int top = matrix[first, i];
            // left -> top
            matrix[first, i] = matrix[last - offset, first];
            // bottom -> left
            matrix[last - offset, first] = matrix[last, last - offset];
            // right -> bottom
            matrix[last, last - offset] = matrix[i, last];
            // top -> right
            matrix[i, last] = top;
        }
    }
}
Advanced
62. What is Trapping Rain Water in .NET Core?

Trapping Rain Water calculates how much water can be trapped between bars using two-pointer technique.

  • Two-Pointer: Efficient O(n) solution
  • Left/Right Max: Track maximum heights
  • Water Volume: Sum of trapped water
  • Applications: Terrain analysis
Trapping Rain Water
public int Trap(int[] height)
{
    int left = 0, right = height.Length - 1;
    int leftMax = 0, rightMax = 0, water = 0;
    while (left < right)
    {
        if (height[left] < height[right])
        {
            if (height[left] >= leftMax) leftMax = height[left];
            else water += leftMax - height[left];
            left++;
        }
        else
        {
            if (height[right] >= rightMax) rightMax = height[right];
            else water += rightMax - height[right];
            right--;
        }
    }
    return water;
}
Advanced
63. What is Longest Increasing Subsequence (LIS) in .NET Core?

LIS finds the longest subsequence where elements are in increasing order using DP or binary search.

  • DP Solution: O(n²) time, O(n) space
  • Binary Search: O(n log n) time
  • Tail Tracking: Maintain increasing tails
  • Applications: Sequencing, bioinformatics
LIS
// DP solution O(n²)
public int LIS(int[] nums)
{
    int n = nums.Length;
    int[] dp = new int[n];
    int maxLen = 0;
    for (int i = 0; i < n; i++)
    {
        dp[i] = 1;
        for (int j = 0; j < i; j++)
            if (nums[j] < nums[i])
                dp[i] = Math.Max(dp[i], dp[j] + 1);
        maxLen = Math.Max(maxLen, dp[i]);
    }
    return maxLen;
}

// Binary search O(n log n)
public int LISBinary(int[] nums)
{
    List<int> tails = new List<int>();
    foreach (int x in nums)
    {
        int idx = tails.BinarySearch(x);
        if (idx < 0) idx = ~idx;
        if (idx == tails.Count) tails.Add(x);
        else tails[idx] = x;
    }
    return tails.Count;
}
Advanced
64. How does Bellman-Ford Algorithm work in .NET Core?

Bellman-Ford finds shortest paths in weighted graphs, handling negative edges and detecting negative cycles.

  • Negative Edges: Handles negative weights
  • Edge Relaxation: V-1 iterations
  • Cycle Detection: Identify negative cycles
  • Applications: Routing, network protocols
Bellman-Ford
public int[] BellmanFord(int V, int[,] edges, int src)
{
    int[] dist = new int[V];
    for (int i = 0; i < V; i++) dist[i] = int.MaxValue;
    dist[src] = 0;

    for (int i = 1; i < V; i++)
        for (int e = 0; e < edges.GetLength(0); e++)
        {
            int u = edges[e, 0], v = edges[e, 1], w = edges[e, 2];
            if (dist[u] != int.MaxValue && dist[u] + w < dist[v])
                dist[v] = dist[u] + w;
        }

    // Check for negative cycles
    for (int e = 0; e < edges.GetLength(0); e++)
    {
        int u = edges[e, 0], v = edges[e, 1], w = edges[e, 2];
        if (dist[u] != int.MaxValue && dist[u] + w < dist[v])
            throw new Exception("Negative cycle detected");
    }
    return dist;
}
Advanced
65. What is Floyd-Warshall Algorithm in .NET Core?

Floyd-Warshall finds all-pairs shortest paths in a weighted graph using dynamic programming in O(V³) time.

  • All-Pairs Shortest Path: Between all vertices
  • DP Approach: Intermediate vertex iteration
  • Negative Edges: Handles without negative cycles
  • Applications: Routing, transitive closure
Floyd-Warshall
public int[,] FloydWarshall(int[,] graph)
{
    int V = graph.GetLength(0);
    int[,] dist = (int[,])graph.Clone();

    for (int k = 0; k < V; k++)
        for (int i = 0; i < V; i++)
            for (int j = 0; j < V; j++)
                if (dist[i, k] != int.MaxValue && dist[k, j] != int.MaxValue)
                    dist[i, j] = Math.Min(dist[i, j], dist[i, k] + dist[k, j]);
    return dist;
}
Advanced
66. How does Kruskal's MST Algorithm work in .NET Core?

Kruskal's Algorithm finds a Minimum Spanning Tree by sorting edges and using union-find to add them without cycles.

  • Edge Sorting: Sort by weight
  • Union-Find: Cycle detection
  • MST Construction: Build spanning tree
  • Applications: Network design, clustering
Kruskal
public int KruskalMST(int V, (int u, int v, int w)[] edges)
{
    Array.Sort(edges, (a, b) => a.w.CompareTo(b.w));
    var uf = new UnionFind(V);
    int totalWeight = 0;
    foreach (var edge in edges)
        if (!uf.Connected(edge.u, edge.v))
        {
            uf.Union(edge.u, edge.v);
            totalWeight += edge.w;
        }
    return totalWeight;
}
Advanced
67. What are String Algorithms in .NET Core?

String Algorithms include longest palindrome, anagram checking, and grouping anagrams for text processing.

  • Longest Palindrome: Expand around center
  • Anagram Check: Frequency counting
  • Group Anagrams: Sort strings as keys
  • Applications: Text analysis, NLP
String Algorithms
// Longest Palindromic Substring (expand around center)
public string LongestPalindrome(string s)
{
    if (string.IsNullOrEmpty(s)) return "";
    int start = 0, maxLen = 1;
    for (int i = 0; i < s.Length; i++)
    {
        Expand(s, i, i, ref start, ref maxLen);
        Expand(s, i, i + 1, ref start, ref maxLen);
    }
    return s.Substring(start, maxLen);
}

private void Expand(string s, int left, int right, ref int start, ref int maxLen)
{
    while (left >= 0 && right < s.Length && s[left] == s[right])
    {
        int len = right - left + 1;
        if (len > maxLen) { start = left; maxLen = len; }
        left--; right++;
    }
}

// Anagram check
public bool IsAnagram(string s, string t)
{
    if (s.Length != t.Length) return false;
    var counts = new int[26];
    foreach (char c in s) counts[c - 'a']++;
    foreach (char c in t) counts[c - 'a']--;
    return counts.All(c => c == 0);
}

// Group Anagrams
public IList<IList<string>> GroupAnagrams(string[] strs)
{
    var map = new Dictionary<string, List<string>>();
    foreach (string s in strs)
    {
        char[] chars = s.ToCharArray();
        Array.Sort(chars);
        string key = new string(chars);
        if (!map.ContainsKey(key)) map[key] = new List<string>();
        map[key].Add(s);
    }
    return new List<IList<string>>(map.Values);
}
Advanced
68. What are Coin Change and Subset Sum in .NET Core?

Coin Change and Subset Sum are classic DP problems dealing with combinations and sums of values.

  • Minimum Coins: Minimum coins for amount
  • Count Ways: Number of combinations
  • Subset Sum: Check if sum is possible
  • Applications: Financial, resource allocation
Coin Change & Subset Sum
// Minimum coins (DP)
public int MinCoins(int[] coins, int amount)
{
    int[] dp = new int[amount + 1];
    Array.Fill(dp, int.MaxValue);
    dp[0] = 0;
    for (int i = 1; i <= amount; i++)
        foreach (int coin in coins)
            if (coin <= i && dp[i - coin] != int.MaxValue)
                dp[i] = Math.Min(dp[i], dp[i - coin] + 1);
    return dp[amount] == int.MaxValue ? -1 : dp[amount];
}

// Count ways (Coin Change II)
public int Change(int amount, int[] coins)
{
    int[] dp = new int[amount + 1];
    dp[0] = 1;
    foreach (int coin in coins)
        for (int i = coin; i <= amount; i++)
            dp[i] += dp[i - coin];
    return dp[amount];
}

// Subset Sum
public bool SubsetSum(int[] nums, int sum)
{
    bool[] dp = new bool[sum + 1];
    dp[0] = true;
    foreach (int num in nums)
        for (int i = sum; i >= num; i--)
            if (dp[i - num]) dp[i] = true;
    return dp[sum];
}
Advanced
69. What are Monotonic Stack Problems in .NET Core?

Monotonic Stack maintains elements in sorted order for problems like next greater element and largest rectangle in histogram.

  • Next Greater Element: Find next greater in array
  • Largest Rectangle: Max area in histogram
  • Stack Maintenance: Keep monotonic property
  • Applications: Data analysis, pattern finding
Monotonic Stack
// Next Greater Element
public int[] NextGreaterElement(int[] nums)
{
    int[] result = new int[nums.Length];
    var stack = new Stack<int>();
    for (int i = nums.Length - 1; i >= 0; i--)
    {
        while (stack.Count > 0 && stack.Peek() <= nums[i])
            stack.Pop();
        result[i] = stack.Count == 0 ? -1 : stack.Peek();
        stack.Push(nums[i]);
    }
    return result;
}

// Largest Rectangle in Histogram
public int LargestRectangleArea(int[] heights)
{
    var stack = new Stack<int>();
    int maxArea = 0;
    for (int i = 0; i <= heights.Length; i++)
    {
        int h = (i == heights.Length) ? 0 : heights[i];
        while (stack.Count > 0 && h < heights[stack.Peek()])
        {
            int height = heights[stack.Pop()];
            int width = stack.Count == 0 ? i : i - stack.Peek() - 1;
            maxArea = Math.Max(maxArea, height * width);
        }
        stack.Push(i);
    }
    return maxArea;
}
Advanced
70. What are Binary Search Variants in .NET Core?

Binary Search Variants handle rotated arrays, peak finding, and finding first/last occurrences of elements.

  • Rotated Array Search: Binary search in rotated sorted
  • Peak Finding: Find any peak element
  • First/Last Position: Range queries
  • Applications: Data structures, algorithms
Binary Search Variants
// Search in Rotated Sorted Array
public int SearchRotated(int[] nums, int target)
{
    int left = 0, right = nums.Length - 1;
    while (left <= right)
    {
        int mid = left + (right - left) / 2;
        if (nums[mid] == target) return mid;
        if (nums[left] <= nums[mid]) // left half sorted
        {
            if (target >= nums[left] && target < nums[mid])
                right = mid - 1;
            else
                left = mid + 1;
        }
        else // right half sorted
        {
            if (target > nums[mid] && target <= nums[right])
                left = mid + 1;
            else
                right = mid - 1;
        }
    }
    return -1;
}

// Find Peak Element
public int FindPeak(int[] nums)
{
    int left = 0, right = nums.Length - 1;
    while (left < right)
    {
        int mid = left + (right - left) / 2;
        if (nums[mid] < nums[mid + 1])
            left = mid + 1;
        else
            right = mid;
    }
    return left;
}

// First and Last Position
public int[] SearchRange(int[] nums, int target)
{
    int first = FindFirst(nums, target);
    if (first == -1) return new int[] { -1, -1 };
    int last = FindLast(nums, target);
    return new int[] { first, last };
}

private int FindFirst(int[] nums, int target)
{
    int left = 0, right = nums.Length - 1, result = -1;
    while (left <= right)
    {
        int mid = left + (right - left) / 2;
        if (nums[mid] == target) { result = mid; right = mid - 1; }
        else if (nums[mid] < target) left = mid + 1;
        else right = mid - 1;
    }
    return result;
}

private int FindLast(int[] nums, int target)
{
    int left = 0, right = nums.Length - 1, result = -1;
    while (left <= right)
    {
        int mid = left + (right - left) / 2;
        if (nums[mid] == target) { result = mid; left = mid + 1; }
        else if (nums[mid] < target) left = mid + 1;
        else right = mid - 1;
    }
    return result;
}
Advanced
71. What is Product of Array Except Self in .NET Core?

Product of Array Except Self calculates the product of all elements except the current one in O(n) time.

  • Left and Right Passes: Track products
  • In-Place Solution: No extra space
  • O(n) Time: Single pass each direction
  • Applications: Array calculations
Product Except Self
public int[] ProductExceptSelf(int[] nums)
{
    int n = nums.Length;
    int[] result = new int[n];
    result[0] = 1;
    for (int i = 1; i < n; i++)
        result[i] = result[i - 1] * nums[i - 1];

    int rightProduct = 1;
    for (int i = n - 1; i >= 0; i--)
    {
        result[i] *= rightProduct;
        rightProduct *= nums[i];
    }
    return result;
}
Advanced
72. What are Flood Fill and Number of Islands in .NET Core?

Flood Fill and Number of Islands are graph traversal problems using DFS/BFS for connected component detection.

  • Flood Fill: Color replacement algorithm
  • Number of Islands: Count connected land cells
  • DFS Traversal: Depth-first on grid
  • Applications: Image processing, maps
Flood Fill & Islands
// Flood Fill
public int[][] FloodFill(int[][] image, int sr, int sc, int newColor)
{
    int oldColor = image[sr][sc];
    if (oldColor == newColor) return image;
    DFS(image, sr, sc, oldColor, newColor);
    return image;
}

private void DFS(int[][] image, int r, int c, int oldColor, int newColor)
{
    if (r < 0 || r >= image.Length || c < 0 || c >= image[0].Length || image[r][c] != oldColor)
        return;
    image[r][c] = newColor;
    DFS(image, r + 1, c, oldColor, newColor);
    DFS(image, r - 1, c, oldColor, newColor);
    DFS(image, r, c + 1, oldColor, newColor);
    DFS(image, r, c - 1, oldColor, newColor);
}

// Number of Islands
public int NumIslands(char[][] grid)
{
    int count = 0;
    for (int i = 0; i < grid.Length; i++)
        for (int j = 0; j < grid[0].Length; j++)
            if (grid[i][j] == '1')
            {
                count++;
                DFSMark(grid, i, j);
            }
    return count;
}

private void DFSMark(char[][] grid, int r, int c)
{
    if (r < 0 || r >= grid.Length || c < 0 || c >= grid[0].Length || grid[r][c] != '1')
        return;
    grid[r][c] = '0';
    DFSMark(grid, r + 1, c);
    DFSMark(grid, r - 1, c);
    DFSMark(grid, r, c + 1);
    DFSMark(grid, r, c - 1);
}
Advanced
74. What is Spiral Matrix in .NET Core?

Spiral Matrix traverses a 2D matrix in spiral order, using four boundaries that shrink as we progress.

  • Boundary Tracking: Top, bottom, left, right
  • Direction Changes: Moving clockwise
  • Layer-by-Layer: Process outer to inner
  • Applications: Matrix manipulation
Spiral Matrix
public IList<int> SpiralOrder(int[][] matrix)
{
    var result = new List<int>();
    if (matrix.Length == 0) return result;
    int top = 0, bottom = matrix.Length - 1;
    int left = 0, right = matrix[0].Length - 1;

    while (top <= bottom && left <= right)
    {
        // left to right
        for (int i = left; i <= right; i++) result.Add(matrix[top][i]);
        top++;
        // top to bottom
        for (int i = top; i <= bottom; i++) result.Add(matrix[i][right]);
        right--;
        if (top <= bottom)
        {
            // right to left
            for (int i = right; i >= left; i--) result.Add(matrix[bottom][i]);
            bottom--;
        }
        if (left <= right)
        {
            // bottom to top
            for (int i = bottom; i >= top; i--) result.Add(matrix[i][left]);
            left++;
        }
    }
    return result;
}
Advanced
75. How does Sudoku Solver work in .NET Core?

Sudoku Solver uses backtracking to fill empty cells with valid numbers, checking row, column, and box constraints.

  • Constraint Checking: Row, column, box
  • Backtracking: Try numbers recursively
  • Efficient Search: Early validation
  • Applications: Puzzle solving, CSP
Sudoku Solver
public bool SolveSudoku(char[][] board)
{
    for (int row = 0; row < 9; row++)
        for (int col = 0; col < 9; col++)
            if (board[row][col] == '.')
            {
                for (char num = '1'; num <= '9'; num++)
                    if (IsValid(board, row, col, num))
                    {
                        board[row][col] = num;
                        if (SolveSudoku(board)) return true;
                        board[row][col] = '.'; // backtrack
                    }
                return false;
            }
    return true;
}

private bool IsValid(char[][] board, int row, int col, char num)
{
    for (int i = 0; i < 9; i++)
    {
        if (board[row][i] == num) return false;
        if (board[i][col] == num) return false;
        int boxRow = 3 * (row / 3) + i / 3;
        int boxCol = 3 * (col / 3) + i % 3;
        if (board[boxRow][boxCol] == num) return false;
    }
    return true;
}
Advanced
76. What is Priority Queue with Custom Comparator in .NET Core?

Priority Queue with Custom Comparator allows ordering elements based on custom criteria using comparer interface.

  • Custom Comparator: Define ordering logic
  • Task Scheduling: Priority-based execution
  • Multiple Criteria: Compare by multiple fields
  • Applications: Scheduling, event handling
Custom Comparator PQ
// Using .NET 6+ PriorityQueue
var pq = new PriorityQueue<string, int>();
pq.Enqueue("High", 1);
pq.Enqueue("Low", 5);
pq.Enqueue("Medium", 3);

while (pq.TryDequeue(out string item, out int priority))
    Console.WriteLine($"{item} (Priority {priority})");

// Custom comparator with PriorityQueue
var customPQ = new PriorityQueue<string, string>(
    Comparer<string>.Create((a, b) => a.Length.CompareTo(b.Length)));
customPQ.Enqueue("short", "short");
customPQ.Enqueue("verylong", "verylong");
Advanced
77. What is Prim's MST Algorithm in .NET Core?

Prim's Algorithm finds a Minimum Spanning Tree by growing the tree one edge at a time using a priority queue.

  • Greedy Approach: Add minimum edge
  • Priority Queue: Efficient edge selection
  • Tree Growth: Expand from start vertex
  • Applications: Network design, clustering
Prim's Algorithm
public int Prim(int V, int[,] graph)
{
    int[] key = new int[V];
    bool[] mstSet = new bool[V];
    for (int i = 0; i < V; i++) key[i] = int.MaxValue;
    key[0] = 0;
    int totalWeight = 0;

    for (int count = 0; count < V; count++)
    {
        int u = MinKey(key, mstSet, V);
        mstSet[u] = true;
        totalWeight += key[u];
        for (int v = 0; v < V; v++)
            if (graph[u, v] != 0 && !mstSet[v] && graph[u, v] < key[v])
                key[v] = graph[u, v];
    }
    return totalWeight;
}

private int MinKey(int[] key, bool[] mstSet, int V)
{
    int min = int.MaxValue, minIndex = -1;
    for (int v = 0; v < V; v++)
        if (!mstSet[v] && key[v] < min)
        { min = key[v]; minIndex = v; }
    return minIndex;
}
Advanced
78. How does Custom Iterator Pattern work in .NET Core?

Custom Iterator enables creating custom iterable objects with specific iteration logic using IEnumerable and IEnumerator.

  • IEnumerable: Create custom sequences
  • IEnumerator: Stateful iteration
  • Lazy Evaluation: Generate on demand
  • Applications: Custom collections, sequences
Custom Iterator
public class FibonacciSequence : IEnumerable<int>
{
    public IEnumerator<int> GetEnumerator()
    {
        int a = 0, b = 1;
        yield return a;
        yield return b;
        while (true)
        {
            int c = a + b;
            yield return c;
            a = b;
            b = c;
        }
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        => GetEnumerator();
}

// Usage
foreach (int num in new FibonacciSequence().Take(10))
    Console.WriteLine(num);
Advanced
79. How do you implement Custom Stack and Queue in .NET Core?

Stack (LIFO) and Queue (FIFO) are fundamental data structures with custom implementations for specific needs.

  • Stack Implementation: List-based push/pop
  • Queue Implementation: Queue for efficiency
  • Operations: Push, pop, enqueue, dequeue
  • Applications: Various algorithms
Custom Stack & Queue
public class CustomStack<T>
{
    private List<T> _items = new List<T>();
    public void Push(T item) => _items.Add(item);
    public T Pop()
    {
        if (_items.Count == 0) throw new InvalidOperationException();
        T item = _items[^1];
        _items.RemoveAt(_items.Count - 1);
        return item;
    }
    public T Peek() => _items[^1];
    public bool IsEmpty => _items.Count == 0;
}

public class CustomQueue<T>
{
    private List<T> _items = new List<T>();
    public void Enqueue(T item) => _items.Add(item);
    public T Dequeue()
    {
        if (_items.Count == 0) throw new InvalidOperationException();
        T item = _items[0];
        _items.RemoveAt(0);
        return item;
    }
    public T Peek() => _items[0];
    public bool IsEmpty => _items.Count == 0;
}
Advanced
80. What are Counting Sort and Radix Sort in .NET Core?

Counting Sort and Radix Sort are non-comparison sorting algorithms efficient for specific input types.

  • Counting Sort: O(n+k) for integers
  • Radix Sort: Digit-by-digit sorting
  • Linear Time: Efficient for certain data
  • Applications: Integer sorting, strings
Counting & Radix Sort
// Counting Sort (non-negative integers)
public int[] CountingSort(int[] arr)
{
    int max = arr.Max();
    int[] count = new int[max + 1];
    foreach (int x in arr) count[x]++;
    int index = 0;
    for (int i = 0; i < count.Length; i++)
        for (int j = 0; j < count[i]; j++)
            arr[index++] = i;
    return arr;
}

// Radix Sort
public int[] RadixSort(int[] arr)
{
    int max = arr.Max();
    for (int exp = 1; max / exp > 0; exp *= 10)
        CountingSortByDigit(arr, exp);
    return arr;
}

private void CountingSortByDigit(int[] arr, int exp)
{
    int[] output = new int[arr.Length];
    int[] count = new int[10];
    for (int i = 0; i < arr.Length; i++)
        count[(arr[i] / exp) % 10]++;
    for (int i = 1; i < 10; i++)
        count[i] += count[i - 1];
    for (int i = arr.Length - 1; i >= 0; i--)
    {
        int digit = (arr[i] / exp) % 10;
        output[--count[digit]] = arr[i];
    }
    Array.Copy(output, arr, arr.Length);
}
Advanced
81. How does Graph Cycle Detection work in .NET Core?

Cycle Detection identifies cycles in directed and undirected graphs using DFS recursion stack or union-find.

  • Directed Graph: DFS with recursion stack
  • Undirected Graph: Union-Find approach
  • Back Edges: Indicate cycles
  • Applications: Deadlock detection, validation
Cycle Detection
// Cycle detection in undirected graph using DFS
public bool HasCycleUndirected(int V, List<int>[] adj)
{
    bool[] visited = new bool[V];
    for (int i = 0; i < V; i++)
        if (!visited[i] && DFS(i, -1, visited, adj))
            return true;
    return false;
}

private bool DFS(int v, int parent, bool[] visited, List<int>[] adj)
{
    visited[v] = true;
    foreach (int neighbor in adj[v])
    {
        if (!visited[neighbor])
        {
            if (DFS(neighbor, v, visited, adj)) return true;
        }
        else if (neighbor != parent)
            return true;
    }
    return false;
}

// Cycle detection in directed graph using recursion stack
public bool HasCycleDirected(int V, List<int>[] adj)
{
    bool[] visited = new bool[V];
    bool[] recStack = new bool[V];
    for (int i = 0; i < V; i++)
        if (!visited[i] && DFSDirected(i, visited, recStack, adj))
            return true;
    return false;
}

private bool DFSDirected(int v, bool[] visited, bool[] recStack, List<int>[] adj)
{
    visited[v] = true;
    recStack[v] = true;
    foreach (int neighbor in adj[v])
    {
        if (!visited[neighbor] && DFSDirected(neighbor, visited, recStack, adj))
            return true;
        else if (recStack[neighbor])
            return true;
    }
    recStack[v] = false;
    return false;
}
Advanced
82. What is Advanced LINQ in .NET Core?

Advanced LINQ includes group joins, select many, and complex aggregations with collections.

  • Group Join: Left outer join operations
  • Select Many: Flatten collections
  • Group By: Group elements by key
  • Aggregations: Complex data transformations
Advanced LINQ
// Group Join
var customers = new[] { new { Id = 1, Name = "John" }, new { Id = 2, Name = "Jane" } };
var orders = new[] { new { CustomerId = 1, Product = "Book" }, new { CustomerId = 1, Product = "Pen" } };

var result = customers.GroupJoin(
    orders,
    c => c.Id,
    o => o.CustomerId,
    (customer, orderList) => new { customer.Name, Orders = orderList.Select(o => o.Product) }
);

// SelectMany
string[][] words = new[] { new[] { "Hello", "World" }, new[] { "Goodbye", "Cruel", "World" } };
var allWords = words.SelectMany(w => w);

// Complex grouping
var grouped = orders.GroupBy(o => o.CustomerId)
                    .Select(g => new { CustomerId = g.Key, Count = g.Count() });

// Aggregations with custom logic
var aggregate = customers.Aggregate("", (acc, c) => acc + c.Name + ", ");
Advanced
83. How does Expression Evaluation work using Stack in .NET Core?

Expression Evaluation uses stacks to evaluate RPN expressions and convert infix to postfix notation.

  • RPN Evaluation: Postfix expression evaluation
  • Infix to Postfix: Shunting-yard algorithm
  • Operator Precedence: Handling precedence rules
  • Applications: Calculators, compilers
Expression Evaluation
// RPN evaluation
public int EvaluateRPN(string[] tokens)
{
    var stack = new Stack<int>();
    foreach (string token in tokens)
    {
        if (int.TryParse(token, out int num))
            stack.Push(num);
        else
        {
            int b = stack.Pop(), a = stack.Pop();
            int result = token switch
            {
                "+" => a + b,
                "-" => a - b,
                "*" => a * b,
                "/" => a / b,
                _ => throw new Exception()
            };
            stack.Push(result);
        }
    }
    return stack.Pop();
}

// Infix to Postfix (Shunting-yard) – simplified
public string InfixToPostfix(string expression)
{
    var output = new List<string>();
    var opStack = new Stack<char>();
    var precedence = new Dictionary<char, int> { { '+', 1 }, { '-', 1 }, { '*', 2 }, { '/', 2 } };

    foreach (char ch in expression)
    {
        if (char.IsDigit(ch)) output.Add(ch.ToString());
        else if (ch == '(') opStack.Push(ch);
        else if (ch == ')')
        {
            while (opStack.Peek() != '(') output.Add(opStack.Pop().ToString());
            opStack.Pop();
        }
        else if (precedence.ContainsKey(ch))
        {
            while (opStack.Count > 0 && precedence.ContainsKey(opStack.Peek()) &&
                   precedence[opStack.Peek()] >= precedence[ch])
                output.Add(opStack.Pop().ToString());
            opStack.Push(ch);
        }
    }
    while (opStack.Count > 0) output.Add(opStack.Pop().ToString());
    return string.Join(" ", output);
}
Advanced
84. What are Strategy and Template Design Patterns in .NET Core?

Strategy Pattern enables interchangeable algorithms. Template Method defines an algorithm skeleton with customizable steps.

  • Strategy: Family of algorithms
  • Template Method: Algorithm structure
  • Flexibility: Dynamic algorithm selection
  • Applications: Framework design, algorithms
Strategy & Template
// Strategy Pattern
public interface ISortStrategy
{
    void Sort(int[] data);
}

public class QuickSort : ISortStrategy
{
    public void Sort(int[] data) => Array.Sort(data);
}

public class BubbleSort : ISortStrategy
{
    public void Sort(int[] data) => BubbleSortAlgorithm(data);
}

public class DataProcessor
{
    private ISortStrategy _strategy;
    public void SetStrategy(ISortStrategy strategy) => _strategy = strategy;
    public void Process(int[] data)
    {
        _strategy.Sort(data);
        // process sorted data
    }
}

// Template Method
public abstract class DataImporter
{
    public void Import()
    {
        ReadData();
        ValidateData();
        TransformData();
        SaveData();
    }

    protected abstract void ReadData();
    protected virtual void ValidateData() { /* default */ }
    protected abstract void TransformData();
    protected virtual void SaveData() { Console.WriteLine("Saving data"); }
}
Advanced
85. How does Rabin-Karp String Matching work in .NET Core?

Rabin-Karp uses rolling hashes for efficient string matching, ideal for multiple pattern search in text.

  • Rolling Hash: Efficient hash updates
  • Pattern Preprocessing: Compute pattern hash
  • Average O(n): Efficient for long texts
  • Applications: Plagiarism detection, DNA
Rabin-Karp
public int RabinKarp(string text, string pattern)
{
    int n = text.Length, m = pattern.Length;
    int d = 256, q = 101; // prime
    int hashPattern = 0, hashText = 0, h = 1;

    // compute h = pow(d, m-1) % q
    for (int i = 0; i < m - 1; i++) h = (h * d) % q;

    // initial hash
    for (int i = 0; i < m; i++)
    {
        hashPattern = (d * hashPattern + pattern[i]) % q;
        hashText = (d * hashText + text[i]) % q;
    }

    for (int i = 0; i <= n - m; i++)
    {
        if (hashPattern == hashText && text.Substring(i, m) == pattern)
            return i;
        if (i < n - m)
        {
            hashText = (d * (hashText - text[i] * h) + text[i + m]) % q;
            if (hashText < 0) hashText += q;
        }
    }
    return -1;
}
Advanced
86. What is Type Erasure in .NET Core?

Type Erasure in .NET is achieved through generics with reified types, maintaining type information at runtime.

  • Reified Generics: Type info at runtime
  • Typeof: Get type information
  • Runtime Type: Type checking at runtime
  • Applications: Reflection, serialization
Type Erasure
// .NET generics preserve type info (reified)
public void TestType<T>(T item)
{
    Type t = typeof(T);
    Console.WriteLine($"Type: {t.Name}");

    if (item is int) Console.WriteLine("It's an int");
    else if (item is string) Console.WriteLine("It's a string");
}

// Usage
TestType(42); // prints "Type: Int32" and "It's an int"
TestType("Hello"); // prints "Type: String" and "It's a string"

// Runtime type checking
object obj = "test";
if (obj is string str) Console.WriteLine(str.ToUpper());
Advanced
87. What are .NET Core Interfaces and Abstract Classes?

Interfaces and Abstract Classes provide contract enforcement and code reuse in .NET's type system.

  • Interfaces: Contract definition
  • Abstract Classes: Partial implementation
  • Multiple Interfaces: Multiple contract support
  • Applications: Plugin architectures, frameworks
Interfaces vs Abstract
// Interface
public interface IRepository<T>
{
    void Add(T item);
    T Get(int id);
}

// Abstract class
public abstract class RepositoryBase<T> : IRepository<T>
{
    protected List<T> _items = new List<T>();
    public virtual void Add(T item) => _items.Add(item);
    public abstract T Get(int id);
}

// Concrete implementation
public class CustomerRepository : RepositoryBase<Customer>
{
    public override Customer Get(int id)
        => _items.FirstOrDefault(c => c.Id == id);
}
Advanced
88. What is Producer-Consumer in .NET Core?

Producer-Consumer pattern coordinates multiple threads/tasks producing and consuming items from a bounded buffer.

  • Bounded Buffer: Limited capacity queue
  • Synchronization: Blocking when full/empty
  • Thread Safety: Avoid race conditions
  • Applications: Task queues, data pipelines
Producer-Consumer
public class BoundedBuffer<T>
{
    private Queue<T> _queue = new Queue<T>();
    private int _capacity;
    private object _lock = new object();

    public BoundedBuffer(int capacity) => _capacity = capacity;

    public void Produce(T item)
    {
        lock (_lock)
        {
            while (_queue.Count >= _capacity) Monitor.Wait(_lock);
            _queue.Enqueue(item);
            Monitor.PulseAll(_lock);
        }
    }

    public T Consume()
    {
        lock (_lock)
        {
            while (_queue.Count == 0) Monitor.Wait(_lock);
            T item = _queue.Dequeue();
            Monitor.PulseAll(_lock);
            return item;
        }
    }
}

// Using BlockingCollection (built-in)
var bc = new BlockingCollection<int>(boundedCapacity: 10);
Task.Run(() => { while (true) bc.Add(new Random().Next(100)); });
foreach (int item in bc.GetConsumingEnumerable()) Console.WriteLine(item);
Advanced
89. What are .NET Core Records and Pattern Matching?

Records provide immutable data types. Pattern Matching enables powerful deconstruction and type-based logic.

  • Records: Immutable data with value equality
  • Positional Records: Position-based deconstruction
  • Pattern Matching: Switch expressions
  • Applications: Data transfer objects, domain models
Records & Pattern Matching
// Record
public record Person(string Name, int Age);

// Positional record with deconstruction
var p = new Person("John", 30);
var (name, age) = p; // deconstruction

// Pattern matching with switch
object obj = 42;
string result = obj switch
{
    int i when i > 0 => "Positive int",
    int i => "Non-positive int",
    string s => $"String: {s}",
    _ => "Unknown"
};

// Property pattern
if (p is Person { Age: > 18 }) Console.WriteLine("Adult");

// Switch expression with tuple
static string GetSeason(int month) => month switch
{
    12 or 1 or 2 => "Winter",
    3 or 4 or 5 => "Spring",
    6 or 7 or 8 => "Summer",
    9 or 10 or 11 => "Fall",
    _ => "Invalid"
};
Advanced
90. What are .NET Core Performance Features?

.NET Core performance features include Span, Memory, and pooled allocations for high-performance applications.

  • Span<T>: Safe memory access
  • Memory<T>: Manage memory buffers
  • ArrayPool: Reuse arrays efficiently
  • Applications: High-performance computing
Performance Features
// Span<T>
public int SumSpan(Span<int> span)
{
    int sum = 0;
    foreach (int i in span) sum += i;
    return sum;
}

// Usage
int[] arr = new int[] { 1, 2, 3 };
Span<int> span = arr.AsSpan();
int sum = SumSpan(span);

// Memory<T>
Memory<int> memory = arr.AsMemory();

// ArrayPool
using System.Buffers;
int[] rented = ArrayPool<int>.Shared.Rent(100);
try { /* use rented */ }
finally { ArrayPool<int>.Shared.Return(rented); }
Advanced
91. How does Reflection work in .NET Core?

Reflection in .NET provides runtime introspection of types, methods, and fields using the Type class.

  • Type Class: Reflect on types
  • MethodInfo: Invoke methods dynamically
  • PropertyInfo: Access properties
  • FieldInfo: Access fields
Reflection
using System.Reflection;

public class MyClass
{
    public int MyProperty { get; set; }
    public void MyMethod() => Console.WriteLine("Method invoked");
}

// Reflection example
Type type = typeof(MyClass);
var obj = Activator.CreateInstance(type);

PropertyInfo prop = type.GetProperty("MyProperty");
prop.SetValue(obj, 42);
Console.WriteLine(prop.GetValue(obj));

MethodInfo method = type.GetMethod("MyMethod");
method.Invoke(obj, null);

// Get all methods
var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance);
foreach (var m in methods) Console.WriteLine(m.Name);

// Get attributes
Attribute[] attrs = Attribute.GetCustomAttributes(type);
Advanced
92. What are Advanced Queries in LINQ?

Advanced LINQ enables building dynamic queries, sorting, projections, and grouping on collections.

  • Dynamic Filtering: Runtime query building
  • Dynamic Ordering: Field-based sorting
  • Projections: Field selection
  • Grouping: Dynamic group-by operations
Advanced LINQ
// Dynamic LINQ query (using System.Linq.Dynamic.Core)
var query = customers.AsQueryable();
if (filterByAge) query = query.Where("Age > 30");
if (sortBy) query = query.OrderBy("Name ASC");
var result = query.ToList();

// Using expression trees
Expression<Func<Customer, bool>> predicate = c => c.Age > 30;
var filtered = customers.AsQueryable().Where(predicate);

// Dynamic projections
var projected = customers.Select(c => new { c.Name, c.Age });

// Group by dynamic key
var grouped = customers.GroupBy(c => c.City);
Advanced
93. How to build a Complete Bank Account System in .NET Core?

A Bank Account System demonstrates object-oriented programming concepts including encapsulation, transactions, and state management.

  • Encapsulation: Private fields with public methods
  • Transactions: Record all account operations
  • Balance Management: Deposit and withdraw operations
  • Statement Generation: Print transaction history
Bank Account System
public class BankAccount
{
    private decimal _balance;
    private List<Transaction> _transactions = new();

    public BankAccount(string owner, decimal initialBalance)
    {
        Owner = owner;
        Deposit(initialBalance);
    }

    public string Owner { get; }
    public decimal Balance => _balance;

    public void Deposit(decimal amount)
    {
        if (amount <= 0) throw new ArgumentException("Amount must be positive");
        _balance += amount;
        _transactions.Add(new Transaction(DateTime.Now, amount, "Deposit"));
    }

    public void Withdraw(decimal amount)
    {
        if (amount <= 0) throw new ArgumentException("Amount must be positive");
        if (amount > _balance) throw new InvalidOperationException("Insufficient funds");
        _balance -= amount;
        _transactions.Add(new Transaction(DateTime.Now, -amount, "Withdrawal"));
    }

    public void PrintStatement()
    {
        Console.WriteLine($"Account Owner: {Owner}, Balance: {Balance:C}");
        foreach (var t in _transactions)
            Console.WriteLine($"{t.Date}: {t.Description} {t.Amount:C}");
    }

    private record Transaction(DateTime Date, decimal Amount, string Description);
}

// Usage
var account = new BankAccount("Alice", 1000);
account.Deposit(500);
account.Withdraw(200);
account.PrintStatement();
Advanced
94. How does IDDFS work in .NET Core?

Iterative Deepening DFS combines the space efficiency of DFS with the completeness of BFS, ideal for large search spaces.

  • Depth-Limited DFS: Search with depth limit
  • Iterative Depth: Increase depth gradually
  • Space Efficiency: O(d) memory
  • Applications: AI, game solving
IDDFS
public bool IDDFS(Graph graph, int start, int target, int maxDepth)
{
    for (int depth = 0; depth <= maxDepth; depth++)
        if (DLS(graph, start, target, depth)) return true;
    return false;
}

private bool DLS(Graph graph, int node, int target, int depth)
{
    if (node == target) return true;
    if (depth == 0) return false;
    foreach (int neighbor in graph.GetNeighbors(node))
        if (DLS(graph, neighbor, target, depth - 1)) return true;
    return false;
}
Advanced
95. How does Sparse Table work in .NET Core?

Sparse Table provides O(1) range minimum queries after O(n log n) preprocessing using dynamic programming.

  • Preprocessing: Build table for power-of-2 ranges
  • Range Queries: O(1) time complexity
  • Memory Usage: O(n log n)
  • Applications: RMQ, LCA
Sparse Table
public class SparseTable
{
    private int[][] _st;
    private int[] _log;

    public SparseTable(int[] arr)
    {
        int n = arr.Length;
        _log = new int[n + 1];
        for (int i = 2; i <= n; i++) _log[i] = _log[i / 2] + 1;

        int k = _log[n] + 1;
        _st = new int[k][];
        _st[0] = arr;

        for (int j = 1; j < k; j++)
        {
            int len = 1 << j;
            _st[j] = new int[n - len + 1];
            for (int i = 0; i + len <= n; i++)
                _st[j][i] = Math.Min(_st[j - 1][i], _st[j - 1][i + (1 << (j - 1))]);
        }
    }

    public int Query(int l, int r)
    {
        int j = _log[r - l + 1];
        return Math.Min(_st[j][l], _st[j][r - (1 << j) + 1]);
    }
}
Advanced
96. How does Fenwick Tree work in .NET Core?

Fenwick Tree (BIT) supports point updates and prefix sum queries in O(log n), ideal for dynamic frequency arrays.

  • Point Update: O(log n) time
  • Prefix Sum: O(log n) time
  • Memory Efficient: O(n) space
  • Applications: Frequency counting, inversions
Fenwick Tree
public class FenwickTree
{
    private int[] _tree;
    public FenwickTree(int n) => _tree = new int[n + 1];

    public void Update(int idx, int delta)
    {
        idx++;
        while (idx < _tree.Length)
        {
            _tree[idx] += delta;
            idx += idx & -idx;
        }
    }

    public int Sum(int idx)
    {
        idx++;
        int sum = 0;
        while (idx > 0)
        {
            sum += _tree[idx];
            idx -= idx & -idx;
        }
        return sum;
    }

    public int RangeSum(int l, int r) => Sum(r) - Sum(l - 1);
}
Advanced
97. How does Shell Sort and Interpolation Search work in .NET Core?

Shell Sort improves insertion sort with gap sequences. Interpolation Search uses value estimation for faster search in uniform distributions.

  • Shell Sort: O(n log n) average
  • Gap Sequence: Knuth's sequence
  • Interpolation Search: O(log log n) average
  • Applications: Specialized sorting/searching
Shell Sort & Interpolation
// Shell Sort
public int[] ShellSort(int[] arr)
{
    int n = arr.Length;
    for (int gap = n / 2; gap > 0; gap /= 2)
        for (int i = gap; i < n; i++)
        {
            int temp = arr[i];
            int j = i;
            while (j >= gap && arr[j - gap] > temp)
            {
                arr[j] = arr[j - gap];
                j -= gap;
            }
            arr[j] = temp;
        }
    return arr;
}

// Interpolation Search (works on uniformly distributed data)
public int InterpolationSearch(int[] arr, int target)
{
    int low = 0, high = arr.Length - 1;
    while (low <= high && target >= arr[low] && target <= arr[high])
    {
        int pos = low + ((target - arr[low]) * (high - low)) / (arr[high] - arr[low]);
        if (arr[pos] == target) return pos;
        if (arr[pos] < target) low = pos + 1;
        else high = pos - 1;
    }
    return -1;
}
Advanced
98. What are Nullable Types in .NET Core?

Nullable Types in .NET allow value types to represent null values, with support for null checking and handling.

  • Nullable<T>: Value type wrapper
  • ? Syntactic sugar for nullable
  • ??: Null coalescing operator
  • ?. : Null conditional operator
Nullable Types
// Nullable types
int? nullableInt = null;
bool? nullableBool = true;

// Null coalescing
int value = nullableInt ?? 0; // if null, use 0

// Null conditional operator
string name = null;
int length = name?.Length ?? 0; // 0 if null

// Nullable value type with HasValue
if (nullableInt.HasValue)
    Console.WriteLine(nullableInt.Value);
else
    Console.WriteLine("null");

// Nullable reference types (C# 8+)
string? nullableString = null;
string nonNullable = "hello";
Advanced
99. How does Parallel Programming with Tasks work in .NET Core?

Parallel Programming in .NET Core uses Tasks and the Parallel class for efficient multi-core processing and data parallelism.

  • Task: Asynchronous operation
  • Parallel.For: Parallel loops
  • PLINQ: Parallel LINQ queries
  • Applications: CPU-intensive operations
Parallel Tasks
using System.Threading.Tasks;

// Parallel.For
Parallel.For(0, 100, i =>
{
    Console.WriteLine($"Processing {i} on thread {Task.CurrentId}");
});

// Parallel.ForEach
var list = Enumerable.Range(1, 100).ToList();
Parallel.ForEach(list, item =>
{
    // process item
});

// PLINQ
var numbers = Enumerable.Range(1, 1000000);
var evens = numbers.AsParallel()
                   .Where(n => n % 2 == 0)
                   .Select(n => n * 2)
                   .ToList();

// Cancellation
var cts = new CancellationTokenSource();
Task.Run(() =>
{
    while (!cts.Token.IsCancellationRequested)
    {
        // work
    }
}, cts.Token);
Advanced
100. How to build a Complete Library Management System in .NET Core?

A Library Management System demonstrates practical application of OOP, collections, and business logic in .NET Core.

  • Book Management: Add, search, track availability
  • Member Management: Registration and borrowing
  • Borrow/Return: Transaction processing
  • Reporting: Display statistics
Library Management System
public class Library
{
    private List<Book> _books = new();
    private List<Member> _members = new();

    public void AddBook(Book book) => _books.Add(book);
    public void RegisterMember(Member member) => _members.Add(member);

    public Book? SearchBook(string title) => _books.FirstOrDefault(b => b.Title.Contains(title));

    public bool BorrowBook(string title, Member member)
    {
        var book = _books.FirstOrDefault(b => b.Title == title && b.IsAvailable);
        if (book == null) return false;
        book.IsAvailable = false;
        member.BorrowBook(book);
        return true;
    }

    public void ReturnBook(Book book, Member member)
    {
        book.IsAvailable = true;
        member.ReturnBook(book);
    }

    public void DisplayStatus()
    {
        Console.WriteLine($"Total Books: {_books.Count}, Total Members: {_members.Count}");
        Console.WriteLine($"Available Books: {_books.Count(b => b.IsAvailable)}");
    }
}

public class Book
{
    public string Title { get; set; }
    public string Author { get; set; }
    public bool IsAvailable { get; set; } = true;
}

public class Member
{
    public string Name { get; set; }
    private List<Book> _borrowed = new();
    public void BorrowBook(Book book) => _borrowed.Add(book);
    public void ReturnBook(Book book) => _borrowed.Remove(book);
    public int BorrowedCount => _borrowed.Count;
}