[{"kind":"course","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"","title":"How Computers Work — CPU, Memory, OS, Processes and Threads","body":"What happens inside a computer when your program runs — bits and bytes, the CPU and instruction cycle, the memory hierarchy (registers, cache, RAM, disk), stack vs heap, virtual memory and paging, the operating system, processes and threads, scheduling, concurrency problems, compilation vs interpretation, and how all of it shows up in .NET and SQL Server. Every program you write — a C API, a SQL query, a React page — finally runs as instructions on a CPU reading and writing memory , managed by an operating system . Knowing this layer explains things that otherwise look like magic: why a cache makes things fast, why the heap needs a garbage collector, why threads cause race conditions, why a query that reads from disk is slow. Layer What it does Example --- --- --- Hardware CPU, RAM, disk/SSD, network card Intel/AMD/ARM CPU, 16 GB RAM, NVMe SSD Operating system Manages hardware, memory, processes, files, network Windows, Linux Runtime Runs your managed code, manages memory .NET CLR, JVM, Node.js (V8) Your program Business logic ASP.NET Core API, SQL Server, browser Era Milestone --- --- 1945 Von Neumann architecture — program and data stored in the same memory 1971 Intel 4004, first commercial microprocessor 1978–1985 x86 (8086) and 32-bit 80386 with protected/virtual memory 1990s CPU caches on chip, pipelining, superscalar execution; Windows NT, Linux 2003–2005 64-bit x86 (AMD64); multi-core CPUs become standard 2010s SSDs replace HDDs; many cores; ARM in phones; cloud virtual machines 2020s Apple Silicon/ARM servers (AWS Graviton, Azure Cobalt), NVMe, GPUs/NPUs for AI Life of a program run: 1. Source code → compiler → machine code or intermediate code (IL for .NET). 2. You start it → the OS creates a process : virtual address space, loads the executable and libraries, creates the main thread . 3. The runtime (CLR) starts, JIT-compiles methods to machine code as they are first called. 4. The CPU executes instructions: fetch → decode → execute → write back, millions per millisecond, using registers and caches. 5. Data lives on the stack (method calls, locals) and the heap (objects); the OS maps virtual pages to physical RAM. 6. I/O (disk, network) is requested from the OS; the thread waits or continues asynchronously. 7. On exit the OS frees all memory, handles and threads of the process. - Windows: Task Manager, Resource Monitor, Performance Monitor (PerfMon), Process Explorer, Windows Performance Analyzer. - Linux: top / htop , ps , free -h , vmstat , iostat , lsof , perf . - .NET: dotnet-counters , dotnet-trace , dotnet-dump , Visual Studio Diagnostic Tools, PerfView, BenchmarkDotNet. - Learning: godbolt.org (see machine code), SharpLab.io (see IL and JIT assembly for C )."},{"kind":"lesson","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"bits-bytes-number-systems-and-encoding","title":"Bits, bytes, number systems and encoding","body":"Computers store everything as bits (0/1). 8 bits = 1 byte . Unit Size --- --- Byte 8 bits KB / KiB 1,000 / 1,024 bytes MB, GB, TB ×1,000 (or ×1,024 for MiB, GiB, TiB) Number systems: decimal (base 10), binary (base 2: 1011 = 11), hexadecimal (base 16: 0xFF = 255; two hex digits = one byte). How data is represented: Data Representation --- --- Integers Binary, two's complement for negatives ( int = 32 bits: −2,147,483,648 … 2,147,483,647) Decimals IEEE 754 floating point ( double = 64 bits: sign, exponent, mantissa) — why 0.1 isn't exact Text Characters → numbers via encodings: ASCII (7-bit), UTF-8 (1–4 bytes, the web standard), UTF-16 (.NET string / char , Windows) Images, audio Pixels/samples as numbers, usually compressed (JPEG, PNG, MP3) csharp Console.WriteLine(Convert.ToString(11, 2)); // 1011 Console.WriteLine(0xFF); // 255 byte[] utf8 = Encoding.UTF8.GetBytes(\"₹100\"); // ₹ takes 3 bytes in UTF-8 Console.WriteLine(utf8.Length); // 6 Console.WriteLine(\"₹100\".Length); // 4 UTF-16 chars Endianness: order of bytes in multi-byte numbers — little-endian (x86, ARM usually) stores the least significant byte first; network protocols use big-endian (\"network byte order\")."},{"kind":"lesson","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"how-the-cpu-executes-instructions","title":"How the CPU executes instructions","body":"The CPU (central processing unit) runs a simple loop billions of times per second (clock speed, e.g. 3.5 GHz): text FETCH next instruction from memory (address in the program counter) DECODE what it means (add, load, compare, jump …) EXECUTE in the ALU (arithmetic/logic unit) or load/store unit WRITE result back to a register or memory → move to next instruction Main parts: Part Role --- --- Registers Tiny, fastest storage inside the CPU (e.g. 16 general-purpose 64-bit registers on x64) ALU Does arithmetic and logic Control unit Decodes instructions, controls the flow Program counter Address of the next instruction Cache (L1/L2/L3) Fast copies of recently used memory Cores Independent execution units — a 8-core CPU runs 8 instruction streams at once (16 with hyper-threading/SMT) What a line of C becomes (simplified x64): csharp int total = price qty + tax; text mov eax, [price] ; load from memory into register imul eax, [qty] ; multiply add eax, [tax] ; add mov [total], eax ; store back to memory Speed tricks inside modern CPUs: pipelining (overlap stages of several instructions), out-of-order execution, branch prediction (guessing if results — sorted data makes branches predictable and loops faster), SIMD vector instructions (process 4–16 numbers at once — System.Numerics.Vector<T in .NET)."},{"kind":"lesson","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"the-memory-hierarchy-registers-cache-ram-disk","title":"The memory hierarchy — registers, cache, RAM, disk","body":"Level Typical size Approx. access time Notes --- --- --- --- Registers < 1 KB < 1 ns Inside the core L1 cache 32–64 KB per core ~1 ns L2 cache 256 KB – 2 MB per core ~3–5 ns L3 cache 8–64 MB shared ~10–20 ns RAM (main memory) 8–512 GB ~80–100 ns Volatile — lost on power off NVMe SSD TBs ~20–100 µs Persistent HDD TBs ~5–10 ms Mechanical seek Network (same datacenter) — ~0.5 ms round trip Network (across continents) — ~150 ms round trip Key idea: each level is ~10× to 1000× slower than the one above. Data moves between cache and RAM in cache lines of 64 bytes, so reading memory sequentially (arrays) is much faster than jumping around (linked lists, scattered objects) — this is locality of reference . csharp // Same work, very different speed: row-by-row walks memory sequentially (cache-friendly) int[,] m = new int[5000, 5000]; long sum = 0; for (int r = 0; r < 5000; r++) for (int c = 0; c < 5000; c++) sum += m[r, c]; // fast for (int c = 0; c < 5000; c++) for (int r = 0; r < 5000; r++) sum += m[r, c]; // several times slower This is also why SQL Server keeps data pages in RAM (buffer pool) and why caching (Redis, in-memory cache) speeds up applications: RAM is ~1000× faster than SSD and ~1,000,000× faster than a cross-continent network call."},{"kind":"lesson","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"stack-vs-heap-how-program-memory-is-laid-out","title":"Stack vs heap — how program memory is laid out","body":"A process's virtual memory is split into regions: text High addresses ┌──────────────────────┐ │ Stack (per thread) │ ← method calls, local variables, return addresses; grows down │ ↓ │ │ │ │ ↑ │ │ Heap │ ← objects created with new; managed by GC in .NET ├──────────────────────┤ │ Static/global data │ ← static fields, constants ├──────────────────────┤ │ Code (text) │ ← machine code (JIT output for .NET) └──────────────────────┘ Low addresses Stack Heap --- --- --- Stores Call frames: parameters, locals, return address Objects (class instances, arrays, strings) Allocation Move a pointer — extremely fast Find space — fast in .NET (bump pointer), but needs cleanup Freed Automatically when the method returns By the garbage collector (.NET/Java) or manually ( free / delete in C/C++) Size Small (1 MB per thread by default on Windows) Large (limited by RAM/address space) Per Thread Process (shared by all threads) Errors Stack overflow (deep/infinite recursion) Out of memory, leaks, fragmentation csharp void PlaceOrder() { int qty = 3; // local value on the stack (inside PlaceOrder's frame) var order = new Order { Qty = qty }; // the reference 'order' is on the stack; the Order object is on the heap Save(order); // a new frame for Save is pushed on the stack } // frame popped: qty and the reference disappear; the Order object stays until GC finds it unreachable Stack overflow example: int F(int n) = F(n + 1); — every call adds a frame until the 1 MB stack is full and the process crashes (in .NET a StackOverflowException cannot be caught)."},{"kind":"lesson","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"virtual-memory-paging-and-memory-management-by-the-os","title":"Virtual memory, paging and memory management by the OS","body":"Each process sees its own virtual address space (e.g. 128 TB on 64-bit Windows/Linux). The OS and CPU (MMU) translate virtual addresses to physical RAM in fixed-size pages (usually 4 KB). - Isolation: one process can't read another's memory → security and stability. - Overcommit: processes can reserve more than physical RAM; pages are loaded only when touched. - Page fault: accessing a page not in RAM → the OS loads it (from the page file/swap or the executable on disk). Too many = thrashing (system becomes extremely slow). - Memory-mapped files: a file mapped into memory; reading memory reads the file (used by databases and the .NET loader). Terms you see in Task Manager / monitoring: Term Meaning --- --- Working set Pages of the process currently in physical RAM Private bytes / commit Memory the process has committed for itself (heap, stacks) Virtual size All reserved address space (often huge, mostly unused) Page file / swap Disk area used when RAM is full Interview tip: \"Memory leak in a managed app\" usually means objects are still referenced (static lists, event handlers, caches without limits), so the GC is not allowed to free them — the OS sees private bytes grow until out-of-memory or the container is killed."},{"kind":"lesson","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"how-memory-is-managed-manual-reference-counting-and-garbage-collection","title":"How memory is managed: manual, reference counting and garbage collection","body":"Approach How Used by Risks --- --- --- --- Manual malloc/free , new/delete C, C++ Leaks, use-after-free, double free Reference counting Each object counts references; freed at 0 Swift, Python (plus cycle collector), COM, C++ shared ptr Cycles leak without extra work Tracing garbage collection Periodically find reachable objects from roots; free the rest .NET, Java, JavaScript, Go Pauses, extra memory Ownership/borrowing Compiler enforces single owner Rust Learning curve Tracing GC in short (what .NET does): 1. Roots — stack references, static fields, CPU registers, GC handles. 2. Mark — follow references from roots; everything reached is alive. 3. Sweep/compact — free unreachable objects; move live ones together to remove gaps (fragmentation) and update references. 4. Generations — new objects die young, so the GC checks young objects often (cheap) and old ones rarely. The full .NET details (generations 0/1/2, Large Object Heap, workstation vs server GC, IDisposable , finalizers) are in the .NET Internals course."},{"kind":"lesson","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"what-the-operating-system-does","title":"What the operating system does","body":"The OS kernel sits between programs and hardware: Job What it means --- --- Process management Create/stop processes, schedule threads on CPU cores Memory management Virtual memory, paging, protection File system Files, folders, permissions (NTFS, ext4) Device drivers & I/O Disk, network, USB, GPU Networking TCP/IP stack, sockets Security Users, permissions, isolation User mode vs kernel mode: your code runs in user mode; when it needs the OS (read a file, send a packet, allocate pages) it makes a system call , the CPU switches to kernel mode, the kernel does the work and returns. System calls are relatively expensive — that's why buffering (reading 64 KB at once instead of one byte at a time) matters."},{"kind":"lesson","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"processes-vs-threads-scheduling-and-context-switches","title":"Processes vs threads, scheduling and context switches","body":"Process Thread --- --- --- What A running program with its own address space and resources A path of execution inside a process Memory Isolated from other processes Shares the process heap with other threads; own stack and registers Creation cost High Lower (still ~1 MB stack reserved, kernel object) Communication IPC: pipes, sockets, shared memory, queues Shared variables (needs synchronisation) Crash impact Only that process Unhandled exception kills the whole process Scheduling: the OS gives each runnable thread a time slice on a core, then switches to another — a context switch (save registers, load another thread's state, cache gets colder). Thousands of threads → lots of switching overhead. That's why .NET uses a thread pool (reuse a small number of threads) and async/await (don't hold a thread while waiting for I/O). Thread states: new → ready → running → waiting/blocked (I/O, lock, sleep) → ready … → terminated. csharp // Process-level info from .NET var p = Process.GetCurrentProcess(); Console.WriteLine($\"PID {p.Id}, threads {p.Threads.Count}, working set {p.WorkingSet64 / 1 048 576} MB\"); Console.WriteLine($\"Cores: {Environment.ProcessorCount}\");"},{"kind":"lesson","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"concurrency-problems-race-conditions-deadlocks-and-how-to-avoid-them","title":"Concurrency problems — race conditions, deadlocks and how to avoid them","body":"Concurrency = several tasks in progress at once (may interleave on one core). Parallelism = tasks literally running at the same time on several cores. Problem What happens Fix --- --- --- Race condition Two threads read-modify-write shared data; updates get lost Locks, atomic operations ( Interlocked ), immutable data, don't share Deadlock Thread A holds lock 1 waiting for lock 2; B holds 2 waiting for 1 — both wait forever Always lock in the same order, use timeouts, keep locks short Starvation A thread never gets the resource Fair locks, priorities Livelock Threads keep reacting to each other without progress Back-off with randomness Thread-pool starvation All pool threads blocked (e.g. .Result on async) Async all the way csharp int counter = 0; Parallel.For(0, 1 000 000, = counter++); // ❌ race: result is less than 1,000,000 Console.WriteLine(counter); int safe = 0; Parallel.For(0, 1 000 000, = Interlocked.Increment(ref safe)); // ✅ atomic var gate = new object(); lock (gate) { / only one thread at a time here / } // ✅ mutual exclusion The same ideas appear in databases: SQL Server uses locks and isolation levels to stop concurrent transactions corrupting data, and can deadlock too (it then kills one transaction as the victim)."},{"kind":"lesson","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"compilers-interpreters-jit-and-aot","title":"Compilers, interpreters, JIT and AOT","body":"Model How Examples Trade-off --- --- --- --- Ahead-of-time compiled Source → machine code before running C, C++, Rust, Go, .NET Native AOT Fast start, platform-specific binary Interpreted Interpreter executes source/bytecode line by line Python (bytecode VM), classic JavaScript, PowerShell Portable, slower Bytecode + JIT Compile to intermediate code; at runtime compile hot methods to machine code .NET (IL → RyuJIT), Java (bytecode → HotSpot), JavaScript V8 Portable + fast after warm-up, startup cost Compiler stages: lexing (characters → tokens) → parsing (tokens → syntax tree) → semantic analysis (types, symbols) → optimisation → code generation. The C compiler Roslyn does these to produce IL; the JIT then turns IL into machine code for the actual CPU (x64 or ARM64), with tiered compilation (quick code first, optimised code for hot methods)."},{"kind":"lesson","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"putting-it-together-what-happens-when-your-dotnet-api-handles-a-request","title":"Putting it together — what happens when your .NET API handles a request","body":"1. The network card receives packets → OS TCP/IP stack reassembles them → data lands in a socket buffer (kernel memory). 2. Kestrel (ASP.NET Core server), waiting asynchronously on that socket, is woken by an I/O completion; a thread-pool thread picks up the work. 3. Bytes are parsed into an HttpContext (objects allocated on the heap ); middleware and your controller run — CPU executes JIT-compiled code, using stack frames for each method call. 4. Your code awaits a SQL query → the thread returns to the pool (no thread blocked); the request is sent through another socket to SQL Server. 5. SQL Server (its own process) checks its buffer pool in RAM ; if the pages aren't cached it reads them from disk (slow), executes the plan, returns rows. 6. The continuation runs on a pool thread, serialises JSON, writes to the socket; the OS sends packets back. 7. Objects of the request become unreachable → collected later by the GC (most die in generation 0, very cheaply). Every performance topic on DevLadder maps to one of these steps: CPU (algorithms), memory (allocations, GC), I/O (disk, database), network (latency, payload size), and threads (async, locking)."},{"kind":"question","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"1","title":"What is the difference between stack and heap memory?","body":"The stack holds method call frames — parameters, local value-type variables and references — per thread; allocation and cleanup are automatic and very fast (push/pop) but it is small (≈1 MB per thread). The heap holds objects created with new , shared by all threads, larger, and in .NET cleaned by the garbage collector. Stack overflow comes from too-deep recursion; heap problems are leaks and fragmentation."},{"kind":"question","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"2","title":"What is the difference between a process and a thread?","body":"A process is a running program with its own isolated virtual memory and resources. A thread is an execution path inside a process; threads of the same process share its heap and resources but each has its own stack and registers. Processes are isolated and heavier; threads are lighter but need synchronisation for shared data, and an unhandled exception in one thread kills the whole process."},{"kind":"question","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"3","title":"What is RAM and why is it faster than disk? What is a cache?","body":"RAM is volatile main memory accessed electronically in ~100 ns; SSDs take tens of microseconds and HDDs milliseconds because of slower technology (and seek mechanics for HDDs). A cache is a small, faster copy of frequently used data closer to where it's needed — CPU L1/L2/L3 caches over RAM, SQL Server's buffer pool over disk, Redis over a database. Caches work because of locality: recently or nearby used data is likely to be used again."},{"kind":"question","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"4","title":"What is the difference between 32-bit and 64-bit?","body":"The width of CPU registers and memory addresses. A 32-bit process can address at most 4 GB (often 2–3 GB usable); a 64-bit process can address terabytes. 64-bit also has more registers. In .NET, \"Any CPU\" assemblies run as 64-bit on a 64-bit OS; pointers/references are 8 bytes, so objects use a bit more memory."},{"kind":"question","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"5","title":"What are binary, hexadecimal, ASCII, UTF-8 and UTF-16?","body":"Binary is base 2 (how hardware stores data); hexadecimal is base 16, a compact way to write bytes ( 0xFF = 255). ASCII maps 128 characters to 7-bit codes. UTF-8 encodes all Unicode characters in 1–4 bytes and is backward-compatible with ASCII — the web standard. UTF-16 uses 2 or 4 bytes per character and is what .NET string and Windows APIs use internally."},{"kind":"question","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"6","title":"What is virtual memory?","body":"An OS + CPU mechanism that gives each process its own large, private address space, mapped page by page (usually 4 KB) to physical RAM or to disk (page file/swap). It isolates processes, lets programs use more memory than physically available, and loads pages lazily. Accessing a page not in RAM causes a page fault; heavy paging (thrashing) makes a system extremely slow."},{"kind":"question","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"7","title":"What is a race condition and how do you prevent it?","body":"When the result depends on the timing of threads accessing shared data, e.g. two threads doing count++ (read, add, write) and one update is lost. Prevent it with mutual exclusion ( lock , SemaphoreSlim ), atomic operations ( Interlocked ), thread-safe collections ( ConcurrentDictionary ), immutable data, or by not sharing state (message passing). In databases, transactions and isolation levels play the same role."},{"kind":"question","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"8","title":"What is a deadlock? How do you avoid it?","body":"Two or more threads (or transactions) each hold a resource the other needs and wait forever. Conditions: mutual exclusion, hold-and-wait, no preemption, circular wait. Avoid by acquiring locks in a consistent order, holding locks briefly, using timeouts ( Monitor.TryEnter , SemaphoreSlim.WaitAsync(timeout) ), and avoiding sync-over-async ( .Result ) in .NET. SQL Server detects deadlocks and kills one victim transaction."},{"kind":"question","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"9","title":"What is a context switch and why is it costly?","body":"The OS saving the state (registers, program counter, stack pointer) of a running thread and loading another's so it can run on that core. Costs: the switch itself, kernel transitions, and colder CPU caches/TLB afterwards. Too many threads → too much switching; hence thread pools and async I/O."},{"kind":"question","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"10","title":"Concurrency vs parallelism?","body":"Concurrency is dealing with many tasks at once (they make progress by interleaving, possibly on one core) — e.g. a web server handling many requests with async I/O. Parallelism is executing many tasks at the same instant on multiple cores — e.g. Parallel.For over CPU-heavy work. Async improves scalability for I/O-bound work; parallelism speeds up CPU-bound work."},{"kind":"question","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"11","title":"What is the difference between a compiler, an interpreter and a JIT?","body":"A compiler translates the whole program to machine code ahead of time (fast start, platform-specific). An interpreter executes code step by step at runtime (portable, slower). A JIT compiles intermediate code (IL/bytecode) to machine code at runtime when methods are first used, optimising hot code — .NET, Java and modern JavaScript engines combine portability with near-native speed after warm-up."},{"kind":"question","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"12","title":"Why is iterating an array faster than a linked list even though both are O(n)?","body":"Arrays store elements contiguously, so each 64-byte cache line brings several elements and the CPU prefetcher predicts the next access; linked-list nodes are scattered across the heap, so each step may be a cache miss costing ~100 ns. Big-O counts operations, not memory latency — cache locality often dominates real performance."},{"kind":"question","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"13","title":"What is a memory leak in a garbage-collected language?","body":"Memory that stays reachable even though the program no longer needs it, so the GC can't free it: static collections that only grow, event handlers never unsubscribed, caches without size limits/expiry, timers holding references, closures capturing big objects, or unmanaged resources not disposed. Find it with memory snapshots/dumps (dotnet-gcdump, Visual Studio, PerfView) and compare which object types grow."},{"kind":"question","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"14","title":"A server has 16 GB RAM but the app is very slow and disk activity is constantly 100%. What might be happening?","body":"Probably memory pressure and paging: processes (or SQL Server with no max memory limit, or a leaking app) use more than physical RAM, so the OS keeps swapping pages to disk (thrashing). Check memory usage per process, page faults/sec and page file usage; set SQL Server max server memory, fix leaks, reduce caching, or add RAM. Also check whether the disk activity is actually database reads due to missing indexes."},{"kind":"question","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"15","title":"A recursive method to process a folder tree crashes the process on a very deep structure. Why, and how do you fix it?","body":"Each recursive call adds a stack frame; very deep recursion exhausts the thread's stack (≈1 MB) and causes a StackOverflowException , which .NET can't catch — the process dies. Fix: rewrite iteratively using an explicit Stack<T / Queue<T on the heap, or limit depth. ( Directory.EnumerateFiles(..., SearchOption.AllDirectories) already does it iteratively.)"},{"kind":"question","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"16","title":"A multithreaded counter in your app gives a different result each run. Explain and fix.","body":"A race condition: counter++ is read-modify-write, so two threads can read the same value and both write back value+1, losing an increment. Fix with Interlocked.Increment(ref counter) , a lock , or by giving each thread its own local counter and summing at the end ( Parallel.For with thread-local state) — the last is also fastest."},{"kind":"cheat","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"1","title":"Speed ladder (approx.)","body":"Register < 1 ns · L1 ~1 ns · L3 ~10–20 ns · RAM ~100 ns · SSD ~50 µs · HDD ~5 ms · same-DC network ~0.5 ms · cross-continent ~150 ms."},{"kind":"cheat","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"2","title":"Stack vs heap","body":"Stack: per thread, frames, locals, fast, auto-freed, ~1 MB, overflow on deep recursion. Heap: shared, objects, GC-managed in .NET, leaks = still referenced."},{"kind":"cheat","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"3","title":"Process vs thread","body":"Process = own address space, isolated. Thread = path inside a process, shares heap, own stack. Context switch = save/restore thread state."},{"kind":"cheat","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"4","title":"Concurrency problems","body":"Race → lock / Interlocked / immutability. Deadlock → same lock order, short locks, timeouts, no .Result . Starvation → fair scheduling, async."},{"kind":"cheat","course_slug":"computer-fundamentals","course_title":"How Computers Work — CPU, Memory, OS, Processes and Threads","ref":"5","title":"Code to execution","body":"C → Roslyn → IL → JIT (tiered) → machine code; OS loads process, CLR manages memory with GC; I/O via system calls."},{"kind":"course","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"","title":"Data Structures & Algorithms — How They Work Inside","body":"Big-O and how to measure algorithms, arrays and dynamic arrays, linked lists, stacks and queues, hash tables (how hashing and collisions work), trees, binary search trees, heaps, tries, graphs, searching, sorting algorithms step by step, recursion, two pointers and sliding window, greedy, dynamic programming and backtracking — with C code and where .NET and SQL Server use each one. A data structure is a way to organise data in memory; an algorithm is a step-by-step procedure to solve a problem using it. The right choice is the difference between a page that loads in 50 ms and one that times out. Need Data structure .NET type Used inside --- --- --- --- Ordered list, index access Dynamic array List<T , T[] Almost everything Fast lookup by key Hash table Dictionary<K,V , HashSet<T Caches, EF Core change tracker, ASP.NET routing tables Last-in-first-out Stack Stack<T Call stack, undo, expression parsing First-in-first-out Queue Queue<T , Channel<T Thread pool work queue, message queues Sorted data, range queries Balanced tree / B-tree SortedDictionary (red-black tree), SortedSet SQL Server indexes (B+ trees) , file systems Smallest/largest first Heap PriorityQueue<T,P Schedulers, Dijkstra, top-K Prefix search Trie — (custom) Autocomplete, routers Relationships Graph adjacency lists Social networks, maps, dependency resolution (DI containers, NuGet) Year Milestone --- --- ~300 BC Euclid's algorithm for greatest common divisor 1945–1960s Merge sort (von Neumann, 1945), binary search, hash tables (1953), quicksort (Hoare, 1959), Dijkstra's shortest path (1956/59), heapsort (1964) 1970s B-trees (Bayer & McCreight, 1970) — the basis of database indexes; red-black trees (1972/1978); Knuth's The Art of Computer Programming 1990s–2000s Skip lists, consistent hashing (distributed caches), MapReduce 2002 Timsort (Python; later Java) 2010s .NET's Array.Sort uses introsort (quicksort + heapsort + insertion sort) 2021 .NET 6 adds PriorityQueue<TElement, TPriority How to solve an algorithm problem (interview or real work): 1. Understand — restate the problem, inputs, outputs, constraints (n up to 10⁵? sorted? duplicates? negative numbers?). 2. Examples — work through a small case by hand, including edge cases (empty, one element, all same). 3. Brute force — say the simplest solution and its complexity. 4. Optimise — look for a better data structure (hash map, heap, sorting first) or pattern (two pointers, sliding window, BFS, DP). 5. Code — clean, with meaningful names. 6. Test — run your examples and edge cases through the code. 7. Analyse — state time and space complexity; mention trade-offs. - Practice: LeetCode, HackerRank, Codility (used by many companies' online tests), GeeksforGeeks, Exercism (C track). - Visualise: visualgo.net, Python Tutor (pythontutor.com supports several languages), USFCA data-structure visualisations. - Measure: BenchmarkDotNet, Stopwatch , Visual Studio profiler. - Reference: Introduction to Algorithms (CLRS), Grokking Algorithms , the Coding Round Practice course on DevLadder for C solutions."},{"kind":"lesson","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"big-o-notation-time-and-space-complexity","title":"Big-O notation — time and space complexity","body":"Big-O describes how the running time (or memory) grows as the input size n grows, ignoring constants. Big-O Name Example n = 1,000,000 → roughly --- --- --- --- O(1) Constant Array index, dictionary lookup 1 step O(log n) Logarithmic Binary search, B-tree index seek 20 steps O(n) Linear Loop over a list, table scan 1,000,000 O(n log n) Linearithmic Good sorting (merge, heap, quick average) 20,000,000 O(n²) Quadratic Nested loops over the same data, bubble sort 10¹² — too slow O(2ⁿ) Exponential All subsets, naive Fibonacci impossible O(n!) Factorial All permutations impossible csharp bool ContainsDuplicate N2(int[] a) // O(n²) time, O(1) space { for (int i = 0; i < a.Length; i++) for (int j = i + 1; j < a.Length; j++) if (a[i] == a[j]) return true; return false; } bool ContainsDuplicate N(int[] a) // O(n) time, O(n) space — trade memory for speed { var seen = new HashSet<int (); foreach (var x in a) if (!seen.Add(x)) return true; return false; } Rules: drop constants (O(2n) → O(n)); keep the dominant term (O(n² + n) → O(n²)); different inputs get different letters (O(a + b), O(a × b)); amortised O(1) means usually O(1), occasionally more (e.g. List<T .Add when it must grow). Best / average / worst case: quicksort is O(n log n) on average but O(n²) in the worst case; hash lookups are O(1) average, O(n) worst (all keys collide)."},{"kind":"lesson","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"arrays-and-dynamic-arrays-how-list-t-grows","title":"Arrays and dynamic arrays (how List<T> grows)","body":"An array is a contiguous block of memory: element i is at start + i × elementSize , so index access is O(1) and iteration is cache-friendly. Size is fixed. A dynamic array ( List<T ) wraps an array and grows when full: text Capacity 4: [a][b][c][d] Add(e) → no room Allocate capacity 8, copy 4 items: [a][b][c][d][e][ ][ ][ ] Doubling makes Add amortised O(1) : n adds cost about 2n copies in total. Operation Array / List<T --- --- Get/set by index O(1) Add at end O(1) amortised Insert/remove at start or middle O(n) — shift elements Search unsorted O(n) Search sorted (binary search) O(log n) csharp var list = new List<int (capacity: 10 000); // pre-size when you know the count → no re-allocations"},{"kind":"lesson","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"linked-lists-stacks-and-queues","title":"Linked lists, stacks and queues","body":"Linked list: nodes scattered in memory, each pointing to the next (and previous, in a doubly linked list). csharp public class Node<T (T value) { public T Value = value; public Node<T ? Next; } Node<int ? Reverse(Node<int ? head) // classic interview question — O(n) time, O(1) space { Node<int ? prev = null; while (head != null) { var next = head.Next; head.Next = prev; // flip the pointer prev = head; head = next; } return prev; } Array/List Linked list --- --- --- Index access O(1) O(n) Insert/delete at a known node O(n) shift O(1) relink Memory Compact, cache-friendly Extra pointer per node, cache misses Stack (LIFO) and queue (FIFO) are usually built on arrays (circular buffer for queues): csharp bool IsBalanced(string s) // stack: matching brackets { var stack = new Stack<char (); var pairs = new Dictionary<char, char { [')'] = '(', [']'] = '[', ['}'] = '{' }; foreach (char c in s) { if (c is '(' or '[' or '{') stack.Push(c); else if (pairs.TryGetValue(c, out var open) && (stack.Count == 0 stack.Pop() != open)) return false; } return stack.Count == 0; } The call stack is literally a stack of frames; recursion uses it, which is why deep recursion overflows it."},{"kind":"lesson","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"hash-tables-how-dictionary-works-inside","title":"Hash tables — how Dictionary works inside","body":"A hash table maps a key to a slot (\"bucket\") using a hash function : text key \"pen\" → GetHashCode() = 193410 → 193410 % 8 buckets = bucket 2 → entry (\"pen\", 10) Steps for dict[\"pen\"] : 1. Compute hash = key.GetHashCode() . 2. bucket = hash % bucketCount . 3. Walk the entries in that bucket comparing hashes and then Equals until found. Collisions (two keys in the same bucket) are inevitable. Strategies: chaining (each bucket holds a small list — .NET Dictionary uses chaining through an entries array) or open addressing (probe the next free slot). When the table fills up (load factor), it resizes to a larger prime size and re-hashes everything — O(n) once, amortised O(1). Why Equals and GetHashCode must agree: if two equal keys produce different hashes, they land in different buckets and lookups fail. If a key's hash changes after insertion (mutable key), the entry becomes unreachable. csharp public record ProductKey(string Sku, int Warehouse); // records implement value-based Equals/GetHashCode var stock = new Dictionary<ProductKey, int { [new(\"PEN-1\", 3)] = 50 }; Console.WriteLine(stock[new(\"PEN-1\", 3)]); // 50 — found because equal keys hash equally Classic use — two-sum in O(n) : csharp int[] TwoSum(int[] nums, int target) { var seen = new Dictionary<int, int (); // value → index for (int i = 0; i < nums.Length; i++) { if (seen.TryGetValue(target - nums[i], out int j)) return [j, i]; seen[nums[i]] = i; } return []; }"},{"kind":"lesson","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"trees-binary-search-trees-and-traversals","title":"Trees, binary search trees and traversals","body":"A tree is nodes connected parent → children with no cycles. A binary search tree (BST) keeps left < node < right , so search, insert and delete are O(height): O(log n) when balanced, O(n) when it degenerates into a line (inserting sorted data). csharp public class TreeNode(int val) { public int Val = val; public TreeNode? Left, Right; } bool Contains(TreeNode? n, int x) = n != null && (x == n.Val (x < n.Val ? Contains(n.Left, x) : Contains(n.Right, x))); void InOrder(TreeNode? n, List<int output) // left, node, right → sorted order for a BST { if (n == null) return; InOrder(n.Left, output); output.Add(n.Val); InOrder(n.Right, output); } int Height(TreeNode? n) = n == null ? 0 : 1 + Math.Max(Height(n.Left), Height(n.Right)); List<List<int LevelOrder(TreeNode? root) // BFS with a queue { var result = new List<List<int (); if (root == null) return result; var q = new Queue<TreeNode ([root]); while (q.Count 0) { var level = new List<int (); for (int size = q.Count; size 0; size--) { var n = q.Dequeue(); level.Add(n.Val); if (n.Left != null) q.Enqueue(n.Left); if (n.Right != null) q.Enqueue(n.Right); } result.Add(level); } return result; } Traversals: pre-order (node, left, right — copy a tree), in-order (sorted output), post-order (children first — delete a tree, evaluate expressions), level-order/BFS . Balanced trees keep height O(log n) automatically: AVL, red-black (.NET SortedDictionary / SortedSet ), and B-trees/B+ trees — very wide trees (hundreds of keys per node) designed for disks. SQL Server indexes are B+ trees : an index seek on a table of 10 million rows touches only 3–4 pages (root → intermediate → leaf)."},{"kind":"lesson","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"heaps-and-priority-queues-tries","title":"Heaps and priority queues, tries","body":"A binary heap is a complete binary tree stored in an array where every parent ≤ its children (min-heap). The smallest item is always at index 0. Operation Cost --- --- Peek min O(1) Insert (bubble up) O(log n) Remove min (move last to top, sift down) O(log n) Build from n items O(n) Array layout: children of index i are at 2i+1 and 2i+2 , parent at (i−1)/2 — no pointers needed. csharp // Top-K largest numbers in O(n log k) with a min-heap of size k int[] TopK(int[] nums, int k) { var heap = new PriorityQueue<int, int (); foreach (var n in nums) { heap.Enqueue(n, n); if (heap.Count k) heap.Dequeue(); // drop the smallest } return heap.UnorderedItems.Select(x = x.Element).ToArray(); } A trie (prefix tree) stores strings character by character; finding all words with a prefix costs O(length of prefix) — autocomplete and routing tables. csharp public class Trie { private sealed class Node { public Dictionary<char, Node Next = []; public bool End; } private readonly Node root = new(); public void Insert(string word) { var node = root; foreach (var c in word) { if (!node.Next.TryGetValue(c, out var child)) node.Next[c] = child = new Node(); node = child; } node.End = true; } public bool StartsWith(string prefix) { var node = root; foreach (var c in prefix) { if (!node.Next.TryGetValue(c, out var child)) return false; node = child; } return true; } }"},{"kind":"lesson","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"graphs-bfs-dfs-and-shortest-paths","title":"Graphs — BFS, DFS and shortest paths","body":"A graph is vertices connected by edges (directed or undirected, weighted or not). Store it as an adjacency list ( Dictionary<int, List<int ) — memory O(V + E). csharp // BFS: shortest path in an unweighted graph (fewest hops) int ShortestHops(Dictionary<int, List<int g, int start, int goal) { var dist = new Dictionary<int, int { [start] = 0 }; var q = new Queue<int ([start]); while (q.Count 0) { int u = q.Dequeue(); if (u == goal) return dist[u]; foreach (int v in g.GetValueOrDefault(u, [])) if (dist.TryAdd(v, dist[u] + 1)) q.Enqueue(v); } return -1; } // DFS: count islands in a grid (connected components) int Islands(char[][] grid) { int count = 0; void Sink(int r, int c) { if (r < 0 c < 0 r = grid.Length c = grid[0].Length grid[r][c] != '1') return; grid[r][c] = '0'; Sink(r + 1, c); Sink(r - 1, c); Sink(r, c + 1); Sink(r, c - 1); } for (int r = 0; r < grid.Length; r++) for (int c = 0; c < grid[0].Length; c++) if (grid[r][c] == '1') { count++; Sink(r, c); } return count; } Algorithm Solves Complexity --- --- --- BFS Shortest path (unweighted), level by level O(V + E) DFS Connectivity, cycle detection, paths, backtracking O(V + E) Dijkstra (with a heap) Shortest path with non-negative weights (maps, routing) O((V + E) log V) Topological sort Order tasks with dependencies (build systems, DI, course prerequisites) O(V + E) Union-Find Grouping/connected components quickly ~O(1) per operation"},{"kind":"lesson","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"binary-search-and-how-sorting-algorithms-work","title":"Binary search and how sorting algorithms work","body":"Binary search — on sorted data, halve the range each step: O(log n). csharp int BinarySearch(int[] a, int target) { int lo = 0, hi = a.Length - 1; while (lo <= hi) { int mid = lo + (hi - lo) / 2; // avoids int overflow of (lo + hi) if (a[mid] == target) return mid; if (a[mid] < target) lo = mid + 1; else hi = mid - 1; } return -1; } Sorting algorithms: Algorithm Idea Best / Avg / Worst Space Stable --- --- --- --- --- Bubble Swap adjacent out-of-order pairs repeatedly n / n² / n² 1 Yes Selection Pick the minimum, put it in front n² / n² / n² 1 No Insertion Insert each item into the sorted left part n / n² / n² 1 Yes — great for small/nearly sorted Merge Split in halves, sort each, merge n log n (all) n Yes Quick Pick a pivot, partition smaller/larger, recurse n log n / n log n / n² log n No Heap Build a heap, extract max repeatedly n log n (all) 1 No Counting/Radix Count occurrences of small integer keys n + k n + k Yes csharp void QuickSort(int[] a, int lo, int hi) { if (lo = hi) return; int pivot = a[(lo + hi) / 2], i = lo, j = hi; while (i <= j) { while (a[i] < pivot) i++; while (a[j] pivot) j--; if (i <= j) { (a[i], a[j]) = (a[j], a[i]); i++; j--; } } QuickSort(a, lo, j); QuickSort(a, i, hi); } int[] MergeSort(int[] a) { if (a.Length <= 1) return a; var left = MergeSort(a[..(a.Length / 2)]); var right = MergeSort(a[(a.Length / 2)..]); var result = new int[a.Length]; int l = 0, r = 0, k = 0; while (l < left.Length && r < right.Length) result[k++] = left[l] <= right[r] ? left[l++] : right[r++]; while (l < left.Length) result[k++] = left[l++]; while (r < right.Length) result[k++] = right[r++]; return result; } In practice: Array.Sort / List.Sort use introsort (quicksort, switching to heapsort if recursion gets too deep and insertion sort for small parts — unstable); LINQ OrderBy is a stable sort. SQL Server sorts in memory or spills to tempdb when the memory grant is too small."},{"kind":"lesson","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"recursion-two-pointers-and-sliding-window","title":"Recursion, two pointers and sliding window","body":"Recursion = a function calling itself with a smaller input until a base case . Every recursion uses stack space; convert to iteration when depth may be large. csharp long Factorial(int n) = n <= 1 ? 1 : n Factorial(n - 1); Two pointers — walk from both ends or at two speeds, O(n) instead of O(n²): csharp bool IsPalindrome(string s) { int i = 0, j = s.Length - 1; while (i < j) { if (!char.IsLetterOrDigit(s[i])) { i++; continue; } if (!char.IsLetterOrDigit(s[j])) { j--; continue; } if (char.ToLowerInvariant(s[i++]) != char.ToLowerInvariant(s[j--])) return false; } return true; } // Fast/slow pointers detect a cycle in a linked list (Floyd's algorithm). Sliding window — maintain a window over a sequence and move its edges: csharp int LongestUniqueSubstring(string s) // \"abcabcbb\" → 3 { var lastSeen = new Dictionary<char, int (); int best = 0, start = 0; for (int end = 0; end < s.Length; end++) { if (lastSeen.TryGetValue(s[end], out int prev) && prev = start) start = prev + 1; lastSeen[s[end]] = end; best = Math.Max(best, end - start + 1); } return best; } Other patterns: prefix sums (range sums in O(1)), binary search on the answer, monotonic stack (next greater element), intervals (sort by start, merge)."},{"kind":"lesson","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"greedy-dynamic-programming-and-backtracking","title":"Greedy, dynamic programming and backtracking","body":"Greedy — make the locally best choice each step; works when that provably leads to the global best (activity selection, coin change with standard coins, Dijkstra, Huffman coding). Dynamic programming (DP) — the problem has overlapping subproblems and optimal substructure ; store answers to subproblems instead of recomputing. csharp // Fibonacci: naive recursion O(2ⁿ) → DP O(n) long Fib(int n) { if (n < 2) return n; long a = 0, b = 1; for (int i = 2; i <= n; i++) (a, b) = (b, a + b); return b; } // Coin change: fewest coins to make an amount (bottom-up table) int MinCoins(int[] coins, int amount) { var dp = new int[amount + 1]; Array.Fill(dp, int.MaxValue); dp[0] = 0; for (int x = 1; x <= amount; x++) foreach (int c in coins) if (c <= x && dp[x - c] != int.MaxValue) dp[x] = Math.Min(dp[x], dp[x - c] + 1); return dp[amount] == int.MaxValue ? -1 : dp[amount]; } Approach: define the state ( dp[i] = answer for the first i items/amount i), the transition (how dp[i] uses smaller states), base cases, and the order of filling. Top-down = recursion + memo ( Dictionary cache); bottom-up = table. Backtracking — build candidates step by step and undo choices that can't lead to a solution (permutations, subsets, N-Queens, Sudoku): csharp List<List<int Subsets(int[] nums) { var result = new List<List<int (); void Go(int i, List<int current) { if (i == nums.Length) { result.Add([.. current]); return; } Go(i + 1, current); // skip nums[i] current.Add(nums[i]); Go(i + 1, current); current.RemoveAt(current.Count - 1); // take it, then undo } Go(0, []); return result; }"},{"kind":"question","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"17","title":"What is Big-O notation? Give examples.","body":"It describes how an algorithm's time or memory grows with input size n, ignoring constants and smaller terms. O(1) dictionary lookup, O(log n) binary search, O(n) one loop, O(n log n) good sorts, O(n²) nested loops over the same data, O(2ⁿ) all subsets. It lets you predict whether a solution scales — e.g. O(n²) on a million items is ~10¹² operations, too slow."},{"kind":"question","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"18","title":"Array vs linked list — when do you use each?","body":"Arrays (and List<T ) store elements contiguously: O(1) index access, cache-friendly iteration, but O(n) inserts/removes in the middle. Linked lists store nodes with pointers: O(1) insert/remove at a known node, but O(n) access by position and poor cache locality. In practice List<T wins most of the time; linked lists suit frequent middle insertions with a node reference (LRU caches pair a linked list with a dictionary)."},{"kind":"question","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"19","title":"How does a hash table (Dictionary) work?","body":"It computes the key's hash code, maps it to a bucket ( hash % size ), and stores the entry there; lookups recompute the hash, go to the bucket and compare with Equals . Collisions are handled by chaining or probing; when the load factor grows, it resizes and rehashes. Average O(1) insert/lookup/delete, worst O(n) if many keys collide. Keys must have consistent Equals / GetHashCode and shouldn't change while stored."},{"kind":"question","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"20","title":"Stack vs queue — examples of where each is used?","body":"Stack is LIFO: function call stack, undo/redo, browser back button, expression evaluation, DFS. Queue is FIFO: print jobs, request/message queues, thread-pool work items, BFS. Both have O(1) push/pop or enqueue/dequeue."},{"kind":"question","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"21","title":"Explain binary search. What is required to use it?","body":"The data must be sorted. Compare the target with the middle element; if smaller, search the left half, otherwise the right half; repeat until found or the range is empty — O(log n). Compute the middle as lo + (hi - lo) / 2 to avoid overflow. Database index seeks work on the same principle over B-tree pages."},{"kind":"question","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"22","title":"Compare quicksort and merge sort.","body":"Both average O(n log n). Merge sort is always O(n log n), stable, but needs O(n) extra memory — good for linked lists and external sorting of huge data. Quicksort sorts in place (O(log n) stack), is usually faster in practice thanks to cache locality, but is O(n²) in the worst case with bad pivots and is not stable. .NET's Array.Sort uses introsort to avoid the worst case."},{"kind":"question","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"23","title":"What is a binary search tree? What happens if it becomes unbalanced?","body":"A binary tree where every node's left subtree has smaller keys and right subtree larger keys, so search/insert/delete follow one path: O(height). Balanced height is log n; inserting sorted data into a plain BST makes it a linked list with O(n) operations. Self-balancing trees (AVL, red-black) and B-trees keep the height logarithmic — SQL Server indexes are B+ trees."},{"kind":"question","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"24","title":"BFS vs DFS?","body":"BFS explores level by level using a queue — finds the shortest path in unweighted graphs, uses memory proportional to the widest level. DFS goes as deep as possible using recursion or a stack — good for connectivity, cycle detection, topological sort and backtracking, uses memory proportional to depth. Both are O(V + E)."},{"kind":"question","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"25","title":"What is dynamic programming? How is it different from recursion?","body":"DP solves problems with overlapping subproblems and optimal substructure by storing subproblem results (memoisation top-down, or a table bottom-up) so each is computed once. Plain recursion may recompute the same subproblem exponentially many times (naive Fibonacci O(2ⁿ) vs DP O(n)). Typical DP problems: coin change, knapsack, longest common subsequence, edit distance, climbing stairs."},{"kind":"question","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"26","title":"What is a heap and what is it used for?","body":"A complete binary tree stored in an array where each parent is smaller (min-heap) or larger (max-heap) than its children. Peek min/max O(1), insert and remove O(log n). Used for priority queues ( PriorityQueue<T,P ), scheduling, top-K problems, merging sorted streams, Dijkstra's algorithm and heapsort."},{"kind":"question","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"27","title":"What are greedy algorithms? When do they fail?","body":"They pick the locally best option at each step without revisiting. They are correct only when the problem has the greedy-choice property — e.g. activity selection, Dijkstra, Huffman coding. They fail on problems like coin change with arbitrary coins (coins 1, 3, 4 for amount 6: greedy gives 4+1+1, optimal is 3+3), where DP is needed."},{"kind":"question","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"28","title":"How does a B-tree differ from a binary search tree and why do databases use it?","body":"A B-tree node holds many keys and has many children (high fan-out), so the tree is very shallow — a few levels cover millions of rows. Each node maps to a disk/database page (8 KB in SQL Server), so a lookup reads only a handful of pages. B+ trees keep all data/rows at the leaf level and link leaves for fast range scans. Binary trees would be far deeper and cause many more page reads."},{"kind":"question","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"29","title":"How would you implement an LRU cache with O(1) operations?","body":"Combine a dictionary (key → linked-list node) with a doubly linked list ordered by recent use. Get: look up the node in the dictionary, move it to the front. Put: update/move to front, or insert at the front; if over capacity, remove the tail node and its dictionary entry. Both operations are O(1). In .NET, LinkedList<T + Dictionary<K, LinkedListNode<T ."},{"kind":"question","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"30","title":"A report compares two lists of 200,000 customer ids with nested loops and takes 20 minutes. Fix it.","body":"Nested loops are O(n × m) ≈ 4 × 10¹⁰ comparisons. Put one list into a HashSet<int (O(m)) and check each id of the other list with Contains (O(1) average) — O(n + m), milliseconds. Or sort both and merge with two pointers (O(n log n)), or let SQL do it with an indexed JOIN/EXISTS."},{"kind":"question","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"31","title":"An autocomplete box queries `WHERE Name LIKE '%term%'` on 5 million products and is slow. How would you improve it?","body":"A leading wildcard can't use a B-tree index, so every keystroke scans the table. Options: prefix search LIKE 'term%' on an indexed column (index seek), a trie or sorted in-memory list of names for prefix lookups, full-text search (SQL Server full-text index, Azure AI Search, Elasticsearch) for word matches, debounce keystrokes and limit to top 10, cache popular prefixes."},{"kind":"question","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"32","title":"You need the 10 most frequent error codes from 50 million log lines. What algorithm?","body":"Stream the lines once, counting with a Dictionary<string, int (O(n) time, O(k) memory for k distinct codes), then select the top 10 with a min-heap of size 10 (O(k log 10)) or sort the k entries. Don't load all lines into memory. For distributed data, count per partition and merge counts (map-reduce)."},{"kind":"cheat","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"1","title":"Complexity ladder","body":"O(1) < O(log n) < O(n) < O(n log n) < O(n²) < O(2ⁿ) < O(n!). For n = 10⁶: O(n log n) OK, O(n²) not."},{"kind":"cheat","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"2","title":"Pick the structure","body":"Index access → array/List · key lookup → Dictionary/HashSet · LIFO → Stack · FIFO → Queue · min/max fast → PriorityQueue · sorted + range → SortedDictionary / B-tree index · prefix → Trie · relationships → graph adjacency list."},{"kind":"cheat","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"3","title":"Sorting facts","body":"Merge: n log n always, stable, O(n) space. Quick: n log n avg, n² worst, in place. Heap: n log n, O(1) space. Insertion: great for tiny/nearly sorted. .NET Array.Sort = introsort (unstable); LINQ OrderBy = stable."},{"kind":"cheat","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"4","title":"Patterns","body":"Two pointers · sliding window · prefix sums · binary search (also on the answer) · BFS (shortest unweighted) · DFS/backtracking · heap for top-K · hash map for counting/lookups · DP for overlapping subproblems · greedy when locally optimal is globally optimal."},{"kind":"cheat","course_slug":"dsa","course_title":"Data Structures & Algorithms — How They Work Inside","ref":"5","title":"Interview method","body":"Clarify → examples → brute force + Big-O → optimise → code → test edge cases → state time/space."},{"kind":"course","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"","title":"Coding Round Practice (DSA in C#)","body":"Big-O, arrays, strings, hashing, two pointers, sliding window, stacks, linked lists, trees, sorting, searching, recursion and the most-asked C coding programs with solutions. Most .NET interviews include a coding round : 1–3 problems in 30–60 minutes, on a shared editor (CoderPad, HackerRank, Codility), on a whiteboard, or in Visual Studio over a screen share. Service companies ask classic programs (reverse a string, palindrome, Fibonacci, duplicates). Product companies ask LeetCode-style easy/medium problems (two sum, sliding window, trees). What interviewers score: 1. Clarifying the problem and edge cases before coding. 2. A working brute-force idea, then an optimised one. 3. Clean, compiling code with good names. 4. Testing with examples and edge cases out loud. 5. Stating time and space complexity . Algorithms don't have versions, but the C features you can use in a coding round do: Feature Since Useful for --- --- --- Generic collections List<T , Dictionary<K,V C 2.0 Everything LINQ C 3.0 Quick grouping/sorting HashSet<T .NET 3.5 Uniqueness / O(1) lookup Tuples + swap (a, b) = (b, a) C 7 Two pointers Ranges/indices s[^1] , s[1..3] C 8 Slicing PriorityQueue<TElement,TPriority .NET 6 Top-K, Dijkstra Collection expressions [1, 2, 3] C 12 Test data CountBy , AggregateBy , Index() LINQ .NET 9 Frequency counting How to solve a problem in an interview (UMPIRE): 1. Understand — restate the problem; ask about input size, nulls, duplicates, negative numbers, sorted or not. 2. Match — which pattern? (hash map, two pointers, sliding window, stack, BFS/DFS, binary search, DP) 3. Plan — say the brute force and its complexity, then the better approach. 4. Implement — write clean code; talk while typing. 5. Review — dry-run with a small example; check edge cases (empty, one element, all same). 6. Evaluate — state time/space complexity and possible improvements. - Visual Studio / VS Code / Rider with dotnet new console for practice. - LINQPad , dotnetfiddle.net , SharpLab — quick online/offline runners. - LeetCode, HackerRank, Codility, CodeSignal, GeeksforGeeks — practice platforms (HackerRank/Codility are often used by Indian service companies for online tests). - NeetCode 150 / Blind 75 — curated problem lists by pattern. - BenchmarkDotNet — compare approaches. - xUnit — write tests for your own solutions."},{"kind":"lesson","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"big-o-notation","title":"Big-O notation","body":"Big-O describes how time or memory grows as input size n grows (worst case, ignoring constants). Big-O Name Example --- --- --- O(1) Constant Array index, dictionary lookup (average) O(log n) Logarithmic Binary search, balanced BST O(n) Linear Single loop, linear search O(n log n) Linearithmic Merge sort, Array.Sort (introsort) O(n²) Quadratic Nested loops, bubble sort O(2ⁿ) Exponential Naive recursive Fibonacci, all subsets O(n!) Factorial All permutations C collection costs: List<T .Add amortised O(1), Insert(0) O(n), Contains O(n); Dictionary / HashSet add/lookup O(1) average; SortedDictionary O(log n); Array.Sort / List.Sort O(n log n). Interview tip: always state both time and space complexity, e.g. \"O(n) time, O(n) extra space for the dictionary.\""},{"kind":"lesson","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"string-programs","title":"String programs","body":"csharp // 1. Reverse a string (without Array.Reverse) static string Reverse(string s) { var chars = s.ToCharArray(); for (int i = 0, j = chars.Length - 1; i < j; i++, j--) (chars[i], chars[j]) = (chars[j], chars[i]); return new string(chars); } // 2. Palindrome (ignore case and non-alphanumerics) — two pointers, O(n) time, O(1) space static bool IsPalindrome(string s) { int i = 0, j = s.Length - 1; while (i < j) { if (!char.IsLetterOrDigit(s[i])) { i++; continue; } if (!char.IsLetterOrDigit(s[j])) { j--; continue; } if (char.ToLowerInvariant(s[i]) != char.ToLowerInvariant(s[j])) return false; i++; j--; } return true; } // 3. Count each character static Dictionary<char, int CharCount(string s) { var counts = new Dictionary<char, int (); foreach (var c in s) counts[c] = counts.GetValueOrDefault(c) + 1; return counts; } // 4. First non-repeating character static char? FirstUnique(string s) { var counts = CharCount(s); foreach (var c in s) if (counts[c] == 1) return c; return null; } // 5. Anagram check — O(n) with a count array for lowercase letters static bool IsAnagram(string a, string b) { if (a.Length != b.Length) return false; var count = new int[26]; for (int i = 0; i < a.Length; i++) { count[a[i] - 'a']++; count[b[i] - 'a']--; } return count.All(c = c == 0); } // 6. Reverse words in a sentence static string ReverseWords(string s) = string.Join(' ', s.Split(' ', StringSplitOptions.RemoveEmptyEntries).Reverse()); // 7. Count vowels static int Vowels(string s) = s.Count(c = \"aeiouAEIOU\".Contains(c));"},{"kind":"lesson","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"number-programs","title":"Number programs","body":"csharp // Fibonacci — iterative O(n) time, O(1) space static long Fib(int n) { if (n < 2) return n; long a = 0, b = 1; for (int i = 2; i <= n; i++) (a, b) = (b, a + b); return b; } // Prime check — O(√n) static bool IsPrime(int n) { if (n < 2) return false; if (n % 2 == 0) return n == 2; for (int i = 3; i i <= n; i += 2) if (n % i == 0) return false; return true; } // Factorial — recursive and iterative static long Fact(int n) = n <= 1 ? 1 : n Fact(n - 1); // Swap without temp int x = 5, y = 9; (x, y) = (y, x); // tuple swap (or x ^= y; y ^= x; x ^= y;) // Armstrong number (153 = 1³ + 5³ + 3³) static bool IsArmstrong(int n) { var digits = n.ToString(); return digits.Sum(d = (int)Math.Pow(d - '0', digits.Length)) == n; } // FizzBuzz for (int i = 1; i <= 15; i++) Console.WriteLine(i % 15 == 0 ? \"FizzBuzz\" : i % 3 == 0 ? \"Fizz\" : i % 5 == 0 ? \"Buzz\" : i.ToString()); // GCD (Euclid) and LCM static int Gcd(int a, int b) = b == 0 ? a : Gcd(b, a % b); static int Lcm(int a, int b) = a / Gcd(a, b) b;"},{"kind":"lesson","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"array-programs","title":"Array programs","body":"csharp // Second largest (distinct) — single pass O(n) static int? SecondLargest(int[] a) { int? first = null, second = null; foreach (var n in a) { if (first is null n first) { second = first; first = n; } else if (n != first && (second is null n second)) second = n; } return second; } // Find duplicates — HashSet O(n) static List<int Duplicates(int[] a) { var seen = new HashSet<int (); var dups = new HashSet<int (); foreach (var n in a) if (!seen.Add(n)) dups.Add(n); return dups.ToList(); } // Missing number in 1..n — sum formula O(n), O(1) space static int Missing(int[] a, int n) = n (n + 1) / 2 - a.Sum(); // Move zeros to the end keeping order — O(n), in place static void MoveZeros(int[] a) { int write = 0; foreach (var n in a) if (n != 0) a[write++] = n; while (write < a.Length) a[write++] = 0; } // Rotate array right by k — reverse trick O(n), O(1) static void Rotate(int[] a, int k) { k %= a.Length; Array.Reverse(a); Array.Reverse(a, 0, k); Array.Reverse(a, k, a.Length - k); } // Merge two sorted arrays — O(n + m) static int[] Merge(int[] x, int[] y) { var r = new int[x.Length + y.Length]; int i = 0, j = 0, k = 0; while (i < x.Length && j < y.Length) r[k++] = x[i] <= y[j] ? x[i++] : y[j++]; while (i < x.Length) r[k++] = x[i++]; while (j < y.Length) r[k++] = y[j++]; return r; }"},{"kind":"lesson","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"hash-map-pattern-two-sum-frequency-grouping","title":"Hash map pattern — Two Sum, frequency, grouping","body":"csharp // Two Sum — O(n) time, O(n) space static (int, int)? TwoSum(int[] nums, int target) { var index = new Dictionary<int, int (); // value - index for (int i = 0; i < nums.Length; i++) { if (index.TryGetValue(target - nums[i], out var j)) return (j, i); index[nums[i]] = i; } return null; } // Group anagrams static IEnumerable<List<string GroupAnagrams(string[] words) = words.GroupBy(w = new string(w.OrderBy(c = c).ToArray())).Select(g = g.ToList()); // Top K frequent elements — PriorityQueue (.NET 6+) static int[] TopK(int[] nums, int k) { var freq = nums.CountBy(n = n); // .NET 9; or GroupBy var pq = new PriorityQueue<int, int (); // min-heap by frequency foreach (var (num, count) in freq) { pq.Enqueue(num, count); if (pq.Count k) pq.Dequeue(); } var result = new int[pq.Count]; for (int i = result.Length - 1; i = 0; i--) result[i] = pq.Dequeue(); return result; }"},{"kind":"lesson","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"two-pointers-and-sliding-window","title":"Two pointers and sliding window","body":"csharp // Pair with sum in a SORTED array — two pointers O(n) static bool HasPair(int[] sorted, int target) { int l = 0, r = sorted.Length - 1; while (l < r) { int sum = sorted[l] + sorted[r]; if (sum == target) return true; if (sum < target) l++; else r--; } return false; } // Longest substring without repeating characters — sliding window O(n) static int LongestUnique(string s) { var last = new Dictionary<char, int (); int best = 0, start = 0; for (int i = 0; i < s.Length; i++) { if (last.TryGetValue(s[i], out var prev) && prev = start) start = prev + 1; last[s[i]] = i; best = Math.Max(best, i - start + 1); } return best; } // Maximum subarray sum — Kadane's algorithm O(n) static int MaxSubArray(int[] a) { int best = a[0], current = a[0]; for (int i = 1; i < a.Length; i++) { current = Math.Max(a[i], current + a[i]); best = Math.Max(best, current); } return best; } // Max sum of any window of size k — fixed sliding window static int MaxWindow(int[] a, int k) { int sum = a.Take(k).Sum(), best = sum; for (int i = k; i < a.Length; i++) { sum += a[i] - a[i - k]; best = Math.Max(best, sum); } return best; }"},{"kind":"lesson","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"stack-problems","title":"Stack problems","body":"csharp // Valid parentheses — O(n) static bool IsValid(string s) { var stack = new Stack<char (); var pairs = new Dictionary<char, char { [')'] = '(', [']'] = '[', ['}'] = '{' }; foreach (var c in s) { if (pairs.ContainsValue(c)) stack.Push(c); else if (pairs.TryGetValue(c, out var open)) { if (stack.Count == 0 stack.Pop() != open) return false; } } return stack.Count == 0; } // Next greater element — monotonic stack O(n) static int[] NextGreater(int[] a) { var result = Enumerable.Repeat(-1, a.Length).ToArray(); var stack = new Stack<int (); // indexes waiting for a greater value for (int i = 0; i < a.Length; i++) { while (stack.Count 0 && a[stack.Peek()] < a[i]) result[stack.Pop()] = a[i]; stack.Push(i); } return result; }"},{"kind":"lesson","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"linked-list-problems","title":"Linked list problems","body":"csharp public class Node(int value) { public int Value = value; public Node? Next; } // Reverse a linked list — iterative O(n), O(1) static Node? Reverse(Node? head) { Node? prev = null; while (head is not null) { var next = head.Next; head.Next = prev; prev = head; head = next; } return prev; } // Detect a cycle — Floyd's slow/fast pointers static bool HasCycle(Node? head) { Node? slow = head, fast = head; while (fast?.Next is not null) { slow = slow!.Next; fast = fast.Next.Next; if (slow == fast) return true; } return false; } // Middle node — slow moves 1, fast moves 2 static Node? Middle(Node? head) { Node? slow = head, fast = head; while (fast?.Next is not null) { slow = slow!.Next; fast = fast.Next.Next; } return slow; }"},{"kind":"lesson","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"lru-cache-design-code","title":"LRU cache (design + code)","body":"Least Recently Used cache with O(1) Get and Put : a Dictionary for lookup + a doubly linked list for recency order. csharp public class LruCache<TKey, TValue (int capacity) where TKey : notnull { private readonly Dictionary<TKey, LinkedListNode<(TKey Key, TValue Value) map = new(); private readonly LinkedList<(TKey Key, TValue Value) list = new(); // front = most recent public bool TryGet(TKey key, out TValue value) { if ( map.TryGetValue(key, out var node)) { list.Remove(node); list.AddFirst(node); value = node.Value.Value; return true; } value = default!; return false; } public void Put(TKey key, TValue value) { if ( map.TryGetValue(key, out var existing)) list.Remove(existing); else if ( map.Count == capacity) { map.Remove( list.Last!.Value.Key); list.RemoveLast(); } map[key] = list.AddFirst((key, value)); } }"},{"kind":"lesson","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"binary-search","title":"Binary search","body":"csharp // O(log n) on a sorted array static int BinarySearch(int[] a, int target) { int lo = 0, hi = a.Length - 1; while (lo <= hi) { int mid = lo + (hi - lo) / 2; // avoids int overflow of (lo + hi) if (a[mid] == target) return mid; if (a[mid] < target) lo = mid + 1; else hi = mid - 1; } return -1; } // Built-in: Array.BinarySearch(a, target), List<T .BinarySearch"},{"kind":"lesson","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"sorting-algorithms","title":"Sorting algorithms","body":"Algorithm Best Average Worst Space Stable --- --- --- --- --- --- Bubble O(n) O(n²) O(n²) O(1) Yes Selection O(n²) O(n²) O(n²) O(1) No Insertion O(n) O(n²) O(n²) O(1) Yes Merge O(n log n) O(n log n) O(n log n) O(n) Yes Quick O(n log n) O(n log n) O(n²) O(log n) No Heap O(n log n) O(n log n) O(n log n) O(1) No .NET's Array.Sort / List.Sort use introsort (quicksort + heapsort + insertion sort) — O(n log n) worst case, not stable . LINQ OrderBy is stable . csharp // Bubble sort with early exit static void BubbleSort(int[] a) { for (int i = 0; i < a.Length - 1; i++) { bool swapped = false; for (int j = 0; j < a.Length - 1 - i; j++) if (a[j] a[j + 1]) { (a[j], a[j + 1]) = (a[j + 1], a[j]); swapped = true; } if (!swapped) break; } } // Quick sort (Lomuto partition) static void QuickSort(int[] a, int lo, int hi) { if (lo = hi) return; int pivot = a[hi], i = lo; for (int j = lo; j < hi; j++) if (a[j] < pivot) { (a[i], a[j]) = (a[j], a[i]); i++; } (a[i], a[hi]) = (a[hi], a[i]); QuickSort(a, lo, i - 1); QuickSort(a, i + 1, hi); } // Merge sort static int[] MergeSort(int[] a) { if (a.Length <= 1) return a; int mid = a.Length / 2; return Merge(MergeSort(a[..mid]), MergeSort(a[mid..])); // Merge from the arrays lesson }"},{"kind":"lesson","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"recursion-memoisation-and-dynamic-programming","title":"Recursion, memoisation and dynamic programming","body":"csharp // Naive Fibonacci is O(2^n); memoised is O(n) static long FibMemo(int n, Dictionary<int, long ? memo = null) { memo ??= new(); if (n < 2) return n; if (memo.TryGetValue(n, out var v)) return v; return memo[n] = FibMemo(n - 1, memo) + FibMemo(n - 2, memo); } // Climbing stairs (1 or 2 steps) — bottom-up DP, same recurrence as Fibonacci static int Climb(int n) { int a = 1, b = 1; for (int i = 2; i <= n; i++) (a, b) = (b, a + b); return b; } // Permutations of a string — backtracking static void Permute(string prefix, string rest, List<string output) { if (rest.Length == 0) { output.Add(prefix); return; } for (int i = 0; i < rest.Length; i++) Permute(prefix + rest[i], rest[..i] + rest[(i + 1)..], output); } Recursion needs a base case ; deep recursion can cause StackOverflowException , which cannot be caught in .NET — convert to iteration for large inputs."},{"kind":"lesson","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"binary-trees-and-bst","title":"Binary trees and BST","body":"csharp public class TreeNode(int val) { public int Val = val; public TreeNode? Left, Right; } // Depth-first traversals static void InOrder(TreeNode? n, List<int o) { if (n is null) return; InOrder(n.Left, o); o.Add(n.Val); InOrder(n.Right, o); } // BST → sorted static void PreOrder(TreeNode? n, List<int o) { if (n is null) return; o.Add(n.Val); PreOrder(n.Left, o); PreOrder(n.Right, o); } // Height / max depth static int Height(TreeNode? n) = n is null ? 0 : 1 + Math.Max(Height(n.Left), Height(n.Right)); // Level-order (BFS) with a queue static List<List<int Levels(TreeNode? root) { var result = new List<List<int (); if (root is null) return result; var q = new Queue<TreeNode (); q.Enqueue(root); while (q.Count 0) { var level = new List<int (); for (int size = q.Count; size 0; size--) { var n = q.Dequeue(); level.Add(n.Val); if (n.Left is not null) q.Enqueue(n.Left); if (n.Right is not null) q.Enqueue(n.Right); } result.Add(level); } return result; } // Validate BST using bounds static bool IsBst(TreeNode? n, long min = long.MinValue, long max = long.MaxValue) = n is null (n.Val min && n.Val < max && IsBst(n.Left, min, n.Val) && IsBst(n.Right, n.Val, max));"},{"kind":"lesson","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"graph-bfs-and-dfs","title":"Graph BFS and DFS","body":"csharp // Number of islands in a grid — DFS flood fill O(rows cols) static int Islands(char[][] g) { int count = 0; void Sink(int r, int c) { if (r < 0 c < 0 r = g.Length c = g[0].Length g[r][c] != '1') return; g[r][c] = '0'; Sink(r + 1, c); Sink(r - 1, c); Sink(r, c + 1); Sink(r, c - 1); } for (int r = 0; r < g.Length; r++) for (int c = 0; c < g[0].Length; c++) if (g[r][c] == '1') { count++; Sink(r, c); } return count; } // Shortest path in an unweighted graph — BFS static int ShortestPath(Dictionary<int, List<int graph, int from, int to) { var dist = new Dictionary<int, int { [from] = 0 }; var q = new Queue<int ([from]); while (q.Count 0) { var node = q.Dequeue(); if (node == to) return dist[node]; foreach (var next in graph.GetValueOrDefault(node, [])) if (dist.TryAdd(next, dist[node] + 1)) q.Enqueue(next); } return -1; }"},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"33","title":"Reverse a string without using built-in Reverse.","body":"Convert to a char[] , swap from both ends towards the middle with two pointers, then build a new string. O(n) time, O(n) space for the array (strings are immutable, so you can't do it in place). csharp static string Reverse(string s) { var c = s.ToCharArray(); for (int i = 0, j = c.Length - 1; i < j; i++, j--) (c[i], c[j]) = (c[j], c[i]); return new string(c); } Mention: for user-visible text with emoji or combining characters, use StringInfo text elements."},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"34","title":"Check whether a string is a palindrome.","body":"Two pointers from both ends, skip non-alphanumerics, compare case-insensitively. O(n) time, O(1) space. Simple version: s == new string(s.Reverse().ToArray()) , which is O(n) extra space. csharp static bool IsPal(string s) { for (int i = 0, j = s.Length - 1; i < j; i++, j--) if (char.ToLower(s[i]) != char.ToLower(s[j])) return false; return true; }"},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"35","title":"Print the Fibonacci series up to n terms.","body":"csharp long a = 0, b = 1; for (int i = 0; i < n; i++) { Console.Write($\"{a} \"); (a, b) = (b, a + b); } Iterative is O(n) time and O(1) space. Naive recursion F(n-1)+F(n-2) is O(2ⁿ) — mention memoisation if asked for recursion."},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"36","title":"Find duplicate elements in an array.","body":"Use a HashSet<int : Add returns false when the item already exists. O(n) time, O(n) space. LINQ alternative: arr.GroupBy(x = x).Where(g = g.Count() 1).Select(g = g.Key) . If O(1) space is required and the array can be modified: sort first (O(n log n)) and compare neighbours. csharp var seen = new HashSet<int (); var dups = arr.Where(x = !seen.Add(x)).Distinct().ToList();"},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"37","title":"Count the occurrences of each character in a string.","body":"csharp var counts = new Dictionary<char, int (); foreach (var c in s) counts[c] = counts.GetValueOrDefault(c) + 1; // LINQ: s.GroupBy(c = c).ToDictionary(g = g.Key, g = g.Count()); // .NET 9: s.CountBy(c = c) O(n) time, O(k) space where k = distinct characters."},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"38","title":"Find the second largest number in an array.","body":"Single pass tracking first and second (skip values equal to first if distinct values are needed). O(n), O(1). Sorting is simpler but O(n log n): arr.Distinct().OrderByDescending(x = x).Skip(1).First() . Clarify: what if all elements are the same or there's only one?"},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"39","title":"Check whether two strings are anagrams.","body":"Same length + same character counts. Use an int[26] count array (lowercase a–z) incrementing for one string and decrementing for the other — O(n) time, O(1) space. Or sort both and compare — O(n log n). For Unicode use a Dictionary<char,int ."},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"40","title":"Swap two numbers without a third variable.","body":"(a, b) = (b, a); in modern C . Classic answers: arithmetic a = a + b; b = a - b; a = a - b; (can overflow) or XOR a ^= b; b ^= a; a ^= b; (integers only)."},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"41","title":"Two Sum: return indexes of two numbers that add up to a target.","body":"Brute force: two loops, O(n²). Optimal: one pass with a Dictionary<value, index . For each number, check whether target - number was seen. O(n) time, O(n) space. If the array is sorted, use two pointers in O(1) space. csharp var seen = new Dictionary<int, int (); for (int i = 0; i < nums.Length; i++) { if (seen.TryGetValue(target - nums[i], out var j)) return [j, i]; seen[nums[i]] = i; }"},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"42","title":"Find the length of the longest substring without repeating characters.","body":"Sliding window: keep the last index of each character. When a repeat appears inside the window, move start past its previous position, and track the max window length. O(n) time, O(k) space. Example: \"abcabcbb\" → 3 (\"abc\")."},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"43","title":"Find the maximum subarray sum (Kadane's algorithm).","body":"At each element, either extend the current subarray or start fresh: cur = max(a[i], cur + a[i]) , and best = max(best, cur) . O(n) time, O(1) space. Works with all-negative arrays if you initialise with a[0] . Example: [-2,1,-3,4,-1,2,1,-5,4] → 6 ([4,-1,2,1])."},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"44","title":"Check for balanced parentheses.","body":"Push opening brackets on a Stack<char . For each closing bracket, the stack must be non-empty and the top must match. At the end the stack must be empty. O(n) time and space."},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"45","title":"Reverse a linked list.","body":"Iterate with three pointers: prev , current , next . Save next , point current.Next to prev , advance both. Return prev . O(n) time, O(1) space. Recursive version: O(n) stack space."},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"46","title":"Detect a loop in a linked list.","body":"Floyd's cycle detection: slow pointer moves one step, fast moves two. If they meet, there is a cycle; if fast reaches null, there isn't. O(n) time, O(1) space. To find the cycle start, reset one pointer to head and move both one step at a time until they meet. Alternative: a HashSet of visited nodes (O(n) space)."},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"47","title":"Implement binary search. What is its complexity?","body":"On a sorted array, compare with the middle element and discard half each time: O(log n) time, O(1) space iteratively. Compute mid = lo + (hi - lo) / 2 to avoid overflow. Variants: first/last occurrence, search in a rotated array, lower bound."},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"48","title":"What sorting algorithm does .NET use? Is it stable?","body":"Array.Sort and List<T .Sort use introspective sort (quicksort, switching to heapsort when recursion is too deep, and insertion sort for small partitions). It's O(n log n) worst case and not stable . Enumerable.OrderBy (LINQ) is a stable sort. Use LINQ when equal elements must keep their original order."},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"49","title":"Find the height of a binary tree and print it level by level.","body":"Height: recursive 1 + max(height(left), height(right)) , with null = 0. Level-order: BFS with a Queue , processing queue.Count nodes per level. Both are O(n). Space is O(h) for recursion and O(w) for the queue (h = height, w = max width)."},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"50","title":"Design and implement an LRU cache with O(1) get and put.","body":"Combine a Dictionary<key, LinkedListNode for O(1) lookup with a doubly LinkedList ordered by recency. On get: move the node to the front. On put: update and move to the front, or insert at the front. If over capacity, remove the last node and its dictionary entry. Thread safety: wrap in a lock or use per-key strategies. In production use MemoryCache with a size limit."},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"51","title":"Find the top K frequent elements.","body":"Count with a dictionary, O(n). Then either sort by count, O(n log n), or use a min-heap of size k ( PriorityQueue<int,int ), O(n log k). Bucket sort by frequency gives O(n). Discuss the trade-offs."},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"52","title":"Count the number of islands in a 2D grid.","body":"Scan the grid. When you find unvisited land ( '1' ), increment the count and flood-fill (DFS or BFS) to mark the whole island visited. O(rows × cols) time; recursion depth can reach rows × cols, so use an explicit stack or queue for big grids. Union-Find is an alternative."},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"53","title":"You are given 10 million log lines and must find the top 10 most frequent IP addresses with limited memory. How?","body":"If the distinct IPs fit in memory: stream the file line by line ( File.ReadLines ), count in a Dictionary<string,int , then keep a min-heap of size 10, O(n log 10). If not: partition by hash of the IP into N temp files so each file's distinct IPs fit in memory, count each file, and merge the per-file top-10s. For a stream with bounded error, use a Count-Min Sketch or the Space-Saving algorithm. In practice you'd load the data into SQL/Kusto and GROUP BY ... ORDER BY COUNT( ) DESC ."},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"54","title":"The interviewer says your O(n²) solution works — \"can you do better?\" What's your approach?","body":"Find the repeated work in the inner loop. Usual upgrades: (1) a hash map/set to replace an inner search, O(n²) → O(n); (2) sort + two pointers , O(n log n); (3) a sliding window for contiguous subarray/substring problems; (4) prefix sums for range sums; (5) a heap for top-K; (6) binary search on a sorted structure or on the answer; (7) memoisation/DP for overlapping subproblems. Say the trade-off (more memory for less time)."},{"kind":"question","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"55","title":"You get stuck halfway through a coding problem in an interview. What do you do?","body":"Keep talking. Restate what works so far, try a smaller example by hand to spot the pattern, consider brute force if the optimal approach is stuck, and ask a clarifying question or for a hint. A working brute-force solution with a clear explanation scores better than a half-written optimal one. Test what you have and state its complexity."},{"kind":"cheat","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"1","title":"Pattern → when to use","body":"Clue in the problem Pattern --- --- \"pair/complement\", \"seen before\", duplicates Hash map / HashSet Sorted array, pair sum, palindrome Two pointers Contiguous subarray/substring, \"longest/shortest window\" Sliding window Brackets, \"next greater\", undo Stack (monotonic stack) Shortest path unweighted, level order BFS (Queue) All paths, islands, tree recursion DFS Sorted + search, \"minimum feasible value\" Binary search Top K, k-th largest, merge k lists Heap ( PriorityQueue ) Overlapping subproblems, \"number of ways\" DP / memoisation All combinations/permutations Backtracking Linked list cycle/middle Fast & slow pointers"},{"kind":"cheat","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"2","title":"Complexity of C# collections","body":"Operation List Dictionary/HashSet SortedDictionary LinkedList --- --- --- --- --- Add O(1) O(1) O(log n) O(1) Search O(n) O(1) O(log n) O(n) Remove O(n) O(1) O(log n) O(1) with node Index O(1) — — O(n) amortised/average"},{"kind":"cheat","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"3","title":"Must-know programs (practise until automatic)","body":"Reverse string · palindrome · anagram · char count · first unique char · reverse words · Fibonacci · prime · factorial · Armstrong · FizzBuzz · swap · second largest · duplicates · missing number · move zeros · rotate array · merge sorted arrays · two sum · Kadane · valid parentheses · reverse linked list · cycle detection · binary search · bubble/quick/merge sort · tree height/BFS · LRU cache."},{"kind":"cheat","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"4","title":"Useful C# snippets","body":"csharp counts[c] = counts.GetValueOrDefault(c) + 1; (a, b) = (b, a); var pq = new PriorityQueue<string, int (); // min-heap var maxPq = new PriorityQueue<int, int (Comparer<int .Create((x, y) = y.CompareTo(x))); int mid = lo + (hi - lo) / 2; s[^1]; s[1..^1]; arr[..k]; Array.Sort(arr); Array.Reverse(arr, i, len); string.Join(\",\", list);"},{"kind":"cheat","course_slug":"coding-practice","course_title":"Coding Round Practice (DSA in C#)","ref":"5","title":"Answer checklist","body":"Clarify → examples → brute force + Big-O → optimise → code → dry-run → edge cases (empty, one, duplicates, negatives, overflow) → final Big-O."},{"kind":"course","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"","title":"Networking & Hosting — How a Website Works, End to End","body":"The complete life cycle of a web request — OSI and TCP/IP models, IP addresses, subnets and ports, DNS, TCP vs UDP, TLS/HTTPS, HTTP/1.1, HTTP/2 and HTTP/3, browser rendering, cookies and sessions, proxies, load balancers and CDNs, web servers (IIS, Kestrel, Nginx), hosting options from shared hosting to cloud and containers, domains and SSL certificates, deploying an ASP.NET site to IIS and Azure, and troubleshooting network problems. When you type https://www.shop.com/orders and press Enter, a dozen systems cooperate in under a second: your browser, the operating system, Wi-Fi/router, your ISP, DNS servers, the internet backbone, a CDN, a load balancer, a web server, your application and a database. This course follows that journey step by step, then shows how to host your own site. Concept One-line meaning --- --- IP address The address of a machine on a network ( 142.250.183.68 , 2404:6800::200e ) Port Which program on that machine ( 443 HTTPS, 80 HTTP, 1433 SQL Server) DNS The internet's phone book: name → IP address TCP Reliable, ordered delivery of bytes between two machines TLS Encryption + server identity → the \"S\" in HTTPS HTTP The request/response language of the web Web server Program that accepts HTTP requests (IIS, Kestrel, Nginx, Apache) Hosting Where your site physically runs (shared host, VPS, cloud PaaS, containers, serverless) Year Milestone --- --- 1969 ARPANET — the first packet-switched network 1974–1983 TCP/IP designed (Cerf & Kahn); ARPANET switches to TCP/IP on 1 Jan 1983 1983–1987 DNS (RFC 882/883, then 1034/1035) 1989–1991 Tim Berners-Lee invents the World Wide Web: HTML, HTTP, URLs, first browser and server 1995–1996 SSL 2.0/3.0 (Netscape); HTTP/1.0; IIS 1.0 ships with Windows NT; Apache becomes the top web server 1997–1999 HTTP/1.1 (RFC 2068 → 2616); TLS 1.0 1998 IPv6 specified (RFC 2460, later 8200) 2004 Nginx released 2008 TLS 1.2 2015 HTTP/2; Let's Encrypt free certificates (public launch 2016) 2018 TLS 1.3 (RFC 8446) 2022 HTTP/3 over QUIC (RFC 9114) 2024–2025 Browsers and clouds widely use HTTP/3; IPv6 carries a large share of traffic (≈45 % of Google users) What happens when you open https://www.shop.com/orders — the complete request life cycle: 1. URL parsing — the browser splits scheme ( https ), host ( www.shop.com ), port (default 443), path ( /orders ). If it's not a URL, it becomes a search. 2. Caches first — HSTS list (forces HTTPS), browser cache, service worker; maybe no network is needed at all. 3. DNS lookup — browser cache → OS cache/hosts file → configured resolver (ISP, 8.8.8.8, 1.1.1.1) → root servers → .com TLD servers → shop.com authoritative servers → returns an IP (often a CDN's). 4. TCP connection — three-way handshake (SYN, SYN-ACK, ACK) to IP:443. (HTTP/3 uses QUIC over UDP instead.) 5. TLS handshake — agree cipher, server sends its certificate, browser validates the chain and hostname, keys are exchanged; from now on everything is encrypted. 6. HTTP request — GET /orders HTTP/2 with headers (Host, cookies, Accept, User-Agent…). 7. Edge — CDN serves cached static files; otherwise forwards to the origin. A WAF filters attacks. 8. Load balancer / reverse proxy — picks a healthy server instance, may terminate TLS. 9. Web server + application — IIS/Kestrel passes the request through the pipeline: authentication, routing, controller, business logic, database queries. 10. Database — SQL Server runs the query (buffer pool, indexes) and returns rows. 11. HTTP response — status (200), headers (Content-Type, Cache-Control, Set-Cookie), body (HTML/JSON), compressed (gzip/Brotli). 12. Browser rendering — parse HTML → DOM, CSS → CSSOM, run JavaScript, layout, paint; fetch images/scripts in parallel (more requests, reusing the connection). 13. After load — JavaScript calls APIs (fetch/XHR), WebSockets for live data; the connection is kept alive for reuse or closed after idle time. - Browser DevTools — Network tab (timing waterfall: DNS, connect, TLS, TTFB, download), Security tab (certificate), Application tab (cookies, storage, service workers). - Command line — ping , tracert / traceroute , nslookup / dig , ipconfig /all / ip a , netstat -ano / ss -tlnp , curl -v , Test-NetConnection host -Port 443 (PowerShell), telnet . - Packet analysis — Wireshark, Fiddler, Charles Proxy. - Online — SSL Labs (TLS grading), DNS checker (propagation), WebPageTest, PageSpeed Insights, downforeveryoneorjustme. - Hosting — IIS Manager, Azure Portal (App Service, Front Door), Cloudflare dashboard, Nginx, Certbot / win-acme (Let's Encrypt)."},{"kind":"lesson","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"osi-and-tcp-ip-models-layers-of-a-network","title":"OSI and TCP/IP models — layers of a network","body":"OSI layer TCP/IP layer What it does Examples --- --- --- --- 7 Application Application Data your app understands HTTP, HTTPS, DNS, SMTP, FTP, SSH 6 Presentation Application Encoding, encryption, compression TLS, UTF-8, gzip 5 Session Application Sessions between apps (handled by TLS/HTTP today) 4 Transport Transport End-to-end delivery between ports TCP , UDP , QUIC 3 Network Internet Addressing and routing between networks IP (v4/v6), ICMP (ping), routers 2 Data link Link Delivery on the local network (frames, MAC addresses) Ethernet, Wi-Fi, switches, ARP 1 Physical Link Bits on the wire/air Cables, fibre, radio Encapsulation: your HTTP request is wrapped in a TCP segment (adds ports), then an IP packet (adds IP addresses), then an Ethernet/Wi-Fi frame (adds MAC addresses). Each router unwraps to layer 3, decides the next hop, and wraps again. The receiver unwraps in reverse order. text [ Ethernet header IP header (src/dst IP) TCP header (src/dst port) HTTP: GET /orders ... trailer ] Interview tip: Asked \"which layer?\": a switch works at layer 2 (MAC), a router at layer 3 (IP), a load balancer at layer 4 (TCP/UDP) or layer 7 (HTTP — can route by URL/header), a firewall at 3–4 (WAF at 7)."},{"kind":"lesson","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"ip-addresses-subnets-ports-nat-and-ipv6","title":"IP addresses, subnets, ports, NAT and IPv6","body":"IPv4 — 32 bits written as four numbers 192.168.1.25 (≈4.3 billion addresses — exhausted). IPv6 — 128 bits 2001:db8::1 (practically unlimited). Range Meaning --- --- 10.0.0.0/8 , 172.16.0.0/12 , 192.168.0.0/16 Private addresses (home/office/cloud VNets) — not routable on the internet 127.0.0.1 / ::1 Loopback — \"this machine\" ( localhost ) 0.0.0.0 \"All interfaces\" when a server listens 169.254.x.x No DHCP answer — self-assigned Subnet / CIDR: 192.168.1.0/24 = the first 24 bits are the network part → 256 addresses (254 usable hosts). /16 = 65,536 addresses. Cloud virtual networks (Azure VNet, AWS VPC) are designed with CIDR blocks and subnets for web, app and database tiers. DHCP gives devices an IP, gateway and DNS automatically. Default gateway = the router to other networks. NAT (network address translation): your home router has one public IP; it rewrites many private addresses to it and tracks connections — that's why your laptop isn't directly reachable from the internet. Port forwarding opens a hole for a specific port. Ports (0–65535) identify the program: Port Service --- --- 80 / 443 HTTP / HTTPS 22 SSH 3389 Remote Desktop (RDP) 1433 SQL Server 5432 / 3306 PostgreSQL / MySQL 6379 Redis 25 / 587 SMTP (mail) 53 DNS 5000–5001, 7000+ Typical ASP.NET Core dev ports A socket = IP + port + protocol; a TCP connection is identified by (client IP, client port, server IP, server port)."},{"kind":"lesson","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"dns-how-names-become-ip-addresses","title":"DNS — how names become IP addresses","body":"text Browser → OS resolver → Recursive resolver (ISP / 8.8.8.8 / 1.1.1.1) → Root server (\"ask .com\") → .com TLD server (\"ask ns1.shop.com\") → Authoritative server for shop.com → \"www.shop.com = 20.43.10.5, TTL 300\" Answer cached at each level for TTL seconds Record Purpose Example --- --- --- A / AAAA Name → IPv4 / IPv6 www → 20.43.10.5 CNAME Alias to another name www → shop.azurewebsites.net MX Mail servers shop.com → mail.protection.outlook.com TXT Text — domain verification, SPF/DKIM/DMARC for email v=spf1 include:... NS Which servers are authoritative ns1.cloudflare.com ALIAS/ANAME CNAME-like at the root domain (provider feature) shop.com → CDN TTL (time to live) — how long resolvers cache the answer. Lower it (e.g. 300 s) before migrating a site so the change propagates quickly. \"DNS propagation\" = waiting for old cached answers to expire. bash nslookup www.shop.com dig +trace www.shop.com see each step from the root ipconfig /flushdns clear Windows DNS cache"},{"kind":"lesson","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"tcp-vs-udp-and-the-tls-handshake-https","title":"TCP vs UDP and the TLS handshake (HTTPS)","body":"TCP UDP --- --- --- Connection Yes — three-way handshake No — just send datagrams Reliability Acknowledgements, retransmission, ordering None — packets may be lost/reordered Flow/congestion control Yes No (app decides) Overhead / latency Higher Lower Used by HTTP/1.1, HTTP/2, SQL Server (TDS), SMTP, SSH DNS, video calls, gaming, streaming, QUIC (HTTP/3) TCP three-way handshake: client SYN → server SYN-ACK → client ACK (one round trip before any data). Closing: FIN / ACK exchange; the closing side keeps TIME WAIT for a while — why creating a new HttpClient per request can exhaust ports. TLS 1.3 handshake (simplified, one round trip): 1. Client Hello — supported ciphers, key share, SNI (which hostname it wants). 2. Server Hello — chosen cipher, its key share, certificate , signature. 3. Client verifies the certificate: issued by a trusted CA (chain to a root in the OS/browser store), not expired, hostname matches, not revoked. 4. Both derive the same session keys (Diffie-Hellman) → encrypted HTTP flows. HTTPS gives confidentiality (encryption), integrity (no tampering) and authentication (you're talking to the real shop.com ). It does not make the application itself secure. Certificates: DV (domain validated — Let's Encrypt, free, 90 days), OV/EV (organisation checks). Wildcard .shop.com ; SAN certificates list several names. Private key must stay secret on the server/Key Vault."},{"kind":"lesson","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"http-in-depth-methods-status-codes-headers-versions","title":"HTTP in depth — methods, status codes, headers, versions","body":"http GET /api/orders?page=1 HTTP/1.1 Host: www.shop.com Accept: application/json Authorization: Bearer eyJhbGciOi... Cookie: session=abc123 HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Cache-Control: private, max-age=60 Content-Encoding: br Set-Cookie: theme=dark; Path=/; Secure; HttpOnly; SameSite=Lax {\"items\":[...],\"total\":42} Method Purpose Safe Idempotent --- --- --- --- GET Read ✅ ✅ POST Create / action ❌ ❌ PUT Replace ❌ ✅ PATCH Partial update ❌ ❌ (usually) DELETE Remove ❌ ✅ HEAD / OPTIONS Headers only / capabilities (CORS preflight) ✅ ✅ Status classes: 1xx info, 2xx success (200, 201, 204), 3xx redirect (301 permanent, 302/307 temporary, 304 not modified), 4xx client error (400, 401, 403, 404, 409, 429), 5xx server error (500, 502 bad gateway, 503 unavailable, 504 gateway timeout). HTTP versions: Version Transport Key point --- --- --- HTTP/1.1 TCP Text; one request at a time per connection (browsers open ~6 per host); keep-alive HTTP/2 TCP + TLS Binary, multiplexing many requests on one connection, header compression (HPACK) — but a lost TCP packet blocks all streams HTTP/3 QUIC over UDP No TCP head-of-line blocking, faster handshake (0-RTT/1-RTT), survives network changes (Wi-Fi → 4G) HTTP is stateless — each request stands alone; state is carried by cookies, tokens or server-side sessions."},{"kind":"lesson","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"cookies-sessions-caching-and-cors","title":"Cookies, sessions, caching and CORS","body":"Cookies — small key/value data the server asks the browser to store and send back: Attribute Meaning --- --- HttpOnly JavaScript can't read it (protects against XSS stealing it) Secure Only sent over HTTPS SameSite=Lax/Strict/None Controls sending on cross-site requests (CSRF protection) Domain , Path , Expires/Max-Age Scope and lifetime Session — the server keeps data (in memory, Redis, SQL) keyed by a session id stored in a cookie. In a web farm, sessions must be shared (distributed cache) or the load balancer must use sticky sessions. HTTP caching: Header Effect --- --- Cache-Control: public, max-age=31536000, immutable Cache for a year (fingerprinted static files like app.3f9a.js ) Cache-Control: no-store Never cache (sensitive pages) ETag + If-None-Match Revalidate: server answers 304 Not Modified without a body Last-Modified + If-Modified-Since Same with dates CORS — a browser rule: JavaScript on origin A may read responses from origin B only if B allows A via Access-Control-Allow-Origin . Non-simple requests send an OPTIONS preflight first."},{"kind":"lesson","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"how-the-browser-renders-a-page","title":"How the browser renders a page","body":"1. Receive HTML bytes → decode → tokenize → build the DOM . 2. Find <link rel=stylesheet → download → build the CSSOM (CSS blocks rendering). 3. Find <script → download and execute (blocks parsing unless defer / async / type=module ). 4. DOM + CSSOM → render tree → layout (positions/sizes) → paint → composite layers on the GPU. 5. Images, fonts, more scripts are requested in parallel; the page becomes interactive when JavaScript has run. 6. JavaScript changes (DOM updates) may trigger re-layout and re-paint. Speed-ups: fewer/smaller requests, compression (Brotli/gzip), HTTP/2/3, CDN, caching headers, lazy-loading images, defer scripts, critical CSS, preconnect/preload hints. Measure with Lighthouse and Core Web Vitals (LCP, INP, CLS)."},{"kind":"lesson","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"proxies-reverse-proxies-load-balancers-cdns-and-firewalls","title":"Proxies, reverse proxies, load balancers, CDNs and firewalls","body":"Component Sits Does --- --- --- Forward proxy Near the client Clients go out through it (corporate filtering, caching) Reverse proxy In front of servers Receives client requests and forwards to backend servers: TLS termination, compression, caching, routing (Nginx, IIS ARR, YARP, Azure Application Gateway) Load balancer In front of a server pool Distributes traffic: round robin, least connections, IP hash; health probes remove dead servers. L4 (TCP) or L7 (HTTP) CDN Edge locations worldwide Caches static (and some dynamic) content close to users: Cloudflare, Azure Front Door, Akamai, CloudFront Firewall / NSG Network boundary Allows/blocks by IP/port WAF Layer 7 Blocks SQL injection, XSS, bots (Azure WAF, Cloudflare WAF) API gateway In front of APIs Auth, rate limiting, routing, versioning (Azure API Management) text User ─▶ DNS ─▶ CDN/WAF (edge) ─▶ Load balancer ─▶ [Web server 1 Web server 2 Web server 3] ─▶ SQL Server Behind a proxy the app sees the proxy's IP — read the original client IP and scheme from X-Forwarded-For / X-Forwarded-Proto (ASP.NET Core: UseForwardedHeaders )."},{"kind":"lesson","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"web-servers-iis-kestrel-nginx-and-how-aspdotnet-is-hosted","title":"Web servers — IIS, Kestrel, Nginx and how ASP.NET is hosted","body":"Server Platform Notes --- --- --- IIS Windows Hosts ASP.NET (Framework) in the w3wp.exe worker process; app pools, bindings, Windows auth, URL Rewrite Kestrel Cross-platform ASP.NET Core's built-in, fast server; can face the internet directly or sit behind a reverse proxy HTTP.sys Windows Kernel-mode HTTP driver; ASP.NET Core can use it directly Nginx / Apache Linux mostly Reverse proxy and static file server in front of Kestrel, Node, PHP IIS key concepts: - Site — bindings (protocol + IP + port + host name, e.g. https :443 www.shop.com with a certificate). - Application pool — the worker process ( w3wp.exe ) running your app; isolation, identity (ApplicationPoolIdentity), recycling, .NET CLR version (\"No Managed Code\" for ASP.NET Core). - HTTP.sys receives requests in the kernel and queues them per app pool. - ASP.NET Core Module (ANCM) — runs ASP.NET Core in-process (inside w3wp, fastest) or out-of-process (IIS proxies to Kestrel). - web.config — module and handler settings; for Core it points IIS at dotnet YourApp.dll or the app's exe. xml <!-- web.config generated by dotnet publish for ASP.NET Core on IIS -- <configuration <system.webServer <handlers <add name=\"aspNetCore\" path=\" \" verb=\" \" modules=\"AspNetCoreModuleV2\" resourceType=\"Unspecified\" / </handlers <aspNetCore processPath=\"dotnet\" arguments=\".\\Shop.Web.dll\" stdoutLogEnabled=\"false\" hostingModel=\"inprocess\" / </system.webServer </configuration"},{"kind":"lesson","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"hosting-options-shared-vps-dedicated-cloud-paas-containers-serverless","title":"Hosting options — shared, VPS, dedicated, cloud PaaS, containers, serverless","body":"Option You manage Good for Examples --- --- --- --- Shared hosting Only your files Small sites, low budget GoDaddy/Hostinger Windows plans with Plesk VPS / virtual machine (IaaS) OS, IIS/Nginx, patches, runtime, app Full control, legacy apps Azure VM, AWS EC2, DigitalOcean Dedicated / on-premises server Everything incl. hardware Compliance, factories, intranets Company data centre PaaS (platform) Only the app + config Most web apps and APIs Azure App Service , Elastic Beanstalk, Heroku Static hosting + CDN Just static files SPAs, documentation, marketing sites Azure Static Web Apps, Vercel, Netlify, GitHub Pages Containers Image + orchestration config Microservices, portability Azure Container Apps, AKS, ECS, Cloud Run Serverless functions Function code Event-driven, spiky workloads Azure Functions, AWS Lambda, Vercel Functions Trade-off: the less you manage, the less control you have — but also less patching, scaling and security work. A typical .NET stack today: React/Angular on Static Web Apps or a CDN, API on App Service/Container Apps, Azure SQL Database, Key Vault for secrets, Application Insights for monitoring. Scaling: vertical (bigger machine) vs horizontal (more instances behind a load balancer — app must be stateless). High availability: multiple instances across availability zones, health checks, database replicas, backups and a tested restore."},{"kind":"lesson","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"domains-dns-setup-and-ssl-certificates-in-practice","title":"Domains, DNS setup and SSL certificates in practice","body":"1. Buy a domain from a registrar (GoDaddy, Namecheap, Cloudflare Registrar, Google Domains successor Squarespace). You rent it yearly. 2. Choose DNS hosting — the registrar's DNS, Cloudflare, or Azure DNS; set NS records accordingly. 3. Point the domain — A record for the root to the server IP (or ALIAS), CNAME www to the platform hostname ( shop.azurewebsites.net ); add TXT records the platform asks for to prove ownership. 4. Certificate — free managed certificates (App Service managed certificate, Cloudflare, Let's Encrypt with Certbot/win-acme for IIS) or buy one; bind it to the site on 443. 5. Redirect HTTP → HTTPS and add HSTS ( UseHttpsRedirection , UseHsts , or an IIS URL Rewrite rule). 6. Email records — MX, SPF, DKIM, DMARC so your mail isn't marked as spam. 7. Verify — nslookup , SSL Labs test, browser padlock, check www and root both work. Common mistakes: certificate for www only but users type the root domain; forgetting renewals (automate them); CNAME at the root (not allowed — use ALIAS/A); long TTLs during migration."},{"kind":"lesson","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"deploying-an-aspdotnet-core-site-to-iis-and-to-azure-app-service","title":"Deploying an ASP.NET Core site to IIS and to Azure App Service","body":"IIS on a Windows server (VM or on-premises): powershell 1. Server: enable IIS and install the .NET Hosting Bundle (runtime + ASP.NET Core Module) Install-WindowsFeature -Name Web-Server -IncludeManagementTools download & run dotnet-hosting-<version -win.exe, then: net stop was /y; net start w3svc 2. Build: publish the app dotnet publish .\\Shop.Web\\Shop.Web.csproj -c Release -o C:\\publish\\shop 3. IIS: app pool with \"No Managed Code\", site pointing to C:\\publish\\shop, bindings 80/443 + certificate Import-Module WebAdministration New-WebAppPool -Name \"ShopPool\" Set-ItemProperty IIS:\\AppPools\\ShopPool -Name managedRuntimeVersion -Value \"\" New-Website -Name \"Shop\" -PhysicalPath \"C:\\publish\\shop\" -ApplicationPool \"ShopPool\" -Port 80 -HostHeader \"www.shop.com\" Then: give the app pool identity read access to the folder (and write access to log folders), set environment ( ASPNETCORE ENVIRONMENT ) and connection strings (environment variables or secured config), open firewall ports 80/443, test locally on the server, then from outside. Azure App Service: bash az group create -n rg-shop -l centralindia az appservice plan create -n plan-shop -g rg-shop --sku B1 --is-linux az webapp create -n shop-web-divakar -g rg-shop -p plan-shop --runtime \"DOTNETCORE:10.0\" dotnet publish -c Release -o ./publish && cd publish && zip -r ../app.zip . && cd .. az webapp deploy -n shop-web-divakar -g rg-shop --src-path app.zip --type zip az webapp config appsettings set -n shop-web-divakar -g rg-shop --settings ASPNETCORE ENVIRONMENT=Production Then: custom domain + managed certificate, connection string to Azure SQL (prefer Managed Identity), Application Insights, deployment slots (staging → swap) and a CI/CD pipeline instead of manual deploys. Troubleshooting a \"site not working\": Symptom Likely cause --- --- DNS PROBE FINISHED NXDOMAIN DNS record missing/wrong or not propagated Connection timed out Firewall/NSG blocks the port, server down, wrong IP Certificate warning Wrong hostname, expired, missing intermediate certificate 502.5 / 500.30 on IIS ASP.NET Core app failed to start — Hosting Bundle missing, wrong runtime, startup exception (enable stdout log, check Event Viewer) 503 Service Unavailable App pool stopped/crashing, overloaded 404 for deep links on an SPA Server not rewriting unknown paths to index.html Works locally, slow live Database latency (different region), no caching, small plan"},{"kind":"question","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"56","title":"What happens when you type a URL in the browser and press Enter?","body":"URL parsed → browser/OS caches checked → DNS resolves the host to an IP (resolver → root → TLD → authoritative) → TCP three-way handshake to port 443 (or QUIC for HTTP/3) → TLS handshake validates the certificate and sets up encryption → HTTP request sent with headers/cookies → CDN/load balancer/reverse proxy route it → web server and application handle it (auth, routing, controller, database) → HTTP response with status, headers, body → browser parses HTML into the DOM, loads CSS/JS/images, builds the render tree, lays out and paints the page; further requests reuse the connection."},{"kind":"question","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"57","title":"What is DNS and what are A, CNAME and MX records?","body":"DNS translates domain names to IP addresses through a hierarchy of servers with caching (TTL). An A record maps a name to an IPv4 address (AAAA for IPv6); a CNAME makes a name an alias of another name (e.g. www → shop.azurewebsites.net ); an MX record lists the mail servers for the domain. TXT records are used for verification and email security (SPF, DKIM, DMARC)."},{"kind":"question","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"58","title":"What is the difference between HTTP and HTTPS?","body":"HTTPS is HTTP over TLS: the connection is encrypted (confidentiality), protected from tampering (integrity), and the server proves its identity with a certificate signed by a trusted certificate authority (authentication). Default ports 80 vs 443. HTTPS is required for modern browser features, SEO and any login or personal data."},{"kind":"question","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"59","title":"TCP vs UDP?","body":"TCP is connection-oriented and reliable: handshake, acknowledgements, retransmission, ordering, flow and congestion control — used for the web, databases, email. UDP is connectionless with no delivery guarantees but lower latency and overhead — used for DNS, voice/video, games and QUIC (HTTP/3), where the application handles reliability."},{"kind":"question","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"60","title":"What are the main HTTP methods and status codes?","body":"GET (read), POST (create/action), PUT (replace, idempotent), PATCH (partial update), DELETE (remove, idempotent), OPTIONS/HEAD. Status: 200 OK, 201 Created, 204 No Content, 301/302 redirects, 304 Not Modified, 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 429 Too Many Requests, 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout."},{"kind":"question","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"61","title":"What is an IP address, a port and a socket? Public vs private IP?","body":"An IP address identifies a machine on a network; a port identifies a program/service on that machine (443 HTTPS, 1433 SQL Server); a socket is the endpoint IP + port + protocol, and a connection is the pair of endpoints. Private IPs (10.x, 172.16–31.x, 192.168.x) are used inside networks and translated by NAT; public IPs are reachable on the internet."},{"kind":"question","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"62","title":"What is a load balancer? What algorithms does it use?","body":"A component that distributes incoming traffic across several servers for scalability and availability, using health probes to skip unhealthy instances. Algorithms: round robin, weighted round robin, least connections, IP hash/sticky sessions, least response time. Layer 4 balancers route by IP/port (fast); layer 7 balancers understand HTTP and can route by path, host or header and terminate TLS."},{"kind":"question","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"63","title":"What is a CDN and how does it improve performance?","body":"A Content Delivery Network caches content at edge servers around the world, so users download from a nearby location: lower latency, less load on the origin, protection against traffic spikes and DDoS, often a WAF and free TLS. Best for static assets with long cache headers and fingerprinted file names; dynamic content can also be accelerated."},{"kind":"question","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"64","title":"Forward proxy vs reverse proxy?","body":"A forward proxy acts for clients (they connect out through it — corporate filtering, anonymity). A reverse proxy acts for servers (clients connect to it and it forwards to backend servers — TLS termination, load balancing, caching, compression, hiding internal servers). Nginx, IIS ARR, YARP and Azure Application Gateway are reverse proxies."},{"kind":"question","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"65","title":"How is an ASP.NET Core app hosted on IIS?","body":"Install the .NET Hosting Bundle (runtime + ASP.NET Core Module). IIS receives requests via HTTP.sys and the app pool's w3wp.exe ; the ASP.NET Core Module runs the app in-process (inside w3wp, fastest) or out-of-process (proxying to Kestrel). The app pool uses \"No Managed Code\"; web.config (generated on publish) configures the module; bindings and certificates are set in IIS."},{"kind":"question","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"66","title":"What is the difference between HTTP/1.1, HTTP/2 and HTTP/3?","body":"HTTP/1.1: text protocol, one outstanding request per connection (browsers open ~6 connections per host), keep-alive. HTTP/2: binary framing, multiplexes many requests over one TCP connection, header compression; still suffers TCP head-of-line blocking on packet loss. HTTP/3: runs over QUIC (UDP), independent streams without head-of-line blocking, faster connection setup, connection migration across networks."},{"kind":"question","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"67","title":"Cookies vs session vs local storage?","body":"Cookies are small values sent automatically with every request to the domain (can be HttpOnly/Secure/SameSite) — used for session ids and auth. A session is server-side data keyed by a session id cookie. localStorage/sessionStorage are browser-only key-value stores readable by JavaScript and never sent automatically — fine for preferences, not for tokens (XSS risk)."},{"kind":"question","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"68","title":"IaaS vs PaaS vs SaaS vs serverless?","body":"IaaS: you get VMs/networks and manage the OS and everything above (Azure VM). PaaS: the platform runs your app; you manage code and configuration (Azure App Service, Azure SQL). SaaS: complete software you just use (Microsoft 365, Salesforce). Serverless: run functions or containers on demand with automatic scaling and pay-per-use (Azure Functions, Container Apps), no server management at all."},{"kind":"question","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"69","title":"How does TLS work and what does a certificate prove?","body":"The client and server negotiate a cipher suite, exchange keys with (elliptic-curve) Diffie-Hellman, and derive symmetric session keys; the server presents a certificate binding its public key to the domain, signed by a certificate authority the client trusts. The client checks the chain, validity dates, hostname (SAN) and revocation. The certificate proves the server controls the domain (DV) and, for OV/EV, who the organisation is."},{"kind":"question","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"70","title":"Users report your site is down, but it works on your machine. How do you troubleshoot?","body":"Check from outside (another network, downforeveryoneorjustme, mobile data). DNS: nslookup from different resolvers — wrong/expired record or propagation. Connectivity: Test-NetConnection host -Port 443 , firewall/NSG, load balancer health probes. TLS: expired certificate or missing intermediate (SSL Labs). Server: app pool/process running, logs (Event Viewer, stdout, Application Insights), 5xx errors, resource limits. Recent changes: deployment, certificate renewal, DNS edits. Your machine may use a cached DNS entry or hosts-file entry."},{"kind":"question","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"71","title":"After moving the site to a new server, some users still reach the old server for hours. Why?","body":"DNS caching: resolvers and clients cache the old A record until its TTL expires (and some ignore TTLs). Next time lower the TTL (e.g. to 300 s) a day before the move, then change the record, keep the old server running (or redirecting) until traffic drains, and raise the TTL afterwards."},{"kind":"question","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"72","title":"An ASP.NET Core app on IIS shows \"HTTP Error 500.30 — ASP.NET Core app failed to start\". What do you check?","body":"The app crashed during startup. Enable stdoutLogEnabled=\"true\" in web.config (create the logs folder with write permission) or check Event Viewer → Application; run the app from the command line on the server ( dotnet Shop.Web.dll ) to see the exception. Common causes: wrong/missing .NET runtime or Hosting Bundle, missing config/connection string for the environment, file permissions for the app pool identity, database unreachable at startup, wrong ASPNETCORE ENVIRONMENT ."},{"kind":"question","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"73","title":"Behind the load balancer, users are randomly logged out. Why?","body":"The app keeps session or authentication state per server (in-memory session, per-machine Data Protection keys), and the load balancer sends requests to different instances. Fix: store session in a distributed cache (Redis/SQL), share the ASP.NET Core Data Protection key ring (Blob Storage/Redis + Key Vault), or use stateless tokens; sticky sessions only as a stop-gap."},{"kind":"cheat","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"1","title":"Request life cycle","body":"URL → cache/HSTS → DNS → TCP (or QUIC) → TLS → HTTP request → CDN/WAF → load balancer → web server → app → DB → response → DOM/CSSOM → layout → paint."},{"kind":"cheat","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"2","title":"Layers","body":"L7 HTTP/DNS · L4 TCP/UDP (ports) · L3 IP (routers) · L2 Ethernet/Wi-Fi (switches, MAC) · L1 physical. L4 vs L7 load balancing."},{"kind":"cheat","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"3","title":"Numbers to know","body":"Ports 80/443/22/3389/1433/6379/53 · private ranges 10/8, 172.16/12, 192.168/16 · /24 = 256 addresses · TLS 1.3 = 1 RTT · TTL 300 s before migrations."},{"kind":"cheat","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"4","title":"Hosting choices","body":"Shared → VPS/VM (IaaS) → PaaS (App Service) → containers (Container Apps/AKS) → serverless (Functions); static SPA → Static Web Apps/CDN."},{"kind":"cheat","course_slug":"networking-hosting","course_title":"Networking & Hosting — How a Website Works, End to End","ref":"5","title":"Troubleshooting toolkit","body":"nslookup / dig · ping / tracert · Test-NetConnection -Port · curl -v · DevTools Network timing · SSL Labs · IIS stdout log + Event Viewer · App Insights."},{"kind":"course","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"","title":"System Design — High-Level Design (HLD) from Basics to Case Studies","body":"How to design large systems — requirements and estimation, scalability and availability, latency vs throughput, CAP and consistency models, load balancing, caching strategies, database choice, replication, partitioning and sharding, consistent hashing, queues and event streaming, rate limiting, search, storage and CDNs, observability, and full case studies (URL shortener, news feed, chat, notification service, e-commerce checkout, file storage, ride booking) with the HLD interview framework. High-Level Design (HLD) describes a system as boxes and arrows: clients, load balancers, services, databases, caches, queues, storage, and how data flows between them. Low-Level Design (LLD) zooms into one box: classes, interfaces, methods, database tables (next course). System design interviews are mostly HLD for experienced roles, with some LLD. Question HLD answers Example decision --- --- How many users/requests/data? 10M users, 2k requests/s peak, 5 TB/year Which components? API gateway, stateless services, Redis, SQL + read replicas, queue, CDN Where is data stored and how is it split? Orders in SQL sharded by customer, images in Blob storage How does it scale and survive failures? Horizontal scaling, replicas across zones, retries, circuit breakers What are the trade-offs? Eventual consistency for feeds, strong consistency for payments Era Milestone in large-scale system design --- --- 1990s Three-tier architecture (presentation, business, data) on single servers 2000s Web farms + load balancers; memcached (2003); Google papers: GFS (2003), MapReduce (2004), Bigtable (2006) 2007 Amazon Dynamo paper — eventual consistency, consistent hashing 2008–2012 Cloud (AWS 2006, Azure 2010); NoSQL (Cassandra, MongoDB, Redis); Kafka (2011) 2012–2015 Microservices, Docker (2013), Kubernetes (2014); Google Spanner (globally consistent SQL) 2016–2020 Serverless, managed databases, service meshes, CQRS/event sourcing popular 2020s Modular monoliths come back for many teams; vector databases and AI workloads; platform engineering The HLD interview framework (≈45 minutes): 1. Requirements (5 min) — functional (what users do) and non-functional (scale, latency, availability, consistency, security). Agree on what's out of scope. 2. Estimation (5 min) — users, requests/second, read:write ratio, storage per year, bandwidth. 3. API design (5 min) — main endpoints with inputs/outputs. 4. Data model (5 min) — main entities, choose SQL vs NoSQL, keys and indexes. 5. High-level diagram (10 min) — client → CDN → load balancer → services → cache/DB/queue/storage. 6. Deep dive (10 min) — 1–2 hard parts the interviewer cares about (feed generation, hot keys, consistency, sharding). 7. Wrap-up (5 min) — bottlenecks, failure scenarios, monitoring, how it evolves at 10× scale. - Diagramming: draw.io / diagrams.net, Excalidraw, Lucidchart, Miro, C4 model (context → container → component → code), PlantUML / Mermaid. - Estimation: latency numbers, powers of two, a calculator. - Reading: Designing Data-Intensive Applications (Kleppmann), System Design Interview (Alex Xu), High Scalability blog, engineering blogs (Netflix, Uber, Stripe, Microsoft), Azure Architecture Center, AWS Well-Architected."},{"kind":"lesson","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"requirements-and-back-of-the-envelope-estimation","title":"Requirements and back-of-the-envelope estimation","body":"Functional requirements — features: \"users post photos\", \"followers see a feed\", \"users like and comment\". Non-functional requirements — qualities: availability (99.9 % = ~8.8 h downtime/year; 99.99 % = ~53 min), latency (p99 < 200 ms), throughput, durability, consistency, security, cost. Useful numbers: Fact Value --- --- Seconds per day ~86,400 ≈ 10⁵ 1 million requests/day ≈ 12 requests/second average Peak factor 2–10× average 1 KB × 1 million 1 GB Memory read / SSD read / same-DC round trip / cross-continent 100 ns / 100 µs / 0.5 ms / 150 ms Example — photo sharing app: 50M daily active users, each views 20 photos and uploads 0.1 per day. - Reads: 50M × 20 / 86,400 ≈ 11,600 requests/s (peak ~50k/s) → heavy read caching + CDN. - Writes: 50M × 0.1 / 86,400 ≈ 58 uploads/s . - Storage: 5M photos/day × 500 KB ≈ 2.5 TB/day → ~900 TB/year → object storage, not a database. - Read:write ≈ 200:1 → optimise for reads."},{"kind":"lesson","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"scalability-availability-latency-and-throughput","title":"Scalability, availability, latency and throughput","body":"Term Meaning --- --- Scalability Handle more load by adding resources Vertical scaling (scale up) Bigger machine — simple, limited, single point of failure Horizontal scaling (scale out) More machines — needs stateless services and data partitioning Availability % of time the system works; achieved by redundancy (no single point of failure) Reliability Works correctly (no data loss, correct results) Latency Time for one request (measure p50, p95, p99 — not the average) Throughput Requests handled per second Durability Data survives failures (replication, backups) Stateless services are the key to horizontal scaling: keep session/state in Redis, a database or the client token, so any instance can serve any request. Availability in series and parallel: two components each 99.9 % in series → 99.8 %; two redundant copies of a 99 % component in parallel → 99.99 %."},{"kind":"lesson","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"cap-theorem-consistency-models-and-pacelc","title":"CAP theorem, consistency models and PACELC","body":"CAP: in a distributed data store, when a network partition happens you must choose between Consistency (every read sees the latest write) and Availability (every request gets a response). Partitions are unavoidable, so the real choice is CP vs AP during failures. Choice Behaviour during partition Examples --- --- --- CP Refuse/timeout some requests to stay consistent Banking ledgers, SQL with synchronous replication, ZooKeeper, etcd AP Answer with possibly stale data, reconcile later Social feeds, shopping carts, DNS, Cassandra, DynamoDB (default) PACELC: if Partition → choose A or C; Else (normal operation) → choose Latency or Consistency. Synchronous replication = more consistency, more latency. Consistency models: strong (linearizable) → read-your-writes → monotonic reads → causal → eventual (replicas converge eventually). Choose per feature: payment balance strong; like counts eventual. ACID vs BASE: ACID (Atomicity, Consistency, Isolation, Durability) — relational transactions. BASE (Basically Available, Soft state, Eventually consistent) — many NoSQL systems."},{"kind":"lesson","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"load-balancing-and-api-gateways","title":"Load balancing and API gateways","body":"Clients → DNS (can balance across regions: Azure Traffic Manager/Front Door) → load balancer (L4 or L7) → service instances. Algorithms: round robin, least connections, consistent hashing (sticky by user/key), weighted. Health checks remove failed instances. Load balancers themselves are redundant (active-passive pairs or managed cloud services). An API gateway adds authentication, rate limiting, request routing to microservices, response aggregation and API versioning (Azure API Management, YARP, Kong)."},{"kind":"lesson","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"caching-where-strategies-and-pitfalls","title":"Caching — where, strategies and pitfalls","body":"text Browser cache → CDN → API gateway/output cache → application in-memory cache → distributed cache (Redis) → database buffer pool Strategy How Good for --- --- --- Cache-aside (lazy loading) App checks cache; on miss loads DB and fills cache Most read-heavy data Read-through Cache library loads from DB itself Simpler app code Write-through Write to cache and DB together Data read right after write Write-behind Write to cache, flush to DB asynchronously High write throughput (risk of loss) Refresh-ahead Refresh popular keys before expiry Predictable hot data Eviction policies: LRU (least recently used — most common), LFU, FIFO, TTL expiry. Pitfalls and fixes: Problem Fix --- --- Stale data Short TTL, delete key on update, versioned keys Cache stampede (many requests miss at once and hit the DB) Lock/single-flight per key ( HybridCache does this), early refresh, jittered TTLs Hot key (one key gets huge traffic) Local in-memory copy, replicate the key, split it Cache penetration (requests for keys that don't exist) Cache \"not found\" briefly, Bloom filter Cold start after restart Warm up popular keys"},{"kind":"lesson","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"choosing-the-database-sql-vs-nosql","title":"Choosing the database — SQL vs NoSQL","body":"Type Examples Strengths Use for --- --- --- --- Relational (SQL) SQL Server, PostgreSQL, MySQL, Azure SQL ACID transactions, joins, constraints, mature tooling Orders, payments, inventory, most business data Key-value Redis, DynamoDB Very fast simple lookups Cache, sessions, counters, leaderboards Document MongoDB, Cosmos DB Flexible JSON documents, easy scaling Catalogs, user profiles, content Wide-column Cassandra, ScyllaDB Massive write throughput, time-ordered data IoT telemetry, messaging history, activity logs Graph Neo4j, Cosmos DB Gremlin Relationships and traversals Social graphs, recommendations, fraud Time-series InfluxDB, TimescaleDB, Azure Data Explorer Time-bucketed metrics Monitoring, sensors Search Elasticsearch, Azure AI Search Full-text search, ranking, facets Product search, logs Object storage Azure Blob, S3 Huge files cheaply Images, videos, backups Vector pgvector, Azure AI Search vectors, Qdrant Similarity search on embeddings AI/RAG, recommendations Default: start with a relational database unless a specific need (massive scale for simple access patterns, flexible schema, special query type) points elsewhere. Many systems are polyglot — SQL for transactions + Redis + Blob + search index."},{"kind":"lesson","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"replication-partitioning-sharding-and-consistent-hashing","title":"Replication, partitioning, sharding and consistent hashing","body":"Replication — copies of data on several nodes: Type How Trade-off --- --- --- Leader–follower (primary–replica) Writes to primary; replicas copy changes; reads can go to replicas Replication lag → stale reads; failover needed Multi-leader Several nodes accept writes (multi-region) Write conflicts to resolve Leaderless (quorum) Write to W nodes, read from R nodes, W + R N for consistency Tunable, complex Synchronous replication = no data loss on failover but slower writes; asynchronous = faster but may lose the last seconds. SQL Server: Always On availability groups; Azure SQL: geo-replication and read replicas. Partitioning / sharding — split data across nodes so each holds a part: Method How Watch out --- --- --- Range By key range (A–M, N–Z; dates) Hot ranges (all new orders go to the latest partition) Hash hash(key) % N Resharding moves almost everything when N changes Consistent hashing Nodes and keys on a hash ring; key goes to the next node clockwise; virtual nodes balance load Adding a node moves only ~1/N of keys — used by Dynamo, Cassandra, distributed caches Directory/lookup A service maps key → shard Extra lookup, flexible Choose a shard key that spreads load evenly and keeps related data together (e.g. CustomerId for orders). Cross-shard queries and transactions become expensive — design around the main access pattern."},{"kind":"lesson","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"queues-event-streaming-and-asynchronous-processing","title":"Queues, event streaming and asynchronous processing","body":"Message queue Event stream (log) --- --- --- Examples RabbitMQ, Azure Service Bus, SQS Kafka, Azure Event Hubs, Kinesis Consumption Message removed after processing; competing consumers Messages kept for days; each consumer group tracks its offset; replay possible Ordering Per queue/session Per partition Use Background jobs, commands, decoupling services Analytics, event sourcing, IoT, activity tracking, CDC Benefits: decoupling (producer doesn't wait for the consumer), load levelling (absorb spikes), reliability (retry, dead-letter queue), fan-out (many subscribers). Design consumers to be idempotent (at-least-once delivery). Use the outbox pattern to publish events reliably with database changes."},{"kind":"lesson","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"rate-limiting-search-storage-and-cdns","title":"Rate limiting, search, storage and CDNs","body":"Rate limiting algorithms: Algorithm Idea --- --- Fixed window Count requests per minute window — simple, bursty at edges Sliding window log/counter Smoother limit over a moving window Token bucket Tokens refill at a rate; each request takes one; allows short bursts — most common Leaky bucket Requests leave at a constant rate — smooths traffic Distributed rate limiting keeps counters in Redis (atomic INCR with expiry or Lua scripts). ASP.NET Core has AddRateLimiter with fixed window, sliding window, token bucket and concurrency limiters; return 429 with Retry-After . Search: an inverted index (word → documents) in Elasticsearch/Azure AI Search, fed asynchronously from the database (change events); supports full text, typo tolerance, facets and ranking. Files and media: store in object storage (Blob/S3), keep only metadata + URL in the database, upload directly from the client with pre-signed/SAS URLs, serve through a CDN, process asynchronously (thumbnails, virus scan, transcoding) via a queue."},{"kind":"lesson","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"case-study-news-feed-social-timeline","title":"Case study — news feed (social timeline)","body":"Requirements: post, follow, see a feed of followed users' posts sorted by time; 100M DAU; feed load < 200 ms. Two ways to build the feed: Fan-out on write (push) Fan-out on read (pull) --- --- --- How When a user posts, insert the post id into each follower's feed list (Redis) When a user opens the feed, fetch recent posts from everyone they follow and merge Read cost Very fast Slow for users following many Write cost Huge for celebrities with millions of followers Cheap Hybrid (used by large networks): push for normal users; for celebrities, pull their posts at read time and merge. text Client → LB → Post service → Posts DB (sharded by post id) → event \"PostCreated\" → Fan-out workers → Redis feed lists (per user, last 500 ids) Client → LB → Feed service → Redis feed list + celebrity posts → hydrate posts from cache/DB → media via CDN Extras: pagination with cursors (not offsets), ranking service, counters for likes eventually consistent, notifications via a queue."},{"kind":"lesson","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"case-study-chat-messaging-system","title":"Case study — chat / messaging system","body":"Requirements: 1:1 and group chat, online presence, delivery/read receipts, message history, push notifications when offline. - Connections: WebSockets (SignalR in .NET) to chat servers; a connection registry (Redis) maps user → server. - Send flow: sender → chat server → persist message (store sorted by conversation + time; wide-column DB or SQL partitioned by conversation) → look up recipient's server → deliver over its WebSocket; if offline → push notification service (APNs/FCM) via a queue. - Ordering: per-conversation sequence numbers; client de-duplicates by message id. - Groups: fan-out to members (small groups) or members pull (large channels). - Presence: heartbeats with TTL in Redis; publish presence changes only to contacts. - Scale: chat servers scale horizontally; a pub/sub backplane (Redis / Azure SignalR Service) routes messages between servers."},{"kind":"lesson","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"case-study-e-commerce-checkout-and-inventory","title":"Case study — e-commerce checkout and inventory","body":"Requirements: browse catalog, cart, checkout, payment, inventory must not oversell, order history; flash sales with traffic spikes. text CDN (images, SPA) → API gateway → Catalog svc (read replicas + cache + search index) → Cart svc (Redis) → Order svc (SQL) ─ outbox ─▶ Service Bus ─▶ Payment svc / Inventory svc / Email svc Key decisions: - Inventory consistency: reserve stock in a transaction with a conditional update ( UPDATE Stock SET Qty = Qty - @n WHERE ProductId = @id AND Qty = @n ); release reservations that aren't paid within N minutes. - Payment idempotency: idempotency key per checkout attempt; payment provider webhooks update order status. - Saga: order created (pending) → payment → inventory confirm → order confirmed; compensate (refund/release) on failure. - Flash sales: queue-based admission (virtual waiting room), pre-warmed caches, rate limiting, autoscaling. - Read scaling: catalog is read-heavy → cache + read replicas + CDN."},{"kind":"lesson","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"case-studies-notification-service-file-storage-and-ride-booking-outlines","title":"Case studies — notification service, file storage and ride booking (outlines)","body":"Notification service: API receives \"notify user X with template T\" → validates preferences (opt-outs, quiet hours) → queues per channel (email, SMS, push) → workers call providers (SendGrid, Twilio, FCM) with retries and dead-letter queues → delivery status stored; rate limits per user; templates and localisation; idempotency keys to avoid duplicate sends. File storage (like Dropbox/OneDrive): files split into chunks (e.g. 4 MB) with hashes → upload only changed chunks (deduplication) directly to object storage via signed URLs → metadata service (SQL) stores file tree, versions, chunk lists → sync service notifies other devices (long polling/WebSockets) → CDN for downloads; conflict handling with versions. Ride booking (like Uber): drivers send location every few seconds → location service stores latest positions in an in-memory geo index (geohash/quadtree, Redis GEO) → rider requests a ride → matching service finds nearby available drivers and offers the trip → trip service manages state machine (requested → accepted → started → completed) → pricing (surge) and payment services → events to analytics. Strong consistency on assigning one driver per trip (conditional update/lock), eventual elsewhere."},{"kind":"lesson","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"reliability-observability-and-disaster-recovery","title":"Reliability, observability and disaster recovery","body":"- Redundancy everywhere: multiple instances, availability zones, replicated databases, no single point of failure. - Failure handling: timeouts, retries with backoff + jitter, circuit breakers, bulkheads, graceful degradation (show cached data), health checks. - Observability: logs, metrics (golden signals: latency, traffic, errors, saturation), distributed traces; SLOs and alerts on symptoms users feel. - Deployments: blue-green, canary releases, feature flags, automatic rollback. - Disaster recovery: RPO (how much data you can lose) and RTO (how long you can be down) drive the design — backups (RPO hours), async geo-replication (minutes), sync replication (zero); regular restore drills. - Security: authentication at the edge, least privilege between services, encryption in transit and at rest, secrets in a vault, WAF, DDoS protection."},{"kind":"question","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"74","title":"What is the difference between HLD and LLD?","body":"HLD shows the architecture of the whole system: components (clients, load balancers, services, databases, caches, queues, CDN), how they interact, data flow, scaling and failure handling. LLD details the inside of components: classes, interfaces, methods, design patterns, database tables and APIs. HLD answers \"what pieces and how they connect\"; LLD answers \"how each piece is built\"."},{"kind":"question","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"75","title":"Vertical vs horizontal scaling?","body":"Vertical: give one machine more CPU/RAM — simple, no code change, but limited and a single point of failure. Horizontal: add more machines behind a load balancer — almost unlimited and fault tolerant, but services must be stateless and data must be replicated/partitioned. Typical path: scale up first, then out."},{"kind":"question","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"76","title":"What is caching? Explain cache-aside.","body":"Storing frequently read data in faster storage (memory/Redis/CDN) to reduce latency and database load. Cache-aside: on read, check the cache; on miss, read from the database and put the result in the cache with a TTL; on write, update the database and delete (or update) the cache key. Watch for stale data, stampedes and hot keys."},{"kind":"question","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"77","title":"What does a load balancer do?","body":"Distributes requests across multiple servers to increase capacity and availability, performs health checks to stop sending traffic to failed servers, and can terminate TLS and route by URL (L7). Algorithms: round robin, least connections, IP hash/consistent hashing, weighted."},{"kind":"question","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"78","title":"Explain the CAP theorem with examples.","body":"In a distributed system, during a network partition you can't have both strong consistency and full availability. CP systems reject or delay requests to avoid stale data (bank balances, configuration stores like etcd); AP systems keep answering and reconcile later (social feeds, DNS, carts in Dynamo-style stores). When there is no partition, the trade-off is latency vs consistency (PACELC)."},{"kind":"question","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"79","title":"SQL or NoSQL — how do you choose?","body":"Start from the data and access patterns. SQL for structured, related data needing transactions, joins and constraints (orders, payments). NoSQL when you need massive horizontal scale for simple key-based access, flexible schemas, very high write throughput, or special models (documents, graphs, time-series). Many systems combine them: SQL as the source of truth, Redis cache, search index, blob storage."},{"kind":"question","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"80","title":"What is sharding? How do you choose a shard key?","body":"Splitting a dataset horizontally across multiple database nodes so each stores a subset, increasing capacity and throughput. A good shard key has high cardinality, spreads reads and writes evenly (no hot shard) and matches the main query pattern so most queries hit one shard (e.g. customer id for orders). Use consistent hashing or a directory to allow adding shards with minimal data movement."},{"kind":"question","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"81","title":"What is consistent hashing and why is it useful?","body":"Nodes and keys are placed on a hash ring; each key belongs to the next node clockwise. When a node is added or removed, only the keys between it and its neighbour move (~1/N of keys), unlike hash % N where almost all keys move. Virtual nodes (many points per server) spread load evenly. Used in distributed caches and databases (Dynamo, Cassandra) and load balancers."},{"kind":"question","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"82","title":"Why use a message queue in system design?","body":"To decouple services (the producer doesn't wait for or depend on the consumer being up), absorb traffic spikes (load levelling), process work asynchronously (emails, video encoding), retry failures with dead-letter queues, and fan out events to multiple subscribers. Consumers must be idempotent because delivery is at-least-once."},{"kind":"question","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"83","title":"Replication: synchronous vs asynchronous?","body":"Synchronous: the write is acknowledged only after replicas confirm — no data loss on failover but higher latency and reduced availability if a replica is slow. Asynchronous: acknowledge after the primary writes — fast, but replicas lag (stale reads) and recent writes can be lost if the primary fails. Many systems use sync within a region and async across regions."},{"kind":"question","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"84","title":"How would you design a rate limiter?","body":"Pick an algorithm (token bucket for bursts, sliding window for smoothness), a key (user id, API key, IP), and limits per endpoint. Store counters in Redis with atomic operations and TTLs so all API instances share them; return 429 with Retry-After; put it in the API gateway or middleware; allow configuration per plan; fail open or closed by policy if Redis is down."},{"kind":"question","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"85","title":"Design a URL shortener (high level).","body":"Write API creates a short code (base62 of a unique id or random 7 chars with collision check) and stores code → long URL in a key-value store or SQL with a unique index; read path GET /{code} checks Redis, then the store, and returns a 301/302 redirect. Reads dominate (100:1) → cache and CDN/edge. Analytics: send click events to a queue/stream and aggregate asynchronously. Scale: shard by code; custom aliases, expiry and abuse checks as extras."},{"kind":"question","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"86","title":"Design a news feed. Push or pull?","body":"Fan-out on write pushes post ids into followers' precomputed feeds (fast reads, expensive for celebrities); fan-out on read builds the feed at read time (cheap writes, slow reads). Use a hybrid: push for normal users, pull and merge for celebrity accounts. Store feeds in Redis lists, posts in a sharded store, media via CDN, use cursor pagination, and rank asynchronously."},{"kind":"question","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"87","title":"What are RPO and RTO?","body":"Recovery Point Objective: the maximum acceptable data loss measured in time (e.g. 5 minutes → you need replication or log backups at least every 5 minutes). Recovery Time Objective: the maximum acceptable downtime to restore service (e.g. 1 hour → automated failover or a tested runbook). Lower values cost more: synchronous replication, hot standby regions."},{"kind":"question","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"88","title":"Your read-heavy API's database is at 90 % CPU. What steps do you take, in order?","body":"Measure the top queries first; add/fix indexes and remove N+1 queries; add caching (in-memory/Redis) for hot data and HTTP caching/CDN where possible; route reads to read replicas; reduce payloads with projection and paging; scale the database up as a quick fix; finally partition/shard if data or write volume demands it. Monitor after each step."},{"kind":"question","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"89","title":"A flash sale will bring 50× normal traffic for 10 minutes. How do you prepare?","body":"Load test beforehand; pre-scale and warm caches; serve static content from the CDN; put a virtual waiting room/queue in front of checkout; rate limit per user; make inventory reservation atomic (conditional update) to prevent overselling; move non-critical work (emails, analytics) to queues; use feature flags to switch off expensive features; monitor dashboards and have a rollback plan."},{"kind":"question","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"90","title":"Users in Europe complain the India-hosted app is slow. What do you change?","body":"Measure where time goes (network latency ≈ 150 ms per round trip). Put static assets and cacheable responses on a CDN; reduce round trips (bundle requests, HTTP/2/3); deploy the stateless API in a European region behind global routing (Azure Front Door/Traffic Manager); add read replicas in Europe for read-heavy data, keep writes in the primary region or use multi-region databases (Cosmos DB, Azure SQL geo-replication) with clear consistency choices; consider data-residency (GDPR) requirements."},{"kind":"cheat","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"1","title":"Interview framework","body":"Requirements → estimation → API → data model → diagram → deep dive → bottlenecks/failures → trade-offs."},{"kind":"cheat","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"2","title":"Estimation shortcuts","body":"1M/day ≈ 12/s · peak 2–10× · day ≈ 10⁵ s · 99.9 % ≈ 8.8 h/yr down · 99.99 % ≈ 53 min/yr."},{"kind":"cheat","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"3","title":"Building blocks","body":"DNS/CDN · load balancer · API gateway · stateless services · cache (Redis) · SQL + replicas · NoSQL · object storage · queue/stream · search index · rate limiter · monitoring."},{"kind":"cheat","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"4","title":"Data scaling ladder","body":"Indexes → caching → read replicas → vertical scale → partitioning → sharding (consistent hashing) → multi-region."},{"kind":"cheat","course_slug":"system-design","course_title":"System Design — High-Level Design (HLD) from Basics to Case Studies","ref":"5","title":"Trade-offs to say out loud","body":"Consistency vs availability · latency vs consistency · push vs pull · SQL vs NoSQL · sync vs async · cost vs redundancy · simplicity (monolith) vs independence (microservices)."},{"kind":"course","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"","title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","body":"How to turn requirements into classes — the LLD interview approach, identifying entities and responsibilities, UML class and sequence diagrams, applying SOLID and design patterns, designing APIs and database tables, concurrency in object design, and complete C designs for parking lot, library management, elevator, vending machine, LRU cache, rate limiter, splitwise/expense sharing and movie ticket booking. Low-Level Design (also called object-oriented design or machine coding) answers: which classes, interfaces, methods and relationships implement this feature cleanly? It sits between HLD (boxes and arrows) and code. HLD LLD --- --- Services, databases, caches, queues Classes, interfaces, enums, methods Scale, availability, data distribution Responsibilities, extensibility, patterns, testability Diagrams: architecture Diagrams: UML class and sequence \"Booking service talks to Payment service via a queue\" \" BookingService.Book() uses ISeatLockProvider and IPaymentGateway \" Interviewers check: clear entities, single responsibilities, use of interfaces, correct relationships (composition vs inheritance), sensible patterns (Strategy, Factory, State, Observer, Singleton used correctly), handling of edge cases and concurrency, and working code. Year Milestone --- --- 1967–1980 Simula and Smalltalk introduce objects and classes 1994 Design Patterns by the Gang of Four (23 patterns) 1997 UML 1.1 standardised by the OMG (Booch, Rumbaugh, Jacobson) 2000 SOLID principles described by Robert C. Martin 2003 Domain-Driven Design (Eric Evans) 2005 UML 2.0 2010s \"Machine coding\" rounds become common at product companies 2020s LLD + HLD rounds standard for senior developer interviews LLD interview approach (45–60 minutes): 1. Clarify requirements — list use cases; agree on scope (e.g. \"parking lot: multiple floors, vehicle types, tickets, payment; no reservations\"). 2. Identify entities (nouns) — Vehicle, Spot, Floor, Ticket, Payment… 3. Identify behaviours (verbs) — park, unpark, calculate fee, pay. 4. Define relationships — has-a (composition/aggregation), is-a (inheritance), uses (dependency). 5. Draw a class diagram — classes, key fields, methods, interfaces, enums. 6. Apply principles & patterns — SOLID, Strategy for varying rules, Factory for creation, State for lifecycles, Observer for notifications. 7. Write code for the core flow; keep it compilable and readable. 8. Discuss extensibility (new vehicle type?), concurrency (two cars, one spot), testing, and persistence (tables). - UML: draw.io, PlantUML, Mermaid (class/sequence diagrams in Markdown), Visual Studio class designer, Lucidchart. - Code: Visual Studio / Rider / VS Code with C ; xUnit for quick tests. - Reading: Head First Design Patterns , refactoring.guru (patterns with C examples), Clean Architecture ."},{"kind":"lesson","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"from-requirements-to-classes-nouns-verbs-and-responsibilities","title":"From requirements to classes — nouns, verbs and responsibilities","body":"Technique: write the use cases as sentences, underline nouns (candidate classes) and verbs (methods), then assign each responsibility to the class that owns the data it needs ( Information Expert ). Example — \"A member borrows a book copy from the library; the system records the due date and charges a fine if it is returned late.\" Nouns → classes Verbs → methods Owner --- --- --- Member, Book, BookCopy, Library, Loan, Fine borrow, return, record due date, charge fine Library.Borrow(member, copy) creates a Loan ; Loan.Return(date) computes overdue days; IFinePolicy.Calculate(loan) gives the amount Guidelines: - Each class has one reason to change (SRP). - Prefer composition (\"has-a\") over inheritance; inherit only for true \"is-a\" with shared behaviour. - Depend on interfaces for things that vary (payment methods, pricing rules, notification channels). - Use enums for fixed sets of states/types; use State/Strategy when behaviour differs per state/type. - Make invalid states impossible (private setters, constructor validation, value objects like Money )."},{"kind":"lesson","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"uml-class-diagrams-and-sequence-diagrams","title":"UML class diagrams and sequence diagrams","body":"Class diagram notation: Symbol Meaning Example --- --- --- + / - / public / private / protected +Park(vehicle): Ticket Solid line + hollow triangle Inheritance (is-a) Car ──▷ Vehicle Dashed line + hollow triangle Implements interface UpiPayment ┈┈▷ IPayment Filled diamond Composition — part can't exist without the whole Floor ◆── Spot Hollow diamond Aggregation — part can exist independently Team ◇── Player Plain arrow Association / dependency Ticket ── Spot 1 , 0..1 , , 1.. Multiplicity ParkingLot 1 ── Floor mermaid classDiagram class ParkingLot { +Park(Vehicle) Ticket +Unpark(Ticket) Receipt } class Floor { +FindSpot(VehicleType) Spot } class Spot { +SpotType Type +bool IsFree +Occupy(Vehicle) +Release() } class Vehicle { <<abstract +string Number +VehicleType Type } ParkingLot \"1\" -- \" \" Floor Floor \"1\" -- \" \" Spot Vehicle < -- Car Vehicle < -- Bike Sequence diagram — the order of calls between objects for one use case: mermaid sequenceDiagram participant G as EntryGate participant L as ParkingLot participant F as Floor participant T as TicketService G- L: Park(car) L- F: FindSpot(Car) F-- L: spot A-12 L- T: Issue(car, spot) T-- G: Ticket 881"},{"kind":"lesson","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"applying-solid-and-design-patterns-in-lld","title":"Applying SOLID and design patterns in LLD","body":"Situation in a design Pattern Example --- --- --- Behaviour varies by type/rule and can be swapped Strategy Fee calculation per vehicle type; payment methods; pricing Creating objects depends on input Factory / Abstract Factory VehicleFactory.Create(\"CAR\", number) Object behaves differently in each lifecycle state State Vending machine (Idle → HasMoney → Dispensing), order status Notify many parts when something happens Observer Display boards update when spots change; notify users Exactly one shared instance Singleton (prefer DI singleton lifetime) ParkingLot instance, configuration Add features without changing a class Decorator Add-ons to a pizza/coffee price; logging around a service Step-by-step construction of complex objects Builder Building a Booking or HTTP request Chain of handlers each deciding to handle or pass on Chain of Responsibility ATM cash dispenser (2000 → 500 → 100 notes), approval workflows Encapsulate a request as an object Command Undo/redo, queued elevator requests Simplify a complex subsystem Facade BookingFacade hides seats, payment, notifications csharp // Strategy + Open/Closed: add a new vehicle fee rule without touching existing code public interface IFeeStrategy { decimal Calculate(TimeSpan duration); } public sealed class CarFee : IFeeStrategy { public decimal Calculate(TimeSpan d) = 40 + Math.Max(0, Math.Ceiling(d.TotalHours) - 1) 30; } public sealed class BikeFee : IFeeStrategy { public decimal Calculate(TimeSpan d) = 20 + Math.Max(0, Math.Ceiling(d.TotalHours) - 1) 10; } public sealed class FeeCalculator(IReadOnlyDictionary<VehicleType, IFeeStrategy strategies) { public decimal For(VehicleType type, TimeSpan duration) = strategies[type].Calculate(duration); }"},{"kind":"lesson","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"design-a-parking-lot","title":"Design a parking lot","body":"Requirements: multiple floors; spot types (Bike, Compact, Large); vehicles (Bike, Car, Truck); entry issues a ticket; exit calculates the fee by type and duration; show free spots; thread-safe allocation. csharp public enum VehicleType { Bike, Car, Truck } public enum SpotType { Bike, Compact, Large } public abstract record Vehicle(string Number, VehicleType Type); public sealed record Car(string Number) : Vehicle(Number, VehicleType.Car); public sealed record Bike(string Number) : Vehicle(Number, VehicleType.Bike); public sealed record Truck(string Number) : Vehicle(Number, VehicleType.Truck); public sealed class Spot(string id, SpotType type) { public string Id { get; } = id; public SpotType Type { get; } = type; public Vehicle? Vehicle { get; private set; } public bool IsFree = Vehicle is null; public void Occupy(Vehicle v) = Vehicle = IsFree ? v : throw new InvalidOperationException($\"Spot {Id} is taken\"); public void Release() = Vehicle = null; } public sealed class Floor(int number, IEnumerable<Spot spots) { public int Number { get; } = number; private readonly List<Spot spots = spots.ToList(); public Spot? FindFree(SpotType type) = spots.FirstOrDefault(s = s.IsFree && s.Type == type); public int FreeCount(SpotType type) = spots.Count(s = s.IsFree && s.Type == type); } public sealed record Ticket(Guid Id, Vehicle Vehicle, Spot Spot, DateTime EntryUtc); public sealed class ParkingLot(IEnumerable<Floor floors, FeeCalculator fees, TimeProvider clock) { private readonly List<Floor floors = floors.ToList(); private readonly Dictionary<Guid, Ticket active = []; private readonly Lock gate = new(); // C 13 System.Threading.Lock private static SpotType SpotFor(VehicleType t) = t switch { VehicleType.Bike = SpotType.Bike, VehicleType.Car = SpotType.Compact, = SpotType.Large }; public Ticket Park(Vehicle v) { lock ( gate) // two gates can't grab the same spot { var spot = floors.Select(f = f.FindFree(SpotFor(v.Type))).FirstOrDefault(s = s != null) ?? throw new InvalidOperationException(\"Parking full for \" + v.Type); spot.Occupy(v); var ticket = new Ticket(Guid.NewGuid(), v, spot, clock.GetUtcNow().UtcDateTime); active[ticket.Id] = ticket; return ticket; } } public decimal Unpark(Guid ticketId) { lock ( gate) { if (! active.Remove(ticketId, out var t)) throw new KeyNotFoundException(\"Unknown ticket\"); t.Spot.Release(); return fees.For(t.Vehicle.Type, clock.GetUtcNow().UtcDateTime - t.EntryUtc); } } } Discussion points: Strategy for fees (new pricing without changing ParkingLot ), TimeProvider for testable time, lock (or per-spot compare-and-swap) for concurrency, Observer to update display boards, persistence tables Spots , Tickets , Payments ."},{"kind":"lesson","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"design-a-library-management-system","title":"Design a library management system","body":"Requirements: books with many copies; members borrow (max 5) and return; due date 14 days; fines for late returns; reservations when no copy is free; search by title/author. csharp public sealed class Book(string isbn, string title, string author) { public string Isbn = isbn, Title = title, Author = author; } public enum CopyStatus { Available, Loaned, Reserved, Lost } public sealed class BookCopy(string barcode, Book book) { public string Barcode = barcode; public Book Book = book; public CopyStatus Status = CopyStatus.Available; } public sealed class Member(int id, string name) { public int Id = id; public string Name = name; public List<Loan Loans { get; } = []; } public sealed class Loan(BookCopy copy, Member member, DateOnly borrowed) { public BookCopy Copy { get; } = copy; public Member Member { get; } = member; public DateOnly Borrowed { get; } = borrowed; public DateOnly Due = Borrowed.AddDays(14); public DateOnly? Returned { get; private set; } public int OverdueDays(DateOnly today) = Math.Max(0, (Returned ?? today).DayNumber - Due.DayNumber); public void Close(DateOnly date) = Returned = date; } public interface IFinePolicy { decimal Fine(Loan loan, DateOnly today); } public sealed class PerDayFine(decimal perDay) : IFinePolicy { public decimal Fine(Loan l, DateOnly t) = l.OverdueDays(t) perDay; } public sealed class LibraryService(IFinePolicy fines, INotifier notifier) { private const int MaxLoans = 5; public Loan Borrow(Member m, BookCopy c, DateOnly today) { if (m.Loans.Count(l = l.Returned is null) = MaxLoans) throw new InvalidOperationException(\"Loan limit reached\"); if (c.Status != CopyStatus.Available) throw new InvalidOperationException(\"Copy not available\"); c.Status = CopyStatus.Loaned; var loan = new Loan(c, m, today); m.Loans.Add(loan); return loan; } public decimal Return(Loan loan, DateOnly today) { loan.Close(today); loan.Copy.Status = CopyStatus.Available; notifier.NotifyNextReservation(loan.Copy.Book); // Observer-style hook for reservations return fines.Fine(loan, today); } } public interface INotifier { void NotifyNextReservation(Book book); } Tables: Books(Isbn PK) , BookCopies(Barcode PK, Isbn FK, Status) , Members , Loans(Id, Barcode FK, MemberId FK, Borrowed, Due, Returned) , Reservations , Fines ."},{"kind":"lesson","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"design-an-elevator-system-and-a-vending-machine-state-pattern","title":"Design an elevator system and a vending machine (State pattern)","body":"Elevator: N elevators, requests from floors (up/down) and inside cars; a dispatcher assigns requests; each elevator moves in a direction serving stops in order (SCAN/\"elevator algorithm\"). csharp public enum Direction { Idle, Up, Down } public sealed class Elevator(int id) { public int Id { get; } = id; public int Floor { get; private set; } public Direction Direction { get; private set; } = Direction.Idle; private readonly SortedSet<int up = [], down = []; public void AddStop(int floor) { if (floor = Floor) up.Add(floor); else down.Add(floor); if (Direction == Direction.Idle) Direction = floor = Floor ? Direction.Up : Direction.Down; } public void Step() // called on each tick { if (Direction == Direction.Up && up.Count 0) { Floor = up.Min; up.Remove(Floor); } else if (Direction == Direction.Down && down.Count 0) { Floor = down.Max; down.Remove(Floor); } Direction = up.Count 0 ? Direction.Up : down.Count 0 ? Direction.Down : Direction.Idle; } public int Cost(int floor) = Math.Abs(Floor - floor) + (Direction == Direction.Idle ? 0 : 2); } public interface IDispatchStrategy { Elevator Choose(IReadOnlyList<Elevator elevators, int floor); } public sealed class NearestElevator : IDispatchStrategy { public Elevator Choose(IReadOnlyList<Elevator e, int floor) = e.MinBy(x = x.Cost(floor))!; } Vending machine with the State pattern — behaviour depends on the current state; each state class handles the actions: csharp public interface IVendingState { void InsertCoin(VendingMachine m, decimal amount); void SelectProduct(VendingMachine m, string code); } public sealed class IdleState : IVendingState { public void InsertCoin(VendingMachine m, decimal amount) { m.Balance += amount; m.State = new HasMoneyState(); } public void SelectProduct(VendingMachine m, string code) = Console.WriteLine(\"Insert money first\"); } public sealed class HasMoneyState : IVendingState { public void InsertCoin(VendingMachine m, decimal amount) = m.Balance += amount; public void SelectProduct(VendingMachine m, string code) { var p = m.Inventory[code]; if (p.Stock == 0) { Console.WriteLine(\"Sold out\"); return; } if (m.Balance < p.Price) { Console.WriteLine($\"Insert {p.Price - m.Balance} more\"); return; } p.Stock--; m.Balance -= p.Price; Console.WriteLine($\"Dispensed {p.Name}, change {m.Balance}\"); m.Balance = 0; m.State = new IdleState(); } } public sealed class Product(string name, decimal price, int stock) { public string Name = name; public decimal Price = price; public int Stock = stock; } public sealed class VendingMachine { public IVendingState State { get; set; } = new IdleState(); public decimal Balance { get; set; } public Dictionary<string, Product Inventory { get; } = []; public void InsertCoin(decimal amount) = State.InsertCoin(this, amount); public void Select(string code) = State.SelectProduct(this, code); }"},{"kind":"lesson","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"design-an-lru-cache-and-a-rate-limiter","title":"Design an LRU cache and a rate limiter","body":"LRU cache — O(1) get and put (dictionary + doubly linked list): csharp public sealed class LruCache<TKey, TValue (int capacity) where TKey : notnull { private readonly Dictionary<TKey, LinkedListNode<(TKey Key, TValue Value) map = []; private readonly LinkedList<(TKey Key, TValue Value) order = new(); // front = most recent private readonly Lock lock = new(); public bool TryGet(TKey key, out TValue value) { lock ( lock) { if ( map.TryGetValue(key, out var node)) { order.Remove(node); order.AddFirst(node); // mark as recently used value = node.Value.Value; return true; } value = default!; return false; } } public void Put(TKey key, TValue value) { lock ( lock) { if ( map.TryGetValue(key, out var existing)) order.Remove(existing); else if ( map.Count == capacity) { map.Remove( order.Last!.Value.Key); order.RemoveLast(); } // evict least recent map[key] = order.AddFirst((key, value)); } } } Token-bucket rate limiter per user: csharp public sealed class TokenBucket(int capacity, double refillPerSecond, TimeProvider clock) { private double tokens = capacity; private DateTimeOffset last = clock.GetUtcNow(); private readonly Lock lock = new(); public bool TryTake() { lock ( lock) { var now = clock.GetUtcNow(); tokens = Math.Min(capacity, tokens + (now - last).TotalSeconds refillPerSecond); last = now; if ( tokens < 1) return false; tokens -= 1; return true; } } } public sealed class RateLimiter(Func<TokenBucket create) { private readonly ConcurrentDictionary<string, TokenBucket buckets = new(); public bool Allow(string userId) = buckets.GetOrAdd(userId, = create()).TryTake(); } In production use ASP.NET Core's built-in AddRateLimiter or Redis for limits shared across servers — but interviewers want to see that you can build it."},{"kind":"lesson","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"design-expense-sharing-splitwise-and-movie-ticket-booking","title":"Design expense sharing (Splitwise) and movie ticket booking","body":"Expense sharing: users, groups, expenses split equally/exactly/by percentage (Strategy), balances between pairs, \"simplify debts\". csharp public interface ISplitStrategy { Dictionary<string, decimal Split(decimal amount, IReadOnlyList<string users, IReadOnlyList<decimal ? values); } public sealed class EqualSplit : ISplitStrategy { public Dictionary<string, decimal Split(decimal amount, IReadOnlyList<string users, IReadOnlyList<decimal ? ) { var share = Math.Round(amount / users.Count, 2); var result = users.ToDictionary(u = u, = share); result[users[0]] += amount - share users.Count; // put rounding remainder on the first user return result; } } public sealed class Ledger { private readonly Dictionary<(string From, string To), decimal owes = []; public void AddExpense(string paidBy, Dictionary<string, decimal shares) { foreach (var (user, amount) in shares.Where(s = s.Key != paidBy)) owes[(user, paidBy)] = owes.GetValueOrDefault((user, paidBy)) + amount; } public decimal NetBalance(string user) = owes.Where(o = o.Key.To == user).Sum(o = o.Value) - owes.Where(o = o.Key.From == user).Sum(o = o.Value); } Movie ticket booking (BookMyShow): entities Movie, Theatre, Screen, Seat, Show, Booking, Payment. The hard part is seat locking : when a user selects seats, lock them for e.g. 10 minutes; confirm on payment or release on timeout; two users must never book the same seat. csharp public interface ISeatLockProvider { bool TryLock(Guid showId, IReadOnlyList<string seats, string userId, TimeSpan ttl); // atomic all-or-nothing void Unlock(Guid showId, IReadOnlyList<string seats, string userId); bool IsLockedBy(Guid showId, string seat, string userId); } // Implementation: in-memory with a lock for one server; Redis SET NX PX per seat or a DB unique constraint on (ShowId, SeatId) for many servers. Flow: GetAvailableSeats(show) → TryLock(seats) → create Booking (Pending) → payment → Confirm (Booked, unique row per seat) or release on failure/timeout."},{"kind":"question","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"91","title":"How do you approach an LLD question?","body":"Clarify requirements and scope → list use cases → find entities (nouns) and behaviours (verbs) → define relationships (composition, inheritance, interfaces) → draw a class diagram → apply SOLID and suitable patterns (Strategy, State, Factory, Observer) → write code for the main flows → discuss edge cases, concurrency, extensibility, testing and persistence."},{"kind":"question","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"92","title":"Composition vs inheritance — which do you prefer in LLD and why?","body":"Prefer composition (\"has-a\") because it keeps classes small and flexible: behaviour can be swapped at runtime via interfaces (Strategy) and changes don't ripple through a hierarchy. Use inheritance only for genuine \"is-a\" relationships with shared behaviour and substitutability (Liskov). Deep inheritance trees become rigid and fragile."},{"kind":"question","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"93","title":"Explain association, aggregation and composition with examples.","body":"Association: objects know/use each other (Teacher ↔ Student). Aggregation: whole–part where the part can exist independently (Team has Players; players exist without the team) — hollow diamond. Composition: strong ownership where the part's lifetime depends on the whole (House has Rooms; Order has OrderLines) — filled diamond."},{"kind":"question","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"94","title":"Design a parking lot — what are the key classes and patterns?","body":"ParkingLot (facade/singleton via DI) composed of Floors composed of Spots; Vehicle hierarchy (Car, Bike, Truck) or a type enum; Ticket; FeeCalculator with Strategy per vehicle type; optional Observer for display boards; Factory for vehicles. Concurrency: lock or atomic spot allocation so two gates can't take one spot. Extensibility: new vehicle/spot types and pricing rules without modifying existing classes."},{"kind":"question","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"95","title":"When do you use the State pattern? Give an LLD example.","body":"When an object's behaviour changes with its internal state and you'd otherwise have large switch statements on state. Each state is a class implementing the same interface; the context delegates to the current state, and states trigger transitions. Examples: vending machine (Idle, HasMoney, Dispensing, SoldOut), order lifecycle, ATM, elevator, document approval."},{"kind":"question","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"96","title":"How do you handle concurrency in an LLD (e.g. seat booking)?","body":"Identify shared mutable state and make the critical operation atomic: locks around allocation in a single process, atomic compare-and-set ( Interlocked , ConcurrentDictionary.TryAdd ), optimistic concurrency (row version) or unique constraints in the database, distributed locks with TTL (Redis SET NX PX ) across servers. Seat booking: temporary locks with expiry, confirm on payment, unique (ShowId, SeatId) constraint as the final guarantee."},{"kind":"question","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"97","title":"What UML diagrams are useful in LLD interviews?","body":"Class diagrams (classes, attributes, methods, interfaces, relationships, multiplicities) and sequence diagrams (order of calls between objects for a use case). Sometimes state diagrams (lifecycle of an order/elevator) and activity diagrams. Keep them simple and focused on the core flow."},{"kind":"question","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"98","title":"How would you make your design extensible for new requirements?","body":"Program to interfaces, isolate what varies (Strategy for rules, Factory for creation, Observer for notifications, Decorator for add-ons), keep classes small with single responsibilities, use dependency injection, avoid type switches spread across the code (Open/Closed), and keep domain logic independent of UI/database so it can be tested and reused."},{"kind":"question","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"99","title":"Design an LRU cache with O(1) operations.","body":"A hash map from key to a node in a doubly linked list ordered by recency. Get: find the node via the map, move it to the front, return the value. Put: if present, update and move to front; otherwise insert at the front, and if capacity is exceeded remove the tail node and its map entry. Add a lock for thread safety. In C : Dictionary<K, LinkedListNode<(K,V) + LinkedList<(K,V) ."},{"kind":"question","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"100","title":"How do you design an elevator system?","body":"Classes: ElevatorSystem/Controller, Elevator (current floor, direction, stop queues), Request (floor, direction), Button/Panel, Dispatcher with a strategy (nearest car, least load, zone-based). Each elevator serves stops in its current direction (SCAN) before reversing. Use the State pattern for Moving/Stopped/Maintenance, Command for requests, and simulate movement with ticks; handle emergency stop and overweight."},{"kind":"question","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"101","title":"Design an ATM cash dispenser. Which pattern fits?","body":"Chain of Responsibility: handlers for ₹2000, ₹500, ₹200 and ₹100 notes; each dispenses as many notes as it can ( amount / denomination , limited by its stock) and passes the remainder to the next handler; if a remainder is left at the end, the request fails and nothing is dispensed (check first, then commit). Around it: ATM with the State pattern (Idle → CardInserted → Authenticated → Transaction), a BankService interface for balance/debit, and transaction logging."},{"kind":"question","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"102","title":"How would you design a notification module that supports email, SMS and push, and new channels later?","body":"An INotificationChannel interface ( SendAsync(recipient, message) ) with one class per channel (Strategy); a factory or DI registration resolves channels by user preferences; a NotificationService builds messages from templates and sends to each selected channel; Observer/event hooks trigger notifications from domain events (OrderShipped). New channels (WhatsApp) = a new class + registration (Open/Closed). Add retries and a queue for reliability."},{"kind":"question","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"103","title":"How do you map an LLD class model to database tables?","body":"Each entity with identity becomes a table with a primary key; value objects become columns (or owned types); one-to-many → foreign key on the \"many\" side; many-to-many → junction table; inheritance → table-per-hierarchy with a discriminator column (simple, fast) or table-per-type (normalised); enums stored as int/string; add unique constraints for business rules (one booking per seat per show) and indexes for the main queries."},{"kind":"question","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"104","title":"What makes a design \"good\" in an LLD interview?","body":"Correctly modelled entities and relationships, small cohesive classes with clear names, dependencies on interfaces for varying behaviour, appropriate (not excessive) patterns, valid states enforced by constructors/methods, handled edge cases and concurrency, testable code (inject time, randomness, external services), and the ability to explain trade-offs and how new requirements fit without rewriting."},{"kind":"question","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"105","title":"In a machine-coding round you have 90 minutes to build a working Splitwise. How do you plan your time?","body":"10 min: requirements and class diagram (User, Group, Expense, Split strategies, Ledger/BalanceSheet). 50 min: implement core — add expense with equal/exact/percent split (Strategy), update pairwise balances, show balances per user, validation (percentages sum to 100, exact amounts sum to total). 20 min: simplify debts (greedy matching of max creditor and max debtor), simple console/driver and a few unit tests. 10 min: refactor names, handle rounding, explain extensions (currencies, persistence, notifications)."},{"kind":"question","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"106","title":"Your parking-lot design uses `if (vehicle is Car) ... else if (vehicle is Bike) ...` in five places. The interviewer adds \"electric cars with charging spots\". What do you change?","body":"The type checks violate Open/Closed — every new type edits five places. Move varying behaviour behind abstractions: a spot-type mapping/strategy per vehicle type, fee strategies registered in a dictionary/DI, and a ChargingSpot type with its own pricing (Decorator/Strategy for charging cost). Adding electric cars then means adding new classes and registering them, not modifying existing logic."},{"kind":"cheat","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"1","title":"LLD steps","body":"Requirements → use cases → nouns/verbs → relationships → class diagram → SOLID + patterns → code core flow → concurrency, edge cases, tests, tables."},{"kind":"cheat","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"2","title":"Pattern picker","body":"Varying rule → Strategy · lifecycle states → State · object creation → Factory/Builder · notify many → Observer · add features → Decorator · pass along handlers → Chain of Responsibility · undo/queue requests → Command · simple front door → Facade · one instance → DI singleton."},{"kind":"cheat","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"3","title":"UML quick key","body":"+ public - private protected · ▷ inheritance · ┈▷ interface · ◆ composition · ◇ aggregation · multiplicities 1, 0..1, , 1.. ."},{"kind":"cheat","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"4","title":"Classic problems","body":"Parking lot · library · elevator · vending machine · ATM (chain of note dispensers) · LRU cache · rate limiter · Splitwise · movie booking (seat locks) · snake & ladder · chess · hotel booking · food delivery."},{"kind":"cheat","course_slug":"lld","course_title":"Low-Level Design (LLD) — Object Design, UML and Classic Problems in C#","ref":"5","title":"Concurrency in LLD","body":"Lock critical sections · atomic ops ( Interlocked , ConcurrentDictionary.TryAdd ) · optimistic concurrency (row version) · unique constraints · distributed locks with TTL · idempotent operations."},{"kind":"course","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"","title":"C# Language — Basics to Advanced","body":"Types, control flow, collections, generics, delegates, async/await, memory and modern C features up to C 14. C (pronounced \"C sharp\") is a modern, object-oriented, type-safe language created by Microsoft (lead designer Anders Hejlsberg) and standardised as ECMA-334. It compiles to IL (Intermediate Language) which the .NET runtime (CLR) turns into machine code with a JIT (or ahead of time with Native AOT). Where C is used: - Web APIs and web apps — ASP.NET Core (MVC, Razor Pages, Web API, Blazor) - Desktop — WPF, WinForms, .NET MAUI, WinUI - Cloud and microservices — Azure Functions, containers, gRPC - Games — Unity - Data, ETL and background workers — Worker Services, console apps Why interviewers care: almost every .NET round starts with C fundamentals (value vs reference types, OOP, collections, LINQ, async) before moving to frameworks. C Year .NET / Visual Studio Headline features --- --- --- --- 1.0 2002 .NET Framework 1.0, VS.NET 2002 Classes, structs, interfaces, events, properties, delegates 2.0 2005 .NET Framework 2.0, VS 2005 Generics, nullable value types, iterators ( yield ), anonymous methods, partial types 3.0 2007 .NET Framework 3.5, VS 2008 LINQ, lambda expressions, var , extension methods, anonymous types, auto-properties, object/collection initialisers 4.0 2010 .NET Framework 4.0, VS 2010 dynamic , named and optional parameters, generic co/contravariance 5.0 2012 .NET Framework 4.5, VS 2012 async / await , caller-info attributes 6.0 2015 VS 2015 (Roslyn compiler) String interpolation, nameof , ?. null-conditional, expression-bodied members, exception filters 7.0–7.3 2017–2018 VS 2017 Tuples, pattern matching, out var , local functions, ref returns, in parameters, Span<T support 8.0 2019 .NET Core 3.0 Nullable reference types, switch expressions, async streams, ranges ^1 / .. , default interface methods, using declarations 9.0 2020 .NET 5 Records, init setters, top-level statements, target-typed new() , relational/logical patterns 10 2021 .NET 6 (LTS) Global usings, file-scoped namespaces, record structs 11 2022 .NET 7 Raw string literals, required members, list patterns, generic math (static abstract interface members) 12 2023 .NET 8 (LTS) Primary constructors for classes, collection expressions [1, 2] , alias any type 13 2024 .NET 9 params collections, System.Threading.Lock , partial properties 14 2025 .NET 10 (LTS) Extension members (extension blocks), the field keyword, null-conditional assignment a?.B = x Interview tip: you don't need every row. Know the big ones: generics (2.0), LINQ (3.0), async/await (5.0), nullable reference types (8.0), records (9.0), and the version you use at work. How a C program runs 1. Write .cs files inside a project ( .csproj ). 2. Build — the Roslyn compiler turns C into IL plus metadata, packaged in an assembly ( .dll / .exe ). 3. Load — the CLR loads the assembly, verifies the IL and resolves dependencies. 4. JIT compile — each method is compiled to native code the first time it is called (tiered compilation re-optimises hot methods). Native AOT compiles everything ahead of time instead. 5. Execute — managed code runs with type safety, exception handling and the garbage collector managing the heap. 6. Unload / exit — finalisers and IDisposable cleanup run; the process ends. Object lifecycle: new → constructor runs → object lives on the managed heap while referenced → becomes unreachable → collected by the GC (Gen 0 → 1 → 2) → finaliser (if any) runs. Deterministic cleanup of unmanaged resources is done with Dispose() / using . Tool Use --- --- Visual Studio 2022/2026 (Windows) Full IDE: debugger, profiler, designers, test explorer Visual Studio Code + C Dev Kit Lightweight cross-platform editor JetBrains Rider Cross-platform IDE with strong refactoring .NET SDK / dotnet CLI dotnet new , build , run , test , publish NuGet Package manager ( dotnet add package ) LINQPad Quick C /LINQ scratchpad, great for interview practice xUnit / NUnit / MSTest Unit testing frameworks BenchmarkDotNet Micro-benchmarks dotnet-trace, dotnet-counters, dotnet-dump Diagnostics in production ILSpy / SharpLab See the IL and lowered C the compiler produces"},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"what-csharp-and-dotnet-are","title":"What C# and .NET are","body":"C is the language ; .NET is the platform (runtime + base class library + SDK). You write C , the compiler produces IL, and the .NET runtime executes it. - CLR (Common Language Runtime): JIT, GC, type safety, exception handling, threading. - BCL (Base Class Library): System , System.Collections.Generic , System.IO , System.Net.Http , ... - CTS / CLS : the common type system that lets C , F and VB.NET interoperate. csharp // Program.cs — a complete program using top-level statements (C 9+) Console.WriteLine(\"Hello, Divakar!\"); var name = args.Length 0 ? args[0] : \"world\"; Console.WriteLine($\"Hello, {name}\"); bash dotnet new console -n HelloApp cd HelloApp dotnet run -- Divakar Interview tip: \"Managed code\" = code whose execution is managed by the CLR (memory, security, exceptions). \"Unmanaged code\" = native code outside the CLR, e.g. Win32 DLLs called via P/Invoke."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"first-program-namespaces-and-keywords","title":"First program, namespaces and keywords","body":"Classic program structure (what every C file looked like before C 9, and what top-level statements generate for you): csharp using System; // import a namespace so you can write Console instead of System.Console namespace Divakar.Shop // logical grouping of types; usually matches the folder { internal class Program // every method lives inside a type { static void Main(string[] args) // entry point: static, named Main, returns void or int (or Task/Task<int ) { Console.WriteLine(\"Hello, Divakar!\"); Console.Write(\"Your name: \"); string? name = Console.ReadLine(); Console.WriteLine($\"Welcome {name}\"); // string interpolation } } } Modern equivalent (C 10+): csharp // GlobalUsings.cs — applies to every file in the project global using System.Text.Json; // Customer.cs — file-scoped namespace saves one level of indentation namespace Divakar.Shop.Models; public class Customer { public string Name { get; set; } = \"\"; } // Program.cs — top-level statements: the compiler creates Program and Main using Divakar.Shop.Models; var c = new Customer { Name = \"Asha\" }; Console.WriteLine(JsonSerializer.Serialize(c)); Namespaces: - Prevent name clashes ( Divakar.Shop.Models.Order vs Divakar.Billing.Order ). - using imports a namespace; using Alias = Some.Long.Namespace.Type; creates an alias; using static System.Math; lets you write Sqrt(2) . - Implicit usings ( <ImplicitUsings enable</ImplicitUsings in the .csproj) auto-import System , System.Linq , System.Collections.Generic , System.IO , System.Threading.Tasks and more. - A namespace is not an assembly: one assembly (DLL) can contain many namespaces and one namespace can span many assemblies. Keywords are reserved words with special meaning: class , int , if , return , public , static , new , this , base , null , true ... You can't use them as identifiers unless prefixed with @ ( int @class = 5; ). Contextual keywords are only special in certain places and can otherwise be used as names: var , async , await , get , set , init , value , yield , record , required , where , select , field (C 14). Naming conventions: PascalCase for types, methods, properties and namespaces; camelCase for locals and parameters; camelCase for private fields; interfaces start with I ( IRepository ); async methods end with Async ."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"data-types-numbers-and-type-conversion","title":"Data types, numbers and type conversion","body":"C keyword .NET type Size Range / precision Literal --- --- --- --- --- byte / sbyte Byte / SByte 1 byte 0–255 / −128–127 255 short / ushort Int16 / UInt16 2 bytes ±32,767 / 0–65,535 100 int / uint Int32 / UInt32 4 bytes ±2.1 billion 42 , 42u long / ulong Int64 / UInt64 8 bytes ±9.2 × 10¹⁸ 42L float Single 4 bytes ~6–9 digits, binary floating point 1.5f double Double 8 bytes ~15–17 digits, binary floating point (default for decimals) 1.5 decimal Decimal 16 bytes 28–29 digits, base-10 — use for money 1.5m char Char 2 bytes One UTF-16 code unit 'A' bool Boolean 1 byte true / false true string String reference Immutable text \"text\" object Object reference Base of every type — csharp Console.WriteLine(0.1 + 0.2 == 0.3); // False — binary floating point can't store 0.1 exactly Console.WriteLine(0.1m + 0.2m == 0.3m); // True — decimal is exact for base-10 values int big = 1 000 000; // digit separators int hex = 0xFF, bin = 0b1010; // Integer overflow wraps silently by default... int max = int.MaxValue; int wrapped = unchecked(max + 1); // -2147483648 // ...unless you ask for checking try { int boom = checked(max + 1); } catch (OverflowException) { Console.WriteLine(\"Overflow!\"); } Console.WriteLine(7 / 2); // 3 — integer division truncates Console.WriteLine(7 / 2.0); // 3.5 Console.WriteLine(7 % 2); // 1 — remainder Console.WriteLine(Math.Round(2.5)); // 2 — banker's rounding (to even) by default Console.WriteLine(Math.Round(2.5, MidpointRounding.AwayFromZero)); // 3 Type conversion: Kind Example Notes --- --- --- Implicit (widening) long l = intValue; double d = intValue; Safe, no data loss, no syntax needed Explicit cast (narrowing) int i = (int)3.99; → 3 May lose data; truncates decimals Convert class Convert.ToInt32(\"42\") , Convert.ToInt32(3.5) → 4 Rounds to even; null → 0 Parse int.Parse(\"42\") Throws FormatException on bad input TryParse int.TryParse(input, out var n) Returns false instead of throwing — use for user input as / is obj as string , obj is int n Reference/pattern conversions without exceptions csharp if (int.TryParse(Console.ReadLine(), out int qty) && qty 0) Console.WriteLine($\"Ordering {qty}\"); else Console.WriteLine(\"Please enter a positive number\"); decimal price = decimal.Parse(\"1,234.50\", NumberStyles.Number, CultureInfo.InvariantCulture); // culture decides what , and . mean Interview tip: \"Why decimal for money?\" — double is binary and can't represent 0.1 exactly, so sums drift ( 0.1 + 0.2 != 0.3 ). decimal stores base-10 digits exactly, at the cost of speed and memory."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"value-types-vs-reference-types","title":"Value types vs reference types","body":"Value types Reference types --- --- --- Examples int , double , bool , char , decimal , struct , enum , DateTime class , string , arrays, delegate , interface , record (class) Variable holds The data itself A reference (address) to an object on the heap Assignment Copies the value Copies the reference — both point to the same object Default 0 , false , ... null Stored Inline: on the stack for locals, inside the containing object for fields Object on the managed heap csharp struct Point { public int X; } class Box { public int X; } var p1 = new Point { X = 1 }; var p2 = p1; // copy p2.X = 99; Console.WriteLine(p1.X); // 1 var b1 = new Box { X = 1 }; var b2 = b1; // same object b2.X = 99; Console.WriteLine(b1.X); // 99 Interview tip: \"Value types live on the stack\" is only partly true. A value-type field inside a class lives on the heap with that object. Say: value types are stored inline where they are declared."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"variables-constants-and-operators","title":"Variables, constants and operators","body":"csharp int age = 30; // declare + initialise; a local must be assigned before use var city = \"Pune\"; // type inferred at compile time — still strongly typed (city is string) const double Pi = 3.14159; // compile-time constant // readonly DateTime created; // (field only) set once, in declaration or constructor int a = 10, b = 3; // several variables in one statement Scope: a variable exists inside the { } block where it is declared; locals are not visible outside their method, loop or if block. Category Operators Example --- --- --- Arithmetic + - / % ++ -- a % b → 1; i++ (use then add) vs ++i (add then use) Assignment = += -= = /= %= ??= total += price; Comparison == != < = <= age = 18 Logical && \\ \\ ! (short-circuit), & \\ (always evaluate both) isAdmin \\ \\ isOwner Bitwise & \\ ^ ~ << flags & Perm.Write Null ?. ?[] ?? ??= ! name?.Length ?? 0 Type is , as , typeof , sizeof , nameof obj is string s Conditional ? : age = 18 ? \"adult\" : \"minor\" Range / index .. ^ arr[^1] last item, arr[1..3] Lambda = x = x 2 csharp int i = 5; Console.WriteLine(i++); // 5 (then i = 6) Console.WriteLine(++i); // 7 string? s = null; int len = s?.Length ?? 0; // null-conditional + null-coalescing s ??= \"default\"; // assign only if null Console.WriteLine(2 + 3 4); // 14 — before + (precedence) Console.WriteLine((2 + 3) 4); // 20 — use brackets to make intent clear - == compares values for value types and references for reference types unless overloaded ( string overloads it to compare text; records compare values). - && and short-circuit : if (user != null && user.IsActive) never touches user when it is null. - is checks type/pattern; as casts and returns null on failure instead of throwing."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"conditions-and-loops-if-ternary-switch-for-while-do-while","title":"Conditions and loops: if, ternary, switch, for, while, do-while","body":"if / else if / else and the ternary operator: csharp if (marks = 75) Console.WriteLine(\"Distinction\"); else if (marks = 35) Console.WriteLine(\"Pass\"); else Console.WriteLine(\"Fail\"); string result = marks = 35 ? \"Pass\" : \"Fail\"; // ternary: condition ? whenTrue : whenFalse string label = marks = 75 ? \"A\" : marks = 35 ? \"B\" : \"F\"; // nesting works but hurts readability switch statement and switch expression: csharp switch (day) { case DayOfWeek.Saturday: case DayOfWeek.Sunday: // stacked cases share one body Console.WriteLine(\"Weekend\"); break; // C does not allow fall-through from a non-empty case case DayOfWeek.Friday when isHoliday: // case guard Console.WriteLine(\"Long weekend\"); break; default: Console.WriteLine(\"Weekday\"); break; } string grade = score switch // switch expression (C 8+) returns a value { = 90 = \"A\", = 75 and < 90 = \"B\", = 50 = \"C\", = \"F\" // discard = default }; Loops: Loop Checks condition Use when --- --- --- for Before each iteration You know the count / need the index foreach — iterates a collection Read every item (can't add/remove items of the collection while looping) while Before (may run 0 times) Repeat until something changes do-while After (runs at least once) Menus, retry prompts csharp for (int i = 0; i < 5; i++) Console.Write(i); // 01234 for (int i = 10; i 0; i -= 2) Console.Write(i); // 108642 foreach (var name in new[] { \"Asha\", \"Ravi\" }) Console.WriteLine(name); int attempts = 0; while (!Connect() && attempts < 3) attempts++; string? input; do { Console.Write(\"Enter yes or no: \"); input = Console.ReadLine(); } while (input is not (\"yes\" or \"no\")); for (int i = 1; i <= 10; i++) { if (i % 2 == 0) continue; // skip the rest of this iteration if (i 7) break; // leave the loop Console.Write(i); // 1357 } Nested loops: break only leaves the innermost loop — extract the loops into a method and return , or use a flag. goto exists but is almost never used. Interview tip: \"for vs foreach\" — foreach works on any IEnumerable , is cleaner and avoids index bugs; for gives the index and lets you modify elements of an array/list by position. Modifying a List<T (Add/Remove) inside foreach throws InvalidOperationException ."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"strings-stringbuilder-and-immutability","title":"Strings, StringBuilder and immutability","body":"string is a reference type that behaves like a value : it is immutable — every \"change\" creates a new string. csharp string s = \"a\"; s += \"b\"; // allocates a new string \"ab\"; \"a\" becomes garbage var sb = new StringBuilder(); for (int i = 0; i < 1000; i++) sb.Append(i).Append(','); string csv = sb.ToString(); // one final allocation - Use StringBuilder when concatenating in loops; for a few concatenations + or interpolation is fine. - String interning: identical literals share one instance ( string.Intern ). - Compare with string.Equals(a, b, StringComparison.OrdinalIgnoreCase) rather than ToLower() . - string.IsNullOrWhiteSpace(x) covers null , \"\" and \" \" ."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"datetime-dateonly-timespan-and-time-zones","title":"DateTime, DateOnly, TimeSpan and time zones","body":"csharp DateTime now = DateTime.Now; // local time of the machine DateTime utc = DateTime.UtcNow; // UTC — store and compare in UTC DateTime d = new DateTime(2026, 10, 24, 9, 30, 0); DateTime tomorrow = DateTime.Today.AddDays(1); TimeSpan gap = new DateTime(2026, 12, 31) - DateTime.Today; // difference = TimeSpan Console.WriteLine($\"{gap.TotalDays:N0} days left\"); TimeSpan timeout = TimeSpan.FromSeconds(30); Console.WriteLine(d.ToString(\"yyyy-MM-dd HH:mm\")); // 2026-10-24 09:30 (custom format) Console.WriteLine(d.ToString(\"D\")); // long date in current culture Console.WriteLine(d.ToString(\"O\")); // ISO 8601 round-trip: 2026-10-24T09:30:00.0000000 if (DateTime.TryParseExact(\"24/10/2026\", \"dd/MM/yyyy\", CultureInfo.InvariantCulture, DateTimeStyles.None, out var parsed)) Console.WriteLine(parsed.DayOfWeek); // Saturday DateOnly birthday = new(1991, 5, 14); // .NET 6+: date without time TimeOnly opening = new(9, 0); // time without date DateTimeOffset placed = DateTimeOffset.UtcNow; // instant + offset — best for timestamps across time zones var india = TimeZoneInfo.FindSystemTimeZoneById(\"India Standard Time\"); // \"Asia/Kolkata\" on Linux (.NET 6+ accepts both) DateTime indiaTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, india); Type Holds Use for --- --- --- DateTime Date + time, Kind = Local/Utc/Unspecified General use; store as UTC DateTimeOffset Date + time + UTC offset Timestamps in APIs and databases DateOnly / TimeOnly Just a date / just a time Birthdays, opening hours TimeSpan A duration Differences, timeouts TimeProvider (.NET 8) Abstraction of \"now\" Unit-testable time Interview tip: DateTime is a struct (value type) and is immutable — d.AddDays(1) returns a new value, it doesn't change d . Store UTC, convert to local only for display."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"arrays-single-multidimensional-and-jagged","title":"Arrays: single, multidimensional and jagged","body":"An array is a fixed-size, zero-indexed block of elements of one type. Arrays are reference types (derived from System.Array ), even when the elements are value types. csharp int[] marks = new int[5]; // five zeros int[] primes = { 2, 3, 5, 7 }; // initializer string[] cities = [\"Pune\", \"Taipei\"]; // collection expression (C 12) marks[0] = 90; Console.WriteLine(primes.Length); // 4 Console.WriteLine(primes[^1]); // 7 — index from end int[] middle = primes[1..3]; // { 3, 5 } — range creates a copy // primes[10] = 1; // IndexOutOfRangeException // Multidimensional (rectangular) array: one block, every row same length int[,] grid = { { 1, 2, 3 }, { 4, 5, 6 } }; Console.WriteLine(grid[1, 2]); // 6 Console.WriteLine(grid.GetLength(0)); // 2 rows Console.WriteLine(grid.GetLength(1)); // 3 columns for (int r = 0; r < grid.GetLength(0); r++) for (int c = 0; c < grid.GetLength(1); c++) Console.Write(grid[r, c] + \" \"); // Jagged array: an array of arrays, rows can have different lengths int[][] jagged = new int[3][]; jagged[0] = [1]; jagged[1] = [1, 2]; jagged[2] = [1, 2, 3]; Console.WriteLine(jagged[2][1]); // 2 foreach (int[] row in jagged) Console.WriteLine(string.Join(\",\", row)); Useful Array methods: Array.Sort(arr) , Array.Reverse(arr) , Array.IndexOf(arr, x) , Array.Find(arr, predicate) , Array.Resize(ref arr, newSize) (creates a new array and copies), Array.Copy , Array.Fill , arr.Clone() (shallow copy). Multidimensional int[,] Jagged int[][] --- --- --- Shape Rectangular — all rows equal Rows can differ Memory One contiguous object Outer array + one array per row Access a[r, c] a[r][c] Speed Slightly slower indexing in the CLR Usually faster, more flexible"},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"collections-overview-generic-vs-non-generic","title":"Collections overview: generic vs non-generic","body":"Type When to use Lookup --- --- --- T[] Fixed size O(1) by index List<T Growable list O(1) index, O(n) search Dictionary<TKey,TValue Key → value O(1) average HashSet<T Unique items, fast Contains O(1) average Queue<T / Stack<T FIFO / LIFO O(1) enqueue/push LinkedList<T Many inserts/removes in the middle O(1) insert with a node SortedDictionary / SortedList Ordered keys O(log n) ConcurrentDictionary , ConcurrentQueue Multi-threaded access thread-safe ImmutableList , FrozenDictionary (.NET 8) Read-only shared data — csharp var prices = new Dictionary<string, decimal { [\"pen\"] = 10m, [\"book\"] = 250m }; if (prices.TryGetValue(\"pen\", out var p)) Console.WriteLine(p); int[] nums = [5, 3, 8]; // collection expression (C 12) List<int list = [.. nums, 10]; // spread - IEnumerable<T = can be iterated; ICollection<T adds Count/Add/Remove; IList<T adds index access. - Prefer returning IReadOnlyList<T / IEnumerable<T from public APIs. Generic vs non-generic collections: Non-generic ( System.Collections , .NET 1.x) Generic replacement ( System.Collections.Generic , .NET 2.0+) --- --- ArrayList List<T Hashtable Dictionary<TKey, TValue SortedList SortedList<TKey, TValue Stack , Queue Stack<T , Queue<T Generic collections are type-safe (compile-time errors instead of runtime InvalidCastException ) and faster for value types (no boxing). Use the non-generic ones only when maintaining old code."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"list-t-and-dictionary-tkey-tvalue-in-depth","title":"List<T> and Dictionary<TKey, TValue> in depth","body":"csharp var names = new List<string { \"Ravi\", \"Asha\" }; names.Add(\"Meera\"); names.AddRange([\"Kiran\", \"John\"]); names.Insert(0, \"Zoya\"); // at index names.Remove(\"John\"); // first match; returns bool names.RemoveAt(0); names.RemoveAll(n = n.StartsWith(\"K\")); bool hasAsha = names.Contains(\"Asha\"); int idx = names.IndexOf(\"Meera\"); string? first = names.Find(n = n.Length 4); names.Sort(); // in place names.ForEach(Console.WriteLine); Console.WriteLine($\"{names.Count} items, capacity {names.Capacity}\"); - List<T is a resizable array: Count = items, Capacity = allocated slots; when full it doubles and copies — pass an initial capacity if you know the size. - Index access O(1); Contains / IndexOf / Remove are O(n); inserting at the start is O(n). csharp var stock = new Dictionary<string, int (StringComparer.OrdinalIgnoreCase) { [\"pen\"] = 10, [\"book\"] = 4 }; stock.Add(\"bag\", 2); // throws ArgumentException if the key exists stock[\"pen\"] = 12; // add or overwrite if (stock.TryGetValue(\"book\", out int qty)) Console.WriteLine(qty); stock.TryAdd(\"pen\", 99); // false — key already there, no exception bool removed = stock.Remove(\"bag\"); foreach (var (item, count) in stock) Console.WriteLine($\"{item}: {count}\"); // var x = stock[\"laptop\"]; // KeyNotFoundException — use TryGetValue - Average O(1) lookup using the key's GetHashCode() and Equals() ; keys must be unique and not null. - Iteration order is not guaranteed — use SortedDictionary / SortedList or sort with LINQ when order matters. - Custom key types must override Equals and GetHashCode consistently (records do this for you)."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"sortedlist-hashset-stack-and-queue","title":"SortedList, HashSet, Stack and Queue","body":"csharp // SortedList<TKey,TValue : kept sorted by key; arrays inside → small memory, O(n) inserts var ranks = new SortedList<int, string { [3] = \"Bronze\", [1] = \"Gold\", [2] = \"Silver\" }; foreach (var kv in ranks) Console.WriteLine($\"{kv.Key}: {kv.Value}\"); // 1 Gold, 2 Silver, 3 Bronze Console.WriteLine(ranks.Keys[0]); // index access to keys/values // HashSet<T : unique items, O(1) Contains, set operations var skills = new HashSet<string { \"C \", \"SQL\" }; skills.Add(\"C \"); // ignored — returns false skills.UnionWith([\"Azure\", \"SQL\"]); // C , SQL, Azure skills.IntersectWith([\"SQL\", \"Azure\", \"React\"]); // SQL, Azure // Stack<T : LIFO — last in, first out (undo, call stack, bracket matching) var undo = new Stack<string (); undo.Push(\"type A\"); undo.Push(\"type B\"); Console.WriteLine(undo.Peek()); // type B (look, don't remove) Console.WriteLine(undo.Pop()); // type B (remove) // undo.Pop() on an empty stack throws InvalidOperationException — use TryPop // Queue<T : FIFO — first in, first out (jobs, BFS, print queue) var jobs = new Queue<string (); jobs.Enqueue(\"email\"); jobs.Enqueue(\"invoice\"); Console.WriteLine(jobs.Dequeue()); // email Console.WriteLine(jobs.TryPeek(out var next) ? next : \"empty\"); // invoice // PriorityQueue<TElement,TPriority (.NET 6): lowest priority value comes out first var pq = new PriorityQueue<string, int (); pq.Enqueue(\"low\", 5); pq.Enqueue(\"urgent\", 1); Console.WriteLine(pq.Dequeue()); // urgent Collection Ordered by Duplicates Typical use --- --- --- --- SortedList<K,V Key (array-based) Keys unique Small, mostly-read sorted maps SortedDictionary<K,V Key (tree-based) Keys unique Many inserts/removes, sorted HashSet<T / SortedSet<T None / sorted No Uniqueness, set maths Stack<T LIFO Yes Undo, parsing Queue<T FIFO Yes Work queues, BFS"},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"arraylist-and-hashtable-legacy-non-generic-collections","title":"ArrayList and Hashtable (legacy non-generic collections)","body":"You will meet these in old .NET Framework code and in interviews. csharp using System.Collections; var list = new ArrayList(); list.Add(1); // boxed to object list.Add(\"two\"); // anything goes — no type safety list.Add(3.5); foreach (object o in list) Console.WriteLine(o); int first = (int)list[0]!; // cast needed; wrong cast → InvalidCastException at runtime var table = new Hashtable(); table[\"IN\"] = \"India\"; table[\"TW\"] = \"Taiwan\"; table[\"IN\"] = \"Bharat\"; // overwrite Console.WriteLine(table[\"XX\"] == null); // True — missing key returns null (Dictionary throws) foreach (DictionaryEntry e in table) Console.WriteLine($\"{e.Key} = {e.Value}\"); ArrayList List<T Hashtable Dictionary<K,V --- --- --- --- --- Type safety ❌ object ✅ ❌ object ✅ Boxing of value types Yes No Yes No Missing key — — Returns null Throws (use TryGetValue ) Thread safety ArrayList.Synchronized wrapper No (use concurrent collections) Safe for many readers + one writer No Interview tip: \"Hashtable vs Dictionary\" — Dictionary is generic (type-safe, no boxing, faster); a missing key throws in Dictionary but returns null in Hashtable; both are hash-based with O(1) average lookup. Use ConcurrentDictionary for multi-threaded writes."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"tuple-and-valuetuple","title":"Tuple and ValueTuple","body":"csharp // System.Tuple (.NET 4): class, read-only, members named Item1..Item7 Tuple<int, string t1 = Tuple.Create(1, \"Asha\"); Console.WriteLine(t1.Item2); // System.ValueTuple (C 7): struct, mutable fields, can have names, nice syntax (int Id, string Name) t2 = (1, \"Asha\"); Console.WriteLine(t2.Name); t2.Name = \"Ravi\"; (int Min, int Max) MinMax(int[] xs) = (xs.Min(), xs.Max()); // return several values var (min, max) = MinMax([4, 9, 1]); // deconstruction Console.WriteLine($\"{min}-{max}\"); (a, b) = (b, a); // swap without a temp variable var counts = new Dictionary<(string City, int Year), int { [(\"Pune\", 2026)] = 10 }; // tuple as a composite key Tuple<... ValueTuple ( , ) --- --- --- Kind Class (heap) Struct (no allocation) Members Item1 , Item2 … read-only properties Named fields, mutable Equality Value equality via Equals == and Equals compare values Use Legacy APIs Modern code: multiple return values, quick grouping For public APIs with a meaning, prefer a record ( record MinMax(int Min, int Max) ) — tuple names are not part of the type at runtime."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"classes-structs-records-and-enums","title":"Classes, structs, records and enums","body":"csharp public class Customer // reference type, identity semantics { public int Id { get; init; } public required string Name { get; set; } // required (C 11) } public struct Money(decimal amount, string currency) // value type; primary constructor (C 12) { public decimal Amount { get; } = amount; public string Currency { get; } = currency; } public record Order(int Id, decimal Total); // reference type with VALUE equality public record struct Coord(double Lat, double Lng); public enum Status { Pending = 1, Shipped = 2, Delivered = 3 } [Flags] public enum Perm { None = 0, Read = 1, Write = 2, Delete = 4 } var p = Perm.Read Perm.Write; bool canWrite = p.HasFlag(Perm.Write); var o1 = new Order(1, 100); var o2 = o1 with { Total = 120 }; // non-destructive copy Console.WriteLine(o1 == new Order(1, 100)); // True — value equality Choose: class for entities with identity/behaviour; struct for small immutable values (< ~16 bytes, no inheritance); record for DTOs and immutable data compared by value."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"structs-and-enums-in-depth","title":"Structs and enums in depth","body":"Struct rules: csharp public readonly struct Temperature // readonly struct: all fields immutable, compiler-enforced { public double Celsius { get; } public Temperature(double celsius) = Celsius = celsius; public double Fahrenheit = Celsius 9 / 5 + 32; public override string ToString() = $\"{Celsius:0. }°C\"; } var t = new Temperature(36.6); Temperature empty = default; // all fields zero — a struct is never null Temperature? maybe = null; // Nullable<Temperature if you need \"no value\" - Value type: copied on assignment and when passed to methods (unless ref / in ). - No inheritance (sealed, derive from System.ValueType ), but can implement interfaces . - Can have constructors, properties, methods, operators; parameterless constructors and field initialisers allowed since C 10. - Keep structs small and immutable ; a mutable struct inside a collection or property leads to \"I changed a copy\" bugs. Enum in depth: csharp public enum OrderStatus : byte // underlying type (default int) { Pending = 1, Paid = 2, Shipped = 3, Cancelled = 9 } OrderStatus s = OrderStatus.Paid; int code = (int)s; // 2 OrderStatus fromCode = (OrderStatus)3; // Shipped string name = s.ToString(); // \"Paid\" bool ok = Enum.TryParse(\"shipped\", ignoreCase: true, out OrderStatus parsed); bool defined = Enum.IsDefined(typeof(OrderStatus), 5); // false — casts don't validate! foreach (var v in Enum.GetValues<OrderStatus ()) Console.WriteLine(v); [Flags] public enum Permission { None = 0, Read = 1, Write = 2, Delete = 4, All = Read Write Delete } var p = Permission.Read Permission.Write; // combine with OR p = Permission.Delete; // add p &= ~Permission.Write; // remove bool canRead = (p & Permission.Read) != 0; // or p.HasFlag(Permission.Read) Console.WriteLine(p); // \"Read, Delete\" - Enum values are named constants of an integral type; [Flags] values must be powers of two so they can combine as bits. - Any integer can be cast to an enum, even undefined ones — validate input with Enum.IsDefined or a switch with a default. - Store enums in databases as int (stable) or string (readable); never reorder existing values."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"boxing-and-unboxing","title":"Boxing and unboxing","body":"Boxing wraps a value type in an object on the heap; unboxing extracts it back with an explicit cast. csharp int n = 42; object o = n; // boxing: heap allocation + copy int m = (int)o; // unboxing: type check + copy // long l = (long)o; // InvalidCastException — must unbox to the exact type var old = new System.Collections.ArrayList(); old.Add(1); // boxes — avoid non-generic collections var modern = new List<int (); modern.Add(1); // no boxing — generics Cost: an allocation and later GC work. Generics (C 2.0) removed most boxing."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"nullable-types-and-null-safety","title":"Nullable types and null safety","body":"csharp int? maybe = null; // Nullable<int if (maybe.HasValue) Console.WriteLine(maybe.Value); int value = maybe ?? -1; nullable enable // nullable reference types (C 8) — on by default in new projects string name = \"x\"; // must not be null string? middle = null; // may be null Console.WriteLine(middle?.Length); // compiler warns if you dereference without a check string sure = middle!; // null-forgiving operator — you promise it isn't null Nullable reference types are compile-time warnings only ; at runtime a string can still be null if a warning was ignored."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"var-object-initializers-anonymous-types-and-dynamic","title":"var, object initializers, anonymous types and dynamic","body":"var (implicitly typed local, C 3): the compiler infers the type from the right-hand side; the variable is still statically typed. csharp var count = 10; // int var customers = new List<Customer (); // var x; // error — must be initialised // var y = null; // error — no type to infer count = \"ten\"; // error — count is int forever Use var when the type is obvious from the right side or very long; write the type when it helps the reader ( decimal total = GetTotal(); ). Object and collection initializers: set properties right after construction without writing many constructors. csharp var c = new Customer { Id = 1, Name = \"Asha\", Address = new Address { City = \"Pune\" } }; var cities = new List<string { \"Pune\", \"Taipei\" }; var phoneBook = new Dictionary<string, string { [\"Asha\"] = \"98200\", [\"Ravi\"] = \"98300\" }; Customer c2 = new() { Name = \"Ravi\" }; // target-typed new (C 9) The constructor runs first, then each property setter in order. Combine with init / required properties for immutable objects that must be fully initialised. Anonymous types: read-only, compiler-generated classes without a name — mainly for LINQ projections inside one method. csharp var person = new { Name = \"Asha\", Age = 28 }; Console.WriteLine(person.Name); // person.Age = 30; // error — properties are read-only var summary = orders.Select(o = new { o.Id, Total = o.Lines.Sum(l = l.Price) }); // property names inferred Console.WriteLine(new { A = 1 }.Equals(new { A = 1 })); // True — value equality Limits: only usable with var (no type name), can't be returned from a method in a typed way (use a record or tuple instead), properties only. dynamic (C 4): type checking moves from compile time to runtime (Dynamic Language Runtime). csharp dynamic d = 10; d = \"now a string\"; // allowed Console.WriteLine(d.Length); // resolved at runtime → 12 // d.NoSuchMethod(); // compiles, but throws RuntimeBinderException at runtime dynamic bag = new ExpandoObject(); // add members at runtime bag.Name = \"Asha\"; bag.Greet = (Func<string )(() = $\"Hi {bag.Name}\"); Console.WriteLine(bag.Greet()); // used for COM interop (Office), dynamic languages, loose data var object dynamic --- --- --- --- Type decided Compile time (inferred) Compile time ( object ) Runtime IntelliSense / compile errors ✅ Only object members ❌ Needs casting No Yes No Performance Normal Boxing for value types Slower (runtime binding) Interview tip: \"Is var the same as dynamic ?\" — No. var is just shorthand; the compiler fixes the type at compile time. dynamic skips compile-time checks and binds at runtime, so mistakes become runtime exceptions."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"properties-indexers-static-and-const-vs-readonly","title":"Properties, indexers, static and const vs readonly","body":"csharp public class Account { private decimal balance; public decimal Balance { get = balance; private set = balance = value = 0 ? value : throw new ArgumentException(); } public string Owner { get; init; } = \"\"; // settable only during initialisation public static int Count { get; private set; } // shared by all instances public string Tier { get; set { field = value.Trim(); } } = \"\"; // C 14 'field' keyword public decimal this[int month] = history[month]; // indexer private readonly decimal[] history = new decimal[12]; } const readonly static readonly --- --- --- Compile-time constant, implicitly static Per instance, set in declaration or constructor One per type, set at runtime once Only primitives/strings Any type Any type Value is copied into calling assemblies — changing it requires recompiling callers Read at runtime Read at runtime"},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"method-parameters-ref-out-in-params-optional-named","title":"Method parameters: ref, out, in, params, optional, named","body":"csharp void Swap(ref int a, ref int b) { (a, b) = (b, a); } // caller's variables change bool TryParseAge(string s, out int age) = int.TryParse(s, out age); // must assign double Length(in Vector3 v) = Math.Sqrt(v.X v.X); // read-only by reference (avoids copy of big struct) int Sum(params int[] xs) = xs.Sum(); // Sum(1,2,3) void Send(string to, string subject = \"Hi\", bool urgent = false) { } int x = 1, y = 2; Swap(ref x, ref y); Send(\"a@b.com\", urgent: true); // named argument skips optional ones - Pass by value (default): for reference types the reference is copied, so the method can mutate the object but cannot make the caller point to a different one — unless you use ref ."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"delegates-func-action-events-and-lambdas","title":"Delegates, Func, Action, events and lambdas","body":"A delegate is a type-safe reference to a method. Func<..., TResult returns a value, Action<... returns void, Predicate<T returns bool. csharp Func<int, int, int add = (a, b) = a + b; Action<string log = msg = Console.WriteLine(msg); Predicate<int isEven = n = n % 2 == 0; public class Thermostat { public event EventHandler<double ? TooHot; // event = delegate with restricted access public void Read(double t) { if (t 40) TooHot?.Invoke(this, t); } } var th = new Thermostat(); th.TooHot += (s, t) = Console.WriteLine($\"Alert {t}\"); th.Read(45); - Event vs delegate: outside the class, an event can only be subscribed ( += ) or unsubscribed ( -= ); it cannot be invoked or reassigned. - Multicast: a delegate can hold several methods; all are invoked in order. - Closure: a lambda captures variables from the outer scope (by reference, not by value)."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"anonymous-methods-predicate-and-multicast-delegates","title":"Anonymous methods, Predicate and multicast delegates","body":"From named method → anonymous method → lambda (the same delegate, three syntaxes through C history): csharp public delegate int Calc(int a, int b); // custom delegate type: the method \"signature\" static int Add(int a, int b) = a + b; Calc c1 = Add; // C 1: named method Calc c2 = delegate (int a, int b) { return a b; }; // C 2: anonymous method Calc c3 = (a, b) = a - b; // C 3: lambda expression Console.WriteLine(c1(4, 2) + c2(4, 2) + c3(4, 2)); // 6 + 8 + 2 = 16 Anonymous methods can omit the parameter list ( delegate { ... } ) when you ignore the parameters; otherwise lambdas replaced them. Built-in generic delegates: Delegate Signature Example --- --- --- Func<T1, ..., TResult Up to 16 inputs, returns TResult Func<decimal, decimal tax = p = p 0.18m; Action<T1, ... Up to 16 inputs, returns void Action<string log = Console.WriteLine; Predicate<T One input, returns bool Predicate<int isAdult = age = age = 18; csharp var ages = new List<int { 12, 25, 17, 40 }; Predicate<int isAdult = a = a = 18; List<int adults = ages.FindAll(isAdult); // List<T .FindAll/Find/RemoveAll take Predicate<T Func<int, bool sameIdea = a = a = 18; // LINQ uses Func<T,bool : ages.Where(sameIdea) Multicast delegates: one delegate instance can hold an invocation list of several methods. csharp static void Email(string msg) = Console.WriteLine($\"Email: {msg}\"); static void Sms(string msg) = Console.WriteLine($\"SMS: {msg}\"); Action<string notify = Email; notify += Sms; notify += msg = Console.WriteLine($\"Push: {msg}\"); notify(\"Order shipped\"); // all three run, in order notify -= Sms; // remove works with the same method; a lambda can't be removed unless you kept a reference to it notify(\"Delivered\"); // Email + Push Func<int f = () = 1; f += () = 2; Console.WriteLine(f()); // 2 — only the LAST return value is kept If one handler throws, the remaining handlers don't run — loop over GetInvocationList() and wrap each call in try/catch when you need isolation."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"extension-methods-generics-and-constraints","title":"Extension methods, generics and constraints","body":"csharp public static class StringExtensions { public static bool IsEmail(this string s) = s.Contains('@'); // call as \"x@y.com\".IsEmail() } public class Repository<T where T : class, IEntity, new() { private readonly List<T items = []; public T Create() { var t = new T(); items.Add(t); return t; } } T Max<T (T a, T b) where T : IComparable<T = a.CompareTo(b) = 0 ? a : b; Constraints: where T : class , struct , new() , notnull , unmanaged , a base class, an interface, or T : U . Covariance / contravariance: IEnumerable<out T lets IEnumerable<string be used as IEnumerable<object ; Action<in T lets Action<object be used as Action<string — see the next lesson."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"covariance-and-contravariance","title":"Covariance and contravariance","body":"Variance answers: \"if Dog is an Animal , can a Something<Dog be used where a Something<Animal is expected?\" Term Direction Keyword Works when T is… Example --- --- --- --- --- Covariance Dog → Animal (more derived to less) out T only returned (output) IEnumerable<out T , Func<out TResult , IReadOnlyList<out T Contravariance Animal → Dog (less derived to more) in T only accepted (input) Action<in T , IComparer<in T , Predicate<in T Invariance Exact type only — both in and out List<T , IList<T , Dictionary<K,V csharp class Animal { public string Name = \"\"; } class Dog : Animal { } IEnumerable<Dog dogs = new List<Dog { new() { Name = \"Rex\" } }; IEnumerable<Animal animals = dogs; // ✅ covariance: you only read Animals out of it Action<Animal feed = a = Console.WriteLine($\"Feeding {a.Name}\"); Action<Dog feedDog = feed; // ✅ contravariance: something that handles any Animal can handle a Dog Func<Dog makeDog = () = new Dog(); Func<Animal makeAnimal = makeDog; // ✅ covariant return // List<Animal list = new List<Dog (); // ❌ invariant: otherwise you could Add(new Cat()) into a list of dogs // Your own variant interface public interface IProducer<out T { T Produce(); } // T only in output positions public interface IConsumer<in T { void Consume(T item); } // T only in input positions Arrays are covariant too ( object[] objs = new string[3]; ), but it's unsafe : objs[0] = 1; compiles and throws ArrayTypeMismatchException at runtime — one reason to prefer generic collections. Interview tip: Remember \" out = things come out (return values) → covariance; in = things go in (parameters) → contravariance\". Variance works only for interfaces and delegates, and only with reference types ( IEnumerable<int is not an IEnumerable<object )."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"pattern-matching-tuples-and-deconstruction","title":"Pattern matching, tuples and deconstruction","body":"csharp object shape = new Circle(2); double area = shape switch { Circle { Radius: var r } = Math.PI r r, // property pattern Rectangle(var w, var h) = w h, // positional pattern null = throw new ArgumentNullException(nameof(shape)), = 0 }; if (order is { Status: Status.Shipped, Total: 1000 }) { / ... / } int[] arr = [1, 2, 3]; if (arr is [1, .., var last]) Console.WriteLine(last); // list pattern (C 11) (string Name, int Age) GetUser() = (\"Asha\", 28); // tuple var (name, age) = GetUser(); // deconstruction"},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"exception-handling","title":"Exception handling","body":"csharp try { var text = File.ReadAllText(path); } catch (FileNotFoundException ex) when (path.EndsWith(\".cfg\")) // exception filter { logger.LogWarning(ex, \"Config missing\"); } catch (IOException ex) { throw new ConfigException(\"Could not read config\", ex); // wrap, keep inner exception } finally { // always runs (cleanup) } - throw; rethrows and keeps the original stack trace ; throw ex; resets it — avoid. - Catch specific exceptions first, general ones last. - Don't use exceptions for normal control flow; use TryParse -style APIs. - Custom exception: derive from Exception , provide the standard constructors (next lesson)."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"built-in-exceptions-throw-and-custom-exceptions","title":"Built-in exceptions, throw and custom exceptions","body":"Exception hierarchy: everything derives from System.Exception . Common built-in exceptions: Exception Thrown when --- --- NullReferenceException You use a member of a null reference ArgumentException / ArgumentNullException / ArgumentOutOfRangeException A method receives an invalid argument (throw these yourself to validate input) InvalidOperationException The object's state doesn't allow the call (e.g. modifying a list during foreach , First() on empty sequence) IndexOutOfRangeException Array index outside its bounds KeyNotFoundException Dictionary indexer with a missing key InvalidCastException Bad explicit cast / unboxing to the wrong type FormatException int.Parse(\"abc\") OverflowException checked arithmetic overflows DivideByZeroException Integer division by zero ( double gives Infinity instead) FileNotFoundException , DirectoryNotFoundException , IOException File system problems NotImplementedException / NotSupportedException Method not written yet / operation not supported by design TimeoutException , OperationCanceledException / TaskCanceledException Timeouts and cancellation HttpRequestException HttpClient call failed OutOfMemoryException , StackOverflowException Runtime failures — the latter can't be caught and kills the process Throwing: csharp public void Withdraw(decimal amount) { ArgumentOutOfRangeException.ThrowIfNegativeOrZero(amount); // .NET 8 throw helpers if (amount Balance) throw new InsufficientFundsException(Balance, amount); Balance -= amount; } public Customer(string name) = Name = name ?? throw new ArgumentNullException(nameof(name)); // throw expression try { Save(); } catch (SqlException ex) { log.LogError(ex, \"Save failed\"); throw; // ✅ rethrow keeps the original stack trace // throw ex; // ❌ resets the stack trace to this line } Custom exception: csharp public class InsufficientFundsException : Exception { public decimal Balance { get; } public decimal Requested { get; } public InsufficientFundsException() { } public InsufficientFundsException(string message) : base(message) { } public InsufficientFundsException(string message, Exception inner) : base(message, inner) { } public InsufficientFundsException(decimal balance, decimal requested) : base($\"Balance {balance} is less than requested {requested}.\") = (Balance, Requested) = (balance, requested); } try { account.Withdraw(5000); } catch (InsufficientFundsException ex) when (ex.Requested 1000) { Console.WriteLine($\"Large withdrawal refused: {ex.Message}\"); } Guidelines: name ends with Exception ; derive from Exception (not ApplicationException ); add properties with useful data; create custom exceptions only when callers will catch them specifically — otherwise use the built-in ones."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"idisposable-using-and-the-garbage-collector","title":"IDisposable, using and the garbage collector","body":"The GC frees managed memory automatically. It is generational : Gen 0 (new, collected often), Gen 1 (buffer), Gen 2 (long-lived). Objects ≥ 85,000 bytes go to the Large Object Heap . Unmanaged resources (file handles, sockets, DB connections) must be released deterministically with IDisposable : csharp using (var conn = new SqlConnection(cs)) // classic using block { conn.Open(); } using var file = File.OpenRead(\"data.csv\"); // using declaration (C 8): disposed at end of scope await using var stream = new FileStream(...); // IAsyncDisposable public sealed class Wrapper : IDisposable { private readonly SafeHandle handle; private bool disposed; public void Dispose() { if ( disposed) return; handle.Dispose(); disposed = true; } } - Finalizer ( ~ClassName() ) runs on the finaliser thread at an unknown time; only needed when you own a raw unmanaged handle. Call GC.SuppressFinalize(this) in Dispose when a finaliser exists. - Calling GC.Collect() manually is almost always wrong."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"span-t-memory-t-and-performance-basics","title":"Span<T>, Memory<T> and performance basics","body":"Span<T is a ref struct view over contiguous memory (array, stack, native) with no allocation . csharp ReadOnlySpan<char line = \"2026-10-20,Pune,42\"; int comma = line.IndexOf(','); ReadOnlySpan<char date = line[..comma]; // slice — no new string int value = int.Parse(line[(line.LastIndexOf(',') + 1)..]); Span<byte buffer = stackalloc byte[256]; // stack memory, no GC - Span<T cannot be stored on the heap (no fields in classes, no boxing). Use Memory<T when you need to keep it or use it across await . - Other tools: ArrayPool<T .Shared , StringBuilder pooling, avoiding LINQ in hot loops, struct enumerators."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"file-directory-and-path-quick-file-operations","title":"File, Directory and Path — quick file operations","body":"The static classes in System.IO do one-line file work: csharp string folder = Path.Combine(AppContext.BaseDirectory, \"data\"); // builds paths with the right separator (\\ or /) Directory.CreateDirectory(folder); // no error if it already exists string file = Path.Combine(folder, \"notes.txt\"); File.WriteAllText(file, \"Line 1\\n\"); // create or overwrite File.AppendAllText(file, \"Line 2\\n\"); // add to the end File.WriteAllLines(file, [\"a\", \"b\", \"c\"]); string all = File.ReadAllText(file); string[] lines = File.ReadAllLines(file); // whole file in memory foreach (var line in File.ReadLines(file)) // lazy — one line at a time, good for big files Console.WriteLine(line); if (File.Exists(file)) File.Copy(file, Path.Combine(folder, \"backup.txt\"), overwrite: true); File.Move(file, Path.Combine(folder, \"renamed.txt\")); File.Delete(Path.Combine(folder, \"backup.txt\")); foreach (var csv in Directory.EnumerateFiles(folder, \" .csv\", SearchOption.AllDirectories)) Console.WriteLine(Path.GetFileName(csv)); Console.WriteLine(Path.GetExtension(\"report.pdf\")); // .pdf Console.WriteLine(Path.GetFileNameWithoutExtension(\"report.pdf\")); // report string temp = Path.GetTempFileName(); await File.WriteAllTextAsync(file, \"async version\"); // async versions for servers/UI apps Watch out for: missing folders ( DirectoryNotFoundException ), files locked by another process ( IOException ), permissions ( UnauthorizedAccessException ), and building paths with string concatenation (use Path.Combine ). Never build paths from user input without validating them (path traversal like ..\\..\\web.config )."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"fileinfo-and-directoryinfo","title":"FileInfo and DirectoryInfo","body":"FileInfo / DirectoryInfo are instance classes: create one object for a path and use its properties and methods repeatedly (security checks happen once, and you get metadata). csharp var info = new FileInfo(@\"C:\\data\\orders.csv\"); if (info.Exists) { Console.WriteLine($\"{info.Name} {info.Length / 1024} KB, modified {info.LastWriteTime:g}\"); Console.WriteLine(info.Extension); // .csv Console.WriteLine(info.DirectoryName); // C:\\data info.CopyTo(@\"C:\\archive\\orders.csv\", overwrite: true); using StreamReader reader = info.OpenText(); Console.WriteLine(reader.ReadLine()); } var dir = new DirectoryInfo(@\"C:\\data\"); foreach (FileInfo f in dir.GetFiles(\" .log\").Where(f = f.LastWriteTime < DateTime.Now.AddDays(-30))) f.Delete(); // clean up logs older than 30 days DirectoryInfo sub = dir.CreateSubdirectory(\"2026\"); File / Directory (static) FileInfo / DirectoryInfo (instance) --- --- --- Usage One-off operations Several operations on the same file/folder Metadata Separate calls ( File.GetLastWriteTime ) Properties ( Length , CreationTime , Attributes ) Refresh Always current Cached — call Refresh() for fresh values"},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"streams-streamreader-streamwriter-and-async-file-i-o","title":"Streams, StreamReader/StreamWriter and async file I/O","body":"A stream is a sequence of bytes you read or write piece by piece, so huge files never need to fit in memory. Stream is the abstract base for FileStream , MemoryStream , NetworkStream , BufferedStream , GZipStream , CryptoStream … csharp // Text: StreamWriter / StreamReader wrap a stream and handle encoding (UTF-8 by default) using (var writer = new StreamWriter(\"log.txt\", append: true)) { writer.WriteLine($\"{DateTime.UtcNow:O} Started\"); } // Dispose flushes and closes the file using var reader = new StreamReader(\"big.csv\"); string? line; long count = 0; while ((line = await reader.ReadLineAsync()) != null) // streams line by line if (line.Contains(\"ERROR\")) count++; // Bytes: FileStream with explicit options await using var fs = new FileStream(\"photo.jpg\", FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 81920, useAsync: true); var buffer = new byte[81920]; int read; while ((read = await fs.ReadAsync(buffer)) 0) { / process buffer[..read] / } // Copy one stream into another (e.g. upload → Blob storage, file → HTTP response) await using var source = File.OpenRead(\"report.pdf\"); await using var target = File.Create(\"copy.pdf\"); await source.CopyToAsync(target); // MemoryStream: a stream over a byte[] in memory — handy for tests and in-memory files using var ms = new MemoryStream(); await JsonSerializer.SerializeAsync(ms, new { Id = 1 }); byte[] json = ms.ToArray(); // Compression by chaining streams await using var zip = new GZipStream(File.Create(\"data.gz\"), CompressionLevel.Optimal); await using var zipWriter = new StreamWriter(zip); await zipWriter.WriteAsync(\"compressed text\"); Class Purpose --- --- FileStream Read/write bytes in a file ( FileMode : Create, Open, Append, OpenOrCreate) StreamReader / StreamWriter Text on top of any stream, with encoding BinaryReader / BinaryWriter Primitive types as binary MemoryStream In-memory byte buffer BufferedStream , GZipStream , CryptoStream Decorators that add buffering, compression, encryption Interview tip: Always dispose streams ( using / await using ) — otherwise file handles stay locked and buffered data may never be written. Use async I/O in web apps so threads aren't blocked while waiting for the disk."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"async-and-await","title":"async and await","body":"async / await lets a method wait for I/O without blocking a thread . The compiler rewrites the method into a state machine. csharp public async Task<string GetPageAsync(HttpClient http, string url, CancellationToken ct) { var response = await http.GetAsync(url, ct); // thread returns to pool while waiting response.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync(ct); } // run independent calls concurrently var t1 = GetPageAsync(http, \"https://a.example\", ct); var t2 = GetPageAsync(http, \"https://b.example\", ct); string[] pages = await Task.WhenAll(t1, t2); Rules: - Return Task / Task<T (or ValueTask<T for hot paths that often complete synchronously). async void only for event handlers. - Don't block on async code with .Result or .Wait() — it can deadlock in UI/old ASP.NET contexts and wastes threads. - Pass CancellationToken through. - In library code, ConfigureAwait(false) avoids capturing the synchronisation context (ASP.NET Core has none). Interview tip: async is about scalability , not speed. One request doesn't get faster; the server handles more concurrent requests because threads aren't blocked waiting on I/O."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"threads-tasks-parallel-and-thread-safety","title":"Threads, Tasks, Parallel and thread safety","body":"Tool Use for --- --- Thread Rarely directly; dedicated long-running thread Task.Run Push CPU-bound work to the thread pool Parallel.For/ForEach/ForEachAsync Data parallelism over collections PLINQ .AsParallel() Parallel LINQ queries Channel<T Producer/consumer pipelines csharp private readonly Lock gate = new(); // C 13 / .NET 9 (use 'object' on older versions) private int count; public void Increment() { lock ( gate) { count++; } } Interlocked.Increment(ref hits); // lock-free atomic counter var cache = new ConcurrentDictionary<string, User (); var user = cache.GetOrAdd(id, LoadUser); using var sem = new SemaphoreSlim(3); // at most 3 concurrent operations await sem.WaitAsync(); try { await CallApiAsync(); } finally { sem.Release(); } Race condition: two threads read-modify-write shared state without synchronisation. Deadlock: two threads each hold a lock the other needs — avoid by always taking locks in the same order and keeping lock scopes small. You cannot await inside a lock block — use SemaphoreSlim ."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"ienumerable-yield-and-async-streams","title":"IEnumerable, yield and async streams","body":"csharp IEnumerable<int Evens(int max) { for (int i = 0; i <= max; i += 2) yield return i; // lazy: produced one at a time when iterated } async IAsyncEnumerable<Order ReadOrdersAsync([EnumeratorCancellation] CancellationToken ct = default) { await foreach (var row in db.StreamAsync(ct)) yield return Map(row); } await foreach (var o in ReadOrdersAsync()) Console.WriteLine(o.Id); Deferred execution: nothing runs until you enumerate ( foreach , ToList() , Count() ). Enumerating twice runs the work twice."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"reflection-attributes-and-dynamic","title":"Reflection, attributes and dynamic","body":"csharp [AttributeUsage(AttributeTargets.Property)] public sealed class MaskAttribute : Attribute { } public class User { public string Name { get; set; } = \"\"; [Mask] public string Pan { get; set; } = \"\"; } foreach (var prop in typeof(User).GetProperties()) { bool masked = prop.GetCustomAttribute<MaskAttribute () is not null; Console.WriteLine($\"{prop.Name}: {(masked ? \" \" : prop.GetValue(user))}\"); } dynamic d = JsonSerializer.Deserialize<ExpandoObject (json)!; // resolved at runtime (DLR) Reflection is slow-ish and not trim/AOT-friendly; modern .NET prefers source generators (e.g. System.Text.Json source-gen, [LoggerMessage] , [GeneratedRegex] )."},{"kind":"lesson","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"what-s-new-in-csharp-12-13-and-14","title":"What's new in C# 12, 13 and 14","body":"csharp // C 12 — primary constructors and collection expressions public class OrderService(IOrderRepo repo, ILogger<OrderService log) { public Task<Order? Get(int id) = repo.FindAsync(id); } int[] a = [1, 2, 3]; // C 13 — params collections and the Lock type void Log(params ReadOnlySpan<string parts) { } Lock gate = new(); // C 14 — extension members, field keyword, null-conditional assignment public static class EnumerableExtensions { extension<T (IEnumerable<T source) { public bool IsEmpty = !source.Any(); // extension PROPERTY } } customer?.Address = newAddress; // assigns only if customer is not null"},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"107","title":"What is the difference between a value type and a reference type?","body":"A value type variable holds the data itself ( int , bool , decimal , DateTime , any struct / enum ). Assigning it copies the value. A reference type variable holds a reference to an object on the managed heap ( class , string , arrays, delegates, record ). Assigning it copies the reference, so two variables can point to the same object. csharp var a = new List<int (); var b = a; b.Add(1); // a.Count == 1 — same object int x = 1; int y = x; y++; // x is still 1 Value types are stored inline (stack for locals, inside the parent object for fields); reference-type objects always live on the heap and are cleaned up by the GC."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"108","title":"What is the difference between `string` and `StringBuilder`?","body":"string is immutable : every concatenation creates a new string object, so building a string in a loop causes many allocations (O(n²) copying). StringBuilder keeps a mutable buffer and appends in place; call ToString() once at the end. Use StringBuilder for loops or many appends, plain strings/interpolation for a handful of pieces."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"109","title":"Explain `const` vs `readonly` vs `static readonly`.","body":"- const : compile-time constant, implicitly static, only primitives/strings; the value is baked into callers at compile time. - readonly : instance field assigned at declaration or in a constructor; can differ per object. - static readonly : one value per type, computed at runtime (e.g. static readonly HttpClient Client = new() ). Gotcha: if library A has public const int Max = 10 and app B uses it, changing it to 20 in A does nothing in B until B is recompiled. Use static readonly for values that may change."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"110","title":"What are boxing and unboxing? Why avoid them?","body":"Boxing converts a value type to object (or an interface) by allocating a heap object and copying the value; unboxing casts it back to the exact value type. It costs an allocation, a copy and GC pressure. Typical sources: non-generic collections ( ArrayList ), string.Format with value-type arguments on old APIs, calling interface methods on structs via the interface. Generics remove most boxing."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"111","title":"What is the difference between `==` and `.Equals()`?","body":"For reference types , == compares references unless the operator is overloaded; Equals() is virtual and can be overridden to compare content. string overloads both to compare text. Records generate value-based Equals and == . For value types, Equals compares content. When you override Equals , also override GetHashCode (objects that are equal must have the same hash code, or dictionaries break)."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"112","title":"What are `ref`, `out` and `in` parameters?","body":"All three pass an argument by reference : - ref — must be initialised before the call; the method can read and change it. - out — need not be initialised; the method must assign it (used by TryParse ). - in — read-only reference; avoids copying large structs."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"113","title":"What is the difference between `var`, `dynamic` and `object`?","body":"var is compile-time type inference — the variable is strongly typed ( var x = 5 is an int ). object is the base type; you need casts to use members. dynamic skips compile-time checks and resolves members at runtime through the DLR; errors appear as RuntimeBinderException . Use dynamic only for COM interop, dynamic JSON or scripting scenarios."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"114","title":"What is the difference between an array, `ArrayList` and `List<T>`?","body":"An array has a fixed size and a single element type. ArrayList (non-generic, legacy) stores object , so value types get boxed and you need casts. List<T is generic, type-safe, resizable (it doubles its internal array when full) and has no boxing. Always prefer List<T ."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"115","title":"Explain `IEnumerable`, `ICollection`, `IList` and `IQueryable`.","body":"- IEnumerable<T : forward-only iteration ( foreach ), deferred execution with LINQ to Objects, runs in memory . - ICollection<T : adds Count , Add , Remove , Contains . - IList<T : adds index access and Insert . - IQueryable<T : builds an expression tree that a provider (EF Core) translates to SQL and runs in the database . csharp db.Orders.Where(o = o.Total 100).ToList(); // IQueryable: WHERE in SQL db.Orders.AsEnumerable().Where(o = o.Total 100).ToList(); // loads ALL rows then filters in memory"},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"116","title":"What are delegates and events? How do they differ?","body":"A delegate is a type-safe function pointer ( Func , Action , custom delegate ). It can be multicast. An event wraps a delegate so outside code can only += / -= handlers; only the declaring class can raise it. This prevents subscribers from wiping out other handlers ( = null ) or raising the event themselves. Pattern: public event EventHandler<TArgs ? Changed; and raise with Changed?.Invoke(this, args) ."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"117","title":"How does async/await work internally? Does it create a new thread?","body":"No new thread is created by await . The compiler turns the method into a state machine . When it hits await on an incomplete task, the method returns to its caller and the thread goes back to the pool. When the I/O completes, a continuation resumes the state machine — on the captured synchronisation context if there is one (UI thread), otherwise on a thread-pool thread. CPU-bound work still needs Task.Run or parallelism to move off the current thread."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"118","title":"What is the difference between `Task.WhenAll` and awaiting tasks one by one?","body":"Awaiting sequentially makes total time the sum of the calls; starting all tasks and then await Task.WhenAll(...) makes it roughly the longest single call. WhenAll throws the first exception when awaited, but the returned task's Exception holds all of them. Use WhenAny for \"first to finish\" or timeouts."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"119","title":"Why is `async void` dangerous?","body":"Callers can't await it, so they can't know when it finishes, and an exception thrown inside crashes the process (it is raised on the synchronisation context instead of being stored in a Task). Use async Task everywhere except event handlers."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"120","title":"What is `IDisposable` and the `using` statement? Dispose vs Finalize?","body":"IDisposable.Dispose() releases unmanaged resources (connections, file handles) deterministically . using guarantees Dispose is called even if an exception is thrown (compiles to try/finally ). A finaliser is called by the GC at an unpredictable time and costs an extra GC cycle; it is only a safety net for raw unmanaged handles. In Dispose call GC.SuppressFinalize(this) if a finaliser exists. Most code just wraps SafeHandle and never writes a finaliser."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"121","title":"Explain garbage collection generations.","body":"The heap is split into Gen 0 (new objects, collected very often and cheaply), Gen 1 (survivors of Gen 0, a buffer), and Gen 2 (long-lived objects, collected rarely and expensively). Most objects die young, so collecting Gen 0 frequently is efficient. Objects of 85,000 bytes or more go to the Large Object Heap , collected with Gen 2. .NET has workstation and server GC modes, plus background (concurrent) GC for Gen 2."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"122","title":"What are extension methods? Any limitations?","body":"Static methods in a static class whose first parameter has this , called as if they were instance methods. LINQ is built on them. Limitations: they can't access private members, an instance method with the same signature always wins, and they're resolved at compile time (no polymorphism). C 14 adds extension members (properties, static members) via extension blocks."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"123","title":"What is the difference between `struct` and `class`?","body":"Struct: value type, copied on assignment, no inheritance (can implement interfaces), can't have a parameterless constructor before C 10, ideal for small immutable data. Class: reference type, supports inheritance and polymorphism, lives on the heap, compared by reference by default. Large mutable structs are a common bug source (you modify a copy)."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"124","title":"What are records and when do you use them?","body":"record (C 9) is a class with value-based equality , a generated ToString , deconstruction and with expressions for non-destructive copies. record struct (C 10) is the value-type version. Use them for DTOs, messages, events and value objects. Avoid them for EF Core entities that are tracked by identity and mutated."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"125","title":"What are generics and what problem do they solve?","body":"Generics let you write type-safe code once for many types ( List<T , Repository<T ). They remove casts and boxing, and errors show up at compile time. Constraints ( where T : class, new() ) restrict which types can be used. For value types the JIT generates specialised code; for reference types the code is shared."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"126","title":"What is the difference between `throw` and `throw ex`?","body":"throw; rethrows the current exception and preserves the original stack trace . throw ex; throws it again from the current line, losing where it really failed. To add context, throw a new exception and pass the original as innerException ."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"127","title":"Why should you use `decimal` instead of `double` for money?","body":"double is binary floating point and can't represent many base-10 fractions exactly (0.1 + 0.2 != 0.3), so totals drift by tiny amounts that show up in invoices and reports. decimal stores base-10 digits exactly with 28–29 significant digits. Trade-off: decimal is slower and uses 16 bytes, so use double for scientific/graphics maths and decimal for money and quantities that must add up exactly. In SQL Server map it to DECIMAL(18,2) , not FLOAT ."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"128","title":"What is the difference between `Parse`, `TryParse` and `Convert`?","body":"int.Parse(\"x\") throws FormatException for bad input (and ArgumentNullException for null). int.TryParse(s, out var n) returns false instead of throwing — use it for user input. Convert.ToInt32(value) accepts many types (object, double, string), returns 0 for null , and rounds doubles to the nearest even number ( Convert.ToInt32(2.5) → 2) whereas a cast truncates ( (int)2.9 → 2). Pass a CultureInfo when parsing numbers and dates from files or APIs."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"129","title":"What is the difference between `Dictionary` and `Hashtable`?","body":"Dictionary<TKey,TValue is generic: type-safe, no boxing, faster; a missing key with the indexer throws KeyNotFoundException (use TryGetValue ). Hashtable is the old non-generic version storing object keys/values: needs casts, boxes value types, and returns null for a missing key. Both are hash tables with O(1) average lookup. For multiple threads use ConcurrentDictionary ."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"130","title":"What is the difference between a multidimensional and a jagged array?","body":"A multidimensional (rectangular) array int[,] is one object where every row has the same length, accessed as a[r, c] . A jagged array int[][] is an array of arrays — each row is a separate array and can have a different length, accessed as a[r][c] . Jagged arrays are more flexible and often faster in .NET; rectangular arrays suit fixed grids such as matrices."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"131","title":"When do you use for, foreach, while and do-while?","body":"for when you need the index or a counted loop; foreach to read every item of any IEnumerable (cleanest, but you can't add/remove items of a List inside it); while to repeat while a condition is true (may run zero times); do-while when the body must run at least once (menus, retry prompts). break exits the loop, continue skips to the next iteration."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"132","title":"What is a namespace? Explain the two meanings of `using`.","body":"A namespace groups related types and prevents name clashes ( Shop.Models.Order vs Billing.Order ). The using directive ( using System.Text; ) imports a namespace — plus using static , aliases and global using . The using statement/declaration ( using var conn = new SqlConnection(...) ) calls Dispose() automatically at the end of the scope, even if an exception is thrown."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"133","title":"What are anonymous types?","body":"Compiler-generated, unnamed classes with read-only properties, created with new { Name = \"Asha\", Age = 28 } and used through var . They have value-based Equals / GetHashCode , and are mostly used for LINQ projections within one method. They can't be returned in a typed way or have methods — use a record or a tuple for that."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"134","title":"What is the difference between Stack and Queue?","body":"Stack<T is LIFO — Push adds to the top, Pop removes the most recent, Peek reads it (undo, expression parsing, DFS). Queue<T is FIFO — Enqueue adds at the back, Dequeue removes the oldest (job processing, BFS, buffering). Both are O(1) for add/remove; TryPop / TryDequeue avoid exceptions on empty collections; PriorityQueue<T,P dequeues by priority."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"135","title":"How do you create a custom exception, and when should you?","body":"Derive from Exception , end the name with Exception , provide the standard constructors (parameterless, message, message + inner exception) plus constructors/properties for useful data (e.g. Balance , Requested ). Create one only when callers need to catch that specific situation (e.g. InsufficientFundsException → show a friendly message or return 409); otherwise throw the built-in ones ( ArgumentException , InvalidOperationException ). Always pass the inner exception when wrapping."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"136","title":"What is the difference between `Tuple` and `ValueTuple`?","body":"Tuple<T1,... (.NET 4) is a class on the heap with read-only Item1 , Item2 properties. ValueTuple (C 7, syntax (int Id, string Name) ) is a struct — no allocation — with named, mutable fields, deconstruction ( var (id, name) = ... ) and == support. Use ValueTuple for returning several values from private/internal methods; use a record for public APIs because tuple element names are not kept at runtime."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"137","title":"What is the difference between `Func`, `Action` and `Predicate`?","body":"All are built-in generic delegate types. Func<T1..., TResult takes up to 16 inputs and returns a value ( Func<int,int,int add ). Action<T1... takes inputs and returns void ( Action<string log ). Predicate<T takes one input and returns bool , used by List<T .Find/FindAll/RemoveAll ; LINQ uses Func<T,bool for the same idea."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"138","title":"What is a multicast delegate?","body":"A delegate whose invocation list contains several methods, built with += and reduced with -= . Invoking it calls each method in order; for delegates with a return value only the last result is returned, and an exception in one handler stops the rest. Events are built on multicast delegates — that's how many subscribers receive one event."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"139","title":"How do you read a very large file efficiently in C#?","body":"Stream it instead of loading it all: File.ReadLines(path) (lazy IEnumerable<string ) or a StreamReader with ReadLineAsync in a loop, a FileStream with a reasonable buffer for binary data, and CopyToAsync to move data between streams. Avoid File.ReadAllText/ReadAllLines for large files (whole file in memory), dispose streams with using , and use async I/O in server apps."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"140","title":"DateTime vs DateTimeOffset — which should you store?","body":"DateTime holds a date/time with a Kind (Local, Utc, Unspecified) but no offset, so the same value can mean different instants on different servers. DateTimeOffset stores the instant plus the UTC offset, so it is unambiguous. Store UTC ( DateTime.UtcNow or DateTimeOffset ) in databases and APIs, convert to the user's time zone only for display, use DateOnly for pure dates like birthdays, and TimeProvider to make \"now\" testable."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"141","title":"What is a `[Flags]` enum?","body":"An enum whose values are powers of two ( Read = 1, Write = 2, Delete = 4 ) so several can be combined in one value with bitwise OR ( Read Write ). Test with (value & Flag) != 0 or HasFlag , remove with value &= ~Flag . [Flags] also makes ToString() print \"Read, Write\". Typical for permissions and options."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"142","title":"How do you make code thread-safe? Compare lock, Monitor, SemaphoreSlim, Interlocked and concurrent collections.","body":"- lock (sugar for Monitor.Enter/Exit ): mutual exclusion inside one process, synchronous only. - SemaphoreSlim : limits concurrency to N and supports WaitAsync , so use it when you must await inside the critical section. - Interlocked : atomic operations on single variables (increment, compare-exchange), lock-free. - ConcurrentDictionary / ConcurrentQueue / Channel<T : built-in thread-safe structures. - Immutability: data that never changes needs no locks. - Across processes/servers: database locks, distributed locks (Redis, blob leases), Mutex for the same machine."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"143","title":"What causes a deadlock with async code and how do you avoid it?","body":"Classic case: in a UI app or old ASP.NET (with a synchronisation context), code calls task.Result . The blocked thread holds the context; the awaited method's continuation needs the same context to resume, so both wait forever. Fixes: go async all the way ( await instead of .Result ), use ConfigureAwait(false) in library code, and never mix blocking and async calls. ASP.NET Core has no synchronisation context, but blocking still causes thread-pool starvation under load."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"144","title":"What are `Span<T>` and `Memory<T>`?","body":"Span<T is a stack-only ( ref struct ) view over contiguous memory: arrays, stackalloc or native memory. You can slice and parse without allocating new arrays or strings. It can't be a class field, boxed or used across await . Memory<T is the heap-storable counterpart, usable in async methods. Both are used heavily inside ASP.NET Core and System.Text.Json for performance."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"145","title":"What is the difference between `Task` and `ValueTask`?","body":"Task is a class, so every async call that returns one allocates (except cached completed tasks). ValueTask<T is a struct that avoids the allocation when the result is often available synchronously (e.g. from a cache). Rules: await a ValueTask only once , don't await it concurrently, and convert with .AsTask() if you need to. The default is still Task ."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"146","title":"What are covariance and contravariance?","body":"They allow implicit conversion of generic type arguments. Covariance ( out T ) works for outputs: IEnumerable<string → IEnumerable<object . Contravariance ( in T ) works for inputs: Action<object → Action<string , IComparer<Animal used as IComparer<Dog . Only interfaces and delegates support this, and only for reference types."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"147","title":"What are source generators and why are they replacing reflection?","body":"Source generators run during compilation and add C code to the project. They remove runtime reflection costs, work with trimming and Native AOT, and catch errors at build time. Examples: System.Text.Json JsonSerializerContext , [LoggerMessage] , [GeneratedRegex] , [LibraryImport] ."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"148","title":"A method builds a CSV of 200,000 rows using `+=` on a string and takes minutes. What do you do?","body":"String concatenation in a loop copies the whole string every time, so the work is O(n²). Replace it with a StringBuilder , or better, stream the rows straight to the output ( StreamWriter , or PipeWriter in ASP.NET Core) so the full file is never held in memory. Measure before and after with a stopwatch or BenchmarkDotNet. For huge exports, page the database query and write as you read."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"149","title":"Your API's memory keeps growing until the pod restarts. How would you investigate?","body":"1. Confirm the trend with dotnet-counters (GC heap size, Gen 2 count, LOH size). 2. Take memory dumps a few minutes apart with dotnet-dump collect (or dotnet-gcdump ) and compare which types grow, using Visual Studio, PerfView or dotnet-dump analyze ( dumpheap -stat , gcroot ). 3. Usual culprits: static collections or caches with no eviction, event handlers never unsubscribed, HttpClient created per request, undisposed streams/DbContexts, large byte arrays on the LOH, unbounded MemoryCache . 4. Fix (size-limited cache, IHttpClientFactory , using , weak events), then load-test to confirm."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"150","title":"Two users update the same in-memory counter and some increments are lost. Why, and how do you fix it?","body":"count++ is read, add, write — three steps. Two threads can read the same value and both write value+1, so one increment is lost (a race condition). Fix with Interlocked.Increment(ref count) , a lock , or a concurrent type. If the counter must survive restarts or work across several servers, keep it in the database ( UPDATE ... SET Count = Count + 1 ) or in Redis INCR instead."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"151","title":"A synchronous method calls `GetDataAsync().Result` and the app hangs under load. Explain and fix.","body":"Blocking on async code ties up a thread while it waits. In a context with a synchronisation context it can deadlock. In ASP.NET Core it causes thread-pool starvation: every request blocks a thread, the pool grows slowly, and requests queue up. Fix: make the call chain async ( await ) from the controller down to the I/O call. If a sync API is truly unavoidable, use a properly synchronous library call rather than sync-over-async."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"152","title":"You need to call 500 external URLs as fast as possible without getting rate-limited. How?","body":"Use async I/O with bounded concurrency : Parallel.ForEachAsync(urls, new ParallelOptions { MaxDegreeOfParallelism = 10 }, ...) or a SemaphoreSlim with Task.WhenAll . Reuse one HttpClient from IHttpClientFactory . Add retries with exponential backoff (Polly / Microsoft.Extensions.Http.Resilience ), respect 429 Retry-After , and pass cancellation tokens and timeouts."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"153","title":"You must count error lines in a 5 GB log file without running out of memory. How?","body":"Stream it: foreach (var line in File.ReadLines(path)) if (line.Contains(\"ERROR\", StringComparison.Ordinal)) count++; or a StreamReader with ReadLineAsync — memory stays constant because only one line is held at a time. Don't use ReadAllText / ReadAllLines . For more speed: a larger buffer ( new StreamReader(path, Encoding.UTF8, true, 1 << 16) ), Span -based searching, or splitting the file into ranges processed in parallel when the disk is fast."},{"kind":"question","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"154","title":"After deploying to the cloud, order times shown to users are 5.5 hours off. What went wrong?","body":"The code used DateTime.Now , which is the server's local time — the cloud server runs in UTC while the developer's PC ran in IST (or the opposite conversion was applied twice). Fix: store and compare in UTC ( DateTime.UtcNow / DateTimeOffset ), mark DateTimeKind.Utc when reading from the database, convert to the user's time zone ( TimeZoneInfo.ConvertTimeFromUtc ) only for display, send ISO 8601 with offset ( \"O\" format) in APIs, and inject TimeProvider so tests can control the time."},{"kind":"cheat","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"1","title":"Types at a glance","body":"Category Types --- --- Integral byte short int (32-bit) long (64-bit), unsigned variants Floating float (~7 digits), double (~15–16 digits), decimal (28–29 digits, use for money ) Others bool , char (UTF-16), string , object , DateTime , DateOnly , TimeOnly , Guid User-defined class , struct , record , record struct , interface , enum , delegate Value types are copied on assignment; reference types share one object."},{"kind":"cheat","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"2","title":"Keywords people mix up","body":"- const vs readonly : compile-time and copied into callers vs set once at runtime. - is vs as : is tests a type/pattern (bool); as casts or gives null . - ref vs out vs in : read/write vs must assign vs read-only. - abstract vs virtual : no body, must override vs has a body, may override. - sealed : can't inherit (class) or override further (method). - new modifier: hides a base member (no polymorphism). - static class: can't be instantiated; only static members. - throw; keeps the stack trace; throw ex; loses it."},{"kind":"cheat","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"3","title":"Null handling","body":"csharp x?.Prop // null if x is null x ?? fallback // fallback if null x ??= value // assign if null x! // \"trust me, not null\" x is null / x is not null ArgumentNullException.ThrowIfNull(x);"},{"kind":"cheat","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"4","title":"Collections — pick fast","body":"Need Use --- --- Ordered list List<T Key lookup Dictionary<K,V Unique items HashSet<T FIFO / LIFO Queue<T / Stack<T Thread-safe map ConcurrentDictionary<K,V Producer/consumer Channel<T Read-only, read-heavy FrozenDictionary / ImmutableArray"},{"kind":"cheat","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"5","title":"async rules","body":"- async Task / Task<T ; async void only for event handlers. - Never .Result / .Wait() — async all the way. - Independent calls: await Task.WhenAll(...) . - Pass CancellationToken . - CPU-bound: Task.Run / Parallel ; I/O-bound: just await . - Use SemaphoreSlim (not lock ) around await ."},{"kind":"cheat","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"6","title":"Memory & disposal","body":"- GC generations 0/1/2; LOH ≥ 85,000 bytes. - using / await using for IDisposable / IAsyncDisposable . - Finaliser = last-resort safety net; GC.SuppressFinalize . - Leaks: static collections, events not unsubscribed, HttpClient per call, unbounded caches. - Low-allocation code: Span<T , ArrayPool , StringBuilder , stackalloc ."},{"kind":"cheat","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"7","title":"Modern syntax quick list","body":"csharp record Person(string Name, int Age); // C 9 var p2 = p1 with { Age = 31 }; global using System.Text.Json; // C 10 namespace Shop.Api; // file-scoped var json = \"\"\"{\"name\": \"Divakar\"}\"\"\"; // raw string (C 11) public required string Name { get; init; } // required (C 11) class Svc(IRepo repo) { } // primary ctor (C 12) int[] xs = [1, 2, ..others]; // collection expressions (C 12) order?.Status = Status.Shipped; // C 14"},{"kind":"cheat","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"8","title":"The 6 answers to have ready","body":"1. Value vs reference types (with the stack/heap nuance). 2. string immutability + StringBuilder . 3. IEnumerable vs IQueryable . 4. async/await doesn't create threads; no .Result . 5. IDisposable + using + GC generations. 6. Delegates vs events."},{"kind":"cheat","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"9","title":"Data types & conversion","body":"Need Use --- --- Money, quantities decimal ( 12.5m ) Scientific / graphics double User input → number int.TryParse(s, out var n) Overflow check checked(a + b) Timestamps UTC: DateTime.UtcNow / DateTimeOffset Pure dates / times DateOnly / TimeOnly"},{"kind":"cheat","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"10","title":"Arrays & collections in one look","body":"int[] fixed · int[,] rectangular · int[][] jagged · List<T growable · Dictionary<K,V key lookup ( TryGetValue ) · HashSet<T unique · SortedList/SortedDictionary ordered keys · Stack<T LIFO · Queue<T FIFO · PriorityQueue<T,P · ArrayList / Hashtable = legacy (boxing, no type safety) · (int, string) ValueTuple for quick multi-returns."},{"kind":"cheat","course_slug":"csharp","course_title":"C# Language — Basics to Advanced","ref":"11","title":"Delegates, exceptions & files","body":"Func returns · Action void · Predicate bool · += multicast · out T covariance, in T contravariance · throw; not throw ex; · custom exception = derive Exception + 3 constructors · File.ReadLines for big files · always using / await using streams · Path.Combine for paths."},{"kind":"course","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"","title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","body":"VB.NET syntax and program structure, data types and Option Strict/Explicit/Infer, operators and control flow, procedures (Sub vs Function, ByVal/ByRef, Optional, ParamArray), arrays and collections, classes and OOP keywords (Inherits, Implements, Overridable, MustInherit, Shadows), properties, modules and Shared members, events and delegates (WithEvents/Handles/AddHandler), error handling (Try/Catch and legacy On Error), LINQ and XML literals, async, WinForms and Web Forms code-behind, and converting VB.NET to C . Visual Basic .NET is a .NET language that compiles to the same IL as C and uses the same CLR, base class library, ASP.NET, ADO.NET and Entity Framework. Many enterprise and government systems (especially .NET Framework Web Forms and WinForms apps from 2002–2015) are written in VB.NET, so developers are often hired to maintain or migrate them. VB.NET C --- --- --- Syntax style English-like keywords, line-oriented, End If / End Sub C-style braces and semicolons Case sensitivity Case-insensitive Case-sensitive Type Dim x As Integer = 5 int x = 5; Same runtime/IL ✅ ✅ New language features Stable since 2020 (no new major features) Evolving every year Typical use today Maintaining legacy apps, Office/VBA developers moving to .NET Most new development Microsoft's position (2020): Visual Basic is supported on .NET 5+ for WinForms, WPF, console and class libraries, but will not get new language features and ASP.NET Core does not offer VB templates (Web Forms/MVC 5 on .NET Framework do). Version Year Shipped with Highlights --- --- --- --- VB 1.0–6.0 (classic) 1991–1998 Visual Studio 6 COM-based, not .NET — VB6 apps are still migrated today VB.NET 7.0 2002 .NET Framework 1.0 Full OOP, structured exception handling, .NET VB 8.0 (2005) 2005 .NET 2.0 Generics (Of T) , My namespace, Using , operator overloading, partial classes, IsNot VB 9.0 (2008) 2007 .NET 3.5 LINQ, XML literals, Option Infer , lambdas, anonymous types, extension methods VB 10 (2010) 2010 .NET 4.0 Auto-implemented properties, multi-line lambdas, implicit line continuation, collection initializers VB 11 (2012) 2012 .NET 4.5 Async / Await , iterators ( Iterator / Yield ) VB 14 (2015) 2015 Roslyn NameOf , string interpolation $\"...\" , ?. null-conditional, multiline strings, read-only auto-properties VB 15–15.5 2017 VS 2017 Tuples, ByRef returns consumption, binary literals, digit separators VB 16–16.9 2019–2020 .NET Core 3 / .NET 5 Comments after line continuation, init-only property consumption; final feature updates How a VB.NET project runs: 1. Write .vb files (Visual Studio with VB project templates). 2. The VB compiler ( vbc , part of Roslyn) compiles them with project-level settings ( Option Strict , Option Explicit , root namespace, imports) into IL in an assembly. 3. The CLR loads and JIT-compiles it exactly like C output; VB-specific helpers live in Microsoft.VisualBasic.dll (e.g. Left , Mid , CInt , My namespace). 4. C and VB projects in one solution reference each other freely — they share the CTS types. - Visual Studio (VB.NET project templates: Console, Class Library, WinForms, WPF; Web Forms/MVC on .NET Framework). - Converters: Telerik Code Converter (online), ICSharpCode CodeConverter (VB ↔ C , Visual Studio extension), SharpDevelop's converter (legacy). - ILSpy can decompile an assembly to either language — useful to see the C equivalent of VB code. - .NET Upgrade Assistant for migrating .NET Framework VB projects to modern .NET."},{"kind":"lesson","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"program-structure-modules-and-the-main-method","title":"Program structure, modules and the Main method","body":"vb Option Strict On ' no implicit narrowing conversions or late binding — always turn on Option Explicit On ' every variable must be declared Option Infer On ' allow Dim x = 5 (type inferred) Imports System.Text ' = C using Namespace Divakar.Shop Module Program ' a Module = C static class; members are Shared automatically Sub Main(args As String()) Console.WriteLine(\"Hello, Divakar!\") Dim name As String = If(args.Length 0, args(0), \"world\") Console.WriteLine($\"Welcome {name}\") ' string interpolation (VB 14) End Sub End Module End Namespace - Statements end at the line break (no semicolons); use for explicit line continuation, though VB 10+ allows implicit continuation after operators, commas and opening brackets. - Comments start with ' (or REM ). - Blocks end with End X ( End If , End Sub , End Class ). - Keywords and identifiers are case-insensitive ( dim = Dim ; the IDE fixes casing). C VB.NET --- --- using System; Imports System static class Helpers Module Helpers static void Main(string[] args) Sub Main(args As String()) // comment ' comment Console.WriteLine(\"x\"); Console.WriteLine(\"x\")"},{"kind":"lesson","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"data-types-variables-constants-and-conversions","title":"Data types, variables, constants and conversions","body":"VB.NET C .NET type Literal --- --- --- --- Integer int Int32 42 , 42I Long long Int64 42L Short / Byte short / byte Int16 / Byte 42S Double / Single double / float Double / Single 1.5R / 1.5F Decimal decimal Decimal 1.5D Boolean bool Boolean True / False Char char Char \"A\"c String string String \"text\" Date DateTime DateTime 10/24/2026 (M/d/yyyy) Object object Object vb Dim count As Integer = 10 Dim price = 99.5D ' Decimal, inferred with Option Infer On Const TaxRate As Decimal = 0.18D Dim total As Decimal = price (1 + TaxRate) Dim nothingYet As String = Nothing ' Nothing = C null (or default for value types) Dim maybe As Integer? = Nothing ' Nullable(Of Integer) ' Conversions Dim n1 As Integer = CInt(\"42\") ' VB conversion keyword (rounds to even for decimals: CInt(2.5) = 2) Dim n2 As Integer = Integer.Parse(\"42\") Dim ok As Boolean = Integer.TryParse(input, n1) Dim d As Double = CDbl(n1) Dim s As String = n1.ToString() Dim o As Object = \"hello\" Dim str As String = DirectCast(o, String) ' cast, throws if wrong type (C (string)o) Dim str2 As String = TryCast(o, String) ' returns Nothing if wrong type (C o as string) Dim v = CType(o, String) ' general conversion Option Strict On — the most important setting: it forbids implicit narrowing conversions ( Dim i As Integer = 3.7 fails) and late binding on Object . With it Off , VB silently converts types and resolves members at runtime — a source of hidden bugs. Turn it on for every project (Project Properties → Compile)."},{"kind":"lesson","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"operators-conditions-and-loops","title":"Operators, conditions and loops","body":"Purpose VB.NET C --- --- --- Equality = == Not equal < != Logical and/or (short-circuit) AndAlso , OrElse && , \\ \\ Logical and/or (always both) And , Or & , \\ Not Not ! String concatenation & (preferred) or + + Integer division / modulus \\ , Mod / (on ints), % Power ^ Math.Pow Reference equality Is , IsNot == on references / is null Ternary If(cond, a, b) cond ? a : b Null-coalescing If(x, fallback) x ?? fallback vb If marks = 75 Then Console.WriteLine(\"Distinction\") ElseIf marks = 35 Then Console.WriteLine(\"Pass\") Else Console.WriteLine(\"Fail\") End If Select Case day ' = C switch Case DayOfWeek.Saturday, DayOfWeek.Sunday Console.WriteLine(\"Weekend\") Case Else Console.WriteLine(\"Weekday\") End Select Select Case score Case Is = 90 : grade = \"A\" Case 75 To 89 : grade = \"B\" Case Else : grade = \"C\" End Select For i As Integer = 1 To 10 Step 2 ' 1,3,5,7,9 (bounds inclusive!) If i = 7 Then Exit For ' = break If i = 3 Then Continue For ' = continue Console.Write(i) Next For Each name As String In names Console.WriteLine(name) Next Do While attempts < 3 ' also: Do Until, Loop While, Loop Until, While...End While attempts += 1 Loop Pitfall: If user IsNot Nothing And user.IsActive Then evaluates both sides and throws when user is Nothing — use AndAlso ."},{"kind":"lesson","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"sub-vs-function-byval-byref-optional-and-paramarray","title":"Sub vs Function, ByVal/ByRef, Optional and ParamArray","body":"vb ' Sub = method returning nothing (C void) Public Sub Log(message As String) Console.WriteLine($\"{Date.Now:HH:mm} {message}\") End Sub ' Function = method returning a value Public Function Add(a As Integer, b As Integer) As Integer Return a + b End Function ' ByVal (default) copies the value/reference; ByRef passes the variable itself (C ref) Public Sub Swap(ByRef a As Integer, ByRef b As Integer) Dim t = a : a = b : b = t End Sub ' Optional parameters and named arguments Public Sub SendMail(toAddr As String, Optional subject As String = \"Hi\", Optional urgent As Boolean = False) End Sub SendMail(\"a@b.com\", urgent:=True) ' ParamArray = C params Public Function Sum(ParamArray values As Integer()) As Integer Return values.Sum() End Function ' Lambdas Dim square = Function(x As Integer) x x Dim show = Sub(msg As String) Console.WriteLine(msg) Dim isAdult As Func(Of Integer, Boolean) = Function(age) age = 18 Overloading uses the same name with different parameters ( Overloads keyword is optional except when overloading inherited members)."},{"kind":"lesson","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"arrays-generics-and-collections","title":"Arrays, generics and collections","body":"vb Dim marks(4) As Integer ' 5 elements! VB declares the UPPER BOUND (0..4), C declares the length Dim primes() As Integer = {2, 3, 5, 7} Dim grid(1, 2) As Integer ' 2 x 3 multidimensional ReDim Preserve marks(9) ' resize keeping values (creates a new array) Console.WriteLine(primes.Length) Dim names As New List(Of String) From {\"Asha\", \"Ravi\"} ' generics use (Of T) names.Add(\"Meera\") Dim stock As New Dictionary(Of String, Integer) From {{\"pen\", 10}, {\"book\", 4}} Dim qty As Integer If stock.TryGetValue(\"pen\", qty) Then Console.WriteLine(qty) Dim adults = people.Where(Function(p) p.Age = 18).OrderBy(Function(p) p.Name).ToList() ' Generic class and method with constraint Public Class Repository(Of T As {Class, New}) Private ReadOnly items As New List(Of T) Public Function Create() As T Dim item As New T() items.Add(item) Return item End Function End Class Indexing uses parentheses arr(0) , not square brackets — the same syntax as method calls."},{"kind":"lesson","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"classes-properties-constructors-and-shared-members","title":"Classes, properties, constructors and Shared members","body":"vb Public Class Customer Private name As String Private Shared count As Integer ' Shared = C static Public Property Id As Integer ' auto-implemented property Public ReadOnly Property CreatedOn As Date = Date.UtcNow Public Property Name As String ' full property with validation Get Return name End Get Set(value As String) If String.IsNullOrWhiteSpace(value) Then Throw New ArgumentException(\"Name required\") name = value.Trim() End Set End Property Public Sub New(name As String) ' constructor Me.Name = name ' Me = C this count += 1 End Sub Public Shared ReadOnly Property Count As Integer Get Return count End Get End Property Public Overrides Function ToString() As String Return $\"{Id}: {Name}\" End Function End Class Dim c As New Customer(\"Asha\") With {.Id = 1} ' object initializer uses With { .Prop = value } C VB.NET --- --- this / base Me / MyBase (and MyClass ) static Shared readonly field ReadOnly const Const internal Friend protected internal Protected Friend new Customer { Id = 1 } New Customer With {.Id = 1} null Nothing"},{"kind":"lesson","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"inheritance-interfaces-and-polymorphism-keywords","title":"Inheritance, interfaces and polymorphism keywords","body":"vb Public MustInherit Class Shape ' MustInherit = C abstract class Public MustOverride Function Area() As Double ' MustOverride = abstract method Public Overridable Function Describe() As String ' Overridable = virtual Return $\"{Me.GetType().Name} with area {Area():0.00}\" End Function End Class Public Class Circle Inherits Shape ' : Shape Public Property Radius As Double Public Overrides Function Area() As Double ' override Return Math.PI Radius ^ 2 End Function End Class Public NotInheritable Class Square ' NotInheritable = C sealed Inherits Shape Implements IComparable(Of Square) ' implement an interface Public Property Side As Double Public Overrides Function Area() As Double Return Side Side End Function Public Function CompareTo(other As Square) As Integer Implements IComparable(Of Square).CompareTo Return Side.CompareTo(other.Side) ' explicit \"Implements\" clause on every member End Function End Class Public Interface IRepository(Of T) Function GetById(id As Integer) As T Sub Save(item As T) End Interface C VB.NET --- --- abstract class / abstract member MustInherit / MustOverride virtual / override Overridable / Overrides sealed class / sealed override NotInheritable / NotOverridable Overrides new (hide member) Shadows class A : B, IX Inherits B + Implements IX interface member implementation (implicit) Implements IX.Member clause required"},{"kind":"lesson","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"events-and-delegates-withevents-handles-addhandler-raiseevent","title":"Events and delegates — WithEvents, Handles, AddHandler, RaiseEvent","body":"vb Public Class Thermostat Public Event TooHot As EventHandler(Of Double) ' declare an event Public Sub Read(temp As Double) If temp 40 Then RaiseEvent TooHot(Me, temp) ' raise it (no null check needed) End Sub End Class ' Style 1: WithEvents + Handles (static wiring — typical in WinForms/Web Forms code-behind) Public Class Monitor Private WithEvents sensor As New Thermostat() Private Sub OnTooHot(sender As Object, t As Double) Handles sensor.TooHot Console.WriteLine($\"Alert {t}\") End Sub End Class ' Style 2: AddHandler / RemoveHandler (dynamic wiring = C += / -=) Dim th As New Thermostat() AddHandler th.TooHot, AddressOf OnTooHot ' AddressOf = method group AddHandler th.TooHot, Sub(s, t) Console.WriteLine($\"Lambda {t}\") RemoveHandler th.TooHot, AddressOf OnTooHot ' Custom delegate type Public Delegate Function Calc(a As Integer, b As Integer) As Integer Dim add As Calc = Function(a, b) a + b In Web Forms VB code-behind you'll see Protected Sub btnSave Click(sender As Object, e As EventArgs) Handles btnSave.Click — the Handles clause connects the button's server event."},{"kind":"lesson","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"error-handling-try-catch-finally-and-legacy-on-error","title":"Error handling — Try/Catch/Finally and legacy On Error","body":"vb Try Dim text = IO.File.ReadAllText(path) Dim n = Integer.Parse(text) Catch ex As IO.FileNotFoundException Log($\"Missing file {path}\") Catch ex As FormatException When path.EndsWith(\".cfg\") ' exception filter Log(\"Bad config value\") Catch ex As Exception Log(ex.ToString()) Throw ' rethrow, keeps stack trace (never \"Throw ex\") Finally CleanUp() End Try Using conn As New SqlConnection(cs) ' = C using; Dispose at End Using conn.Open() End Using Public Class InsufficientFundsException Inherits Exception Public Sub New(message As String) MyBase.New(message) End Sub End Class Legacy unstructured error handling (from VB6, still compiles in VB.NET — you'll find it in old code): vb Sub OldStyle() On Error GoTo ErrHandler ' jump to label on any error Dim x As Integer = CInt(\"abc\") Exit Sub ErrHandler: Console.WriteLine(\"Error \" & Err.Number & \": \" & Err.Description) Resume Next ' continue with the next statement (dangerous — hides errors) End Sub Refactor On Error to Try/Catch when maintaining such code; On Error Resume Next silently ignores failures."},{"kind":"lesson","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"linq-xml-literals-async-and-iterators","title":"LINQ, XML literals, async and iterators","body":"vb ' LINQ query syntax Dim expensive = From p In products Where p.Price 1000 Order By p.Price Descending Select p.Name, p.Price ' Aggregate and Group By Dim byCategory = From p In products Group By p.Category Into Total = Sum(p.Price), Count() ' XML literals — unique to VB: XML directly in code, with embedded expressions Dim doc = <orders <%= From o In orders Select <order id=<%= o.Id % total=<%= o.Total % / % </orders Dim ids = From x In doc...<order Select CInt(x.@id) ' ... = descendants, .@ = attribute ' Async / Await Public Async Function GetPageAsync(url As String) As Task(Of String) Using client As New HttpClient() Return Await client.GetStringAsync(url) End Using End Function ' Iterator functions = C yield return Public Iterator Function Evens(max As Integer) As IEnumerable(Of Integer) For i = 0 To max Step 2 Yield i Next End Function"},{"kind":"lesson","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"the-my-namespace-microsoft-visualbasic-helpers-and-late-binding","title":"The My namespace, Microsoft.VisualBasic helpers and late binding","body":"vb Dim userName = My.User.Name ' current Windows user Dim content = My.Computer.FileSystem.ReadAllText(\"a.txt\") My.Settings.LastOpened = Date.Now : My.Settings.Save() ' WinForms settings Dim conn = My.Settings.ShopConnectionString ' Classic VB functions from Microsoft.VisualBasic Dim first3 = Left(\"Divakar\", 3) ' \"Div\" (= \"Divakar\".Substring(0, 3)) Dim mid = Mid(\"Divakar\", 2, 3) ' \"iva\" (1-based!) Dim len = Len(\"Divakar\") If IsNumeric(input) Then ... Dim answer = MsgBox(\"Save changes?\", MsgBoxStyle.YesNo) ' WinForms only Late binding ( Option Strict Off ): calling members on an Object resolved at runtime — used historically for COM/Office automation ( CreateObject(\"Excel.Application\") ). With Option Strict On use proper types or dynamic -like patterns via interop assemblies. 1-based vs 0-based: classic functions ( Mid , InStr ) are 1-based; .NET methods ( Substring , IndexOf ) are 0-based — a common bug source when mixing them."},{"kind":"lesson","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"converting-vbdotnet-to-csharp-and-migration-strategy","title":"Converting VB.NET to C# and migration strategy","body":"VB.NET C --- --- Dim x As New List(Of Integer) var x = new List<int (); If x Is Nothing Then if (x is null) For i = 0 To n - 1 for (int i = 0; i < n; i++) arr(0) arr[0] Dim a(9) As Integer (10 items) var a = new int[10]; x \\ y , x Mod y x / y (ints), x % y \"a\" & \"b\" \"a\" + \"b\" AndAlso / OrElse && / \\ \\ DirectCast(o, T) / TryCast(o, T) (T)o / o as T AddHandler e, AddressOf M e += M; Handles btn.Click wire btn.Click += ... (or markup) Shared / Module static / static class MustInherit / Overridable abstract / virtual On Error Resume Next no equivalent — rewrite with try/catch My.Settings IOptions<T / appsettings.json Migration strategy for a legacy VB.NET app: 1. Turn on Option Strict and fix warnings (finds hidden bugs first). 2. Add tests around critical behaviour. 3. Mixed-language solution: new code in C class libraries referenced by the VB project (both compile to IL). 4. Convert class libraries one by one with a converter, review by hand (Mid/InStr 1-based, integer division, Nothing semantics for value types, On Error ). 5. UI: Web Forms → ASP.NET Core MVC/Razor Pages or Blazor (rewrite page by page behind a reverse proxy — strangler pattern); WinForms VB can move to .NET 8/10 WinForms directly. 6. Use .NET Upgrade Assistant for project files and package updates."},{"kind":"question","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"155","title":"What is the difference between VB.NET and C#?","body":"Both compile to the same IL and run on the same CLR with the same libraries, so performance is the same. Differences are syntax and features: VB.NET uses English-like keywords, is case-insensitive, line-based with End blocks, has XML literals, My namespace, WithEvents/Handles and optional late binding; C uses C-style syntax, is case-sensitive and gets new language features every year while VB.NET has been feature-stable since 2020. Most new projects use C ; VB.NET is mainly maintained in legacy systems."},{"kind":"question","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"156","title":"What do Option Strict, Option Explicit and Option Infer do?","body":"Option Explicit On requires variables to be declared. Option Strict On disallows implicit narrowing conversions and late binding — catching type errors at compile time (strongly recommended). Option Infer On lets Dim x = 5 infer the type from the initializer. Set them per project (Compile settings) or per file at the top."},{"kind":"question","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"157","title":"What is the difference between Sub and Function?","body":"A Sub performs an action and returns no value (C void method). A Function returns a value with Return (or by assigning to the function name in old code). Both can take ByVal/ByRef, Optional and ParamArray parameters."},{"kind":"question","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"158","title":"ByVal vs ByRef?","body":"ByVal (the default) passes a copy of the value — for reference types, a copy of the reference, so the method can modify the object but not replace the caller's variable. ByRef passes the variable itself, so assigning a new value inside the method changes the caller's variable (C ref )."},{"kind":"question","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"159","title":"What are the VB.NET equivalents of static, this, null and abstract?","body":"static → Shared (and a Module is like a static class), this → Me , base → MyBase , null → Nothing , abstract class → MustInherit , abstract method → MustOverride , virtual → Overridable , override → Overrides , sealed → NotInheritable , internal → Friend ."},{"kind":"question","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"160","title":"Why does `Dim arr(5) As Integer` create 6 elements?","body":"VB.NET array declarations specify the upper bound , not the length, and arrays are zero-based — so arr(5) has indexes 0 to 5 = 6 elements. In C , new int[5] specifies the length (indexes 0–4). A classic off-by-one source when converting code."},{"kind":"question","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"161","title":"And vs AndAlso, Or vs OrElse?","body":"And / Or always evaluate both operands (and also act as bitwise operators on integers). AndAlso / OrElse short-circuit: the second operand is evaluated only if needed. Use AndAlso for conditions like If obj IsNot Nothing AndAlso obj.IsActive Then to avoid NullReferenceException."},{"kind":"question","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"162","title":"How are events handled in VB.NET?","body":"Declare with Event , raise with RaiseEvent . Subscribe statically by declaring the field WithEvents and adding a Handles obj.EventName clause to the handler (common in WinForms/Web Forms code-behind), or dynamically with AddHandler obj.Event, AddressOf Handler and RemoveHandler (like C += / -= )."},{"kind":"question","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"163","title":"DirectCast vs CType vs TryCast?","body":"DirectCast performs a type cast requiring an inheritance/interface relationship and throws InvalidCastException on failure (fast, like C (T)x ). CType performs any defined conversion including VB conversions (string to integer) and user-defined conversions. TryCast returns Nothing instead of throwing (reference types only, like C as )."},{"kind":"question","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"164","title":"What is the difference between On Error GoTo and Try/Catch?","body":"On Error GoTo label / Resume Next is legacy unstructured error handling from VB6: errors jump to a label or are silently skipped, making flow hard to follow and hiding failures. Try/Catch/Finally is structured exception handling with typed exceptions, filters ( When ), Finally cleanup and proper rethrowing. Use Try/Catch; refactor On Error when touching old code."},{"kind":"question","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"165","title":"What is a Module in VB.NET?","body":"A container whose members are implicitly Shared and which can't be instantiated or inherited — compiled as a sealed class with static members (C static class). Module members can be called without qualifying the module name, which is convenient for helper functions and Sub Main ."},{"kind":"question","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"166","title":"What are XML literals?","body":"A VB-only feature that lets you write XML directly in code as XElement / XDocument objects, embed expressions with <%= % , and query with axis properties ( .<child , ...<descendant , .@attribute ). Handy for generating and reading XML configuration or reports with LINQ to XML."},{"kind":"question","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"167","title":"Can a C# project and a VB.NET project be in the same solution?","body":"Yes. Each project compiles to IL in its own assembly, and projects reference each other normally (same CTS types). A single project can't mix languages. This makes gradual migration possible: put new code in C libraries consumed by the VB application. Keep public APIs CLS-compliant (avoid names differing only by case, which VB can't distinguish)."},{"kind":"question","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"168","title":"Does VB.NET run on .NET 8/10?","body":"Yes for console, class libraries, WinForms and WPF (and Worker Services); the compiler is part of Roslyn. VB.NET won't get new language features, ASP.NET Core has no VB templates (you can still reference VB libraries from ASP.NET Core C projects), and Web Forms stays on .NET Framework."},{"kind":"question","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"169","title":"You must maintain a large VB.NET Web Forms app and gradually move it to modern .NET. What is your plan?","body":"Stabilise first: source control, Option Strict On, logging, tests on critical flows. Extract business logic from code-behind into class libraries (VB or new C ), target netstandard2.0 where possible so both old and new apps can use them. Put a reverse proxy (YARP/IIS ARR) in front and rebuild pages/features in ASP.NET Core (C ) one area at a time, sharing authentication and the database (strangler fig). Retire Web Forms pages as their replacements go live."},{"kind":"question","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"170","title":"After converting a VB function to C#, string results are off by one character. Why?","body":"VB's classic string functions ( Mid , InStr , Left ) are 1-based , while .NET methods ( Substring , IndexOf ) are 0-based, and InStr returns 0 for \"not found\" while IndexOf returns −1. Converters sometimes translate them literally. Fix the indexes, add unit tests comparing old and new outputs for typical inputs."},{"kind":"cheat","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"1","title":"Keyword map VB → C#","body":"Dim x As T → T x · Sub/Function → void/method · Me/MyBase → this/base · Shared/Module → static · Nothing → null · Inherits/Implements → : · MustInherit/MustOverride → abstract · Overridable/Overrides → virtual/override · NotInheritable → sealed · Friend → internal · Shadows → new."},{"kind":"cheat","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"2","title":"Operators","body":"= equality · < not equal · & concat · \\ int division · Mod · ^ power · AndAlso/OrElse short-circuit · Is/IsNot reference · If(c,a,b) ternary · If(x,y) null-coalesce."},{"kind":"cheat","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"3","title":"Must-know settings","body":"Option Strict On · Option Explicit On · Option Infer On · arrays declare upper bound · (Of T) generics · arr(i) indexing."},{"kind":"cheat","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"4","title":"Events","body":"Event + RaiseEvent · WithEvents + Handles · AddHandler/RemoveHandler + AddressOf ."},{"kind":"cheat","course_slug":"vbnet","course_title":"VB.NET — Visual Basic .NET from Basics to Advanced (with C# Comparison)","ref":"5","title":"Migration","body":"Option Strict first → tests → extract logic to libraries → convert libraries → rebuild UI in ASP.NET Core (strangler) → watch 1-based string functions and integer division."},{"kind":"course","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"","title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","body":"Every .NET version from .NET Framework 1.0 to .NET 10, the .NET architecture (CLR, BCL, CTS, CLS), compilation from C /VB.NET to IL to machine code (Roslyn, JIT, tiered compilation, ReadyToRun, Native AOT), assemblies, manifests, metadata, GAC and strong names, AppDomains vs AssemblyLoadContext, type loading and method tables, stack and heap, value vs reference type layout, the garbage collector in depth (generations, LOH, POH, workstation/server, background GC), finalization, IDisposable, memory leaks and diagnostics, threading and the thread pool, async internals and exceptions inside the CLR. .NET is a developer platform: a runtime that executes code (the CLR), a huge class library (BCL), languages (C , VB.NET, F ), SDK tools ( dotnet CLI, compilers, NuGet) and app models (ASP.NET, WinForms, WPF, MAUI, Worker Services). text ┌──────────────────────────────────────────────────────────────┐ │ Your code: C · VB.NET · F │ ├──────────────────────────────────────────────────────────────┤ │ App models: ASP.NET Core · Web Forms/MVC (Framework) · WPF · │ │ WinForms · MAUI · Worker · Console │ ├──────────────────────────────────────────────────────────────┤ │ Base Class Library (BCL): System, Collections, IO, Net, Linq, │ │ Threading, Text.Json, Data, Security … │ ├──────────────────────────────────────────────────────────────┤ │ CLR (Common Language Runtime): JIT · GC · type system (CTS) · │ │ type safety · exceptions · threading · security · interop │ ├──────────────────────────────────────────────────────────────┤ │ Operating system: Windows · Linux · macOS · (Android/iOS) │ └──────────────────────────────────────────────────────────────┘ Term Full form One line --- --- --- CLR Common Language Runtime The virtual machine that loads, compiles (JIT), runs and manages .NET code CTS Common Type System Rules for how types are defined and behave — shared by all .NET languages CLS Common Language Specification Subset of CTS every language must support so libraries work across languages IL / MSIL / CIL (Microsoft/Common) Intermediate Language CPU-independent instructions produced by the compiler JIT Just-In-Time compiler Converts IL to native machine code at runtime (RyuJIT) BCL / FCL Base / Framework Class Library Built-in libraries GC Garbage Collector Automatic memory management Managed code — Code executed under the CLR (memory, safety managed) Unmanaged code — Native code outside the CLR (C/C++ DLLs, COM, Win32) — called via P/Invoke or COM interop Every .NET version (release year, what shipped, support status as of 2026): .NET Framework (Windows only): Version Year CLR Visual Studio Headline features --- --- --- --- --- 1.0 2002 1.0 VS .NET 2002 First release: CLR, C 1.0, VB.NET, ASP.NET Web Forms, ADO.NET, WinForms 1.1 2003 1.1 VS .NET 2003 ASP.NET mobile controls, ODBC/Oracle providers, side-by-side execution 2.0 2005 2.0 VS 2005 Generics , nullable types, anonymous methods, partial classes, ASP.NET 2.0 (master pages, membership), 64-bit 3.0 2006 2.0 (VS 2005 extensions) WPF, WCF, WF (Workflow), CardSpace 3.5 2007 2.0 VS 2008 LINQ , C 3.0, ASP.NET AJAX; 3.5 SP1 (2008): Entity Framework 1, ASP.NET Dynamic Data 4.0 2010 4 VS 2010 TPL ( Task ), PLINQ, dynamic , MEF, Code Contracts, ASP.NET MVC 2 era 4.5 2012 4 VS 2012 async/await , ASP.NET Web API, SignalR, Web Forms model binding 4.5.1 / 4.5.2 2013 / 2014 4 VS 2013 Debugging and performance improvements 4.6 – 4.6.2 2015 – 2016 4 VS 2015 RyuJIT for x64, ASP.NET 4.6, long-path support (4.6.2) 4.7 – 4.7.2 2017 – 2018 4 VS 2017 TLS 1.2 defaults, high-DPI WinForms 4.8 2019 4 VS 2019 Last major Framework version ; JIT and accessibility updates 4.8.1 2022 4 VS 2022 Native ARM64 support .NET Framework 4.8/4.8.1 is supported as part of Windows (no new features). Web Forms, WCF server and Windows Workflow exist only here. .NET Core (cross-platform, open source): Version Year Type Headline features --- --- --- --- 1.0 2016 — Cross-platform runtime, ASP.NET Core 1.0, EF Core 1.0, project.json 1.1 2016 — More APIs 2.0 2017 — .NET Standard 2.0 (~32k APIs), Razor Pages, back to .csproj 2.1 2018 LTS Span<T , SignalR, HttpClientFactory , global tools 2.2 2018 — Health checks, IIS in-process hosting 3.0 2019 — WinForms & WPF on Windows, C 8, Blazor Server, gRPC, endpoint routing, System.Text.Json 3.1 2019 LTS Long-term support version of 3.0; Blazor improvements .NET 5 and later (\"one .NET\" — the successor of both Framework and Core): Version Release Support C Headline features --- --- --- --- --- .NET 5 Nov 2020 STS 9 Unified platform name (skipped \"4\" to avoid confusion with Framework), records, single-file apps .NET 6 Nov 2021 LTS 10 Minimal APIs, hot reload, MAUI (2022), DateOnly , PriorityQueue , unified WebApplication .NET 7 Nov 2022 STS 11 Generic math, rate limiting, output caching, Native AOT for console .NET 8 Nov 2023 LTS 12 Native AOT for ASP.NET Core APIs, Blazor United (static SSR + interactive), TimeProvider , FrozenDictionary , Aspire (preview), keyed DI .NET 9 Nov 2024 STS (extended to 24 months) 13 HybridCache , built-in OpenAPI generation, System.Threading.Lock , LINQ CountBy / AggregateBy , GC dynamic adaptation (DATAS) on by default for Server GC .NET 10 Nov 2025 LTS 14 Extension members, field keyword, file-based apps ( dotnet run app.cs ), JIT de-virtualisation and stack allocation improvements, EF Core 10, ASP.NET Core 10 .NET 11 Nov 2026 (expected) STS 15 In preview during 2026 Support policy: a new version every November; LTS (even numbers) = 3 years of support, STS (odd numbers) = 2 years (extended from 18 months starting with .NET 9). .NET Standard (1.0–2.1) was a specification of APIs shared by Framework, Core, Xamarin and Unity — target netstandard2.0 only for libraries that must still run on .NET Framework. From source code to running program: 1. Write C /VB.NET/F source. 2. Compile — Roslyn ( csc / vbc , run by dotnet build /MSBuild) produces an assembly ( .dll / .exe ) containing IL + metadata (types, members, references) + manifest (assembly name, version, culture, references, resources). 3. Launch — the host ( dotnet.exe /apphost/IIS ANCM) reads .runtimeconfig.json , locates the right runtime version and starts the CLR ( coreclr.dll / libcoreclr.so ). 4. Load — the assembly loader loads the assembly and its dependencies ( .deps.json ) into an AssemblyLoadContext. 5. Type loading — the first use of a type builds its MethodTable (type info, method slots), runs its static constructor. 6. JIT — the first call to a method compiles its IL to native code (tier 0, quick), replaces the stub; hot methods are recompiled with full optimisations (tier 1, possibly using profile data — Dynamic PGO). 7. Execute — native code runs on the CPU; allocations go to the managed heap; the GC reclaims unreachable objects; exceptions unwind stack frames. 8. Shutdown — finalizers may run, the process exits and the OS frees everything. - Inspect IL/assemblies: ILSpy, dnSpy, dotPeek, ildasm (Framework SDK), SharpLab.io (C → IL → JIT assembly in the browser). - Diagnostics CLI: dotnet-counters (GC, CPU, thread pool live), dotnet-trace (event traces), dotnet-dump (memory dumps + analyze ), dotnet-gcdump (heap snapshots), dotnet-stack . - Profilers: Visual Studio Diagnostic Tools / Performance Profiler, PerfView, JetBrains dotMemory/dotTrace, WinDbg + SOS. - Benchmarking: BenchmarkDotNet ( [MemoryDiagnoser] shows allocations). - Info: dotnet --info , dotnet --list-runtimes , dotnet --list-sdks ."},{"kind":"lesson","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"dotnet-framework-vs-dotnet-core-vs-dotnet-5-the-history-explained","title":".NET Framework vs .NET Core vs .NET 5+ — the history explained","body":".NET Framework .NET Core 1–3.1 .NET 5+ --- --- --- --- Years 2002–2019 (4.8.1 in 2022) 2016–2019 2020 → OS Windows only Windows, Linux, macOS Windows, Linux, macOS, mobile (MAUI), WebAssembly Source Closed (reference source available) Open source (MIT) Open source Deployment Machine-wide install, part of Windows Side-by-side, self-contained possible Same + single-file, Native AOT Web ASP.NET Web Forms, MVC 5, Web API 2 ASP.NET Core ASP.NET Core Performance Good Much faster Fastest; improves every release Status Maintenance only Out of support Active Mono (2004, open source, by Ximian → Xamarin → Microsoft) ran .NET on Linux/macOS/mobile and powers Unity and Xamarin; today its runtime is used inside .NET for mobile and WebAssembly. Interview tip: \"Why did they skip .NET 4?\" — to avoid confusion with .NET Framework 4.x; .NET 5 dropped \"Core\" from the name because it became the .NET going forward."},{"kind":"lesson","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"clr-cts-cls-what-each-one-does","title":"CLR, CTS, CLS — what each one does","body":"CLR responsibilities: Component Job --- --- Class loader Loads assemblies and types, builds MethodTables JIT compiler IL → native code Garbage collector Allocates and frees managed memory Type checker / verifier Type safety — no invalid casts or reading random memory Exception manager Structured exception handling across frames and languages Thread support Managed threads, thread pool, synchronisation Security Type safety, (Framework: Code Access Security — removed in Core) Interop P/Invoke, COM interop, marshalling Debugging / profiling APIs Debuggers, profilers, diagnostics CTS — the type system all languages share: text System.Object ├── Value types (System.ValueType): int, double, bool, char, decimal, DateTime, struct, enum (System.Enum) └── Reference types: class, string, array (System.Array), delegate (System.Delegate), interface, record The CTS defines visibility (public, private, internal, protected), inheritance rules (single class inheritance, multiple interfaces), members (fields, methods, properties, events) and how values are boxed. Because C int and VB.NET Integer are both System.Int32 , the languages interoperate perfectly. CLS — the common subset for cross-language libraries. Examples of non-CLS-compliant features: unsigned types in public APIs ( uint — VB.NET historically lacked them), names differing only by case ( Name and name — VB.NET is case-insensitive), pointers. Mark libraries with [assembly: CLSCompliant(true)] and the compiler warns about violations."},{"kind":"lesson","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"compilation-roslyn-il-jit-tiered-compilation-readytorun-and-native-aot","title":"Compilation: Roslyn, IL, JIT, tiered compilation, ReadyToRun and Native AOT","body":"csharp public static int Add(int a, int b) = a + b; compiles to IL (stack-based, CPU-independent): text .method public hidebysig static int32 Add(int32 a, int32 b) cil managed { ldarg.0 // push a ldarg.1 // push b add // pop two, push sum ret // return top of stack } and at runtime the JIT turns it into native code for the actual CPU: text ; x64 lea eax, [rcx+rdx] ret Technique When code becomes native Pros Cons --- --- --- --- JIT (default) At first call of each method Optimises for the actual CPU and runtime profile Startup cost (\"warm-up\") Tiered compilation (.NET Core 3+) Tier 0 quick JIT first, tier 1 optimised for hot methods (after ~30 calls), with Dynamic PGO (on by default since .NET 8) Fast startup and fast steady state More complex ReadyToRun (R2R) Precompiled native code inside the DLL; JIT can still re-optimise Faster startup, still flexible Larger files Native AOT (.NET 7+) Whole app compiled to a native executable at publish Instant start, small memory, no JIT, no runtime install No dynamic code loading, reflection limits (trimming), longer builds NGen (.NET Framework) Native images in a machine cache Faster startup Fragile, Framework-only bash dotnet publish -c Release -r linux-x64 -p:PublishReadyToRun=true dotnet publish -c Release -r win-x64 -p:PublishAot=true"},{"kind":"lesson","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"assemblies-metadata-manifest-gac-strong-names-and-versioning","title":"Assemblies, metadata, manifest, GAC, strong names and versioning","body":"An assembly is the unit of deployment, versioning and security: a .dll or .exe containing: Part Contains --- --- PE header Windows/OS executable format CLR header Runtime version, entry point, flags Metadata Every type, method, field, parameter, attribute and referenced member — what reflection and IntelliSense read IL code Method bodies Manifest Assembly identity (name, version , culture, public key token), list of files, referenced assemblies Resources Embedded files, localised strings Kinds: private assemblies (in the app folder — the norm today), shared assemblies in the GAC (Global Assembly Cache, .NET Framework only — C:\\Windows\\Microsoft.NET\\assembly ), satellite assemblies (localised resources, fr\\MyApp.resources.dll ). Strong name = name + version + culture + public key token, signed with a key pair; required for the GAC in .NET Framework. Version format: major.minor.build.revision . Binding redirects in app.config / web.config solved \"DLL hell\" version conflicts in Framework; modern .NET resolves versions via NuGet and deps.json (no GAC). xml <!-- .NET Framework web.config binding redirect -- <dependentAssembly <assemblyIdentity name=\"Newtonsoft.Json\" publicKeyToken=\"30ad4fe6b2a6aeed\" culture=\"neutral\" / <bindingRedirect oldVersion=\"0.0.0.0-13.0.0.0\" newVersion=\"13.0.0.0\" / </dependentAssembly AppDomain vs AssemblyLoadContext: .NET Framework used AppDomains to isolate and unload code inside one process (IIS used one per web app). .NET Core removed multiple AppDomains; use AssemblyLoadContext (collectible contexts can be unloaded — plugins) or separate processes/containers for isolation."},{"kind":"lesson","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"stack-heap-and-how-value-and-reference-types-are-laid-out","title":"Stack, heap and how value and reference types are laid out","body":"Each thread has a stack (1 MB default on Windows, 8 MB typical on Linux) holding frames: arguments, locals, return addresses, spilled registers. The managed heap is shared by the process and holds objects. Every heap object has a header: text Reference variable (8 bytes on 64-bit) ──▶ [ Object header / sync block index (8 bytes) MethodTable pointer (8 bytes) fields … ] └▶ MethodTable: type info, base type, interface map, vtable slots for methods So an empty object costs ~24 bytes on 64-bit. A struct has no header — its fields are stored inline wherever it lives (stack frame, inside an array, inside another object). csharp class PointClass { public int X, Y; } // heap object: header + MT pointer + 8 bytes of fields (+ padding) ≈ 24 bytes struct PointStruct { public int X, Y; } // 8 bytes, inline var a = new PointStruct[1000]; // one array object, 8,000 bytes of data inline — cache friendly var b = new PointClass[1000]; // one array of 1000 references + up to 1000 separate objects Where things live: Thing Location --- --- Local int / struct variable Stack (or a CPU register) Reference variable (local) Stack — the object it points to is on the heap Object fields (including value-type fields) Inside the object on the heap Array elements Inside the array object on the heap Static fields Special heap area associated with the type (live as long as the AssemblyLoadContext) Locals captured by a lambda or used across await Moved into a heap object (closure class / async state machine)"},{"kind":"lesson","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"the-garbage-collector-in-depth-generations-loh-poh-and-gc-modes","title":"The garbage collector in depth — generations, LOH, POH and GC modes","body":"Allocation: the GC hands each thread an allocation context; new just bumps a pointer — allocation is very cheap. Collection — mark, (sweep), compact: 1. Suspend managed threads at safe points (for blocking GCs). 2. Mark — starting from roots (stack slots and registers, static fields, GC handles, finalization queue), follow references and mark reachable objects. 3. Plan/compact — slide surviving objects together, update all references; free space becomes one contiguous block (no fragmentation). Sometimes it only sweeps (builds a free list) when compaction isn't worth it. 4. Resume threads. Generations (the \"weak generational hypothesis\": most objects die young): Generation Holds Collected --- --- --- Gen 0 Newly allocated small objects Very often, very fast (ms or less) Gen 1 Survivors of one gen-0 GC — buffer between young and old Often Gen 2 Long-lived objects (caches, singletons, static data) Rarely; a \"full GC\" — most expensive LOH — Large Object Heap Objects ≥ 85,000 bytes (big arrays, big strings) Only with gen 2; not compacted by default (can fragment) POH — Pinned Object Heap (.NET 5+) Objects allocated as pinned ( GC.AllocateArray(..., pinned: true) ) With gen 2, never moved Objects that survive a collection are promoted to the next generation. Gen-2 objects referencing gen-0 objects are tracked with a card table so gen-0 GCs don't have to scan all of gen 2. GC modes: Mode Behaviour Default for --- --- --- Workstation One heap; collections on the triggering thread; low pause, less throughput Desktop/console apps Server One heap + GC thread per core ; higher throughput, more memory ASP.NET Core apps Concurrent / Background GC Gen-2 marking runs concurrently with the app; gen 0/1 still pause briefly On by default DATAS (dynamic adaptation, .NET 8 opt-in, on by default with Server GC in .NET 9) Server GC that grows/shrinks heap count to the load — less memory for small containers Containers xml <!-- .csproj -- <PropertyGroup <ServerGarbageCollector true</ServerGarbageCollector <ConcurrentGarbageCollection true</ConcurrentGarbageCollection </PropertyGroup csharp Console.WriteLine(GC.CollectionCount(0) + \" gen0, \" + GC.CollectionCount(2) + \" gen2\"); Console.WriteLine(GC.GetTotalMemory(forceFullCollection: false) / 1 048 576 + \" MB\"); var info = GC.GetGCMemoryInfo(); // heap size, fragmentation, pause durations // GC.Collect(); // almost never call this in production code What triggers a GC: gen-0 budget exhausted (most common), GC.Collect() , low memory notification from the OS, LOH allocation thresholds, container memory limits."},{"kind":"lesson","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"finalization-idisposable-and-the-dispose-pattern","title":"Finalization, IDisposable and the Dispose pattern","body":"The GC frees managed memory only. Unmanaged resources (file handles, sockets, database connections, OS handles, native memory) must be released explicitly — that's what IDisposable is for. csharp public sealed class ReportWriter : IDisposable { private readonly FileStream file = new(\"report.txt\", FileMode.Create); private bool disposed; public void Write(string text) { ObjectDisposedException.ThrowIf( disposed, this); / ... / } public void Dispose() { if ( disposed) return; file.Dispose(); // release what we own disposed = true; } } using var writer = new ReportWriter(); // Dispose() called at end of scope, even on exceptions Finalizers ( ~ClassName() ) run on a dedicated finalizer thread some time after the object becomes unreachable: - Objects with a finalizer survive at least one extra GC (they go to the f-reachable queue ), so they are more expensive. - Order and timing are not guaranteed; finalizers may never run on process crash. - Use them only as a safety net for directly owned unmanaged handles — and prefer SafeHandle , which already implements this correctly. The full Dispose pattern (for non-sealed classes that own unmanaged resources): csharp public class NativeBuffer : IDisposable { private IntPtr ptr = Marshal.AllocHGlobal(1024); private bool disposed; protected virtual void Dispose(bool disposing) { if ( disposed) return; if (disposing) { / dispose managed members (other IDisposables) / } Marshal.FreeHGlobal( ptr); // free unmanaged memory in both paths ptr = IntPtr.Zero; disposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } // no need to finalize anymore ~NativeBuffer() = Dispose(false); // safety net if Dispose was forgotten } IAsyncDisposable / await using for resources whose cleanup is asynchronous (streams flushing to network, DbConnection in async code). Dispose Finalize --- --- --- Called by Your code ( using ) GC finalizer thread Timing Deterministic Non-deterministic Purpose Release managed + unmanaged resources early Last-chance release of unmanaged resources Cost Cheap Extra GC survival, finalizer thread work"},{"kind":"lesson","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"memory-leaks-in-dotnet-and-how-to-find-them","title":"Memory leaks in .NET and how to find them","body":"Common causes of managed \"leaks\" (objects kept reachable): Cause Example Fix --- --- --- Static/singleton collections that only grow static List<Order all Bounded caches ( MemoryCache with size limits/expiry) Event handlers not unsubscribed Short-lived object subscribes to a long-lived publisher's event -= in Dispose, weak events Captured variables in long-lived lambdas/timers Timer callback capturing a big object Dispose timers, avoid capturing Wrong DI lifetimes Scoped DbContext captured inside a singleton (\"captive dependency\") Respect lifetimes; ValidateScopes HttpClient per request Socket exhaustion (not memory, but similar symptom) IHttpClientFactory Not disposing unmanaged resources Streams, Bitmap , connections using LOH fragmentation Many large temporary arrays ArrayPool<T , RecyclableMemoryStream , reuse buffers Pinned objects Long-lived GCHandle.Alloc(..., Pinned) POH or Memory<T / Span<T patterns Investigation steps: bash dotnet-counters monitor -p <pid --counters System.Runtime watch GC heap size, gen-2 count, LOH size over time dotnet-gcdump collect -p <pid heap snapshot → open in Visual Studio / PerfView dotnet-dump collect -p <pid && dotnet-dump analyze <file dumpheap -stat ; gcroot <address Take two snapshots some minutes apart, compare object counts by type, then use gcroot (or \"paths to root\" in the profiler) to see who is holding the growing objects."},{"kind":"lesson","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"type-loading-method-calls-and-virtual-dispatch","title":"Type loading, method calls and virtual dispatch","body":"- When a type is first used, the CLR loads its metadata and builds an EEClass (static type info) and a MethodTable (per-type runtime structure: size, base type, interfaces, vtable of method slots). - Static constructor ( static Foo() { } ) runs once before first use of the type (thread-safe, guaranteed by the CLR). - Non-virtual call: direct call to the method's code address (after JIT). - Virtual call: load the object's MethodTable pointer → read the slot for that method → call it. Overrides replace the slot in the derived type's vtable — that's runtime polymorphism. - Interface call: resolved through virtual stub dispatch (cached per call site). - Sealed classes and the JIT's devirtualisation (helped by PGO) turn virtual calls into direct calls and allow inlining — a reason to mark classes sealed when not designed for inheritance. - Generics: for reference-type arguments the JIT shares one native implementation ( List<string and List<Customer share code); for value types it generates specialised code ( List<int , List<double ) — no boxing and full speed."},{"kind":"lesson","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"threads-the-thread-pool-and-how-async-await-works-inside","title":"Threads, the thread pool and how async/await works inside","body":"Managed threads map 1:1 to OS threads. Creating them is expensive, so .NET uses the ThreadPool : worker threads that run queued work items ( Task.Run , timers, continuations) plus I/O completion handling. It injects threads gradually (hill-climbing) when work is queued faster than it completes — blocking calls cause thread-pool starvation (slow responses, growing queues). async/await under the hood: csharp public async Task<int GetCountAsync() { var json = await http.GetStringAsync(url); // 1. starts I/O, returns an incomplete Task return Parse(json); // 3. continuation after I/O completes } 1. The compiler rewrites the method into a state machine struct ( IAsyncStateMachine ) with a MoveNext() method; locals become fields. 2. At await , if the task isn't complete, the state machine registers a continuation and returns to the caller — the thread goes back to the pool (no thread waits for the network). 3. When the I/O completes (signalled by the OS via IOCP/epoll), a pool thread runs MoveNext() again from the saved state. 4. SynchronizationContext: UI apps and classic ASP.NET resume on the original context (UI thread/request context); ASP.NET Core has no SynchronizationContext, so continuations run on any pool thread. ConfigureAwait(false) in libraries avoids capturing a context. 5. Blocking on async ( .Result , .Wait() ) holds a thread and, with a single-threaded context, can deadlock . ExecutionContext flows ambient data (AsyncLocal, culture, activity/trace id) across awaits automatically."},{"kind":"lesson","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"exceptions-boxing-strings-and-other-runtime-behaviours","title":"Exceptions, boxing, strings and other runtime behaviours","body":"Exceptions inside the CLR: throw creates the exception object and captures the stack trace; the runtime does a two-pass unwind — first finds a matching catch (running exception filters when (...) without unwinding), then unwinds frames running finally blocks. Throwing is expensive (stack walk) — don't use exceptions for normal control flow. Unhandled exceptions on any thread terminate the process (after AppDomain.UnhandledException fires). Boxing: converting a value type to object /interface allocates a heap object with a header and copies the value; unboxing type-checks and copies back. Generics avoid it. Strings: immutable UTF-16 reference types; literals are interned (one instance per value per process); concatenation in loops creates garbage — use StringBuilder , string.Create , interpolation handlers, or Span<char . Type safety and verification: the CLR prevents treating memory as the wrong type; unsafe code with pointers opts out (requires AllowUnsafeBlocks ). Reflection and metadata: typeof(T).GetMethods() reads the assembly metadata at runtime — flexible but slow and AOT-unfriendly; source generators (System.Text.Json, logging, regex) do the work at compile time instead. Interop: P/Invoke ( [LibraryImport(\"user32.dll\")] source-generated in .NET 7+, [DllImport] before) calls native functions with marshalling of parameters; COM interop for Office automation and legacy components."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"171","title":"What is the CLR and what does it do?","body":"The Common Language Runtime is .NET's execution engine. It loads assemblies, verifies type safety, JIT-compiles IL to native code, manages memory with the garbage collector, handles exceptions, threads and synchronisation, provides interop with native code and exposes debugging/profiling services. Code running under it is \"managed code\"."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"172","title":"What are CTS and CLS?","body":"CTS (Common Type System) defines how types are declared and used in .NET — value vs reference types, inheritance, members, visibility — so all languages share one type system (C int = VB.NET Integer = System.Int32 ). CLS (Common Language Specification) is a subset of CTS rules that every .NET language supports, so a CLS-compliant library can be used from any language (e.g. avoid public unsigned types or names differing only in case)."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"173","title":"What is IL (MSIL/CIL) and what does the JIT do?","body":"IL is the CPU-independent, stack-based intermediate code the C /VB.NET compilers produce, stored with metadata in assemblies. At runtime the JIT compiles each method's IL to native machine code on its first call, optimised for the actual CPU; tiered compilation starts with quick code and re-compiles hot methods with full optimisation. ReadyToRun and Native AOT precompile to reduce startup time."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"174","title":"What is the difference between .NET Framework, .NET Core and .NET 5+?","body":".NET Framework (2002–2019) is Windows-only, installed machine-wide, and now only maintained (4.8.1 last); it has Web Forms, WCF and WWF. .NET Core (2016–2019) was the open-source, cross-platform, high-performance rewrite. .NET 5 (2020) onward unifies them as simply \".NET\", released every November with LTS versions (6, 8, 10) supported for 3 years. New projects use .NET 8/10."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"175","title":"What is managed vs unmanaged code?","body":"Managed code runs under the CLR, which handles memory (GC), type safety and exceptions — C , VB.NET, F . Unmanaged code runs directly on the OS without the CLR — C/C++ DLLs, Win32 APIs, COM components — and manages its own memory. .NET calls unmanaged code via P/Invoke or COM interop; resources from it must be released with IDisposable / SafeHandle ."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"176","title":"What is an assembly? What does it contain?","body":"The unit of deployment and versioning in .NET — a .dll or .exe containing IL code, metadata describing all types and members, a manifest (name, version, culture, public key token, references) and optional resources. Assemblies can be private (in the app folder), shared in the GAC (.NET Framework) or satellite (localised resources)."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"177","title":"Explain how the garbage collector works. What are generations?","body":"The GC allocates objects by bumping a pointer and, when the gen-0 budget is used up, suspends threads, marks all objects reachable from roots (stack, statics, handles), compacts survivors and updates references. Generations: gen 0 for new objects (collected often and cheaply), gen 1 as a buffer, gen 2 for long-lived objects (full, expensive collections). Large objects (≥ 85,000 bytes) go to the LOH, collected with gen 2 and not compacted by default."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"178","title":"Dispose vs Finalize — what's the difference? What is the Dispose pattern?","body":"Dispose (from IDisposable ) is called deterministically by your code ( using ) to release resources early; a finalizer ( ~Class() ) is called non-deterministically by the GC's finalizer thread as a safety net for unmanaged resources and makes objects survive an extra GC. The Dispose pattern: Dispose() calls Dispose(true) and GC.SuppressFinalize(this) ; the finalizer calls Dispose(false) ; Dispose(bool disposing) frees managed resources only when disposing is true and unmanaged resources always. Prefer SafeHandle over writing finalizers."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"179","title":"Where are value types and reference types stored?","body":"Reference-type objects are always on the managed heap; variables hold references to them. Value types are stored inline where they are declared: on the stack (or in registers) for locals, inside the containing object for fields, inside the array for array elements, and on the heap when boxed or captured by closures/async methods. So \"value types live on the stack\" is only partly true."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"180","title":"Workstation vs Server GC?","body":"Workstation GC uses one heap and runs collections on the allocating thread — lower memory and shorter pauses, suited to desktop apps. Server GC creates one heap and one dedicated GC thread per logical core and collects in parallel — higher throughput and allocation rates, more memory, the default for ASP.NET Core. Both support background (concurrent) gen-2 collection; .NET 9 enables DATAS to adapt Server GC heap count to load."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"181","title":"What is the GAC and is it used in .NET Core?","body":"The Global Assembly Cache is a machine-wide store for strong-named shared assemblies in .NET Framework, letting multiple apps share one version (with binding redirects for versioning). .NET Core/.NET 5+ doesn't use the GAC: dependencies come from NuGet and are deployed with the app (or the shared framework), resolved via deps.json ."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"182","title":"AppDomain vs AssemblyLoadContext?","body":"AppDomains (.NET Framework) isolated code within one process and could be unloaded — IIS ran each web app in its own AppDomain. .NET Core supports only one AppDomain; isolation and unloading of plugins use AssemblyLoadContext (collectible contexts can be unloaded), and strong isolation uses separate processes or containers."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"183","title":"What is tiered compilation, ReadyToRun and Native AOT?","body":"Tiered compilation JITs methods quickly at tier 0 and recompiles frequently used methods with full optimisation (tier 1, with Dynamic PGO) — fast startup and fast steady state. ReadyToRun ships precompiled native code inside assemblies for faster startup while keeping the JIT. Native AOT compiles the entire app ahead of time into a self-contained native executable — fastest startup and lowest memory, but no runtime code generation and limited reflection."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"184","title":"How does async/await work internally?","body":"The compiler turns an async method into a state-machine struct; each await checks whether the awaited task has completed — if not, it stores the current state, registers a continuation and returns an incomplete Task to the caller, releasing the thread. When the operation completes (the OS signals I/O completion), the continuation runs MoveNext() from the saved state on a thread-pool thread (or the captured SynchronizationContext). No thread is blocked while waiting for I/O."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"185","title":"How do you find a memory leak in a production .NET application?","body":"Confirm growth with dotnet-counters / Application Insights (GC heap size and gen-2 size rising, gen-2 collections not reclaiming). Capture heap snapshots ( dotnet-gcdump ) or full dumps ( dotnet-dump ) at two points in time, compare object counts by type, and find the roots keeping them alive ( gcroot , \"paths to root\"). Typical culprits: unbounded static caches, event handlers not unsubscribed, timers, captive dependencies in DI, undisposed resources, LOH fragmentation from large buffers."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"186","title":"What is the Large Object Heap and why can it cause problems?","body":"Objects of 85,000 bytes or more are allocated on the LOH, which is collected only with gen 2 and not compacted by default, so frequent large temporary allocations (big arrays, MemoryStream buffers, large strings) cause expensive full GCs and fragmentation (memory grows though objects are freed). Fix with buffer reuse ( ArrayPool<T , RecyclableMemoryStream ), streaming instead of loading everything, or occasional LOH compaction ( GCSettings.LargeObjectHeapCompactionMode )."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"187","title":"How does virtual method dispatch work in the CLR?","body":"Each type has a MethodTable with a vtable of slots for its virtual methods; derived types copy the base slots and replace those they override. A virtual call loads the object's MethodTable pointer, reads the slot for the method and calls that address — so the runtime type decides which implementation runs. Sealed types and JIT devirtualisation (with PGO) can turn these into direct calls and enable inlining."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"188","title":"An ASP.NET Core API's memory grows steadily until the container is OOM-killed every few hours. What do you do?","body":"Monitor GC counters to see if the managed heap (gen 2/LOH) grows or native memory grows. Take two dotnet-gcdump snapshots and compare the biggest growing types; check their roots. Common findings: an in-memory cache without limits, a singleton holding scoped objects or request data, event subscriptions, HttpClient created per request, large response buffering in the LOH. Also set container memory limits correctly (GC respects them), consider DATAS/workstation GC for small containers, and add alerts on memory growth."},{"kind":"question","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"189","title":"A console tool processes images and becomes slow with frequent gen-2 collections. Why?","body":"Each image creates large byte arrays ( 85 KB) on the LOH; allocating many short-lived large objects forces gen-2 collections and fragments the LOH. Reuse buffers with ArrayPool<byte .Shared , process images as streams, dispose Bitmap /image objects promptly (they hold native memory), and measure with BenchmarkDotNet's MemoryDiagnoser or dotnet-counters ."},{"kind":"cheat","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"1","title":"Architecture in one line","body":"Source → Roslyn → assembly (IL + metadata + manifest) → host starts CLR → loader + type loader → JIT (tier 0 → tier 1 + PGO) → native code → GC manages heap."},{"kind":"cheat","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"2","title":"Version map","body":"Framework 1.0 (2002) → 2.0 generics → 3.5 LINQ → 4.0 TPL → 4.5 async → 4.8 last (4.8.1 ARM64). Core 1.0 (2016) → 2.1 LTS → 3.1 LTS. .NET 5 (2020) → 6 LTS → 7 → 8 LTS → 9 → 10 LTS (2025). Even = LTS 3 yrs, odd = STS 2 yrs."},{"kind":"cheat","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"3","title":"GC essentials","body":"Gen 0 → 1 → 2; LOH ≥ 85,000 bytes (not compacted); POH for pinned; Workstation vs Server (+ background, DATAS); roots = stacks, statics, handles; finalizers delay collection; never GC.Collect() in normal code."},{"kind":"cheat","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"4","title":"Dispose rules","body":"using / await using everything disposable · SafeHandle instead of finalizers · Dispose(bool) + GC.SuppressFinalize for the full pattern · dispose what you own only."},{"kind":"cheat","course_slug":"dotnet-internals","course_title":".NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection","ref":"5","title":"Diagnose","body":"dotnet-counters (live) · dotnet-gcdump (heap) · dotnet-dump analyze ( dumpheap -stat , gcroot ) · dotnet-trace (CPU/events) · BenchmarkDotNet MemoryDiagnoser."},{"kind":"course","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"","title":"OOP Concepts in C#","body":"Classes and objects, the four pillars (encapsulation, abstraction, inheritance, polymorphism), interfaces vs abstract classes, composition and object relationships. Object-Oriented Programming (OOP) organises code around objects — bundles of data (state) and behaviour (methods) — instead of loose functions and global data. C is designed around OOP, and every .NET interview tests it. The four pillars : Pillar One line C features --- --- --- Encapsulation Hide internal state; expose a controlled API private fields, properties, access modifiers Abstraction Show what an object does, hide how interface , abstract class Inheritance Reuse and extend a base type (\"is-a\") : BaseClass , virtual / override , sealed Polymorphism One interface, many implementations Overloading (compile time), overriding (runtime) OOP is a paradigm, not a versioned product, but C has added OOP-related features over time: C OOP-related additions --- --- 1.0 Classes, interfaces, inheritance, virtual/override, abstract, sealed, properties, events 2.0 Generics, static classes, partial classes 3.0 Auto-properties, object initialisers, extension methods 8.0 Default interface methods (interfaces can contain implementations) 9.0 Records (value equality), init accessors, covariant return types 11 required members, static abstract members in interfaces 12 Primary constructors for classes and structs 14 Extension members (extension properties) History: Simula 67 introduced classes; Smalltalk (1970s) popularised \"everything is an object\"; C++, Java and C made OOP mainstream. Object lifecycle in .NET 1. Type loading — the first time a type is used, the CLR loads it and runs its static constructor once. 2. Allocation — new reserves memory on the managed heap (value types: inline). 3. Construction — field initialisers run, then base-class constructor, then the derived constructor body ( : base(...) / : this(...) chaining). 4. Use — methods called, state changes through its public API. 5. Unreachable — no references remain. 6. Collection — GC reclaims memory; a finaliser runs first if defined. 7. Disposal (optional, deterministic) — Dispose() via using releases unmanaged resources earlier. OOP design lifecycle (OOAD): requirements → identify nouns (classes) and verbs (methods) → define responsibilities and relationships (UML class diagram) → apply principles (SOLID) and patterns → implement → unit test → refactor. - Visual Studio Class Designer / Class Diagram — visualise classes and inheritance. - UML tools — draw.io, PlantUML, Mermaid, StarUML, Lucidchart. - ReSharper / Rider — refactorings: extract interface, pull members up, introduce parameter object. - SharpLab.io — see what the compiler generates (records, primary constructors). - xUnit + Moq/NSubstitute — test classes through interfaces."},{"kind":"lesson","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"class-object-fields-properties-and-methods","title":"Class, object, fields, properties and methods","body":"A class is a blueprint; an object is an instance created from it at runtime. csharp public class BankAccount { private decimal balance; // field (state) — private public string Owner { get; } // read-only property public decimal Balance = balance; // computed property public BankAccount(string owner, decimal opening = 0) // constructor { Owner = owner; balance = opening; } public void Deposit(decimal amount) // method (behaviour) { if (amount <= 0) throw new ArgumentOutOfRangeException(nameof(amount)); balance += amount; } } var acc = new BankAccount(\"Divakar\", 500); // object acc.Deposit(250); Console.WriteLine(acc.Balance); // 750"},{"kind":"lesson","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"constructors-default-parameterised-static-private-chaining","title":"Constructors: default, parameterised, static, private, chaining","body":"csharp public class Logger { public static readonly DateTime LoadedAt; static Logger() { LoadedAt = DateTime.UtcNow; } // static ctor: once per type, before first use public string Name { get; } public Logger() : this(\"default\") { } // chaining to another ctor public Logger(string name) { Name = name; } } public class Settings { private Settings() { } // private ctor: no outside 'new' public static Settings Load() = new Settings(); // factory method / Singleton } public class Admin : User { public Admin(string email) : base(email) { } // call base constructor } - If you write no constructor, C provides a parameterless one. Writing any constructor removes it. - Order: static fields → static ctor (once) → instance field initialisers → base ctor → derived ctor body. - Copy constructor: a constructor taking another instance of the same type (records generate one)."},{"kind":"lesson","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"access-modifiers","title":"Access modifiers","body":"Modifier Accessible from --- --- public Everywhere private Same class only (default for class members) protected Same class and derived classes internal Same assembly (default for top-level types) protected internal Same assembly or derived classes anywhere private protected Derived classes in the same assembly only file (C 11) Same source file (for types) Interview tip: the default access for class members is private ; for a top-level class it is internal ."},{"kind":"lesson","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"static-members-static-classes-and-partial-classes","title":"Static members, static classes and partial classes","body":"csharp public static class MathHelper // cannot be instantiated or inherited { public static double Square(double x) = x x; } public class Counter { public static int Instances; // shared across all objects public Counter() = Instances++; } public partial class Customer { public string Name { get; set; } = \"\"; } // file 1 public partial class Customer { public string Display() = Name.ToUpper(); } // file 2 (e.g. generated code) Static members belong to the type , not to an object. Avoid mutable static state in web apps — it is shared by every request and thread."},{"kind":"lesson","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"encapsulation","title":"Encapsulation","body":"Encapsulation = keep data private and allow changes only through methods that enforce the rules (invariants). csharp // Bad: anyone can put the object in an invalid state public class OrderBad { public List<OrderLine Lines = new(); public decimal Total; } // Good: the object protects its invariants public class Order { private readonly List<OrderLine lines = []; public IReadOnlyList<OrderLine Lines = lines; public decimal Total = lines.Sum(l = l.Price l.Qty); public void AddLine(Product p, int qty) { if (qty <= 0) throw new ArgumentException(\"Qty must be positive\"); lines.Add(new OrderLine(p.Id, p.Price, qty)); } } Benefits: validation in one place, freedom to change internals, fewer bugs."},{"kind":"lesson","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"abstraction","title":"Abstraction","body":"Abstraction = expose only what callers need and hide implementation details. In C you abstract with interfaces and abstract classes . csharp public interface IPaymentGateway { Task<PaymentResult ChargeAsync(decimal amount, string currency, string token); } public class RazorpayGateway : IPaymentGateway { / HTTP calls, signatures, retries hidden here / } public class StripeGateway : IPaymentGateway { / ... / } public class CheckoutService(IPaymentGateway gateway) // depends on the abstraction only { public Task<PaymentResult Pay(Order o) = gateway.ChargeAsync(o.Total, \"INR\", o.CardToken); } Interview tip: encapsulation is about hiding data (how state is protected); abstraction is about hiding complexity (what is exposed). They work together."},{"kind":"lesson","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"inheritance","title":"Inheritance","body":"A derived class inherits members of a base class and can extend or override them. C supports single class inheritance and multiple interface implementation . csharp public abstract class Employee { public string Name { get; } protected Employee(string name) = Name = name; public abstract decimal MonthlyPay(); // must override public virtual string Describe() = $\"{Name}: {MonthlyPay():C}\"; // may override } public class Permanent(string name, decimal salary) : Employee(name) { public override decimal MonthlyPay() = salary / 12; } public sealed class Contractor(string name, decimal rate, int hours) : Employee(name) { public override decimal MonthlyPay() = rate hours; public override string Describe() = base.Describe() + \" (contract)\"; } Types of inheritance: single, multilevel (A→B→C), hierarchical (B and C from A). Multiple class inheritance is not allowed (avoids the diamond problem); use interfaces instead."},{"kind":"lesson","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"polymorphism-overloading-vs-overriding","title":"Polymorphism: overloading vs overriding","body":"Compile-time (static) polymorphism — method overloading : same name, different parameter lists, chosen by the compiler. Operator overloading is also compile-time. Runtime (dynamic) polymorphism — method overriding : a virtual / abstract base method replaced with override in a derived class; the actual object type decides at runtime. csharp public class Calculator { public int Add(int a, int b) = a + b; // overloads public double Add(double a, double b) = a + b; public int Add(int a, int b, int c) = a + b + c; } List<Employee staff = [new Permanent(\"Asha\", 1 200 000), new Contractor(\"Ravi\", 900, 160)]; foreach (var e in staff) Console.WriteLine(e.Describe()); // each object's own override runs Method hiding ( new ) is different: the method chosen depends on the variable's type, not the object's. csharp class A { public virtual string Who() = \"A\"; public string Name() = \"A\"; } class B : A { public override string Who() = \"B\"; public new string Name() = \"B\"; } A x = new B(); Console.WriteLine(x.Who()); // B (override — runtime type) Console.WriteLine(x.Name()); // A (hiding — compile-time type)"},{"kind":"lesson","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"interface-vs-abstract-class","title":"Interface vs abstract class","body":"Interface Abstract class --- --- --- Purpose A contract / capability (\"can do\") A partial base implementation (\"is a\") Multiple A class can implement many A class can inherit only one Fields / state No instance fields Can have fields and state Constructors No Yes Implementation Default methods allowed since C 8 Abstract and concrete members Access modifiers Members public by default Any Use when Unrelated types share behaviour; for DI and mocking Related types share code and state csharp public interface IShape { double Area(); string Name = GetType().Name; } // default implementation (C 8) public abstract class Shape : IShape { public abstract double Area(); public override string ToString() = $\"{GetType().Name} area={Area():F2}\"; // shared code } public class Circle(double r) : Shape { public override double Area() = Math.PI r r; }"},{"kind":"lesson","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"explicit-interface-implementation","title":"Explicit interface implementation","body":"Used when two interfaces have the same member, or to hide a member from the class's public API. csharp public interface IPrinter { void Print(); } public interface IScanner { void Print(); } // same name public class Mfp : IPrinter, IScanner { void IPrinter.Print() = Console.WriteLine(\"printing\"); void IScanner.Print() = Console.WriteLine(\"printing scan log\"); } var m = new Mfp(); ((IPrinter)m).Print(); // only callable through the interface"},{"kind":"lesson","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"sealed-classes-virtual-override-base-and-new","title":"Sealed classes, virtual, override, base and new","body":"- virtual — the base method can be overridden. - override — replaces a virtual/abstract member. - sealed override — stops further overriding down the chain. - sealed class — cannot be inherited (e.g. string ); also lets the JIT devirtualise calls. - base.Method() — call the base implementation from the override. - new — hides a base member (rarely what you want; the compiler warns without it). - Static methods can't be virtual (except static abstract interface members in C 11 for generic math)."},{"kind":"lesson","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"association-aggregation-and-composition","title":"Association, aggregation and composition","body":"Relationship Meaning Lifetime Example --- --- --- --- Association \"uses\" / knows about Independent Teacher ↔ Student Aggregation \"has-a\", weak ownership Part can exist without whole Department has Employees Composition \"owns-a\", strong ownership Part dies with whole Order owns OrderLines ; House owns Rooms Inheritance \"is-a\" — Car is a Vehicle csharp public class Order // composition: lines are created and owned by the order { private readonly List<OrderLine lines = []; public void Add(string sku, int qty) = lines.Add(new OrderLine(sku, qty)); } public class Department // aggregation: employees exist independently { public List<Employee Members { get; } = []; }"},{"kind":"lesson","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"composition-over-inheritance","title":"Composition over inheritance","body":"Deep inheritance trees are fragile: a change in the base class ripples down (\"fragile base class problem\"), and you inherit things you don't need. Prefer composing objects from small pieces and inheriting only for true \"is-a\" relationships. csharp // Inheritance explosion: EmailNotifier, SmsNotifier, EmailAndSmsNotifier, LoggedEmailNotifier... // Composition: combine behaviours at runtime public interface IChannel { Task SendAsync(string to, string msg); } public class Notifier(IEnumerable<IChannel channels) { public Task NotifyAsync(string to, string msg) = Task.WhenAll(channels.Select(c = c.SendAsync(to, msg))); }"},{"kind":"lesson","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"object-equality-gethashcode-and-tostring","title":"Object equality, GetHashCode and ToString","body":"csharp public sealed class Money : IEquatable<Money { public decimal Amount { get; } public string Currency { get; } public Money(decimal amount, string currency) = (Amount, Currency) = (amount, currency); public bool Equals(Money? other) = other is not null && Amount == other.Amount && Currency == other.Currency; public override bool Equals(object? obj) = Equals(obj as Money); public override int GetHashCode() = HashCode.Combine(Amount, Currency); public override string ToString() = $\"{Amount} {Currency}\"; } // Or simply: public record Money(decimal Amount, string Currency); — generates all of the above Rule: equal objects must return equal hash codes, otherwise Dictionary / HashSet lookups fail."},{"kind":"lesson","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"cohesion-coupling-and-the-law-of-demeter","title":"Cohesion, coupling and the Law of Demeter","body":"- High cohesion: a class does one focused job; its members belong together. - Low coupling: classes depend on few others, through abstractions. - Law of Demeter (\"talk to friends, not strangers\"): avoid order.Customer.Address.City.Name chains; ask the object to do the work: order.ShippingCity() . - Tell, don't ask: tell the object what to do rather than pulling data out and deciding for it. These lead straight into SOLID, covered in the next course."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"190","title":"What are the four pillars of OOP? Explain each with an example.","body":"1. Encapsulation — private state with a controlled public API. BankAccount keeps balance private and exposes Deposit() that rejects negative amounts. 2. Abstraction — expose what , hide how . IPaymentGateway.ChargeAsync() hides HTTP calls, signatures and retries. 3. Inheritance — a derived class reuses and extends a base. Contractor : Employee reuses Name and Describe() . 4. Polymorphism — the same call behaves differently by type. employee.MonthlyPay() runs the Permanent or Contractor override at runtime."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"191","title":"What is the difference between a class and an object?","body":"A class is a type definition (blueprint) describing fields, properties and methods; it exists in code and metadata. An object is an instance of that class created at runtime with new , occupying memory with its own state. One class, many objects."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"192","title":"What is the difference between method overloading and method overriding?","body":"Overloading Overriding --- --- Same name, different parameters Same signature in a derived class Same class (or derived) Requires virtual / abstract + override Resolved at compile time Resolved at runtime by the object's type Return type alone can't differ Return type the same (covariant returns allowed since C 9)"},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"193","title":"What is the difference between an abstract class and an interface? When do you use which?","body":"An abstract class can hold state, constructors and shared implementation, and a class can inherit only one. An interface is a contract; a class can implement many, and it has no instance state (default methods are allowed since C 8). Use an interface for capabilities and dependency injection ( IEmailSender ) and an abstract class when related types share code and state ( Shape , Employee ). A common design is to use both: the interface for consumers, an abstract base for shared code."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"194","title":"Does C# support multiple inheritance?","body":"Not for classes — a class has exactly one base class, which avoids the diamond problem (ambiguity when two parents implement the same member). A class can implement multiple interfaces . If two interfaces declare the same member, use explicit interface implementation to disambiguate."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"195","title":"What are access modifiers? What are the defaults?","body":"public , private , protected , internal , protected internal , private protected (plus file for types). Defaults: class members are private ; top-level types are internal ; interface members are public ."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"196","title":"What is a constructor? Can it be private or static?","body":"A constructor initialises a new object and has the class's name and no return type. A private constructor prevents outside instantiation (Singleton, factory methods, static-like classes). A static constructor takes no parameters and no access modifier, runs once before the type is first used, and initialises static data. Constructors can be overloaded and chained with this(...) / base(...) . They are not inherited."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"197","title":"What is the `sealed` keyword?","body":"A sealed class can't be inherited (e.g. string ). A sealed override method can't be overridden further. Use it to lock down security-sensitive or invariant-heavy types. It also gives a small performance gain because the JIT can devirtualise calls."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"198","title":"What is the difference between method overriding and method hiding (`new`)?","body":"With override , the runtime type decides which method runs — true polymorphism. With hiding ( new ), the compile-time variable type decides: A x = new B(); x.Name() calls A.Name() . Hiding breaks polymorphism and is usually a design smell. The compiler warns if you hide a member without the new keyword."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"199","title":"What is the difference between composition and inheritance? Why \"favour composition\"?","body":"Inheritance is a static \"is-a\" relationship fixed at compile time; subclasses depend on base-class internals, so base changes can break them. Composition is \"has-a\": an object holds other objects (often via interfaces) and delegates to them. You can swap them at runtime, test them in isolation and avoid class explosions. Use inheritance only when the subtype really is a substitutable kind of the base (see LSP)."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"200","title":"Explain association, aggregation and composition with examples.","body":"All three are \"uses/has\" relationships of different strength. Association : two classes know about each other and have independent lifetimes (Doctor–Patient). Aggregation : whole–part where the part can exist alone (Team–Player; delete the team and the players remain). Composition : whole–part with shared lifetime (Order–OrderLine, House–Room; delete the order and its lines go too)."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"201","title":"Can you create an instance of an abstract class? Can an abstract class have a constructor?","body":"You can't instantiate it with new . It can have constructors, usually protected , which derived classes call via : base(...) to initialise shared state. An abstract class can also have no abstract members at all; it's then just a base that must not be used directly."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"202","title":"What are virtual methods? Why aren't methods virtual by default in C#?","body":"A virtual method can be overridden in derived classes. C makes methods non-virtual by default (unlike Java) for performance (non-virtual calls are direct and can be inlined) and versioning safety: designers must explicitly allow overriding, so a new base method can't accidentally change the behaviour of subclasses."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"203","title":"What is a static class? Static vs singleton?","body":"A static class can't be instantiated or inherited and contains only static members (e.g. Math , extension method holders). A singleton is a normal class with one instance. It can implement interfaces, be passed as a dependency, be lazily created and be mocked. In ASP.NET Core you usually get singleton behaviour by registering a service with AddSingleton rather than writing the pattern by hand."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"204","title":"Why must you override GetHashCode when you override Equals?","body":"Hash-based collections ( Dictionary , HashSet ) first compare hash codes to find a bucket, then call Equals . If two equal objects return different hash codes, lookups miss and duplicates appear. The contract: a.Equals(b) ⇒ a.GetHashCode() == b.GetHashCode() . Use HashCode.Combine(...) , or use a record , which generates both."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"205","title":"What is an interface default method (C# 8) and why was it added?","body":"Interfaces can now include a method body. It was added so library authors can add members to a published interface without breaking existing implementers , and for Java/Swift interop. The default implementation is only reachable through the interface type, not through the class variable."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"206","title":"What are cohesion and coupling? How do you measure them in practice?","body":"Cohesion is how strongly related a class's responsibilities are; coupling is how much a class depends on others. Aim for high cohesion and low coupling. Signs of trouble: classes named Manager / Helper / Utils with unrelated methods, constructors with 8+ dependencies, and changes that ripple across many files. Tools: Visual Studio code metrics (class coupling, maintainability index), NDepend, SonarQube."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"207","title":"What are covariant return types (C# 9)?","body":"An override can return a more derived type than the base method. For example, Animal.Clone() returns Animal , and Dog.Clone() can be declared to return Dog . Callers then don't need to cast."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"208","title":"You have `Bird` with a `Fly()` method and now need `Penguin`. How do you model it?","body":"Making Penguin : Bird and throwing NotSupportedException from Fly() violates Liskov substitution: callers that loop over birds and call Fly() will crash. Split the capability out: Bird (common: eat, lay eggs) plus an IFlyable interface implemented only by birds that fly. Code that needs flying asks for IFlyable . This is composition of capabilities over a deep hierarchy."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"209","title":"A `ReportGenerator` class has methods for fetching data, formatting PDF and Excel, emailing and logging. It's 3,000 lines. How would you refactor it?","body":"Identify the responsibilities and extract each into a focused class behind an interface: IReportDataSource , IReportFormatter (with PdfFormatter and ExcelFormatter ), IReportSender and ILogger . ReportGenerator then orchestrates them, receiving them by constructor injection. Add unit tests around the current behaviour before extracting (characterisation tests), then refactor in small steps. Result: SRP, OCP (new format = new formatter class) and easy mocking."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"210","title":"Your team adds a new payment method every quarter, and each time someone edits a big switch statement in `PaymentService`. What design would you suggest?","body":"Replace the switch with polymorphism : an IPaymentMethod interface with one class per method (Card, UPI, Wallet, BankTransfer). Register all of them in DI, and have a resolver pick the right one by key. Adding a method means adding a class and a DI registration, without touching existing code (Open/Closed principle, Strategy pattern)."},{"kind":"question","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"211","title":"An interviewer asks you to design classes for a parking lot. What would you show?","body":"Start with the nouns: ParkingLot (has Levels ), Level (has Spots ), ParkingSpot (abstract: Compact , Large , Motorbike , EvCharging ), Vehicle (abstract: Car , Bike , Truck ), Ticket , Payment , EntryGate / ExitGate . Behaviour: ParkingLot.Park(vehicle) finds a fitting spot (Strategy for allocation), issues a Ticket ; Exit(ticket) calculates the fee (Strategy for pricing) and frees the spot. Mention encapsulation (spot availability private), polymorphism ( CanFit(vehicle) ), concurrency (two cars taking the same spot: lock per level or an atomic DB update), and extensibility (new vehicle types)."},{"kind":"cheat","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"1","title":"Four pillars in one line each","body":"- Encapsulation — private data, public methods that guard rules. - Abstraction — interfaces/abstract classes expose what , hide how . - Inheritance — Derived : Base reuses and extends (\"is-a\"). - Polymorphism — overloading (compile time) and overriding (runtime)."},{"kind":"cheat","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"2","title":"Interface vs abstract class","body":"Interface Abstract class --- --- --- Inherit many? Yes No (one) State/fields No Yes Constructor No Yes Default implementation Yes (C 8+) Yes Best for Contracts, DI, mocking Shared base code"},{"kind":"cheat","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"3","title":"Keywords","body":"Keyword Meaning --- --- virtual May be overridden abstract Must be overridden; no body override Replaces base virtual/abstract sealed No further inheritance/override new Hides a base member (no polymorphism) base Access base members/constructor this Current instance / chain constructors static Belongs to the type"},{"kind":"cheat","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"4","title":"Relationships","body":"- Association: uses (independent lifetimes) - Aggregation: has-a (part survives) - Composition: owns-a (part dies with whole) - Inheritance: is-a - Prefer composition; inherit only for true substitutable \"is-a\"."},{"kind":"cheat","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"5","title":"Constructor order","body":"Static field initialisers → static ctor (once) → instance field initialisers (derived, then base) → base ctor body → derived ctor body."},{"kind":"cheat","course_slug":"oop","course_title":"OOP Concepts in C#","ref":"6","title":"Equality checklist","body":"- Override Equals(object) , implement IEquatable<T , override GetHashCode with HashCode.Combine . - Or use record for value equality for free."},{"kind":"course","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"","title":"SOLID Principles with Examples","body":"The five SOLID principles with bad-vs-good C code, plus DRY, KISS, YAGNI, dependency injection and how SOLID shows up in ASP.NET Core. SOLID is five object-oriented design principles that make code easier to change, test and extend. The acronym was coined by Michael Feathers around 2004 for principles collected by Robert C. Martin (\"Uncle Bob\") in the late 1990s and early 2000s. Letter Principle One-line meaning --- --- --- S Single Responsibility A class should have one reason to change O Open/Closed Open for extension, closed for modification L Liskov Substitution Subtypes must be usable wherever the base type is expected I Interface Segregation Many small, specific interfaces beat one fat interface D Dependency Inversion Depend on abstractions, not concrete classes Interviewers almost always ask you to explain each with an example and then show where you applied it . Year Milestone --- --- 1987 Barbara Liskov presents the substitution idea (keynote \"Data Abstraction and Hierarchy\"); formalised with Jeannette Wing in 1994 1988 Bertrand Meyer defines the Open/Closed Principle in Object-Oriented Software Construction 1996–2000 Robert C. Martin publishes articles on OCP, LSP, DIP, ISP; paper \"Design Principles and Design Patterns\" (2000) ~2004 Michael Feathers arranges them into the acronym SOLID 2002 / 2006 Agile Software Development: Principles, Patterns, and Practices (and the C edition, 2006) 2017 Clean Architecture restates SRP as \"a module should be responsible to one actor\" How SOLID is applied during development: 1. Design — split responsibilities (SRP), define interfaces around what consumers need (ISP, DIP). 2. Implement — inject dependencies through constructors; keep classes small. 3. Extend — add behaviour by adding new classes (OCP) rather than editing switches. 4. Test — mock the abstractions; unit-test each class in isolation. 5. Review — code review checks for god classes, new of services inside business logic, and subclasses that throw NotSupportedException (LSP smell). 6. Refactor — when a class keeps changing for unrelated reasons, split it. - ASP.NET Core DI container ( Microsoft.Extensions.DependencyInjection ) — DIP in practice. - Scrutor — assembly scanning and decorators for the built-in container. - Autofac — advanced DI container. - xUnit + Moq / NSubstitute / FakeItEasy — mocking abstractions. - SonarQube / SonarLint, NDepend, Visual Studio code metrics — find large classes, high coupling, complexity. - ArchUnitNET / NetArchTest — enforce layering rules in tests."},{"kind":"lesson","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"s-single-responsibility-principle","title":"S — Single Responsibility Principle","body":"\"A class should have one, and only one, reason to change.\" — Robert C. Martin \"Reason to change\" = one actor or stakeholder. A class that formats invoices and saves them and emails them changes when finance, DBAs or the email provider change. csharp // ❌ Violates SRP — three reasons to change public class InvoiceService { public decimal Calculate(Invoice i) = i.Lines.Sum(l = l.Qty l.Price) 1.18m; public void Save(Invoice i) { using var c = new SqlConnection(\"...\"); / INSERT ... / } public void Email(Invoice i) { var smtp = new SmtpClient(\"smtp.example.com\"); / ... / } } // ✅ One responsibility each public class InvoiceCalculator { public decimal Total(Invoice i) = i.Lines.Sum(l = l.Qty l.Price) 1.18m; } public interface IInvoiceRepository { Task SaveAsync(Invoice i); } public interface IInvoiceSender { Task SendAsync(Invoice i); } public class InvoiceWorkflow(InvoiceCalculator calc, IInvoiceRepository repo, IInvoiceSender sender) { public async Task CompleteAsync(Invoice i) { i.Total = calc.Total(i); await repo.SaveAsync(i); await sender.SendAsync(i); } } Interview tip: SRP doesn't mean \"one method per class\". It means one cohesive job. Controllers that only orchestrate are fine."},{"kind":"lesson","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"o-open-closed-principle","title":"O — Open/Closed Principle","body":"Software entities should be open for extension, closed for modification : add new behaviour by adding code, not by editing tested code. csharp // ❌ Every new customer type edits this method public decimal Discount(string type, decimal amount) = type switch { \"Regular\" = amount 0.05m, \"Gold\" = amount 0.10m, \"Platinum\" = amount 0.15m, // edit again next quarter... = 0 }; // ✅ New type = new class; existing code untouched (Strategy pattern) public interface IDiscountRule { string Type { get; } decimal Apply(decimal amount); } public class GoldDiscount : IDiscountRule { public string Type = \"Gold\"; public decimal Apply(decimal a) = a 0.10m; } public class PlatinumDiscount : IDiscountRule { public string Type = \"Platinum\"; public decimal Apply(decimal a) = a 0.15m; } public class DiscountService(IEnumerable<IDiscountRule rules) { public decimal Discount(string type, decimal amount) = rules.FirstOrDefault(r = r.Type == type)?.Apply(amount) ?? 0; } // Program.cs builder.Services.AddSingleton<IDiscountRule, GoldDiscount (); builder.Services.AddSingleton<IDiscountRule, PlatinumDiscount (); ASP.NET Core itself is OCP: you extend the pipeline by adding middleware, filters and services, without editing the framework."},{"kind":"lesson","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"l-liskov-substitution-principle","title":"L — Liskov Substitution Principle","body":"If S is a subtype of T , objects of type T may be replaced by objects of type S without breaking the program . Subclasses must honour the base class's contract: no stronger preconditions, no weaker postconditions, no surprise exceptions. csharp // ❌ Classic violation: Square changes Rectangle's behaviour public class Rectangle { public virtual int Width { get; set; } public virtual int Height { get; set; } public int Area = Width Height; } public class Square : Rectangle { public override int Width { set { base.Width = value; base.Height = value; } } public override int Height { set { base.Width = value; base.Height = value; } } } void Resize(Rectangle r) { r.Width = 5; r.Height = 4; Debug.Assert(r.Area == 20); } // fails for Square (16) // ✅ Model what they share, not a false \"is-a\" public interface IShape { int Area { get; } } public record Rect(int Width, int Height) : IShape { public int Area = Width Height; } public record Sq(int Side) : IShape { public int Area = Side Side; } LSP smells: throw new NotSupportedException() in an override, if (x is SpecialSubclass) checks in callers, overrides that do nothing."},{"kind":"lesson","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"i-interface-segregation-principle","title":"I — Interface Segregation Principle","body":"Clients should not be forced to depend on methods they don't use. Split fat interfaces into role interfaces. csharp // ❌ Fat interface — a basic printer must implement Fax and Scan public interface IMachine { void Print(Doc d); void Scan(Doc d); void Fax(Doc d); } public class BasicPrinter : IMachine { public void Print(Doc d) { } public void Scan(Doc d) = throw new NotSupportedException(); // also an LSP smell public void Fax(Doc d) = throw new NotSupportedException(); } // ✅ Role interfaces public interface IPrinter { void Print(Doc d); } public interface IScanner { void Scan(Doc d); } public interface IFax { void Fax(Doc d); } public class BasicPrinter2 : IPrinter { public void Print(Doc d) { } } public class OfficeMachine : IPrinter, IScanner, IFax { / all three / } Real-world .NET example: IReadOnlyList<T vs IList<T ; IEnumerable<T vs ICollection<T ."},{"kind":"lesson","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"d-dependency-inversion-principle","title":"D — Dependency Inversion Principle","body":"1. High-level modules should not depend on low-level modules; both depend on abstractions . 2. Abstractions should not depend on details; details depend on abstractions. csharp // ❌ High-level policy welded to a detail public class OrderService { private readonly SqlOrderRepository repo = new SqlOrderRepository(); // can't test, can't swap } // ✅ Depend on an abstraction owned by the high-level layer public interface IOrderRepository { Task AddAsync(Order o); } public class OrderService(IOrderRepository repo) { public Task PlaceAsync(Order o) = repo.AddAsync(o); } public class SqlOrderRepository(AppDbContext db) : IOrderRepository { public async Task AddAsync(Order o) { db.Orders.Add(o); await db.SaveChangesAsync(); } } // Composition root (Program.cs) builder.Services.AddScoped<IOrderRepository, SqlOrderRepository (); builder.Services.AddScoped<OrderService (); DIP vs DI vs IoC: - DIP — the principle (depend on abstractions). - IoC (Inversion of Control) — the general idea that a framework/container controls object creation and flow, not your code. - DI (Dependency Injection) — the technique : dependencies are passed in (constructor, method or property injection), usually by an IoC container."},{"kind":"lesson","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"dependency-injection-lifetimes-in-aspdotnet-core","title":"Dependency injection lifetimes in ASP.NET Core","body":"Lifetime One instance per Typical use --- --- --- AddTransient Every resolution Lightweight, stateless services AddScoped HTTP request (scope) DbContext , unit of work, per-request state AddSingleton Application Configuration, caches, HttpClient handlers, thread-safe services csharp builder.Services.AddSingleton<IClock, SystemClock (); builder.Services.AddScoped<IOrderRepository, SqlOrderRepository (); builder.Services.AddTransient<IEmailBuilder, EmailBuilder (); builder.Services.AddKeyedSingleton<IPaymentGateway, StripeGateway (\"stripe\"); // .NET 8 keyed services Captive dependency bug: a singleton that takes a scoped service (e.g. DbContext ) keeps that one instance forever, so it is shared across requests and threads. The default container throws in Development ( ValidateScopes ). Fix: inject IServiceScopeFactory and create a scope, or change the lifetimes."},{"kind":"lesson","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"dry-kiss-yagni-and-separation-of-concerns","title":"DRY, KISS, YAGNI and separation of concerns","body":"- DRY — Don't Repeat Yourself: every piece of knowledge has one authoritative place. (Duplicate-looking code that changes for different reasons is not a DRY violation.) - KISS — Keep It Simple: the simplest design that works is easiest to maintain. - YAGNI — You Aren't Gonna Need It: don't build for hypothetical future requirements. - Separation of Concerns: UI, business logic and data access in separate layers. - Composition over inheritance , Law of Demeter , Tell don't ask . Interview tip: show balance. \"I apply SOLID where change is likely — payment providers, export formats. For a 20-line admin script I keep it simple (KISS/YAGNI).\""},{"kind":"lesson","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"solid-in-a-layered-clean-architecture-solution","title":"SOLID in a layered / Clean Architecture solution","body":"src/ Shop.Domain/ entities, value objects, domain interfaces (no dependencies) Shop.Application/ use cases, IOrderRepository, IEmailSender (→ Domain) Shop.Infrastructure/ EF Core repos, SMTP sender, Azure Blob (→ Application) Shop.Api/ controllers, DI composition root (→ Application, Infrastructure) - DIP: Application defines IOrderRepository ; Infrastructure implements it. Dependencies point inwards . - SRP: one handler per use case ( PlaceOrderHandler ), e.g. with MediatR or plain classes. - OCP: cross-cutting concerns as decorators/pipeline behaviours (logging, validation, caching) without editing handlers. - ISP: small ports ( IClock , ICurrentUser , IFileStore ). - LSP: every IFileStore (local, Azure Blob, S3) behaves the same for callers."},{"kind":"question","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"212","title":"What are the SOLID principles? Explain each briefly.","body":"- S ingle Responsibility: one reason to change per class. - O pen/Closed: extend behaviour by adding code, not modifying existing code. - L iskov Substitution: subclasses must work anywhere the base class works. - I nterface Segregation: small client-specific interfaces instead of a fat one. - D ependency Inversion: high- and low-level modules depend on abstractions; inject dependencies. Follow with one concrete example from your own project, e.g. \"payment providers behind IPaymentGateway , registered in DI — that's OCP and DIP.\""},{"kind":"question","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"213","title":"Give a real example of the Single Responsibility Principle.","body":"An InvoiceService that calculates totals, writes to SQL and sends email has three reasons to change. Split it into InvoiceCalculator , IInvoiceRepository and IInvoiceSender , with a small workflow class orchestrating them. Now an SMTP-to-SendGrid change touches only the sender, and each part has focused unit tests."},{"kind":"question","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"214","title":"How do you implement the Open/Closed Principle in C#?","body":"Through abstractions and polymorphism : define an interface ( IDiscountRule , IExportFormatter ), implement each variant as its own class, and let the consumer receive IEnumerable<IDiscountRule from DI. Adding a variant means a new class and registration; no existing, tested code changes. Other OCP tools: Strategy, Decorator, middleware, filters, events."},{"kind":"question","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"215","title":"Explain the Liskov Substitution Principle with the Rectangle–Square example.","body":"Mathematically a square is a rectangle, but if Square overrides Width / Height setters to keep sides equal, code written for Rectangle (set width 5, height 4, expect area 20) breaks and gets 16. The subtype changed the base's behaviour, which violates LSP. Fix: don't inherit; make both implement IShape with an Area , or make them immutable. Practical LSP violations: overrides throwing NotSupportedException , or a read-only collection deriving from a writable one."},{"kind":"question","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"216","title":"What is the difference between Dependency Inversion, Dependency Injection and Inversion of Control?","body":"DIP is the design principle : depend on abstractions. IoC is the broader concept that control of object creation and flow is handed to a framework or container. DI is a technique to achieve IoC/DIP: dependencies are supplied from outside (constructor injection preferred) rather than created with new inside the class. ASP.NET Core's built-in container is an IoC container that performs DI."},{"kind":"question","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"217","title":"What are the service lifetimes in ASP.NET Core DI and what is a captive dependency?","body":"Transient (new each time), Scoped (one per request/scope), Singleton (one for the app). A captive dependency happens when a longer-lived service holds a shorter-lived one — e.g. a singleton injecting a scoped DbContext . The DbContext then lives forever and is shared across threads, which causes concurrency exceptions and stale data. Fix: make the consumer scoped, or inject IServiceScopeFactory and create a scope per operation (common in BackgroundService )."},{"kind":"question","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"218","title":"Give an Interface Segregation example from .NET itself.","body":"IEnumerable<T (iterate only) → IReadOnlyCollection<T (+Count) → IReadOnlyList<T (+indexer) vs ICollection<T / IList<T (mutation). A method that only reads should accept IEnumerable<T / IReadOnlyList<T . Similarly, ASP.NET Core splits IConfiguration and IOptions<T , and logging into ILogger and ILoggerFactory ."},{"kind":"question","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"219","title":"Is it OK to violate SOLID sometimes?","body":"Yes. SOLID is a set of guidelines, not laws. Over-applying them creates \"interface for everything\" designs, needless indirection and many tiny files. Apply them where change is likely or testing needs seams (external services, business rules that vary). For stable, simple code, KISS and YAGNI win. Good answer: \"I refactor towards SOLID when a second variant or a test need appears.\""},{"kind":"question","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"220","title":"Which design patterns support which SOLID principles?","body":"Strategy, Decorator, Template Method, Observer → OCP . Adapter, Facade → DIP/ISP (wrap details behind your own abstraction). Factory/Abstract Factory → DIP (hide creation). Repository → DIP/SRP . Chain of Responsibility/middleware → SRP + OCP . Composite → LSP (leaf and composite are interchangeable)."},{"kind":"question","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"221","title":"How does Clean Architecture apply the Dependency Inversion Principle?","body":"The Domain and Application layers define interfaces (ports) such as IOrderRepository or IEmailSender . The Infrastructure layer implements them with EF Core, SMTP or Azure. The API project (composition root) wires them together. Source-code dependencies point inward, so business rules don't reference EF Core or ASP.NET. You can test them with in-memory fakes and swap infrastructure without touching them."},{"kind":"question","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"222","title":"What is the Stable Dependencies / Stable Abstractions principle?","body":"They are package-level principles from Robert C. Martin. Stable Dependencies: depend in the direction of stability (packages that many others rely on should change rarely). Stable Abstractions: stable packages should be abstract (interfaces), so they can be extended without modification. Together they explain why the domain/interfaces project sits at the centre and has no dependencies."},{"kind":"question","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"223","title":"Your `NotificationService` sends email via SMTP using `new SmtpClient()` inside the method. The business now wants SMS and WhatsApp too, and tests keep sending real emails. What do you change?","body":"1. Introduce INotificationChannel { Task SendAsync(Notification n); } (DIP). 2. Implement EmailChannel (SMTP or SendGrid), SmsChannel and WhatsAppChannel (OCP: one class per channel). 3. Inject IEnumerable<INotificationChannel into NotificationService and select by the user's preference. 4. Move settings to IOptions<SmtpSettings . 5. In unit tests, use a fake channel, so no real emails are sent. 6. Optional: a decorator for retry/logging (OCP), and a queue so sending doesn't block the request."},{"kind":"question","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"224","title":"A code review shows `if (shape is Circle) ... else if (shape is Square) ...` in five places. What principle is violated and how do you fix it?","body":"It violates OCP (every new shape edits five places) and usually LSP/polymorphism . Move the behaviour into the types: abstract double Area() (or an interface method) implemented by each shape, and callers just call shape.Area() . If the operation shouldn't live in the shape (e.g. rendering), use the Visitor pattern, or a dictionary of strategies keyed by type."},{"kind":"question","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"225","title":"A background service crashes with \"Cannot consume scoped service from singleton\". Explain and fix.","body":"AddHostedService registers hosted services as singletons. Injecting a scoped service (like DbContext ) into the constructor is a captive dependency, so the container refuses it. Inject IServiceScopeFactory instead; inside ExecuteAsync , for each unit of work, do using var scope = factory.CreateScope(); var db = scope.ServiceProvider.GetRequiredService<AppDbContext (); . Each iteration then gets a fresh, correctly disposed context."},{"kind":"question","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"226","title":"How would you explain where you applied SOLID in your last project?","body":"Give a concrete STAR-style example. \"Our reporting module had exports to PDF and Excel inside one 2,000-line class. I introduced IReportExporter with one class per format and registered them in DI. The controller picks one by format key (OCP, SRP). Data access moved behind IReportRepository (DIP), which let us unit-test the exporters with fake data. Adding CSV later took half a day and touched no existing code.\""},{"kind":"cheat","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"1","title":"SOLID in one table","body":"Principle Smell Fix --- --- --- --- S Single Responsibility God class, Manager / Utils Split by reason to change O Open/Closed Growing switch / if-else on type Strategy/polymorphism + DI L Liskov Substitution Override throws NotSupportedException ; is checks Fix the hierarchy; use interfaces/composition I Interface Segregation Implementers leave methods empty Split into role interfaces D Dependency Inversion new ConcreteService() inside logic Inject an abstraction"},{"kind":"cheat","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"2","title":"DI lifetimes","body":"Instance per Use for --- --- --- Transient resolution stateless, light Scoped request DbContext , unit of work Singleton app config, caches, thread-safe services Never inject scoped into singleton → use IServiceScopeFactory ."},{"kind":"cheat","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"3","title":"Other principles","body":"- DRY — one source of truth for knowledge. - KISS — simplest thing that works. - YAGNI — don't build for imaginary futures. - SoC — separate UI / business / data. - Composition over inheritance. - Law of Demeter — no a.B.C.D chains."},{"kind":"cheat","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"4","title":"Quick code: DIP + OCP","body":"csharp public interface IExporter { string Format { get; } byte[] Export(Report r); } public class PdfExporter : IExporter { public string Format = \"pdf\"; public byte[] Export(Report r) = ...; } public class ExcelExporter : IExporter { public string Format = \"xlsx\"; public byte[] Export(Report r) = ...; } public class ExportService(IEnumerable<IExporter exporters) { public byte[] Run(Report r, string fmt) = exporters.Single(e = e.Format == fmt).Export(r); }"},{"kind":"cheat","course_slug":"solid","course_title":"SOLID Principles with Examples","ref":"5","title":"One-liners to say in the interview","body":"- SRP : \"A class should have one reason to change — one actor it serves.\" - OCP : \"Add new behaviour by adding classes, not by editing tested ones.\" - LSP : \"A subclass must work anywhere its base class is expected — no surprises.\" - ISP : \"Don't force clients to depend on methods they don't use.\" - DIP : \"High-level policy depends on abstractions; details plug in through DI.\" - Balance : \"I apply SOLID where change is likely; for simple, stable code I keep it simple.\""},{"kind":"course","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"","title":"Design Patterns (GoF + Enterprise) in C#","body":"Creational, structural and behavioural Gang-of-Four patterns with C code, plus Repository, Unit of Work, CQRS, Mediator, Options and microservice patterns. A design pattern is a proven, reusable solution to a common design problem: a template, not finished code. The classic catalogue is Design Patterns: Elements of Reusable Object-Oriented Software (1994) by the Gang of Four (Gamma, Helm, Johnson, Vlissides), with 23 patterns in three groups: Group Purpose Patterns --- --- --- Creational (5) How objects are created Singleton, Factory Method, Abstract Factory, Builder, Prototype Structural (7) How objects are composed Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy Behavioural (11) How objects interact Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor Enterprise and cloud patterns used daily in .NET: Repository, Unit of Work, Dependency Injection, CQRS, Mediator (MediatR), Options, Specification, Outbox, Circuit Breaker, Retry, Saga, API Gateway. Year Milestone --- --- 1977 Christopher Alexander, A Pattern Language (architecture) inspires software patterns 1994 GoF book: 23 patterns 1996 Pattern-Oriented Software Architecture (POSA) 2002 Martin Fowler, Patterns of Enterprise Application Architecture — Repository, Unit of Work, Data Mapper, Active Record 2003 Eric Evans, Domain-Driven Design — Aggregates, Value Objects, Domain Events 2003 Hohpe & Woolf, Enterprise Integration Patterns — messaging 2010s Cloud design patterns (Microsoft Azure Architecture Center): Circuit Breaker, Retry, CQRS, Event Sourcing, Saga, Strangler Fig How to use a pattern well: 1. Notice the problem (e.g. a growing switch on type, an awkward third-party API, object creation spread everywhere). 2. Name the pattern that fits (Strategy, Adapter, Factory). 3. Apply it minimally — the simplest version that solves today's problem. 4. Test behaviour through the abstraction. 5. Revisit — remove a pattern that adds indirection with no benefit. Patterns are a vocabulary. Saying \"I wrapped the SDK in an Adapter and added a caching Decorator\" communicates a whole design in one sentence. - refactoring.guru — free illustrated catalogue (with C examples). - dofactory.com — .NET-specific pattern examples. - MediatR — Mediator/CQRS pipeline library (commercial licence from v13). - Polly / Microsoft.Extensions.Http.Resilience — Retry, Circuit Breaker, Timeout, Bulkhead. - Scrutor — Decorator registration in ASP.NET Core DI. - Azure Architecture Center — Cloud design patterns catalogue."},{"kind":"lesson","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"singleton","title":"Singleton","body":"Ensure a class has one instance with a global access point. csharp // Thread-safe, lazy Singleton public sealed class AppConfig { private static readonly Lazy<AppConfig instance = new(() = new AppConfig()); public static AppConfig Instance = instance.Value; private AppConfig() { / load settings once / } public string ConnectionString { get; private set; } = \"\"; } // Modern .NET: let the DI container own the lifetime instead builder.Services.AddSingleton<IAppConfig, AppConfig (); Other thread-safe options: a static readonly field (initialised by the CLR's type initialiser, thread-safe), or double-checked locking. Downsides of the hand-written pattern: global state, hidden dependencies, hard to test. Prefer AddSingleton ."},{"kind":"lesson","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"factory-method-and-simple-factory","title":"Factory Method and Simple Factory","body":"Let a method decide which concrete class to create; callers depend only on the abstraction. csharp public interface INotification { void Send(string to, string msg); } public class EmailNotification : INotification { public void Send(string to, string msg) { } } public class SmsNotification : INotification { public void Send(string to, string msg) { } } // Simple factory public static class NotificationFactory { public static INotification Create(string channel) = channel switch { \"email\" = new EmailNotification(), \"sms\" = new SmsNotification(), = throw new ArgumentException($\"Unknown channel {channel}\") }; } // GoF Factory Method: subclasses decide what to create public abstract class DocumentExporter { protected abstract IWriter CreateWriter(); // factory method public void Export(Doc d) { var w = CreateWriter(); w.Write(d); } } public class PdfExporter : DocumentExporter { protected override IWriter CreateWriter() = new PdfWriter(); } In .NET: IHttpClientFactory.CreateClient() , ILoggerFactory.CreateLogger() , DbProviderFactory ."},{"kind":"lesson","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"abstract-factory","title":"Abstract Factory","body":"Create families of related objects without naming concrete classes. csharp public interface IUiFactory { IButton CreateButton(); ITextBox CreateTextBox(); } public class LightThemeFactory : IUiFactory { public IButton CreateButton() = new LightButton(); public ITextBox CreateTextBox() = new LightTextBox(); } public class DarkThemeFactory : IUiFactory { public IButton CreateButton() = new DarkButton(); public ITextBox CreateTextBox() = new DarkTextBox(); } // e.g. ADO.NET: DbProviderFactory creates matching DbConnection, DbCommand, DbParameter for SQL Server / Oracle / SQLite DbProviderFactory f = SqlClientFactory.Instance; using DbConnection conn = f.CreateConnection()!; using DbCommand cmd = f.CreateCommand()!; Factory Method = one product via inheritance; Abstract Factory = a family of products via composition."},{"kind":"lesson","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"builder","title":"Builder","body":"Construct a complex object step by step , separating construction from representation. Fluent builders are everywhere in .NET. csharp public class EmailBuilder { private readonly MailMessage m = new(); public EmailBuilder From(string a) { m.From = new MailAddress(a); return this; } public EmailBuilder To(string a) { m.To.Add(a); return this; } public EmailBuilder Subject(string s) { m.Subject = s; return this; } public EmailBuilder Html(string body) { m.Body = body; m.IsBodyHtml = true; return this; } public MailMessage Build() = m.To.Count == 0 ? throw new InvalidOperationException(\"No recipient\") : m; } var mail = new EmailBuilder().From(\"hr@corp.test\").To(\"divakar@corp.test\").Subject(\"Offer\").Html(\"<b Welcome</b \").Build(); // .NET examples: WebApplication.CreateBuilder(), StringBuilder, UriBuilder, SqlConnectionStringBuilder, EF Core ModelBuilder"},{"kind":"lesson","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"prototype","title":"Prototype","body":"Create new objects by cloning an existing one. csharp public record ReportTemplate(string Title, string Font, IReadOnlyList<string Columns); var monthly = new ReportTemplate(\"Monthly\", \"Segoe UI\", [\"Date\", \"Sales\"]); var weekly = monthly with { Title = \"Weekly\" }; // records give shallow cloning via 'with' Watch out for shallow vs deep copy : MemberwiseClone() and with copy references to nested objects."},{"kind":"lesson","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"adapter","title":"Adapter","body":"Convert one interface into another that clients expect — wrap a legacy or third-party API. csharp public interface ISmsSender { Task SendAsync(string phone, string text); } // our interface public class TwilioSmsAdapter(TwilioRestClient client, string from) : ISmsSender // adapts the SDK { public Task SendAsync(string phone, string text) = MessageResource.CreateAsync(to: new PhoneNumber(phone), from: new PhoneNumber(from), body: text, client: client); } Benefits: the vendor SDK is isolated in one class, so switching providers or mocking in tests is easy."},{"kind":"lesson","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"decorator","title":"Decorator","body":"Add behaviour to an object dynamically by wrapping it , without changing its class. Wrappers implement the same interface. csharp public interface IProductRepository { Task<Product? GetAsync(int id); } public class SqlProductRepository(AppDbContext db) : IProductRepository { public Task<Product? GetAsync(int id) = db.Products.FindAsync(id).AsTask(); } public class CachedProductRepository(IProductRepository inner, IMemoryCache cache) : IProductRepository { public Task<Product? GetAsync(int id) = cache.GetOrCreateAsync($\"product:{id}\", e = { e.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5); return inner.GetAsync(id); }); } // With Scrutor: builder.Services.AddScoped<IProductRepository, SqlProductRepository (); builder.Services.Decorate<IProductRepository, CachedProductRepository (); .NET examples: Stream wrappers ( BufferedStream , GZipStream , CryptoStream ), DelegatingHandler in HttpClient ."},{"kind":"lesson","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"facade-proxy-and-composite","title":"Facade, Proxy and Composite","body":"Facade — one simple interface over a complex subsystem. csharp public class CheckoutFacade(IInventory inv, IPayment pay, IShipping ship, IEmail email) { public async Task<OrderResult PlaceOrder(Cart cart) { await inv.ReserveAsync(cart); var receipt = await pay.ChargeAsync(cart.Total); var tracking = await ship.BookAsync(cart); await email.SendConfirmationAsync(cart.CustomerEmail, tracking); return new OrderResult(receipt, tracking); } } Proxy — a stand-in that controls access: lazy loading (EF Core lazy-loading proxies), remote proxies (gRPC/WCF clients), protection proxies (authorisation checks), caching proxies. Composite — treat individual objects and groups the same way (tree structures). csharp public interface IMenuItem { decimal Price(); } public record Dish(string Name, decimal Cost) : IMenuItem { public decimal Price() = Cost; } public class Combo(params IMenuItem[] items) : IMenuItem { public decimal Price() = items.Sum(i = i.Price()) 0.9m; }"},{"kind":"lesson","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"bridge-and-flyweight","title":"Bridge and Flyweight","body":"Bridge — separate an abstraction from its implementation so both can vary independently (e.g. Notification × Channel : Urgent/Normal notifications over Email/SMS without 4 subclasses). Flyweight — share common immutable state across many objects to save memory (e.g. string interning, glyph objects in a text editor, ArrayPool<T is a related idea)."},{"kind":"lesson","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"strategy","title":"Strategy","body":"Define a family of algorithms, encapsulate each one, and make them interchangeable at runtime . csharp public interface IShippingCost { string Mode { get; } decimal Calculate(decimal weightKg); } public class Standard : IShippingCost { public string Mode = \"standard\"; public decimal Calculate(decimal w) = 50 + w 10; } public class Express : IShippingCost { public string Mode = \"express\"; public decimal Calculate(decimal w) = 120 + w 25; } public class ShippingService(IEnumerable<IShippingCost strategies) { public decimal Quote(string mode, decimal kg) = strategies.Single(s = s.Mode == mode).Calculate(kg); } The most common answer to \"how do you remove a big switch statement?\". Also: IComparer<T passed to Sort is a strategy."},{"kind":"lesson","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"observer-and-events","title":"Observer and events","body":"Subjects notify subscribed observers when state changes. In C : events/delegates , IObservable<T / IObserver<T , Rx, and at system level message brokers (pub/sub). csharp public class StockTicker { public event EventHandler<PriceChanged ? PriceChanged; public void Update(string sym, decimal price) = PriceChanged?.Invoke(this, new PriceChanged(sym, price)); } var ticker = new StockTicker(); ticker.PriceChanged += ( , e) = Console.WriteLine($\"{e.Symbol}: {e.Price}\"); Remember to unsubscribe ( -= ) — a long-lived publisher holding handlers of short-lived subscribers is a classic memory leak."},{"kind":"lesson","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"chain-of-responsibility-and-aspdotnet-core-middleware","title":"Chain of Responsibility (and ASP.NET Core middleware)","body":"Pass a request along a chain of handlers; each handles it or passes it on. csharp app.Use(async (context, next) = { var sw = Stopwatch.StartNew(); await next(context); // pass to the next handler context.Response.Headers[\"X-Elapsed-Ms\"] = sw.ElapsedMilliseconds.ToString(); }); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); Other examples: HttpClient DelegatingHandler pipeline, MediatR pipeline behaviours, approval workflows (Team Lead → Manager → Director by amount)."},{"kind":"lesson","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"command-template-method-state-and-mediator","title":"Command, Template Method, State and Mediator","body":"Command — wrap a request as an object (queue it, log it, undo it). CQRS commands ( PlaceOrderCommand ) and background job payloads are commands. Template Method — the base class defines the algorithm's skeleton; subclasses fill in steps. csharp public abstract class DataImporter { public void Run() { var raw = Extract(); var clean = Transform(raw); Load(clean); } // fixed skeleton protected abstract string[] Extract(); protected virtual string[] Transform(string[] rows) = rows.Where(r = r.Length 0).ToArray(); protected abstract void Load(string[] rows); } State — an object changes behaviour when its internal state changes (Order: Pending → Paid → Shipped → Delivered, each state class allowing only valid transitions). Mediator — objects talk through a mediator instead of directly, which reduces coupling. MediatR: controllers send IRequest s, handlers process them. csharp public record GetOrder(int Id) : IRequest<OrderDto? ; public class GetOrderHandler(AppDbContext db) : IRequestHandler<GetOrder, OrderDto? { public Task<OrderDto? Handle(GetOrder q, CancellationToken ct) = db.Orders.Where(o = o.Id == q.Id).Select(o = new OrderDto(o.Id, o.Total)).FirstOrDefaultAsync(ct); } // controller: return await mediator.Send(new GetOrder(id));"},{"kind":"lesson","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"iterator-visitor-memento-and-interpreter","title":"Iterator, Visitor, Memento and Interpreter","body":"- Iterator — sequential access without exposing internals: IEnumerable<T + yield return . - Visitor — add operations to a class hierarchy without changing it (double dispatch); Roslyn syntax walkers and LINQ ExpressionVisitor use it. - Memento — capture and restore state (undo). Records + with make snapshots easy. - Interpreter — evaluate a small grammar (rule engines, expression trees)."},{"kind":"lesson","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"repository-and-unit-of-work","title":"Repository and Unit of Work","body":"Repository — a collection-like abstraction over data access. Unit of Work — tracks changes and commits them in one transaction . csharp public interface IOrderRepository { Task<Order? GetAsync(int id, CancellationToken ct = default); void Add(Order order); } public interface IUnitOfWork { Task<int SaveChangesAsync(CancellationToken ct = default); } public class OrderRepository(AppDbContext db) : IOrderRepository { public Task<Order? GetAsync(int id, CancellationToken ct) = db.Orders.Include(o = o.Lines).FirstOrDefaultAsync(o = o.Id == id, ct); public void Add(Order order) = db.Orders.Add(order); } Note: EF Core's DbSet<T already is a repository and DbContext a unit of work. Many teams use DbContext directly. Others add repositories per aggregate to keep EF out of the domain and simplify testing. A generic repository over EF often adds little value — be ready to discuss this trade-off."},{"kind":"lesson","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"cqrs-outbox-and-saga","title":"CQRS, Outbox and Saga","body":"CQRS — separate the write model (commands that change state, with validation and business rules) from the read model (queries optimised for display, e.g. Dapper or views). It can share one database or use separate read stores. Transactional Outbox — to reliably publish an event when data changes, save the event in an Outbox table in the same DB transaction as the business data; a background worker publishes it to the broker and marks it sent. This avoids \"saved but message lost\" or \"message sent but save rolled back\". Saga — manage a business transaction spanning several services (each with its own DB) as a sequence of local transactions with compensating actions on failure (orchestration via a coordinator, or choreography via events)."},{"kind":"lesson","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"resilience-patterns-retry-circuit-breaker-timeout-bulkhead","title":"Resilience patterns: Retry, Circuit Breaker, Timeout, Bulkhead","body":"csharp // .NET 8+: Microsoft.Extensions.Http.Resilience (built on Polly v8) builder.Services.AddHttpClient<IPaymentClient, PaymentClient (c = c.BaseAddress = new Uri(\"https://pay.example\")) .AddStandardResilienceHandler(); // rate limiter, total timeout, retry (exponential + jitter), circuit breaker, attempt timeout - Retry — transient failures; use exponential backoff + jitter; only for idempotent operations. - Circuit Breaker — after N failures, stop calling for a period (open), then test (half-open), then close. - Timeout — never wait forever. - Bulkhead — isolate resources so one slow dependency can't exhaust all threads/connections. - Fallback — default/cached response when everything fails."},{"kind":"lesson","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"options-pattern-and-other-dotnet-specific-patterns","title":"Options pattern and other .NET-specific patterns","body":"csharp public class SmtpSettings { public string Host { get; set; } = \"\"; public int Port { get; set; } } builder.Services.Configure<SmtpSettings (builder.Configuration.GetSection(\"Smtp\")); builder.Services.AddOptions<SmtpSettings ().BindConfiguration(\"Smtp\").ValidateDataAnnotations().ValidateOnStart(); public class Mailer(IOptions<SmtpSettings opt) { private readonly SmtpSettings s = opt.Value; } IOptions<T (singleton, read once), IOptionsSnapshot<T (scoped, re-read per request), IOptionsMonitor<T (singleton with change notifications). Also: Specification pattern (encapsulate query criteria), Result pattern (return success/failure objects instead of throwing for expected errors), Null Object , Lazy loading ."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"227","title":"What are design patterns? Name the three GoF categories.","body":"Reusable, named solutions to recurring design problems. GoF (1994) lists 23 in three categories: Creational (Singleton, Factory Method, Abstract Factory, Builder, Prototype), Structural (Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy), Behavioural (Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor)."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"228","title":"How do you implement a thread-safe Singleton in C#?","body":"Use Lazy<T : private static readonly Lazy<Svc i = new(() = new Svc()); public static Svc Instance = i.Value; with a private constructor and a sealed class. Lazy<T is thread-safe by default ( ExecutionAndPublication ). Alternatives: a static readonly field (thread-safe because of the type initialiser), or double-checked locking with volatile . In ASP.NET Core, prefer services.AddSingleton<ISvc, Svc () . It's testable and the container manages the lifetime."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"229","title":"What is the difference between Factory Method and Abstract Factory?","body":"Factory Method creates one product , and subclasses (or a method) decide which concrete class to create. Abstract Factory creates a family of related products through an interface with several create methods (button + textbox for a theme; connection + command + parameter for a DB provider). Factory Method uses inheritance; Abstract Factory uses composition (you pass the factory object)."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"230","title":"What is the Strategy pattern? Where have you used it?","body":"It encapsulates interchangeable algorithms behind an interface and selects one at runtime. Examples: discount rules, shipping cost calculators, payment gateways, export formats, tax rules by country. With DI, register every strategy and inject IEnumerable<IStrategy , or use keyed services (.NET 8). It removes switch statements and satisfies OCP."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"231","title":"What is the difference between Decorator and Adapter?","body":"A Decorator keeps the same interface and adds behaviour (caching, logging, retry) by wrapping an object. You can stack several. An Adapter changes the interface so an incompatible class fits what the client expects (wrapping a vendor SDK behind ISmsSender ). In short, Decorator = same interface + extra behaviour; Adapter = different interface, same behaviour."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"232","title":"Explain the Repository and Unit of Work patterns. Do you need them with EF Core?","body":"A Repository hides data access behind a collection-like interface; Unit of Work groups changes into one transaction. EF Core already implements both ( DbSet<T , DbContext.SaveChanges ). Adding them on top is optional. Pros: domain code doesn't reference EF, queries are centralised, testing is easier. Cons: extra layers, and generic repositories often leak IQueryable or limit EF features. A balanced answer: aggregate-specific repositories in DDD/Clean Architecture; direct DbContext usage in simpler apps, with integration tests using SQLite/Testcontainers."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"233","title":"How is ASP.NET Core middleware an example of Chain of Responsibility?","body":"Each middleware receives the HttpContext and a next delegate. It can act before and after calling next , or short-circuit (e.g. return 401 without calling the rest). The order of app.Use... calls defines the chain: exception handler → HTTPS redirection → static files → routing → CORS → authentication → authorization → endpoints."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"234","title":"What is the Observer pattern and how does C# support it?","body":"Observers subscribe to a subject and get notified of changes. C supports it with events and delegates ( event EventHandler<T ), IObservable<T / IObserver<T (with Rx.NET), INotifyPropertyChanged in UI binding, and at architecture level pub/sub messaging (Azure Service Bus topics, Kafka). Pitfall: forgetting to unsubscribe causes memory leaks."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"235","title":"What is the Facade pattern? Give a real example.","body":"A Facade provides a simple API over a complicated subsystem. Example: a CheckoutService.PlaceOrder() that coordinates inventory, payment, shipping and email so the controller makes one call. In .NET, File.ReadAllText is a facade over FileStream + StreamReader + encoding detection."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"236","title":"What is the Builder pattern? Show .NET examples.","body":"Builder constructs complex objects step by step, often fluently, and validates at Build() . .NET examples: WebApplication.CreateBuilder(args) → builder.Build() , StringBuilder , UriBuilder , SqlConnectionStringBuilder , HostBuilder , EF Core's ModelBuilder fluent API, and test-data builders in unit tests."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"237","title":"What is the Mediator pattern and what does MediatR do?","body":"Mediator centralises communication so components don't reference each other directly. MediatR implements an in-process mediator: controllers Send a request object, and exactly one handler processes it. Notifications can go to many handlers. Pipeline behaviours add cross-cutting concerns (validation, logging, transactions). Note: MediatR moved to a commercial licence from version 13 (2025). Some teams write a small mediator themselves or call handlers directly."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"238","title":"Template Method vs Strategy?","body":"Both vary part of an algorithm. Template Method uses inheritance : the base class fixes the skeleton and subclasses override steps, decided at compile time. Strategy uses composition : the whole algorithm is an injected object, swappable at runtime. Prefer Strategy for flexibility; Template Method suits frameworks with a fixed workflow (e.g. ETL importers, BackgroundService.ExecuteAsync )."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"239","title":"Explain CQRS. When is it worth it?","body":"Command Query Responsibility Segregation splits writes (commands, rich domain model, validation) from reads (queries, flat DTOs, maybe Dapper/views/a separate read DB). It's worth it when read and write workloads or shapes differ a lot, for complex domains, or for high read scale. It can be as light as separate command and query handler classes on one DB. It adds complexity, and with separate stores you get eventual consistency . Don't use it for simple CRUD."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"240","title":"What is the Outbox pattern and why is it needed?","body":"It's for publishing an integration event reliably when a DB change commits. Writing to the DB and then publishing to a broker is not atomic (dual-write problem). With Outbox, the event row is inserted into an OutboxMessages table in the same transaction as the business change. A background processor reads unsent rows, publishes them, and marks them sent. Delivery is at-least-once , so consumers must be idempotent (Inbox table or dedupe key). Libraries: MassTransit, NServiceBus, Wolverine, CAP."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"241","title":"How do Retry and Circuit Breaker work together?","body":"Retry handles brief transient faults (timeouts, 503, 429) with exponential backoff and jitter. The Circuit Breaker wraps retries: if failures exceed a threshold, it opens and fails fast for a break period, protecting the struggling dependency and your own threads. Then it goes half-open to probe, and closes on success. In .NET 8+, AddStandardResilienceHandler() configures them with timeouts and rate limiting. Retry only idempotent operations, or use idempotency keys."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"242","title":"What is the Saga pattern?","body":"It coordinates a distributed transaction across microservices without 2PC: a sequence of local transactions, each publishing an event or command. If a step fails, compensating transactions undo earlier steps (refund the payment, release the stock). Orchestration : a central saga orchestrator (state machine) tells services what to do. Choreography : services react to each other's events. Orchestration is easier to follow; choreography is more decoupled."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"243","title":"What is the Specification pattern?","body":"It encapsulates a business rule or query criterion in an object ( IsActiveCustomerSpec , OrdersAboveAmountSpec(1000) ). You can combine them (And/Or/Not) and reuse them for in-memory checks and EF Core queries (as Expression<Func<T,bool ). It keeps query logic out of controllers and avoids duplicated Where clauses. Ardalis.Specification is a popular library."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"244","title":"The product details page calls the DB for every request and is slow. You can't change the repository class. Which pattern helps?","body":"A Decorator : CachedProductRepository : IProductRepository wraps the existing repository, checks IMemoryCache / IDistributedCache (Redis) first, and falls back to the inner repository on a miss. Register it with Scrutor's Decorate<, or manual factory registration. No existing code changes (OCP). Add expiration, and invalidate on product updates (remove the cache key in the update path, or publish an event)."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"245","title":"Your app must support three SMS vendors and switch between them by configuration or when one is down. Design it.","body":"Define ISmsSender . Write an Adapter per vendor SDK ( TwilioSender , GupshupSender , MsgKitSender ), registered as keyed services or IEnumerable<ISmsSender . Choose the active one from IOptionsMonitor<SmsOptions (Strategy) so config changes apply without a restart. Add a failover decorator that tries the primary and, on failure or an open circuit (Polly Circuit Breaker), uses the secondary. Log the vendor used, and make sends idempotent with a message ID."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"246","title":"An expense approval needs Team Lead below ₹10,000, Manager up to ₹1,00,000, and Director above. Which pattern?","body":"Chain of Responsibility : IApprover with SetNext(IApprover) and Handle(Expense) . Each approver handles it if the amount is within its limit, otherwise it passes it on. Build the chain from configuration so limits and new levels don't need code changes. A State pattern can track the expense's lifecycle (Submitted → Approved/Rejected → Paid)."},{"kind":"question","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"247","title":"When an order is placed you must save it, publish `OrderPlaced` to Service Bus, and never lose the message even if the broker is down. How?","body":"Use the Transactional Outbox : in the same SaveChanges transaction, insert the order and an outbox row with the serialized event. A BackgroundService polls unsent outbox rows, publishes them to Service Bus, and marks them sent, retrying while the broker is down. Consumers dedupe by message ID (idempotent consumer / Inbox). MassTransit's EF Core outbox does this out of the box."},{"kind":"cheat","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"1","title":"23 GoF patterns — one line each","body":"Pattern One line --- --- Singleton One instance ( Lazy<T / AddSingleton ) Factory Method Subclass/method decides concrete type Abstract Factory Family of related objects Builder Step-by-step construction, fluent Prototype Clone existing object Adapter Convert interface (wrap SDK) Bridge Split abstraction from implementation Composite Tree; leaf and group treated alike Decorator Wrap to add behaviour, same interface Facade Simple API over subsystem Flyweight Share immutable state Proxy Stand-in controlling access (lazy, remote, auth) Chain of Responsibility Pass along handlers (middleware) Command Request as object (queue, undo) Interpreter Evaluate a grammar Iterator Sequential access ( IEnumerable ) Mediator Central communication (MediatR) Memento Snapshot/restore state Observer Subscribe/notify (events) State Behaviour depends on state object Strategy Interchangeable algorithms Template Method Base skeleton, subclass steps Visitor New operations without changing classes"},{"kind":"cheat","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"2","title":"Patterns hiding in .NET","body":".NET feature Pattern --- --- Middleware, DelegatingHandler Chain of Responsibility IHttpClientFactory , ILoggerFactory Factory WebApplication.CreateBuilder Builder Stream wrappers Decorator event / IObservable Observer IEnumerable + yield Iterator DbContext / DbSet Unit of Work / Repository EF lazy-loading proxies Proxy IComparer<T Strategy ExpressionVisitor Visitor"},{"kind":"cheat","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"3","title":"Enterprise/cloud","body":"- Repository + UoW — data access abstraction + one transaction. - CQRS — separate reads and writes. - Outbox — event + data in the same transaction. - Saga — distributed transaction with compensation. - Retry / Circuit Breaker / Timeout / Bulkhead — resilience ( AddStandardResilienceHandler ). - Options — typed config: IOptions / IOptionsSnapshot / IOptionsMonitor . - Strangler Fig — replace a legacy system piece by piece. - API Gateway / BFF — single entry point per client type."},{"kind":"cheat","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"4","title":"Answer formula","body":"Problem → pattern name → how it works (2 lines) → code shape (interface + classes) → where you used it → trade-off."},{"kind":"cheat","course_slug":"design-patterns","course_title":"Design Patterns (GoF + Enterprise) in C#","ref":"5","title":"Which pattern for which problem?","body":"Problem in the interview question Pattern --- --- Big switch on type / many interchangeable algorithms Strategy Add caching/logging/retry without touching a class Decorator Wrap a third-party SDK behind your own interface Adapter One simple call over many subsystems Facade Object creation varies by input/config Factory Method / Abstract Factory Complex object with many optional parts Builder Exactly one shared instance Singleton (prefer AddSingleton ) Notify many listeners of changes Observer / events Request passes through a series of handlers Chain of Responsibility Behaviour depends on the object's state State Fixed algorithm with customisable steps Template Method Decouple senders and handlers (CQRS) Mediator / Command Reliable event publishing with DB writes Outbox Flaky downstream service Retry + Circuit Breaker"},{"kind":"course","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"","title":"ADO.NET — Connected & Disconnected Data Access","body":"Connected vs disconnected architecture, SqlConnection, SqlCommand, DataReader, DataSet/DataAdapter, parameters, stored procedures, transactions, connection pooling, bulk copy, async and Dapper micro-ORM. ADO.NET is the low-level data access API in .NET ( System.Data ). Every ORM — Entity Framework, Dapper — is built on it. Interviews ask about it because it shows you understand what happens between your code and the database. Two architectures: - Connected — DbConnection + DbCommand + DbDataReader : open a connection, stream rows forward-only, close. Fast, low memory. - Disconnected — DataAdapter fills an in-memory DataSet / DataTable ; the connection is closed while you work; changes are pushed back with Update() . Providers: Microsoft.Data.SqlClient (SQL Server — the current, recommended package; System.Data.SqlClient is deprecated), Npgsql (PostgreSQL), MySqlConnector , Oracle.ManagedDataAccess.Core , Microsoft.Data.Sqlite . Dapper (Stack Overflow, 2011) is a micro-ORM: extension methods on IDbConnection that map query results to objects, keeping SQL fully in your control with near-ADO.NET speed. Year Milestone --- --- 2002 ADO.NET 1.0 with .NET Framework 1.0 (successor of COM-based ADO) 2005 ADO.NET 2.0: provider factories ( DbProviderFactory ), SqlBulkCopy , MARS, async-ish APIs 2008 .NET 3.5: LINQ to SQL, LINQ to DataSet; EF 1.0 (SP1) 2012 .NET 4.5: real async ( OpenAsync , ExecuteReaderAsync ) 2011 Dapper released by Stack Overflow 2019 Microsoft.Data.SqlClient 1.0 — new SQL Server driver shipped via NuGet 2022–2025 Microsoft.Data.SqlClient 5.x/6.x: TDS 8 / strict encryption, Encrypt=true by default (4.0+), Entra ID (Azure AD) authentication, SqlBatch (.NET 6 DbBatch ) Breaking-change gotcha: Microsoft.Data.SqlClient 4.0+ defaults to Encrypt=True . Local dev servers with self-signed certificates need TrustServerCertificate=True (dev only). Connected access lifecycle: 1. Create SqlConnection with a connection string. 2. Open() / OpenAsync() — gets a physical connection from the pool (or creates one). 3. Create SqlCommand (SQL text or stored procedure) + parameters . 4. Execute: ExecuteReader (rows), ExecuteScalar (single value), ExecuteNonQuery (rows affected). 5. Read with SqlDataReader.Read() forward-only, column by column. 6. Close/Dispose reader → command → connection (with using ) — the connection returns to the pool , not physically closed. Disconnected lifecycle: SqlDataAdapter.Fill(dataSet) (opens and closes the connection automatically) → work offline (edit rows; each DataRow has a RowState : Added, Modified, Deleted, Unchanged) → adapter.Update(dataSet) generates INSERT/UPDATE/DELETE (via SqlCommandBuilder or explicit commands) → AcceptChanges() . Transaction lifecycle: BeginTransaction() → assign to every command → execute → Commit() or Rollback() (automatic rollback on dispose without commit). - SQL Server Management Studio (SSMS) / Azure Data Studio (retiring Feb 2026 in favour of the VS Code MSSQL extension) — write and test SQL. - SQL Server Profiler / Extended Events — see what your app sends. - Visual Studio Server Explorer / SQL Server Object Explorer . - Dapper , Dapper.Contrib , DbUp (migrations as SQL scripts), RepoDB . - Testcontainers for .NET — real SQL Server in Docker for tests. - Polly — retry transient SQL errors (or SqlRetryLogicProvider in SqlClient 3.0+)."},{"kind":"lesson","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"core-objects-and-the-connected-model","title":"Core objects and the connected model","body":"Object Role --- --- SqlConnection Connection to the DB (pooled) SqlCommand SQL statement or stored procedure SqlParameter Typed parameter value — prevents SQL injection SqlDataReader Fast, forward-only, read-only stream of rows SqlDataAdapter Bridge between DB and DataSet DataSet / DataTable In-memory relational data SqlTransaction Groups commands atomically SqlBulkCopy High-speed bulk insert csharp const string cs = \"Server=.;Database=Shop;Integrated Security=True;TrustServerCertificate=True\"; await using var conn = new SqlConnection(cs); await conn.OpenAsync(ct); await using var cmd = new SqlCommand(\"SELECT Id, Name, Price FROM Products WHERE CategoryId = @cat\", conn); cmd.Parameters.Add(\"@cat\", SqlDbType.Int).Value = categoryId; await using var reader = await cmd.ExecuteReaderAsync(ct); var list = new List<Product (); while (await reader.ReadAsync(ct)) { list.Add(new Product( reader.GetInt32(0), reader.GetString(1), reader.GetDecimal(2))); } Use ordinal getters ( GetInt32(0) ) or cache reader.GetOrdinal(\"Name\") for speed; check reader.IsDBNull(i) before reading nullable columns."},{"kind":"lesson","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"executereader-vs-executescalar-vs-executenonquery","title":"ExecuteReader vs ExecuteScalar vs ExecuteNonQuery","body":"csharp // ExecuteScalar — first column of first row var count = (int)(await new SqlCommand(\"SELECT COUNT( ) FROM Orders\", conn).ExecuteScalarAsync())!; // ExecuteNonQuery — INSERT/UPDATE/DELETE/DDL; returns rows affected var cmd = new SqlCommand(\"UPDATE Products SET Price = Price 1.1 WHERE CategoryId = @c\", conn); cmd.Parameters.AddWithValue(\"@c\", 3); int affected = await cmd.ExecuteNonQueryAsync(); // Insert and get the new identity in one round trip var ins = new SqlCommand(\"INSERT INTO Customers(Name) OUTPUT INSERTED.Id VALUES (@n)\", conn); ins.Parameters.Add(\"@n\", SqlDbType.NVarChar, 100).Value = \"Acme\"; int newId = (int)(await ins.ExecuteScalarAsync())!; Multiple result sets: reader.NextResult() / NextResultAsync() moves to the next SELECT's results."},{"kind":"lesson","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"parameters-and-sql-injection","title":"Parameters and SQL injection","body":"csharp // ❌ NEVER — SQL injection: name = \"x'; DROP TABLE Users;--\" var bad = new SqlCommand(\"SELECT FROM Users WHERE Name = '\" + name + \"'\", conn); // ✅ Parameterised var good = new SqlCommand(\"SELECT FROM Users WHERE Name = @name\", conn); good.Parameters.Add(\"@name\", SqlDbType.NVarChar, 50).Value = name; - Parameters send values separately from SQL text — they are never executed as code. - Prefer Parameters.Add(name, SqlDbType, size) over AddWithValue : AddWithValue infers the type (e.g. nvarchar(4000) for strings), which can cause implicit conversions that prevent index seeks (varchar column vs nvarchar parameter) and plan-cache bloat. - Pass DBNull.Value for nulls, not null . - Dynamic table/column names can't be parameters — validate against an allow-list or use QUOTENAME in SQL."},{"kind":"lesson","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"stored-procedures-and-output-parameters","title":"Stored procedures and output parameters","body":"csharp await using var cmd = new SqlCommand(\"dbo.usp PlaceOrder\", conn) { CommandType = CommandType.StoredProcedure }; cmd.Parameters.Add(\"@CustomerId\", SqlDbType.Int).Value = customerId; cmd.Parameters.Add(\"@Total\", SqlDbType.Decimal).Value = total; var outId = cmd.Parameters.Add(\"@OrderId\", SqlDbType.Int); outId.Direction = ParameterDirection.Output; var ret = cmd.Parameters.Add(\"@ReturnValue\", SqlDbType.Int); ret.Direction = ParameterDirection.ReturnValue; await cmd.ExecuteNonQueryAsync(); int orderId = (int)outId.Value; int status = (int)ret.Value; Table-valued parameters (TVP) send many rows in one call: csharp var table = new DataTable(); table.Columns.Add(\"ProductId\", typeof(int)); table.Columns.Add(\"Qty\", typeof(int)); foreach (var l in lines) table.Rows.Add(l.ProductId, l.Qty); var p = cmd.Parameters.AddWithValue(\"@Lines\", table); p.SqlDbType = SqlDbType.Structured; p.TypeName = \"dbo.OrderLineType\"; // CREATE TYPE dbo.OrderLineType AS TABLE (ProductId INT, Qty INT)"},{"kind":"lesson","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"dataset-datatable-and-dataadapter","title":"DataSet, DataTable and DataAdapter","body":"csharp var ds = new DataSet(); using var da = new SqlDataAdapter(\"SELECT Id, Name, Price FROM Products\", cs); da.Fill(ds, \"Products\"); // opens + closes connection automatically DataTable t = ds.Tables[\"Products\"]!; foreach (DataRow row in t.Rows) Console.WriteLine($\"{row[\"Name\"]}: {row[\"Price\"]}\"); t.Rows[0][\"Price\"] = 999m; // RowState = Modified var cb = new SqlCommandBuilder(da); // auto-generates INSERT/UPDATE/DELETE (needs a primary key) da.Update(ds, \"Products\"); // pushes changes back DataView view = new(t) { RowFilter = \"Price 1000\", Sort = \"Price DESC\" }; DataReader DataSet --- --- Connected, forward-only, read-only Disconnected, in-memory, random access, editable Very fast, low memory Heavier; holds all rows One row at a time Multiple tables + relations + constraints Best for APIs, reports streaming Legacy WinForms grids, offline editing, XML serialisation Modern apps rarely use DataSets; they map to POCOs with Dapper/EF."},{"kind":"lesson","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"transactions","title":"Transactions","body":"csharp await using var conn = new SqlConnection(cs); await conn.OpenAsync(); await using var tx = (SqlTransaction)await conn.BeginTransactionAsync(IsolationLevel.ReadCommitted); try { var debit = new SqlCommand(\"UPDATE Accounts SET Balance = Balance - @amt WHERE Id = @from AND Balance = @amt\", conn, tx); debit.Parameters.Add(\"@amt\", SqlDbType.Decimal).Value = amount; debit.Parameters.Add(\"@from\", SqlDbType.Int).Value = fromId; if (await debit.ExecuteNonQueryAsync() != 1) throw new InvalidOperationException(\"Insufficient funds\"); var credit = new SqlCommand(\"UPDATE Accounts SET Balance = Balance + @amt WHERE Id = @to\", conn, tx); credit.Parameters.Add(\"@amt\", SqlDbType.Decimal).Value = amount; credit.Parameters.Add(\"@to\", SqlDbType.Int).Value = toId; await credit.ExecuteNonQueryAsync(); await tx.CommitAsync(); } catch { await tx.RollbackAsync(); throw; } TransactionScope (System.Transactions) gives ambient transactions across multiple connections/resources: create with TransactionScopeAsyncFlowOption.Enabled for async code; it can escalate to a distributed transaction (MSDTC) if several connections are involved — avoid that in cloud apps."},{"kind":"lesson","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"connection-pooling","title":"Connection pooling","body":"- Opening a physical connection is expensive (TCP, TLS, login). ADO.NET keeps a pool per unique connection string (and per Windows identity for integrated security). - Open() takes a connection from the pool; Close() / Dispose() returns it. - Defaults (SqlClient): Min Pool Size=0 , Max Pool Size=100 , Pooling=true , Connection Timeout=15 . - Pool exhaustion (\"Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool\") = connections not disposed, long-running transactions, or too many concurrent requests. - Different connection strings (even a different space/order) create separate pools — build them once from config. - Keep connections open as briefly as possible: open late, close early, always with using ."},{"kind":"lesson","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"bulk-operations-and-async","title":"Bulk operations and async","body":"csharp using var bulk = new SqlBulkCopy(conn, SqlBulkCopyOptions.TableLock, tx) { DestinationTableName = \"dbo.StagingSales\", BatchSize = 10 000, BulkCopyTimeout = 600 }; bulk.ColumnMappings.Add(\"Date\", \"SaleDate\"); bulk.ColumnMappings.Add(\"Amount\", \"Amount\"); await bulk.WriteToServerAsync(dataTableOrDataReader); // streams rows using the bulk insert protocol - SqlBulkCopy loads millions of rows in seconds vs minutes with row-by-row INSERTs. - Use async APIs ( OpenAsync , ExecuteReaderAsync , ReadAsync ) in web apps to free threads during I/O. - CommandTimeout default is 30 seconds; set it per command for long reports. - Batch many statements with SqlBatch / DbBatch (.NET 6+) or TVPs instead of N round trips."},{"kind":"lesson","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"dapper-micro-orm","title":"Dapper micro-ORM","body":"csharp using Dapper; await using var conn = new SqlConnection(cs); // Query → objects (parameters are anonymous objects; always parameterised) var products = await conn.QueryAsync<Product ( \"SELECT Id, Name, Price FROM Products WHERE CategoryId = @CategoryId AND Price @Min\", new { CategoryId = 3, Min = 500m }); var one = await conn.QuerySingleOrDefaultAsync<Product (\"SELECT FROM Products WHERE Id = @id\", new { id }); int rows = await conn.ExecuteAsync(\"UPDATE Products SET Price = @Price WHERE Id = @Id\", new { Id = 5, Price = 99m }); // IN list expansion var some = await conn.QueryAsync<Product (\"SELECT FROM Products WHERE Id IN @Ids\", new { Ids = new[] { 1, 2, 3 } }); // Multi-mapping (JOIN → object graph) var orders = await conn.QueryAsync<Order, Customer, Order ( \"SELECT o. , c. FROM Orders o JOIN Customers c ON c.Id = o.CustomerId\", (o, c) = { o.Customer = c; return o; }, splitOn: \"Id\"); // Multiple result sets using var multi = await conn.QueryMultipleAsync(\"SELECT FROM Orders WHERE Id=@id; SELECT FROM OrderLines WHERE OrderId=@id\", new { id }); var order = await multi.ReadSingleAsync<Order (); order.Lines = (await multi.ReadAsync<OrderLine ()).ToList(); // Stored procedure var report = await conn.QueryAsync<SalesRow (\"dbo.usp SalesReport\", new { Year = 2026 }, commandType: CommandType.StoredProcedure); // Transaction await conn.OpenAsync(); await using var tx = await conn.BeginTransactionAsync(); await conn.ExecuteAsync(\"INSERT ...\", param, tx); await tx.CommitAsync(); Dapper vs EF Core: Dapper — full SQL control, fastest mapping, great for reads/reports/stored procedures; no change tracking, migrations or LINQ. EF Core — productivity, LINQ, change tracking, migrations, relationships. Many systems use both : EF Core for writes (commands), Dapper for complex reads (queries) — a light CQRS."},{"kind":"question","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"248","title":"What is ADO.NET? Name its main objects.","body":"ADO.NET is .NET's core data access library ( System.Data + provider packages). Main objects: Connection (connects to the DB), Command (executes SQL/procs), Parameter , DataReader (forward-only fast read), DataAdapter (fills/updates DataSets), DataSet / DataTable (in-memory data), Transaction . For SQL Server use Microsoft.Data.SqlClient ( SqlConnection , SqlCommand ...)."},{"kind":"question","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"249","title":"What is the difference between connected and disconnected architecture?","body":"Connected: the connection stays open while you read with a DataReader — forward-only, read-only, very fast, minimal memory. Disconnected: a DataAdapter fills a DataSet / DataTable , then closes the connection; you can navigate, edit and later push changes back with Update() — more memory, more flexibility. Modern apps mostly use the connected model (directly or via Dapper/EF)."},{"kind":"question","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"250","title":"What is the difference between ExecuteReader, ExecuteScalar and ExecuteNonQuery?","body":"ExecuteReader returns a DataReader for one or more result sets. ExecuteScalar returns the first column of the first row (COUNT, SUM, new identity via OUTPUT / SCOPE IDENTITY() ). ExecuteNonQuery runs INSERT/UPDATE/DELETE/DDL and returns the number of rows affected (-1 for statements that don't affect rows, or when SET NOCOUNT ON is set)."},{"kind":"question","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"251","title":"DataReader vs DataSet?","body":"DataReader: connected, forward-only, read-only, one row at a time, fastest and lowest memory — use for streaming results to APIs. DataSet: disconnected, in-memory collection of DataTables with relations and constraints, random access and editable, can be serialised to XML — heavier; used in legacy WinForms/reporting. EF/Dapper map to objects instead."},{"kind":"question","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"252","title":"How do you prevent SQL injection in ADO.NET?","body":"Always use parameters ( @name placeholders + SqlParameter with explicit type/size) or stored procedures with parameters — never concatenate user input into SQL. Validate input, use least-privilege DB accounts, and for dynamic identifiers (table/column names) use an allow-list. ORMs (EF, Dapper) parameterise automatically."},{"kind":"question","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"253","title":"What is the `using` statement's role with SqlConnection?","body":"SqlConnection , SqlCommand and SqlDataReader implement IDisposable . using guarantees Dispose() (which closes the connection and returns it to the pool) even if an exception occurs. Forgetting to dispose leaks pooled connections and eventually causes pool-timeout errors."},{"kind":"question","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"254","title":"What is connection pooling? How do you troubleshoot pool exhaustion?","body":"ADO.NET reuses open physical connections from a pool keyed by the exact connection string. Open() borrows, Close()/Dispose() returns. Default max is 100 per pool. Exhaustion symptoms: \"Timeout expired… obtaining a connection from the pool\". Causes: missing using /dispose, connections held across long work or await s of slow external calls, long transactions, or traffic beyond 100 concurrent DB operations. Fix: dispose properly, shorten connection lifetimes, async I/O, raise Max Pool Size only after fixing leaks, monitor with performance counters/ sys.dm exec sessions ."},{"kind":"question","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"255","title":"How do you implement a transaction in ADO.NET?","body":"var tx = conn.BeginTransaction(isolationLevel) , assign tx to every command ( new SqlCommand(sql, conn, tx) ), execute, then tx.Commit() ; on exception tx.Rollback() . Disposing an uncommitted transaction rolls it back. For multiple connections/resources use TransactionScope (async flow enabled), avoiding distributed escalation in the cloud. Keep transactions short to reduce locking."},{"kind":"question","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"256","title":"Why is `AddWithValue` considered bad practice?","body":"It infers the SQL type from the .NET value: strings become nvarchar with a length equal to the value, decimals get inferred precision. Mismatches with column types (e.g. varchar column vs nvarchar parameter) force implicit conversions that can turn index seeks into scans, and varying lengths create many cached plans. Use Parameters.Add(\"@p\", SqlDbType.VarChar, 50).Value = x with explicit type and size."},{"kind":"question","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"257","title":"How do you call a stored procedure with output parameters?","body":"Set CommandType = CommandType.StoredProcedure , add input parameters, add an output parameter with Direction = ParameterDirection.Output (and size for strings), optionally a ReturnValue parameter, execute ( ExecuteNonQuery ), then read param.Value after execution (after closing the reader if you used ExecuteReader )."},{"kind":"question","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"258","title":"What is SqlBulkCopy and when do you use it?","body":"A class that streams large volumes of rows into a SQL Server table using the bulk insert protocol — from a DataTable , DataReader or DataRow[] . It's orders of magnitude faster than individual INSERTs. Configure BatchSize , BulkCopyTimeout , column mappings and TableLock . Typical use: ETL staging loads, imports from CSV/Excel. Load into a staging table, then MERGE into the final table."},{"kind":"question","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"259","title":"What is MARS?","body":"Multiple Active Result Sets ( MultipleActiveResultSets=True in the connection string) lets you have more than one open DataReader (or execute commands while reading) on the same connection. Useful in some EF lazy-loading scenarios, but it adds overhead; usually better to restructure queries."},{"kind":"question","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"260","title":"What is Dapper and how does it compare with EF Core and raw ADO.NET?","body":"Dapper is a micro-ORM: extension methods ( Query<T , Execute , QueryMultiple ) on IDbConnection that map rows to objects using cached IL. Compared with raw ADO.NET it removes mapping boilerplate with almost the same speed; compared with EF Core it has no change tracking, LINQ, migrations or relationship management — you write all SQL. Use Dapper for read-heavy, performance-critical or complex SQL/stored procedures; EF Core for domain-rich write models. They combine well."},{"kind":"question","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"261","title":"How do you handle transient errors (e.g. Azure SQL failovers) in ADO.NET?","body":"Use retry logic for transient error numbers (e.g. 40613, 40501, 40197, 10928/10929, 4060, 49918–49920, timeouts): SqlClient's configurable retry logic ( SqlRetryLogicBaseProvider via RetryLogicProvider on the connection/command), Polly with exponential backoff, or EF Core's EnableRetryOnFailure . Only retry idempotent operations or whole transactions, and keep Connect Retry Count for idle connection resiliency."},{"kind":"question","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"262","title":"How would you pass a list of 5,000 IDs to a SQL query efficiently?","body":"Options: a table-valued parameter (TVP; best for SQL Server; plan-stable), STRING SPLIT on a delimited string or OPENJSON on a JSON array parameter (EF Core 8 does this for Contains ), or bulk-insert into a temp/staging table and join. Avoid building IN (1,2,3,...) strings — injection risk, plan-cache pollution and the 2,100-parameter limit for individual parameters."},{"kind":"question","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"263","title":"Under load the API logs \"Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool.\" How do you fix it?","body":"Pool exhaustion. 1) Search for connections/readers not in using blocks and for code holding connections across slow calls (HTTP, file I/O) or long transactions. 2) Check sync-over-async blocking that keeps connections open longer. 3) Check slow queries (Query Store) — slow queries hold connections. 4) Monitor active connections ( sys.dm exec sessions by program name). 5) Only then tune Max Pool Size , and consider caching or fewer round trips (batching). Also ensure one consistent connection string."},{"kind":"question","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"264","title":"You must import a 2-million-row CSV into SQL Server nightly. How would you do it in .NET?","body":"Stream the file (don't load it all) with a CSV reader (CsvHelper) exposing an IDataReader or batches of DataTable s; SqlBulkCopy into a staging table with TableLock and a batch size (10k–50k); then a set-based stored procedure validates and MERGE s/ INSERT s into target tables inside a transaction; log rejected rows; make it idempotent (truncate staging first, track file/batch IDs). Alternatives: SSIS or Azure Data Factory for ops-managed pipelines."},{"kind":"question","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"265","title":"A query is fast in SSMS but slow from the application. Why?","body":"Common causes: (1) different SET options — SSMS uses ARITHABORT ON , apps usually OFF, so they get different cached plans; (2) parameter sniffing — the app's cached plan was compiled for an atypical parameter value; (3) parameter type mismatch (nvarchar parameter vs varchar column → implicit conversion, scan); (4) app reading huge result sets slowly or network latency. Investigate with Query Store / actual execution plans, fix types, consider OPTION (RECOMPILE) or OPTIMIZE FOR , update statistics, add proper indexes."},{"kind":"cheat","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"1","title":"Core objects","body":"SqlConnection · SqlCommand · SqlParameter · SqlDataReader · SqlDataAdapter · DataSet / DataTable / DataView · SqlTransaction · SqlBulkCopy · SqlCommandBuilder ."},{"kind":"cheat","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"2","title":"Execute methods","body":"Method Returns Use --- --- --- ExecuteReader DataReader SELECT rows ExecuteScalar object (1 value) COUNT, new ID ExecuteNonQuery int rows affected INSERT/UPDATE/DELETE/DDL ExecuteXmlReader XmlReader FOR XML queries"},{"kind":"cheat","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"3","title":"Template","body":"csharp await using var conn = new SqlConnection(cs); await conn.OpenAsync(ct); await using var cmd = new SqlCommand(sql, conn); cmd.Parameters.Add(\"@id\", SqlDbType.Int).Value = id; await using var r = await cmd.ExecuteReaderAsync(ct); while (await r.ReadAsync(ct)) { var name = r.GetString(r.GetOrdinal(\"Name\")); }"},{"kind":"cheat","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"4","title":"Connection string keys","body":"Server · Database · Integrated Security=True / User Id + Password / Authentication=Active Directory Default · Encrypt=True · TrustServerCertificate=True (dev) · Max Pool Size · Connect Timeout · MultipleActiveResultSets · Application Name ."},{"kind":"cheat","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"5","title":"Dapper","body":"Query<T · QueryFirstOrDefault<T · QuerySingle<T · Execute · ExecuteScalar<T · QueryMultiple · multi-mapping splitOn · IN @Ids · commandType: CommandType.StoredProcedure · pass transaction ."},{"kind":"cheat","course_slug":"adonet","course_title":"ADO.NET — Connected & Disconnected Data Access","ref":"6","title":"Remember","body":"Always parameterise · explicit SqlDbType + size · using / await using · open late, close early · pool max 100 · Encrypt=True default in SqlClient 4+ · SqlBulkCopy for bulk · TVP for lists · retry transient errors."},{"kind":"course","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"","title":"LINQ — Language Integrated Query","body":"Query vs method syntax, deferred execution, filtering, projection, ordering, grouping, joins, aggregation, set and element operators, IEnumerable vs IQueryable, expression trees, performance and the classic LINQ interview programs. LINQ (Language Integrated Query) adds query capabilities directly to C . One syntax works over many data sources: Provider Data source Runs --- --- --- LINQ to Objects IEnumerable<T — arrays, lists, dictionaries In memory LINQ to Entities (EF Core) IQueryable<T → SQL In the database LINQ to XML XDocument , XElement In memory PLINQ .AsParallel() Parallel, in memory Others Cosmos DB SDK, MongoDB driver, OData Remote LINQ is built on C 3.0 features: extension methods , lambda expressions , anonymous types , var , object initialisers and expression trees . Year .NET / C LINQ additions --- --- --- 2007 .NET 3.5 / C 3.0 LINQ introduced: Where, Select, OrderBy, GroupBy, Join, ... ; LINQ to SQL, LINQ to XML 2010 .NET 4.0 PLINQ ( AsParallel ), Zip 2017–2019 .NET Core 2.x–3.0 Append , Prepend , SkipLast , TakeLast , ToHashSet 2021 .NET 6 MinBy , MaxBy , DistinctBy , UnionBy , IntersectBy , ExceptBy , Chunk , Take(Range) , TryGetNonEnumeratedCount 2022 .NET 7 Order() , OrderDescending() 2024 .NET 9 CountBy , AggregateBy , Index() 2025 .NET 10 LeftJoin , RightJoin operators; System.Linq.AsyncEnumerable (async LINQ over IAsyncEnumerable<T ) in the box How a LINQ query executes: 1. Define — you compose operators ( Where , Select , ...). Nothing runs yet; you've built a query object (an iterator chain, or an expression tree for IQueryable ). 2. Enumerate — execution starts when you iterate ( foreach ) or call an immediate operator: ToList , ToArray , ToDictionary , Count , Sum , First , Any , ... 3. Pull pipeline (LINQ to Objects) — each element flows through Where → Select → consumer one at a time (streaming). Some operators must buffer everything first ( OrderBy , GroupBy , Reverse , Distinct partially). 4. Translation (IQueryable) — the provider (EF Core) walks the expression tree, translates it to SQL, sends it to the DB and materialises results. 5. Re-enumeration re-runs the whole query — cache with ToList() if you need the results more than once. - LINQPad — the classic LINQ playground (C queries against objects and databases, shows generated SQL). - Visual Studio — IntelliSense, debugger \"Results View\" (careful: it enumerates the query). - EF Core logging ( LogTo(Console.WriteLine) , ToQueryString() ) — see SQL generated from LINQ. - ReSharper/Rider — convert loops ↔ LINQ. - SharpLab — see how query syntax lowers to method calls. - BenchmarkDotNet — compare LINQ vs loops in hot paths."},{"kind":"lesson","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"query-syntax-vs-method-syntax","title":"Query syntax vs method syntax","body":"csharp var products = new List<Product { new(1, \"Laptop\", \"Electronics\", 65000, 5), new(2, \"Mouse\", \"Electronics\", 900, 50), new(3, \"Desk\", \"Furniture\", 9000, 0), new(4, \"Chair\", \"Furniture\", 6500, 12), }; // Query syntax (SQL-like) — compiled into method calls var q1 = from p in products where p.Price 5000 orderby p.Price descending select new { p.Name, p.Price }; // Method syntax (fluent, lambda-based) — same result var q2 = products.Where(p = p.Price 5000) .OrderByDescending(p = p.Price) .Select(p = new { p.Name, p.Price }); public record Product(int Id, string Name, string Category, decimal Price, int Stock); Query syntax supports from, where, select, orderby, group … by … into, join … on … equals, let . Everything else ( Count , First , Distinct , Skip , Take , Any , Sum ) needs method syntax. Most teams use method syntax; query syntax is nicer for multi-joins and let ."},{"kind":"lesson","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"deferred-vs-immediate-execution","title":"Deferred vs immediate execution","body":"csharp var numbers = new List<int { 1, 2, 3 }; var evens = numbers.Where(n = n % 2 == 0); // deferred: nothing executed yet numbers.Add(4); Console.WriteLine(string.Join(\",\", evens)); // 2,4 — query ran now, saw the added item var snapshot = numbers.Where(n = n 1).ToList(); // immediate: executed and stored numbers.Add(10); Console.WriteLine(snapshot.Count); // 3 — unaffected Deferred (return a query) Immediate (execute now) --- --- Where , Select , SelectMany , OrderBy , ThenBy , GroupBy , Join , Skip , Take , Distinct , Concat , Zip ToList , ToArray , ToDictionary , ToHashSet , ToLookup , Count , Sum , Min , Max , Average , First , Single , Any , All , Contains , Aggregate Interview tip: \"Multiple enumeration\" — iterating a deferred query twice runs it twice (two DB round trips for EF). Materialise once with ToList() if you need it again."},{"kind":"lesson","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"filtering-projection-and-ordering","title":"Filtering, projection and ordering","body":"csharp var inStock = products.Where(p = p.Stock 0); var withIndex = products.Where((p, i) = i % 2 == 0); // overload with index var names = products.Select(p = p.Name); var dto = products.Select(p = new ProductDto(p.Id, p.Name.ToUpper())); var sorted = products.OrderBy(p = p.Category) // primary sort .ThenByDescending(p = p.Price) // secondary sort .ToList(); var electronics = products.OfType<Product ().Where(p = p.Category == \"Electronics\"); // OfType filters by type Calling OrderBy twice replaces the first sort — use ThenBy for secondary keys. LINQ OrderBy is a stable sort."},{"kind":"lesson","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"element-quantifier-and-partitioning-operators","title":"Element, quantifier and partitioning operators","body":"Operator Empty sequence More than one match --- --- --- First() throws returns first FirstOrDefault() default/null returns first Single() throws throws SingleOrDefault() default/null throws Last() / LastOrDefault() throws / default returns last ElementAt(i) / ElementAtOrDefault(i) throws / default — csharp bool anyOut = products.Any(p = p.Stock == 0); // stops at first match bool allPriced = products.All(p = p.Price 0); bool hasMouse = products.Select(p = p.Name).Contains(\"Mouse\"); var page2 = products.OrderBy(p = p.Id).Skip(10).Take(10); var whileCheap = products.OrderBy(p = p.Price).TakeWhile(p = p.Price < 10000); foreach (var batch in products.Chunk(100)) { / process 100 at a time (.NET 6) / } var cheapest = products.MinBy(p = p.Price); // .NET 6 — returns the element, not the value Use Any() instead of Count() 0 — Any stops at the first element."},{"kind":"lesson","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"grouping","title":"Grouping","body":"csharp var byCategory = products .GroupBy(p = p.Category) .Select(g = new { Category = g.Key, Count = g.Count(), TotalValue = g.Sum(p = p.Price p.Stock), MostExpensive = g.MaxBy(p = p.Price)!.Name }); // query syntax with 'into' var q = from p in products group p by p.Category into g where g.Count() 1 select new { g.Key, Avg = g.Average(p = p.Price) }; // group by multiple keys (anonymous type) var multi = orders.GroupBy(o = new { o.CustomerId, o.OrderDate.Year }); // ToLookup: immediate, re-usable grouping (key - IEnumerable) ILookup<string, Product lookup = products.ToLookup(p = p.Category); var furniture = lookup[\"Furniture\"]; // empty sequence if key missing (no exception) // .NET 9 shortcuts var counts = products.CountBy(p = p.Category); // KeyValuePair<string,int var totals = products.AggregateBy(p = p.Category, 0m, (sum, p) = sum + p.Price);"},{"kind":"lesson","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"joins-inner-left-group-join-cross","title":"Joins: inner, left, group join, cross","body":"csharp var customers = new[] { new Customer(1, \"Acme\"), new Customer(2, \"Zen\"), new Customer(3, \"Nova\") }; var orders = new[] { new Order(101, 1, 500m), new Order(102, 1, 250m), new Order(103, 2, 900m) }; // INNER JOIN var inner = customers.Join(orders, c = c.Id, o = o.CustomerId, (c, o) = new { c.Name, o.Id, o.Total }); // query syntax var inner2 = from c in customers join o in orders on c.Id equals o.CustomerId select new { c.Name, o.Total }; // LEFT JOIN — classic GroupJoin + SelectMany + DefaultIfEmpty var left = from c in customers join o in orders on c.Id equals o.CustomerId into custOrders from o in custOrders.DefaultIfEmpty() select new { c.Name, OrderId = o?.Id, Total = o?.Total ?? 0 }; // .NET 10: built-in LeftJoin operator var left10 = customers.LeftJoin(orders, c = c.Id, o = o.CustomerId, (c, o) = new { c.Name, Total = o?.Total ?? 0 }); // GROUP JOIN — each customer with its orders var perCustomer = customers.GroupJoin(orders, c = c.Id, o = o.CustomerId, (c, os) = new { c.Name, Orders = os.Count(), Sum = os.Sum(o = o.Total) }); // CROSS JOIN var cross = from size in new[] { \"S\", \"M\" } from color in new[] { \"Red\", \"Blue\" } select size + color; record Customer(int Id, string Name); record Order(int Id, int CustomerId, decimal Total); Query syntax join uses equals (not == ) and the outer key must be on the left."},{"kind":"lesson","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"aggregation-and-selectmany","title":"Aggregation and SelectMany","body":"csharp int count = products.Count(p = p.Stock 0); decimal total = products.Sum(p = p.Price); decimal avg = products.Average(p = p.Price); decimal max = products.Max(p = p.Price); // value Product priciest = products.MaxBy(p = p.Price)!; // element (.NET 6) // Aggregate = fold/reduce string csv = products.Select(p = p.Name).Aggregate((a, b) = a + \",\" + b); int factorial = Enumerable.Range(1, 5).Aggregate(1, (acc, n) = acc n); // 120 // SelectMany flattens nested collections var allLines = orders.SelectMany(o = o.Lines); // IEnumerable<Line var tags = posts.SelectMany(p = p.Tags).Distinct(); var pairs = customers.SelectMany(c = c.Orders, (c, o) = new { c.Name, o.Id }); Select → one output per input (can produce IEnumerable<IEnumerable<T ); SelectMany → flattens to IEnumerable<T ."},{"kind":"lesson","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"set-operators-and-generation","title":"Set operators and generation","body":"csharp int[] a = [1, 2, 3, 4], b = [3, 4, 5]; a.Union(b); // 1 2 3 4 5 (distinct) a.Concat(b); // 1 2 3 4 3 4 5 (keeps duplicates) a.Intersect(b); // 3 4 a.Except(b); // 1 2 a.Distinct(); products.DistinctBy(p = p.Category); // .NET 6 customersA.ExceptBy(customersB.Select(c = c.Id), c = c.Id); Enumerable.Range(1, 10); // 1..10 Enumerable.Repeat(\"x\", 3); // x x x Enumerable.Empty<int (); a.Zip(b, (x, y) = x y); // pairs element-wise a.Reverse(); a.Append(9); a.Prepend(0); foreach (var (index, item) in products.Index()) { } // .NET 9 Custom equality for Distinct/Union/Intersect/Except on classes: implement IEquatable<T + GetHashCode , pass an IEqualityComparer<T , use records, or use the By variants."},{"kind":"lesson","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"ienumerable-vs-iqueryable","title":"IEnumerable vs IQueryable","body":"IEnumerable<T IQueryable<T --- --- --- Namespace System.Collections.Generic System.Linq Lambdas compiled to Delegates ( Func<T,bool ) Expression trees ( Expression<Func<T,bool ) Execution In memory (LINQ to Objects) Translated by a provider (SQL) and run remotely Filtering big tables Loads everything, filters in RAM WHERE runs in the database Use Collections already in memory EF Core DbSet s, remote sources csharp IQueryable<Order q = db.Orders.Where(o = o.Total 1000); // nothing sent yet q = q.OrderBy(o = o.CreatedAt).Take(20); // still composing Console.WriteLine(q.ToQueryString()); // see the SQL (EF Core 5+) var list = await q.ToListAsync(); // SELECT TOP(20) ... WHERE Total 1000 ORDER BY ... IEnumerable<Order bad = db.Orders; // as IEnumerable var slow = bad.Where(o = o.Total 1000).ToList(); // SELECT FROM Orders, then filter in memory!"},{"kind":"lesson","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"expression-trees-and-dynamic-queries","title":"Expression trees and dynamic queries","body":"An expression tree is code as data : a tree of Expression nodes that a provider can inspect and translate. csharp Func<int, bool del = n = n 5; // compiled code Expression<Func<int, bool expr = n = n 5; // data structure Console.WriteLine(expr.Body); // (n 5) var compiled = expr.Compile(); // can still compile and run // Build a filter dynamically: p = p.Price minPrice var param = Expression.Parameter(typeof(Product), \"p\"); var body = Expression.GreaterThan(Expression.Property(param, nameof(Product.Price)), Expression.Constant(5000m)); var lambda = Expression.Lambda<Func<Product, bool (body, param); var results = db.Products.Where(lambda); // Simpler: compose conditionally IQueryable<Product query = db.Products; if (category is not null) query = query.Where(p = p.Category == category); if (minPrice is not null) query = query.Where(p = p.Price = minPrice); Libraries: System.Linq.Dynamic.Core (string-based dynamic LINQ), LinqKit (PredicateBuilder for OR conditions)."},{"kind":"lesson","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"linq-with-ef-core-what-translates-and-common-pitfalls","title":"LINQ with EF Core: what translates and common pitfalls","body":"- Projection with Select into DTOs fetches only needed columns and needs no tracking. - Methods EF can't translate (your own C methods) cause an exception (EF Core 3.0+ no longer silently evaluates on the client, except in the final Select ). - Contains on a local list → WHERE Id IN (...) (EF 8+ can send it as a JSON parameter for plan reuse). - N+1 : looping over orders and touching o.Customer with lazy loading → one query per order. Use Include or projection. - Count() vs Any() : use AnyAsync() for existence. - First without OrderBy → nondeterministic order. - String comparisons follow DB collation (often case-insensitive in SQL Server). - Use async operators ( ToListAsync , FirstOrDefaultAsync ) in web apps. csharp var summaries = await db.Customers .Where(c = c.IsActive) .Select(c = new CustomerSummary(c.Id, c.Name, c.Orders.Count, c.Orders.Sum(o = (decimal?)o.Total) ?? 0)) .OrderByDescending(s = s.Total) .Take(10) .ToListAsync(ct);"},{"kind":"lesson","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"performance-and-plinq","title":"Performance and PLINQ","body":"- LINQ to Objects allocates iterators and delegates: fine for most code, measure in hot paths (tight loops over millions of items may prefer for / Span<T ). - .NET 7–9 heavily optimised Sum , Min , Max , Average , Order , Count (vectorised for arrays/spans). - Avoid Count() on IEnumerable when you only need \"any\"; prefer TryGetNonEnumeratedCount . - Prefer HashSet.Contains over list.Contains inside a Where (O(1) vs O(n)). - PLINQ : source.AsParallel().Where(...).Select(...) uses multiple cores for CPU-bound work on large data; order not preserved unless AsOrdered() ; not useful for I/O-bound work or small collections. csharp var allowed = new HashSet<int (allowedIds); var filtered = items.Where(i = allowed.Contains(i.Id)); // O(n) instead of O(n m) var primes = Enumerable.Range(2, 5 000 000).AsParallel().Where(IsPrime).Count();"},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"266","title":"What is LINQ and what are its advantages?","body":"LINQ (Language Integrated Query, C 3.0/.NET 3.5) gives a uniform, strongly typed query syntax for in-memory collections, databases (EF Core), XML and more. Advantages: compile-time checking and IntelliSense, less boilerplate than loops, readable declarative code, composable queries, deferred execution, and one skill across data sources."},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"267","title":"What is deferred execution? Which operators execute immediately?","body":"A deferred query isn't executed when defined. It runs each time it is enumerated, so it sees the current data. Where , Select , OrderBy , GroupBy , Skip / Take and Join are deferred. ToList , ToArray , ToDictionary , Count , Sum , Max , First , Single , Any , All and Aggregate execute immediately. Pitfalls: enumerating the same query twice runs it twice; captured variables are read at execution time, not definition time."},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"268","title":"What is the difference between First, FirstOrDefault, Single and SingleOrDefault?","body":"First returns the first match and throws if there are none. FirstOrDefault returns default/null if there are none. Single expects exactly one match and throws for none or several. SingleOrDefault returns default for none and throws for several. Use Single when duplicates would indicate a data bug (unique keys). Use First with an OrderBy for \"top 1\". In EF, Single fetches 2 rows to check uniqueness."},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"269","title":"What is the difference between Select and SelectMany?","body":"Select projects each element to exactly one result; if the result is a collection you get nested collections. SelectMany projects each element to a sequence and flattens them into one sequence. Example: orders.Select(o = o.Lines) gives IEnumerable<List<Line , while orders.SelectMany(o = o.Lines) gives IEnumerable<Line ."},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"270","title":"What is the difference between IEnumerable and IQueryable?","body":"IEnumerable<T executes in memory with compiled delegates (LINQ to Objects). IQueryable<T builds an expression tree that a provider (EF Core) translates into SQL and executes in the database. Filtering an IQueryable reduces the rows transferred; casting a DbSet to IEnumerable before Where loads the whole table into memory. Keep queries as IQueryable until the final materialisation."},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"271","title":"Query syntax vs method syntax — which is better?","body":"They compile to the same method calls. Query syntax reads like SQL and is convenient for joins, let and grouping. Method syntax supports every operator ( Count , Distinct , Take , Any ...) and is more common in codebases. They can be mixed: (from p in products where p.Stock 0 select p).Count() ."},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"272","title":"How do you perform a left outer join in LINQ?","body":"Before .NET 10: GroupJoin followed by SelectMany with DefaultIfEmpty() . In query syntax: join o in orders on c.Id equals o.CustomerId into g from o in g.DefaultIfEmpty() select new { c.Name, Total = o == null ? 0 : o.Total } . .NET 10 adds a LeftJoin operator, and EF Core 10 translates it to LEFT JOIN . In EF Core you often don't need explicit joins at all: navigation properties generate them."},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"273","title":"Write a LINQ query to find the second highest salary.","body":"csharp var second = employees.Select(e = e.Salary).Distinct() .OrderByDescending(s = s).Skip(1).FirstOrDefault(); // Nth highest: .Skip(n - 1) // with ties (employees having that salary): var who = employees.Where(e = e.Salary == second);"},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"274","title":"How do you group data and get counts or sums per group?","body":"GroupBy(key) followed by Select(g = new { g.Key, Count = g.Count(), Total = g.Sum(x = x.Amount) }) . Group by multiple keys with an anonymous type: GroupBy(o = new { o.CustomerId, o.Date.Year }) . Filter groups with Where after grouping (like SQL HAVING ). .NET 9 adds CountBy and AggregateBy for the common cases."},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"275","title":"What is the difference between `Any()` and `Count() > 0`?","body":"Any() stops at the first element (O(1) for most sequences); in EF it generates EXISTS , which is efficient. Count() enumerates everything (for non-collections) or runs COUNT( ) over all matching rows. Use Any() to check existence. (For ICollection<T , Count() uses the Count property, but Any() is still clearer.)"},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"276","title":"What is the difference between `ToList()`, `ToArray()`, `ToDictionary()` and `ToLookup()`?","body":"All materialise immediately. ToList gives a growable List<T , ToArray a fixed array (slightly more compact). ToDictionary(key) maps unique keys to values and throws on duplicate keys . ToLookup(key) groups into a key → many-values structure, allows duplicates, and returns an empty sequence for missing keys."},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"277","title":"What is the difference between `Union` and `Concat`? `Distinct` with custom objects?","body":"Concat appends one sequence to another, keeping duplicates. Union returns distinct elements from both. For classes, Distinct / Union use default equality (reference equality unless Equals / GetHashCode are overridden). Use records, implement IEquatable<T , pass an IEqualityComparer<T , or use DistinctBy / UnionBy (.NET 6)."},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"278","title":"What does `let` do in query syntax?","body":"It introduces a range variable that stores an intermediate calculation, so you don't repeat it: from p in products let discounted = p.Price 0.9m where discounted 1000 select new { p.Name, discounted } . It compiles to a Select into an anonymous type."},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"279","title":"What are expression trees and why does EF Core need them?","body":"An expression tree ( Expression<Func<T,bool ) represents code as an inspectable data structure instead of compiled IL. EF Core walks the tree to understand the lambda ( o = o.Total 1000 ) and translate it into SQL. That's why only translatable constructs work in IQueryable queries. You can build expression trees dynamically for runtime filters, or compile them into delegates."},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"280","title":"What is the N+1 problem in LINQ/EF and how do you fix it?","body":"One query loads N parent rows, then accessing a navigation property per row triggers N extra queries (lazy loading, or querying inside a loop). Fix: eager load with Include / ThenInclude , project with Select into DTOs (one SQL with joins/subqueries), use AsSplitQuery() for multiple collection includes, or batch-load children with Where(x = ids.Contains(x.ParentId)) . Detect it with EF logging, MiniProfiler or Application Insights dependency counts."},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"281","title":"Why might a LINQ query throw \"could not be translated\"?","body":"The expression contains something the provider can't convert to SQL: a custom C method, an unsupported .NET method, complex client-side logic, or certain GroupBy shapes. EF Core 3.0+ throws instead of silently evaluating on the client (except in the final projection). Fix: rewrite with translatable operations, move the logic after AsEnumerable() / ToListAsync() (only after filtering), map a DB function ( HasDbFunction ) or use raw SQL."},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"282","title":"When would you use PLINQ, and when not?","body":"For CPU-bound operations on large in-memory collections where each element's work is independent (image processing, heavy calculations): AsParallel() spreads the work across cores. Not for I/O-bound work (use async with Task.WhenAll / Parallel.ForEachAsync ), small collections (overhead dominates), order-sensitive results (unless AsOrdered , which costs), or code with shared mutable state (race conditions)."},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"283","title":"A report screen calls `db.Orders.ToList().Where(o => o.CustomerId == id)` and is slow with 2 million orders. What's wrong?","body":"ToList() executes immediately and loads all 2 million rows into memory, then filters in C . Move the filter before materialisation: await db.Orders.Where(o = o.CustomerId == id).Select(o = new OrderDto(...)).ToListAsync() . The WHERE then runs in SQL with an index on CustomerId . Add paging and AsNoTracking , and project only the needed columns."},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"284","title":"Given a list of employees, write LINQ to return each department's highest-paid employee and the department's average salary.","body":"csharp var result = employees .GroupBy(e = e.Department) .Select(g = new { Department = g.Key, TopEarner = g.MaxBy(e = e.Salary)!.Name, AverageSalary = g.Average(e = e.Salary), Headcount = g.Count() }) .OrderByDescending(x = x.AverageSalary); For ties at the top, use g.Where(e = e.Salary == g.Max(x = x.Salary)) ."},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"285","title":"Find duplicate emails in a customer list and keep only the first record of each.","body":"csharp var duplicates = customers.GroupBy(c = c.Email.ToLowerInvariant()) .Where(g = g.Count() 1) .Select(g = new { Email = g.Key, Count = g.Count() }); var deduped = customers.DistinctBy(c = c.Email.ToLowerInvariant()).ToList(); // keeps first occurrence // pre-.NET 6: customers.GroupBy(c = c.Email).Select(g = g.First())"},{"kind":"question","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"286","title":"A method returns `IEnumerable<Order>` from a DB query, and two `foreach` loops over it hit the database twice. Why, and how do you fix it?","body":"The method returns a deferred query, so each enumeration executes it again (two SQL round trips, possibly different results). Materialise once with ToList() / ToListAsync() , and return IReadOnlyList<Order to make it explicit. Analyzers (CA1851, ReSharper's \"possible multiple enumeration\") warn about this."},{"kind":"cheat","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"1","title":"Operator families","body":"Family Operators --- --- Filter Where , OfType Project Select , SelectMany Sort OrderBy , OrderByDescending , ThenBy , ThenByDescending , Reverse , Order Group GroupBy , ToLookup , CountBy , AggregateBy Join Join , GroupJoin , LeftJoin / RightJoin (.NET 10), Zip Set Distinct(By) , Union(By) , Intersect(By) , Except(By) , Concat Partition Skip , Take , SkipWhile , TakeWhile , Chunk , TakeLast Element First , Single , Last , ElementAt (+OrDefault) Quantifier Any , All , Contains Aggregate Count , Sum , Min , Max , MinBy , MaxBy , Average , Aggregate Convert ToList , ToArray , ToDictionary , ToHashSet , ToLookup , AsEnumerable , AsQueryable , Cast Generate Range , Repeat , Empty"},{"kind":"cheat","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"2","title":"Deferred vs immediate","body":"Deferred: returns IEnumerable / IQueryable . Immediate: returns a value, collection or element."},{"kind":"cheat","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"3","title":"IEnumerable vs IQueryable","body":"Delegates, in memory vs expression trees, translated to SQL. Keep IQueryable until ToListAsync() ."},{"kind":"cheat","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"4","title":"Classic snippets","body":"csharp list.OrderByDescending(x = x.Salary).Skip(1).First(); // 2nd highest list.GroupBy(x = x.Dept).Select(g = new { g.Key, C = g.Count() }); list.GroupBy(x = x.Email).Where(g = g.Count() 1); // duplicates from c in cs join o in os on c.Id equals o.CId into g from o in g.DefaultIfEmpty() select ...; // left join words.GroupBy(w = w).ToDictionary(g = g.Key, g = g.Count()); // word frequency string.Join(\",\", list.Select(x = x.Name)); nested.SelectMany(x = x.Items);"},{"kind":"cheat","course_slug":"linq","course_title":"LINQ — Language Integrated Query","ref":"5","title":"Pitfalls","body":"ToList() too early · multiple enumeration · Count() 0 instead of Any() · First without OrderBy · N+1 with lazy loading · untranslatable methods in IQueryable · list.Contains in loops (use HashSet )."},{"kind":"course","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"","title":"Entity Framework (EF6 & EF Core)","body":"DbContext, code-first and database-first, conventions and Fluent API, relationships, migrations, querying and loading strategies, change tracking, concurrency, transactions, performance tuning and EF6 vs EF Core. Entity Framework Core (EF Core) is Microsoft's open-source ORM (Object-Relational Mapper) for .NET. You work with C classes (entities) and LINQ; EF Core generates SQL, tracks changes and maps results back to objects. Supported databases (providers): SQL Server / Azure SQL, SQLite, PostgreSQL (Npgsql), MySQL/MariaDB (Pomelo), Oracle, Cosmos DB, In-Memory (testing only). Workflows: - Code-first — write entity classes, generate the schema with migrations (most common for new apps). - Database-first — scaffold classes from an existing DB ( dotnet ef dbcontext scaffold ). EF6 (Entity Framework 6) is the older .NET Framework ORM, now in maintenance; EF Core is the modern rewrite (and EF6 also runs on .NET Core 3.1+ for migration scenarios). Version Year Highlights --- --- --- EF 1.0 → EF 6 2008 → 2013 .NET Framework ORM; EDMX designer, Code First (4.1), migrations (4.3) EF Core 1.0 2016 Rewrite, lightweight, cross-platform EF Core 2.0/2.1 2017/2018 Global query filters, owned types, lazy loading proxies, value conversions EF Core 3.0/3.1 (LTS) 2019 LINQ overhaul — no more silent client evaluation EF Core 5 2020 Many-to-many without join entity, split queries, filtered Include, ToQueryString() EF Core 6 (LTS) 2021 Temporal tables, compiled models, migration bundles, pre-convention config EF Core 7 2022 ExecuteUpdate / ExecuteDelete (bulk), JSON columns, TPC mapping EF Core 8 (LTS) 2023 Complex types (value objects), primitive collections, raw SQL for unmapped types, HierarchyId EF Core 9 2024 Better Cosmos DB, auto-compiled models for AOT (experimental), UseSeeding EF Core 10 (LTS) 2025 Ships with .NET 10: named query filters, LeftJoin / RightJoin translation, vector search for SQL Server, complex types improvements EF Core majors follow .NET's yearly November releases and support policy (even = LTS). DbContext lifecycle (ASP.NET Core): registered scoped → one instance per HTTP request → created via DI → used for queries and changes → SaveChanges() → disposed at the end of the request. A DbContext is a unit of work , not thread-safe , and meant to be short-lived . Entity states (change tracking): State Meaning On SaveChanges --- --- --- Detached Not tracked nothing Added New, Add() called INSERT Unchanged Loaded, not modified nothing Modified Property changed UPDATE (changed columns) Deleted Remove() called DELETE Query lifecycle: LINQ → expression tree → EF query pipeline (translation, cached compiled query) → SQL → DbDataReader → materialise entities → identity resolution (one instance per key per context) → tracked as Unchanged (unless AsNoTracking ). SaveChanges lifecycle: DetectChanges() (snapshot comparison) → order commands by dependencies → begin transaction (implicit) → batch INSERT/UPDATE/DELETE → read back generated values (identity, rowversion) → commit → states become Unchanged . Migration lifecycle: change model → dotnet ef migrations add Name (generates Up/Down C ) → review → dotnet ef database update in dev → in prod apply via SQL script ( migrations script --idempotent ) or migration bundle in CI/CD. Tool Use --- --- dotnet-ef CLI ( dotnet tool install --global dotnet-ef ) migrations, scaffold, bundles, dbcontext optimize Package Manager Console (VS) Add-Migration , Update-Database , Scaffold-DbContext EF Core Power Tools (VS extension) Reverse engineer, diagram the model SQL Server Profiler / Extended Events / Query Store See and tune generated SQL LogTo , EnableSensitiveDataLogging (dev), ToQueryString() Debug queries MiniProfiler, Application Insights Query timing in apps EFCore.BulkExtensions, Z.EntityFramework.Extensions Third-party bulk operations Testcontainers, SQLite Integration tests"},{"kind":"lesson","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"what-an-orm-is-and-ef6-vs-ef-core","title":"What an ORM is, and EF6 vs EF Core","body":"An ORM (object-relational mapper) maps classes to tables and objects to rows, generating SQL so you work with C objects and LINQ instead of DataReader loops. Entity Framework is Microsoft's ORM, in two generations: Entity Framework 6 (EF6) EF Core --- --- --- Released EF 1 (2008, .NET 3.5 SP1) → EF 4.1 Code First (2011) → EF6 (2013) , 6.4/6.5 last 2016 (1.0) → EF Core 10 (2025) Runs on .NET Framework (EF 6.3+ also on .NET Core 3.1+/.NET 5+) .NET Core / .NET 5+ only Status Maintenance only (bug/security fixes) Active — new features every year Modelling EDMX designer (Database First / Model First, XML model: CSDL + SSDL + MSL) or Code First Code First only (plus reverse engineering with dotnet ef dbcontext scaffold ) Context API DbContext (wrapper over the older ObjectContext ) DbContext only Lazy loading On by default (virtual navigation properties) Off by default (opt-in proxies) Performance Slower Much faster (compiled queries, batching, no-tracking, split queries) Extras Spatial, entity splitting, stored-proc mapping in EDMX Global query filters, owned/complex types, JSON columns, bulk ExecuteUpdate/ExecuteDelete , temporal tables, interceptors, many providers (SQL Server, PostgreSQL, SQLite, Cosmos DB) EF6 Database First with EDMX (legacy apps): Add → ADO.NET Entity Data Model → \"EF Designer from database\" → pick tables/procedures → Visual Studio generates ShopModel.edmx (diagram) + T4 templates that generate entity classes and a ShopEntities : DbContext . Changing the database means \"Update Model from Database\" in the designer. The connection string contains metadata ( metadata=res:// /ShopModel.csdl ...;provider=System.Data.SqlClient;provider connection string=\"...\" ). csharp // EF6 (System.Data.Entity) — .NET Framework MVC 5 / Web Forms using (var db = new ShopEntities()) { var orders = db.Orders.Include(o = o.Customer).Where(o = o.Total 1000).ToList(); // Include(lambda) needs System.Data.Entity db.Orders.Add(new Order { CustomerId = 42, Total = 4500 }); db.SaveChanges(); } csharp // EF Core (Microsoft.EntityFrameworkCore) — same idea, modern API await using var db = new ShopDbContext(options); var orders = await db.Orders.Include(o = o.Customer).Where(o = o.Total 1000).AsNoTracking().ToListAsync(); Migrating EF6 → EF Core: move EDMX models to code-first classes (scaffold from the database), replace System.Data.Entity namespaces, review lazy-loading assumptions (add explicit Include ), re-test queries that EF Core translates differently (client evaluation is no longer silent), replace EF6-only features (EDMX stored-procedure mapping, entity splitting differences), and adopt EF Core migrations from a baseline. Interview tip: \"Code First vs Database First\": Code First — classes are the source of truth and migrations create/alter the database; Database First — the existing database is the source of truth and the model is generated from it (EDMX in EF6, scaffolding in EF Core)."},{"kind":"lesson","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"dbcontext-dbset-and-configuration","title":"DbContext, DbSet and configuration","body":"csharp public class AppDbContext(DbContextOptions<AppDbContext options) : DbContext(options) { public DbSet<Customer Customers = Set<Customer (); public DbSet<Order Orders = Set<Order (); protected override void OnModelCreating(ModelBuilder b) { b.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly); // IEntityTypeConfiguration<T classes } } public class Customer { public int Id { get; set; } // convention: primary key public required string Name { get; set; } public string? Email { get; set; } public List<Order Orders { get; set; } = []; // navigation (one-to-many) } public class Order { public int Id { get; set; } public int CustomerId { get; set; } // foreign key by convention public Customer Customer { get; set; } = null!; public decimal Total { get; set; } public DateTime CreatedAt { get; set; } } // Program.cs builder.Services.AddDbContext<AppDbContext (o = o.UseSqlServer(builder.Configuration.GetConnectionString(\"Db\"), sql = sql.EnableRetryOnFailure())); AddDbContextPool reuses context instances for high-throughput apps; AddDbContextFactory + IDbContextFactory<T for Blazor Server, background services and parallel work."},{"kind":"lesson","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"code-first-vs-database-first-and-migrations","title":"Code-first vs database-first and migrations","body":"bash dotnet tool install --global dotnet-ef dotnet add package Microsoft.EntityFrameworkCore.SqlServer dotnet add package Microsoft.EntityFrameworkCore.Design dotnet ef migrations add InitialCreate creates Migrations/xxxx InitialCreate.cs + model snapshot dotnet ef database update applies pending migrations ( EFMigrationsHistory table) dotnet ef migrations remove removes the last, unapplied migration dotnet ef migrations script --idempotent -o deploy.sql SQL for DBAs / pipelines dotnet ef migrations bundle --self-contained executable that applies migrations (CI/CD) database-first (scaffold) dotnet ef dbcontext scaffold \"Server=.;Database=Legacy;Trusted Connection=True;TrustServerCertificate=True\" \\ Microsoft.EntityFrameworkCore.SqlServer -o Models --context LegacyContext - Migrations are C classes with Up() and Down() ; review them — renames may be generated as drop + add (data loss). - In production prefer idempotent scripts or bundles applied by the pipeline over Database.Migrate() at app start (race conditions with multiple instances, permissions)."},{"kind":"lesson","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"conventions-data-annotations-and-fluent-api","title":"Conventions, data annotations and Fluent API","body":"Configuration precedence: Fluent API Data Annotations Conventions . csharp // Data annotations public class Product { public int Id { get; set; } [Required, MaxLength(200)] public string Name { get; set; } = \"\"; [Column(TypeName = \"decimal(18,2)\")] public decimal Price { get; set; } [Timestamp] public byte[] RowVersion { get; set; } = []; } // Fluent API (keeps entities clean; more powerful) public class ProductConfig : IEntityTypeConfiguration<Product { public void Configure(EntityTypeBuilder<Product b) { b.ToTable(\"Products\", \"catalog\"); b.HasKey(p = p.Id); b.Property(p = p.Name).IsRequired().HasMaxLength(200); b.Property(p = p.Price).HasPrecision(18, 2); b.HasIndex(p = p.Name).IsUnique(); b.Property(p = p.RowVersion).IsRowVersion(); b.HasQueryFilter(p = !p.IsDeleted); // global query filter (soft delete) } } Fluent-only features: composite keys ( HasKey(x = new { x.A, x.B }) ), indexes, sequences, table splitting, owned types, value conversions, query filters, seed data ( HasData ), inheritance mapping."},{"kind":"lesson","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"one-to-one-one-to-many-many-to-many","title":"One-to-one, one-to-many, many-to-many","body":"csharp // One-to-many: Customer 1 — Order b.Entity<Order ().HasOne(o = o.Customer).WithMany(c = c.Orders) .HasForeignKey(o = o.CustomerId).OnDelete(DeleteBehavior.Restrict); // One-to-one: User 1 — 1 Profile (dependent has the FK) b.Entity<User ().HasOne(u = u.Profile).WithOne(p = p.User).HasForeignKey<Profile (p = p.UserId); // Many-to-many (EF Core 5+): skip navigations, join table created automatically public class Student { public int Id { get; set; } public List<Course Courses { get; set; } = []; } public class Course { public int Id { get; set; } public List<Student Students { get; set; } = []; } // Many-to-many with payload → explicit join entity public class Enrollment { public int StudentId { get; set; } public int CourseId { get; set; } public DateTime EnrolledOn { get; set; } } Delete behaviours: Cascade (default for required relationships), Restrict / NoAction , SetNull , ClientSetNull . SQL Server rejects multiple cascade paths — use Restrict on one."},{"kind":"lesson","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"owned-types-complex-types-value-conversions-and-inheritance","title":"Owned types, complex types, value conversions and inheritance","body":"csharp // Value object stored in the owner's table (Address City, Address Street columns) b.Entity<Customer ().OwnsOne(c = c.Address); // owned entity b.Entity<Customer ().ComplexProperty(c = c.Address); // EF Core 8 complex type (true value semantics) // Enum stored as string b.Entity<Order ().Property(o = o.Status).HasConversion<string ().HasMaxLength(20); // JSON column (EF Core 7+) b.Entity<Order ().OwnsOne(o = o.Metadata, m = m.ToJson()); Inheritance strategies: Strategy Tables Pros/cons --- --- --- TPH — Table per Hierarchy (default) One table + discriminator column Fastest queries; nullable columns TPT — Table per Type Base table + one per derived type Normalised; joins make it slower TPC — Table per Concrete type (EF 7) One table per concrete class No joins for concrete queries; IDs must be unique across tables"},{"kind":"lesson","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"querying-tracking-vs-no-tracking","title":"Querying, tracking vs no-tracking","body":"csharp var c = await db.Customers.FindAsync(5); // checks the change tracker first, then DB var active = await db.Customers.Where(x = x.IsActive).OrderBy(x = x.Name).ToListAsync(ct); // Read-only: skip change tracking (faster, less memory) var list = await db.Products.AsNoTracking().Where(p = p.Price 100).ToListAsync(ct); // Projection — best for read models; selects only needed columns, never tracked var dtos = await db.Orders .Where(o = o.CreatedAt = from) .Select(o = new OrderDto(o.Id, o.Customer.Name, o.Total)) .ToListAsync(ct); AsNoTrackingWithIdentityResolution() — no tracking but still one instance per key. Configure default: UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking) for read-heavy contexts."},{"kind":"lesson","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"loading-related-data-eager-explicit-lazy","title":"Loading related data: eager, explicit, lazy","body":"csharp // Eager loading var orders = await db.Orders .Include(o = o.Customer) .Include(o = o.Lines.Where(l = l.Qty 0)) // filtered include (EF 5) .ThenInclude(l = l.Product) .AsSplitQuery() // avoid cartesian explosion with multiple collections .ToListAsync(); // Explicit loading var customer = await db.Customers.FirstAsync(c = c.Id == id); await db.Entry(customer).Collection(c = c.Orders).LoadAsync(); await db.Entry(order).Reference(o = o.Customer).LoadAsync(); // Lazy loading (opt-in): Microsoft.EntityFrameworkCore.Proxies + UseLazyLoadingProxies(); virtual navigations When loaded Risk --- --- --- Eager ( Include ) Same query Cartesian explosion with several collections → AsSplitQuery Explicit When you call Load Extra round trips, but controlled Lazy On first access of navigation N+1 queries , hidden DB calls, serialisation loops"},{"kind":"lesson","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"raw-sql-stored-procedures-and-bulk-operations","title":"Raw SQL, stored procedures and bulk operations","body":"csharp // Raw SQL returning entities — interpolation is parameterised (safe) var big = await db.Orders.FromSql($\"SELECT FROM Orders WHERE Total {minTotal}\").Where(o = o.Status == \"Open\").ToListAsync(); // Unmapped types (EF Core 8) var rows = await db.Database.SqlQuery<SalesRow ($\"EXEC dbo.usp SalesByMonth @Year = {year}\").ToListAsync(); // Non-query await db.Database.ExecuteSqlAsync($\"UPDATE Products SET Price = Price {factor} WHERE CategoryId = {cat}\"); // Set-based bulk update/delete without loading entities (EF Core 7) await db.Orders.Where(o = o.CreatedAt < cutoff && o.Status == \"Draft\").ExecuteDeleteAsync(ct); await db.Products.Where(p = p.CategoryId == 3) .ExecuteUpdateAsync(s = s.SetProperty(p = p.Price, p = p.Price 1.1m), ct); FromSqlRaw / ExecuteSqlRaw take a string + parameters — never concatenate user input into them. ExecuteUpdate/Delete bypass the change tracker (tracked entities become stale) and run immediately."},{"kind":"lesson","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"add-update-delete-and-savechanges","title":"Add, update, delete and SaveChanges","body":"csharp // Add db.Customers.Add(new Customer { Name = \"Acme\" }); await db.SaveChangesAsync(ct); // Update — tracked (connected) scenario var p = await db.Products.FindAsync(id); p!.Price = 499; // change tracker notices await db.SaveChangesAsync(ct); // UPDATE Products SET Price = @p0 WHERE Id = @p1 // Update — disconnected (e.g. DTO from API) db.Products.Update(product); // marks ALL properties modified db.Entry(product).Property(x = x.Price).IsModified = true; // or mark only specific ones // Delete db.Products.Remove(p); await db.SaveChangesAsync(ct); SaveChanges wraps all pending changes in one transaction and batches statements (SQL Server default batch up to 42 statements). Interceptors ( SaveChangesInterceptor ) or overriding SaveChangesAsync are common for audit fields ( CreatedAt , ModifiedBy )."},{"kind":"lesson","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"concurrency-control","title":"Concurrency control","body":"csharp public class Product { public int Id { get; set; } public decimal Price { get; set; } [Timestamp] public byte[] RowVersion { get; set; } = []; // SQL Server rowversion } try { product.Price = newPrice; await db.SaveChangesAsync(); // UPDATE ... WHERE Id = @id AND RowVersion = @originalVersion } catch (DbUpdateConcurrencyException ex) { var entry = ex.Entries.Single(); var dbValues = await entry.GetDatabaseValuesAsync(); // options: client wins (refresh original values and retry), store wins (reload), or ask the user to merge } Optimistic concurrency (rowversion / IsConcurrencyToken() ): no locks; detect conflicts on save — default choice for web apps. Pessimistic (locks: SELECT ... WITH (UPDLOCK) , serializable transactions): prevents conflicts but reduces throughput."},{"kind":"lesson","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"transactions","title":"Transactions","body":"csharp await using var tx = await db.Database.BeginTransactionAsync(ct); try { db.Orders.Add(order); await db.SaveChangesAsync(ct); // gets order.Id await db.Inventory.Where(i = i.ProductId == pid).ExecuteUpdateAsync(s = s.SetProperty(i = i.Qty, i = i.Qty - qty), ct); await tx.CommitAsync(ct); } catch { await tx.RollbackAsync(ct); throw; } With EnableRetryOnFailure , user-initiated transactions must run inside an execution strategy: await db.Database.CreateExecutionStrategy().ExecuteAsync(async () = { ... }) . Savepoints are created automatically by SaveChanges inside an explicit transaction."},{"kind":"lesson","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"ef-core-performance-checklist","title":"EF Core performance checklist","body":"1. Project with Select — fetch only needed columns. 2. AsNoTracking for read-only queries. 3. Avoid N+1 — no lazy loading in loops; Include or projection. 4. AsSplitQuery for multiple collection includes (cartesian explosion). 5. Paginate ; never load whole tables. 6. Indexes for filters/joins/order-bys ( HasIndex ). 7. ExecuteUpdate / ExecuteDelete for set-based changes. 8. AddDbContextPool and compiled queries ( EF.CompileAsyncQuery ) for hot paths. 9. Keep contexts short-lived; don't track thousands of entities (DetectChanges cost). 10. Check generated SQL ( ToQueryString , logging) and execution plans; drop to Dapper/raw SQL for complex reports. 11. Avoid client-side ToList() before Where . 12. Use AnyAsync for existence, CountAsync only when needed. csharp private static readonly Func<AppDbContext, int, Task<Product? GetById = EF.CompileAsyncQuery((AppDbContext db, int id) = db.Products.FirstOrDefault(p = p.Id == id));"},{"kind":"lesson","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"global-query-filters-interceptors-shadow-properties-and-temporal-tables","title":"Global query filters, interceptors, shadow properties and temporal tables","body":"csharp // Soft delete + multi-tenancy filter b.Entity<Order ().HasQueryFilter(o = !o.IsDeleted && o.TenantId == tenantId); db.Orders.IgnoreQueryFilters(); // bypass when needed // Shadow property: exists in the model/table but not in the class b.Entity<Order ().Property<DateTime (\"LastUpdated\"); db.Entry(order).Property(\"LastUpdated\").CurrentValue = DateTime.UtcNow; // Audit interceptor public class AuditInterceptor(TimeProvider clock) : SaveChangesInterceptor { public override ValueTask<InterceptionResult<int SavingChangesAsync(DbContextEventData e, InterceptionResult<int r, CancellationToken ct = default) { foreach (var entry in e.Context!.ChangeTracker.Entries<IAuditable ()) if (entry.State is EntityState.Added or EntityState.Modified) entry.Entity.UpdatedAt = clock.GetUtcNow(); return base.SavingChangesAsync(e, r, ct); } } // SQL Server temporal tables (EF Core 6) b.Entity<Product ().ToTable(t = t.IsTemporal()); var asOf = await db.Products.TemporalAsOf(DateTime.UtcNow.AddDays(-7)).ToListAsync();"},{"kind":"lesson","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"testing-code-that-uses-ef-core","title":"Testing code that uses EF Core","body":"- In-Memory provider — fast but not relational (no SQL, no constraints, no transactions); Microsoft discourages it for testing DB behaviour. - SQLite in-memory ( DataSource=:memory: ) — relational, fast; some SQL Server differences. - Testcontainers with real SQL Server — most accurate; slower startup (share one container per test run, reset with Respawn). - Or hide EF behind repositories and mock those for unit tests of business logic."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"287","title":"What is Entity Framework Core and what are its advantages?","body":"An open-source, cross-platform ORM that maps C classes to database tables. You query with LINQ and EF generates parameterised SQL, tracks changes and saves them in a transaction. Advantages: productivity (less data-access boilerplate), strong typing and compile-time checks, migrations for schema evolution, multiple DB providers, built-in protection from SQL injection, relationships and change tracking handled for you. Trade-offs: generated SQL must be monitored for performance; complex reports may be better in raw SQL/Dapper."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"288","title":"Code-first vs database-first?","body":"Code-first: you design entity classes and DbContext; migrations create and evolve the schema — the model is the source of truth (common for new projects). Database-first: the database exists (or DBAs own it); you scaffold entities and context from it with dotnet ef dbcontext scaffold and re-scaffold when the schema changes. EF Core has no EDMX designer (that was EF6)."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"289","title":"What is DbContext? Is it thread-safe? What lifetime should it have?","body":"DbContext represents a session with the database: it holds DbSets, the change tracker, configuration, and implements unit of work ( SaveChanges ). It is not thread-safe — never share it across concurrent operations (no parallel await s on the same context). Register it scoped in ASP.NET Core (one per request) and keep it short-lived; use IDbContextFactory for background services, Blazor Server or parallel work."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"290","title":"What are migrations? What commands do you use?","body":"Migrations are versioned C files describing schema changes (Up/Down), generated by comparing the current model with the model snapshot. Commands: dotnet ef migrations add <Name , dotnet ef database update [target] , dotnet ef migrations remove , dotnet ef migrations list , dotnet ef migrations script --idempotent , dotnet ef migrations bundle . Applied migrations are recorded in EFMigrationsHistory ."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"291","title":"What is the difference between eager, lazy and explicit loading?","body":"Eager: related data loaded in the same query with Include / ThenInclude . Explicit: load later on demand with Entry(x).Collection(...).Load() / .Reference(...).Load() . Lazy: navigation properties load automatically on first access (needs proxies or ILazyLoader , virtual navigations) — convenient but causes hidden N+1 queries. Projections ( Select ) are often better than any of them for read models."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"292","title":"What is the difference between `Find` and `FirstOrDefault`?","body":"Find(key) looks up by primary key and first checks the change tracker — if the entity is already tracked, no DB query is sent. FirstOrDefault(predicate) always queries the database (with any predicate) and supports Include /ordering. Find can't use Include ."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"293","title":"What is change tracking? What is AsNoTracking?","body":"When EF loads entities it keeps a snapshot of their original values. On SaveChanges , DetectChanges compares current vs original values and generates UPDATEs for changed columns; entity states drive INSERT/DELETE. AsNoTracking() skips this — faster and less memory for read-only queries, but changes to those objects won't be saved unless you attach them."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"294","title":"Explain entity states in EF Core.","body":"Detached (not tracked), Added (INSERT on save), Unchanged (loaded, no changes), Modified (UPDATE on save), Deleted (DELETE on save). Inspect/set with db.Entry(entity).State . Attach → Unchanged; Update → Modified (all properties); Add → Added; Remove → Deleted (or detached if it was Added). After a successful save, Added/Modified become Unchanged and Deleted become Detached."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"295","title":"What is the N+1 problem and how do you avoid it in EF Core?","body":"Loading N parent entities with one query and then triggering one query per parent for its related data (usually lazy loading in a loop or view). Avoid by eager loading ( Include ), projecting into DTOs with the needed related fields in one query, using AsSplitQuery when including collections, and disabling lazy loading. Detect via SQL logging or profilers showing many similar queries."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"296","title":"How does EF Core handle concurrency?","body":"Optimistic concurrency via concurrency tokens: a [Timestamp] / IsRowVersion() rowversion column (SQL Server updates it automatically) or IsConcurrencyToken() on specific properties. EF adds the original value to the UPDATE/DELETE WHERE clause; if 0 rows are affected it throws DbUpdateConcurrencyException , which you handle by reloading, overwriting (client wins) or merging. No database locks are held between read and write."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"297","title":"How do you configure relationships? Data annotations vs Fluent API?","body":"By convention (navigation properties + XxxId FK), data annotations ( [ForeignKey] , [InverseProperty] , [Required] ), or Fluent API ( HasOne/WithMany/HasForeignKey/OnDelete ). Fluent API has the highest precedence, keeps domain classes free of persistence attributes and supports everything (composite keys, indexes, delete behaviour, owned types, filters). Organise it in IEntityTypeConfiguration<T classes."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"298","title":"What are global query filters? Give use cases.","body":"LINQ predicates configured per entity type in OnModelCreating ( HasQueryFilter ) that EF automatically adds to every query for that type — e.g. soft delete ( !IsDeleted ) and multi-tenancy ( TenantId == currentTenant ). Bypass with IgnoreQueryFilters() . EF Core 10 adds named filters so you can disable them individually."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"299","title":"How do you execute raw SQL or stored procedures in EF Core?","body":"FromSql($\"...\") (interpolated → parameterised) or FromSqlRaw(sql, params) on a DbSet returns entities and can be composed with LINQ (if the SQL is composable). Database.SqlQuery<T ($\"...\") returns unmapped types (EF 8). Database.ExecuteSql($\"...\") / ExecuteSqlRaw for non-queries/stored procedures. Never concatenate user input into the raw variants."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"300","title":"What are ExecuteUpdate and ExecuteDelete?","body":"EF Core 7 set-based operations that translate directly into a single UPDATE / DELETE ... WHERE statement without loading entities into memory or using the change tracker — e.g. db.Orders.Where(o = o.Expired).ExecuteDeleteAsync() . Much faster for bulk changes. Caveats: they run immediately (not part of SaveChanges unless inside an explicit transaction) and tracked entities aren't updated."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"301","title":"How do you improve EF Core query performance?","body":"Project only needed columns; AsNoTracking ; avoid N+1 and lazy loading; AsSplitQuery for multiple collection includes; paginate; add indexes for filters and sorts; set-based ExecuteUpdate/Delete ; compiled queries and DbContext pooling for hot paths; check generated SQL and execution plans; avoid client evaluation; batch writes; keep contexts small; cache read-mostly data; and use Dapper or views/stored procedures for complex reporting queries."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"302","title":"What is the difference between `Update()` and attaching then setting properties?","body":"db.Update(entity) attaches a detached entity and marks all properties as Modified → UPDATE writes every column (can overwrite concurrent changes in other columns). Loading the entity and setting properties (or Attach + marking specific properties IsModified = true ) updates only changed columns. In APIs, prefer loading → mapping the DTO onto the tracked entity → saving, with a concurrency token."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"303","title":"EF Core vs EF6 — key differences?","body":"EF Core: cross-platform, lighter, faster, supports more DB providers incl. Cosmos, has features like global query filters, ExecuteUpdate , JSON columns, compiled models, split queries; no EDMX designer, no ObjectContext. EF6: .NET Framework-centric (also runs on .NET Core 3.1+), EDMX/database-first designer, mature but maintenance only. New development should use EF Core."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"304","title":"A page listing 50 orders takes 5 seconds and the log shows 51 SQL queries. Fix it.","body":"Classic N+1: one query for orders and one per order for its customer (lazy loading). Replace with a single projection: db.Orders.AsNoTracking().OrderByDescending(o = o.CreatedAt).Take(50).Select(o = new OrderRow(o.Id, o.Customer.Name, o.Total)).ToListAsync() → one SQL with a JOIN. Disable lazy loading globally, add an index on CreatedAt , and confirm with logging that only one query runs."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"305","title":"Two users edit the same product price at the same time and the later save silently overwrites the earlier one. How do you prevent lost updates?","body":"Add a rowversion concurrency token ( [Timestamp] byte[] RowVersion ). Send the RowVersion to the client with the data and back on update; set it as the original value ( db.Entry(p).Property(x = x.RowVersion).OriginalValue = dto.RowVersion ). If someone else saved first, EF throws DbUpdateConcurrencyException ; return 409 Conflict (or 412 with ETags) with the current values so the user can review and retry."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"306","title":"You need to delete 5 million log rows older than 90 days nightly without blocking the app. What do you do?","body":"Don't load entities. Use ExecuteDeleteAsync in batches (e.g. loop deleting Take(10 000) by key range or TOP (10000) raw SQL until 0 rows) to keep transactions small and avoid lock escalation and log growth; run off-peak via a background job; ensure an index on the date column. Better long-term: table partitioning by month and TRUNCATE /switch out old partitions, or a retention policy in a time-series store."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"307","title":"Deploying a migration renamed a column and dropped production data. How do you prevent this?","body":"EF scaffolded the rename as drop + add. Prevention: always review generated migrations; use migrationBuilder.RenameColumn explicitly (or HasColumnName to keep the DB name); apply schema changes through reviewed idempotent SQL scripts in the pipeline with a DBA/peer review; take backups before deploying; use expand-contract (add new column → backfill → switch code → drop old later) for zero-downtime changes; test migrations against a production-like copy."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"308","title":"A BackgroundService throws \"A second operation was started on this context instance before a previous operation completed.\" Why?","body":"The same DbContext was used concurrently — e.g. parallel tasks ( Task.WhenAll ) or a singleton service holding one context. DbContext isn't thread-safe. Fix: create a new scope/context per unit of work ( IServiceScopeFactory or IDbContextFactory<T .CreateDbContext() per task), and await each operation before starting the next on the same context."},{"kind":"question","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"309","title":"What is the difference between DbContext and ObjectContext?","body":"ObjectContext was the original Entity Framework (EF 1–4) API: verbose, tied to EDMX models and ObjectSet<T . DbContext (EF 4.1+) is a simpler, lightweight wrapper over ObjectContext with DbSet<T , Code First, change tracking via ChangeTracker and easy configuration; you could still reach the ObjectContext through IObjectContextAdapter in EF6. EF Core has only DbContext — ObjectContext doesn't exist there."},{"kind":"cheat","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"1","title":"Setup","body":"bash dotnet add package Microsoft.EntityFrameworkCore.SqlServer dotnet add package Microsoft.EntityFrameworkCore.Design dotnet tool install -g dotnet-ef dotnet ef migrations add Init dotnet ef database update dotnet ef migrations script --idempotent -o deploy.sql dotnet ef dbcontext scaffold \"<conn \" Microsoft.EntityFrameworkCore.SqlServer -o Models"},{"kind":"cheat","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"2","title":"Entity states","body":"Detached · Added → INSERT · Unchanged · Modified → UPDATE · Deleted → DELETE."},{"kind":"cheat","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"3","title":"Loading","body":"Include/ThenInclude (eager) · Entry().Collection().Load() (explicit) · lazy proxies (avoid) · Select projection (best for reads) · AsSplitQuery ."},{"kind":"cheat","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"4","title":"Query tips","body":"AsNoTracking · Select DTOs · AnyAsync · paginate Skip/Take · ToQueryString() · FromSql($\"\") · SqlQuery<T · ExecuteUpdate/Delete · EF.CompileAsyncQuery · IgnoreQueryFilters ."},{"kind":"cheat","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"5","title":"Configuration precedence","body":"Fluent API Data Annotations Conventions. Use IEntityTypeConfiguration<T ."},{"kind":"cheat","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"6","title":"Relationships","body":"HasOne().WithMany().HasForeignKey().OnDelete() · HasOne().WithOne().HasForeignKey<T () · many-to-many via skip navigations · owned/complex types · TPH (default) / TPT / TPC."},{"kind":"cheat","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"7","title":"Concurrency & transactions","body":"[Timestamp] byte[] RowVersion → DbUpdateConcurrencyException → 409 · SaveChanges = one transaction · BeginTransactionAsync for multiple saves · execution strategy with retries."},{"kind":"cheat","course_slug":"efcore","course_title":"Entity Framework (EF6 & EF Core)","ref":"8","title":"DbContext rules","body":"Scoped · short-lived · not thread-safe · IDbContextFactory for background/parallel · AddDbContextPool for throughput."},{"kind":"course","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"","title":"Dapper — The Micro-ORM from Basics to Advanced","body":"What Dapper is and how it works inside, Query/QueryFirst/QuerySingle/Execute, parameters and SQL injection safety, stored procedures and output parameters, multi-mapping joins, QueryMultiple, transactions, bulk inserts and table-valued parameters, async and buffering, custom type handlers, DynamicParameters, repository and unit-of-work patterns, Dapper vs EF Core vs ADO.NET, performance and testing. Dapper is a lightweight object mapper (\"micro-ORM\") created by Stack Overflow (Sam Saffron and Marc Gravell, 2011). It adds extension methods to IDbConnection that run your SQL and map the results to objects — nearly as fast as hand-written ADO.NET, with a fraction of the code. ADO.NET Dapper EF Core --- --- --- --- You write SQL Yes Yes No (LINQ → SQL), optional raw SQL Mapping rows to objects Manual ( reader[\"Name\"] ) Automatic by column name Automatic Change tracking, migrations, relationships No No Yes Performance Fastest (manual) ~Same as ADO.NET Good, more overhead Code volume High Low Lowest for CRUD Best for Special cases, bulk Reports, read-heavy APIs, stored procedures, performance-critical paths Domain models, CRUD, complex writes Many teams combine them: EF Core for writes, Dapper for complex reads/reports (CQRS-lite). Year Milestone --- --- 2011 Dapper open-sourced by Stack Overflow 2012–2016 Multi-mapping, QueryMultiple, async methods, .NET Core support 2017 Dapper 1.50+ for .NET Standard 2019 Dapper 2.0 — modern target frameworks 2023 Dapper 2.1 — AOT-friendlier work begins; Dapper.AOT (source-generated, no runtime reflection emit) 2024–2025 Dapper 2.1.x maintained; works with Microsoft.Data.SqlClient , Npgsql, MySqlConnector, SQLite Related packages: Dapper.Contrib / Dapper.SimpleCRUD (generated CRUD), Dapper.AOT , DapperQueryBuilder , Dapper.Bulk . What happens when you call connection.Query<Order (sql, new { CustomerId = 42 }) : 1. Dapper builds a cache key from the SQL text, the parameter object's type and the result type. 2. First time only: it generates (via IL emit / compiled code) a parameter writer that turns the anonymous object's properties into DbParameter s, and a row mapper that reads a DbDataReader row into an Order by matching column names to properties/constructor parameters. These are cached — later calls are fast. 3. Opens the connection if it is closed (and closes it again afterwards). 4. Creates a DbCommand , adds parameters, executes ExecuteReader . 5. Maps each row with the cached mapper; with buffered: true (default) it reads all rows into a List<T before returning. 6. Disposes the reader and command. - NuGet: Dapper , Microsoft.Data.SqlClient (SQL Server), Npgsql , MySqlConnector , Microsoft.Data.Sqlite . - SQL Server Management Studio / Azure Data Studio for writing and tuning SQL; actual execution plans. - MiniProfiler (also from Stack Overflow) to see SQL timings per request. - Testcontainers (real SQL Server in Docker) for integration tests."},{"kind":"lesson","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"setup-and-the-core-methods","title":"Setup and the core methods","body":"csharp // dotnet add package Dapper // dotnet add package Microsoft.Data.SqlClient using Dapper; using Microsoft.Data.SqlClient; public record Product(int Id, string Name, string Category, decimal Price); await using var conn = new SqlConnection(connectionString); // Many rows IEnumerable<Product all = await conn.QueryAsync<Product (\"SELECT Id, Name, Category, Price FROM dbo.Products\"); // Exactly one row expected Product p = await conn.QuerySingleAsync<Product (\"SELECT FROM dbo.Products WHERE Id = @Id\", new { Id = 5 }); // First or nothing Product? maybe = await conn.QueryFirstOrDefaultAsync<Product ( \"SELECT TOP 1 FROM dbo.Products WHERE Category = @Cat ORDER BY Price\", new { Cat = \"Pens\" }); // Scalar value int count = await conn.ExecuteScalarAsync<int (\"SELECT COUNT( ) FROM dbo.Products\"); // INSERT/UPDATE/DELETE — returns affected rows int rows = await conn.ExecuteAsync(\"UPDATE dbo.Products SET Price = Price 1.1 WHERE Category = @Cat\", new { Cat = \"Pens\" }); // Insert and get the new id int newId = await conn.QuerySingleAsync<int ( \"INSERT INTO dbo.Products (Name, Category, Price) OUTPUT INSERTED.Id VALUES (@Name, @Category, @Price)\", new { Name = \"Gel pen\", Category = \"Pens\", Price = 25m }); Method Rows expected Throws when --- --- --- Query<T 0..n — QueryFirst<T ≥ 1 (takes first) 0 rows QueryFirstOrDefault<T 0..n (takes first) — QuerySingle<T exactly 1 0 or 1 rows QuerySingleOrDefault<T 0 or 1 1 rows Execute — (returns affected count) — ExecuteScalar<T first column of first row — Mapping rules: column names match property names case-insensitively; use SQL aliases when names differ ( SELECT ProductName AS Name ); records/classes with constructors are matched by parameter names; set DefaultTypeMap.MatchNamesWithUnderscores = true to map product name → ProductName ."},{"kind":"lesson","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"parameters-sql-injection-and-in-lists","title":"Parameters, SQL injection and IN lists","body":"Dapper always sends values as real parameters — never concatenate user input into SQL. csharp // ❌ SQL injection: name = \"x'; DROP TABLE Products;--\" var bad = conn.Query<Product ($\"SELECT FROM Products WHERE Name = '{name}'\"); // ✅ parameterised var good = conn.Query<Product (\"SELECT FROM Products WHERE Name = @name\", new { name }); // IN list: Dapper expands a collection into (@ids1, @ids2, ...) var some = conn.Query<Product (\"SELECT FROM Products WHERE Id IN @ids\", new { ids = new[] { 1, 2, 3 } }); // Explicit types/sizes with DynamicParameters (helps plan caching for strings) var p = new DynamicParameters(); p.Add(\"@Name\", name, DbType.String, size: 200); p.Add(\"@Category\", new DbString { Value = cat, IsAnsi = true, Length = 100 }); // VARCHAR, avoids implicit conversion var result = conn.Query<Product (\"SELECT FROM Products WHERE Name = @Name AND Category = @Category\", p); Dynamic sort columns or table names can't be parameters — whitelist them: csharp string orderBy = sort switch { \"price\" = \"Price\", \"name\" = \"Name\", = \"Id\" }; // never use raw input var sql = $\"SELECT FROM Products ORDER BY {orderBy} OFFSET @Skip ROWS FETCH NEXT @Take ROWS ONLY\";"},{"kind":"lesson","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"stored-procedures-output-parameters-and-return-values","title":"Stored procedures, output parameters and return values","body":"csharp var p = new DynamicParameters(); p.Add(\"@CustomerId\", 42); p.Add(\"@FromDate\", new DateTime(2026, 1, 1)); p.Add(\"@TotalCount\", dbType: DbType.Int32, direction: ParameterDirection.Output); p.Add(\"@ReturnValue\", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue); var orders = await conn.QueryAsync<OrderDto (\"dbo.usp GetCustomerOrders\", p, commandType: CommandType.StoredProcedure); int total = p.Get<int (\"@TotalCount\"); // read after the reader is consumed int ret = p.Get<int (\"@ReturnValue\"); sql CREATE OR ALTER PROCEDURE dbo.usp GetCustomerOrders @CustomerId INT, @FromDate DATE, @TotalCount INT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @TotalCount = COUNT( ) FROM dbo.Orders WHERE CustomerId = @CustomerId AND OrderDate = @FromDate; SELECT Id, OrderDate, Total FROM dbo.Orders WHERE CustomerId = @CustomerId AND OrderDate = @FromDate ORDER BY OrderDate DESC; RETURN 0; END"},{"kind":"lesson","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"multi-mapping-joins-into-object-graphs","title":"Multi-mapping — joins into object graphs","body":"csharp public class Order { public int Id { get; set; } public DateTime OrderDate { get; set; } public Customer Customer { get; set; } = null!; public List<OrderLine Lines { get; } = []; } public class Customer { public int Id { get; set; } public string Name { get; set; } = \"\"; } public class OrderLine { public int Id { get; set; } public string Product { get; set; } = \"\"; public int Qty { get; set; } } // One-to-one: Order + Customer var sql = @\"SELECT o.Id, o.OrderDate, c.Id, c.Name FROM dbo.Orders o JOIN dbo.Customers c ON c.Id = o.CustomerId\"; var orders = await conn.QueryAsync<Order, Customer, Order (sql, (order, customer) = { order.Customer = customer; return order; }, splitOn: \"Id\"); // where the second object's columns start (default \"Id\") // One-to-many: Orders + Lines — de-duplicate parents with a dictionary var lookup = new Dictionary<int, Order (); var sql2 = @\"SELECT o.Id, o.OrderDate, l.Id, l.Product, l.Qty FROM dbo.Orders o JOIN dbo.OrderLines l ON l.OrderId = o.Id WHERE o.CustomerId = @cid\"; await conn.QueryAsync<Order, OrderLine, Order (sql2, (o, l) = { if (!lookup.TryGetValue(o.Id, out var existing)) lookup[o.Id] = existing = o; existing.Lines.Add(l); return existing; }, new { cid = 42 }, splitOn: \"Id\"); var result = lookup.Values.ToList(); splitOn names the first column of each subsequent object; if your second table's key isn't called Id , pass its column name (e.g. splitOn: \"CustomerId\" )."},{"kind":"lesson","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"querymultiple-transactions-and-bulk-operations","title":"QueryMultiple, transactions and bulk operations","body":"csharp // Several result sets in one round trip using (var multi = await conn.QueryMultipleAsync(@\" SELECT FROM dbo.Customers WHERE Id = @id; SELECT FROM dbo.Orders WHERE CustomerId = @id; SELECT COUNT( ) FROM dbo.Complaints WHERE CustomerId = @id;\", new { id = 42 })) { var customer = await multi.ReadSingleAsync<Customer (); var orders = (await multi.ReadAsync<Order ()).ToList(); var complaints = await multi.ReadSingleAsync<int (); } // Transactions await conn.OpenAsync(); await using var tx = await conn.BeginTransactionAsync(); try { var orderId = await conn.QuerySingleAsync<int ( \"INSERT INTO dbo.Orders (CustomerId, OrderDate) OUTPUT INSERTED.Id VALUES (@cid, SYSUTCDATETIME())\", new { cid = 42 }, tx); await conn.ExecuteAsync(\"INSERT INTO dbo.OrderLines (OrderId, Product, Qty) VALUES (@orderId, @Product, @Qty)\", lines.Select(l = new { orderId, l.Product, l.Qty }), tx); // passing a list executes once per item await tx.CommitAsync(); } catch { await tx.RollbackAsync(); throw; } Passing an IEnumerable of parameter objects to Execute runs the statement once per item — fine for tens of rows, slow for thousands. For bulk loads use: Technique Use --- --- SqlBulkCopy Fastest insert of thousands–millions of rows (from a DataTable or IDataReader ) Table-valued parameter (TVP) Send a set of rows to a stored procedure or MERGE in one call INSERT ... SELECT FROM OPENJSON(@json) Send JSON and insert set-based csharp // Table-valued parameter var table = new DataTable(); table.Columns.Add(\"ProductId\", typeof(int)); table.Columns.Add(\"Qty\", typeof(int)); foreach (var l in lines) table.Rows.Add(l.ProductId, l.Qty); await conn.ExecuteAsync(\"dbo.usp AddLines\", new { OrderId = orderId, Lines = table.AsTableValuedParameter(\"dbo.OrderLineType\") }, commandType: CommandType.StoredProcedure);"},{"kind":"lesson","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"buffering-streaming-type-handlers-and-dynamic-results","title":"Buffering, streaming, type handlers and dynamic results","body":"csharp // Unbuffered: stream rows one by one (huge exports) — keep the connection open while iterating await foreach (var row in conn.QueryUnbufferedAsync<Order (\"SELECT FROM dbo.Orders\")) await writer.WriteLineAsync($\"{row.Id},{row.OrderDate:O}\"); // dynamic results when you don't have a class var rows = await conn.QueryAsync(\"SELECT Category, COUNT( ) AS Total FROM dbo.Products GROUP BY Category\"); foreach (dynamic r in rows) Console.WriteLine($\"{r.Category}: {r.Total}\"); // Custom type handler: store a JSON column as a typed object public class JsonHandler<T : SqlMapper.TypeHandler<T { public override T Parse(object value) = JsonSerializer.Deserialize<T ((string)value)!; public override void SetValue(IDbDataParameter p, T? value) { p.DbType = DbType.String; p.Value = JsonSerializer.Serialize(value); } } SqlMapper.AddTypeHandler(new JsonHandler<Address ()); // DateOnly etc. need a handler on older Dapper versions Command timeout and cancellation: new CommandDefinition(sql, args, commandTimeout: 60, cancellationToken: ct) passed to QueryAsync ."},{"kind":"lesson","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"repository-unit-of-work-and-connection-management-in-aspdotnet-core","title":"Repository, unit of work and connection management in ASP.NET Core","body":"csharp public interface IDbConnectionFactory { DbConnection Create(); } public sealed class SqlConnectionFactory(IConfiguration cfg) : IDbConnectionFactory { public DbConnection Create() = new SqlConnection(cfg.GetConnectionString(\"Shop\")); } public interface IProductRepository { Task<IReadOnlyList<ProductDto SearchAsync(string? q, int page, int size, CancellationToken ct); Task<ProductDto? GetAsync(int id, CancellationToken ct); Task<int CreateAsync(CreateProduct cmd, CancellationToken ct); } public sealed class ProductRepository(IDbConnectionFactory db) : IProductRepository { public async Task<IReadOnlyList<ProductDto SearchAsync(string? q, int page, int size, CancellationToken ct) { const string sql = @\"SELECT Id, Name, Category, Price FROM dbo.Products WHERE (@q IS NULL OR Name LIKE @q + '%') ORDER BY Name OFFSET @skip ROWS FETCH NEXT @size ROWS ONLY\"; await using var conn = db.Create(); var rows = await conn.QueryAsync<ProductDto (new CommandDefinition(sql, new { q, skip = (page - 1) size, size }, cancellationToken: ct)); return rows.AsList(); } public async Task<ProductDto? GetAsync(int id, CancellationToken ct) { await using var conn = db.Create(); return await conn.QuerySingleOrDefaultAsync<ProductDto (new CommandDefinition( \"SELECT Id, Name, Category, Price FROM dbo.Products WHERE Id = @id\", new { id }, cancellationToken: ct)); } public async Task<int CreateAsync(CreateProduct c, CancellationToken ct) { await using var conn = db.Create(); return await conn.QuerySingleAsync<int (new CommandDefinition( \"INSERT INTO dbo.Products (Name, Category, Price) OUTPUT INSERTED.Id VALUES (@Name, @Category, @Price)\", c, cancellationToken: ct)); } } // Program.cs builder.Services.AddSingleton<IDbConnectionFactory, SqlConnectionFactory (); builder.Services.AddScoped<IProductRepository, ProductRepository (); - Open connections late and dispose early — ADO.NET connection pooling makes this cheap. - A unit of work shares one connection + transaction across several repositories for one business operation. - Keep SQL in one place (repository or .sql resources), name queries clearly, and test them against a real database."},{"kind":"lesson","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"performance-testing-and-choosing-dapper-vs-ef-core","title":"Performance, testing and choosing Dapper vs EF Core","body":"Performance tips: - Select only needed columns; page on the server ( OFFSET/FETCH or keyset paging). - Use correct parameter types ( DbString IsAnsi for VARCHAR columns) to avoid implicit conversions that prevent index seeks. - Use QueryMultiple instead of several round trips; TVPs/SqlBulkCopy for bulk. - Dapper caches per SQL text — don't build SQL with embedded values (cache grows without limit and plans aren't reused). - Use QueryUnbufferedAsync for very large results. - Check the execution plan; Dapper is only as fast as your SQL. Testing: unit-test services by mocking the repository interface; integration-test repositories against a real SQL Server (Testcontainers / LocalDB) — mocking IDbConnection extension methods is impractical. When to choose what: Situation Choice --- --- Complex reporting queries, dashboards, existing stored procedures Dapper Rich domain with relationships, change tracking, migrations EF Core Read-heavy API endpoints needing maximum speed Dapper (or EF Core with AsNoTracking + projection — often close enough) Bulk loads / ETL SqlBulkCopy / TVPs (with or without Dapper) Mixed EF Core for commands, Dapper for queries (they can share a connection/transaction via db.Database.GetDbConnection() )"},{"kind":"question","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"310","title":"What is Dapper and why use it?","body":"A micro-ORM: extension methods on IDbConnection that execute SQL you write and map result rows to objects automatically. It's almost as fast as raw ADO.NET with far less code, gives full control over SQL (stored procedures, CTEs, window functions), and has no change tracking or migrations. Ideal for read-heavy and performance-critical data access and for teams comfortable with SQL."},{"kind":"question","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"311","title":"Dapper vs Entity Framework Core?","body":"Dapper: you write SQL; minimal overhead; no change tracking, relationships, migrations or LINQ translation — perfect for reports and tuned queries. EF Core: LINQ queries translated to SQL, change tracking and SaveChanges , relationships, migrations, interceptors — faster to build CRUD and domain models, some overhead. Many projects use both: EF Core for writes, Dapper for complex reads."},{"kind":"question","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"312","title":"How does Dapper prevent SQL injection?","body":"When you pass values in the parameter object ( new { Id = id } ) or DynamicParameters , Dapper creates real DbParameter s, so the database treats them as data, never as SQL. Injection is only possible if you concatenate user input into the SQL string — never do that; whitelist identifiers like sort columns."},{"kind":"question","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"313","title":"Difference between Query, QueryFirst, QuerySingle and Execute?","body":"Query returns all rows ( IEnumerable<T ). QueryFirst returns the first row and throws if none ( OrDefault returns default). QuerySingle expects exactly one row and throws on zero or multiple ( OrDefault allows zero). Execute runs a command and returns the number of affected rows; ExecuteScalar returns the first column of the first row."},{"kind":"question","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"314","title":"How do you call a stored procedure with output parameters in Dapper?","body":"Create DynamicParameters , add inputs and add outputs with direction: ParameterDirection.Output (and ReturnValue if needed), call Query / Execute with commandType: CommandType.StoredProcedure , then read outputs with p.Get<T (\"@Name\") after the results have been consumed."},{"kind":"question","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"315","title":"What is multi-mapping and what does splitOn do?","body":"Mapping one row from a JOIN into several related objects: Query<Order, Customer, Order (sql, (o, c) = { o.Customer = c; return o; }, splitOn: \"Id\") . splitOn tells Dapper at which column the next object's columns begin (default \"Id\"). For one-to-many, use a dictionary to de-duplicate parent objects and add children."},{"kind":"question","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"316","title":"How do you use transactions with Dapper?","body":"Open the connection, BeginTransaction , pass the transaction to every Dapper call ( transaction: tx or positional argument), Commit on success and Rollback in a catch (or let Dispose roll back). For multiple repositories in one operation, share the connection and transaction through a unit-of-work object. TransactionScope also works (with async flow enabled)."},{"kind":"question","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"317","title":"How do you insert thousands of rows efficiently?","body":"Not by passing a list to Execute (one round trip per row). Use SqlBulkCopy for raw speed, a table-valued parameter to a stored procedure (or MERGE ) for set-based logic, or JSON + OPENJSON in one statement. Batch very large loads and use transactions appropriately."},{"kind":"question","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"318","title":"What is buffered vs unbuffered querying in Dapper?","body":"Buffered (default) reads all rows into a list before returning and closes the reader — simple and safe. Unbuffered ( buffered: false or QueryUnbufferedAsync ) yields rows while reading, keeping the reader and connection open until enumeration finishes — lower memory for huge results, but you must finish iterating before using the connection again."},{"kind":"question","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"319","title":"How does Dapper map columns to properties and how do you handle mismatched names?","body":"By name, case-insensitive, to public properties/fields or constructor parameters. For mismatches use SQL aliases ( SELECT product name AS Name ), DefaultTypeMap.MatchNamesWithUnderscores = true , or a custom type map ( SqlMapper.SetTypeMap with CustomPropertyTypeMap ). Custom value conversions use SqlMapper.TypeHandler<T ."},{"kind":"question","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"320","title":"How does Dapper achieve its performance?","body":"It generates and caches mapping code per (SQL, parameter type, result type) the first time a query runs — IL-emitted delegates that read the data reader directly into objects and write parameters — so later calls avoid reflection. It adds very little on top of ADO.NET: no change tracking, no expression translation. Dapper.AOT moves this generation to compile time with source generators."},{"kind":"question","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"321","title":"How do you manage connections with Dapper in ASP.NET Core?","body":"Register a connection factory (singleton) that creates new SqlConnection s; create, use and dispose a connection per operation ( await using ), relying on connection pooling. For multi-step transactions use a scoped unit of work holding one connection and transaction. Avoid keeping connections open for the whole request or sharing one connection across threads."},{"kind":"question","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"322","title":"A Dapper search endpoint is slow even though the same SQL is fast in SSMS. What could cause it?","body":"Different parameter types: Dapper sends string as NVARCHAR , and if the column is VARCHAR SQL Server converts the column, preventing an index seek — use DbString { IsAnsi = true } . Parameter sniffing: SSMS runs with literal values while the app reuses a plan compiled for different values — check the cached plan; consider OPTION (RECOMPILE) or better indexes. Also different SET options (ARITHABORT) produce different plans, and the app may be returning far more rows/columns or doing N+1 calls."},{"kind":"question","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"323","title":"Your team builds SQL with string interpolation for filters in Dapper. What problems does this cause and how do you fix it?","body":"SQL injection risk, no plan reuse in SQL Server and an ever-growing Dapper query cache (each distinct SQL string is cached) → memory growth. Fix: parameterise all values, build optional filters with WHERE (@x IS NULL OR Col = @x) or a safe builder (DapperQueryBuilder / SqlBuilder ) that appends parameterised fragments, and whitelist dynamic identifiers."},{"kind":"question","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"324","title":"How would you migrate a large ADO.NET DataReader-based data layer to Dapper?","body":"Keep the SQL and stored procedures; replace manual reader loops with Query<T mapped to DTOs, DynamicParameters for procedures with outputs, and QueryMultiple for multi-result procedures. Do it repository by repository behind existing interfaces, with integration tests comparing outputs before and after. Watch column-name mismatches and type differences (DBNull handling, decimal/money, dates)."},{"kind":"cheat","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"1","title":"Core calls","body":"Query<T · QueryFirst(OrDefault)<T · QuerySingle(OrDefault)<T · Execute · ExecuteScalar<T · QueryMultiple · QueryUnbufferedAsync · all with Async versions and CommandDefinition for timeout/cancellation."},{"kind":"cheat","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"2","title":"Parameters","body":"Anonymous object new { Id = id } · DynamicParameters for types/size/direction · IN @ids with a collection · DbString { IsAnsi = true } for VARCHAR · never interpolate values."},{"kind":"cheat","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"3","title":"Advanced","body":"Multi-mapping Query<A,B,A (sql, map, splitOn:) · stored procs commandType: CommandType.StoredProcedure · outputs p.Get<T () · transactions pass tx · TVP AsTableValuedParameter · SqlBulkCopy for bulk · SqlMapper.TypeHandler<T ."},{"kind":"cheat","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"4","title":"Architecture","body":"Connection factory (singleton) · repositories (scoped) · open late, dispose early · unit of work for multi-step transactions · EF Core for writes + Dapper for reads is common."},{"kind":"cheat","course_slug":"dapper","course_title":"Dapper — The Micro-ORM from Basics to Advanced","ref":"5","title":"Performance","body":"Only needed columns · server paging · correct parameter types · fewer round trips · read the execution plan."},{"kind":"course","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"","title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","body":"How ASP.NET Web Forms works inside IIS (application and page life cycle), folder structure (App Code, App Data, App Start, Bin, App Themes), Web Site vs Web Application projects, .aspx/.aspx.cs code-behind, server controls and events, PostBack and ViewState, state management (ViewState, ControlState, Session, Application, Cache, cookies, query strings, hidden fields), validation controls, master pages, user controls and custom controls, data binding with GridView/Repeater and SqlDataSource vs ObjectDataSource, Global.asax and web.config, Forms authentication, custom errors, performance and migrating Web Forms to ASP.NET Core. ASP.NET Web Forms (2002, .NET Framework) lets developers build web pages the way they built Windows Forms: drag server controls onto a page, double-click a button and write a C /VB.NET event handler . The framework hides HTTP's statelessness using PostBack (forms post to the same page) and ViewState (control state stored in a hidden field). Strength Weakness --- --- Very fast development for data-entry/admin screens (GridView, FormView, validators) Heavy pages (ViewState), less control over HTML Event-driven model familiar to desktop developers Hard to unit test (logic in code-behind) Huge control ecosystem (Telerik, DevExpress, Infragistics) Tightly coupled to IIS/System.Web; not in .NET Core Still powers many enterprise/government intranets No new features; migration needed for modern .NET Web Forms remains supported on .NET Framework 4.8/4.8.1 (as part of Windows), so these apps keep running — and developers who understand them are needed for maintenance and migration. Community project WebFormsCore /Blazor migration tools exist, but there is no official Web Forms for .NET Core. Version Year .NET Framework Highlights --- --- --- --- ASP.NET 1.0 2002 1.0 Web Forms, server controls, ViewState, code-behind, web.config, Forms auth ASP.NET 1.1 2003 1.1 Mobile controls, request validation ASP.NET 2.0 2005 2.0 Master pages , themes/skins, Membership/Roles/Profile providers, GridView/DetailsView/FormView, data source controls, Web Parts, App Code , partial classes ASP.NET 3.5 2007 3.5 ASP.NET AJAX (UpdatePanel, ScriptManager), ListView, LINQ, LinqDataSource ; 3.5 SP1: Dynamic Data, routing ( System.Web.Routing ) ASP.NET 4.0 2010 4.0 ClientIDMode (clean IDs), ViewStateMode , routing for Web Forms, Response.RedirectPermanent , cleaner HTML ASP.NET 4.5 2012 4.5 Model binding ( SelectMethod / ItemType ), strongly typed data controls, async pages, bundling & minification, unobtrusive validation ASP.NET 4.6 – 4.8 2015 – 2019 4.6 – 4.8 HTTP/2 support on Windows 10/IIS, async model binding, maintenance updates 1. Application / request life cycle in IIS (integrated pipeline): text Browser → HTTP.sys → IIS (w3wp.exe, app pool, .NET CLR v4.0) → ASP.NET HttpRuntime → HttpApplication (Global.asax) events, run by HTTP modules: BeginRequest → AuthenticateRequest → AuthorizeRequest → ResolveRequestCache → MapRequestHandler → AcquireRequestState (Session loaded) → PreRequestHandlerExecute → HTTP HANDLER executes (for .aspx: the Page class → PAGE LIFE CYCLE below) → PostRequestHandlerExecute → ReleaseRequestState (Session saved) → UpdateRequestCache → LogRequest → EndRequest → response sent The first request to the application raises Application Start (Global.asax); .aspx files are compiled dynamically (or precompiled) into classes deriving from your code-behind class, which derives from System.Web.UI.Page . 2. Page life cycle (the most-asked Web Forms interview topic): Stage / event What happens Typical use --- --- --- Page request & start Determines IsPostBack , sets Request / Response — PreInit Before controls initialise Set master page or theme dynamically, create dynamic controls Init Each control's Init (children first), control IDs set Initialise control properties, add dynamic controls InitComplete ViewState tracking turned on — (PostBack) Load ViewState / ControlState Restore control values from VIEWSTATE — (PostBack) Load PostBack data Apply posted form values to controls — PreLoad Before Load — Load Page then each control's Load Data loading — usually inside if (!IsPostBack) Control events (PostBack) TextChanged , SelectedIndexChanged , then the Button Click that caused the postback Your business actions LoadComplete After events — PreRender Last chance to change controls before rendering Final UI adjustments PreRenderComplete, SaveStateComplete ViewState saved into VIEWSTATE — Render Each control writes its HTML (method, not event) Custom controls override Render Unload Cleanup (children first, then page); response already sent Close resources Mnemonic: \"SILVER\" — Start, Init, Load, Validate, Event handling, Render (plus Unload). - Visual Studio 2022/2026 with the \"ASP.NET and web development\" workload (.NET Framework 4.8 templates) — designer view, Toolbox, Properties window. - IIS / IIS Express, IIS Manager, Event Viewer, Failed Request Tracing. - Third-party control suites: Telerik UI for ASP.NET AJAX, DevExpress ASP.NET Web Forms, Infragistics. - ViewState decoders (to inspect page size), browser DevTools, Glimpse (legacy), Application Insights / ELMAH for errors. - Migration: .NET Upgrade Assistant (project files), Blazor migration guides, YARP for incremental migration."},{"kind":"lesson","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"project-types-and-folder-structure","title":"Project types and folder structure","body":"Web Site project (File → New → Web Site): no project file; every .cs file compiled dynamically on the server; App Code for classes. Web Application project (preferred for real apps): a .csproj , compiled into one DLL in bin , better for source control and builds. text ShopWeb/ (ASP.NET Web Application, .NET Framework 4.8) ├── App Code/ shared classes compiled dynamically (Web Site projects mainly) ├── App Data/ local data files (.mdf, XML) — not served to browsers ├── App GlobalResources/ .resx strings for localisation (whole app) ├── App LocalResources/ .resx per page ├── App Start/ startup classes: RouteConfig, BundleConfig, IdentityConfig ├── App Themes/ themes: .skin and .css files per theme ├── Account/ Login.aspx, Register.aspx (Identity/Membership template) ├── bin/ compiled assemblies (YourApp.dll) and references ├── Content/ CSS ├── Scripts/ JavaScript (jQuery, Bootstrap) ├── Controls/ user controls (.ascx) ├── Admin/ pages protected by role (web.config <authorization per folder) ├── Default.aspx markup (HTML + server controls) ├── Default.aspx.cs code-behind (partial class Default : Page) ├── Default.aspx.designer.cs auto-generated control field declarations ├── Site.Master (+ .cs) master page layout ├── Global.asax (+ .cs) application events ├── Web.config configuration (connection strings, auth, modules, custom errors) ├── Web.Debug.config / Web.Release.config config transforms for publishing └── packages.config NuGet packages (older style) Folders starting with App are special: IIS/ASP.NET blocks direct browser access to them."},{"kind":"lesson","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"pages-code-behind-server-controls-and-events","title":"Pages, code-behind, server controls and events","body":"aspx <%@ Page Title=\"Products\" Language=\"C \" MasterPageFile=\"~/Site.Master\" AutoEventWireup=\"true\" CodeBehind=\"Products.aspx.cs\" Inherits=\"ShopWeb.Products\" % <asp:Content ID=\"Main\" ContentPlaceHolderID=\"MainContent\" runat=\"server\" <asp:Label ID=\"lblMessage\" runat=\"server\" CssClass=\"text-success\" / <asp:TextBox ID=\"txtName\" runat=\"server\" / <asp:RequiredFieldValidator runat=\"server\" ControlToValidate=\"txtName\" ErrorMessage=\"Name is required\" Display=\"Dynamic\" / <asp:DropDownList ID=\"ddlCategory\" runat=\"server\" AutoPostBack=\"true\" OnSelectedIndexChanged=\"ddlCategory SelectedIndexChanged\" / <asp:Button ID=\"btnSave\" runat=\"server\" Text=\"Save\" OnClick=\"btnSave Click\" / <asp:GridView ID=\"gvProducts\" runat=\"server\" AutoGenerateColumns=\"false\" DataKeyNames=\"Id\" <Columns <asp:BoundField DataField=\"Name\" HeaderText=\"Name\" / <asp:BoundField DataField=\"Price\" HeaderText=\"Price\" DataFormatString=\"{0:C}\" / </Columns </asp:GridView </asp:Content csharp public partial class Products : System.Web.UI.Page { protected void Page Load(object sender, EventArgs e) // AutoEventWireup=\"true\" wires Page Load by name { if (!IsPostBack) // first visit only — otherwise you overwrite user input { ddlCategory.DataSource = ProductService.GetCategories(); ddlCategory.DataBind(); BindGrid(); } } protected void ddlCategory SelectedIndexChanged(object sender, EventArgs e) = BindGrid(); protected void btnSave Click(object sender, EventArgs e) { if (!Page.IsValid) return; // server-side validation result ProductService.Add(txtName.Text.Trim(), ddlCategory.SelectedValue); lblMessage.Text = \"Saved\"; BindGrid(); } private void BindGrid() { gvProducts.DataSource = ProductService.GetByCategory(ddlCategory.SelectedValue); gvProducts.DataBind(); } } Control categories: HTML controls ( <input — plain), HTML server controls ( <input runat=\"server\" — accessible in code), Web server controls ( <asp:TextBox ), validation controls , data controls (GridView, Repeater, ListView, DetailsView, FormView), navigation (Menu, TreeView, SiteMapPath), login controls , user controls (.ascx) and custom controls . Inline code expressions: <%= value % (write, not encoded), <%: value % (HTML-encoded — use this), <% Eval(\"Name\") % (data binding), <%$ ConnectionStrings:Shop % (expression builder)."},{"kind":"lesson","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"postback-autopostback-and-viewstate-how-they-work","title":"PostBack, AutoPostBack and ViewState — how they work","body":"- A Web Forms page wraps everything in one <form runat=\"server\" that posts back to the same URL. - PostBack = the browser submits the form to the same page; the page object is created again from scratch on the server, rebuilds controls, restores state and raises the events. - AutoPostBack=\"true\" makes controls like DropDownList post immediately on change (via doPostBack JavaScript); EVENTTARGET and EVENTARGUMENT hidden fields tell the server which control fired. - IsPostBack is false on the first GET and true on postbacks. ViewState: html <input type=\"hidden\" name=\" VIEWSTATE\" id=\" VIEWSTATE\" value=\"/wEPDwUKLTY1NDU2MTc0MQ9kFgJmD2QWAg...\" / - Stores control properties that changed programmatically (e.g. a Label's text, a GridView's data) so they survive postbacks. - Base64-encoded, signed (MAC) to prevent tampering, optionally encrypted ( ViewStateEncryptionMode ) — but not secret by default ; never store sensitive data. - Grows page size and slows requests — large GridViews can produce hundreds of KB. - Control: EnableViewState=\"false\" per control/page, ViewStateMode=\"Disabled\" + enable selectively (4.0+), store state elsewhere. - ControlState — a small, separate state that controls need to function (e.g. GridView page index); cannot be turned off. csharp // Your own values in ViewState (per page, survives postbacks of that page) private int CurrentStep { get = (int?)ViewState[\"Step\"] ?? 1; set = ViewState[\"Step\"] = value; }"},{"kind":"lesson","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"state-management-client-side-vs-server-side","title":"State management — client-side vs server-side","body":"Technique Where stored Scope / lifetime Use for --- --- --- --- ViewState Hidden field in the page One page, across its postbacks Control values, small page data ControlState Hidden field One control Essential control data Hidden field Page Postbacks Small values for client script Query string URL One request/link Ids, filters, bookmarkable state ( ?id=5 ) — visible, validate it Cookies Browser Until expiry Preferences, \"remember me\" (4 KB limit) Session Server (InProc memory, StateServer, SQL Server) keyed by a cookie One user, until timeout (20 min default) Cart, user data during a visit Application Server memory Whole app, all users, until restart Rarely-changing global data (with locking) Cache ( HttpRuntime.Cache ) Server memory All users, with expiry/dependencies Expensive lookups, reference data Profile Database (provider) Per user, permanent User preferences (legacy) csharp Session[\"Cart\"] = cart; // InProc by default var cart = Session[\"Cart\"] as Cart ?? new Cart(); Application.Lock(); Application[\"Visitors\"] = (int)(Application[\"Visitors\"] ?? 0) + 1; Application.UnLock(); Cache.Insert(\"Categories\", categories, null, DateTime.Now.AddMinutes(30), Cache.NoSlidingExpiration); Response.Cookies.Add(new HttpCookie(\"theme\", \"dark\") { Expires = DateTime.Now.AddDays(30), HttpOnly = true, Secure = true }); Response.Redirect(\"Orders.aspx?customerId=\" + customerId, endResponse: false); Session modes (web.config <sessionState mode=\"...\" ): InProc (fastest; lost on app-pool recycle; not shared in a web farm), StateServer (separate Windows service; survives recycles), SQLServer (durable, shared across a farm), Custom (Redis provider), Off . Objects stored out-of-process must be [Serializable] . Page navigation: Response.Redirect (browser makes a new request — URL changes, 302), Server.Transfer (server switches page — URL doesn't change, same request), cross-page posting ( PostBackUrl )."},{"kind":"lesson","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"validation-controls-master-pages-themes-and-user-controls","title":"Validation controls, master pages, themes and user controls","body":"Validation controls (client-side JavaScript + server-side check, Page.IsValid ): Control Checks --- --- RequiredFieldValidator Value entered CompareValidator Compare with another control/value/type ( Operator=\"DataTypeCheck\" ) RangeValidator Between min and max RegularExpressionValidator Pattern (email, phone) CustomValidator Your own function ( OnServerValidate , ClientValidationFunction ) ValidationSummary Shows all errors in one place ValidationGroup separates groups of validators on one page; CausesValidation=\"false\" on Cancel buttons. Always check Page.IsValid on the server — client scripts can be bypassed. Master pages (layout template): aspx <%@ Master Language=\"C \" CodeBehind=\"Site.master.cs\" Inherits=\"ShopWeb.SiteMaster\" % <html <head runat=\"server\" <title </title </head <body <form runat=\"server\" <header Divakar Shop</header <asp:ContentPlaceHolder ID=\"MainContent\" runat=\"server\" / <footer © 2026</footer </form </body </html Access the master from a page with <%@ MasterType VirtualPath=\"~/Site.Master\" % and Master.SomeProperty . Nested master pages are allowed. Event order: at runtime the master page becomes a child control of the page. Init (and Unload ) run child-first, so the master's Init runs before the page's Init ; Load and PreRender run parent-first, so the page's Load runs before the master's Load . Themes and skins: App Themes/Dark/Controls.skin sets default control properties ( <asp:Button runat=\"server\" CssClass=\"btn btn-dark\" / ); apply with Theme=\"Dark\" in the page or web.config <pages theme=\"Dark\" . User controls (.ascx) — reusable page fragments with their own markup and code-behind: aspx <%@ Control Language=\"C \" CodeBehind=\"AddressEditor.ascx.cs\" Inherits=\"ShopWeb.Controls.AddressEditor\" % <asp:TextBox ID=\"txtCity\" runat=\"server\" / csharp public partial class AddressEditor : UserControl { public string City { get = txtCity.Text; set = txtCity.Text = value; } // expose properties public event EventHandler? AddressChanged; // and events } aspx <%@ Register Src=\"~/Controls/AddressEditor.ascx\" TagPrefix=\"uc\" TagName=\"Address\" % <uc:Address ID=\"shipping\" runat=\"server\" / (Custom server controls compiled into DLLs are covered in the Custom Controls & Components course.)"},{"kind":"lesson","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"data-binding-gridview-repeater-listview-and-data-source-controls","title":"Data binding — GridView, Repeater, ListView and data source controls","body":"Control Output Paging/sorting/editing built in Use --- --- --- --- GridView HTML table ✅ Admin grids with edit/delete Repeater Exactly your template HTML ❌ (do it yourself) Lightweight custom lists ListView Your templates + layout ✅ (with DataPager) Flexible lists with editing DataList Table/flow layout Partial Legacy DetailsView / FormView One record ✅ Detail/edit forms aspx <asp:Repeater ID=\"rptOrders\" runat=\"server\" ItemType=\"ShopWeb.Models.OrderDto\" <ItemTemplate <div class=\"order\" <% : Item.Id % — <% : Item.Total.ToString(\"C\") % </div </ItemTemplate </asp:Repeater <!-- ASP.NET 4.5 model binding: the grid calls your methods -- <asp:GridView ID=\"gv\" runat=\"server\" ItemType=\"ShopWeb.Models.Product\" DataKeyNames=\"Id\" SelectMethod=\"GetProducts\" UpdateMethod=\"UpdateProduct\" AllowPaging=\"true\" AllowSorting=\"true\" AutoGenerateEditButton=\"true\" / csharp public IQueryable<Product GetProducts() = db.Products.OrderBy(p = p.Name); // paging/sorting applied by the grid public void UpdateProduct(int id) { var p = db.Products.Find(id); if (p != null && TryUpdateModel(p)) db.SaveChanges(); } Data source controls: SqlDataSource (SQL in markup — quick but mixes data access into the UI), ObjectDataSource (calls methods on your business class — better layering), EntityDataSource , LinqDataSource . Prefer model binding or code-behind binding to services. GridView events: RowDataBound (format each row), RowCommand (custom buttons with CommandName / CommandArgument ), RowEditing / RowUpdating / RowDeleting , PageIndexChanging , Sorting ."},{"kind":"lesson","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"ajax-in-web-forms-scriptmanager-updatepanel-and-page-methods","title":"AJAX in Web Forms — ScriptManager, UpdatePanel and page methods","body":"aspx <asp:ScriptManager runat=\"server\" / <asp:UpdatePanel ID=\"upCart\" runat=\"server\" UpdateMode=\"Conditional\" <ContentTemplate <asp:Label ID=\"lblCount\" runat=\"server\" / <asp:Button ID=\"btnAdd\" runat=\"server\" Text=\"Add\" OnClick=\"btnAdd Click\" / </ContentTemplate </asp:UpdatePanel <asp:UpdateProgress runat=\"server\" AssociatedUpdatePanelID=\"upCart\" <ProgressTemplate Loading…</ProgressTemplate </asp:UpdateProgress An UpdatePanel performs a partial postback : the whole page life cycle still runs on the server and the full ViewState is posted, but only the panel's HTML is replaced in the browser. It feels faster but isn't lighter on the server. Alternatives: [WebMethod] page methods / ASMX or Web API endpoints called with jQuery $.ajax / fetch for truly light calls."},{"kind":"lesson","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"global-asax-web-config-http-modules-and-handlers","title":"Global.asax, web.config, HTTP modules and handlers","body":"csharp public class Global : HttpApplication { protected void Application Start(object sender, EventArgs e) // once per app domain start { RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } protected void Session Start(object sender, EventArgs e) { } // new user session protected void Application BeginRequest(object sender, EventArgs e) { } protected void Application Error(object sender, EventArgs e) // unhandled exceptions — log here { var ex = Server.GetLastError(); Logger.Error(ex); } protected void Session End(object sender, EventArgs e) { } // InProc session mode only protected void Application End(object sender, EventArgs e) { } } xml <configuration <connectionStrings <add name=\"Shop\" connectionString=\"Server=.;Database=Shop;Integrated Security=true\" providerName=\"System.Data.SqlClient\" / </connectionStrings <appSettings <add key=\"PageSize\" value=\"20\" / </appSettings <system.web <compilation debug=\"false\" targetFramework=\"4.8\" / <!-- debug=false in production! -- <httpRuntime targetFramework=\"4.8\" maxRequestLength=\"10240\" / <authentication mode=\"Forms\" <forms loginUrl=\"~/Account/Login.aspx\" timeout=\"30\" requireSSL=\"true\" / </authentication <sessionState mode=\"InProc\" timeout=\"20\" / <customErrors mode=\"RemoteOnly\" defaultRedirect=\"~/Error.aspx\" <error statusCode=\"404\" redirect=\"~/NotFound.aspx\" / </customErrors </system.web <location path=\"Admin\" <system.web <authorization <allow roles=\"Admin\" / <deny users=\" \" / </authorization </system.web </location <system.webServer <modules <add name=\"AuditModule\" type=\"ShopWeb.Infrastructure.AuditModule\" / </modules <httpErrors errorMode=\"DetailedLocalOnly\" / </system.webServer </configuration Config inheritance: machine.config → root web.config (Framework folder) → site web.config → sub-folder web.config s. Changing web.config restarts the application . HTTP module ( IHttpModule ) — hooks pipeline events for every request (auth, logging, URL rewriting). HTTP handler ( IHttpHandler ) — produces the response for a request type ( .aspx page handler, .ashx generic handler for files/images/JSON). csharp public class ThumbnailHandler : IHttpHandler // Thumbnail.ashx { public bool IsReusable = true; public void ProcessRequest(HttpContext context) { context.Response.ContentType = \"image/png\"; context.Response.BinaryWrite(ImageService.Thumbnail(context.Request.QueryString[\"id\"])); } }"},{"kind":"lesson","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"authentication-security-and-custom-error-handling-in-web-forms","title":"Authentication, security and custom error handling in Web Forms","body":"- Windows authentication (intranet, Active Directory) or Forms authentication (login page + encrypted auth cookie, FormsAuthentication.SetAuthCookie ); later ASP.NET Identity (OWIN) replaced Membership providers. - Authorization in web.config <authorization per folder/page, or in code User.IsInRole(\"Admin\") . - Built-in protections: request validation (blocks <script in input), ViewState MAC, event validation; still HTML-encode output ( <%: % , Server.HtmlEncode ), use parameterised SQL, set ViewStateUserKey against CSRF, requireSSL , HttpOnly cookies. Error handling levels (most specific first): csharp // 1. try/catch around risky code in the event handler // 2. Page level protected void Page Error(object sender, EventArgs e) { var ex = Server.GetLastError(); Logger.Error(ex, \"Error on \" + Request.Url); Server.ClearError(); Response.Redirect(\"~/Error.aspx\", false); } // 3. Application level — Global.asax Application Error (logs everything unhandled) // 4. web.config <customErrors (ASP.NET) and <httpErrors (IIS) — friendly pages, never show stack traces to users customErrors mode=\"On\" shows custom pages to everyone; RemoteOnly shows details only on the server; Off shows the \"yellow screen of death\" — never in production. ELMAH or log4net/NLog/Serilog capture errors (see the Exception Handling and Logging courses)."},{"kind":"lesson","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"performance-tuning-and-migrating-web-forms-to-modern-dotnet","title":"Performance tuning and migrating Web Forms to modern .NET","body":"Performance: - Disable ViewState where not needed; page GridViews server-side; avoid huge UpdatePanels. - Output caching: <%@ OutputCache Duration=\"60\" VaryByParam=\"id\" % ; data caching with Cache . - compilation debug=\"false\" ; bundling and minification; compress static files in IIS. - Async pages ( Async=\"true\" + RegisterAsyncTask ) for slow I/O. - Session: avoid storing large objects; use EnableSessionState=\"ReadOnly\" or False where possible (session locking serialises requests from one user). Migration options: Target Effort Notes --- --- --- Stay on .NET Framework 4.8 None Supported with Windows; no new features ASP.NET Core MVC / Razor Pages High (rewrite UI) Most common target; reuse business/data layers if extracted Blazor (Server or United/Web App) High Component + event model feels closer to Web Forms Incremental (strangler) Medium, spread over time YARP/IIS ARR routes migrated paths to the new Core app; share auth cookie and database; System.Web adapters help share session Steps: extract business logic from code-behind into class libraries ( netstandard2.0 ), add tests, set up the new app beside the old, migrate page by page, retire old pages."},{"kind":"question","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"325","title":"Explain the ASP.NET Web Forms page life cycle.","body":"Page request → start (IsPostBack set) → PreInit (set master/theme, create dynamic controls) → Init (controls initialised) → InitComplete → load ViewState and postback data (postbacks) → PreLoad → Load (page then controls; load data in !IsPostBack ) → control events (change events, then the Click that caused the postback) → LoadComplete → PreRender (final changes) → SaveStateComplete (ViewState saved) → Render (HTML written) → Unload (cleanup). Mnemonic SILVER: Start, Init, Load, Validate, Event, Render."},{"kind":"question","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"326","title":"What is ViewState? Pros and cons?","body":"A hidden form field ( VIEWSTATE ) holding base64-encoded, MAC-signed state of controls (and your own values) so they survive postbacks of the same page without server memory. Pros: automatic, per-page, no server storage. Cons: increases page size and request time, not secure by default (only signed, not encrypted), can't be used across pages. Disable it where unnecessary and never store sensitive data."},{"kind":"question","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"327","title":"What is PostBack and IsPostBack?","body":"A postback is the form submitting back to the same page so server-side events (button clicks, selection changes) can run. IsPostBack is false on the first request and true on postbacks — load initial data only when !IsPostBack , otherwise you overwrite the user's input and waste database calls."},{"kind":"question","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"328","title":"What state management options exist in ASP.NET?","body":"Client-side: ViewState, ControlState, hidden fields, cookies, query strings. Server-side: Session (InProc, StateServer, SQLServer, custom), Application, Cache, Profile. Choose by scope (page, user, all users), size, security and whether it must survive restarts or work in a web farm."},{"kind":"question","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"329","title":"Response.Redirect vs Server.Transfer?","body":"Response.Redirect sends a 302 to the browser, which makes a new request — URL changes, works for any URL, an extra round trip, previous page data lost unless passed. Server.Transfer switches execution to another page on the server within the same request — URL in the browser stays the same, faster, can access the previous page ( PreviousPage ), only within the same application."},{"kind":"question","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"330","title":"What are the Session state modes? Which would you use in a web farm?","body":"InProc (in the worker process memory — fastest, lost on app-pool recycle, not shared), StateServer (aspnet state service — survives recycles, shared, serialisation needed), SQLServer (stored in SQL — durable, shared, slower), Custom (e.g. Redis provider), Off. In a web farm use SQLServer, StateServer or a Redis custom provider (or sticky sessions as a weaker alternative)."},{"kind":"question","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"331","title":"User control vs custom control?","body":"A user control (.ascx) is markup + code-behind built visually and reused within one application (registered with @Register Src= ). A custom (server) control is a class deriving from Control / WebControl / CompositeControl that renders its own HTML, compiled into a DLL, reusable across applications, can appear in the Toolbox and support design-time features — more work to build."},{"kind":"question","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"332","title":"What are master pages and how do content pages use them?","body":"A master page ( .master ) defines a shared layout with ContentPlaceHolder s; content pages specify MasterPageFile and fill placeholders with <asp:Content . At runtime the master page is merged into the page's control tree (as a child control). Access it with Master (strongly typed via @MasterType ), switch it dynamically in PreInit , nest masters for sections."},{"kind":"question","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"333","title":"What is the role of Global.asax and web.config?","body":"Global.asax holds application-level event handlers: Application Start/End, Session Start/End, BeginRequest, AuthenticateRequest, Application Error. Web.config holds hierarchical configuration: connection strings, app settings, authentication/authorization, session, custom errors, modules/handlers, compilation; changes restart the app."},{"kind":"question","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"334","title":"HTTP module vs HTTP handler?","body":"Modules ( IHttpModule ) subscribe to pipeline events and run for every request — authentication, logging, URL rewriting, compression. Handlers ( IHttpHandler ) generate the response for specific requests/extensions — the Page handler for .aspx , .ashx generic handlers for images or files. A request passes through many modules but is processed by one handler."},{"kind":"question","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"335","title":"What does an UpdatePanel actually do?","body":"It turns a full postback into an asynchronous partial postback: the browser still posts the whole form including ViewState, the server runs the full page life cycle, but only the panel's markup (and updated ViewState) is returned and replaced. It improves perceived responsiveness, not server load. For light calls use page methods or Web API with JavaScript."},{"kind":"question","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"336","title":"How do you handle errors globally in Web Forms?","body":"Try/catch for expected errors in handlers; Page Error for page-level handling; Application Error in Global.asax to log every unhandled exception ( Server.GetLastError() ), then customErrors / httpErrors in web.config to show friendly error pages (404, 500) instead of details. Use a logging framework or ELMAH."},{"kind":"question","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"337","title":"Why does a dynamically added control lose its value or events after postback?","body":"Because controls created in code must be recreated on every request, with the same IDs, early enough (PreInit/Init) for ViewState and posted data to be applied and events to fire. Creating them in Load or only on the first request ( !IsPostBack ) means the control doesn't exist when the framework restores state and raises events."},{"kind":"question","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"338","title":"What is the difference between a Web Site project and a Web Application project?","body":"Web Site: no project file, files compiled dynamically on the server (each page/folder its own assembly), App Code for shared classes, easy to edit live but harder to manage. Web Application: .csproj , compiled ahead into one assembly in bin , designer files, better for builds, refactoring, source control and deployment — the standard for professional projects."},{"kind":"question","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"339","title":"A Web Forms page with a big GridView is very slow to post back. How do you fix it?","body":"Measure page size: ViewState of the GridView is likely hundreds of KB. Disable ViewState on the grid and rebind on postback, or keep only keys; use server-side paging (load only the current page from the database) instead of binding thousands of rows; replace UpdatePanels around the grid with lighter AJAX calls if needed; cache reference data; check SQL queries and session locking."},{"kind":"question","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"340","title":"You must add a new feature to a legacy Web Forms app while the company plans to move to ASP.NET Core. How do you build it?","body":"Put the business logic in a separate class library (netstandard2.0 or .NET Framework library with clean interfaces) and unit-test it; keep code-behind thin, calling services. If the feature is a new area, consider building it directly in the new ASP.NET Core app behind a reverse proxy sharing authentication (strangler pattern), so it doesn't need to be migrated later."},{"kind":"question","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"341","title":"Users randomly lose their session (shopping cart) in production. What could cause it?","body":"InProc session lost when the app pool recycles (scheduled recycling, memory limits, web.config/bin changes, crashes) or when requests hit different servers in a web farm without shared session; session timeout too short; cookieless/cookie issues. Fix: StateServer/SQLServer/Redis session, review recycling settings, store less in session, sticky sessions only as a stop-gap."},{"kind":"cheat","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"1","title":"Page life cycle","body":"PreInit → Init → InitComplete → (LoadViewState, LoadPostData) → PreLoad → Load → control events → LoadComplete → PreRender → SaveStateComplete → Render → Unload."},{"kind":"cheat","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"2","title":"Application pipeline","body":"BeginRequest → Authenticate → Authorize → ResolveRequestCache → AcquireRequestState → PreRequestHandlerExecute → handler (Page) → PostRequestHandlerExecute → ReleaseRequestState → UpdateRequestCache → EndRequest."},{"kind":"cheat","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"3","title":"State options","body":"Page: ViewState/ControlState/hidden field · request: query string · browser: cookies · user: Session (InProc/StateServer/SQL/Redis) · all users: Application/Cache."},{"kind":"cheat","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"4","title":"Folders & files","body":"App Code · App Data · App Start · App Themes · App GlobalResources · bin · .aspx + .aspx.cs + .designer.cs · .master · .ascx · .ashx · Global.asax · Web.config (+ transforms)."},{"kind":"cheat","course_slug":"aspnet-webforms","course_title":"ASP.NET Web Forms — Page Life Cycle, ViewState, Controls and State Management","ref":"5","title":"Errors","body":"try/catch → Page Error → Application Error (log) → customErrors/httpErrors (friendly pages) · never debug=\"true\" or customErrors=\"Off\" in production."},{"kind":"course","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"","title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","body":"The MVC pattern, the classic MVC 5 project and folder structure (App Start, Controllers, Models, Views, Areas, Global.asax, Views/web.config), the full request life cycle from UrlRoutingModule to MvcHandler, controller factory, action invoker, filters, model binding, action results and the Razor view engine, routing (convention and attribute), controllers and action results, Razor views, HTML helpers, partial views and child actions, model binding and validation, filters (authorization, action, result, exception), ViewBag/ViewData/TempData, bundling, dependency injection with Unity/Autofac, OWIN and ASP.NET Identity, Web API 2 side by side, error handling and migrating MVC 5 to ASP.NET Core. ASP.NET MVC (2009) brought the Model–View–Controller pattern to ASP.NET on .NET Framework as an alternative to Web Forms: no ViewState, no page life cycle, full control of HTML, clean URLs and testable controllers. MVC 5 (2013) is the final version; its successor is ASP.NET Core MVC . Part Responsibility Example --- --- --- Model Data and business rules (entities, view models, validation) Product , ProductViewModel View Presentation — Razor templates producing HTML Views/Products/Index.cshtml Controller Handles the request, calls services, chooses the view/result ProductsController.Index() Web Forms MVC 5 ASP.NET Core MVC --- --- --- --- Model Event-driven pages, ViewState Request → controller action → view Same as MVC 5, rebuilt HTML control Generated by controls Full Full Testability Poor Good Very good (built-in DI) Platform .NET Framework, IIS .NET Framework, IIS (System.Web) Cross-platform, Kestrel DI Third-party Third-party (Unity, Autofac, Ninject) Built in Version Year Highlights --- --- --- MVC 1.0 2009 Controllers, ASPX view engine, routing, HTML helpers MVC 2 2010 Areas, strongly typed helpers ( TextBoxFor ), data annotations validation, async controllers MVC 3 2011 Razor view engine, unobtrusive JavaScript validation, global filters, ViewBag , NuGet MVC 4 2012 Web API , mobile templates, async/await controllers ( Task<ActionResult ), bundling & minification MVC 5 2013 Attribute routing , ASP.NET Identity, authentication filters, filter overrides, Bootstrap templates, One ASP.NET MVC 5.1 / 5.2 2014 Enum helpers, attribute routing constraints, bug fixes; 5.2.x maintenance releases (latest 5.3.0 in 2023) The MVC 5 request life cycle (inside IIS + System.Web): text 1. Browser → IIS → ASP.NET pipeline (HttpApplication events, Global.asax) 2. UrlRoutingModule (PostResolveRequestCache) matches the URL against RouteTable.Routes 3. Matched route → MvcRouteHandler → creates MvcHandler (an IHttpHandler) 4. MvcHandler.ProcessRequest → ControllerBuilder → IControllerFactory (DefaultControllerFactory or your DI factory) creates the controller, e.g. ProductsController 5. Controller.Execute → ControllerActionInvoker: a. finds the action method (name + HTTP verb + selectors) b. Authentication filters → Authorization filters ([Authorize]) c. Model binding: route values, query string, form → action parameters; validation → ModelState d. Action filters OnActionExecuting → ACTION METHOD runs → OnActionExecuted e. Action returns an ActionResult (ViewResult, JsonResult, RedirectResult …) f. Result filters OnResultExecuting → ActionResult.ExecuteResult → OnResultExecuted 6. ViewResult → ViewEngines (RazorViewEngine) locate the .cshtml → compiled into a class → rendered with layout/partials → HTML 7. Exception filters handle errors at any step ([HandleError]) → Application Error as last resort 8. Response flows back through the remaining pipeline events (EndRequest) to the browser - Visual Studio with \"ASP.NET Web Application (.NET Framework)\" → MVC template; scaffolding (Add → Controller with views, using Entity Framework). - IIS / IIS Express; Glimpse (legacy request inspector); MiniProfiler; ELMAH for errors. - NuGet packages: Microsoft.AspNet.Mvc , Microsoft.AspNet.Razor , Microsoft.AspNet.Web.Optimization (bundling), Microsoft.AspNet.Identity. , Unity.Mvc5 / Autofac.Mvc5 . - Migration: .NET Upgrade Assistant, System.Web adapters, YARP for side-by-side migration."},{"kind":"lesson","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"mvc-5-folder-structure-explained","title":"MVC 5 folder structure explained","body":"text ShopMvc/ (ASP.NET Web Application, .NET Framework 4.8, MVC template) ├── App Data/ local database files, not web-accessible ├── App Start/ startup configuration called from Global.asax │ ├── RouteConfig.cs conventional routes (\"{controller}/{action}/{id}\") │ ├── FilterConfig.cs global filters (HandleErrorAttribute, AuthorizeAttribute) │ ├── BundleConfig.cs CSS/JS bundles and minification │ ├── IdentityConfig.cs, Startup.Auth.cs ASP.NET Identity + OWIN cookie authentication │ └── UnityConfig.cs dependency injection container (if added) ├── Areas/ sub-applications, each with its own Controllers/Models/Views │ └── Admin/ (AdminAreaRegistration.cs, Controllers/, Views/) ├── Content/ CSS (bootstrap.css, Site.css), images ├── Controllers/ HomeController.cs, ProductsController.cs, AccountController.cs ├── fonts/ icon fonts ├── Models/ entities, view models, DbContext (often moved to separate projects) ├── Scripts/ jQuery, jquery.validate, bootstrap.js, your JS ├── Views/ │ ├── Shared/ Layout.cshtml, Error.cshtml, partials ( LoginPartial.cshtml), EditorTemplates/, DisplayTemplates/ │ ├── Home/ Index.cshtml, About.cshtml (folder name = controller name) │ ├── Products/ Index.cshtml, Details.cshtml, Create.cshtml, Edit.cshtml │ ├── ViewStart.cshtml sets Layout for all views │ └── web.config Razor config (namespaces for views) + blocks direct access to .cshtml ├── Global.asax / Global.asax.cs Application Start: AreaRegistration, FilterConfig, RouteConfig, BundleConfig ├── Startup.cs OWIN startup (Identity, SignalR) ├── packages.config NuGet packages ├── Web.config (+ Web.Debug/Release.config transforms) └── ShopMvc.csproj Conventions: a controller class ends with Controller and lives in Controllers/ ; its views are in Views/<ControllerName /<ActionName .cshtml ; shared views in Views/Shared . Layered solutions usually add Shop.Core (domain), Shop.Data (EF/Dapper), Shop.Services projects referenced by the web project."},{"kind":"lesson","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"routing-conventional-and-attribute-routes","title":"Routing — conventional and attribute routes","body":"csharp // App Start/RouteConfig.cs public static class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute(\"{resource}.axd/{ pathInfo}\"); routes.MapMvcAttributeRoutes(); // enable [Route] attributes (MVC 5) routes.MapRoute( name: \"ProductBySlug\", url: \"products/{category}/{slug}\", defaults: new { controller = \"Products\", action = \"BySlug\" }); routes.MapRoute( name: \"Default\", url: \"{controller}/{action}/{id}\", defaults: new { controller = \"Home\", action = \"Index\", id = UrlParameter.Optional }); } } // Attribute routing [RoutePrefix(\"orders\")] public class OrdersController : Controller { [Route(\"\")] public ActionResult Index() = View(); [Route(\"{id:int}\")] public ActionResult Details(int id) = View( orders.Get(id)); [Route(\"customer/{customerId:int}/{year:int:min(2000)?}\")] public ActionResult ByCustomer(int customerId, int? year) = View(); } Routes are checked in order — put specific routes before the generic default. Url.Action(\"Details\", \"Orders\", new { id = 5 }) and Html.ActionLink generate URLs from routes, so URLs change in one place."},{"kind":"lesson","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"controllers-actions-and-action-results","title":"Controllers, actions and action results","body":"csharp public class ProductsController : Controller { private readonly IProductService products; public ProductsController(IProductService products) = products = products; // needs a DI container in MVC 5 public ActionResult Index(string q, int page = 1) = View( products.Search(q, page)); public ActionResult Details(int id) { var p = products.Get(id); if (p == null) return HttpNotFound(); return View(p); } [HttpGet] public ActionResult Create() = View(new ProductEditModel()); [HttpPost, ValidateAntiForgeryToken] public ActionResult Create(ProductEditModel model) { if (!ModelState.IsValid) return View(model); // redisplay with validation messages products.Add(model); TempData[\"Message\"] = \"Product created\"; return RedirectToAction(nameof(Index)); // Post-Redirect-Get pattern } public async Task<ActionResult Export() = File(await products.ExportCsvAsync(), \"text/csv\", \"products.csv\"); public JsonResult Lookup(string term) = Json( products.Lookup(term), JsonRequestBehavior.AllowGet); } ActionResult Helper Purpose --- --- --- ViewResult View() Render a view PartialViewResult PartialView() Render a partial (AJAX) RedirectToRouteResult RedirectToAction() Redirect to an action RedirectResult Redirect(url) Redirect to a URL JsonResult Json() JSON (GET needs AllowGet ) ContentResult Content() Plain text/HTML FileResult File() Downloads HttpStatusCodeResult / HttpNotFoundResult new HttpStatusCodeResult(400) / HttpNotFound() Status codes EmptyResult — Nothing Action selectors: [HttpGet] , [HttpPost] , [ActionName(\"Delete\")] , [NonAction] (public method that isn't an action), [ChildActionOnly] ."},{"kind":"lesson","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"razor-views-layouts-html-helpers-and-partial-views","title":"Razor views, layouts, HTML helpers and partial views","body":"cshtml @model ShopMvc.Models.ProductEditModel @{ ViewBag.Title = \"Create product\"; } <h2 @ViewBag.Title</h2 @using (Html.BeginForm(\"Create\", \"Products\", FormMethod.Post)) { @Html.AntiForgeryToken() @Html.ValidationSummary(true, \"\", new { @class = \"text-danger\" }) @Html.LabelFor(m = m.Name) @Html.TextBoxFor(m = m.Name, new { @class = \"form-control\" }) @Html.ValidationMessageFor(m = m.Name) @Html.DropDownListFor(m = m.CategoryId, Model.Categories, \"-- choose --\") @Html.EditorFor(m = m.Price) <button type=\"submit\" class=\"btn btn-primary\" Save</button } @Html.Partial(\" ProductTips\") @ partial view, uses current model unless passed @ @Html.Action(\"TopSellers\", \"Products\") @ child action: runs a controller action and renders its result @ @section scripts { @Scripts.Render(\"~/bundles/jqueryval\") } cshtml @ Views/Shared/ Layout.cshtml @ <!DOCTYPE html <html <head <title @ViewBag.Title - Divakar Shop</title @Styles.Render(\"~/Content/css\")</head <body @Html.Partial(\" LoginPartial\") <div class=\"container\" @RenderBody()</div @Scripts.Render(\"~/bundles/jquery\") @RenderSection(\"scripts\", required: false) </body </html Razor basics: @expression (HTML-encoded automatically), @{ code block } , @if/@foreach , @Html.Raw(x) (no encoding — dangerous), @ comment @ , @: text line. Views are compiled into classes deriving from WebViewPage<TModel the first time they are requested (or at build with MvcBuildViews ). Partial view vs child action: a partial renders a template with data you pass; a child action ( Html.Action ) runs a full controller action (with its own data access and filters) — useful for widgets like a cart summary on every page. (ASP.NET Core replaces child actions with view components.) Display/editor templates: Views/Shared/EditorTemplates/DateTime.cshtml customises Html.EditorFor for every DateTime property."},{"kind":"lesson","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"passing-data-viewdata-viewbag-tempdata-session-and-strongly-typed-models","title":"Passing data — ViewData, ViewBag, TempData, Session and strongly typed models","body":"Mechanism Type Lifetime Typical use --- --- --- --- Strongly typed model View(model) + @model One request The main data — IntelliSense, compile-time checks (preferred) ViewData ViewDataDictionary (string keys) Current request, controller → view Small extras ViewBag dynamic wrapper over ViewData Current request Title, small extras (no compile-time checking) TempData Dictionary backed by Session (default) Until read in a subsequent request Messages after redirect (Post-Redirect-Get) Session Session[\"key\"] User session Cart, wizard state TempData.Keep(\"key\") keeps a value for another request; TempData.Peek(\"key\") reads without marking it for deletion."},{"kind":"lesson","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"model-binding-and-validation","title":"Model binding and validation","body":"The DefaultModelBinder fills action parameters and complex objects from value providers : form fields, route data, query string, posted files — matching by name (including nested Address.City , indexed Lines[0].Qty ). csharp public class ProductEditModel { [Required, StringLength(200)] public string Name { get; set; } [Range(0.01, 1000000), DataType(DataType.Currency)] public decimal Price { get; set; } [Display(Name = \"Category\")] public int CategoryId { get; set; } [Remote(\"IsNameUnique\", \"Products\", ErrorMessage = \"Name already exists\")] // AJAX validation public string Code { get; set; } public IEnumerable<SelectListItem Categories { get; set; } } // Custom validation attribute public class FutureDateAttribute : ValidationAttribute { public override bool IsValid(object value) = value is DateTime d && d DateTime.Today; } - ModelState.IsValid after binding; add your own errors with ModelState.AddModelError(\"Name\", \"...\") . - Unobtrusive client validation (jquery.validate + jquery.validate.unobtrusive) uses data-val- attributes generated from the annotations — client validation is a convenience; server checks are mandatory. - IValidatableObject for cross-field rules; FluentValidation as an alternative library. - Over-posting/mass assignment: bind to view models (or [Bind(Include = \"Name,Price\")] ) — never bind directly to EF entities with sensitive fields like IsAdmin ."},{"kind":"lesson","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"filters-authentication-authorization-action-result-and-exception","title":"Filters — authentication, authorization, action, result and exception","body":"Filter (MVC 5) Interface Runs Built-in examples --- --- --- --- Authentication IAuthenticationFilter First — establishes identity Custom token checks Authorization IAuthorizationFilter Before model binding/action [Authorize] , [AllowAnonymous] , [RequireHttps] , [ValidateAntiForgeryToken] , [ChildActionOnly] Action IActionFilter Before/after the action method [OutputCache] (also result), custom logging/auditing Result IResultFilter Before/after the result executes Modify view data, timing Exception IExceptionFilter When an unhandled exception occurs [HandleError] csharp public class LogActionAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext ctx) = Trace.WriteLine($\"→ {ctx.ActionDescriptor.ControllerDescriptor.ControllerName}.{ctx.ActionDescriptor.ActionName}\"); public override void OnActionExecuted(ActionExecutedContext ctx) = Trace.WriteLine($\"← done, exception: {ctx.Exception?.Message}\"); } // Registration levels: global (FilterConfig), controller, action public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); // shows Views/Shared/Error.cshtml when customErrors is On filters.Add(new AuthorizeAttribute()); // whole site requires login ([AllowAnonymous] to opt out) filters.Add(new LogActionAttribute()); } } Order: authentication → authorization → (model binding) → action filters → action → action filters (after) → result filters → result → result filters (after); exception filters on errors. The Order property and scope (global → controller → action) control ordering."},{"kind":"lesson","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"dependency-injection-bundling-identity-and-web-api-2-in-mvc-5","title":"Dependency injection, bundling, Identity and Web API 2 in MVC 5","body":"Dependency injection — MVC 5 has no built-in container; plug one in through DependencyResolver : csharp // Unity.Mvc5 — App Start/UnityConfig.cs public static void RegisterComponents() { var container = new UnityContainer(); container.RegisterType<ShopDbContext (new PerRequestLifetimeManager()); container.RegisterType<IProductService, ProductService (); DependencyResolver.SetResolver(new UnityDependencyResolver(container)); } (Autofac: builder.RegisterControllers(...) , DependencyResolver.SetResolver(new AutofacDependencyResolver(container)) .) Bundling and minification: csharp bundles.Add(new ScriptBundle(\"~/bundles/jquery\").Include(\"~/Scripts/jquery-{version}.js\")); bundles.Add(new StyleBundle(\"~/Content/css\").Include(\"~/Content/bootstrap.css\", \"~/Content/site.css\")); BundleTable.EnableOptimizations = true; // or compilation debug=\"false\" in web.config ASP.NET Identity + OWIN: Startup.Auth.cs configures cookie authentication ( UseCookieAuthentication ), external logins (Google, Microsoft), UserManager / SignInManager with EF tables ( AspNetUsers , AspNetRoles ); [Authorize(Roles = \"Admin\")] protects actions. Web API 2 in the same project: ApiController classes under /api/... , configured in WebApiConfig.Register ( config.MapHttpAttributeRoutes() ), returning data with content negotiation (JSON/XML). MVC and Web API 2 have separate pipelines, filters and DI resolvers in .NET Framework — ASP.NET Core unifies them."},{"kind":"lesson","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"error-handling-custom-error-pages-and-logging-in-mvc-5","title":"Error handling, custom error pages and logging in MVC 5","body":"Layers of error handling: 1. try/catch in actions/services for expected failures (show a validation message, return 404/409). 2. Exception filters — [HandleError(ExceptionType = typeof(DbUpdateException), View = \"DatabaseError\")] or a custom IExceptionFilter that logs and shows a view (only for exceptions inside MVC actions/results). 3. Controller.OnException override — per-controller handling. 4. Application Error in Global.asax — catches everything else (routing errors, errors outside MVC), log and redirect. 5. web.config — customErrors (ASP.NET) and httpErrors (IIS) for friendly pages for 404/500. csharp public class GlobalExceptionFilter : IExceptionFilter { public void OnException(ExceptionContext ctx) { Log.Error(ctx.Exception, \"Unhandled error in {Controller}\", ctx.RouteData.Values[\"controller\"]); if (ctx.HttpContext.Request.IsAjaxRequest()) { ctx.Result = new JsonResult { Data = new { error = \"Something went wrong\" }, JsonRequestBehavior = JsonRequestBehavior.AllowGet }; ctx.HttpContext.Response.StatusCode = 500; } else ctx.Result = new ViewResult { ViewName = \"Error\" }; ctx.ExceptionHandled = true; ctx.HttpContext.Response.TrySkipIisCustomErrors = true; } } xml <system.web <customErrors mode=\"On\" defaultRedirect=\"~/Error\" <error statusCode=\"404\" redirect=\"~/Error/NotFound\" / </customErrors </system.web <system.webServer <httpErrors errorMode=\"Custom\" existingResponse=\"Replace\" <remove statusCode=\"404\" / <error statusCode=\"404\" path=\"/Error/NotFound\" responseMode=\"ExecuteURL\" / </httpErrors </system.webServer"},{"kind":"lesson","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"mvc-5-vs-aspdotnet-core-mvc-and-migration","title":"MVC 5 vs ASP.NET Core MVC and migration","body":"Topic MVC 5 (.NET Framework) ASP.NET Core MVC --- --- --- Hosting IIS only (System.Web) Kestrel, IIS, Linux, containers Startup Global.asax + App Start + web.config Program.cs (WebApplication builder) + appsettings.json Pipeline HttpModules/HttpHandlers Middleware DI Third-party via DependencyResolver Built in MVC + Web API Separate frameworks One framework ( ControllerBase ) Child actions Html.Action View components Helpers HTML helpers Tag helpers (+ HTML helpers) Bundling System.Web.Optimization Static files + build tools (Vite/Webpack/LibMan) or WebOptimizer Config ConfigurationManager.AppSettings IConfiguration , Options pattern Auth OWIN/Identity 2, Forms auth ASP.NET Core Identity, cookie/JWT handlers Static files Served by IIS UseStaticFiles() from wwwroot Migration path: move business/data logic into libraries; create a new ASP.NET Core project; port controllers (mostly the same code), views (mostly the same Razor, replace child actions and bundling), filters (similar interfaces), configuration and DI; use the .NET Upgrade Assistant and System.Web adapters ; for big apps migrate incrementally behind YARP (route migrated paths to the new app, the rest to the old app, share authentication)."},{"kind":"question","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"342","title":"What is MVC? Explain Model, View and Controller.","body":"An architectural pattern separating concerns: the Model holds data and business rules, the View renders the UI (Razor templates), and the Controller receives requests, works with the model/services and chooses the response. Benefits: testable controllers, clean URLs, full HTML control, parallel work on UI and logic."},{"kind":"question","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"343","title":"Explain the ASP.NET MVC 5 request life cycle.","body":"Request → IIS/ASP.NET pipeline → UrlRoutingModule matches a route → MvcRouteHandler → MvcHandler → controller factory creates the controller → ControllerActionInvoker selects the action → authentication and authorization filters → model binding and validation → action filters (before) → action executes and returns an ActionResult → action filters (after) → result filters → result executes (ViewResult → Razor view engine finds and renders the view) → response. Exception filters handle errors along the way."},{"kind":"question","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"344","title":"Describe the MVC 5 folder structure.","body":"Controllers (classes ending in Controller), Models , Views/<Controller /<Action .cshtml with Views/Shared for layouts/partials and ViewStart.cshtml , App Start (RouteConfig, FilterConfig, BundleConfig, IdentityConfig), Areas for modules with their own MVC folders, Content (CSS), Scripts (JS), App Data , Global.asax for startup, Web.config (plus Views/web.config for Razor settings)."},{"kind":"question","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"345","title":"ViewData vs ViewBag vs TempData?","body":"ViewData is a string-keyed dictionary and ViewBag a dynamic wrapper over the same data — both live only for the current request (controller → view). TempData survives until it is read in a subsequent request (stored in session by default), so it's used for messages after a redirect; Keep / Peek retain it longer. Prefer strongly typed view models for real data."},{"kind":"question","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"346","title":"What types of ActionResult are there?","body":"ViewResult ( View ), PartialViewResult, RedirectResult/RedirectToRouteResult ( Redirect , RedirectToAction ), JsonResult, ContentResult, FileResult ( File ), JavaScriptResult, HttpStatusCodeResult/HttpNotFoundResult, EmptyResult. Actions can also return plain types, which are converted to ContentResult."},{"kind":"question","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"347","title":"What are filters in MVC? Name the types and their order.","body":"Attributes/classes that run logic before or after stages of action execution: authentication filters, authorization filters ( [Authorize] ), action filters ( OnActionExecuting/Executed ), result filters ( OnResultExecuting/Executed ) and exception filters ( [HandleError] ). Order: authentication → authorization → action → result, with exception filters on errors; they can be applied globally, per controller or per action."},{"kind":"question","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"348","title":"Conventional routing vs attribute routing?","body":"Conventional routes are defined centrally ( MapRoute(\"{controller}/{action}/{id}\") ) and matched in order. Attribute routing (MVC 5, routes.MapMvcAttributeRoutes() ) puts [Route] / [RoutePrefix] on controllers/actions — clearer for REST-style or custom URLs, with inline constraints ( {id:int} ). Both can be combined; attribute routes are usually registered first."},{"kind":"question","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"349","title":"How does model binding and validation work?","body":"The DefaultModelBinder uses value providers (form, route, query string, files) to fill action parameters by name, including complex and nested objects and collections. Data annotations and IValidatableObject validate the model; errors go into ModelState , checked with ModelState.IsValid . Unobtrusive jQuery validation mirrors the rules on the client. Use view models to avoid over-posting."},{"kind":"question","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"350","title":"Partial view vs child action (vs view component in Core)?","body":"A partial view is a reusable template rendered with data you pass ( Html.Partial ). A child action ( Html.Action ) invokes a controller action that loads its own data and returns a partial — for self-contained widgets. ASP.NET Core removed child actions in favour of view components, which are lighter (no full action pipeline)."},{"kind":"question","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"351","title":"How do you implement dependency injection in MVC 5?","body":"Use a container (Unity, Autofac, Ninject, Simple Injector), register services with lifetimes (per-request for DbContext), and set it as the MVC DependencyResolver (and a separate resolver for Web API 2). The controller factory then constructs controllers with their dependencies through constructor injection."},{"kind":"question","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"352","title":"What is the Post-Redirect-Get pattern and why use it?","body":"After a successful POST, redirect (302) to a GET action instead of returning a view. It prevents duplicate submissions when the user refreshes, gives a clean URL, and pairs with TempData for success messages."},{"kind":"question","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"353","title":"How do you prevent CSRF and XSS in MVC 5?","body":"CSRF: @Html.AntiForgeryToken() in forms and [ValidateAntiForgeryToken] on POST actions (plus SameSite cookies). XSS: Razor encodes @ output by default — avoid Html.Raw on user input, validate input, use Content Security Policy. Also [Authorize] , HTTPS, parameterised queries, and view models against over-posting."},{"kind":"question","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"354","title":"How do you handle errors globally in MVC 5?","body":"Register a global exception filter ( HandleErrorAttribute or a custom IExceptionFilter ) for errors inside controllers/views, override OnException where needed, use Application Error in Global.asax for everything else (including 404s from routing), log with a logging framework, and configure customErrors / httpErrors for friendly error pages with correct status codes."},{"kind":"question","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"355","title":"What are Areas and when do you use them?","body":"Areas divide a large MVC application into functional sections (Admin, Billing, Reports), each with its own Controllers, Models and Views and route registration ( AreaRegistration ). They keep large projects organised and allow same-named controllers in different areas. In ASP.NET Core they work similarly with [Area(\"Admin\")] ."},{"kind":"question","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"356","title":"You must migrate a large MVC 5 app to ASP.NET Core without stopping feature work. How?","body":"Incremental migration: create an ASP.NET Core app in front with YARP proxying unmigrated routes to the MVC 5 app; share authentication (shared cookie/data protection or a common identity provider) and session via System.Web adapters; move shared logic into netstandard libraries; migrate controller by controller (largely copy with small changes), replace child actions with view components, bundling with a build tool, HttpContext.Current usages with injected services; delete old routes as they move."},{"kind":"question","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"357","title":"An action returns stale data because of `[OutputCache]`. How do you fix it while keeping performance?","body":"Review the cache key: vary by the right parameters ( VaryByParam , VaryByCustom for user/culture), shorten the duration, use Location = Client / None for per-user data, or move to data caching in the service layer with explicit invalidation when data changes (remove the cache entry on update). Never cache personalised pages server-side without varying by user."},{"kind":"cheat","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"1","title":"Request life cycle","body":"UrlRoutingModule → MvcRouteHandler → MvcHandler → ControllerFactory → ActionInvoker → authN/authZ filters → model binding → action filters → action → result filters → ActionResult.ExecuteResult → view engine → response."},{"kind":"cheat","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"2","title":"Folders","body":"App Start (Route/Filter/Bundle/Identity config) · Controllers · Models · Views (+Shared, ViewStart, web.config) · Areas · Content · Scripts · Global.asax · Web.config."},{"kind":"cheat","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"3","title":"Data to views","body":"Strongly typed model ViewData/ViewBag (this request) · TempData (next request) · Session (user)."},{"kind":"cheat","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"4","title":"Filters","body":"Authentication → Authorization → Action → Result · Exception · global/controller/action scope."},{"kind":"cheat","course_slug":"aspnet-mvc5","course_title":"ASP.NET MVC 5 (.NET Framework) — Folder Structure, Request Life Cycle and Features","ref":"5","title":"MVC 5 → Core","body":"Global.asax → Program.cs · modules → middleware · child actions → view components · HTML helpers → tag helpers · DependencyResolver → built-in DI · separate Web API → unified controllers."},{"kind":"course","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"","title":"Modern .NET — Hosting, Configuration, DI & Deployment","body":".NET Framework vs .NET Core vs modern .NET, CLR, JIT/AOT, GC, assemblies, NuGet, the generic host, configuration, DI, logging, support lifecycle and deployment models. .NET is Microsoft's free, open-source, cross-platform developer platform. Today \" .NET \" (5, 6, 7, 8, 9, 10…) means the unified, cross-platform successor of .NET Core . The older .NET Framework (1.0–4.8.1) is Windows-only and in maintenance mode. .NET Framework .NET Core / modern .NET --- --- --- Platforms Windows only Windows, Linux, macOS Open source Reference source only Fully open source (github.com/dotnet) Latest 4.8.1 (2022), maintenance only .NET 10 (Nov 2025, LTS) Web ASP.NET (System.Web), Web Forms, MVC 5, Web API 2, WCF server ASP.NET Core (MVC, Razor Pages, Web API, Minimal APIs, Blazor, SignalR, gRPC) Deployment Machine-wide install Side-by-side, self-contained, single-file, containers, Native AOT Performance Good Much faster (Span, tiered JIT, PGO) Building blocks: runtime (CLR, GC, JIT), libraries (BCL), SDK (compilers, dotnet CLI, MSBuild), ASP.NET Core and Windows Desktop runtimes. Version Released Type Notes / support end --- --- --- --- .NET Framework 1.0 2002 — First release with C 1.0 .NET Framework 2.0 / 3.5 2005 / 2007 — Generics; LINQ, WCF, WPF (3.0) .NET Framework 4.0 → 4.8.1 2010 → 2022 — TPL, async (4.5); 4.8.1 is the last version, supported with Windows .NET Core 1.0 Jun 2016 — Cross-platform rewrite .NET Core 2.1 / 3.1 2018 / 2019 LTS 3.1 added WPF/WinForms on Windows; 3.1 ended Dec 2022 .NET 5 Nov 2020 STS \"Core\" dropped from the name; one .NET .NET 6 Nov 2021 LTS Minimal APIs, hot reload, MAUI (later); ended Nov 2024 .NET 7 Nov 2022 STS Rate limiting, output caching; ended May 2024 .NET 8 Nov 2023 LTS Native AOT for ASP.NET Core, keyed DI, Blazor full-stack; support ends 10 Nov 2026 .NET 9 Nov 2024 STS HybridCache, Lock type, OpenAPI built in; STS support was extended to 24 months, so it also ends 10 Nov 2026 .NET 10 Nov 2025 LTS C 14, supported until Nov 2028 Release cadence: a new major version every November . Even numbers are LTS (3 years of support); odd numbers are STS (24 months since .NET 9; previously 18). Monthly patch releases (\"Patch Tuesday\"). Application startup lifecycle (generic host / ASP.NET Core): 1. Main / top-level statements run. 2. WebApplication.CreateBuilder(args) (or Host.CreateApplicationBuilder ) creates the host builder: loads configuration (appsettings.json → appsettings.{Environment}.json → user secrets in Development → environment variables → command line), sets up logging and the DI container . 3. You register services: builder.Services.Add... . 4. builder.Build() builds the service provider and the app. 5. You configure the middleware pipeline ( app.Use... ) and endpoints. 6. app.Run() starts the host: IHostedService.StartAsync for each hosted service, then Kestrel listens. 7. Requests are processed through middleware → endpoint. 8. On shutdown (Ctrl+C / SIGTERM): IHostApplicationLifetime.ApplicationStopping fires, hosted services StopAsync , the container disposes singletons. Build/compile lifecycle: source → Roslyn → IL assembly (.dll) + metadata + PDB → (publish) → at runtime JIT → native code. With Native AOT , IL is compiled to a native executable at publish time (no JIT, fast startup, smaller memory, but no runtime code generation and limited reflection). Support lifecycle: Preview → RC (go-live) → GA (November) → patches → end of support (LTS 3 years, STS 2 years). Tool Purpose --- --- dotnet CLI new , build , run , test , publish , add package , tool install , --info Visual Studio 2022/2026, VS Code + C Dev Kit, Rider IDEs MSBuild / .csproj (SDK-style) Build system NuGet / nuget.org, Azure Artifacts Packages and private feeds global.json Pin SDK version Directory.Build.props , Directory.Packages.props Shared build settings, central package management dotnet-counters, dotnet-trace, dotnet-dump, dotnet-gcdump Runtime diagnostics PerfView, Visual Studio profiler Performance analysis .NET Upgrade Assistant / GitHub Copilot app modernization Migrate .NET Framework → modern .NET ILSpy, dotPeek Decompile assemblies"},{"kind":"lesson","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"dotnet-framework-vs-dotnet-core-vs-dotnet-5","title":".NET Framework vs .NET Core vs .NET 5+","body":"- .NET Framework (2002–): Windows-only, installed machine-wide, tied to Windows updates. Last version 4.8.1. Still supported for existing apps, but receives no new features. ASP.NET Web Forms, WCF server and Windows Workflow live here. - .NET Core (2016–2019): open source, cross-platform, modular, side-by-side versions, high performance. - .NET 5+ (2020–): the unification — one .NET for cloud, web, desktop, mobile (MAUI), games and IoT. Version 4 was skipped to avoid confusion with .NET Framework 4.x. - .NET Standard (2.0, 2.1): a specification of APIs shared across implementations; target netstandard2.0 only when a library must also run on .NET Framework. New libraries target net8.0 / net10.0 . xml <!-- SDK-style project -- <Project Sdk=\"Microsoft.NET.Sdk.Web\" <PropertyGroup <TargetFramework net10.0</TargetFramework <Nullable enable</Nullable <ImplicitUsings enable</ImplicitUsings </PropertyGroup <ItemGroup <PackageReference Include=\"Dapper\" Version=\"2.1.66\" / </ItemGroup </Project"},{"kind":"lesson","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"assemblies-namespaces-nuget-and-project-structure","title":"Assemblies, namespaces, NuGet and project structure","body":"- Assembly — the unit of deployment and versioning ( .dll / .exe ) containing IL, metadata and a manifest. No GAC in modern .NET (the GAC exists only in .NET Framework). - Namespace — logical grouping of types; one assembly can contain many namespaces and vice versa. - NuGet package ( .nupkg ) — zip with assemblies for one or more target frameworks plus dependencies. - Solution ( .sln or the newer .slnx ) contains projects; a project produces one assembly. bash dotnet new sln -n Shop dotnet new webapi -n Shop.Api dotnet new classlib -n Shop.Core dotnet sln add Shop.Api Shop.Core dotnet add Shop.Api reference Shop.Core dotnet add Shop.Api package Microsoft.EntityFrameworkCore.SqlServer Deep dive: how the CLR, JIT, memory and the garbage collector work inside is covered in the .NET Internals: CLR, Memory & GC course."},{"kind":"lesson","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"generic-host-and-program-cs","title":"Generic host and Program.cs","body":"csharp var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddDbContext<AppDbContext (o = o.UseSqlServer(builder.Configuration.GetConnectionString(\"Db\"))); builder.Services.AddHostedService<OutboxPublisher (); // background worker var app = builder.Build(); if (app.Environment.IsDevelopment()) app.MapOpenApi(); app.UseHttpsRedirection(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run(); Non-web apps (worker services, console tools) use Host.CreateApplicationBuilder(args) and get the same configuration/DI/logging. csharp public class OutboxPublisher(ILogger<OutboxPublisher log, IServiceScopeFactory scopes) : BackgroundService { protected override async Task ExecuteAsync(CancellationToken stoppingToken) { using var timer = new PeriodicTimer(TimeSpan.FromSeconds(10)); while (await timer.WaitForNextTickAsync(stoppingToken)) { using var scope = scopes.CreateScope(); var db = scope.ServiceProvider.GetRequiredService<AppDbContext (); // publish pending messages... } } }"},{"kind":"lesson","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"configuration-and-the-options-pattern","title":"Configuration and the Options pattern","body":"Sources, later overrides earlier: appsettings.json → appsettings.{ASPNETCORE ENVIRONMENT}.json → User Secrets (Development) → environment variables → command-line args. Also Azure Key Vault and Azure App Configuration providers. json { \"ConnectionStrings\": { \"Db\": \"Server=.;Database=Shop;Trusted Connection=True;TrustServerCertificate=True\" }, \"Smtp\": { \"Host\": \"smtp.example.com\", \"Port\": 587 } } csharp var host = builder.Configuration[\"Smtp:Host\"]; // ':' separates sections // env var override: Smtp Host=smtp.prod.example.com (' ' in environment variables) builder.Services.AddOptions<SmtpOptions ().BindConfiguration(\"Smtp\").ValidateDataAnnotations().ValidateOnStart(); bash dotnet user-secrets init dotnet user-secrets set \"Smtp:Password\" \"local-only-secret\""},{"kind":"lesson","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"built-in-dependency-injection","title":"Built-in dependency injection","body":"csharp builder.Services.AddTransient<IEmailBuilder, EmailBuilder (); builder.Services.AddScoped<IOrderService, OrderService (); builder.Services.AddSingleton<IClock, SystemClock (); builder.Services.AddKeyedScoped<IPaymentGateway, RazorpayGateway (\"razorpay\"); // .NET 8 builder.Services.TryAddSingleton<ICache, MemoryCacheAdapter (); // only if not registered public class CheckoutController([FromKeyedServices(\"razorpay\")] IPaymentGateway gateway) : ControllerBase { } - Constructor injection preferred; [FromServices] for action parameters; IServiceProvider only in factories/composition roots (avoid the Service Locator anti-pattern). - Validation in Development catches scope problems ( ValidateScopes , ValidateOnBuild ). - Third-party containers (Autofac) plug in via UseServiceProviderFactory for features like interception/modules."},{"kind":"lesson","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"logging-opentelemetry-and-health-checks","title":"Logging, OpenTelemetry and health checks","body":"csharp builder.Logging.ClearProviders().AddConsole(); // providers: Console, Debug, EventLog, Application Insights, Serilog... builder.Services.AddOpenTelemetry() .WithTracing(t = t.AddAspNetCoreInstrumentation().AddHttpClientInstrumentation().AddOtlpExporter()) .WithMetrics(m = m.AddAspNetCoreInstrumentation().AddRuntimeInstrumentation().AddOtlpExporter()); builder.Services.AddHealthChecks().AddSqlServer(connStr); // AspNetCore.HealthChecks.SqlServer package app.MapHealthChecks(\"/health\"); Log levels: Trace < Debug < Information < Warning < Error < Critical. Configure per category in appsettings.json → Logging:LogLevel . .NET Aspire (now just \"Aspire\") gives a dev-time orchestrator and dashboard with OpenTelemetry out of the box."},{"kind":"lesson","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"deployment-models-and-hosting","title":"Deployment models and hosting","body":"Model What ships When --- --- --- Framework-dependent Your DLLs; runtime installed on server Smallest output; shared runtime patched by ops Self-contained Your app + runtime No runtime install needed; bigger Single-file One executable Easy distribution Native AOT Native binary, no JIT Fast startup, low memory: serverless, containers, CLIs Container Docker image ( mcr.microsoft.com/dotnet/aspnet:10.0 ) Kubernetes, Azure Container Apps Hosting ASP.NET Core: Kestrel (built-in cross-platform web server) behind IIS (in-process via the ASP.NET Core Module, or out-of-process), Nginx/Apache, Azure App Service, containers or YARP. dotnet publish -c Release produces the deployable output. .NET SDK can build container images without a Dockerfile: dotnet publish -t:PublishContainer ."},{"kind":"lesson","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"performance-features-of-modern-dotnet","title":"Performance features of modern .NET","body":"- Span<T / Memory<T , ArrayPool<T , stackalloc — fewer allocations. - System.Text.Json (fast, source-generated) instead of Newtonsoft for new code. - Tiered compilation + Dynamic PGO, ReadyToRun, Native AOT. - ValueTask , IAsyncEnumerable , System.IO.Pipelines , Channel<T . - FrozenDictionary / FrozenSet (.NET 8) for read-heavy lookups; SearchValues<T for fast searches. - Output caching, response compression, HybridCache (.NET 9). - Measure with BenchmarkDotNet; profile with dotnet-trace / PerfView before optimising."},{"kind":"lesson","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"migrating-from-dotnet-framework-to-modern-dotnet","title":"Migrating from .NET Framework to modern .NET","body":"1. Inventory: target framework, NuGet packages, use of System.Web , WCF, Web Forms, AppDomains, Remoting, Windows-only APIs. 2. Upgrade dependencies to versions that support .NET Standard 2.0 / modern .NET. 3. Convert projects to SDK-style .csproj ; move class libraries to netstandard2.0 or multi-target first. 4. Use .NET Upgrade Assistant (or GitHub Copilot app modernization) to automate conversions. 5. ASP.NET MVC/Web API → ASP.NET Core (incrementally with YARP reverse proxy + System.Web adapters — Strangler Fig). 6. Replace: web.config app settings → appsettings.json + Options; HttpContext.Current → injected IHttpContextAccessor ; Global.asax → Program.cs middleware; WCF server → gRPC/REST or CoreWCF; EF6 → EF Core (or keep EF6, which runs on .NET Core 3.1+). 7. Test thoroughly, benchmark, deploy side by side, switch traffic gradually."},{"kind":"question","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"358","title":"What is the difference between .NET Framework, .NET Core and .NET 5/6/8/10?","body":".NET Framework is the original Windows-only implementation (last version 4.8.1, maintenance only). .NET Core was a cross-platform, open-source, high-performance rewrite (2016–2019). From .NET 5 (2020) the platform is unified as just \".NET\", the successor of .NET Core, with yearly November releases (even = LTS, 3 years; odd = STS, 2 years). New projects should target the current LTS, .NET 10."},{"kind":"question","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"359","title":"What is the CLR and what does it do?","body":"The Common Language Runtime is .NET's execution engine. It loads assemblies, verifies and JIT-compiles IL to native code, manages memory with the garbage collector, enforces type safety, handles exceptions, manages threads and the thread pool, and provides interop with native code. Code running under the CLR is \"managed code\"."},{"kind":"question","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"360","title":"What is JIT compilation? What are ReadyToRun and Native AOT?","body":"JIT (Just-In-Time) compiles IL to machine code at runtime, the first time each method is called. Tiered compilation first produces quick code, then re-optimises hot methods, with Dynamic PGO using live profiling. ReadyToRun ships precompiled code inside assemblies to cut startup time, while keeping JIT as a fallback. Native AOT compiles the entire app to a native executable at publish time: fastest startup, smallest memory, no JIT. The cost is no dynamic code generation and limited reflection, so it needs trimming-compatible libraries."},{"kind":"question","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"361","title":"What are LTS and STS releases?","body":"LTS (Long-Term Support) releases ship in even-numbered years' November (.NET 6, 8, 10) and get 3 years of free patches. STS (Standard-Term Support) releases are odd-numbered (.NET 7, 9) and get 24 months of support (18 months before .NET 9). Enterprises usually standardise on LTS. Both .NET 8 and .NET 9 reach end of support on 10 November 2026, and .NET 10 is supported until November 2028."},{"kind":"question","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"362","title":"What is an assembly? What is the GAC?","body":"An assembly is a compiled unit ( .dll / .exe ) containing IL code, type metadata, a manifest (name, version, culture, references) and resources. It is the unit of deployment, versioning and security. The Global Assembly Cache was a machine-wide store for strongly named shared assemblies in .NET Framework. Modern .NET has no GAC: each app carries its dependencies, or uses the shared framework installed side by side."},{"kind":"question","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"363","title":"What is .NET Standard? Do I still need it?","body":".NET Standard is a formal specification of APIs available on all .NET implementations (2.0 is the widely used version; 2.1 is not supported by .NET Framework). Target netstandard2.0 only if a library must also be consumed by .NET Framework apps. Otherwise target modern TFMs like net8.0 / net10.0 , or multi-target <TargetFrameworks net48;net8.0</TargetFrameworks ."},{"kind":"question","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"364","title":"Explain the order of configuration sources in ASP.NET Core.","body":"Default for WebApplication.CreateBuilder : appsettings.json → appsettings.{Environment}.json → User Secrets (Development only) → environment variables → command-line arguments. Later sources override earlier ones, so env vars in production override JSON files. Hierarchical keys use : in code ( Smtp:Host ) and in environment variables ( Smtp Host ). Production secrets belong in Azure Key Vault or the hosting platform's secret store, not in JSON."},{"kind":"question","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"365","title":"What is the difference between IOptions, IOptionsSnapshot and IOptionsMonitor?","body":"IOptions<T is a singleton that reads values once at first use and never reloads. IOptionsSnapshot<T is scoped and recomputed per request, so it picks up config file changes between requests; it can't be injected into singletons. IOptionsMonitor<T is a singleton that always returns the current value via CurrentValue and offers OnChange callbacks; use it in singletons and background services."},{"kind":"question","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"366","title":"What is a BackgroundService / IHostedService?","body":"IHostedService has StartAsync / StopAsync , called by the host at startup and shutdown. BackgroundService is a base class where you implement ExecuteAsync(CancellationToken) for long-running loops: queue consumers, schedulers, outbox publishers. It's registered as a singleton via AddHostedService<T () , so create DI scopes for scoped services. Honour the stopping token for graceful shutdown. For complex schedules, use Quartz.NET or Hangfire."},{"kind":"question","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"367","title":"What is Kestrel? Do you still need IIS?","body":"Kestrel is ASP.NET Core's built-in, cross-platform, high-performance web server. It can face the internet directly. A reverse proxy (IIS, Nginx, Azure Front Door, YARP) is still often used for TLS termination, port sharing, load balancing and static file caching. On Windows, IIS hosts ASP.NET Core through the ASP.NET Core Module, in-process (default, fastest) or out-of-process (proxying to Kestrel)."},{"kind":"question","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"368","title":"Framework-dependent vs self-contained deployment?","body":"Framework-dependent: small output, but requires the matching .NET runtime on the server. Ops can patch the runtime centrally. Self-contained: includes the runtime for a specific RID (e.g. linux-x64 ), so nothing needs installing, but the output is bigger and you must republish to get runtime patches. Containers make this mostly moot: the base image provides the runtime."},{"kind":"question","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"369","title":"How does the .NET garbage collector work? Workstation vs Server GC?","body":"It's a generational, mark-and-compact (tracing) collector. It marks objects reachable from roots, then sweeps or compacts Gen 0/1/2; the LOH holds objects of 85,000 bytes or more and is collected with Gen 2. Collections are triggered by allocation budgets. Workstation GC uses one heap, tuned for responsiveness on client apps. Server GC uses a heap and GC thread per core for throughput and is the ASP.NET Core default; DATAS in .NET 9+ adapts the heap count dynamically. Background GC collects Gen 2 concurrently while Gen 0/1 collections continue."},{"kind":"question","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"370","title":"What are the limitations of Native AOT?","body":"No runtime code generation ( Reflection.Emit , some dynamic proxies), limited reflection (trimming removes unused code, so you need source generators or annotations), no dynamic assembly loading, and a platform-specific build per OS/architecture. Some libraries are incompatible: classic EF Core full model building has AOT limitations, MVC controllers are not supported (Minimal APIs are). It's best for microservices, serverless functions and CLI tools where startup time and memory matter."},{"kind":"question","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"371","title":"How would you migrate a large ASP.NET MVC 5 app on .NET Framework 4.8 to .NET 10?","body":"Incrementally, with the Strangler Fig pattern. Put a new ASP.NET Core app with YARP in front, which proxies unknown routes to the old app. Use System.Web adapters to share session/auth. Move class libraries to netstandard2.0 /multi-target first, then migrate controllers and views route by route, replacing System.Web dependencies, HttpContext.Current , web.config settings and Global.asax with modern equivalents. Use the Upgrade Assistant for mechanical changes. EF6 can stay initially (it runs on modern .NET) and move to EF Core later. Ship each slice to production behind the proxy."},{"kind":"question","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"372","title":"Your ASP.NET Core API on .NET 8 must keep getting security patches after November 2026. What do you do and when?","body":".NET 8 reaches end of support on 10 November 2026, after which there are no security fixes. Plan the upgrade to .NET 10 (LTS, supported to Nov 2028) well before then. Bump the TargetFramework, update Microsoft. and EF Core packages to 10.x, read the breaking-changes docs, run the full test suite, fix analyzer warnings, update the Docker base images ( aspnet:10.0 ) and CI SDK versions ( global.json , the UseDotNet task), deploy to staging, run load tests, then roll out. Budget time for third-party packages that lag behind."},{"kind":"question","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"373","title":"An API's CPU is fine but requests queue up and latency spikes under load. Thread count keeps growing. What's happening?","body":"That points to thread-pool starvation : synchronous blocking ( .Result , .Wait() , sync I/O, Thread.Sleep ) inside request handling. Each blocked thread waits on I/O, the pool injects new threads slowly (about one or two per second), and requests queue. Confirm with dotnet-counters (ThreadPool Queue Length and Thread Count rising) and dotnet-stack /a dump showing blocked threads. Fix by going async end to end, using async DB/HTTP APIs, and removing sync-over-async."},{"kind":"question","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"374","title":"Configuration works locally but in Azure App Service the app uses the wrong connection string. How do you debug it?","body":"Check ASPNETCORE ENVIRONMENT on the App Service (it decides which appsettings.{env}.json loads). App Service Connection strings and App settings become environment variables and override JSON. Check the key names ( ConnectionStrings Db , or the connection-strings section with the right type). Check slot settings after a swap and Key Vault references resolving (managed identity permissions). Log the configuration source (never the secret value) at startup, or use builder.Configuration.GetDebugView() locally."},{"kind":"cheat","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"1","title":"Versions and support","body":"Version Type Support ends --- --- --- .NET Framework 4.8.1 Legacy With Windows (no new features) .NET 6 LTS Nov 2024 (ended) .NET 7 STS May 2024 (ended) .NET 8 LTS 10 Nov 2026 .NET 9 STS 10 Nov 2026 .NET 10 LTS Nov 2028 New major every November · even = LTS (3 yrs) · odd = STS (2 yrs)."},{"kind":"cheat","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"2","title":"Runtime terms","body":"CLR (runtime) · IL (intermediate code) · JIT (runtime compile) · tiered compilation + Dynamic PGO · R2R (precompiled) · Native AOT · CTS/CLS · BCL · GC Gen 0/1/2 + LOH (≥ 85 KB) + POH · Workstation vs Server GC."},{"kind":"cheat","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"3","title":"dotnet CLI","body":"bash dotnet --info / --list-sdks dotnet new webapi -n Api dotnet add package Serilog.AspNetCore dotnet build -c Release dotnet test --collect:\"XPlat Code Coverage\" dotnet publish -c Release -r linux-x64 --self-contained dotnet publish -t:PublishContainer dotnet user-secrets set \"Key\" \"Value\" dotnet tool install -g dotnet-ef"},{"kind":"cheat","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"4","title":"Configuration order (last wins)","body":"appsettings.json → appsettings.{Env}.json → user secrets (Dev) → env vars ( A B ) → command line."},{"kind":"cheat","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"5","title":"Options","body":"IOptions (singleton, once) · IOptionsSnapshot (scoped, per request) · IOptionsMonitor (singleton, live + OnChange)."},{"kind":"cheat","course_slug":"dotnet-platform","course_title":"Modern .NET — Hosting, Configuration, DI & Deployment","ref":"6","title":"DI lifetimes","body":"Transient · Scoped (per request) · Singleton · Keyed (.NET 8) · no scoped-in-singleton."},{"kind":"course","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"","title":"ASP.NET Core MVC (and Razor Pages)","body":"The MVC pattern, request lifecycle, routing, controllers, model binding and validation, Razor views, layouts, tag helpers, view components, filters, state management, Identity and security. ASP.NET Core MVC is a framework for building server-rendered web apps using the Model–View–Controller pattern on top of the ASP.NET Core pipeline. - Model — data and business rules (entities, view models, validation). - View — the UI, written in Razor ( .cshtml — HTML + C ). - Controller — handles the request, calls services, picks a view or result. The same framework also offers Razor Pages (page-focused: each .cshtml has a PageModel ), Web API controllers (JSON, no views — next course) and Blazor (component-based UI in C ). Interview focus areas: request lifecycle, routing, model binding/validation, filters, ViewData / ViewBag / TempData , partial views vs view components, tag helpers, authentication/authorisation, antiforgery. Version Year Highlights --- --- --- ASP.NET MVC 1–5 2009–2013 On .NET Framework / System.Web; MVC 5 + Web API 2 were separate frameworks ASP.NET Core 1.0 2016 Rewrite: cross-platform, Kestrel, built-in DI; MVC and Web API unified ASP.NET Core 2.0 2017 Razor Pages , Microsoft.AspNetCore.All metapackage ASP.NET Core 2.1 / 2.2 2018 [ApiController] , HTTPS by default, GDPR features, SignalR, Identity UI as Razor Class Library ASP.NET Core 3.0 / 3.1 2019 Endpoint routing , Blazor Server, generic host, System.Text.Json ASP.NET Core 5 / 6 2020 / 2021 Minimal hosting model ( WebApplication ), Minimal APIs, hot reload ASP.NET Core 7 2022 Rate limiting, output caching middleware ASP.NET Core 8 2023 Blazor Web App (static SSR + interactivity), Identity API endpoints, keyed DI, AOT for minimal APIs ASP.NET Core 9 2024 MapStaticAssets (fingerprinted, compressed static files), built-in OpenAPI, HybridCache ASP.NET Core 10 2025 Ships with .NET 10 (LTS): validation for Minimal APIs, OpenAPI 3.1, passkey support in Identity, Blazor improvements MVC request lifecycle (in order): 1. Request arrives at Kestrel (possibly via IIS/Nginx). 2. Middleware pipeline runs in registration order: exception handler → HSTS/HTTPS redirection → static files → routing → CORS → authentication → authorization → session → endpoints. 3. Endpoint routing matches the URL to a controller action (conventional or attribute routes). 4. Controller creation — the controller factory creates the controller via DI. 5. Filter pipeline begins: authorization filters → resource filters (before) → model binding → model validation → action filters (OnActionExecuting). 6. Action method executes and returns an IActionResult ( View() , RedirectToAction() , Json() , ...). 7. Action filters (OnActionExecuted) → result filters (OnResultExecuting). 8. Result execution — for ViewResult , the view engine finds the .cshtml , runs ViewStart , layout, view, partials/view components, and writes HTML. 9. Result filters (OnResultExecuted) → resource filters (after). 10. Exception filters handle unhandled exceptions from controller/action stages. 11. Response flows back out through middleware to the client. Razor view lifecycle: ViewImports.cshtml (usings, tag helpers) → ViewStart.cshtml (sets Layout ) → view body renders → @RenderBody() in the layout → @RenderSection(\"Scripts\", required: false) . - Visual Studio — MVC templates, scaffolding (controllers + views from a model), Razor IntelliSense, Browser Link, Hot Reload. - dotnet new mvc , dotnet new webapp (Razor Pages), dotnet aspnet-codegenerator (scaffolding CLI). - LibMan / npm — client libraries (Bootstrap, jQuery validation). - ASP.NET Core Identity + scaffolded Identity UI. - Browser DevTools , Fiddler , Postman — inspect requests. - Glimpse-style diagnostics : app.UseDeveloperExceptionPage() (default in Development), logging."},{"kind":"lesson","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"project-and-folder-structure-every-folder-and-file-explained","title":"Project and folder structure — every folder and file explained","body":"dotnet new mvc -n MyShop.Web (or Visual Studio → \"ASP.NET Core Web App (Model-View-Controller)\") creates: text MyShop.Web/ ├── Connected Services/ (VS only) service references ├── Dependencies/ (VS only) view of NuGet packages, frameworks, analyzers ├── Properties/ │ └── launchSettings.json local run profiles: URLs/ports, environment (ASPNETCORE ENVIRONMENT=Development) — NOT used in production ├── wwwroot/ the web root: the ONLY folder served as static files │ ├── css/site.css │ ├── js/site.js │ ├── lib/ client libraries (bootstrap, jquery, jquery-validation) │ └── favicon.ico ├── Controllers/ │ └── HomeController.cs classes ending in \"Controller\", deriving from Controller ├── Models/ │ └── ErrorViewModel.cs view models / DTOs (domain entities usually live in other projects) ├── Views/ │ ├── ViewImports.cshtml @using namespaces + @addTagHelper for ALL views in this folder and below │ ├── ViewStart.cshtml code run before every view — normally sets Layout = \" Layout\" │ ├── Home/ one folder per controller │ │ ├── Index.cshtml view for HomeController.Index() │ │ └── Privacy.cshtml │ └── Shared/ views searched by every controller │ ├── Layout.cshtml master layout (<html , <head , nav, @RenderBody(), footer) │ ├── Layout.cshtml.css CSS isolation for the layout (scoped CSS) │ ├── ValidationScriptsPartial.cshtml jquery validation scripts partial │ └── Error.cshtml error page used by UseExceptionHandler(\"/Home/Error\") ├── appsettings.json configuration for all environments (logging, connection strings, options) ├── appsettings.Development.json overrides for Development (merged on top) ├── Program.cs app entry point: builds the host, registers services (DI), defines the middleware pipeline and routes └── MyShop.Web.csproj SDK-style project: <Project Sdk=\"Microsoft.NET.Sdk.Web\" , target framework, package references Folders that real projects usually add: text ├── Areas/Admin/Controllers, Views, ... feature sections with their own controllers/views ([Area(\"Admin\")]) ├── ViewComponents/ reusable widgets with logic (CartSummaryViewComponent.cs) │ └── (views in Views/Shared/Components/CartSummary/Default.cshtml) ├── TagHelpers/ custom tag helpers ├── Filters/ action/exception filters ├── Middleware/ custom middleware classes ├── Services/ application services (or a separate class library) ├── Data/ DbContext, migrations, seed data (or Infrastructure project) ├── Extensions/ IServiceCollection extension methods (AddShopServices) ├── Resources/ .resx files for localisation └── Properties/PublishProfiles/ publish settings (folder, IIS, Azure) Program.cs — the whole app setup in one file (.NET 6+ minimal hosting): csharp var builder = WebApplication.CreateBuilder(args); // 1. host: configuration, logging, DI container, Kestrel // 2. Register services (DI container) builder.Services.AddControllersWithViews(); // MVC + Razor views builder.Services.AddDbContext<ShopDbContext (o = o.UseSqlServer(builder.Configuration.GetConnectionString(\"Shop\"))); builder.Services.AddScoped<IProductService, ProductService (); builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(); var app = builder.Build(); // 3. build the app (service provider created) // 4. Middleware pipeline — ORDER MATTERS if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler(\"/Home/Error\"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapStaticAssets(); // .NET 9+ (older: app.UseStaticFiles() before UseRouting) // 5. Endpoints app.MapControllerRoute(name: \"areas\", pattern: \"{area:exists}/{controller=Home}/{action=Index}/{id?}\"); app.MapControllerRoute(name: \"default\", pattern: \"{controller=Home}/{action=Index}/{id?}\").WithStaticAssets(); app.Run(); // 6. start Kestrel and block until shutdown View lookup convention: for ProductsController.Details() returning View() , the view engine searches Views/Products/Details.cshtml , then Views/Shared/Details.cshtml (and Areas/{area}/Views/... for areas). Partial views starting with by convention. Comparison with MVC 5: Global.asax + App Start/ Config.cs + web.config → Program.cs + appsettings.json ; Content/ + Scripts/ → wwwroot/ ; Views/web.config → ViewImports.cshtml ; packages.config → <PackageReference in the .csproj. Interview tip: Only wwwroot is publicly served. Files like appsettings.json or .cshtml are never downloadable — Razor views are compiled into the app's assembly at build time."},{"kind":"lesson","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"how-aspdotnet-core-mvc-works-inside-from-kestrel-to-html","title":"How ASP.NET Core MVC works inside — from Kestrel to HTML","body":"Phase 1 — Startup (once): 1. WebApplication.CreateBuilder creates the generic host : loads configuration (appsettings.json → appsettings.{Env}.json → user secrets → environment variables → command line), sets up logging, creates the IServiceCollection and configures Kestrel as the IServer . 2. You register services; builder.Build() creates the root IServiceProvider . 3. Use... calls compose the middleware pipeline into a single RequestDelegate (each middleware wraps the next). 4. MapControllerRoute / MapControllers registers endpoint data sources : at startup MVC discovers controllers (public classes ending in Controller in the app's assemblies — the application parts ), builds an ActionDescriptor for every action (routes, HTTP methods, filters, parameters) and turns them into endpoints . 5. app.Run() starts hosted services and Kestrel, which listens on the configured ports. Phase 2 — Each request: text Kestrel (socket → HTTP parser) ──► HttpContext created (Request, Response, Features, RequestServices = new DI SCOPE) │ ▼ Middleware pipeline (RequestDelegate chain) ExceptionHandler ─► HSTS/HttpsRedirection ─► Static assets? (serve & short-circuit) ─► UseRouting: EndpointRoutingMiddleware matches URL + HTTP method against all endpoints (a compiled DFA matcher), stores the chosen Endpoint + route values in HttpContext ─► UseAuthentication: reads cookie/JWT → HttpContext.User ─► UseAuthorization: reads [Authorize] metadata from the selected endpoint → allow / 401 / 403 ─► Endpoint middleware: invokes the endpoint's RequestDelegate │ ▼ MVC: ControllerActionInvoker (ResourceInvoker) — the filter pipeline 1. Authorization filters 2. Resource filters (before) ← e.g. caching can short-circuit here 3. Controller created by the controller activator (constructor dependencies resolved from the request scope) 4. Model binding: value providers (route, query, form, headers, body via input formatters e.g. System.Text.Json) + model binders → action parameters; then validation (DataAnnotations/IValidatableObject) → ModelState 5. Action filters (OnActionExecuting) 6. ACTION METHOD executes → returns IActionResult (ViewResult, JsonResult, RedirectResult...) 7. Action filters (OnActionExecuted) 8. Exception filters (if the action/filters threw) 9. Result filters (OnResultExecuting) 10. Result execution: ViewResult → IViewEngine (RazorViewEngine) finds the compiled view → creates ViewContext → runs ViewStart → view's ExecuteAsync writes HTML (tag helpers run, partials/view components render) → layout renders with @RenderBody → HTML written to the response body ObjectResult/JsonResult → output formatter (System.Text.Json) serialises to the body 11. Result filters (OnResultExecuted), Resource filters (after) ◄─ response flows back through middleware (they can still act after next()) ◄─ Kestrel writes the response bytes; the request's DI scope is disposed (scoped services like DbContext disposed) Key internals to remember: Piece What it really is --- --- HttpContext Per-request object: Request , Response , User , Items , Features , RequestServices Middleware Func<RequestDelegate, RequestDelegate — each calls next(context) or short-circuits Endpoint A RequestDelegate + metadata (route pattern, [Authorize] , CORS policy, action descriptor) Routing Two steps: match in UseRouting , execute in the endpoint middleware — middleware between them (auth, CORS) can read the selected endpoint Controller lifetime A new controller instance per request (transient), created from the request's DI scope Scoped services One instance per request (DbContext) — disposed at the end of the request Model binding Value providers + model binder providers ( [FromRoute] , [FromQuery] , [FromForm] , [FromBody] , [FromServices] , [FromHeader] ) Razor views Compiled at build time by the Razor SDK into classes deriving from RazorPage<TModel inside the app assembly (runtime compilation only if you add the package for development) Tag helpers Classes executed while the view renders, turning <input asp-for into HTML Output IActionResult.ExecuteResultAsync writes to HttpContext.Response.Body (a pipe to Kestrel) Writing your own middleware shows the pipeline idea: csharp app.Use(async (context, next) = { var sw = Stopwatch.StartNew(); // runs on the way IN await next(context); // everything after this middleware runs here sw.Stop(); // runs on the way OUT app.Logger.LogInformation(\"{Path} took {Ms} ms → {Status}\", context.Request.Path, sw.ElapsedMilliseconds, context.Response.StatusCode); }); Interview tip: Asked \"explain the request life cycle\", answer in this order: Kestrel → HttpContext + DI scope → middleware (exception, HTTPS, static files, routing, authentication, authorization) → endpoint → MVC filters (authorization, resource, model binding + validation, action, exception, result) → action → result execution (view engine / formatter) → back out through middleware → scope disposed."},{"kind":"lesson","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"controllers-actions-and-action-results","title":"Controllers, actions and action results","body":"csharp public class ProductsController(IProductService products) : Controller { public async Task<IActionResult Index() = View(await products.GetAllAsync()); public async Task<IActionResult Details(int id) { var p = await products.GetAsync(id); return p is null ? NotFound() : View(p); } [HttpGet] public IActionResult Create() = View(); [HttpPost, ValidateAntiForgeryToken] public async Task<IActionResult Create(ProductInput input) { if (!ModelState.IsValid) return View(input); // redisplay with errors var id = await products.CreateAsync(input); TempData[\"Message\"] = \"Product created\"; return RedirectToAction(nameof(Details), new { id }); // Post-Redirect-Get } } Result Helper --- --- HTML view View() , PartialView() Redirect Redirect() , RedirectToAction() , RedirectToRoute() , LocalRedirect() Data Json() , Content() , File() , Ok() Status NotFound() , BadRequest() , Unauthorized() , Forbid() , StatusCode(503) Post-Redirect-Get (PRG) prevents duplicate form submissions on browser refresh."},{"kind":"lesson","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"routing-conventional-vs-attribute","title":"Routing: conventional vs attribute","body":"csharp // Conventional (Program.cs) app.MapControllerRoute(\"default\", \"{controller=Home}/{action=Index}/{id?}\"); app.MapControllerRoute(\"blog\", \"blog/{year:int}/{slug}\", defaults: new { controller = \"Blog\", action = \"Post\" }); // Attribute routing [Route(\"shop/products\")] public class ProductsController : Controller { [HttpGet(\"\")] public IActionResult Index() = View(); [HttpGet(\"{id:int:min(1)}\")] public IActionResult Details(int id) = View(); [HttpGet(\"by-category/{name:alpha}\")] public IActionResult ByCategory(string name) = View(); } - Route constraints: int , bool , guid , datetime , min(1) , range(1,100) , alpha , regex(...) , length(3,20) . - Endpoint routing (3.0+): UseRouting() selects the endpoint early so middleware like CORS/auth know which endpoint (and its metadata) will run. - Areas split large apps: [Area(\"Admin\")] + route {area:exists}/{controller}/{action} . - Generate URLs, never hard-code: Url.Action(\"Details\", \"Products\", new { id }) , asp-action tag helper."},{"kind":"lesson","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"model-binding-sources","title":"Model binding sources","body":"Model binding maps HTTP request data to action parameters. Sources in order: form fields → route values → query string (and files). Explicit attributes override: csharp public IActionResult Search( [FromQuery] string q, [FromRoute] int page, [FromForm] string sort, [FromHeader(Name = \"X-Tenant\")] string tenant, [FromServices] IClock clock, [FromBody] SearchFilter filter) // body (JSON) — typical in Web API, only one [FromBody] per action { ... } Complex types bind by property name ( Address.City → input.Address.City ). Collections bind by index ( Items[0].Qty ). Over-posting / mass assignment: binding directly to entities lets attackers set fields like IsAdmin . Use view models / input models with only the allowed fields (or [Bind(\"Name,Price\")] )."},{"kind":"lesson","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"validation-with-data-annotations","title":"Validation with data annotations","body":"csharp public class ProductInput { [Required, StringLength(100, MinimumLength = 3)] public string Name { get; set; } = \"\"; [Range(1, 1 000 000)] [DataType(DataType.Currency)] public decimal Price { get; set; } [EmailAddress] public string? SupplierEmail { get; set; } [RegularExpression(@\"^[A-Z]{3}-\\d{4}$\", ErrorMessage = \"SKU must look like ABC-1234\")] public string Sku { get; set; } = \"\"; [Remote(action: \"SkuAvailable\", controller: \"Products\")] // AJAX check via jQuery unobtrusive validation public string? Code { get; set; } } - Server-side: ModelState.IsValid (always check — client validation can be bypassed). - Client-side: jQuery Validation + Unobtrusive ( ValidationScriptsPartial ) reads data-val- attributes generated by tag helpers. - Custom rules: a ValidationAttribute subclass or IValidatableObject.Validate() for cross-field rules; FluentValidation library for complex rules. - Add errors manually: ModelState.AddModelError(nameof(input.Sku), \"SKU already exists\");"},{"kind":"lesson","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"passing-data-viewdata-viewbag-tempdata-strongly-typed-models","title":"Passing data: ViewData, ViewBag, TempData, strongly typed models","body":"Type Lifetime Use --- --- --- --- Strongly typed @model Any class Current request Preferred — compile-time checked ViewData ViewDataDictionary (string keys) Current request Small extras, e.g. page title ViewBag dynamic wrapper over ViewData Current request Same as ViewData, no casting TempData Dictionary backed by cookie (default) or session Until read (survives one redirect) Flash messages after PRG Session ISession (needs AddSession + distributed cache) Across requests Wizard state, cart (prefer DB for important data) csharp ViewData[\"Title\"] = \"Products\"; ViewBag.Count = 5; TempData[\"Message\"] = \"Saved\"; // read once on next request; TempData.Keep() / Peek() to retain cshtml @model IEnumerable<Product <h1 @ViewData[\"Title\"]</h1 @if (TempData[\"Message\"] is string msg) { <div class=\"alert alert-success\" @msg</div }"},{"kind":"lesson","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"razor-syntax-layouts-sections-and-partial-views","title":"Razor syntax, layouts, sections and partial views","body":"cshtml @model ProductListVm @{ ViewData[\"Title\"] = \"Products\"; } <h1 @ViewData[\"Title\"] (@Model.Items.Count)</h1 @foreach (var p in Model.Items) { <partial name=\" ProductCard\" model=\"p\" / } @if (!Model.Items.Any()) { <p No products.</p } <p Total: @Model.Items.Sum(i = i.Price).ToString(\"C\")</p @ Razor comment @ @section Scripts { <partial name=\" ValidationScriptsPartial\" / } cshtml <!-- Views/Shared/ Layout.cshtml -- <!DOCTYPE html <html <head <title @ViewData[\"Title\"] - MyShop</title </head <body <partial name=\" Nav\" / <main @RenderBody()</main @await RenderSectionAsync(\"Scripts\", required: false) </body </html - @ outputs HTML-encoded values (XSS protection); @Html.Raw() disables encoding — avoid with user input. - ViewStart.cshtml sets the default layout; ViewImports.cshtml holds @using and @addTagHelper ."},{"kind":"lesson","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"tag-helpers-vs-html-helpers","title":"Tag helpers vs HTML helpers","body":"cshtml @addTagHelper , Microsoft.AspNetCore.Mvc.TagHelpers <form asp-controller=\"Products\" asp-action=\"Create\" method=\"post\" <div asp-validation-summary=\"ModelOnly\" </div <label asp-for=\"Name\" </label <input asp-for=\"Name\" class=\"form-control\" / <span asp-validation-for=\"Name\" </span <select asp-for=\"CategoryId\" asp-items=\"Model.Categories\" </select <button type=\"submit\" Save</button </form <a asp-action=\"Details\" asp-route-id=\"@item.Id\" View</a <img src=\"~/img/logo.png\" asp-append-version=\"true\" / <environment include=\"Development\" <script src=\"~/js/site.js\" </script </environment Old style HTML helpers : @Html.TextBoxFor(m = m.Name) , @Html.ActionLink(\"View\", \"Details\", new { id }) . Tag helpers look like HTML, are designer-friendly, and the <form tag helper adds the antiforgery token automatically . Custom tag helper: a class deriving from TagHelper overriding Process(TagHelperContext, TagHelperOutput) ."},{"kind":"lesson","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"partial-views-vs-view-components","title":"Partial views vs view components","body":"Partial view View component --- --- --- Logic None (just markup with a model you pass) Has its own C class with InvokeAsync — can call services Data Parent must supply the model Fetches its own data Use Reusable markup fragments (product card) Widgets: shopping cart summary, menu, recent posts Invoke <partial name=\" Card\" model=\"x\" / @await Component.InvokeAsync(\"Cart\") or <vc:cart </vc:cart csharp public class CartViewComponent(ICartService cart) : ViewComponent { public async Task<IViewComponentResult InvokeAsync() = View(await cart.GetSummaryAsync(UserClaimsPrincipal)); } // View: Views/Shared/Components/Cart/Default.cshtml Child actions ( @Html.Action ) from MVC 5 no longer exist — view components replace them."},{"kind":"lesson","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"filters-and-their-order","title":"Filters and their order","body":"Filter Runs Example --- --- --- Authorization First; can short-circuit [Authorize] , custom policy checks Resource Before/after model binding Caching, short-circuit for maintenance Action Before/after the action method Logging, validation, modifying arguments Exception When an unhandled exception occurs in the MVC pipeline Convert to error view/ProblemDetails Result Before/after the result executes Add headers, modify the result csharp public class AuditFilter(ILogger<AuditFilter log) : IAsyncActionFilter { public async Task OnActionExecutionAsync(ActionExecutingContext ctx, ActionExecutionDelegate next) { log.LogInformation(\"Executing {Action}\", ctx.ActionDescriptor.DisplayName); var executed = await next(); if (executed.Exception is null) log.LogInformation(\"Done {Action}\", ctx.ActionDescriptor.DisplayName); } } builder.Services.AddControllersWithViews(o = o.Filters.Add<AuditFilter ()); // global // or [ServiceFilter(typeof(AuditFilter))] on a controller/action (filter resolved from DI) Scope order: global → controller → action on the way in (reverse on the way out); override with Order . Filters vs middleware: middleware sees every request (including static files) and knows nothing about MVC; filters run only for MVC actions and have access to ModelState , action arguments and results."},{"kind":"lesson","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"authentication-authorisation-and-identity","title":"Authentication, authorisation and Identity","body":"csharp builder.Services.AddDefaultIdentity<IdentityUser (o = o.SignIn.RequireConfirmedAccount = true) .AddRoles<IdentityRole () .AddEntityFrameworkStores<AppDbContext (); builder.Services.AddAuthorization(o = { o.AddPolicy(\"CanApprove\", p = p.RequireRole(\"Manager\").RequireClaim(\"department\", \"Finance\")); o.FallbackPolicy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build(); // secure by default }); [Authorize(Policy = \"CanApprove\")] public class ApprovalsController : Controller { [AllowAnonymous] public IActionResult About() = View(); } - Authentication = who you are (cookie, JWT, OpenID Connect with Microsoft Entra ID/Google). Authorisation = what you may do (roles, claims, policies, resource-based checks via IAuthorizationService ). - MVC apps typically use cookie authentication ; APIs use JWT bearer tokens . - Identity stores users, hashed passwords (PBKDF2), roles, claims, 2FA, lockout, external logins."},{"kind":"lesson","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"security-antiforgery-xss-https-cors","title":"Security: antiforgery, XSS, HTTPS, CORS","body":"- CSRF: cookie-authenticated forms must include an antiforgery token. The form tag helper adds it; validate with [ValidateAntiForgeryToken] or globally with AutoValidateAntiforgeryTokenAttribute . - XSS: Razor HTML-encodes @ output; never Html.Raw user input; add a Content-Security-Policy header. - HTTPS + HSTS: UseHttpsRedirection() , UseHsts() in production. - Open redirect: use LocalRedirect() / Url.IsLocalUrl(returnUrl) for return URLs. - Cookies: HttpOnly , Secure , SameSite=Lax/Strict . - Error pages: developer exception page only in Development."},{"kind":"lesson","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"caching-session-and-performance-in-mvc","title":"Caching, session and performance in MVC","body":"csharp builder.Services.AddOutputCache(o = o.AddPolicy(\"Products\", b = b.Expire(TimeSpan.FromMinutes(5)).Tag(\"products\"))); app.UseOutputCache(); [OutputCache(PolicyName = \"Products\")] public IActionResult Index() = View(); // invalidate after an update: await outputCacheStore.EvictByTagAsync(\"products\", ct); cshtml <cache expires-after=\"@TimeSpan.FromMinutes(10)\" vary-by-user=\"true\" @await Component.InvokeAsync(\"RecentOrders\") </cache Other levers: IMemoryCache / IDistributedCache / HybridCache for data, response compression, bundling/minification (or MapStaticAssets compression), async actions, avoiding N+1 queries in views (load everything in the controller with projections)."},{"kind":"lesson","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"razor-pages-vs-mvc","title":"Razor Pages vs MVC","body":"Razor Pages (2.0+) organises UI by page rather than by controller: Pages/Products/Edit.cshtml + Edit.cshtml.cs ( PageModel with OnGet / OnPostAsync handlers, [BindProperty] ). It's simpler for form-centric CRUD pages; MVC suits apps with many actions per resource, complex routing or shared controllers with APIs. Both use the same Razor, tag helpers, model binding, validation, filters and DI, and can live in one app. csharp public class EditModel(AppDbContext db) : PageModel { [BindProperty] public ProductInput Input { get; set; } = new(); public async Task<IActionResult OnGetAsync(int id) { / load / return Page(); } public async Task<IActionResult OnPostAsync(int id) { if (!ModelState.IsValid) return Page(); await db.SaveChangesAsync(); return RedirectToPage(\"Index\"); } }"},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"375","title":"What is MVC? Explain the role of each component.","body":"Model–View–Controller separates an app into three parts. The Model holds data, business rules and validation (entities, view models). The View renders UI from a model (Razor .cshtml ). The Controller receives the request, works with services and models, and returns a result (view, redirect, JSON). Benefits: separation of concerns, testable controllers, parallel work on UI and logic, and clean URLs through routing."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"376","title":"Explain the ASP.NET Core MVC request lifecycle.","body":"Kestrel receives the request, which flows through the middleware pipeline (exception handling, HTTPS, static files, routing, authentication, authorisation). Endpoint routing selects the controller action. The controller is created via DI, then the filter pipeline runs: authorisation filters → resource filters → model binding and validation → action filters → the action executes → result filters → result execution (the view engine renders the view with its layout and partials). Exception filters handle errors in that stage, and the response goes back out through the middleware."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"377","title":"What is the difference between ViewData, ViewBag and TempData?","body":"ViewData is a string-keyed dictionary and ViewBag is a dynamic wrapper over the same data. Both live only for the current request (controller → view) and need no casting with ViewBag. TempData persists until it is read , typically across one redirect (PRG flash messages); it's stored in a cookie by default or in session. Keep() / Peek() retain values. Prefer strongly typed view models over all three for real data."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"378","title":"What is the difference between conventional and attribute routing?","body":"Conventional routing defines URL templates centrally ( {controller=Home}/{action=Index}/{id?} ) and is good for uniform MVC apps. Attribute routing puts templates on controllers/actions ( [Route(\"products/{id:int}\")] ), giving precise control, constraints and versioning; it's required for [ApiController] . Both can coexist. Attribute routes are matched without the conventional patterns."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"379","title":"What is model binding?","body":"The process of mapping HTTP request data (form fields, route values, query string, headers, body, files) to action parameters and model properties by name. Attributes [FromForm] , [FromQuery] , [FromRoute] , [FromHeader] , [FromBody] and [FromServices] control the source. After binding, validation runs and fills ModelState ."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"380","title":"How does validation work in ASP.NET Core MVC?","body":"Data annotations ( [Required] , [StringLength] , [Range] , [EmailAddress] , [RegularExpression] , [Compare] ) on models are checked after model binding, and the results go into ModelState . Check ModelState.IsValid in the action and redisplay the view with errors. Tag helpers emit data-val- attributes, so jQuery Unobtrusive Validation validates on the client too. Custom rules use a ValidationAttribute , IValidatableObject or FluentValidation. Server-side validation is mandatory because the client side can be bypassed."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"381","title":"What are `_Layout`, `_ViewStart` and `_ViewImports`?","body":"Layout.cshtml is the master template (header, nav, footer) with @RenderBody() and optional @RenderSection . ViewStart.cshtml runs before every view in its folder and usually sets Layout = \" Layout\" . ViewImports.cshtml holds shared directives — @using , @addTagHelper , @inject — for all views in that folder hierarchy."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"382","title":"Partial view vs view component — when do you use which?","body":"Use a partial view to reuse markup when the parent already has the data (e.g. a product card in a list). Use a view component when the widget needs its own logic and data from services, independent of the page's model (shopping cart badge, navigation menu, \"latest posts\"). View components replace MVC 5 child actions and can be invoked as tag helpers ( <vc:cart / )."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"383","title":"What are filters? List the types and their execution order.","body":"Filters run code at specific stages of the MVC action pipeline: Authorization → Resource → (model binding) → Action → action → Action (after) → Result → result execution → Result (after). Exception filters catch unhandled exceptions from these stages. They can be applied globally, per controller or per action (in that order on the way in), and use DI via ServiceFilter / TypeFilter . Use cases: auth, logging, caching, validation, error handling."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"384","title":"What is the difference between middleware and filters?","body":"Middleware is part of the ASP.NET Core pipeline. It runs for every request, including static files and non-MVC endpoints, works with HttpContext only, and its order is set in Program.cs. Filters are part of MVC. They run only for controller actions and Razor Pages, and can see MVC context such as ModelState , action arguments and IActionResult . Use middleware for cross-cutting HTTP concerns (logging, CORS, exception handling) and filters for action-specific concerns (validation, audit per action)."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"385","title":"What are tag helpers? How are they better than HTML helpers?","body":"Tag helpers are server-side C classes that enhance HTML-looking elements via asp- attributes ( <input asp-for=\"Name\" / , <a asp-action=\"Details\" asp-route-id=\"5\" ). Compared with HTML helpers ( @Html.TextBoxFor ), they look like plain HTML, give better IntelliSense, are friendlier to designers, and add features automatically (antiforgery tokens in forms, cache-busting with asp-append-version ). Custom tag helpers derive from TagHelper ."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"386","title":"How do you prevent CSRF attacks in ASP.NET Core MVC?","body":"Use antiforgery tokens. The form tag helper injects a hidden RequestVerificationToken field paired with a cookie. Validate with [ValidateAntiForgeryToken] per action or globally with AutoValidateAntiforgeryTokenAttribute . For AJAX, send the token in a header ( RequestVerificationToken ) configured via AddAntiforgery(o = o.HeaderName = ...) . SameSite cookies add defence in depth. APIs using JWT in the Authorization header aren't vulnerable in the same way."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"387","title":"What is the difference between `RedirectToAction`, `Redirect` and `LocalRedirect`?","body":"All send a 302 by default ( Permanent variants send 301/308). RedirectToAction(\"Details\", new { id }) builds the URL from routing. Redirect(url) goes to any URL, including external ones, which is risky with user input (open redirect). LocalRedirect(url) only allows local URLs and throws otherwise, so use it for returnUrl after login."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"388","title":"What is Post-Redirect-Get and why is it used?","body":"After a successful POST, the server responds with a redirect (302/303) to a GET page instead of rendering a view directly. Refreshing the browser then repeats the harmless GET instead of resubmitting the form, which prevents duplicate orders or payments. TempData carries the success message across the redirect."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"389","title":"What is an Area in MVC?","body":"A way to partition a large MVC app into functional sections (Admin, Billing, Customer), each with its own Controllers, Views and Models folders. Controllers are marked [Area(\"Admin\")] and routes include {area:exists} . Tag helpers use asp-area ."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"390","title":"How do you handle errors globally in MVC?","body":"In production, app.UseExceptionHandler(\"/Home/Error\") (shows a friendly error page, logs the exception) plus app.UseStatusCodePagesWithReExecute(\"/Error/{0}\") for 404s. In development, the developer exception page is enabled by default. Exception filters handle MVC-specific cases. .NET 8 adds IExceptionHandler implementations registered with AddExceptionHandler<T () . Always log with a correlation ID and never show stack traces to users."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"391","title":"How does authentication differ between an MVC app and a Web API?","body":"MVC apps usually use cookie authentication : after login (Identity or OpenID Connect via Entra ID), an encrypted auth cookie identifies the user on each request, and antiforgery tokens protect forms. Web APIs consumed by SPAs or mobile apps usually use JWT bearer tokens in the Authorization header, validated statelessly (issuer, audience, signature, expiry). In both, authorisation uses [Authorize] with roles, claims or policies. For SPAs, a BFF (Backend-for-Frontend) that keeps tokens server-side and uses cookies is now recommended for security."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"392","title":"How would you implement resource-based authorisation (e.g. only the owner can edit a document)?","body":"Attribute-based roles can't express \"owner of this specific document\". Load the resource, then call IAuthorizationService.AuthorizeAsync(User, document, \"EditPolicy\") . Write an AuthorizationHandler<SameOwnerRequirement, Document that succeeds when document.OwnerId == user id or the user is an admin. Return Forbid() on failure. This also prevents IDOR attacks."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"393","title":"How do you unit-test an MVC controller?","body":"Inject dependencies through interfaces and mock them (Moq/NSubstitute). Instantiate the controller, call the action, and assert on the IActionResult type and model: var result = Assert.IsType<ViewResult (await controller.Details(5)); Assert.IsType<Product (result.Model); . Set controller.ControllerContext with a fake HttpContext / User when needed. For routing, filters and views end to end, use integration tests with WebApplicationFactory ."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"394","title":"Users double-click \"Place Order\" and two orders are created. How do you fix it?","body":"Defence in layers: (1) disable the button on submit with JavaScript; (2) use Post-Redirect-Get ; (3) make the server idempotent — generate an order token (GUID) when rendering the form, store it in a hidden field, and enforce a unique constraint on it in the DB, so a second POST with the same token is rejected or returns the existing order. The DB unique constraint is the only fully reliable guard."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"395","title":"A product page shows another customer's order when the URL ID is changed. What is the bug and the fix?","body":"It's an IDOR (Insecure Direct Object Reference) / broken access control. The action loads by ID without checking ownership. Fix: always scope queries by the current user ( db.Orders.Where(o = o.Id == id && o.CustomerId == userId) ), or use resource-based authorisation. Return 404 (not 403) to avoid revealing existence. Audit other endpoints, add integration tests for access control, and consider EF Core global query filters for multi-tenant data."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"396","title":"Your MVC home page takes 4 seconds. Profiling shows 120 SQL queries per request. What do you do?","body":"That's an N+1 query problem : views or lazy loading trigger a query per item. Fix: load all needed data in the controller/service with one or a few queries using Include or, better, projections ( Select into a view model). Disable lazy loading. Cache rarely changing data (categories, menus) with IMemoryCache / HybridCache or the <cache tag helper. Add output caching for anonymous pages. Measure again with logging of EF queries or MiniProfiler."},{"kind":"question","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"397","title":"After deploying, users see old CSS/JS from browser cache. How do you prevent this?","body":"Use cache busting. asp-append-version=\"true\" on <script , <link and <img adds a hash query string that changes when the file changes. In .NET 9+, MapStaticAssets() with .WithStaticAssets() fingerprints and compresses assets at build time with long-lived caching headers. Bundlers (Vite/webpack) produce hashed file names."},{"kind":"cheat","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"1","title":"Request lifecycle","body":"Middleware → Routing → Controller (DI) → Authorization filter → Resource filter → Model binding → Validation → Action filter → Action → Action filter → Result filter → View render → Result filter → Response. Exception filters wrap the action/result stages."},{"kind":"cheat","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"2","title":"Middleware order (MVC)","body":"csharp app.UseExceptionHandler(\"/Home/Error\"); app.UseHsts(); app.UseHttpsRedirection(); app.UseStaticFiles(); // or MapStaticAssets() app.UseRouting(); app.UseCors(); app.UseAuthentication(); app.UseAuthorization(); app.UseSession(); app.MapControllerRoute(\"default\", \"{controller=Home}/{action=Index}/{id?}\");"},{"kind":"cheat","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"3","title":"Passing data","body":"Lifetime --- --- Model ( @model ) Request — preferred ViewData / ViewBag Request TempData Until read (one redirect) Session Across requests"},{"kind":"cheat","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"4","title":"Action results","body":"View · PartialView · ViewComponent · Json · Content · File · Redirect · RedirectToAction · LocalRedirect · NotFound · BadRequest · Unauthorized · Forbid · StatusCode ."},{"kind":"cheat","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"5","title":"Binding attributes","body":"[FromQuery] [FromRoute] [FromForm] [FromBody] [FromHeader] [FromServices] [Bind(\"A,B\")] [BindProperty] (Razor Pages)."},{"kind":"cheat","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"6","title":"Validation attributes","body":"[Required] [StringLength] [MaxLength] [Range] [EmailAddress] [Phone] [Url] [Compare(\"Password\")] [RegularExpression] [Remote] · custom ValidationAttribute · IValidatableObject ."},{"kind":"cheat","course_slug":"aspnet-core-mvc","course_title":"ASP.NET Core MVC (and Razor Pages)","ref":"7","title":"Security checklist","body":"Antiforgery on POST forms · [Authorize] + fallback policy · ownership checks (IDOR) · LocalRedirect for returnUrl · no Html.Raw on user input · HTTPS + HSTS · secure cookies · view models (no over-posting)."},{"kind":"course","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"","title":"ASP.NET Core Web API & REST","body":"REST principles, controllers vs Minimal APIs, middleware, status codes, validation and ProblemDetails, JWT authentication, versioning, OpenAPI, caching, rate limiting, CORS, gRPC/SignalR and microservices basics. ASP.NET Core Web API builds HTTP services that return data (usually JSON) for SPAs (React/Angular/Vue), mobile apps and other services. Two programming models: - Controller-based APIs — [ApiController] classes with actions (feature-rich: filters, model binding conventions). - Minimal APIs (.NET 6+) — lambda endpoints mapped in Program.cs ( app.MapGet(...) ), less ceremony, AOT-friendly. Related technologies: gRPC (high-performance HTTP/2 + Protobuf RPC), SignalR (real-time WebSockets), GraphQL (Hot Chocolate), YARP (reverse proxy/API gateway). REST (Representational State Transfer, Roy Fielding, 2000) constraints: client–server, stateless, cacheable, uniform interface (resources identified by URIs, manipulated via representations, standard HTTP methods), layered system, (optional) code on demand. Version Highlights for APIs --- --- ASP.NET Web API 1/2 (2012/2013) On .NET Framework; attribute routing in v2; OWIN ASP.NET Core 1.0 (2016) Web API merged into MVC: one Controller base 2.1 (2018) [ApiController] (automatic 400s, binding inference), ControllerBase , ActionResult<T , ProblemDetails 3.0 (2019) Endpoint routing, System.Text.Json default, gRPC templates 6 (2021) Minimal APIs , WebApplication minimal hosting 7 (2022) Route groups, endpoint filters, typed results, rate limiting , output caching 8 (2023) Native AOT for Minimal APIs, [FromForm] in Minimal APIs, keyed services, Identity API endpoints, IExceptionHandler 9 (2024) Built-in OpenAPI document generation ( Microsoft.AspNetCore.OpenApi , Swashbuckle removed from templates), HybridCache 10 (2025) OpenAPI 3.1, built-in validation for Minimal APIs ( AddValidation() ), Server-Sent Events results, JSON Patch with System.Text.Json API request lifecycle: 1. Client sends an HTTP request (method + URL + headers + body). 2. Kestrel → middleware: exception handler → HTTPS → CORS → authentication (JWT validated) → authorization → rate limiter → response caching/output caching. 3. Endpoint routing selects the action/minimal endpoint. 4. Controller APIs: filters → model binding ( [FromBody] JSON deserialised with System.Text.Json) → validation ( [ApiController] returns 400 ProblemDetails automatically if invalid) → action. 5. Action calls services/repositories (async I/O to DB/HTTP). 6. Result ( Ok(dto) , CreatedAtAction , NotFound() ) → content negotiation picks a formatter (JSON by default) → serialised response with status code and headers. 7. Logging/telemetry middleware records the request; response returns. API lifecycle (product): design (OpenAPI contract) → implement → test (unit, integration, contract) → document → version → deploy behind a gateway → monitor → deprecate old versions (Sunset header) → retire. Tool Use --- --- Postman, Insomnia, Bruno Manual and collection-based API testing .http files in Visual Studio / VS Code REST Client Requests stored with the code Swagger UI / Scalar / ReDoc Interactive docs from the OpenAPI document NSwag, Kiota, OpenAPI Generator Generate typed clients Microsoft.AspNetCore.Mvc.Testing Integration tests ( WebApplicationFactory ) k6, JMeter, NBomber, Azure Load Testing Load testing Azure API Management, YARP, Ocelot Gateways Application Insights, OpenTelemetry, Seq, Serilog Observability curl / httpie Command-line testing"},{"kind":"lesson","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"rest-principles-and-resource-design","title":"REST principles and resource design","body":"Action Method URI Success status --- --- --- --- List GET /api/orders?status=open&page=2 200 Get one GET /api/orders/42 200 / 404 Create POST /api/orders 201 + Location header Replace PUT /api/orders/42 200 / 204 Partial update PATCH /api/orders/42 200 / 204 Delete DELETE /api/orders/42 204 Sub-resource GET /api/customers/7/orders 200 Guidelines: nouns not verbs ( /orders , not /getOrders ), plural collections, hierarchy for relationships, query string for filtering/sorting/paging, consistent casing (kebab-case paths, camelCase JSON), version the API, use standard status codes. Idempotent methods give the same result if repeated: GET, PUT, DELETE, HEAD, OPTIONS. Safe methods don't change state: GET, HEAD, OPTIONS. POST is neither; PATCH is not guaranteed idempotent."},{"kind":"lesson","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"http-status-codes-you-must-know","title":"HTTP status codes you must know","body":"Code Meaning When --- --- --- 200 OK Success with body GET, PUT returning the resource 201 Created Resource created POST; include Location 202 Accepted Queued for async processing Long-running jobs 204 No Content Success, no body DELETE, PUT 301/308 Moved permanently URL changes 304 Not Modified Cached copy still valid ETag / If-None-Match 400 Bad Request Invalid input Validation errors 401 Unauthorized Not authenticated Missing/invalid token 403 Forbidden Authenticated but not allowed Role/policy fails 404 Not Found Resource doesn't exist 405 Method Not Allowed Wrong verb 409 Conflict State conflict Duplicate, concurrency 412 Precondition Failed If-Match ETag mismatch Optimistic concurrency 415 Unsupported Media Type Wrong Content-Type 422 Unprocessable Content Semantically invalid Business rule violations (some APIs) 429 Too Many Requests Rate limited + Retry-After 500 Internal Server Error Unhandled server error 502/503/504 Gateway / unavailable / timeout Downstream failures"},{"kind":"lesson","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"controller-based-api","title":"Controller-based API","body":"csharp [ApiController] [Route(\"api/[controller]\")] public class OrdersController(IOrderService orders) : ControllerBase { [HttpGet] public async Task<ActionResult<PagedResult<OrderDto List([FromQuery] OrderQuery q, CancellationToken ct) = Ok(await orders.ListAsync(q, ct)); [HttpGet(\"{id:int}\")] [ProducesResponseType<OrderDto (StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task<ActionResult<OrderDto Get(int id, CancellationToken ct) = await orders.GetAsync(id, ct) is { } dto ? dto : NotFound(); [HttpPost] public async Task<ActionResult<OrderDto Create(CreateOrderRequest req, CancellationToken ct) { var dto = await orders.CreateAsync(req, ct); return CreatedAtAction(nameof(Get), new { id = dto.Id }, dto); // 201 + Location } [HttpDelete(\"{id:int}\")] public async Task<IActionResult Delete(int id, CancellationToken ct) = await orders.DeleteAsync(id, ct) ? NoContent() : NotFound(); } [ApiController] gives: attribute routing required, automatic 400 ValidationProblemDetails when ModelState is invalid, binding-source inference (complex types from body, simple from route/query), ProblemDetails for error status codes."},{"kind":"lesson","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"minimal-apis","title":"Minimal APIs","body":"csharp var orders = app.MapGroup(\"/api/orders\").WithTags(\"Orders\").RequireAuthorization(); orders.MapGet(\"/\", async (IOrderService svc, [AsParameters] OrderQuery q, CancellationToken ct) = TypedResults.Ok(await svc.ListAsync(q, ct))); orders.MapGet(\"/{id:int}\", async Task<Results<Ok<OrderDto , NotFound (int id, IOrderService svc, CancellationToken ct) = await svc.GetAsync(id, ct) is { } dto ? TypedResults.Ok(dto) : TypedResults.NotFound()); orders.MapPost(\"/\", async (CreateOrderRequest req, IOrderService svc, CancellationToken ct) = { var dto = await svc.CreateAsync(req, ct); return TypedResults.Created($\"/api/orders/{dto.Id}\", dto); }).AddEndpointFilter<ValidationFilter<CreateOrderRequest (); Controllers Minimal APIs --- --- --- Style Classes + attributes Lambdas/handlers in code Filters MVC filters Endpoint filters Model validation Automatic with [ApiController] .NET 10 AddValidation() or FluentValidation/filters Native AOT Not supported Supported Best for Large APIs, teams used to MVC Microservices, small/fast APIs"},{"kind":"lesson","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"middleware-built-in-and-custom","title":"Middleware: built-in and custom","body":"csharp public class CorrelationIdMiddleware(RequestDelegate next) { public async Task InvokeAsync(HttpContext ctx, ILogger<CorrelationIdMiddleware log) { var id = ctx.Request.Headers[\"X-Correlation-Id\"].FirstOrDefault() ?? Guid.NewGuid().ToString(); ctx.Response.Headers[\"X-Correlation-Id\"] = id; using (log.BeginScope(new Dictionary<string, object { [\"CorrelationId\"] = id })) await next(ctx); } } app.UseMiddleware<CorrelationIdMiddleware (); // inline app.Use(async (ctx, next) = { / before / await next(ctx); / after / }); app.Run(async ctx = await ctx.Response.WriteAsync(\"terminal\")); // terminal: no next app.Map(\"/health\", b = b.Run(async c = await c.Response.WriteAsync(\"OK\"))); // branch Use can call next ; Run is terminal; Map / MapWhen branch the pipeline. Order matters : e.g. UseAuthentication before UseAuthorization ; CORS before auth; exception handler first."},{"kind":"lesson","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"global-error-handling-with-problemdetails","title":"Global error handling with ProblemDetails","body":"csharp builder.Services.AddProblemDetails(); builder.Services.AddExceptionHandler<GlobalExceptionHandler (); public class GlobalExceptionHandler(ILogger<GlobalExceptionHandler log, IProblemDetailsService pd) : IExceptionHandler { public async ValueTask<bool TryHandleAsync(HttpContext ctx, Exception ex, CancellationToken ct) { var (status, title) = ex switch { NotFoundException = (404, \"Not found\"), ValidationException = (400, \"Validation failed\"), ConflictException = (409, \"Conflict\"), = (500, \"Unexpected error\") }; if (status == 500) log.LogError(ex, \"Unhandled exception\"); ctx.Response.StatusCode = status; return await pd.TryWriteAsync(new() { HttpContext = ctx, ProblemDetails = { Status = status, Title = title }, Exception = ex }); } } app.UseExceptionHandler(); app.UseStatusCodePages(); ProblemDetails (RFC 9457, formerly 7807) is the standard JSON error shape: type , title , status , detail , instance , plus extensions such as traceId and errors ."},{"kind":"lesson","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"dtos-validation-and-mapping","title":"DTOs, validation and mapping","body":"- Never expose EF entities directly: use request/response DTOs (records) to avoid over-posting, circular references and leaking internal fields. - Validate with data annotations, FluentValidation , or .NET 10 Minimal API validation. - Map with hand-written mapping/extension methods, Mapperly (source generator) or AutoMapper (commercial licence since v15, 2025). csharp public record CreateOrderRequest([Required] int CustomerId, [MinLength(1)] List<OrderLineRequest Lines); public record OrderDto(int Id, string Customer, decimal Total, string Status); public static class OrderMapping { public static OrderDto ToDto(this Order o) = new(o.Id, o.Customer.Name, o.Total, o.Status.ToString()); } public class CreateOrderValidator : AbstractValidator<CreateOrderRequest { public CreateOrderValidator() { RuleFor(x = x.CustomerId).GreaterThan(0); RuleForEach(x = x.Lines).ChildRules(l = l.RuleFor(x = x.Qty).InclusiveBetween(1, 100)); } }"},{"kind":"lesson","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"paging-filtering-sorting-and-hateoas","title":"Paging, filtering, sorting and HATEOAS","body":"csharp public record OrderQuery(string? Status, string? Sort = \"-createdAt\", int Page = 1, int PageSize = 20); public async Task<PagedResult<OrderDto ListAsync(OrderQuery q, CancellationToken ct) { var query = db.Orders.AsNoTracking(); if (q.Status is not null) query = query.Where(o = o.Status == q.Status); query = q.Sort == \"-createdAt\" ? query.OrderByDescending(o = o.CreatedAt) : query.OrderBy(o = o.CreatedAt); var total = await query.CountAsync(ct); var items = await query.Skip((q.Page - 1) q.PageSize).Take(Math.Min(q.PageSize, 100)) .Select(o = new OrderDto(o.Id, o.Customer.Name, o.Total, o.Status)).ToListAsync(ct); return new(items, total, q.Page, q.PageSize); } - Cap the page size. For large/realtime data use keyset (cursor) pagination : WHERE Id @lastId ORDER BY Id — stable and fast, no deep OFFSET . - HATEOAS (hypermedia links in responses) is REST's top maturity level (Richardson Maturity Model level 3); rarely fully used in practice."},{"kind":"lesson","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"jwt-authentication","title":"JWT authentication","body":"csharp builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(o = { o.Authority = \"https://login.microsoftonline.com/<tenant-id /v2.0\"; // or your identity server o.Audience = \"api://shop-api\"; // for self-issued tokens instead: // o.TokenValidationParameters = new() { ValidateIssuer = true, ValidIssuer = \"...\", ValidateAudience = true, // ValidAudience = \"...\", ValidateLifetime = true, IssuerSigningKey = new SymmetricSecurityKey(keyBytes), ClockSkew = TimeSpan.FromMinutes(1) }; }); builder.Services.AddAuthorization(o = o.AddPolicy(\"orders.write\", p = p.RequireClaim(\"scp\", \"Orders.Write\"))); app.UseAuthentication(); app.UseAuthorization(); A JWT has three Base64Url parts: header.payload.signature . The payload holds claims ( sub , iss , aud , exp , iat , roles/scopes). It is signed, not encrypted — anyone can read it, so never put secrets in it. The server validates signature, issuer, audience and expiry without a DB lookup (stateless). - Access token : short-lived (5–60 min). Refresh token : long-lived, stored securely, rotated on use, revocable server-side. - OAuth 2.0 flows: Authorization Code + PKCE (SPAs, mobile, web), Client Credentials (service-to-service). Implicit and password grants are deprecated. - OpenID Connect adds identity (ID token) on top of OAuth 2.0."},{"kind":"lesson","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"cors-https-rate-limiting-and-api-keys","title":"CORS, HTTPS, rate limiting and API keys","body":"csharp builder.Services.AddCors(o = o.AddPolicy(\"spa\", p = p.WithOrigins(\"https://app.example.com\") .AllowAnyHeader().AllowAnyMethod().AllowCredentials())); app.UseCors(\"spa\"); builder.Services.AddRateLimiter(o = { o.RejectionStatusCode = StatusCodes.Status429TooManyRequests; o.AddFixedWindowLimiter(\"per-client\", l = { l.PermitLimit = 100; l.Window = TimeSpan.FromMinutes(1); }); // also: sliding window, token bucket, concurrency limiters; partition by user/IP with PartitionedRateLimiter }); app.UseRateLimiter(); app.MapGet(\"/api/search\", Search).RequireRateLimiting(\"per-client\"); - CORS is a browser mechanism: the server tells browsers which other origins may call it (preflight OPTIONS for non-simple requests). It is not authentication — non-browser clients ignore it. Never AllowAnyOrigin with credentials (not allowed anyway). - Other protections: HTTPS only, input validation, request size limits, API keys for partner identification (not as the only auth), secrets in Key Vault, security headers."},{"kind":"lesson","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"caching-response-output-in-memory-distributed-hybridcache","title":"Caching: response, output, in-memory, distributed, HybridCache","body":"Cache Where Use --- --- --- HTTP caching headers ( Cache-Control , ETag ) Client/CDN/proxy Public GET resources Output caching (.NET 7) Server memory (or Redis) Whole responses; tag-based eviction IMemoryCache Process memory Single instance, fast IDistributedCache (Redis, SQL) Shared Multiple instances / scale-out HybridCache (.NET 9) L1 memory + L2 distributed Stampede protection, tags, one API csharp builder.Services.AddHybridCache(); public class ProductService(HybridCache cache, AppDbContext db) { public ValueTask<ProductDto? GetAsync(int id, CancellationToken ct) = cache.GetOrCreateAsync($\"product:{id}\", async token = await db.Products.Where(p = p.Id == id).Select(p = new ProductDto(p.Id, p.Name, p.Price)).FirstOrDefaultAsync(token), cancellationToken: ct); } Cache invalidation strategies: expiration (absolute/sliding), explicit removal on write, tags, versioned keys."},{"kind":"lesson","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"api-versioning-and-openapi","title":"API versioning and OpenAPI","body":"csharp // Asp.Versioning.Http / Asp.Versioning.Mvc packages builder.Services.AddApiVersioning(o = { o.DefaultApiVersion = new ApiVersion(1, 0); o.AssumeDefaultVersionWhenUnspecified = true; o.ReportApiVersions = true; // api-supported-versions header o.ApiVersionReader = new UrlSegmentApiVersionReader(); }); [ApiVersion(\"1.0\")][ApiVersion(\"2.0\")] [Route(\"api/v{version:apiVersion}/orders\")] public class OrdersController : ControllerBase { [HttpGet, MapToApiVersion(\"2.0\")] public IActionResult GetV2() = Ok(); } // OpenAPI (.NET 9+ built in) builder.Services.AddOpenApi(); app.MapOpenApi(); // /openapi/v1.json // UI: Scalar (app.MapScalarApiReference()) or Swashbuckle/NSwag Swagger UI Versioning strategies: URL segment ( /v2/orders — most visible), query string ( ?api-version=2.0 ), header ( api-version: 2 ), media type ( Accept: application/vnd.shop.v2+json ). Only make breaking changes in a new major version; additive changes are non-breaking."},{"kind":"lesson","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"httpclient-correctly-ihttpclientfactory-and-resilience","title":"HttpClient correctly: IHttpClientFactory and resilience","body":"csharp builder.Services.AddHttpClient<IWeatherClient, WeatherClient (c = { c.BaseAddress = new Uri(\"https://api.weather.example/\"); c.Timeout = TimeSpan.FromSeconds(10); }).AddStandardResilienceHandler(); public class WeatherClient(HttpClient http) : IWeatherClient { public Task<Forecast? GetAsync(string city, CancellationToken ct) = http.GetFromJsonAsync<Forecast ($\"forecast?city={Uri.EscapeDataString(city)}\", ct); } - new HttpClient() per request → socket exhaustion (sockets stay in TIME WAIT). One static HttpClient forever → stale DNS . - IHttpClientFactory pools and recycles HttpMessageHandler s (default lifetime 2 minutes) — solves both. (Alternatively a singleton HttpClient with SocketsHttpHandler.PooledConnectionLifetime .)"},{"kind":"lesson","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"real-time-and-rpc-signalr-grpc-webhooks","title":"Real-time and RPC: SignalR, gRPC, webhooks","body":"- SignalR — server push to clients over WebSockets (fallback: Server-Sent Events, long polling). Hubs, groups, Azure SignalR Service for scale-out. Use for chat, dashboards, notifications. - gRPC — contract-first ( .proto ), HTTP/2, binary Protobuf, streaming (server, client, bidirectional), generated clients. Great for internal service-to-service calls; browsers need gRPC-Web. - Webhooks — your API calls the client's URL when events happen; sign payloads (HMAC), retry with backoff, idempotency. - Server-Sent Events — one-way server → browser streaming over HTTP (.NET 10 adds TypedResults.ServerSentEvents )."},{"kind":"lesson","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"microservices-basics-for-api-developers","title":"Microservices basics for API developers","body":"- Each service owns its data (database per service), deploys independently, communicates via HTTP/gRPC (sync) or messaging (async: Azure Service Bus, RabbitMQ, Kafka). - API Gateway (Azure API Management, YARP, Ocelot): routing, auth, rate limiting, aggregation; BFF per client type. - Service discovery (Kubernetes DNS, Aspire service discovery), config centralised, observability via OpenTelemetry traces with correlation IDs. - Resilience : timeouts, retries, circuit breakers; idempotency keys for POSTs; Outbox for reliable events; Saga for distributed transactions. - Start with a modular monolith unless you need independent scaling/deployment — microservices add operational cost."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"398","title":"What is REST? What are its constraints?","body":"REST is an architectural style for networked APIs (Roy Fielding, 2000). Constraints: client–server separation, statelessness (each request carries everything needed, e.g. a token), cacheability, a uniform interface (resources identified by URIs, standard methods, self-descriptive messages, optionally hypermedia), a layered system, and optional code-on-demand. In practice: resource-oriented URLs, HTTP verbs, status codes, and JSON representations."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"399","title":"What is the difference between PUT, POST and PATCH?","body":"POST creates a resource (server assigns the ID) or triggers a process; not idempotent; returns 201 + Location. PUT replaces the whole resource at a known URI; idempotent (sending it twice gives the same state). PATCH partially updates (JSON Patch or JSON Merge Patch); not necessarily idempotent. Missing fields in PUT usually mean \"set to default/null\", in PATCH they mean \"leave unchanged\"."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"400","title":"What is the difference between 401 and 403?","body":"401 Unauthorized really means unauthenticated : no valid credentials, so the client should log in or refresh its token (the response includes WWW-Authenticate ). 403 Forbidden means the identity is known but lacks permission, and re-authenticating won't help. In ASP.NET Core, Challenge() produces 401 and Forbid() produces 403."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"401","title":"What does the `[ApiController]` attribute do?","body":"It enables API conventions: attribute routing is required, invalid ModelState automatically returns 400 with ValidationProblemDetails (no if (!ModelState.IsValid) needed), binding sources are inferred ( [FromBody] for complex types, route/query for simple ones, IFormFile from the form), and error status codes get ProblemDetails bodies. Apply it to the class or the whole assembly."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"402","title":"What is middleware? How do you write custom middleware?","body":"Middleware are components in the request pipeline. Each receives HttpContext , can do work, call next to pass the request on, and do more work on the way back, or short-circuit. Write a class with a constructor taking RequestDelegate next and an InvokeAsync(HttpContext) method, then register it with app.UseMiddleware<T () ; or use inline app.Use(async (ctx, next) = ...) . Run is terminal; Map branches. Order defines behaviour."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"403","title":"What is the difference between `IActionResult` and `ActionResult<T>`?","body":"IActionResult can return any result but carries no type information. ActionResult<T (2.1+) lets you return either a T (implicitly wrapped in a 200 OK) or any ActionResult ( NotFound() ), and lets OpenAPI tools infer the response type. Minimal APIs use TypedResults and Results<Ok<T , NotFound for the same purpose."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"404","title":"Controllers vs Minimal APIs — which do you choose?","body":"Both are fully supported and equally fast. Controllers suit large APIs with many endpoints, teams familiar with MVC, and heavy use of MVC filters and conventions. Minimal APIs suit microservices and small services; they have less ceremony, route groups, endpoint filters, typed results and Native AOT support (controllers aren't AOT-compatible). They can coexist in one app. Organise Minimal APIs with extension methods per feature ( app.MapOrders() )."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"405","title":"How does JWT authentication work in ASP.NET Core?","body":"The client authenticates with an identity provider (Microsoft Entra ID, Auth0, Duende IdentityServer, or your own login endpoint) and receives a signed JWT access token. It sends Authorization: Bearer <token on each request. The JwtBearer handler validates the signature (via the authority's published keys or a configured key), issuer, audience and expiry, then builds HttpContext.User from the claims. [Authorize] with roles, scopes or policies decides access. Tokens are stateless, so revocation needs short expiry plus refresh tokens or a deny list."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"406","title":"What is CORS and why do you get CORS errors?","body":"Browsers enforce the same-origin policy: a page from https://app.com can't read responses from https://api.com unless the API sends Access-Control-Allow-Origin (and related headers). For non-simple requests, the browser first sends a preflight OPTIONS . CORS errors mean the server didn't allow that origin, method or header, or UseCors is misplaced in the pipeline. Fix server-side with a named policy listing the exact origins. CORS doesn't protect the API from non-browser clients."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"407","title":"Why should you use IHttpClientFactory?","body":"Creating and disposing HttpClient per request leaves sockets in TIME WAIT and can exhaust ports. A single long-lived static instance doesn't respect DNS changes. IHttpClientFactory manages pooled handlers with a rotation lifetime, supports named and typed clients, central configuration, and delegating handlers for logging, auth headers and resilience ( AddStandardResilienceHandler )."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"408","title":"How do you handle exceptions globally in a Web API?","body":"Use UseExceptionHandler() with IExceptionHandler implementations (.NET 8+) and AddProblemDetails() to return RFC 9457 ProblemDetails JSON. Map known exception types to statuses (NotFound → 404, Validation → 400, Conflict → 409), log unexpected ones as errors with a trace ID, and never return stack traces in production. For expected failures, consider the Result pattern instead of exceptions."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"409","title":"How do you version an API?","body":"Use the Asp.Versioning packages. Strategies: URL segment ( /api/v2/orders , most common and cache-friendly), query string ( ?api-version=2.0 ), header ( api-version ), or media type. Keep old versions running for a deprecation period, report supported/deprecated versions in headers, document each version in OpenAPI, and introduce a new major version only for breaking changes (removing or renaming fields, changing types or semantics)."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"410","title":"What is content negotiation?","body":"The client states the formats it accepts ( Accept: application/json or application/xml ), and the server picks an output formatter that matches. If none matches, it uses the default (JSON) or returns 406 if ReturnHttpNotAcceptable = true . Input format is determined by Content-Type ; an unsupported one gives 415. XML support is added with AddXmlSerializerFormatters() ."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"411","title":"How do you implement pagination? Offset vs keyset?","body":"Offset: Skip((page-1) size).Take(size) plus a total count. It's simple and allows jumping to any page, but it gets slow for deep pages (the DB still scans skipped rows) and is unstable when data changes. Keyset/cursor: WHERE (CreatedAt, Id) < (@lastCreatedAt, @lastId) ORDER BY CreatedAt DESC, Id DESC with Take(size) and a nextCursor in the response. It's fast and stable, suited to infinite scroll and large tables. Always cap the page size."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"412","title":"What are the rate-limiting algorithms in ASP.NET Core?","body":"Built-in since .NET 7 ( AddRateLimiter ): Fixed window (N requests per window; bursty at window edges), Sliding window (window split into segments; smoother), Token bucket (tokens refill at a rate; allows bursts up to bucket size), Concurrency (max simultaneous requests). Partition by user, API key or IP; return 429 with Retry-After . For multiple instances, apply limits at the gateway (APIM, Front Door) or use a distributed store."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"413","title":"How do you make a POST endpoint idempotent (e.g. payments)?","body":"Require an Idempotency-Key header (a client-generated UUID). On the first request, store the key with request hash, status and response in a table (unique constraint on key + client). Concurrent duplicates hit the constraint and wait or get 409. Later repeats return the stored response instead of re-executing. Expire keys after a period. Combine this with DB unique constraints on business identifiers. Stripe's API popularised the pattern."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"414","title":"How would you secure a public Web API end to end?","body":"HTTPS only with HSTS; OAuth 2.0/OIDC with short-lived JWTs (Authorization Code + PKCE for user clients, client credentials for services); scope/role/policy authorisation plus resource ownership checks (IDOR); input validation and request size limits; parameterised data access; rate limiting and an API gateway/WAF (APIM, Front Door); strict CORS; secrets in Key Vault with managed identities; security headers; dependency scanning; logging and alerting on auth failures; no sensitive data in URLs or logs; and regular penetration tests or OWASP ZAP scans."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"415","title":"gRPC vs REST — when do you use gRPC?","body":"gRPC uses HTTP/2 with Protobuf binary serialisation, has contract-first .proto definitions with generated strongly typed clients, supports bidirectional streaming, and has lower latency and smaller payloads. Use it for internal microservice-to-microservice communication, streaming or polyglot environments. Use REST/JSON for public APIs and browser clients (gRPC needs gRPC-Web in browsers), and where human readability and HTTP caching matter."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"416","title":"How do you test a Web API?","body":"Unit tests for services and handlers with mocked dependencies. Integration tests with WebApplicationFactory<Program : spin up the real pipeline in memory, replace infrastructure with Testcontainers SQL Server or a test DB, call endpoints with HttpClient , and assert status codes and JSON. Add auth tests (fake JWT or a test auth handler), contract tests (OpenAPI diff, Pact), and load tests (k6, Azure Load Testing) before release."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"417","title":"Your API returns 200 OK with `{ \"success\": false, \"error\": \"Not found\" }` for everything. How would you improve it?","body":"Use proper HTTP semantics. Return 404 for not found, 400/422 with ValidationProblemDetails for invalid input, 409 for conflicts, 401/403 for auth, 201 + Location for creates, 204 for deletes, and 500 ProblemDetails with a traceId for unexpected errors. Clients, proxies, caches and monitoring tools rely on status codes; with 200 for everything, error-rate dashboards and retries break. Roll it out in a new API version so existing clients keep working."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"418","title":"An endpoint that lists orders is slow (3 s) for a customer with 50,000 orders. What do you do?","body":"Profile first (Application Insights, EF logging). Typical fixes: add pagination (keyset for deep lists), project only needed columns with Select into DTOs, use AsNoTracking , add a covering index on (CustomerId, CreatedAt DESC) INCLUDE (Total, Status) , avoid N+1 by not lazy loading, return totals separately or approximately, and cache hot results with HybridCache. If the client needs everything for export, make it an async job (202 Accepted + status URL) that streams a file."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"419","title":"A downstream payment API is slow and occasionally down, and your API threads pile up. How do you protect your service?","body":"Add timeouts (per attempt and total), retries with exponential backoff and jitter only for idempotent calls (or with idempotency keys), a circuit breaker to fail fast while it's down, and a bulkhead/concurrency limit so payment calls can't consume all resources. AddStandardResilienceHandler() covers most of this. For non-interactive flows, put requests on a queue (Service Bus) and process them asynchronously with status callbacks or webhooks. Return a clear 503/202 to clients and alert on circuit-open events."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"420","title":"Mobile clients on an old app version break when you rename a JSON field. How do you avoid this in future?","body":"Treat the API as a contract. Make only additive changes in the current version (new optional fields; never rename or remove). Introduce a new version ( /v2 ) for breaking changes, and keep v1 alive with a published deprecation timeline ( Deprecation / Sunset headers). Add OpenAPI diff checks in CI to catch breaking changes, and use consumer-driven contract tests. Clients should ignore unknown fields (tolerant reader)."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"421","title":"After scaling the API to 3 instances, users randomly get logged out and in-memory cache data differs. Why?","body":"The state was per instance: in-memory session or cache, and maybe Data Protection keys (used for cookies and antiforgery) generated per instance. Fix: keep the API stateless (JWT), store session/cache in Redis ( IDistributedCache /HybridCache L2), and persist Data Protection keys to a shared store (Azure Blob + Key Vault, Redis or a DB) with the same application name. Avoid sticky sessions as a crutch."},{"kind":"question","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"422","title":"What is Swagger/OpenAPI and how do you add it to an ASP.NET Core API?","body":"OpenAPI is a standard, machine-readable description of an HTTP API (endpoints, parameters, schemas, auth); Swagger is the original name and the tooling around it (Swagger UI to explore and try endpoints). In .NET 9+ use the built-in builder.Services.AddOpenApi() + app.MapOpenApi() (serves /openapi/v1.json ) and add a UI such as Scalar or Swagger UI; earlier versions use Swashbuckle ( AddSwaggerGen , UseSwagger , UseSwaggerUI ) or NSwag. The document also lets you generate typed clients for Angular/React and test tools."},{"kind":"cheat","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"1","title":"HTTP methods","body":"Method Safe Idempotent Typical response --- --- --- --- GET ✓ ✓ 200 POST ✗ ✗ 201 + Location PUT ✗ ✓ 200/204 PATCH ✗ ✗ 200/204 DELETE ✗ ✓ 204"},{"kind":"cheat","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"2","title":"Status codes to remember","body":"200 · 201 · 202 · 204 · 304 · 400 · 401 (who are you?) · 403 (not allowed) · 404 · 409 · 412 · 415 · 422 · 429 · 500 · 502 · 503 · 504."},{"kind":"cheat","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"3","title":"Pipeline order","body":"csharp app.UseExceptionHandler(); app.UseHttpsRedirection(); app.UseCors(\"spa\"); app.UseAuthentication(); app.UseAuthorization(); app.UseRateLimiter(); app.UseOutputCache(); app.MapControllers();"},{"kind":"cheat","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"4","title":"Minimal API essentials","body":"MapGet/MapPost/MapPut/MapPatch/MapDelete · MapGroup · TypedResults · Results<Ok<T , NotFound · [AsParameters] · AddEndpointFilter · RequireAuthorization · RequireRateLimiting · WithTags / WithName ."},{"kind":"cheat","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"5","title":"Security","body":"JWT = header.payload.signature (signed, not encrypted ) · validate iss/aud/exp/signature · Auth Code + PKCE / Client Credentials · CORS ≠ auth · rate limit · HTTPS/HSTS · Key Vault."},{"kind":"cheat","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"6","title":"Caching options","body":"HTTP headers/ETag · Output cache · IMemoryCache · IDistributedCache (Redis) · HybridCache (.NET 9)."},{"kind":"cheat","course_slug":"aspnet-core-webapi","course_title":"ASP.NET Core Web API & REST","ref":"7","title":"Remember","body":"DTOs not entities · ProblemDetails for errors · CancellationToken everywhere · IHttpClientFactory · pagination with max size · version before breaking · idempotency keys for payments."},{"kind":"course","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"","title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","body":"Exceptions from first principles to production — try/catch/finally, filters, rethrowing, custom exception hierarchies, exceptions vs Result pattern, async and parallel exceptions, global handlers (AppDomain, TaskScheduler, Application Error), every way to handle errors in Web Forms, MVC 5, Web API 2, ASP.NET Core MVC and Web API (middleware, exception filters, IExceptionHandler, ProblemDetails, UseStatusCodePages), Blazor error boundaries, background services, SQL and HTTP error handling, retries with Polly, custom error pages, error codes and correlation ids. An exception is an object that represents an error and interrupts normal flow until some code catches it. Good error handling means: 1. Prevent what you can (validate input, check state). 2. Handle what you can recover from, close to where it happens (retry, fallback, user message). 3. Let the rest bubble up to a global handler that logs everything and returns a safe, consistent response. 4. Never hide errors (empty catch), leak details (stack traces) to users, or use exceptions for normal control flow. Layer Strategy --- --- Method Guard clauses, try/catch only for errors you can handle, using for cleanup Service / domain Throw meaningful (custom) exceptions or return a Result for expected failures Infrastructure Translate low-level errors (SqlException, HttpRequestException), retry transient faults Application boundary Global handler: log with correlation id, map to HTTP status / friendly page Process Last-chance handlers for crashes (log and exit) Year .NET feature --- --- 2002 Structured exception handling in C /VB.NET; Web Forms Page Error , Application Error , customErrors 2009–2013 MVC [HandleError] , IExceptionFilter ; Web API 2 IExceptionHandler , IExceptionLogger (2014) 2012 async/await — exceptions flow through Task ; AggregateException from Task.Wait 2015 C 6 exception filters ( catch (X ex) when (...) ) 2016 ASP.NET Core UseExceptionHandler , UseDeveloperExceptionPage , UseStatusCodePages 2018 [ApiController] automatic 400 ProblemDetails (Core 2.1) 2019–2022 ProblemDetails for errors; AddProblemDetails (.NET 7) 2023 .NET 8 IExceptionHandler , throw helpers ( ArgumentNullException.ThrowIfNull , ArgumentOutOfRangeException.ThrowIfNegative ) 2024–2025 .NET 9/10 refinements: StatusCodeSelector for exception handler, ProblemDetails improvements; RFC 9457 replaces RFC 7807 What happens when an exception is thrown in an ASP.NET Core request: 1. throw creates the exception object and captures the stack trace. 2. The CLR searches up the call stack for a matching catch (exception filters when are evaluated during this search). 3. If found: finally blocks of the frames being unwound run, then the catch block runs. 4. If no catch in your code: the exception propagates out of the controller → MVC exception filters (if any) → middleware pipeline → exception handler middleware ( UseExceptionHandler / IExceptionHandler ), which logs it and writes an error response (ProblemDetails or error page). 5. If nothing handles it (e.g. in a background thread), AppDomain.UnhandledException fires and the process terminates . - Debugger: Exception Settings window (break when thrown), Call Stack, $exception . - Logging: ILogger + Serilog/NLog → Seq, Application Insights, ELK (see the Logging course). - Error tracking: Sentry, Raygun, Application Insights Failures blade, ELMAH (.NET Framework). - Resilience: Polly, Microsoft.Extensions.Http.Resilience . - Analyzers: CA1031 (don't catch general exceptions), CA2200 (rethrow to preserve stack), CA1062 (validate arguments)."},{"kind":"lesson","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"try-catch-finally-filters-and-rethrowing-correctly","title":"try, catch, finally, filters and rethrowing correctly","body":"csharp public async Task<Report LoadReportAsync(string path, CancellationToken ct) { ArgumentException.ThrowIfNullOrWhiteSpace(path); // guard clause (.NET 8) FileStream? stream = null; try { stream = File.OpenRead(path); return await ReportParser.ParseAsync(stream, ct); } catch (FileNotFoundException ex) // most specific first { throw new ReportNotFoundException(path, ex); // wrap with context, keep inner exception } catch (JsonException ex) when (ex.LineNumber is not null) // exception filter — no unwinding if false { logger.LogWarning(ex, \"Bad report format at line {Line}\", ex.LineNumber); throw; // rethrow, keeps original stack trace } catch (OperationCanceledException) when (ct.IsCancellationRequested) { throw; // cancellation is not an error — let it flow } finally { stream?.Dispose(); // always runs (prefer 'using') } } Rule Why --- --- Catch specific exceptions You know how to handle them; others should bubble throw; not throw ex; throw ex resets the stack trace Wrap with an inner exception Adds context without losing the cause using instead of finally for disposal Shorter, can't forget Never catch { } empty Hidden failures, impossible debugging Don't catch Exception in the middle of the code Only at boundaries (global handler, background loop) Exceptions are expensive Don't use them for normal flow ( TryParse , TryGetValue ) ExceptionDispatchInfo.Capture(ex).Throw() rethrows an exception captured elsewhere (another thread) while preserving its stack trace."},{"kind":"lesson","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"custom-exceptions-and-exception-hierarchies","title":"Custom exceptions and exception hierarchies","body":"csharp // A small hierarchy for the application's expected failures public abstract class AppException : Exception { protected AppException(string message, Exception? inner = null) : base(message, inner) { } public abstract string ErrorCode { get; } } public sealed class NotFoundException(string entity, object key) : AppException($\"{entity} '{key}' was not found.\") { public override string ErrorCode = \"not found\"; } public sealed class BusinessRuleException(string message, string code) : AppException(message) { public override string ErrorCode = code; // e.g. \"credit limit exceeded\" } public sealed class ConflictException(string message) : AppException(message) { public override string ErrorCode = \"conflict\"; } // Usage in a service public async Task ApproveAsync(int orderId) { var order = await db.Orders.FindAsync(orderId) ?? throw new NotFoundException(\"Order\", orderId); if (order.Total order.Customer.CreditLimit) throw new BusinessRuleException(\"Order exceeds the customer's credit limit.\", \"credit limit exceeded\"); } The global handler maps NotFoundException → 404, BusinessRuleException → 422/400, ConflictException → 409, anything else → 500."},{"kind":"lesson","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"exceptions-vs-the-result-pattern","title":"Exceptions vs the Result pattern","body":"Exceptions Result object --- --- --- Signal throw return Result.Fail(\"...\") Visible in signature No Yes ( Result<Order ) Cost Expensive (stack trace) Cheap Forgetting to handle Bubbles to global handler Compiler doesn't force checking unless designed so Good for Unexpected/exceptional failures, invariants broken Expected outcomes: validation failed, not found, rule violated csharp public readonly record struct Result<T (T? Value, string? Error) { public bool IsSuccess = Error is null; public static Result<T Ok(T value) = new(value, null); public static Result<T Fail(string error) = new(default, error); } public Result<Order PlaceOrder(Cart cart) { if (cart.Items.Count == 0) return Result<Order .Fail(\"Cart is empty\"); return Result<Order .Ok(new Order(cart)); } // Controller maps results to HTTP var result = service.PlaceOrder(cart); return result.IsSuccess ? Ok(result.Value) : BadRequest(new { error = result.Error }); Many teams combine: Result for validation/business outcomes, exceptions for truly exceptional problems (database down, bug)."},{"kind":"lesson","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"exceptions-in-async-parallel-and-background-code","title":"Exceptions in async, parallel and background code","body":"csharp // await rethrows the first inner exception directly try { await http.GetStringAsync(url); } catch (HttpRequestException ex) { / handled / } // Task.WhenAll: await throws the FIRST exception; all are in the task's AggregateException var all = Task.WhenAll(tasks); try { await all; } catch { foreach (var ex in all.Exception!.InnerExceptions) logger.LogError(ex, \"Task failed\"); } // .Wait() / .Result wrap in AggregateException (and can deadlock) — avoid // Parallel.ForEach collects exceptions into AggregateException try { Parallel.ForEach(items, Process); } catch (AggregateException ae) { ae.Handle(ex = ex is InvalidDataException); } // handle some, rethrow the rest // async void: exceptions crash the process (can't be awaited/caught) — only for event handlers Background services — an unhandled exception in ExecuteAsync stops the host by default (.NET 6+, BackgroundServiceExceptionBehavior.StopHost ). Wrap each iteration: csharp protected override async Task ExecuteAsync(CancellationToken ct) { while (!ct.IsCancellationRequested) { try { await ProcessBatchAsync(ct); } catch (OperationCanceledException) when (ct.IsCancellationRequested) { break; } catch (Exception ex) { logger.LogError(ex, \"Batch failed; retrying in 30 s\"); } await Task.Delay(TimeSpan.FromSeconds(30), ct); } } Last-chance handlers (log, then let the process die): csharp AppDomain.CurrentDomain.UnhandledException += (s, e) = Log.Fatal((Exception)e.ExceptionObject, \"Unhandled exception\"); TaskScheduler.UnobservedTaskException += (s, e) = { Log.Error(e.Exception, \"Unobserved task exception\"); e.SetObserved(); };"},{"kind":"lesson","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"aspdotnet-web-forms-and-mvc-5-dotnet-framework","title":"ASP.NET Web Forms and MVC 5 (.NET Framework)","body":"Web Forms (from local to global): Level How --- --- Code try/catch in event handlers Page Page Error → Server.GetLastError() , Server.ClearError() Application Application Error in Global.asax — log everything unhandled Configuration <customErrors mode=\"On RemoteOnly\" defaultRedirect=\"~/Error.aspx\" + <httpErrors in IIS Tools ELMAH (logs + viewer at /elmah.axd ), log4net/NLog MVC 5: Level How --- --- Action try/catch Controller Override OnException(ExceptionContext filterContext) Filter [HandleError(ExceptionType = ..., View = \"Error\")] , custom IExceptionFilter , global via FilterConfig Application Application Error (catches routing 404s and non-MVC errors) Configuration customErrors + httpErrors Web API 2: ExceptionFilterAttribute (per controller/action), global IExceptionHandler (one place to shape the response) and IExceptionLogger (many loggers), HttpResponseException / Request.CreateErrorResponse for explicit status codes. csharp public class ApiExceptionHandler : ExceptionHandler // Web API 2 { public override void Handle(ExceptionHandlerContext context) { context.Result = new ResponseMessageResult(context.Request.CreateResponse(HttpStatusCode.InternalServerError, new { error = \"An unexpected error occurred.\", correlationId = context.Request.GetCorrelationId() })); } } config.Services.Replace(typeof(IExceptionHandler), new ApiExceptionHandler());"},{"kind":"lesson","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"aspdotnet-core-every-way-to-handle-exceptions","title":"ASP.NET Core — every way to handle exceptions","body":"1. Developer exception page (development only — shows stack traces): csharp if (app.Environment.IsDevelopment()) app.UseDeveloperExceptionPage(); // on by default in Development with WebApplication 2. Exception handler middleware + IExceptionHandler (.NET 8+) — the recommended global handler: csharp builder.Services.AddProblemDetails(o = o.CustomizeProblemDetails = ctx = ctx.ProblemDetails.Extensions[\"traceId\"] = Activity.Current?.Id ?? ctx.HttpContext.TraceIdentifier); builder.Services.AddExceptionHandler<AppExceptionHandler (); // can register several; they run in order until one returns true var app = builder.Build(); app.UseExceptionHandler(); // MVC apps: app.UseExceptionHandler(\"/Home/Error\") for an HTML page app.UseStatusCodePages(); // ProblemDetails/HTML bodies for empty 4xx/5xx responses (e.g. 404) public sealed class AppExceptionHandler(ILogger<AppExceptionHandler logger, IProblemDetailsService problems) : IExceptionHandler { public async ValueTask<bool TryHandleAsync(HttpContext http, Exception ex, CancellationToken ct) { var (status, title) = ex switch { NotFoundException = (StatusCodes.Status404NotFound, \"Resource not found\"), BusinessRuleException = (StatusCodes.Status422UnprocessableEntity, \"Business rule violated\"), ConflictException or DbUpdateConcurrencyException = (StatusCodes.Status409Conflict, \"Conflict\"), ValidationException = (StatusCodes.Status400BadRequest, \"Validation failed\"), OperationCanceledException = (499, \"Client closed request\"), = (StatusCodes.Status500InternalServerError, \"An unexpected error occurred\") }; if (status = 500) logger.LogError(ex, \"Unhandled exception for {Method} {Path}\", http.Request.Method, http.Request.Path); else logger.LogWarning(\"Handled {Exception}: {Message}\", ex.GetType().Name, ex.Message); http.Response.StatusCode = status; return await problems.TryWriteAsync(new ProblemDetailsContext { HttpContext = http, Exception = ex, ProblemDetails = new ProblemDetails { Status = status, Title = title, Detail = status < 500 ? ex.Message : null, // never leak internals for 500s Extensions = { [\"errorCode\"] = (ex as AppException)?.ErrorCode } } }); } } 3. Custom middleware (works on every .NET Core version; same idea): csharp public sealed class ErrorHandlingMiddleware(RequestDelegate next, ILogger<ErrorHandlingMiddleware logger) { public async Task InvokeAsync(HttpContext context) { try { await next(context); } catch (Exception ex) { logger.LogError(ex, \"Unhandled exception\"); if (context.Response.HasStarted) throw; // can't change a response already being sent context.Response.StatusCode = 500; await context.Response.WriteAsJsonAsync(new { title = \"Unexpected error\", traceId = context.TraceIdentifier }); } } } app.UseMiddleware<ErrorHandlingMiddleware (); // register FIRST so it wraps everything 4. MVC exception filters — only for exceptions thrown inside controllers/actions/filters (not middleware, not routing): csharp public sealed class DomainExceptionFilter : IExceptionFilter { public void OnException(ExceptionContext ctx) { if (ctx.Exception is BusinessRuleException br) { ctx.Result = new UnprocessableEntityObjectResult(new ProblemDetails { Title = br.Message, Status = 422 }); ctx.ExceptionHandled = true; } } } builder.Services.AddControllers(o = o.Filters.Add<DomainExceptionFilter ()); 5. Validation errors — [ApiController] automatically returns 400 ValidationProblemDetails when model binding/validation fails; customise with ConfigureApiBehaviorOptions(o = o.InvalidModelStateResponseFactory = ...) . 6. Status code pages for non-exception errors — UseStatusCodePagesWithReExecute(\"/Error/{0}\") renders a friendly page for 404/403 in MVC apps. Mechanism Catches Best for --- --- --- UseExceptionHandler + IExceptionHandler Everything after it in the pipeline Global, recommended Custom middleware Everything after it Older versions, special needs Exception filters Exceptions in MVC actions/filters Mapping domain exceptions per controller try/catch in action That action Expected, local recovery UseStatusCodePages Empty error status responses Consistent 404/401/403 bodies Developer exception page Everything (dev) Debugging only"},{"kind":"lesson","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"blazor-maui-wpf-winforms-and-console-apps","title":"Blazor, MAUI/WPF/WinForms and console apps","body":"- Blazor: <ErrorBoundary around components shows fallback UI when a child component throws; unhandled errors in Blazor Server break the circuit — show the blazor-error-ui and log on the server. razor <ErrorBoundary <ChildContent <OrderGrid / </ChildContent <ErrorContent <p class=\"alert alert-danger\" Couldn't load orders. Please retry.</p </ErrorContent </ErrorBoundary - WinForms: Application.ThreadException (UI thread) + Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException) + AppDomain.UnhandledException . - WPF: Application.DispatcherUnhandledException (set e.Handled = true after logging if safe). - Console/worker: try/catch in Main around the host run, log fatal, return a non-zero exit code."},{"kind":"lesson","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"handling-sql-http-and-transient-errors-retries-with-polly","title":"Handling SQL, HTTP and transient errors (retries with Polly)","body":"SQL Server errors — inspect SqlException.Number : Number Meaning Handling --- --- --- 2627 / 2601 Unique constraint / unique index violation 409 Conflict (\"email already registered\") 547 Foreign key / check constraint violation 400/409 with a clear message 1205 Deadlock victim Retry the transaction -2 Timeout Retry carefully / optimise query 4060, 18456 Can't open database / login failed Configuration problem — alert 40613, 40501, 40197 (Azure SQL) Transient service errors Retry with backoff ( EnableRetryOnFailure in EF Core) csharp try { await db.SaveChangesAsync(); } catch (DbUpdateException ex) when (ex.InnerException is SqlException { Number: 2627 or 2601 }) { throw new ConflictException(\"A customer with this email already exists.\"); } // EF Core built-in retry for transient errors options.UseSqlServer(cs, sql = sql.EnableRetryOnFailure(maxRetryCount: 5, maxRetryDelay: TimeSpan.FromSeconds(10), errorNumbersToAdd: null)); HTTP calls — HttpRequestException (network/DNS/connection), non-success status codes ( EnsureSuccessStatusCode() throws), TaskCanceledException (timeout). Use resilience pipelines: csharp builder.Services.AddHttpClient<PaymentClient (c = c.BaseAddress = new(\"https://pay.example.com\")) .AddStandardResilienceHandler(); // retry with backoff + jitter, circuit breaker, attempt and total timeouts Retry only transient and idempotent operations; never retry a payment POST without an idempotency key. Combine with a circuit breaker so a failing dependency isn't hammered."},{"kind":"lesson","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"custom-error-pages-error-codes-and-user-friendly-messages","title":"Custom error pages, error codes and user-friendly messages","body":"Principles for what users see: - Clear, polite message + what to do next (\"We couldn't save your order. Please try again in a minute.\"). - A reference/correlation id the user can quote to support — the same id is in the logs. - No stack traces, SQL, server names or file paths (information disclosure). - Correct HTTP status codes (404 page returns 404, not 200). - Stable error codes for APIs ( \"errorCode\": \"credit limit exceeded\" ) so clients can react without parsing text; localise messages on the client. ASP.NET Core MVC error pages: csharp app.UseExceptionHandler(\"/Error\"); // 500s → ErrorController app.UseStatusCodePagesWithReExecute(\"/Error/{0}\"); // 404/403 → same controller, original URL kept public class ErrorController : Controller { [Route(\"Error/{code:int?}\")] public IActionResult Index(int? code) { var feature = HttpContext.Features.Get<IExceptionHandlerPathFeature (); // original path + exception (log it) ViewBag.RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; return code switch { 404 = View(\"NotFound\"), 403 = View(\"Forbidden\"), = View(\"ServerError\") }; } } ProblemDetails (RFC 9457) for APIs: json { \"type\": \"https://shop.example.com/errors/credit-limit\", \"title\": \"Business rule violated\", \"status\": 422, \"detail\": \"Order exceeds the customer's credit limit.\", \"instance\": \"/api/orders/1001/approve\", \"errorCode\": \"credit limit exceeded\", \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01\" }"},{"kind":"question","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"423","title":"What is the difference between throw and throw ex?","body":"throw; rethrows the current exception and preserves the original stack trace. throw ex; throws the same object as if it originated at that line, resetting the stack trace and hiding where the error really happened. Use throw; or wrap in a new exception with the original as InnerException ."},{"kind":"question","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"424","title":"What are best practices for exception handling in .NET?","body":"Validate early with guard clauses; catch only specific exceptions you can handle; never swallow exceptions silently; use using for cleanup; rethrow with throw; ; wrap with context and inner exceptions; don't use exceptions for normal flow ( TryParse ); have one global handler at each application boundary that logs with a correlation id and returns safe responses; custom exceptions only when callers handle them specifically."},{"kind":"question","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"425","title":"What does finally do? When doesn't it run?","body":"finally runs after the try (and any catch) whether an exception occurred or not — for cleanup. It doesn't run if the process is killed, on Environment.FailFast , on a StackOverflowException, or if the thread hangs inside try. using statements compile to try/finally."},{"kind":"question","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"426","title":"How do you create a custom exception?","body":"Derive from Exception (or your own base like AppException ), name it ...Exception , provide constructors for message and inner exception, and add properties with useful data (entity, key, error code). Create one when callers need to distinguish that case (e.g. map to 404 or 409); otherwise use built-in exceptions."},{"kind":"question","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"427","title":"How do you implement global exception handling in ASP.NET Core?","body":"Use UseExceptionHandler() with AddProblemDetails() and one or more IExceptionHandler implementations (.NET 8+) — or custom middleware registered first in older versions — to log the exception with a trace id and map exception types to status codes (404, 409, 422, 500) with ProblemDetails bodies. Add UseStatusCodePages for empty error responses, exception filters for MVC-specific mapping, and the developer exception page only in development."},{"kind":"question","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"428","title":"Middleware vs exception filter for handling exceptions — which and why?","body":"Exception middleware/handler wraps the whole pipeline, so it catches errors from routing, other middleware, controllers, minimal APIs and views — the right place for global logging and response shaping. Exception filters only see exceptions from MVC actions and filters but have access to MVC context (action, model state) — useful for controller-specific mapping. Typically: a global handler plus optional filters."},{"kind":"question","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"429","title":"How are errors handled in ASP.NET MVC 5 and Web Forms?","body":"Web Forms: try/catch → Page Error → Application Error in Global.asax → customErrors / httpErrors in web.config (ELMAH or log frameworks for logging). MVC 5: try/catch → controller OnException → [HandleError] /custom IExceptionFilter (global in FilterConfig) → Application Error (for routing/404 and non-MVC errors) → customErrors/httpErrors. Web API 2 adds IExceptionHandler / IExceptionLogger ."},{"kind":"question","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"430","title":"Exceptions or Result objects — when to use which?","body":"Use exceptions for unexpected or exceptional conditions (bugs, infrastructure down, broken invariants) — they bubble to a global handler. Use Result objects for expected outcomes that callers must handle (validation failed, not found in a lookup, business rule rejected) — explicit in the signature and cheaper. Mixing them consistently (documented in the team) is common."},{"kind":"question","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"431","title":"How do exceptions behave with async/await and Task.WhenAll?","body":"await unwraps and rethrows the task's exception directly (the first one). Task.WhenAll faults with all exceptions in AggregateException , but await rethrows only the first — inspect task.Exception.InnerExceptions for all. .Result / .Wait() wrap in AggregateException and risk deadlocks. async void exceptions can't be caught by callers and crash the process."},{"kind":"question","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"432","title":"What is ProblemDetails?","body":"A standard JSON format (RFC 9457, previously 7807) for HTTP API errors with type , title , status , detail , instance and extension fields (e.g. traceId , errorCode , validation errors ). ASP.NET Core produces it for validation errors ( [ApiController] ) and, with AddProblemDetails , for exceptions and status codes — clients get one consistent error shape."},{"kind":"question","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"433","title":"How do you handle a unique-key violation from SQL Server?","body":"Catch DbUpdateException (EF) or SqlException with Number 2627/2601, translate it to a domain/conflict exception, and return 409 with a friendly message (\"email already registered\"). Better still, check for duplicates first for a nicer UX, but keep the unique constraint as the real guarantee against race conditions."},{"kind":"question","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"434","title":"What happens to an unhandled exception in a background thread or BackgroundService?","body":"An unhandled exception on a thread (not a Task) terminates the process after raising AppDomain.UnhandledException . In a BackgroundService , an exception escaping ExecuteAsync stops the host by default since .NET 6 (configurable with BackgroundServiceExceptionBehavior ). Unobserved faulted tasks raise TaskScheduler.UnobservedTaskException but no longer crash the process. Wrap each unit of work in try/catch, log, and continue or back off."},{"kind":"question","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"435","title":"Why should you not catch System.Exception everywhere?","body":"It hides bugs and unexpected states, makes the program continue with corrupted data, catches exceptions you can't handle (OutOfMemory, cancellation) and duplicates logging. Catch Exception only at boundaries — global handlers, top of background loops, plug-in hosts — where you log and fail safely."},{"kind":"question","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"436","title":"Users see a yellow error page with SQL details in production. What do you change?","body":"Turn on custom errors ( customErrors mode=\"On\" / RemoteOnly and IIS httpErrors in .NET Framework; UseExceptionHandler and not the developer page outside Development in Core), make sure ASPNETCORE ENVIRONMENT=Production / compilation debug=\"false\" , add a global handler that logs the full exception with a correlation id and shows a friendly page with that id, and review what else leaked (connection strings, versions)."},{"kind":"question","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"437","title":"An API returns 500 for \"customer not found\" and \"invalid quantity\". How do you improve it?","body":"Distinguish expected failures from bugs: validate input (400 via [ApiController] /FluentValidation), throw or return a NotFound result (404), map business rule violations to 409/422 with error codes — all through a global IExceptionHandler producing ProblemDetails. Keep 500 for real unexpected errors only, which then become meaningful alerts."},{"kind":"question","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"438","title":"Intermittent \"deadlock victim\" errors appear under load. How do you handle them in code?","body":"They are SQL error 1205 — transient by nature. Retry the whole transaction a few times with backoff (EF Core execution strategy / Polly), keeping the operation idempotent. In parallel fix the cause: consistent access order of tables, shorter transactions, proper indexes, RCSI isolation to reduce reader/writer blocking."},{"kind":"cheat","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"1","title":"Rules","body":"Validate early · catch specific · throw; · wrap with inner · using for cleanup · no empty catch · no exceptions for flow · global handler at boundaries · log once with correlation id · friendly messages, no internals."},{"kind":"cheat","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"2","title":"ASP.NET Core","body":"AddProblemDetails + AddExceptionHandler<T + UseExceptionHandler() · UseStatusCodePages(WithReExecute) · exception filters for MVC · [ApiController] 400s · developer page only in Development."},{"kind":"cheat","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"3","title":".NET Framework","body":"Web Forms: try/catch → Page Error → Application Error → customErrors/httpErrors · MVC 5: OnException → [HandleError]/IExceptionFilter → Application Error · Web API 2: IExceptionHandler/IExceptionLogger."},{"kind":"cheat","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"4","title":"Status mapping","body":"Validation 400 · auth 401/403 · not found 404 · conflict/duplicate/concurrency 409 · business rule 422 · rate limit 429 · bug/unknown 500 · dependency down 502/503 · timeout 504."},{"kind":"cheat","course_slug":"exception-handling","course_title":"Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type","ref":"5","title":"Async & process","body":"await rethrows first exception · WhenAll → check InnerExceptions · avoid async void · BackgroundService: try/catch per iteration · AppDomain.UnhandledException / TaskScheduler.UnobservedTaskException for last-chance logging."},{"kind":"course","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"","title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","body":"Why and what to log, log levels, structured vs plain-text logging, Microsoft.Extensions.Logging (ILogger, providers, categories, filtering, scopes, high-performance LoggerMessage source generators), Serilog (sinks, enrichers, request logging), NLog and log4net (including .NET Framework apps), Trace and Windows Event Log, writing a custom logger provider (file and database), audit logging, correlation ids and distributed tracing with OpenTelemetry and Application Insights, log storage and querying (Seq, ELK, Azure Monitor/KQL), security (PII, secrets) and performance. Logging records what an application does so you can understand behaviour, diagnose problems and audit actions — especially in production where you can't attach a debugger. Signal Answers Example tools --- --- --- Logs What happened, in detail? ILogger, Serilog, NLog, log4net Metrics How many / how fast / how often? System.Diagnostics.Metrics , Prometheus, App Insights Traces Where did time go across services for one request? Activity , OpenTelemetry, Jaeger, App Insights Audit trail Who did what to which data, when? Dedicated audit tables/log store Together logs, metrics and traces are called observability . Year Milestone --- --- 2001–2004 log4net (Apache port of log4j); System.Diagnostics.Trace / EventLog in .NET Framework 2006 NLog 1.0 2009 ELMAH (error logging for ASP.NET Web Forms/MVC) 2013 Serilog — structured logging for .NET 2016 Microsoft.Extensions.Logging ( ILogger<T ) with ASP.NET Core 1.0 2019–2021 LoggerMessage.Define ; .NET 6 logging source generator ( [LoggerMessage] ) 2021–2023 OpenTelemetry .NET 1.0 (tracing 2021, metrics 2022, logs 2023) 2024–2025 .NET 8/9 log redaction/enrichment ( Microsoft.Extensions.Telemetry ), .NET Aspire dashboard with OpenTelemetry logs Life of a log event: 1. Code calls logger.LogWarning(\"Payment {PaymentId} retry {Attempt}\", id, attempt) . 2. The logger checks if the level is enabled for this category (cheap check — nothing else happens if not). 3. A log entry is created: timestamp, level, category, message template, named properties (PaymentId, Attempt), exception, scope data (RequestId, TraceId, user). 4. Each registered provider/sink receives it: console, file, Seq, Application Insights, database… 5. Sinks often buffer and batch asynchronously, then write/send. 6. Logs are stored with a retention period, queried (search by property, KQL), turned into alerts and dashboards. - Frameworks: Microsoft.Extensions.Logging, Serilog (+ Serilog.AspNetCore, sinks), NLog (+ NLog.Web.AspNetCore), log4net, ELMAH (.NET Framework). - Stores/viewers: Seq, Elasticsearch + Kibana (ELK/Elastic Stack), Grafana Loki, Azure Monitor / Application Insights (KQL), Datadog, Splunk, Windows Event Viewer. - Tracing: OpenTelemetry SDK + exporters (OTLP), .NET Aspire dashboard, Jaeger, Zipkin. - CLI: dotnet-trace , dotnet-counters , dotnet-monitor ."},{"kind":"lesson","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"what-to-log-log-levels-and-structured-logging","title":"What to log, log levels and structured logging","body":"Level Use for Example --- --- --- Trace Very detailed internals; may contain sensitive data — off in production \"Entering CalculateTax with 3 lines\" Debug Developer diagnostics \"Cache miss for product 42\" Information Normal significant events \"Order 1001 placed by customer 42 (₹4,500)\" Warning Unexpected but handled; might need attention \"Payment gateway slow (3.2 s), retrying\" Error A failure of the current operation \"Failed to save order 1001\" + exception Critical The app or a major part is down \"Cannot connect to database — shutting down\" What to log: application start/stop and configuration summary, incoming requests (method, path, status, duration), important business events, external calls (target, duration, result), handled failures (warning) and unhandled exceptions (error, with stack trace), security events (logins, permission denied). What NOT to log: passwords, tokens, full card numbers, secrets, connection strings, personal data beyond what's necessary (GDPR/DPDP), huge payloads. Structured logging — log a message template with named properties instead of a pre-built string: csharp // ❌ String interpolation — one opaque string, can't query by OrderId, allocates even if the level is disabled logger.LogInformation($\"Order {order.Id} placed by {customer.Id} total {order.Total}\"); // ✅ Message template — properties are stored separately and searchable logger.LogInformation(\"Order {OrderId} placed by {CustomerId} total {Total}\", order.Id, customer.Id, order.Total); In Seq/App Insights you can then query OrderId = 1001 or Total 10000 across millions of entries."},{"kind":"lesson","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"microsoft-extensions-logging-ilogger-providers-and-configuration","title":"Microsoft.Extensions.Logging — ILogger, providers and configuration","body":"csharp public class OrderService(ILogger<OrderService logger) // category = full class name { public async Task PlaceAsync(Order order) { logger.LogInformation(\"Placing order {OrderId} with {LineCount} lines\", order.Id, order.Lines.Count); try { await repository.SaveAsync(order); } catch (Exception ex) { logger.LogError(ex, \"Failed to save order {OrderId}\", order.Id); // exception first parameter throw; } } } Providers (where logs go): Console, Debug, EventSource, EventLog (Windows), Azure App Service, Application Insights, OpenTelemetry — plus third-party (Serilog, NLog) plugged in as providers. csharp var builder = WebApplication.CreateBuilder(args); // adds Console, Debug, EventSource (+ EventLog on Windows) by default builder.Logging.ClearProviders(); builder.Logging.AddConsole(); builder.Logging.AddJsonConsole(); // structured JSON to stdout — ideal for containers Filtering by category and level ( appsettings.json ): json { \"Logging\": { \"LogLevel\": { \"Default\": \"Information\", \"Microsoft.AspNetCore\": \"Warning\", \"Microsoft.EntityFrameworkCore.Database.Command\": \"Warning\", \"Divakar.Shop.Payments\": \"Debug\" }, \"Console\": { \"LogLevel\": { \"Default\": \"Warning\" } } } } The most specific category prefix wins; provider-specific sections override the general one; appsettings.Development.json usually turns on Debug."},{"kind":"lesson","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"scopes-correlation-ids-and-high-performance-logging","title":"Scopes, correlation ids and high-performance logging","body":"Scopes attach properties to every log written inside a block: csharp using (logger.BeginScope(new Dictionary<string, object { [\"OrderId\"] = order.Id, [\"CustomerId\"] = order.CustomerId })) { logger.LogInformation(\"Validating\"); // includes OrderId and CustomerId logger.LogInformation(\"Charging\"); // same } ASP.NET Core automatically adds RequestId , RequestPath , TraceId , SpanId scopes (when the provider includes scopes, e.g. \"IncludeScopes\": true for console). Correlation id — one id that follows a request through UI → API → other services → logs: csharp app.Use(async (ctx, next) = { var id = ctx.Request.Headers[\"X-Correlation-ID\"].FirstOrDefault() ?? Activity.Current?.TraceId.ToString() ?? Guid.NewGuid().ToString(); ctx.Response.Headers[\"X-Correlation-ID\"] = id; using (ctx.RequestServices.GetRequiredService<ILogger<Program ().BeginScope(new Dictionary<string, object { [\"CorrelationId\"] = id })) await next(); }); With OpenTelemetry/W3C trace context, the TraceId already plays this role across services automatically. High-performance logging — the source generator (.NET 6+): csharp public static partial class Log { [LoggerMessage(EventId = 1001, Level = LogLevel.Information, Message = \"Order {OrderId} placed for {Total}\")] public static partial void OrderPlaced(ILogger logger, int orderId, decimal total); [LoggerMessage(EventId = 5001, Level = LogLevel.Error, Message = \"Payment failed for order {OrderId}\")] public static partial void PaymentFailed(ILogger logger, Exception ex, int orderId); } Log.OrderPlaced(logger, order.Id, order.Total); // no boxing, no template parsing at runtime, level checked first Also: if (logger.IsEnabled(LogLevel.Debug)) before expensive message construction; avoid logging in tight loops; let sinks batch asynchronously."},{"kind":"lesson","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"serilog-sinks-enrichers-and-request-logging","title":"Serilog — sinks, enrichers and request logging","body":"csharp // dotnet add package Serilog.AspNetCore Serilog.Sinks.Seq Serilog.Sinks.File using Serilog; Log.Logger = new LoggerConfiguration() // bootstrap logger to capture startup errors .WriteTo.Console() .CreateBootstrapLogger(); try { var builder = WebApplication.CreateBuilder(args); builder.Services.AddSerilog((services, cfg) = cfg .ReadFrom.Configuration(builder.Configuration) // levels/sinks from appsettings \"Serilog\" section .ReadFrom.Services(services) .Enrich.FromLogContext() .Enrich.WithProperty(\"Application\", \"Shop.Api\") .WriteTo.Console() .WriteTo.File(\"logs/shop-.log\", rollingInterval: RollingInterval.Day, retainedFileCountLimit: 14) .WriteTo.Seq(\"http://localhost:5341\")); var app = builder.Build(); app.UseSerilogRequestLogging(); // one summary event per request: method, path, status, elapsed app.MapControllers(); app.Run(); } catch (Exception ex) { Log.Fatal(ex, \"Application terminated unexpectedly\"); } finally { Log.CloseAndFlush(); // flush buffered sinks } json \"Serilog\": { \"MinimumLevel\": { \"Default\": \"Information\", \"Override\": { \"Microsoft.AspNetCore\": \"Warning\" } } } Concepts: sinks (Console, File, Seq, Elasticsearch, Application Insights, SQL Server via Serilog.Sinks.MSSqlServer ), enrichers (machine name, thread id, environment, user), destructuring ( {@Order} logs the object's properties; {$Order} its ToString), LogContext.PushProperty(\"TenantId\", id) ."},{"kind":"lesson","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"nlog-and-log4net-including-dotnet-framework-apps","title":"NLog and log4net (including .NET Framework apps)","body":"NLog — configuration-driven ( nlog.config ), many targets, layouts: xml <nlog xmlns=\"http://www.nlog-project.org/schemas/NLog.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" <targets async=\"true\" <target xsi:type=\"File\" name=\"file\" fileName=\"logs/${shortdate}.log\" layout=\"${longdate} ${level:uppercase=true} ${logger} ${message} ${exception:format=tostring}\" / <target xsi:type=\"Database\" name=\"db\" connectionString=\"${configsetting:ConnectionStrings.Logs}\" commandText=\"INSERT INTO dbo.Logs (Logged, Level, Logger, Message, Exception) VALUES (@t, @l, @lg, @m, @e)\" <parameter name=\"@t\" layout=\"${date}\" / <parameter name=\"@l\" layout=\"${level}\" / <parameter name=\"@lg\" layout=\"${logger}\" / <parameter name=\"@m\" layout=\"${message}\" / <parameter name=\"@e\" layout=\"${exception:tostring}\" / </target </targets <rules <logger name=\"Microsoft. \" maxlevel=\"Info\" final=\"true\" / <!-- drop noisy framework info -- <logger name=\" \" minlevel=\"Info\" writeTo=\"file,db\" / </rules </nlog csharp builder.Logging.ClearProviders(); builder.Host.UseNLog(); // NLog.Web.AspNetCore — ILogger<T calls now go to NLog log4net — common in .NET Framework (Web Forms/MVC 5/WCF) code: xml <log4net <appender name=\"RollingFile\" type=\"log4net.Appender.RollingFileAppender\" <file value=\"App Data\\Logs\\app.log\" / <appendToFile value=\"true\" / <rollingStyle value=\"Date\" / <datePattern value=\"yyyyMMdd\" / <layout type=\"log4net.Layout.PatternLayout\" <conversionPattern value=\"%date [%thread] %-5level %logger - %message%newline%exception\" / </layout </appender <root <level value=\"INFO\" / <appender-ref ref=\"RollingFile\" / </root </log4net csharp // Global.asax Application Start: log4net.Config.XmlConfigurator.Configure(); private static readonly ILog Log = LogManager.GetLogger(typeof(ProductsController)); Log.Info(\"Products page loaded\"); Log.Error(\"Save failed\", ex); Built-in .NET Framework options: System.Diagnostics.Trace with listeners in web.config, EventLog.WriteEntry (Windows Event Viewer — needs a registered source), ASP.NET health monitoring , ELMAH (automatic unhandled-error logging with a web viewer /elmah.axd — protect it!). Serilog NLog log4net MS ILogger only --- --- --- --- --- Structured logging Native, best Good Limited Yes (depends on provider) Config Code or JSON XML/JSON XML JSON Typical use Modern .NET Modern + Framework Legacy Framework Simple apps, with OpenTelemetry/App Insights"},{"kind":"lesson","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"writing-a-custom-logger-provider-file-and-database","title":"Writing a custom logger provider (file and database)","body":"You implement ILoggerProvider (creates loggers per category) and ILogger (writes entries). Keep writes non-blocking : queue entries and write them on a background task. csharp public sealed class DbLoggerProvider : ILoggerProvider { private readonly Channel<LogRow queue = Channel.CreateBounded<LogRow (new BoundedChannelOptions(10 000) { FullMode = BoundedChannelFullMode.DropOldest }); private readonly Task writer; private readonly string connectionString; private readonly LogLevel minLevel; public DbLoggerProvider(string connectionString, LogLevel minLevel) { connectionString = connectionString; minLevel = minLevel; writer = Task.Run(WriteLoopAsync); } public ILogger CreateLogger(string categoryName) = new DbLogger(categoryName, this); internal bool IsEnabled(LogLevel level) = level = minLevel && level != LogLevel.None; internal void Enqueue(LogRow row) = queue.Writer.TryWrite(row); private async Task WriteLoopAsync() { var batch = new List<LogRow (100); await foreach (var row in queue.Reader.ReadAllAsync()) { batch.Add(row); if (batch.Count < 100 && queue.Reader.Count 0) continue; // gather a batch try { await using var conn = new SqlConnection( connectionString); await conn.ExecuteAsync(\"INSERT INTO dbo.AppLogs (Utc, Level, Category, Message, Exception, TraceId) \" + \"VALUES (@Utc, @Level, @Category, @Message, @Exception, @TraceId)\", batch); // Dapper } catch { / never let logging crash the app; optionally fall back to a file / } batch.Clear(); } } public void Dispose() { queue.Writer.TryComplete(); writer.Wait(TimeSpan.FromSeconds(5)); } } internal sealed class DbLogger(string category, DbLoggerProvider provider) : ILogger { public IDisposable? BeginScope<TState (TState state) where TState : notnull = null; public bool IsEnabled(LogLevel logLevel) = provider.IsEnabled(logLevel); public void Log<TState (LogLevel level, EventId id, TState state, Exception? ex, Func<TState, Exception?, string formatter) { if (!IsEnabled(level)) return; provider.Enqueue(new LogRow(DateTime.UtcNow, level.ToString(), category, formatter(state, ex), ex?.ToString(), Activity.Current?.TraceId.ToString())); } } public sealed record LogRow(DateTime Utc, string Level, string Category, string Message, string? Exception, string? TraceId); // Registration builder.Logging.AddProvider(new DbLoggerProvider(builder.Configuration.GetConnectionString(\"Logs\")!, LogLevel.Warning)); sql CREATE TABLE dbo.AppLogs ( Id BIGINT IDENTITY PRIMARY KEY, Utc DATETIME2 NOT NULL, Level VARCHAR(20) NOT NULL, Category NVARCHAR(256) NOT NULL, Message NVARCHAR(MAX) NOT NULL, Exception NVARCHAR(MAX) NULL, TraceId VARCHAR(64) NULL); CREATE INDEX IX AppLogs Utc ON dbo.AppLogs(Utc) INCLUDE (Level); Considerations: bounded queue (don't run out of memory if the DB is down), batching, retention job (delete/archive old rows), separate database from business data, never log inside the logger (infinite recursion). In most cases prefer an existing sink (Serilog MSSqlServer, NLog Database target) — but interviewers like to see you can build one."},{"kind":"lesson","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"audit-logging-vs-diagnostic-logging","title":"Audit logging vs diagnostic logging","body":"Diagnostic logs Audit logs --- --- --- Purpose Troubleshooting, monitoring Compliance, security, accountability Content Technical events, errors, timings Who, what, when, where, before/after values Retention Days–weeks Years (regulation-driven) Integrity Best effort; may sample/drop Must be complete, tamper-evident Storage Log platforms Database tables / immutable storage csharp // EF Core SaveChanges interceptor writing audit rows for changed entities public sealed class AuditInterceptor(ICurrentUser user) : SaveChangesInterceptor { public override ValueTask<InterceptionResult<int SavingChangesAsync(DbContextEventData e, InterceptionResult<int result, CancellationToken ct = default) { var db = e.Context!; var audits = db.ChangeTracker.Entries() .Where(x = x.State is EntityState.Added or EntityState.Modified or EntityState.Deleted && x.Entity is not AuditEntry) .Select(x = new AuditEntry { Table = x.Metadata.GetTableName()!, Action = x.State.ToString(), User = user.Name, Utc = DateTime.UtcNow, Changes = JsonSerializer.Serialize(x.Properties.Where(p = p.IsModified x.State != EntityState.Modified) .ToDictionary(p = p.Metadata.Name, p = new { Old = p.OriginalValue, New = p.CurrentValue })) }).ToList(); db.Set<AuditEntry ().AddRange(audits); return base.SavingChangesAsync(e, result, ct); } } SQL Server alternatives: temporal tables (automatic row history), SQL Server Audit , Change Data Capture."},{"kind":"lesson","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"opentelemetry-application-insights-and-querying-logs-in-production","title":"OpenTelemetry, Application Insights and querying logs in production","body":"csharp builder.Logging.AddOpenTelemetry(o = { o.IncludeFormattedMessage = true; o.IncludeScopes = true; }); builder.Services.AddOpenTelemetry() .ConfigureResource(r = r.AddService(\"Shop.Api\")) .WithTracing(t = t.AddAspNetCoreInstrumentation().AddHttpClientInstrumentation().AddSqlClientInstrumentation()) .WithMetrics(m = m.AddAspNetCoreInstrumentation().AddRuntimeInstrumentation()) .UseOtlpExporter(); // to the Aspire dashboard, Jaeger, Grafana, or Azure Monitor (UseAzureMonitor()) Logs written inside a request automatically carry its TraceId/SpanId , so you can jump from an error log to the full distributed trace. Querying (Application Insights / Azure Monitor KQL): kusto traces where timestamp ago(1h) and severityLevel = 3 where customDimensions.OrderId == \"1001\" project timestamp, message, operation Id exceptions where timestamp ago(24h) summarize count() by type, outerMessage order by count desc Production practices: - Log to stdout as JSON in containers; let the platform ship logs. - Central log store with retention policies and access control. - Alerts on error rates and critical events, not on every single error. - Sampling for high-volume debug/trace data; never sample audit logs. - Redact sensitive values ( Microsoft.Extensions.Compliance.Redaction , Serilog destructuring policies). - Change levels at runtime without redeploy (configuration reload, App Configuration, Serilog LoggingLevelSwitch )."},{"kind":"question","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"439","title":"What are the log levels in .NET and when do you use each?","body":"Trace (very detailed internals, off in production), Debug (developer diagnostics), Information (normal business events: order placed, user logged in), Warning (unexpected but handled: retry, slow dependency), Error (an operation failed — with the exception), Critical (system-wide failure needing immediate attention). Configure the minimum level per category so production logs stay useful and affordable."},{"kind":"question","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"440","title":"What is structured logging and why is it better than string logs?","body":"Logging a message template with named properties ( \"Order {OrderId} placed\", id ) so each property is stored as a separate field. You can search, filter and aggregate by OrderId or Total across millions of entries, build dashboards and alerts, and the logger avoids formatting work when the level is disabled. Interpolated strings lose that structure."},{"kind":"question","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"441","title":"How does logging work in ASP.NET Core?","body":"Through Microsoft.Extensions.Logging : inject ILogger<T (category = class name), call LogInformation/LogError etc. Providers (Console, Debug, EventLog, Application Insights, OpenTelemetry, Serilog/NLog) write the entries; appsettings.json \"Logging\" section filters by category and level; scopes add contextual properties like RequestId and TraceId."},{"kind":"question","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"442","title":"What should never be logged?","body":"Passwords, tokens/API keys, connection strings, full card numbers/CVV, secrets, and personal data beyond what's needed (Aadhaar/PAN, health data, full addresses) — logs are widely accessible and kept long. Mask or redact, log identifiers instead of content, and review log output in code reviews."},{"kind":"question","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"443","title":"Serilog vs NLog vs log4net vs built-in ILogger?","body":"ILogger is the abstraction your code depends on; the others are implementations plugged in as providers. Serilog: structured logging first, rich sinks and enrichers, code or JSON configuration — the popular choice for modern .NET. NLog: mature, XML/JSON config, many targets, good performance, works in Framework and Core. log4net: older, XML-configured, common in legacy .NET Framework apps, limited structured support. Built-in providers + OpenTelemetry/App Insights are enough for many cloud apps."},{"kind":"question","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"444","title":"How do you correlate logs across multiple services?","body":"Use a correlation/trace id generated at the edge and propagated in headers (W3C traceparent automatically via Activity /OpenTelemetry, or X-Correlation-ID ), include it in every log (scope/enricher), return it to clients in error responses, and send logs from all services to one store where you can filter by that id or open the distributed trace."},{"kind":"question","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"445","title":"How would you write a custom logger in .NET?","body":"Implement ILoggerProvider (creates ILogger instances per category and holds shared resources) and ILogger ( IsEnabled , Log , BeginScope ), register it with builder.Logging.AddProvider(...) . Make writing asynchronous and batched through a bounded queue (Channel) so logging never blocks requests, handle sink failures without throwing, and dispose/flush on shutdown."},{"kind":"question","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"446","title":"What are logging scopes?","body":"A way to attach contextual properties to all log entries written within a block ( using (logger.BeginScope(...)) ) — e.g. OrderId, TenantId, CorrelationId. ASP.NET Core adds request scopes automatically. Providers must support scopes (Serilog's Enrich.FromLogContext , console IncludeScopes )."},{"kind":"question","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"447","title":"What is the difference between audit logging and application logging?","body":"Application (diagnostic) logs help developers and operators troubleshoot — technical, short retention, can be sampled. Audit logs record who did what to which data and when (often with before/after values) for compliance and security — complete, tamper-evident, long retention, stored separately (audit tables, temporal tables, SQL Server Audit, immutable storage)."},{"kind":"question","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"448","title":"How do you make logging fast and avoid performance problems?","body":"Use message templates (no interpolation), check IsEnabled before expensive work, use the [LoggerMessage] source generator for hot paths, avoid logging large objects or inside tight loops, set sensible minimum levels per category, use asynchronous/batching sinks, and sample high-volume diagnostic data."},{"kind":"question","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"449","title":"How did you log errors in .NET Framework Web Forms/MVC apps?","body":"Typically log4net or NLog configured in web.config/separate config, initialised in Application Start ; unhandled errors captured in Application Error (and MVC exception filters) and logged with the request URL and user; ELMAH for automatic error capture with a protected viewer; Windows Event Log for critical service events; health monitoring in older apps."},{"kind":"question","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"450","title":"How do you change log levels in production without redeploying?","body":"Keep levels in configuration ( appsettings.json , environment variables, Azure App Configuration) with reloadOnChange so ILogger filters update live; Serilog supports LoggingLevelSwitch controlled from configuration or an admin endpoint; NLog reloads nlog.config automatically ( autoReload=\"true\" ). Raise the level only for the affected category and lower it again afterwards."},{"kind":"question","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"451","title":"What is the difference between Console.WriteLine/Debug.WriteLine and a logging framework?","body":"Console.WriteLine writes plain text to stdout with no levels, categories, structure or filtering; Debug.WriteLine only works in debug builds with a debugger listener. A logging framework adds levels, categories, structured properties, scopes, multiple outputs (files, Seq, App Insights), filtering by configuration, async batching and correlation with traces — essential for production."},{"kind":"question","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"452","title":"Production has an intermittent bug you can't reproduce. How do you use logging to find it?","body":"Check existing logs around the failure times (filter by error, user, trace id); if insufficient, add targeted structured logs (inputs, decisions, external call results) at Information/Debug for that category, temporarily raise its level via configuration without redeploying, correlate with traces and metrics (load, dependency latency), and look for patterns (specific tenant, data, time, server). Remove or lower the extra logging afterwards."},{"kind":"question","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"453","title":"Logging costs on the cloud are exploding. What do you change?","body":"Measure which categories produce the most volume; raise minimum levels for noisy framework categories (EF commands, ASP.NET routing) and Debug/Trace in production; replace per-item logs in loops with summaries; sample high-volume telemetry; shorten retention for diagnostic logs (keep audit logs separately); use metrics instead of logs for counts; drop duplicate logging of the same exception at multiple layers."},{"kind":"question","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"454","title":"The app writes logs to a database, and when the database is slow, requests become slow too. Fix it.","body":"Logging is synchronous on the request path. Make it asynchronous with a bounded in-memory queue and a background writer that batches inserts; drop or spill to a local file when the queue is full; use a separate logging database or, better, a dedicated log platform (Seq/App Insights/ELK); never let logging failures throw into business code."},{"kind":"cheat","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"1","title":"Levels","body":"Trace < Debug < Information < Warning < Error < Critical · production default Information, framework categories Warning."},{"kind":"cheat","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"2","title":"Do","body":"Message templates with named properties · LogError(ex, ...) with the exception · scopes/enrichers for context · correlation/trace ids · JSON to stdout in containers · central store + retention + alerts."},{"kind":"cheat","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"3","title":"Don't","body":"Interpolate log messages · log secrets/PII · log the same exception at every layer · log inside tight loops · block requests on log writes."},{"kind":"cheat","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"4","title":"Libraries","body":"ILogger (abstraction) · Serilog (structured, sinks, enrichers, UseSerilogRequestLogging ) · NLog ( nlog.config targets/rules) · log4net (legacy XML appenders) · ELMAH (Framework errors) · OpenTelemetry (logs + traces + metrics)."},{"kind":"cheat","course_slug":"logging","course_title":"Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger","ref":"5","title":"Custom logger","body":"ILoggerProvider + ILogger · bounded Channel queue · background batch writer · never throw · flush on Dispose · builder.Logging.AddProvider(...) ."},{"kind":"course","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"","title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","body":"Building reusable UI in every .NET UI technology — Web Forms user controls and custom server controls (Control, WebControl, CompositeControl, rendering, ViewState-backed properties, events, postback data, templated controls, design-time attributes), MVC 5 custom HTML helpers, display/editor templates and child actions, ASP.NET Core partial views, custom tag helpers, view components and Razor Class Libraries, Blazor components (parameters, EventCallback, RenderFragment, cascading values, generic components) and WinForms/WPF custom controls. A custom control/component packages markup + behaviour so it can be reused across pages or applications: a date picker, an address editor, a paged grid, a price label that formats currency, a \"cart summary\" widget. Technology Reuse options (simple → powerful) --- --- ASP.NET Web Forms User control (.ascx) → custom server control (class, compiled DLL) → composite/templated control ASP.NET MVC 5 Partial view → display/editor template → custom HTML helper → child action ASP.NET Core MVC/Razor Pages Partial view → tag helper → view component → Razor Class Library (package for many apps) Blazor Razor component ( .razor ) with parameters, events, child content; component libraries WinForms / WPF UserControl → derived control → owner-drawn/custom control with templates (WPF) Interview focus: the difference between user controls and custom controls , tag helpers vs HTML helpers , view components vs partial views , and how state/events work in components. Year Milestone --- --- 2002 Web Forms server controls, user controls, Control / WebControl base classes; WinForms UserControl 2005 ASP.NET 2.0 CompositeControl , control state, adaptive rendering; WPF in 2006 (templated controls) 2009–2011 MVC HTML helpers, Razor (2011), display/editor templates 2016 ASP.NET Core tag helpers and view components 2018–2019 Razor Class Libraries (Core 2.1), Blazor (3.0) components 2023–2025 .NET 8 Blazor Web App (static SSR + interactive render modes), QuickGrid; component libraries (MudBlazor, Radzen, Telerik, Syncfusion) How a reusable component is designed: 1. Identify repetition — same markup/logic on 3+ pages. 2. Define the API — inputs (properties/parameters/attributes), outputs (events/callbacks), slots (child content/templates). 3. Encapsulate markup, styling and behaviour; avoid reaching into the page. 4. Handle state — Web Forms: ViewState/ControlState; Blazor: component fields + parameters; MVC/Core: stateless per request. 5. Package — same project, shared class library, Razor Class Library or NuGet package. 6. Document and test — examples, unit tests (bUnit for Blazor), accessibility checks. - Visual Studio designers and Toolbox (Web Forms/WinForms), [ToolboxData] , [Designer] attributes. - Razor Class Library template ( dotnet new razorclasslib ), NuGet packaging. - bUnit for testing Blazor components; Playwright for UI tests. - Component libraries for reference: Telerik/DevExpress (Web Forms), MudBlazor/Radzen/FluentUI Blazor (Blazor)."},{"kind":"lesson","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"user-controls-vs-custom-server-controls","title":"User controls vs custom server controls","body":"User control ( .ascx ) Custom server control (class) --- --- --- Built with Markup + code-behind (designer support) Code only (C /VB), renders its own HTML Reuse Within one web application (needs the .ascx file) Across applications (compiled DLL), Toolbox support Effort Low Higher Design-time Basic Rich (designers, smart tags, property grid) Registration <%@ Register Src=\"~/Controls/X.ascx\" TagPrefix=\"uc\" TagName=\"X\" % <%@ Register Assembly=\"Shop.Controls\" Namespace=\"Shop.Controls\" TagPrefix=\"shop\" % or web.config <controls Example Address editor, login box for this site Reusable <shop:Money label, rating control sold to many projects User controls were covered in the Web Forms course; here we build custom controls ."},{"kind":"lesson","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"building-a-custom-server-control-rendering-properties-and-viewstate","title":"Building a custom server control — rendering, properties and ViewState","body":"csharp [DefaultProperty(nameof(Amount))] [ToolboxData(\"<{0}:MoneyLabel runat=\\\"server\\\" / \")] public class MoneyLabel : WebControl // WebControl adds style properties (CssClass, Font, etc.) { public MoneyLabel() : base(HtmlTextWriterTag.Span) { } [Category(\"Data\"), DefaultValue(typeof(decimal), \"0\")] public decimal Amount { get = (decimal?)ViewState[nameof(Amount)] ?? 0m; // ViewState-backed so it survives postbacks set = ViewState[nameof(Amount)] = value; } [Category(\"Appearance\"), DefaultValue(\"en-IN\")] public string Culture { get = (string?)ViewState[nameof(Culture)] ?? \"en-IN\"; set = ViewState[nameof(Culture)] = value; } protected override void AddAttributesToRender(HtmlTextWriter writer) { base.AddAttributesToRender(writer); // id, class, style if (Amount < 0) writer.AddAttribute(HtmlTextWriterAttribute.Class, CssClass + \" negative\"); } protected override void RenderContents(HtmlTextWriter writer) = writer.WriteEncodedText(Amount.ToString(\"C\", CultureInfo.GetCultureInfo(Culture))); } aspx <%@ Register Assembly=\"Shop.Controls\" Namespace=\"Shop.Controls\" TagPrefix=\"shop\" % <shop:MoneyLabel ID=\"lblTotal\" runat=\"server\" Amount=\"4500\" CssClass=\"price\" / Base classes: Base Use --- --- Control Minimal: no style properties; override Render WebControl Adds CssClass , Style , Enabled , tag rendering ( RenderBeginTag / RenderContents ) CompositeControl Builds child controls ( CreateChildControls ) — reuse existing TextBoxes/Buttons DataBoundControl / CompositeDataBoundControl Bind to data sources ( DataSource , DataBind ) Existing control (e.g. TextBox ) Extend behaviour (a NumericTextBox )"},{"kind":"lesson","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"composite-controls-events-postback-data-and-templates","title":"Composite controls, events, postback data and templates","body":"csharp // Composite control: label + textbox + validator + event public class SearchBox : CompositeControl, INamingContainer { private TextBox text = null!; private Button button = null!; public event EventHandler<string ? Search; // expose an event to the page public string Placeholder { get = (string?)ViewState[\"Ph\"] ?? \"Search\"; set = ViewState[\"Ph\"] = value; } protected override void CreateChildControls() // create children on every request (postbacks too) { Controls.Clear(); text = new TextBox { ID = \"q\" }; text.Attributes[\"placeholder\"] = Placeholder; button = new Button { ID = \"go\", Text = \"Go\" }; button.Click += (s, e) = Search?.Invoke(this, text.Text.Trim()); Controls.Add( text); Controls.Add( button); } } - INamingContainer gives child controls unique client ids ( SearchBox1$q ). - IPostBackDataHandler — implement LoadPostData / RaisePostDataChangedEvent for controls that read posted form values themselves. - IPostBackEventHandler — RaisePostBackEvent for controls that trigger postbacks ( Page.ClientScript.GetPostBackEventReference ). - Templated controls — [TemplateContainer] + ITemplate properties ( ItemTemplate , EmptyTemplate ) let users supply markup, like Repeater. - ControlState ( OnInit: Page.RegisterRequiresControlState(this) , override SaveControlState/LoadControlState ) for state that must work even with ViewState disabled. - Embedded resources (JS/CSS/images) via [assembly: WebResource] and ClientScript.GetWebResourceUrl ."},{"kind":"lesson","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"mvc-5-custom-html-helpers-display-editor-templates-and-child-actions","title":"MVC 5: custom HTML helpers, display/editor templates and child actions","body":"csharp public static class HtmlHelperExtensions { // Simple helper public static MvcHtmlString Money(this HtmlHelper html, decimal amount, string culture = \"en-IN\") { var tag = new TagBuilder(\"span\"); tag.AddCssClass(amount < 0 ? \"money negative\" : \"money\"); tag.SetInnerText(amount.ToString(\"C\", CultureInfo.GetCultureInfo(culture))); // encodes text return MvcHtmlString.Create(tag.ToString()); } // Strongly typed helper with an expression (like TextBoxFor) public static MvcHtmlString RatingFor<TModel (this HtmlHelper<TModel html, Expression<Func<TModel, int expr, int max = 5) { var name = ExpressionHelper.GetExpressionText(expr); var value = (int)(ModelMetadata.FromLambdaExpression(expr, html.ViewData).Model ?? 0); var sb = new StringBuilder(\"<span class=\\\"rating\\\" \"); for (int i = 1; i <= max; i++) sb.Append($\"<label <input type=\\\"radio\\\" name=\\\"{HttpUtility.HtmlAttributeEncode(name)}\\\" value=\\\"{i}\\\" {(i == value ? \"checked\" : \"\")}/ ★</label \"); return MvcHtmlString.Create(sb.Append(\"</span \").ToString()); } } cshtml @Html.Money(Model.Total) @Html.RatingFor(m = m.Stars) Register the namespace in Views/web.config ( <add namespace=\"Shop.Web.Helpers\" / ) so all views see it. Razor @helper (MVC 5 only) — inline helpers in App Code/Helpers.cshtml . Display/editor templates — Views/Shared/DisplayTemplates/Money.cshtml used by Html.DisplayFor(m = m.Price) when the property has [UIHint(\"Money\")] or matches the type name. Child actions ( Html.Action ) for self-contained widgets with their own data."},{"kind":"lesson","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"aspdotnet-core-custom-tag-helpers","title":"ASP.NET Core: custom tag helpers","body":"Tag helpers let server code participate in rendering HTML-looking elements and attributes — editor-friendly and readable. csharp // <money amount=\"Model.Total\" culture=\"en-IN\" </money → <span class=\"money\" ₹4,500.00</span [HtmlTargetElement(\"money\")] public sealed class MoneyTagHelper : TagHelper { public decimal Amount { get; set; } public string Culture { get; set; } = \"en-IN\"; public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName = \"span\"; output.TagMode = TagMode.StartTagAndEndTag; output.Attributes.SetAttribute(\"class\", Amount < 0 ? \"money negative\" : \"money\"); output.Content.SetContent(Amount.ToString(\"C\", CultureInfo.GetCultureInfo(Culture))); // SetContent HTML-encodes } } // Attribute tag helper: <button asp-confirm=\"Delete this order?\" Delete</button [HtmlTargetElement(Attributes = \"asp-confirm\")] public sealed class ConfirmTagHelper : TagHelper { [HtmlAttributeName(\"asp-confirm\")] public string Message { get; set; } = \"\"; public override void Process(TagHelperContext context, TagHelperOutput output) = output.Attributes.SetAttribute(\"onclick\", $\"return confirm('{JavaScriptEncoder.Default.Encode(Message)}');\"); } cshtml @ Views/ ViewImports.cshtml @ @addTagHelper , Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper , Shop.Web <money amount=\"Model.Total\" </money <button type=\"submit\" asp-confirm=\"Delete this order?\" Delete</button HTML helper ( @Html.TextBoxFor ) Tag helper ( <input asp-for ) --- --- C method call in markup HTML element/attribute Harder for designers to read Looks like HTML, IntelliSense for attributes Available in MVC 5 and Core ASP.NET Core only Async tag helpers override ProcessAsync (e.g. to load data or get child content with output.GetChildContentAsync() )."},{"kind":"lesson","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"aspdotnet-core-view-components-vs-partial-views","title":"ASP.NET Core: view components vs partial views","body":"A view component is a mini-controller + view for a reusable widget that needs its own data and logic (replaces MVC 5 child actions). csharp public sealed class CartSummaryViewComponent(ICartService carts) : ViewComponent { public async Task<IViewComponentResult InvokeAsync(int maxItems = 3) { var cart = await carts.GetForUserAsync(UserClaimsPrincipal); return View(cart.Take(maxItems)); // Views/Shared/Components/CartSummary/Default.cshtml } } cshtml @await Component.InvokeAsync(\"CartSummary\", new { maxItems = 5 }) <vc:cart-summary max-items=\"5\" </vc:cart-summary @ tag-helper syntax @ Partial view View component Tag helper --- --- --- --- Data Passed in by the parent Loads its own (DI, async) Attributes Logic Minimal Yes (class with DI) Rendering logic Typical use Repeated markup (product card) Widgets: cart summary, menu, recent posts Element/attribute enhancement Can be called from a controller PartialView() ViewComponent() result — Razor Class Library (RCL): put views, view components, tag helpers, Razor Pages and static assets ( wwwroot → content/LibName/... ) in a class library and reference it (or ship as NuGet) to reuse UI across apps."},{"kind":"lesson","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"blazor-components-parameters-events-child-content-and-generics","title":"Blazor components — parameters, events, child content and generics","body":"razor @ Components/ConfirmButton.razor @ <button class=\"btn @CssClass\" @onclick=\"AskAsync\" disabled=\"@ busy\" @ChildContent</button @if ( asking) { <div class=\"confirm\" <span @Message</span <button @onclick=\"() = ConfirmAsync(true)\" Yes</button <button @onclick=\"() = ConfirmAsync(false)\" No</button </div } @code { [Parameter] public string Message { get; set; } = \"Are you sure?\"; [Parameter] public string CssClass { get; set; } = \"btn-danger\"; [Parameter] public RenderFragment? ChildContent { get; set; } // content between the tags [Parameter] public EventCallback OnConfirmed { get; set; } // event to the parent private bool asking, busy; private void AskAsync() = asking = true; private async Task ConfirmAsync(bool yes) { asking = false; if (!yes) return; busy = true; await OnConfirmed.InvokeAsync(); // parent's handler runs, UI re-renders busy = false; } } razor <ConfirmButton Message=\"Delete this order?\" OnConfirmed=\"DeleteOrderAsync\" Delete</ConfirmButton razor @ Generic, templated component @ @typeparam TItem <table class=\"table\" <thead <tr @Header</tr </thead <tbody @foreach (var item in Items) { <tr @Row(item)</tr }</tbody </table @code { [Parameter, EditorRequired] public IReadOnlyList<TItem Items { get; set; } = []; [Parameter] public RenderFragment? Header { get; set; } [Parameter, EditorRequired] public RenderFragment<TItem Row { get; set; } = default!; } Key concepts: lifecycle ( OnInitialized(Async) , OnParametersSet(Async) , OnAfterRender(Async) , Dispose ), StateHasChanged() , @bind / @bind-Value two-way binding ( Value + ValueChanged parameters), CascadingValue / [CascadingParameter] for shared context (theme, auth state), @key for list diffing, render modes in .NET 8+ (Static SSR, InteractiveServer, InteractiveWebAssembly, InteractiveAuto), JS interop ( IJSRuntime ), CSS isolation ( Component.razor.css )."},{"kind":"lesson","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"winforms-and-wpf-custom-controls","title":"WinForms and WPF custom controls","body":"WinForms: Approach How --- --- UserControl Combine existing controls in the designer (address panel) Inherited control class NumericTextBox : TextBox — override OnKeyPress to allow digits only Owner-drawn / custom-drawn class Gauge : Control — override OnPaint(PaintEventArgs e) and draw with GDI+, call Invalidate() when data changes csharp public class NumericTextBox : TextBox { protected override void OnKeyPress(KeyPressEventArgs e) { if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar)) e.Handled = true; // block non-digits base.OnKeyPress(e); } } WPF: UserControl (XAML composition) vs custom control ( Control subclass with a default ControlTemplate in Themes/Generic.xaml , fully re-stylable); expose data through dependency properties (support binding, styling, animation) and routed events . csharp public class RatingControl : Control { public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(nameof(Value), typeof(int), typeof(RatingControl), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); public int Value { get = (int)GetValue(ValueProperty); set = SetValue(ValueProperty, value); } static RatingControl() = DefaultStyleKeyProperty.OverrideMetadata(typeof(RatingControl), new FrameworkPropertyMetadata(typeof(RatingControl))); }"},{"kind":"lesson","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"designing-good-reusable-components","title":"Designing good reusable components","body":"- Small, focused API: few required inputs, sensible defaults, clear names. - No hidden dependencies on the page: pass data in; raise events out. - Encode output (XSS): use the framework's encoding ( WriteEncodedText , SetContent , Razor @ ). - Accessibility: proper labels, keyboard support, ARIA where needed, focus management in dialogs. - Styling hooks: CSS classes/parameters; CSS isolation in Blazor; themes/skins in Web Forms. - Performance: avoid heavy ViewState (Web Forms), avoid re-rendering large lists (Blazor @key , ShouldRender , virtualization), cache data in view components when safe. - Versioning & packaging: shared library/RCL/NuGet with semantic versions; document breaking changes. - Testing: bUnit (Blazor), unit tests for tag helpers ( TagHelperOutput ), UI tests for critical widgets."},{"kind":"question","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"455","title":"What is the difference between a user control and a custom control in ASP.NET?","body":"User control (.ascx): created with markup + code-behind, easy to build, reusable only within the same web application (the .ascx file must be present), limited design-time support. Custom server control: a compiled class deriving from Control / WebControl / CompositeControl that renders its own HTML; reusable across applications via a DLL, can be added to the Toolbox with designer support, more effort to build."},{"kind":"question","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"456","title":"What is a custom HTML helper in MVC and how do you create one?","body":"An extension method on HtmlHelper (or HtmlHelper<TModel ) returning MvcHtmlString / IHtmlContent that generates reusable markup, e.g. @Html.Money(total) . Build HTML with TagBuilder (which encodes text), import the namespace in Views/web.config (MVC 5) or ViewImports.cshtml (Core)."},{"kind":"question","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"457","title":"What are tag helpers? How do they differ from HTML helpers?","body":"Tag helpers are classes that process HTML elements/attributes in Razor ( <input asp-for=\"Name\" , custom <money amount=\"...\" ), producing HTML on the server. They look like HTML (designer-friendly, attribute IntelliSense) versus HTML helpers which are C method calls ( @Html.TextBoxFor(...) ). Tag helpers exist only in ASP.NET Core; both can be mixed."},{"kind":"question","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"458","title":"View component vs partial view?","body":"A partial view renders markup with data provided by the caller; a view component is a class with its own logic and dependencies (constructor injection, async InvokeAsync ) plus a view — for widgets that fetch their own data (cart summary, navigation menu). View components replace MVC 5 child actions and are lighter than a full controller action."},{"kind":"question","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"459","title":"How do you create a reusable Blazor component? How does a child notify a parent?","body":"Create a .razor file with markup and an @code block; expose inputs as [Parameter] properties, content slots as RenderFragment ( ChildContent , templates RenderFragment<T ), and notify the parent through [Parameter] EventCallback / EventCallback<T invoked with InvokeAsync , which also triggers the parent's re-render. For two-way binding expose Value + ValueChanged ."},{"kind":"question","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"460","title":"How do you keep a custom Web Forms control's property value across postbacks?","body":"Store it in ViewState in the property getter/setter ( ViewState[\"Amount\"] ), which is saved and restored automatically; for essential state that must work even with ViewState disabled use ControlState ( RegisterRequiresControlState , SaveControlState/LoadControlState ). Child controls of composite controls must be recreated in CreateChildControls on every request."},{"kind":"question","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"461","title":"What is a Razor Class Library?","body":"A class library project that contains Razor views, Razor Pages, view components, tag helpers, Blazor components and static web assets, which other ASP.NET Core apps reference (project or NuGet). It lets teams share UI (layouts, admin areas, component kits) across applications; static files are served from content/{LibraryName}/ ."},{"kind":"question","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"462","title":"What are dependency properties in WPF and why do custom controls use them?","body":"Properties registered with the WPF property system ( DependencyProperty.Register ) whose values can come from bindings, styles, templates, animations and inheritance, with change notifications and default values. Custom controls expose their public properties as dependency properties so consumers can data-bind and style them."},{"kind":"question","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"463","title":"How do you test UI components?","body":"Blazor: bUnit renders components in memory, sets parameters, triggers events and asserts markup/callbacks. Tag helpers: unit test Process with fake TagHelperContext / TagHelperOutput . View components: unit test InvokeAsync results with mocked services. Web Forms controls: test logic extracted from the control; render tests via HtmlTextWriter . End-to-end: Playwright/Selenium."},{"kind":"question","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"464","title":"What is the difference between Control, WebControl and CompositeControl in Web Forms?","body":"Control is the base of all server controls — no styling properties; you override Render and write all HTML. WebControl adds common style properties (CssClass, Style, Font, Enabled) and a tag-rendering model ( TagKey , AddAttributesToRender , RenderContents ). CompositeControl builds its UI from child controls in CreateChildControls (reusing TextBoxes, Buttons, validators) and handles naming and child-control lifetime for you."},{"kind":"question","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"465","title":"How do you make a Blazor component support two-way binding with @bind-Value?","body":"Expose a [Parameter] public T Value and a [Parameter] public EventCallback<T ValueChanged (optionally ValueExpression for validation). When the component's internal value changes, call await ValueChanged.InvokeAsync(newValue) . The parent can then write <MyInput @bind-Value=\"model.Name\" / , which Blazor expands to Value + ValueChanged."},{"kind":"question","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"466","title":"What are display and editor templates in MVC?","body":"Razor partials placed in Views/Shared/DisplayTemplates or EditorTemplates (or per controller) named after a type ( DateTime.cshtml , Money.cshtml ) or selected with [UIHint(\"Money\")] . Html.DisplayFor / EditorFor automatically use them, so every property of that type renders consistently across the site — a lightweight way to build reusable UI without code."},{"kind":"question","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"467","title":"How do you share UI components across several ASP.NET Core applications?","body":"Put them in a Razor Class Library — views, partials, view components, tag helpers, Blazor components and static assets — and reference it as a project or publish it as an internal NuGet package with semantic versioning. Consumers add @addTagHelper / @using in ViewImports , and static files are available under content/{LibraryName}/ ."},{"kind":"question","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"468","title":"Twenty MVC pages repeat the same \"price with discount badge\" markup with slight differences. What do you build?","body":"In ASP.NET Core: a tag helper ( <price amount=\"..\" discount=\"..\" ) if it only needs values passed in, or a partial view/display template for richer markup; a view component if it must fetch data (e.g. live offers). In MVC 5: a custom HTML helper or a display template with [UIHint] . Centralising fixes formatting bugs once and keeps pages consistent."},{"kind":"question","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"469","title":"A dynamically created custom control in Web Forms loses its value and its Click event doesn't fire. Why?","body":"Its child controls aren't recreated early enough or with the same IDs on postback, so ViewState and posted data can't be applied and the event source isn't found. Create children in CreateChildControls (called via EnsureChildControls ) on every request, implement INamingContainer , and add dynamic instances of the control in Page Init / PreInit , not inside if (!IsPostBack) ."},{"kind":"question","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"470","title":"A Blazor grid component with 5,000 rows makes the page slow. How do you improve it?","body":"Virtualize rows ( <Virtualize component) or page server-side, add @key to row elements, avoid re-rendering the whole grid on every change ( ShouldRender , immutable parameters, split into smaller components), avoid heavy work in OnParametersSet , and use QuickGrid or a component library's optimised grid."},{"kind":"cheat","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"1","title":"Pick the right reuse tool","body":"Web Forms: user control (one app) → custom/composite control (many apps) · MVC 5: partial/display template → HTML helper → child action · Core: partial → tag helper → view component → Razor Class Library · Blazor: component (+ library) · WinForms/WPF: UserControl → custom control."},{"kind":"cheat","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"2","title":"Web Forms control essentials","body":"WebControl + RenderContents · ViewState-backed properties · CompositeControl.CreateChildControls + INamingContainer · events · ControlState · [ToolboxData] ."},{"kind":"cheat","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"3","title":"Core essentials","body":"Tag helper: [HtmlTargetElement] , Process(Async) , @addTagHelper · View component: InvokeAsync , Views/Shared/Components/Name/Default.cshtml , <vc:name ."},{"kind":"cheat","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"4","title":"Blazor essentials","body":"[Parameter] · EventCallback · RenderFragment / RenderFragment<T · @typeparam · @bind-Value = Value + ValueChanged · CascadingValue · lifecycle methods · @key · Virtualize."},{"kind":"cheat","course_slug":"custom-controls","course_title":"Custom Controls & Reusable UI Components in .NET — Web Forms to Blazor","ref":"5","title":"Good component rules","body":"Small API · data in, events out · encode output · accessible · styleable · tested · versioned."},{"kind":"course","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"","title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","body":"How real .NET solutions are organised — solution and project structure, 3-tier and N-layer architecture, Onion, Hexagonal (ports and adapters) and Clean Architecture, Vertical Slice architecture, modular monolith, DDD building blocks, CQRS, the folder structure of each style with naming conventions, shared build settings (Directory.Build.props, central package management), test projects, where cross-cutting concerns live, and how to choose an architecture. Architecture = how code is split into parts, what each part is responsible for, and which parts may depend on which. A good structure makes code easy to find, change, test and deploy . Style Core idea Typical fit --- --- --- 3-tier / N-layer UI → Business (BLL) → Data (DAL) Classic enterprise apps, Web Forms/MVC 5 Onion / Clean / Hexagonal Domain at the centre; infrastructure and UI depend inward on interfaces Medium–large apps with real business logic, long life Vertical Slice Organise by feature (one folder per use case), not by technical layer APIs with many independent features, CQRS Modular monolith One deployable, split into independent modules Growing products; stepping stone to microservices Microservices Separate deployable services per business capability Large organisations (see the Microservices course) Year Milestone --- --- 1990s Client/server, then 3-tier architecture 2002 Fowler's Patterns of Enterprise Application Architecture (layers, repository, unit of work) 2003 Domain-Driven Design (Eric Evans) 2005 Hexagonal architecture / ports and adapters (Alistair Cockburn) 2008 Onion architecture (Jeffrey Palermo) 2010 CQRS popularised (Greg Young) 2012 Clean Architecture (Robert C. Martin) 2018 Vertical Slice architecture (Jimmy Bogard) 2020s Modular monoliths; templates: Jason Taylor's CleanArchitecture, Ardalis CleanArchitecture; .NET Aspire solution layouts; .slnx solution format (VS 2022 17.13+/.NET 9 SDK) How a request flows through a Clean Architecture ASP.NET Core API: text HTTP request → Api (controller / minimal endpoint, model binding, auth) [Presentation] → Application (use case / command handler, validation, DTO mapping) [Application] → Domain (entities enforce business rules, domain events) [Domain — no dependencies] → Application calls interfaces (IOrderRepository, IEmailSender, IClock) → Infrastructure implements them (EF Core DbContext, SMTP, Azure Blob) [Infrastructure] → database / external services ← result → DTO → HTTP response Dependency rule: source-code dependencies point inwards (Api → Application → Domain; Infrastructure → Application/Domain). The Domain knows nothing about EF Core, ASP.NET or SQL. - dotnet new sln , dotnet new classlib/webapi/xunit , dotnet sln add , dotnet add reference . - Templates: Clean.Architecture.Solution.Template (Jason Taylor), Ardalis.CleanArchitecture.Template , .NET Aspire starter. - Architecture tests: NetArchTest , ArchUnitNET (enforce \"Domain must not reference Infrastructure\"). - Visual Studio dependency diagrams / code maps, NDepend. - Diagrams: C4 model, draw.io, Structurizr."},{"kind":"lesson","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"solutions-projects-references-and-naming-conventions","title":"Solutions, projects, references and naming conventions","body":"bash dotnet new sln -n Shop dotnet new classlib -n Shop.Domain -o src/Shop.Domain dotnet new classlib -n Shop.Application -o src/Shop.Application dotnet new classlib -n Shop.Infrastructure -o src/Shop.Infrastructure dotnet new webapi -n Shop.Api -o src/Shop.Api dotnet new xunit -n Shop.UnitTests -o tests/Shop.UnitTests dotnet sln add src/ / .csproj tests/ / .csproj dotnet add src/Shop.Application reference src/Shop.Domain dotnet add src/Shop.Infrastructure reference src/Shop.Application dotnet add src/Shop.Api reference src/Shop.Application src/Shop.Infrastructure Repository layout (common convention): text Shop/ ├── src/ production projects ├── tests/ test projects (mirror src names + .UnitTests / .IntegrationTests) ├── docs/ architecture decision records (ADRs), diagrams ├── build/ or eng/ build scripts, pipeline templates ├── deploy/ Dockerfiles, Bicep/Terraform, Helm charts ├── .github/ or .azuredevops/ CI/CD pipelines ├── Directory.Build.props shared MSBuild settings for all projects ├── Directory.Packages.props central NuGet package versions ├── global.json pinned .NET SDK version ├── .editorconfig code style rules └── Shop.sln (or Shop.slnx) Naming: Company.Product.Layer ( Divakar.Shop.Domain ), namespaces match folders, one public type per file, plural folder names for collections of things ( Controllers , Entities ), test classes named <ClassUnderTest Tests . xml <!-- Directory.Build.props: applies to every project below this folder -- <Project <PropertyGroup <TargetFramework net10.0</TargetFramework <Nullable enable</Nullable <ImplicitUsings enable</ImplicitUsings <TreatWarningsAsErrors true</TreatWarningsAsErrors </PropertyGroup </Project <!-- Directory.Packages.props: <ManagePackageVersionsCentrally true</ManagePackageVersionsCentrally + <PackageVersion Include=\"Dapper\" Version=\"2.1.66\" / --"},{"kind":"lesson","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"3-tier-and-n-layer-architecture","title":"3-tier and N-layer architecture","body":"text Presentation layer (UI) Web Forms pages / MVC controllers & views / API controllers ↓ calls Business Logic Layer (BLL) services: validation, calculations, workflows ↓ calls Data Access Layer (DAL) ADO.NET / Dapper / EF repositories, stored procedures ↓ Database Tier vs layer: a layer is a logical separation in code; a tier is a physical deployment unit (browser, web server, database server). A 3-layer app can run on 1, 2 or 3 tiers. Typical .NET Framework solution: text ShopSolution/ ├── Shop.Web/ Web Forms or MVC 5 (UI) ├── Shop.BLL/ ProductService.cs, OrderService.cs ├── Shop.DAL/ ProductRepository.cs (ADO.NET), ShopEntities.edmx (EF6) ├── Shop.Entities/ (Models) Product.cs, Order.cs — shared by all layers └── Shop.Common/ helpers, constants, logging Pros: simple, familiar, clear separation. Cons: business logic tends to depend on the DAL (hard to unit test without a database), \"anemic\" services, changes ripple across layers, everything depends on the database schema."},{"kind":"lesson","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"onion-hexagonal-and-clean-architecture","title":"Onion, Hexagonal and Clean Architecture","body":"All three share one idea: the domain and use cases are the centre; frameworks, databases and UIs are details at the edge , connected through interfaces (Dependency Inversion). text ┌────────────────────────────────────────┐ │ Presentation (Api, Web, Blazor) │ │ ┌──────────────────────────────────┐ │ │ │ Infrastructure (EF Core, email, │ │ │ │ files, external APIs) │ │ │ │ ┌──────────────────────────┐ │ │ │ │ │ Application (use cases, │ │ │ │ │ │ interfaces, DTOs) │ │ │ │ │ │ ┌──────────────────┐ │ │ │ │ │ │ │ Domain (entities,│ │ │ │ │ │ │ │ value objects, │ │ │ │ │ │ │ │ domain rules) │ │ │ │ │ │ │ └──────────────────┘ │ │ │ │ │ └──────────────────────────┘ │ │ │ └──────────────────────────────────┘ │ └────────────────────────────────────────┘ dependencies point INWARD only - Hexagonal (ports & adapters): the application exposes ports (interfaces like IOrderRepository , IPaymentGateway ); adapters implement them (SQL adapter, Stripe adapter) or drive the app (REST controller, message consumer). - Onion: concentric rings — Domain Model → Domain Services → Application Services → outer ring (UI, infrastructure, tests). - Clean Architecture: Entities → Use Cases → Interface Adapters → Frameworks & Drivers; same dependency rule. Clean Architecture folder structure (ASP.NET Core): text src/ ├── Shop.Domain/ no project references, no NuGet except tiny helpers │ ├── Common/ BaseEntity.cs, ValueObject.cs, IDomainEvent.cs │ ├── Entities/ Order.cs, OrderLine.cs, Customer.cs, Product.cs │ ├── ValueObjects/ Money.cs, Address.cs, Email.cs │ ├── Enums/ OrderStatus.cs │ ├── Events/ OrderPlacedEvent.cs │ └── Exceptions/ DomainException.cs ├── Shop.Application/ references Domain only │ ├── Common/ │ │ ├── Interfaces/ IApplicationDbContext.cs, IEmailSender.cs, ICurrentUser.cs, IDateTime.cs │ │ ├── Behaviours/ ValidationBehaviour.cs, LoggingBehaviour.cs (pipeline behaviours) │ │ ├── Exceptions/ NotFoundException.cs, ValidationException.cs │ │ └── Models/ PagedList.cs, Result.cs │ ├── Orders/ │ │ ├── Commands/PlaceOrder/ PlaceOrderCommand.cs, PlaceOrderHandler.cs, PlaceOrderValidator.cs │ │ ├── Queries/GetOrders/ GetOrdersQuery.cs, GetOrdersHandler.cs, OrderDto.cs │ │ └── EventHandlers/ OrderPlacedEmailHandler.cs │ └── DependencyInjection.cs AddApplication() extension ├── Shop.Infrastructure/ references Application (and Domain) │ ├── Persistence/ ShopDbContext.cs, Configurations/OrderConfiguration.cs, Migrations/, Interceptors/ │ ├── Repositories/ (if used) OrderRepository.cs │ ├── Services/ SmtpEmailSender.cs, DateTimeService.cs, BlobFileStorage.cs │ ├── Identity/ identity/auth integration │ └── DependencyInjection.cs AddInfrastructure(configuration) └── Shop.Api/ references Application + Infrastructure (composition root) ├── Controllers/ or Endpoints/ OrdersController.cs / OrderEndpoints.cs ├── Middleware/ ExceptionHandler.cs ├── Filters/ ├── Program.cs builder.Services.AddApplication().AddInfrastructure(cfg); app pipeline └── appsettings.json tests/ ├── Shop.Domain.UnitTests/ ├── Shop.Application.UnitTests/ ├── Shop.Infrastructure.IntegrationTests/ (Testcontainers SQL Server) └── Shop.Api.FunctionalTests/ (WebApplicationFactory) csharp // Application defines what it needs... public interface IEmailSender { Task SendAsync(string to, string subject, string body, CancellationToken ct); } // ...Infrastructure provides it... public sealed class SmtpEmailSender(IOptions<SmtpOptions o) : IEmailSender { / SmtpClient / MailKit / } // ...Api wires it (composition root) builder.Services.AddScoped<IEmailSender, SmtpEmailSender (); Benefits: domain logic testable without a database, swap infrastructure (SQL → Cosmos, SMTP → SendGrid) without touching use cases, framework upgrades isolated. Costs: more projects and mapping code — overkill for small CRUD apps."},{"kind":"lesson","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"vertical-slice-architecture","title":"Vertical Slice architecture","body":"Instead of horizontal layers, organise by feature/use case : everything needed for \"Place order\" lives together. text src/Shop.Api/ ├── Features/ │ ├── Orders/ │ │ ├── PlaceOrder.cs request + validator + handler + endpoint in one file (or a folder) │ │ ├── GetOrderById.cs │ │ ├── CancelOrder.cs │ │ └── OrderMappings.cs │ ├── Products/ │ │ ├── SearchProducts.cs may use Dapper for a fast query │ │ └── CreateProduct.cs may use EF Core │ └── Customers/ ... ├── Domain/ shared entities (if any rich domain) ├── Infrastructure/ DbContext, external clients ├── Common/ behaviours, result types, exceptions └── Program.cs maps all feature endpoints csharp public static class PlaceOrder { public sealed record Command(int CustomerId, List<Line Lines); public sealed record Line(int ProductId, int Qty); public sealed class Validator : AbstractValidator<Command { public Validator() { RuleFor(c = c.Lines).NotEmpty(); RuleForEach(c = c.Lines).ChildRules(l = l.RuleFor(x = x.Qty).GreaterThan(0)); } } public static void MapEndpoint(IEndpointRouteBuilder app) = app.MapPost(\"/api/orders\", async (Command cmd, ShopDbContext db, IValidator<Command v, CancellationToken ct) = { var result = await v.ValidateAsync(cmd, ct); if (!result.IsValid) return Results.ValidationProblem(result.ToDictionary()); var order = Order.Create(cmd.CustomerId, cmd.Lines.Select(l = (l.ProductId, l.Qty))); db.Orders.Add(order); await db.SaveChangesAsync(ct); return Results.Created($\"/api/orders/{order.Id}\", new { order.Id }); }); } Pros: a change touches one folder; features can use different techniques (EF here, Dapper there); easy to delete a feature; fits CQRS. Cons: possible duplication between slices; needs discipline to extract real shared domain logic."},{"kind":"lesson","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"modular-monolith-and-ddd-building-blocks","title":"Modular monolith and DDD building blocks","body":"Modular monolith — one deployable application, divided into modules by business capability; each module has its own folders/projects, its own database schema and a small public API; modules communicate via interfaces or in-process events. text src/ ├── Shop.Host/ ASP.NET Core host — registers all modules ├── Modules/ │ ├── Catalog/ Catalog.Api (endpoints) · Catalog.Core (domain + use cases) · Catalog.Infrastructure (schema \"catalog\") │ ├── Ordering/ Ordering.Api · Ordering.Core · Ordering.Infrastructure (schema \"ordering\") │ └── Billing/ Billing.Api · Billing.Core · Billing.Infrastructure (schema \"billing\") └── Shared/ Shared.Kernel (base types), Shared.Infrastructure (event bus, outbox) Rules: no module reads another's tables; communication through a module's public contracts or integration events; architecture tests enforce boundaries. A module can later become a microservice. DDD building blocks: Block Meaning Example --- --- --- Entity Has identity that persists Order (Id 1001) Value object Defined by its values, immutable Money(4500, \"INR\") , Address Aggregate (root) Consistency boundary; outside code changes it only through the root Order with OrderLines Domain service Logic that doesn't belong to one entity PricingService Domain event Something that happened OrderPlaced Repository Collection-like access to aggregates IOrderRepository Bounded context Boundary where a model applies Sales vs Shipping"},{"kind":"lesson","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"cqrs-mediatr-and-cross-cutting-concerns-placement","title":"CQRS, MediatR and cross-cutting concerns placement","body":"CQRS separates commands (change state, return little) from queries (return data, no side effects). In a single app it usually means separate handler classes and models; reads can use Dapper/views while writes use EF Core and rich domain models. csharp public sealed record GetOrdersQuery(int CustomerId, int Page) : IRequest<PagedList<OrderDto ; public sealed class GetOrdersHandler(IDbConnectionFactory db) : IRequestHandler<GetOrdersQuery, PagedList<OrderDto { public async Task<PagedList<OrderDto Handle(GetOrdersQuery q, CancellationToken ct) { / Dapper query on a view / return default!; } } // Controller: return Ok(await mediator.Send(new GetOrdersQuery(id, page))); MediatR (commercial licence from v13, 2025) or similar mediators add pipeline behaviours for validation, logging, transactions. You can also call handlers directly via DI — the pattern doesn't require a library. Where do cross-cutting concerns go? Concern Place --- --- Exception handling Api: UseExceptionHandler + IExceptionHandler Validation Application: FluentValidation + pipeline behaviour; Domain: invariants in constructors/methods Logging Everywhere via ILogger<T ; request logging middleware in Api Authentication/authorization Api (middleware, policies); resource checks in Application Transactions Application (unit of work around a command) Caching Application (decorator/behaviour) or Infrastructure Configuration Api/Infrastructure (Options pattern), injected as interfaces/options Mapping Application (manual mapping, Mapster, or AutoMapper)"},{"kind":"lesson","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"folder-structures-for-each-app-type-at-a-glance","title":"Folder structures for each app type at a glance","body":"Small ASP.NET Core Web API (single project, feature-friendly): text Shop.Api/ ├── Features/ or Controllers/ endpoints grouped by feature ├── Domain/ entities, enums, value objects ├── Data/ ShopDbContext, Configurations/, Migrations/ ├── Services/ business services + interfaces ├── Contracts/ (Dtos/) request/response models ├── Infrastructure/ email, storage, external API clients ├── Middleware/ · Filters/ · Extensions/ ├── Program.cs · appsettings .json ASP.NET Core MVC app (layered): Shop.Web (Controllers, Views, ViewComponents, wwwroot) + Shop.Application + Shop.Domain + Shop.Infrastructure (same layers as Clean Architecture, but the Web project has views). Blazor Web App (.NET 8+): Shop (server project: Components/ with App.razor , Routes.razor , Layout/ , Pages/ , Program.cs ) + Shop.Client (WebAssembly project for interactive components) + shared libraries. Worker / background processing: Shop.Worker ( Worker.cs BackgroundService classes, Program.cs with Host.CreateApplicationBuilder ) reusing Application/Infrastructure projects. .NET Framework legacy (Web Forms / MVC 5): Shop.Web (pages/controllers, App Start, Global.asax, Web.config) + Shop.BLL + Shop.DAL + Shop.Entities + Shop.Common . Full stack monorepo: text repo/ ├── src/ Shop.Api · Shop.Application · Shop.Domain · Shop.Infrastructure · Shop.Worker · Shop.AppHost (Aspire) ├── web/ shop-ui/ (Angular: src/app/core, shared, features/orders, ... React: src/components, pages, hooks, services, store) ├── tests/ · deploy/ · docs/ · .github/workflows/ Rule of thumb: group by feature at the top level when the app grows ; keep technical sub-folders inside a feature only if they help."},{"kind":"lesson","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"choosing-an-architecture","title":"Choosing an architecture","body":"Situation Recommendation --- --- Small CRUD app, short life, 1–2 developers Single project with folders (Controllers, Services, Data) — keep it simple Business-heavy app, long life, several developers Clean/Onion architecture or Vertical Slice + rich domain where needed API with many independent features Vertical Slice (+ CQRS) Growing product, several teams Modular monolith Very large org, independent scaling/deployments Microservices (each service internally clean/vertical) Legacy Web Forms/MVC 5 Extract BLL/DAL into libraries first, then migrate UI Write the decision in an ADR (Architecture Decision Record): context, decision, consequences. Enforce it with architecture tests so it doesn't erode."},{"kind":"question","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"471","title":"Explain 3-tier (N-layer) architecture.","body":"Presentation (UI), business logic (services/BLL) and data access (DAL/repositories), each calling only the layer below. It separates concerns and lets teams work on layers independently. Layers are logical; tiers are physical machines. Weakness: business logic often depends directly on data access, making it hard to test and change."},{"kind":"question","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"472","title":"What is Clean Architecture? What is the dependency rule?","body":"An architecture that places the domain (entities, business rules) and application use cases at the centre and frameworks, UI and databases at the outside. The dependency rule: source-code dependencies only point inward — the domain depends on nothing; the application defines interfaces that infrastructure implements; the web project is the composition root that wires everything with DI."},{"kind":"question","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"473","title":"How do you structure a typical ASP.NET Core Web API solution?","body":"src/ with Domain (entities, value objects), Application (use cases, DTOs, interfaces, validation), Infrastructure (EF Core DbContext, migrations, external services) and Api (controllers/endpoints, middleware, Program.cs) projects; tests/ with unit, integration and functional test projects; shared settings in Directory.Build.props, central package versions, global.json, .editorconfig; Dockerfile and pipelines alongside."},{"kind":"question","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"474","title":"Onion vs Clean vs Hexagonal architecture?","body":"Same core idea with different vocabulary: business logic at the centre, independent of infrastructure, connected through interfaces. Hexagonal talks about ports (interfaces) and adapters (implementations/drivers); Onion about concentric rings (domain model, domain services, application services, infrastructure/UI); Clean about entities, use cases, interface adapters and frameworks with the explicit dependency rule. In .NET they produce similar project structures."},{"kind":"question","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"475","title":"Vertical Slice vs layered architecture?","body":"Layered organises by technical concern (controllers, services, repositories) so one feature spans many folders and projects. Vertical Slice organises by feature/use case — request, validation, handler, endpoint together — so changes are local and each slice can choose its data access. Slices can still share a domain model. Vertical slices suit CQRS-style APIs with many independent use cases."},{"kind":"question","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"476","title":"Where do you put the repository interfaces and why?","body":"In the Application (or Domain) layer — the inner layer defines what it needs ( IOrderRepository ), and Infrastructure implements it. This is Dependency Inversion: the business logic doesn't depend on EF Core or SQL, can be unit-tested with fakes, and the implementation can change without touching use cases."},{"kind":"question","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"477","title":"What is a modular monolith?","body":"A single deployable application split into well-defined modules by business capability, each with its own code, data (separate schema) and public API; modules interact only through contracts or events. You get microservice-like boundaries without distributed-system complexity, and modules can be extracted into services later if needed."},{"kind":"question","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"478","title":"Layer vs tier?","body":"A layer is a logical grouping of code by responsibility (UI, business, data). A tier is a physical deployment boundary (client device, web server, application server, database server). You can deploy several layers on one tier; crossing tiers adds network calls, latency and failure modes."},{"kind":"question","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"479","title":"What is CQRS? Do you need MediatR for it?","body":"Command Query Responsibility Segregation: separate models/handlers for writes (commands that change state) and reads (queries that return data). It allows optimised read models (Dapper, views, caches) and rich write models. MediatR is just one way to dispatch requests to handlers with pipeline behaviours; you can implement CQRS with plain interfaces and DI."},{"kind":"question","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"480","title":"How do you prevent architecture erosion over time?","body":"Make rules explicit (ADRs, diagrams), enforce dependencies with project references (inner projects simply can't reference outer ones) and architecture tests (NetArchTest/ArchUnitNET in CI), code reviews with a checklist, templates for new features, internal visibility ( internal + InternalsVisibleTo ) to hide implementation details, and regular refactoring."},{"kind":"question","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"481","title":"What are aggregates and why do they matter for structure?","body":"An aggregate is a cluster of domain objects treated as one unit for changes, with a root entity that enforces invariants (Order with OrderLines). Outside code references only the root and changes go through its methods; one transaction modifies one aggregate. This defines repository boundaries (one repository per aggregate root) and keeps business rules in one place."},{"kind":"question","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"482","title":"What is the composition root?","body":"The single place where the application's object graph is wired together — in ASP.NET Core, Program.cs (often via AddApplication() / AddInfrastructure() extension methods) registers interfaces with their implementations in the DI container. Only the composition root knows about all projects; inner layers depend only on abstractions."},{"kind":"question","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"483","title":"You join a project where controllers contain SQL, business rules and email sending. How do you restructure it safely?","body":"Add characterization tests around key endpoints first. Extract business logic into application services/handlers with interfaces for data access and email; move SQL into repositories or query classes in an infrastructure project; introduce DI registration; keep controllers thin (bind, call, return). Do it feature by feature (strangler within the codebase), not as a big-bang rewrite, and agree on the target structure in an ADR."},{"kind":"question","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"484","title":"A small internal tool (5 screens) is being built with 8 projects in Clean Architecture. Is that right?","body":"Probably over-engineered: more projects, mapping and indirection than the problem needs, slowing the team. A single project with clear folders (Features or Controllers/Services/Data) and good tests is enough; keep the door open by keeping logic out of controllers. Choose architecture by complexity and expected lifetime, not by habit."},{"kind":"question","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"485","title":"How would you organise a solution with an ASP.NET Core API, an Angular front end and background workers?","body":"Monorepo: src/Shop.Api , src/Shop.Worker (BackgroundService/queue consumers), shared Shop.Application / Shop.Domain / Shop.Infrastructure projects used by both, web/shop-ui (Angular workspace), tests/ for each, deploy/ with Dockerfiles per deployable, CI pipelines that build only what changed. Or with .NET Aspire, an AppHost project orchestrating API, worker, database and the front end locally."},{"kind":"cheat","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"1","title":"Styles","body":"3-tier/N-layer (UI → BLL → DAL) · Onion/Clean/Hexagonal (domain centre, dependencies inward) · Vertical Slice (per feature) · Modular monolith (modules + schemas) · Microservices."},{"kind":"cheat","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"2","title":"Clean Architecture projects","body":"Domain (entities, value objects, events) ← Application (use cases, interfaces, DTOs, validation) ← Infrastructure (EF, email, files) ; Api = composition root (controllers, middleware, Program.cs)."},{"kind":"cheat","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"3","title":"Repo layout","body":"src/ · tests/ · docs/ (ADRs) · deploy/ · Directory.Build.props · Directory.Packages.props · global.json · .editorconfig · .sln / .slnx ."},{"kind":"cheat","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"4","title":"Placement of concerns","body":"Exceptions & auth → Api · validation & transactions & mapping → Application · invariants → Domain · persistence & external services → Infrastructure · logging → everywhere via ILogger."},{"kind":"cheat","course_slug":"project-architecture","course_title":".NET Project Architectures & Folder Structures — Layered, Clean, Onion, Vertical Slice","ref":"5","title":"Choosing","body":"Small CRUD → simple single project · rich domain → Clean · many independent features → Vertical Slice · many teams → modular monolith · independent scaling/deploys → microservices · write an ADR, enforce with architecture tests."},{"kind":"course","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"","title":"Clean Code, Testing & Best Practices","body":"Naming, functions, error handling, code smells and refactoring, unit testing with xUnit and Moq, TDD, code review, Git workflow, security and logging best practices for .NET teams. Clean code is code that other people can read, change and trust. Interviews for mid and senior roles check whether you write maintainable code, test it, review others' code and follow team practices (Git flow, CI, logging, security). Core ideas, from Robert C. Martin's Clean Code (2008), Martin Fowler's Refactoring (1999, 2nd ed. 2018) and Kent Beck's Test-Driven Development (2002): - Code is read far more often than it is written — optimise for the reader. - Small, focused functions and classes with intention-revealing names. - Tests are part of the code, not an afterthought. - Leave the code cleaner than you found it (the \"Boy Scout rule\"). Year Milestone --- --- 1999 Fowler, Refactoring (code smells catalogue); Beck, Extreme Programming Explained 2002 Beck, Test-Driven Development: By Example 2004 Feathers, Working Effectively with Legacy Code 2007 xUnit.net 1.0 released (by NUnit's original author) 2008 Martin, Clean Code 2011 Martin, The Clean Coder 2018 Refactoring 2nd edition 2024 xUnit v3 released; MSTest 3.x, NUnit 4 are current .NET analyzers: Roslyn analyzers ship in the SDK ( <AnalysisLevel latest</AnalysisLevel ), plus .editorconfig rules enforced at build. Code lifecycle in a team (typical Git + PR flow): 1. Pick a ticket (Azure Boards/Jira) → create a branch feature/1234-order-export . 2. Write a failing test (TDD) or write the code, then the tests. 3. Run the analyzers, formatter ( dotnet format ) and tests locally. 4. Commit small, meaningful commits; push; open a pull request . 5. CI pipeline: build → unit tests → code coverage → static analysis (SonarQube) → security scan. 6. Code review by 1–2 peers; address comments. 7. Merge (squash) to main ; CD deploys to dev → QA → staging → production. 8. Monitor logs and metrics; fix bugs with a regression test first. Test lifecycle (xUnit): for each test, a new instance of the test class is created (constructor = setup), the test runs, then Dispose() = teardown. Shared expensive setup uses IClassFixture<T (per class) or collection fixtures (across classes). Area Tools --- --- Unit testing xUnit, NUnit, MSTest Mocking Moq, NSubstitute, FakeItEasy Assertions Shouldly, FluentAssertions (v8+ needs a commercial licence) Integration tests WebApplicationFactory (Microsoft.AspNetCore.Mvc.Testing), Testcontainers, Respawn Coverage Coverlet, ReportGenerator, Visual Studio Enterprise Static analysis Roslyn analyzers, SonarQube/SonarCloud, ReSharper, StyleCop.Analyzers Formatting dotnet format , .editorconfig , CSharpier Mutation testing Stryker.NET Architecture tests NetArchTest, ArchUnitNET Security Dependabot, dotnet list package --vulnerable , GitHub Advanced Security, OWASP ZAP"},{"kind":"lesson","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"naming","title":"Naming","body":"- Names reveal intent: daysSinceLastLogin , not d or data2 . - Classes = nouns ( InvoiceCalculator ); methods = verbs ( CalculateTotal , SendReminder ). - Booleans read as questions: isActive , hasAccess , canRetry . - Avoid noise words: Manager , Processor , Data , Info (unless they really mean something). - .NET conventions: PascalCase for types, methods, properties, constants; camelCase for locals and parameters; camelCase for private fields; I prefix for interfaces; Async suffix for async methods. csharp // ❌ public List<int Get(List<int l) { var r = new List<int (); foreach (var x in l) if (x % 2 == 0) r.Add(x); return r; } // ✅ public IReadOnlyList<int GetEvenNumbers(IEnumerable<int numbers) = numbers.Where(n = n % 2 == 0).ToList();"},{"kind":"lesson","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"functions-parameters-and-guard-clauses","title":"Functions, parameters and guard clauses","body":"- Small; do one thing ; one level of abstraction. - Few parameters (≤ 3); group many into a parameter object/record. - No hidden side effects; avoid boolean \"flag\" parameters that switch behaviour. - Return early with guard clauses instead of deep nesting. csharp // ❌ Arrow code public decimal Ship(Order o) { if (o != null) { if (o.IsPaid) { if (o.Lines.Count 0) { return Calculate(o); } else throw ...; } else throw ...; } else throw ...; } // ✅ Guard clauses public decimal Ship(Order? o) { ArgumentNullException.ThrowIfNull(o); if (!o.IsPaid) throw new InvalidOperationException(\"Order not paid\"); if (o.Lines.Count == 0) throw new InvalidOperationException(\"Order is empty\"); return Calculate(o); }"},{"kind":"lesson","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"comments-formatting-and-magic-numbers","title":"Comments, formatting and magic numbers","body":"- Good code explains what ; comments explain why (business reason, workaround, link to ticket). - Delete commented-out code — Git remembers it. - Replace magic numbers/strings with named constants or enums: if (age = LegalDrivingAge) . - XML doc comments ( /// ) for public APIs. - Enforce formatting with .editorconfig + dotnet format in CI so reviews don't argue about spaces."},{"kind":"lesson","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"error-handling-and-logging-best-practices","title":"Error handling and logging best practices","body":"- Throw exceptions for exceptional situations; use TryX or a Result type for expected failures (validation, not found). - Catch only what you can handle; let the rest bubble to a global exception handler (ASP.NET Core UseExceptionHandler + IExceptionHandler / ProblemDetails). - Never swallow exceptions ( catch { } ). - Structured logging with message templates, not string interpolation: csharp // ❌ logger.LogInformation($\"Order {orderId} placed by {userId}\"); // allocates always; loses structure // ✅ logger.LogInformation(\"Order {OrderId} placed by {UserId}\", orderId, userId); // High-performance, source-generated: public static partial class Log { [LoggerMessage(Level = LogLevel.Warning, Message = \"Payment {PaymentId} failed: {Reason}\")] public static partial void PaymentFailed(ILogger logger, string paymentId, string reason); } - Never log secrets, passwords, tokens or full card numbers; mask PII. - Use correlation IDs / OpenTelemetry trace IDs to follow a request across services."},{"kind":"lesson","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"common-code-smells","title":"Common code smells","body":"Smell Symptom Refactoring --- --- --- Long method ~30 lines, many comments explaining blocks Extract Method Large class / God class Many responsibilities, 1000+ lines Extract Class (SRP) Long parameter list 5+ params Introduce Parameter Object Duplicated code Same logic in many places Extract Method/Class, DRY Switch on type switch (type) repeated Replace Conditional with Polymorphism (Strategy) Feature envy Method uses another class's data more than its own Move Method Primitive obsession string email , decimal amount + string currency everywhere Value objects ( Email , Money ) Shotgun surgery One change edits many files Move related code together Dead code Unused methods/params Delete Magic numbers if (status == 3) Enum/constant"},{"kind":"lesson","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"safe-refactoring-and-legacy-code","title":"Safe refactoring and legacy code","body":"1. Cover with tests first — characterisation tests that pin current behaviour (even if odd). 2. Make small steps , run tests after each. 3. Use IDE refactorings (Rename, Extract Method, Introduce Variable) — they're safe. 4. Separate refactoring commits from behaviour changes. 5. For untestable legacy code: find seams (Feathers) — extract an interface around a static/DB call, inject it, then test. 6. Strangler Fig for big rewrites: route new features to new code, migrate piece by piece."},{"kind":"lesson","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"unit-testing-with-xunit-aaa-pattern","title":"Unit testing with xUnit (AAA pattern)","body":"csharp public class DiscountCalculatorTests { private readonly DiscountCalculator sut = new(); // system under test [Fact] public void Gold customer gets 10 percent() { // Arrange var order = new Order(total: 1000m, tier: Tier.Gold); // Act var discount = sut.Calculate(order); // Assert Assert.Equal(100m, discount); } [Theory] [InlineData(Tier.Regular, 1000, 0)] [InlineData(Tier.Gold, 1000, 100)] [InlineData(Tier.Platinum, 1000, 150)] public void Discount by tier(Tier tier, decimal total, decimal expected) = Assert.Equal(expected, sut.Calculate(new Order(total, tier))); [Fact] public void Negative total throws() = Assert.Throws<ArgumentOutOfRangeException (() = sut.Calculate(new Order(-1, Tier.Gold))); } Good unit tests are FIRST : Fast, Isolated, Repeatable, Self-validating, Timely. Name them by behaviour: Method State ExpectedResult or a readable sentence."},{"kind":"lesson","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"mocking-with-moq-nsubstitute","title":"Mocking with Moq / NSubstitute","body":"csharp [Fact] public async Task PlaceOrder saves and sends confirmation() { var repo = new Mock<IOrderRepository (); var email = new Mock<IEmailSender (); var sut = new OrderService(repo.Object, email.Object); await sut.PlaceAsync(new Order(1, 500m)); repo.Verify(r = r.AddAsync(It.Is<Order (o = o.Id == 1)), Times.Once); email.Verify(e = e.SendAsync(It.IsAny<string (), It.IsAny<string ()), Times.Once); } // NSubstitute equivalent var repo2 = Substitute.For<IOrderRepository (); await repo2.Received(1).AddAsync(Arg.Is<Order (o = o.Id == 1)); Test doubles: Dummy (unused), Stub (returns canned data), Fake (working lightweight version, e.g. in-memory repo), Mock (verifies interactions), Spy (records calls). Don't mock what you don't own (e.g. HttpClient ) — wrap it or use a fake HttpMessageHandler ."},{"kind":"lesson","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"test-pyramid-integration-tests-and-tdd","title":"Test pyramid, integration tests and TDD","body":"Test pyramid: many fast unit tests → fewer integration tests (API + real DB) → few end-to-end/UI tests (Playwright/Selenium). csharp // Integration test with WebApplicationFactory public class OrdersApiTests(WebApplicationFactory<Program factory) : IClassFixture<WebApplicationFactory<Program { [Fact] public async Task Get unknown order returns 404() { var client = factory.CreateClient(); var res = await client.GetAsync(\"/api/orders/999999\"); Assert.Equal(HttpStatusCode.NotFound, res.StatusCode); } } TDD cycle — Red, Green, Refactor: write a failing test → write the minimum code to pass → clean up. Benefits: testable design, a safety net, living documentation. Code coverage: a useful signal, not a goal. 80% coverage of meaningful branches beats 100% of trivial getters. Mutation testing (Stryker) checks whether tests actually catch bugs."},{"kind":"lesson","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"git-workflow-and-pull-requests","title":"Git workflow and pull requests","body":"bash git switch -c feature/1234-export-csv git add -p stage hunks deliberately git commit -m \"Add CSV exporter for monthly report ( 1234)\" git fetch origin && git rebase origin/main git push -u origin feature/1234-export-csv open PR → CI runs → review → squash merge - Branching models: trunk-based (short-lived branches, feature flags — common with CI/CD) vs GitFlow (develop/release/hotfix branches — heavier). - merge keeps history with a merge commit; rebase rewrites your commits on top of the target for a linear history (never rebase shared branches). - Good PRs: small (< ~400 lines), one purpose, description with why + how to test, screenshots for UI. - Resolve conflicts locally, re-run tests."},{"kind":"lesson","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"code-review-checklist","title":"Code review checklist","body":"1. Correctness — does it do what the ticket says? Edge cases (null, empty, large, concurrent)? 2. Tests — new behaviour covered? Bug fix has a regression test? 3. Design — SOLID, no duplication, right layer, no unnecessary abstraction. 4. Readability — names, function size, comments explain why. 5. Performance — N+1 queries, loading whole tables, blocking async, missing indexes. 6. Security — input validation, parameterised SQL, authorisation checks, no secrets in code, safe logging. 7. Operability — logging, metrics, config, migrations, backward compatibility. Tone: comment on the code, not the person; ask questions (\"What happens if X is null?\"); mark nits as optional; approve when good enough."},{"kind":"lesson","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"secure-coding-basics-owasp-top-10-for-dotnet-devs","title":"Secure coding basics (OWASP Top 10 for .NET devs)","body":"Risk .NET practice --- --- Injection (SQL, command) Parameterised queries / EF Core / Dapper parameters; never concatenate input Broken access control [Authorize] + policies; check ownership ( order.UserId == currentUser ) — prevent IDOR Cryptographic failures HTTPS everywhere, HSTS; hash passwords with ASP.NET Core Identity (PBKDF2); never roll your own crypto Security misconfiguration No detailed errors in production; remove default accounts; least privilege Vulnerable components Keep NuGet packages updated; Dependabot; dotnet list package --vulnerable XSS Razor encodes by default; avoid Html.Raw with user input; CSP header CSRF Antiforgery tokens for cookie-auth forms ( [ValidateAntiForgeryToken] ) Secrets User Secrets locally; Azure Key Vault / env vars in prod; never commit appsettings.Production.json secrets Logging failures Log security events; never log secrets SSRF Validate/allow-list outbound URLs"},{"kind":"question","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"486","title":"What is clean code? What practices do you follow?","body":"Code that is easy to read, change and test. My practices: meaningful names, small single-purpose methods, guard clauses instead of deep nesting, no magic numbers, consistent formatting enforced by .editorconfig / dotnet format , comments for why , unit tests for business logic, small PRs and code review, and the Boy Scout rule — leave code slightly better each time."},{"kind":"question","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"487","title":"What is unit testing? What makes a good unit test?","body":"A unit test verifies a small piece of logic (a method/class) in isolation from external dependencies (DB, network, time), which are replaced with test doubles. Good tests are FIRST (Fast, Isolated, Repeatable, Self-validating, Timely), follow Arrange-Act-Assert, test behaviour not implementation details, have one logical assertion focus, and have descriptive names."},{"kind":"question","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"488","title":"What is the difference between `[Fact]` and `[Theory]` in xUnit?","body":"[Fact] is a test with no parameters that always runs once. [Theory] is a parameterised test that runs once per data set, supplied by [InlineData] , [MemberData] or [ClassData] . Use theories to test the same rule with many inputs (boundary values)."},{"kind":"question","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"489","title":"What are xUnit, NUnit and MSTest? Differences?","body":"All three are .NET test frameworks. xUnit (most common in new .NET Core projects): new class instance per test, constructor/ IDisposable for setup/teardown, [Fact]/[Theory] , fixtures for shared state. NUnit : [Test] , [TestCase] , [SetUp]/[TearDown] , rich constraint assertions. MSTest : Microsoft's, [TestMethod] , [DataRow] , [TestInitialize] , well integrated into Visual Studio. Functionally similar; teams pick by convention."},{"kind":"question","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"490","title":"What is mocking? Mock vs stub vs fake?","body":"Mocking replaces a real dependency with a controllable test double. A stub returns predefined data (state-based testing). A mock also verifies that expected interactions happened ( Verify(..., Times.Once) ). A fake is a working lightweight implementation (in-memory repository, fake clock). Use stubs/fakes by default; verify interactions only when the interaction is the behaviour (e.g. \"an email was sent\")."},{"kind":"question","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"491","title":"How do you unit-test code that uses `DateTime.Now`, `HttpClient` or a database?","body":"- Time: inject TimeProvider (.NET 8 built-in abstraction; FakeTimeProvider in tests) or your own IClock . - HttpClient: inject a typed client and in tests provide a fake HttpMessageHandler returning canned responses — or wrap the external API behind an interface and mock that. - Database: hide it behind a repository interface for unit tests; for the data layer itself, write integration tests against a real engine (SQL Server in Testcontainers, or SQLite) rather than EF's InMemory provider, which doesn't behave like a relational DB."},{"kind":"question","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"492","title":"What is TDD? Have you used it?","body":"Test-Driven Development: Red (write a failing test for the next small behaviour), Green (write the minimum code to pass), Refactor (clean up with tests protecting you). It produces testable, decoupled designs and high meaningful coverage. Honest answer: \"I use TDD for business rules and bug fixes — I first write a test that reproduces the bug — and test-after for thin glue code.\""},{"kind":"question","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"493","title":"What is the test pyramid?","body":"Many fast, cheap unit tests at the base; fewer integration/API tests (real DB, real HTTP pipeline via WebApplicationFactory ) in the middle; very few slow, brittle end-to-end UI tests (Playwright) at the top. An inverted pyramid (\"ice-cream cone\") with mostly manual/UI tests is slow and flaky."},{"kind":"question","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"494","title":"What do you check in a code review?","body":"Correctness and edge cases, tests, design (SOLID, right layer), readability, performance (N+1 queries, sync-over-async, unbounded loads), security (injection, authorisation, secrets, logging PII), and operability (logging, config, migrations, backward compatibility). I keep comments respectful and specific, separate blocking issues from nits, and prefer small PRs."},{"kind":"question","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"495","title":"What are code smells? Name five and their fixes.","body":"Symptoms that suggest a deeper design problem: Long Method → Extract Method; God Class → Extract Class (SRP); Duplicate Code → extract shared method; Switch on type → polymorphism/Strategy; Primitive Obsession → value objects; Long Parameter List → parameter object; Feature Envy → Move Method."},{"kind":"question","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"496","title":"Merge vs rebase? What is a squash merge?","body":"merge combines branches and keeps both histories with a merge commit (non-destructive). rebase replays your commits on top of another branch, which rewrites them for a linear history — never on shared/public branches. Squash merge combines all PR commits into one commit on main , keeping history clean (one commit per feature)."},{"kind":"question","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"497","title":"Trunk-based development vs GitFlow?","body":"Trunk-based : everyone integrates into main at least daily via short-lived branches; incomplete features hidden behind feature flags; enables CI/CD. GitFlow : long-lived develop , release/ , hotfix/ branches; fits scheduled releases and multiple supported versions but causes merge pain. Most modern teams use trunk-based or GitHub Flow."},{"kind":"question","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"498","title":"What is mutation testing?","body":"A tool (Stryker.NET) makes small changes (\"mutants\") to your code — flipping to = , removing a call — and reruns the tests. If tests still pass, the mutant \"survived\", meaning your tests don't really check that behaviour. It measures test quality , unlike line coverage."},{"kind":"question","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"499","title":"How do you prevent SQL injection and IDOR in a .NET API?","body":"SQL injection: never concatenate user input into SQL; use EF Core LINQ, FromSql($\"...\") (interpolation is parameterised), Dapper parameters or SqlParameter . IDOR (Insecure Direct Object Reference): don't trust IDs from the URL — always check the resource belongs to the current user or tenant ( WHERE Id = @id AND UserId = @currentUser ), using resource-based authorisation or global query filters for multi-tenant data."},{"kind":"question","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"500","title":"You join a team with a 10-year-old codebase, no tests and frequent production bugs. What's your plan?","body":"1. Understand: talk to the team, read bug history, find the riskiest, most-changed areas (Git churn). 2. Add a CI pipeline with build + analyzers if missing. 3. Write characterisation/integration tests around the critical flows before touching them. 4. Fix bugs test-first (a regression test per bug). 5. Refactor incrementally in touched areas (Boy Scout rule), not a big-bang rewrite. 6. Add logging/monitoring to see failures early. 7. Agree on coding standards and PR reviews. 8. Measure: bug count, deployment frequency, time to fix."},{"kind":"question","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"501","title":"A reviewer rejects your PR saying the method is too long and untestable. How do you respond and fix it?","body":"Accept feedback professionally — ask for specifics if unclear. Then extract cohesive parts into well-named private methods or separate classes, move external calls (DB, HTTP, time) behind injected interfaces so the logic is testable, add unit tests for the extracted logic, and keep the PR focused. Reply to each comment with what you changed."},{"kind":"question","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"502","title":"A test passes locally but fails randomly in CI. What could cause it?","body":"Flaky test causes: dependence on time/date or time zone, test order or shared static state, parallel tests sharing a DB/file, race conditions with async code (missing await ), relying on dictionary/hash ordering, network calls to real services, culture-specific formatting. Fix by isolating state (fresh DB per test or transactions/Respawn), injecting TimeProvider , awaiting properly, fixing culture, and removing external calls."},{"kind":"question","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"503","title":"Production logs show `Object reference not set to an instance of an object` with no context. How do you make this debuggable next time?","body":"Enable nullable reference types and fix warnings; validate inputs with guard clauses ( ArgumentNullException.ThrowIfNull ); use structured logging with context (OrderId, UserId, CorrelationId); a global exception handler that logs the full exception with request path and trace ID; OpenTelemetry/Application Insights for distributed traces; publish symbols (portable PDBs) so stack traces have line numbers."},{"kind":"cheat","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"1","title":"Clean code rules","body":"- Intention-revealing names; verbs for methods, nouns for classes. - Functions: small, one thing, ≤ 3 params, guard clauses. - No magic numbers; no commented-out code; comments explain why . - Exceptions for exceptional cases; global handler; structured logs. - Boy Scout rule; small PRs; consistent formatting."},{"kind":"cheat","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"2","title":"Naming conventions (.NET)","body":"Element Style Example --- --- --- Class, method, property PascalCase OrderService.PlaceOrder Interface I + PascalCase IOrderRepository Local, parameter camelCase orderTotal Private field camelCase repository Async method Async suffix GetOrderAsync Constant PascalCase MaxRetryCount"},{"kind":"cheat","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"3","title":"Testing","body":"- AAA: Arrange · Act · Assert. FIRST tests. - xUnit: [Fact] , [Theory] + [InlineData] ; ctor = setup, Dispose = teardown; IClassFixture<T . - Moq: new Mock<T () , .Setup(...).ReturnsAsync(...) , .Verify(..., Times.Once) . - Doubles: dummy, stub, fake, mock, spy. - Pyramid: unit ≫ integration ≫ E2E. - WebApplicationFactory<Program for API tests; Testcontainers for real SQL Server. - TimeProvider / FakeTimeProvider for time."},{"kind":"cheat","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"4","title":"Code smells → refactorings","body":"Long method → Extract Method · God class → Extract Class · Switch on type → Polymorphism · Duplicates → Extract/DRY · Long params → Parameter Object · Primitive obsession → Value Object · Feature envy → Move Method."},{"kind":"cheat","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"5","title":"Git","body":"bash git switch -c feature/x git add -p && git commit -m \"Why + what\" git fetch && git rebase origin/main git push -u origin feature/x git stash / git stash pop git cherry-pick <sha git revert <sha safe undo on shared branch git reset --soft HEAD~1 undo last local commit, keep changes"},{"kind":"cheat","course_slug":"clean-code","course_title":"Clean Code, Testing & Best Practices","ref":"6","title":"Security quick list","body":"Parameterised SQL · [Authorize] + ownership checks · HTTPS/HSTS · Identity password hashing · Antiforgery · Razor encoding · Key Vault for secrets · updated packages · no secrets/PII in logs."},{"kind":"course","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"","title":"Microservices & System Design with .NET","body":"Monolith vs modular monolith vs microservices, service boundaries (DDD), REST/gRPC and messaging, API gateways, data per service, sagas and the outbox pattern, resilience, observability, caching, scaling and the system-design interview round. Microservices is an architectural style where an application is built as a set of small, independently deployable services, each owning one business capability and its own data, communicating over the network (HTTP/gRPC or messages). Style What it is Good for --- --- --- Monolith One deployable unit, one database Small teams, early products — simple to build, test and deploy Modular monolith One deployable, but strict internal modules (own schema, public interfaces) Most business apps; easy to split later Microservices Many deployables, each with its own data and pipeline Large organisations, parts with very different scaling/release needs System design is the interview round where you design a whole system (requirements → APIs → data → components → scaling → trade-offs). Microservice concepts (queues, caches, gateways, consistency) are the vocabulary of that round. In .NET the common toolset is: ASP.NET Core (REST/minimal APIs), gRPC, YARP (reverse proxy / gateway), MassTransit or NServiceBus over RabbitMQ / Azure Service Bus, Polly / Microsoft.Extensions.Http.Resilience , OpenTelemetry, Docker, Kubernetes/AKS or Azure Container Apps, and .NET Aspire for local orchestration and observability. Year Milestone --- --- 2011–2014 \"Microservices\" term popularised (James Lewis, Martin Fowler — article 2014) 2015–2017 Netflix OSS, Docker and Kubernetes make the style mainstream 2017 Microsoft eShopOnContainers reference app and the \".NET Microservices: Architecture for Containerized .NET Applications\" guide 2019 gRPC support in ASP.NET Core 3.0 2021 YARP 1.0 reverse proxy 2023 .NET 8: Microsoft.Extensions.Http.Resilience (built on Polly v8); .NET Aspire preview 2024 .NET Aspire 8.0 GA (May 2024) — orchestration, service discovery, OpenTelemetry dashboard 2025 .NET 10 and Aspire 9.x/13 — Aspire grows into a general app-host for distributed apps Industry trend to mention: many teams moved back to modular monoliths after over-splitting (e.g. the Amazon Prime Video monitoring case study, 2023). Interviewers like candidates who choose microservices for a reason, not by default. Life of a request in a microservice system: 1. Client → API gateway (YARP / Azure API Management): TLS, auth token validation, routing, rate limiting. 2. Gateway → service A over HTTP/gRPC (service discovery finds an instance). 3. Service A reads/writes its own database . 4. Service A publishes an event (OrderPlaced) via the outbox to a message broker . 5. Services B and C consume the event asynchronously and update their own data. 6. Every hop carries a trace id (W3C traceparent ) so one distributed trace shows the whole flow. Life of a service: identify boundary (bounded context) → define contract (API/events) → build + tests → container image → CI/CD → deploy (rolling/blue-green/canary) → monitor (logs, metrics, traces, alerts) → evolve contract with versioning. - Communication: ASP.NET Core Web API / minimal APIs, gRPC, SignalR, YARP, Azure API Management, Ocelot (older). - Messaging: RabbitMQ, Azure Service Bus, Kafka / Azure Event Hubs, MassTransit, NServiceBus, Wolverine. - Resilience: Polly, Microsoft.Extensions.Http.Resilience (retry, circuit breaker, timeout, hedging). - Observability: OpenTelemetry, .NET Aspire dashboard, Application Insights, Prometheus + Grafana, Jaeger/Zipkin, Seq. - Hosting: Docker, Kubernetes / AKS, Azure Container Apps, Dapr (sidecar building blocks). - Data & cache: SQL Server / Azure SQL, Cosmos DB, PostgreSQL, Redis. - Design: C4 model diagrams, Event Storming for DDD boundaries."},{"kind":"lesson","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"monolith-modular-monolith-and-microservices","title":"Monolith, modular monolith and microservices","body":"Monolith — all features in one process and one database. - ✅ Simple development, debugging, transactions, deployment. - ❌ Grows into a \"big ball of mud\"; one bug or slow module affects all; the whole app scales together. Modular monolith — one deployable, but modules are isolated: text Shop.Api (one process) ├── Modules/Orders (orders schema, IOrdersModule public API) ├── Modules/Catalog (catalog schema) └── Modules/Billing (billing schema) Rule: modules talk only through public interfaces or in-process events — never each other's tables. Microservices — each module becomes its own service with its own database and pipeline. Monolith Microservices --- --- --- Deployment All or nothing Per service Scaling Whole app Per service Data consistency ACID transactions Eventual consistency, sagas Failure Process crash = outage Partial failures, need resilience Team fit One team Many teams, one service each Operations cost Low High (CI/CD, monitoring, networking) Interview tip: \"I would start with a modular monolith and extract a service when a module needs independent scaling, release cadence or ownership.\" This is the answer most senior interviewers want."},{"kind":"lesson","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"finding-service-boundaries-with-domain-driven-design","title":"Finding service boundaries with Domain-Driven Design","body":"Split by business capability , not by technical layer (never \"a database service\" + \"a UI service\"). DDD vocabulary interviewers use: Term Meaning Example --- --- --- Bounded context A boundary in which a model and its language are consistent \"Customer\" means different things in Sales and Support Ubiquitous language Shared terms between developers and business Order, Shipment, Invoice Aggregate Cluster of objects changed together with one root enforcing rules Order (root) + OrderLines Domain event Something that happened in the domain OrderPlaced , PaymentFailed Anti-corruption layer Translator protecting your model from another system's model Adapter over a legacy ERP csharp public class Order // aggregate root: all changes go through it so rules are always enforced { private readonly List<OrderLine lines = []; public IReadOnlyList<OrderLine Lines = lines; public OrderStatus Status { get; private set; } = OrderStatus.Draft; public void AddLine(int productId, int qty, decimal price) { if (Status != OrderStatus.Draft) throw new InvalidOperationException(\"Order already submitted\"); if (qty <= 0) throw new ArgumentOutOfRangeException(nameof(qty)); lines.Add(new OrderLine(productId, qty, price)); } } Good boundary signals: high cohesion inside, few calls across, data owned by one place, a team can own it end to end."},{"kind":"lesson","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"synchronous-communication-rest-grpc-and-the-api-gateway","title":"Synchronous communication — REST, gRPC and the API gateway","body":"REST (HTTP + JSON) gRPC (HTTP/2 + Protobuf) --- --- --- Contract OpenAPI (optional) .proto file (required, code-generated) Payload Text JSON — readable, larger Binary — small and fast Streaming Limited (SSE, WebSockets) Client, server and bidirectional streaming Browser support Native Needs gRPC-Web Best for Public APIs, browser clients Internal service-to-service calls csharp // Typed HttpClient with built-in resilience (.NET 8+) builder.Services.AddHttpClient<CatalogClient (c = c.BaseAddress = new Uri(\"https+http://catalog\")) .AddStandardResilienceHandler(); // retry, circuit breaker, timeouts API gateway — single entry point for clients: routing, TLS termination, authentication, rate limiting, request aggregation, caching. In .NET: YARP ; in Azure: API Management or Application Gateway. Backend-for-Frontend (BFF) : a gateway per client type (web, mobile) shaped for that client. json // YARP appsettings.json \"ReverseProxy\": { \"Routes\": { \"orders\": { \"ClusterId\": \"orders\", \"Match\": { \"Path\": \"/api/orders/{ rest}\" } } }, \"Clusters\": { \"orders\": { \"Destinations\": { \"d1\": { \"Address\": \"http://orders-api:8080/\" } } } } } Danger: long synchronous call chains (A → B → C → D) multiply latency and failure probability. Prefer async messaging for anything that doesn't need an immediate answer."},{"kind":"lesson","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"asynchronous-communication-queues-topics-and-events","title":"Asynchronous communication — queues, topics and events","body":"Concept Meaning --- --- Queue (point-to-point) One message → one consumer (work distribution). Service Bus queue, RabbitMQ queue Topic / pub-sub One message → every subscriber gets a copy. Service Bus topics, RabbitMQ fanout exchange, Kafka Command vs event Command = \"do this\" (one handler). Event = \"this happened\" (zero or many listeners) At-least-once delivery A message can arrive twice → consumers must be idempotent Dead-letter queue Where messages go after repeated failures, for inspection and replay Event streaming Ordered, replayable log (Kafka, Event Hubs) — for analytics, IoT, event sourcing csharp // MassTransit consumer — idempotent by checking a processed-message table public class OrderPlacedConsumer(AppDb db) : IConsumer<OrderPlaced { public async Task Consume(ConsumeContext<OrderPlaced ctx) { if (await db.Processed.AnyAsync(p = p.MessageId == ctx.MessageId)) return; // already handled db.Invoices.Add(new Invoice(ctx.Message.OrderId, ctx.Message.Total)); db.Processed.Add(new ProcessedMessage(ctx.MessageId!.Value)); await db.SaveChangesAsync(); } } Benefits: temporal decoupling (consumer can be down), load levelling (queue absorbs peaks), easy to add new subscribers."},{"kind":"lesson","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"database-per-service-sagas-and-the-outbox-pattern","title":"Database per service, sagas and the outbox pattern","body":"Database per service: each service owns its data; others access it only via the service's API or events. This keeps services independently deployable — but you lose cross-service ACID transactions and joins. Saga — a long business transaction made of local transactions, each with a compensating action if a later step fails: text PlaceOrder: Orders: create (Pending) → Payment: charge → Inventory: reserve → Orders: confirm Failure at Inventory: Payment: refund (compensate) → Orders: cancel - Choreography — services react to each other's events (simple, but the flow is implicit). - Orchestration — a coordinator (MassTransit state machine, Durable Functions) tells each service what to do (explicit, easier to monitor). Transactional outbox — solves \"saved to DB but failed to publish the event\" (dual write): csharp await using var tx = await db.Database.BeginTransactionAsync(); db.Orders.Add(order); db.Outbox.Add(new OutboxMessage(\"OrderPlaced\", JsonSerializer.Serialize(new OrderPlaced(order.Id, order.Total)))); await db.SaveChangesAsync(); await tx.CommitAsync(); // A background worker reads unsent Outbox rows, publishes them, marks them sent (MassTransit/NServiceBus have this built in). Inbox / idempotent consumer — store processed message ids so duplicates are ignored. CAP theorem (short version): during a network partition a distributed system must choose Consistency or Availability. Most microservice systems choose availability + eventual consistency for cross-service data."},{"kind":"lesson","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"cqrs-and-event-sourcing","title":"CQRS and event sourcing","body":"CQRS (Command Query Responsibility Segregation): separate the write model (commands, validation, domain rules) from the read model (queries, denormalised views shaped for screens). text Command → Handler → Domain model → Write DB ──(events)── Projector → Read DB/view → Query handler → UI - Can be one database with separate code paths (most common) or separate stores. - Reads scale independently; read models can be rebuilt. Event sourcing: store the sequence of events ( OrderCreated , LineAdded , OrderShipped ) instead of only current state; current state = replay of events. Gives a full audit trail and time travel, but adds complexity (versioning events, snapshots, projections). Tools: Marten (PostgreSQL), EventStoreDB, Cosmos DB change feed. Interview tip: CQRS does not require event sourcing or MediatR. Say \"we used CQRS-lite: commands through EF Core, queries through Dapper on views\"."},{"kind":"lesson","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"resilience-retries-timeouts-circuit-breakers","title":"Resilience — retries, timeouts, circuit breakers","body":"In a distributed system something is always failing . Patterns: Pattern What it does --- --- Timeout Never wait forever for a dependency Retry with exponential backoff + jitter Recover from transient faults (network blips, 503) — only for idempotent operations Circuit breaker After repeated failures, fail fast for a while so the dependency can recover Bulkhead Limit concurrent calls so one slow dependency can't exhaust all threads/connections Fallback Return cached/default data when a dependency is down Hedging Send a second request if the first is slow, use the first answer csharp builder.Services.AddHttpClient<PaymentClient () .AddResilienceHandler(\"payments\", b = { b.AddTimeout(TimeSpan.FromSeconds(10)); b.AddRetry(new HttpRetryStrategyOptions { MaxRetryAttempts = 3, BackoffType = DelayBackoffType.Exponential, UseJitter = true }); b.AddCircuitBreaker(new HttpCircuitBreakerStrategyOptions { FailureRatio = 0.5, BreakDuration = TimeSpan.FromSeconds(30) }); }); Also: health checks ( AddHealthChecks() , /health/live and /health/ready for Kubernetes probes) and graceful degradation ."},{"kind":"lesson","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"observability-logs-metrics-and-distributed-traces","title":"Observability — logs, metrics and distributed traces","body":"Signal Answers .NET tooling --- --- --- Logs What happened in this service? ILogger , Serilog, structured logging Metrics How much/how fast/how many errors? System.Diagnostics.Metrics , Prometheus, Azure Monitor Traces Where did time go across services? ActivitySource , OpenTelemetry, Jaeger, App Insights csharp builder.Services.AddOpenTelemetry() .WithTracing(t = t.AddAspNetCoreInstrumentation().AddHttpClientInstrumentation().AddSqlClientInstrumentation().AddOtlpExporter()) .WithMetrics(m = m.AddAspNetCoreInstrumentation().AddRuntimeInstrumentation().AddOtlpExporter()); The trace id flows automatically through HttpClient and most message libraries (W3C Trace Context), so one request can be followed across every service. .NET Aspire wires OpenTelemetry, health checks, resilience and service discovery by default ( AddServiceDefaults() ) and shows everything in its dashboard. Golden signals to alert on: latency, traffic, errors, saturation ."},{"kind":"lesson","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"scaling-caching-and-the-system-design-round","title":"Scaling, caching and the system design round","body":"Scaling: - Vertical — bigger machine (simple, limited). Horizontal — more instances behind a load balancer; services must be stateless (session in Redis/cookies, files in Blob storage). - Database scaling — indexes first, then read replicas, caching, partitioning, and finally sharding. - Autoscaling — Kubernetes HPA / KEDA (scale on queue length), App Service autoscale, Container Apps scale rules. Caching strategies: Strategy How --- --- Cache-aside App reads cache → on miss reads DB and fills cache (most common) Write-through Write to cache and DB together Expiry + invalidation TTL, plus delete keys on update; beware stale data and stampedes Where Browser/CDN → API output cache → distributed cache (Redis) → DB buffer pool csharp // .NET 9+ HybridCache: in-memory + distributed, with stampede protection var product = await cache.GetOrCreateAsync($\"product:{id}\", async ct = await db.Products.FindAsync([id], ct), new HybridCacheEntryOptions { Expiration = TimeSpan.FromMinutes(10) }); System design answer template: requirements (functional + non-functional) → estimates (users, RPS, storage) → API → data model → high-level diagram → deep dive on 1–2 hard parts → bottlenecks, failures and trade-offs. Classic designs to practise: URL shortener (key generation, redirects, cache, analytics), e-commerce checkout (saga, stock, payment idempotency), notification service (queues, retries, templates, preferences), rate limiter (token bucket in Redis), chat (WebSockets/SignalR, fan-out, presence), file upload service (pre-signed URLs, Blob storage, virus scan queue)."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"504","title":"What are microservices? What are their advantages and disadvantages?","body":"Small, independently deployable services, each owning one business capability and its own data, talking over HTTP/gRPC or messages. Advantages: independent deployment and scaling, team autonomy, fault isolation, technology freedom per service. Disadvantages: distributed-system complexity (network failures, latency), no cross-service transactions (eventual consistency, sagas), harder testing and debugging, much more DevOps and monitoring work, data duplication."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"505","title":"Monolith vs microservices — which would you choose for a new project?","body":"Usually start with a modular monolith : one deployable with strict module boundaries and separate schemas. It is faster to build and easier to operate, and the boundaries let you extract services later. Choose microservices when there is a concrete need — independent scaling, separate teams with separate release cycles, very different technology or reliability needs — and the organisation can afford the DevOps cost."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"506","title":"How do microservices communicate?","body":"Synchronously with REST over HTTP (public/browser APIs) or gRPC (fast internal calls, contracts in .proto ), usually through an API gateway; asynchronously with messages through a broker (RabbitMQ, Azure Service Bus, Kafka) using queues for commands and topics for events. Prefer async for anything that doesn't need an immediate reply — it decouples availability and absorbs load spikes."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"507","title":"What is an API gateway and why use one?","body":"A single entry point in front of the services. It routes requests, terminates TLS, validates tokens, applies rate limiting and CORS, can aggregate several calls into one response and hides the internal topology from clients. .NET: YARP or Ocelot; Azure: API Management or Application Gateway. A Backend-for-Frontend is a gateway tailored to one client type."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"508","title":"What is \"database per service\" and how do you query data across services?","body":"Each service owns its tables; nobody else reads or writes them directly. Cross-service data is obtained by calling the owner's API, by API composition (gateway/BFF calls several services and merges), or by keeping a local read-only copy updated via events (CQRS read model). Reporting usually goes to a separate data warehouse fed by events or CDC."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"509","title":"Explain the saga pattern. Choreography vs orchestration?","body":"A saga is a sequence of local transactions across services, each with a compensating action to undo it if a later step fails (charge → refund). Choreography: each service listens for events and publishes the next one — simple, decentralised, but the overall flow is hard to see. Orchestration: a central coordinator (state machine) sends commands and tracks state — explicit and easier to monitor and change, but one more component."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"510","title":"What is the outbox pattern and what problem does it solve?","body":"The dual-write problem: saving to the database and publishing a message are two systems, so a crash between them leaves them inconsistent. With an outbox, the business data and the message are written in one local transaction (message into an Outbox table); a separate relay publishes outbox rows to the broker and marks them sent. Delivery becomes at-least-once, so consumers must be idempotent (often an Inbox table of processed ids)."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"511","title":"How do you make a service resilient to failures of its dependencies?","body":"Timeouts on every call; retries with exponential backoff and jitter for transient, idempotent operations; circuit breaker to fail fast while a dependency is down; bulkheads to limit concurrency; fallbacks/cached data; async messaging so work is queued rather than lost; health checks and auto-restart. In .NET: AddStandardResilienceHandler() / Polly."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"512","title":"What is idempotency and why is it important in distributed systems?","body":"An operation is idempotent if doing it twice has the same effect as once. Messages are delivered at least once and clients retry on timeouts, so duplicates are normal. Techniques: idempotency keys on POST (store key + result, return the same result on repeat), natural keys/unique constraints, processed-message tables, \"set\" operations instead of \"increment\"."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"513","title":"REST vs gRPC — when would you choose gRPC?","body":"gRPC for internal service-to-service calls where performance and strict contracts matter: binary Protobuf, HTTP/2 multiplexing, code-generated clients, streaming. REST for public APIs, browser clients, easy debugging and broad tooling. gRPC needs gRPC-Web or a gateway for browsers."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"514","title":"How do you implement distributed tracing in .NET?","body":"Use OpenTelemetry: add ASP.NET Core, HttpClient and SqlClient instrumentation and an exporter (OTLP to Jaeger, Aspire dashboard, Application Insights). .NET's Activity API propagates the W3C traceparent header automatically, so all spans of one request share a trace id. Add the trace id to logs to jump from a log line to the full trace."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"515","title":"How do you handle data consistency without distributed transactions?","body":"Accept eventual consistency and design for it: keep each aggregate's invariants inside one service and one local transaction; use sagas with compensations for multi-service workflows; outbox + idempotent consumers for reliable events; reservation patterns (reserve stock, confirm later, expire if unpaid); show pending states in the UI. Two-phase commit (MSDTC) is avoided — it blocks and doesn't work across most cloud services and brokers."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"516","title":"Explain CQRS. When is it worth it?","body":"Separate models for writes (commands that enforce business rules) and reads (queries/views optimised for screens). Worth it when reads vastly outnumber writes, read shapes differ a lot from the write model, or reads and writes need to scale separately. Overkill for simple CRUD. It doesn't require event sourcing or separate databases; a common form is EF Core for commands and Dapper over views for queries."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"517","title":"How do you version APIs and events without breaking consumers?","body":"Prefer additive, backward-compatible changes (new optional fields; consumers ignore unknown fields). For breaking changes: URL or header versioning (Asp.Versioning), run old and new side by side, deprecate with a timeline. For events: include a version, never change meaning of existing fields, publish new event types for big changes, use a schema registry for Kafka/Avro. Consumer-driven contract tests (Pact) catch breaks in CI."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"518","title":"How do you scale a .NET service horizontally?","body":"Make it stateless (no in-memory session or local files; use Redis, cookies, Blob storage), run multiple instances behind a load balancer, use a distributed cache and a shared Data Protection key ring, keep DB connections pooled and queries efficient, and autoscale on CPU/RPS or queue length (Kubernetes HPA/KEDA, Container Apps rules). Background jobs need a lock or a queue so they don't run on every instance."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"519","title":"Design a URL shortener.","body":"Requirements: create short link, redirect fast, optional expiry and analytics; e.g. 100M links, read-heavy (100:1). API: POST /links → { code } , GET /{code} → 301/302. Key generation: base62 of a unique id (DB sequence or Snowflake-style id) or a random 7-char code with uniqueness check. Store code → URL in a key-value store or SQL with a unique index; cache hot codes in Redis; CDN/edge for redirects. Analytics: publish click events to a queue/stream and aggregate asynchronously so redirects stay fast. Discuss collisions, abuse (rate limits, malware checks) and custom aliases."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"520","title":"An order service calls payment, which calls a slow fraud check; under load the whole site times out. What do you change?","body":"Cascading failure from synchronous chains. Add timeouts and a circuit breaker around the fraud call, a bulkhead so slow calls can't use every connection, and a fallback (accept low-value orders, flag for review). Better: make the flow asynchronous — accept the order as Pending, send a message for payment/fraud processing, update status by events, and notify the user. Scale the fraud service, and add tracing to prove where the time goes."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"521","title":"Customers are charged twice when the client retries a payment request. Fix it.","body":"Make the payment endpoint idempotent: the client sends an Idempotency-Key header (GUID per checkout attempt); the server stores the key with the result in the same transaction as the charge; a repeat request with the same key returns the stored result instead of charging again. Also pass an idempotency key to the payment provider (Stripe and others support this) and use a unique constraint on (OrderId, PaymentAttempt)."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"522","title":"You must split a large .NET monolith into services. How do you start?","body":"Don't big-bang rewrite. Map bounded contexts and coupling first; make the monolith modular (clear modules, separate schemas, no cross-module table access). Use the strangler fig pattern: put a gateway (YARP) in front, extract one well-bounded, high-value module at a time (often notifications, catalog or reporting), give it its own data (sync via events during migration), route its traffic to the new service, then remove the old code. Invest early in CI/CD, containers and observability."},{"kind":"question","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"523","title":"A message consumer keeps failing on one bad message and blocks the queue. What do you do?","body":"Configure limited retries with backoff, then move the message to the dead-letter queue so processing continues. Alert on DLQ depth, log the failure with the message id, fix the bug or the data, then replay from the DLQ. Make the consumer idempotent so replays are safe, and validate message schemas."},{"kind":"cheat","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"1","title":"Decide the style","body":"Modular monolith by default → extract a service only for independent scaling, release cadence, ownership or technology. Split by business capability (bounded context), never by technical layer."},{"kind":"cheat","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"2","title":"Communication","body":"Need Use --- --- Public/browser API REST + OpenAPI via gateway Fast internal call gRPC \"Do this later\" Queue (command) \"This happened\" Topic/pub-sub (event) High-volume stream / replay Kafka / Event Hubs"},{"kind":"cheat","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"3","title":"Consistency toolbox","body":"Local transaction per aggregate · saga (choreography/orchestration) with compensations · transactional outbox · idempotent consumer / inbox · idempotency keys · eventual consistency shown in UI."},{"kind":"cheat","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"4","title":"Resilience toolbox","body":"Timeout · retry + backoff + jitter (idempotent only) · circuit breaker · bulkhead · fallback · health checks (live/ready) · DLQ. .NET: AddStandardResilienceHandler() ."},{"kind":"cheat","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"5","title":"Observability","body":"Logs + metrics + traces via OpenTelemetry; correlation/trace id everywhere; golden signals: latency, traffic, errors, saturation; .NET Aspire dashboard locally, App Insights/Grafana in production."},{"kind":"cheat","course_slug":"microservices","course_title":"Microservices & System Design with .NET","ref":"6","title":"System design template","body":"Requirements → estimates → API → data model → diagram → deep dive → bottlenecks & failures → trade-offs. Always mention cache, queue, replicas, idempotency and monitoring."},{"kind":"course","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"","title":"SQL Server & T-SQL","body":"Database design and normalisation, data types, constraints, joins, subqueries, CTEs, window functions, stored procedures, functions, views, triggers, indexes, execution plans, transactions, isolation levels, locking, error handling and performance tuning. Microsoft SQL Server is a relational database management system (RDBMS). T-SQL (Transact-SQL) is Microsoft's extension of ANSI SQL with variables, control flow, error handling, stored procedures and more. The SQL Server family: Component Purpose --- --- Database Engine Stores and queries data (OLTP) SSIS (Integration Services) ETL — see the SSIS course SSRS (Reporting Services) / Power BI Report Server Paginated reports SSAS (Analysis Services) OLAP cubes, tabular models SQL Server Agent Job scheduling Azure SQL Database / Managed Instance PaaS versions in Azure Editions: Enterprise, Standard, Developer (free, full features, non-production), Express (free, limited), and Azure SQL. SQL statement categories: Category Statements --- --- DDL (Definition) CREATE , ALTER , DROP , TRUNCATE DML (Manipulation) SELECT , INSERT , UPDATE , DELETE , MERGE DCL (Control) GRANT , REVOKE , DENY TCL (Transaction) BEGIN TRAN , COMMIT , ROLLBACK , SAVE TRAN Version Year Highlights --- --- --- SQL Server 2005 2005 CTEs, ROW NUMBER /ranking functions, TRY...CATCH , SSIS replaces DTS, CLR integration 2008 / 2008 R2 2008/2010 MERGE , DATE / TIME types, table-valued parameters, filtered indexes 2012 2012 OFFSET/FETCH , LAG / LEAD , window frames, SEQUENCE , THROW , TRY CONVERT , IIF , Always On Availability Groups, columnstore (read-only) 2014 2014 In-Memory OLTP (Hekaton), updatable clustered columnstore 2016 2016 Query Store , temporal tables, JSON functions, Row-Level Security, Dynamic Data Masking, Always Encrypted, STRING SPLIT 2017 2017 Linux support , STRING AGG , TRIM , CONCAT WS , graph tables, adaptive query processing 2019 2019 Intelligent Query Processing (scalar UDF inlining, table variable deferred compilation), Accelerated Database Recovery, UTF-8 2022 2022 Azure Synapse Link, ledger tables, GREATEST / LEAST , DATE BUCKET , GENERATE SERIES , IS [NOT] DISTINCT FROM , parameter-sensitive plan optimisation 2025 2025 AI-ready: native vector data type and vector search, native JSON type, regular expression functions ( REGEXP LIKE etc.), optimized locking, Fabric mirroring How SQL Server executes a query: 1. Parse — syntax check, build a parse tree. 2. Bind (algebrize) — resolve names, types, permissions. 3. Optimise — the cost-based query optimizer uses statistics to choose an execution plan (join types, index seeks vs scans, parallelism). 4. Plan cache — plan stored for reuse (parameterised queries reuse plans). 5. Execute — the storage engine reads pages from the buffer pool (memory) or disk, acquiring locks/latches. 6. Return results to the client. Logical query processing order (not the written order): FROM → ON → JOIN → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → TOP / OFFSET-FETCH That's why you can't use a SELECT alias in WHERE , but you can in ORDER BY . Transaction lifecycle: BEGIN TRAN → statements write to the transaction log first (write-ahead logging) → COMMIT (durable once the log is hardened) or ROLLBACK (undo using the log). Checkpoints write dirty pages to data files; recovery replays/undoes the log after a crash. Database development lifecycle: requirements → conceptual model (ER diagram) → logical design (normalisation) → physical design (types, indexes, partitions) → implementation (DDL scripts/migrations) → testing → deployment (DACPAC/scripts) → monitoring and tuning → maintenance (backups, index/statistics maintenance). Tool Use --- --- SQL Server Management Studio (SSMS 21) Main admin/dev IDE: queries, execution plans, Agent, backups VS Code + MSSQL extension Cross-platform editor (Azure Data Studio retired Feb 2026) SQL Server Data Tools (SSDT) / SQL database projects Schema as code, DACPAC deployments sqlcmd , bcp Command-line scripts and bulk copy SQL Server Profiler / Extended Events Tracing (Profiler is deprecated; prefer XEvents) Query Store Plan history, regressed queries, forcing plans Database Engine Tuning Advisor Index suggestions SQL Server Agent Scheduled jobs sp WhoIsActive, sp Blitz (First Responder Kit) Free community diagnostic scripts Redgate SQL Prompt / SQL Compare, dbForge Productivity and schema compare Flyway, DbUp, EF migrations Database migrations"},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"keys-constraints-and-data-types","title":"Keys, constraints and data types","body":"sql CREATE TABLE dbo.Departments ( DeptId INT IDENTITY(1,1) CONSTRAINT PK Departments PRIMARY KEY, DeptName NVARCHAR(100) NOT NULL CONSTRAINT UQ Departments Name UNIQUE ); CREATE TABLE dbo.Employees ( EmpId INT IDENTITY(1,1) PRIMARY KEY, -- clustered by default FullName NVARCHAR(150) NOT NULL, Email VARCHAR(200) NOT NULL UNIQUE, DeptId INT NULL REFERENCES dbo.Departments(DeptId), -- foreign key ManagerId INT NULL REFERENCES dbo.Employees(EmpId), -- self-reference Salary DECIMAL(12,2) NOT NULL CHECK (Salary 0), HireDate DATE NOT NULL DEFAULT (CAST(GETDATE() AS DATE)), IsActive BIT NOT NULL DEFAULT 1, RowVer ROWVERSION ); Key/constraint Meaning --- --- Primary key Unique + NOT NULL; one per table; clustered index by default Candidate key Any column set that could be the PK Alternate key Candidate key not chosen as PK (enforce with UNIQUE) Composite key PK of several columns Surrogate key System-generated (IDENTITY, SEQUENCE, GUID) Natural key Business value (PAN, email) Foreign key References a PK/unique key; enforces referential integrity UNIQUE No duplicates (allows one NULL in SQL Server) CHECK / DEFAULT / NOT NULL Domain rules Types: INT/BIGINT , DECIMAL(p,s) for money (avoid FLOAT ), VARCHAR (1 byte/char, non-Unicode) vs NVARCHAR (Unicode), DATE , DATETIME2 (prefer over DATETIME ), DATETIMEOFFSET , BIT , UNIQUEIDENTIFIER , VARBINARY(MAX) ."},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"normalisation-1nf-bcnf-and-denormalisation","title":"Normalisation (1NF → BCNF) and denormalisation","body":"Form Rule Fix example --- --- --- 1NF Atomic values, no repeating groups Phones = '98..,99..' → separate CustomerPhones rows 2NF 1NF + no partial dependency on part of a composite key OrderItems(OrderId, ProductId, ProductName) → move ProductName to Products 3NF 2NF + no transitive dependency (non-key → non-key) Employees(DeptId, DeptName) → move DeptName to Departments BCNF Every determinant is a candidate key Stricter 3NF for overlapping candidate keys 4NF / 5NF No multi-valued / join dependencies Rare in interviews Denormalisation — deliberately adding redundancy (e.g. storing OrderTotal , reporting tables, star schemas) to speed reads at the cost of update complexity. OLTP systems: normalise to 3NF. Data warehouses: denormalised star schemas (facts + dimensions)."},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"ddl-vs-dml-delete-vs-truncate-vs-drop","title":"DDL vs DML; DELETE vs TRUNCATE vs DROP","body":"DELETE TRUNCATE DROP --- --- --- --- Type DML DDL DDL Removes Rows (with optional WHERE) All rows The whole table (structure + data) Logging Each row logged Page deallocations logged (minimal) Metadata Triggers Fires DELETE triggers No No Identity Not reset Reset to seed Gone Rollback Yes (in a transaction) Yes, inside a transaction in SQL Server Yes, inside a transaction FK-referenced table Allowed Not allowed Not allowed Speed Slower Fast Fast"},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"select-where-order-by-top-offset-fetch","title":"SELECT, WHERE, ORDER BY, TOP, OFFSET-FETCH","body":"sql SELECT TOP (10) e.EmpId, e.FullName, e.Salary FROM dbo.Employees AS e WHERE e.IsActive = 1 AND e.HireDate = '2024-01-01' AND e.FullName LIKE N'A%' AND e.DeptId IN (1, 2, 3) AND e.Salary BETWEEN 50000 AND 150000 ORDER BY e.Salary DESC; -- Paging (SQL Server 2012+) SELECT EmpId, FullName FROM dbo.Employees ORDER BY EmpId OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY; -- NULL handling SELECT FullName, ISNULL(ManagerId, 0) AS Mgr, COALESCE(Email, 'n/a') AS Email FROM dbo.Employees WHERE ManagerId IS NULL; -- never \"= NULL\" ISNULL (2 args, T-SQL, returns type of first arg) vs COALESCE (ANSI, any number of args, returns highest-precedence type)."},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"joins","title":"Joins","body":"sql -- INNER: matching rows only SELECT e.FullName, d.DeptName FROM Employees e INNER JOIN Departments d ON d.DeptId = e.DeptId; -- LEFT: all employees, department if any SELECT e.FullName, d.DeptName FROM Employees e LEFT JOIN Departments d ON d.DeptId = e.DeptId; -- Anti-join: departments with no employees SELECT d.DeptName FROM Departments d LEFT JOIN Employees e ON e.DeptId = d.DeptId WHERE e.EmpId IS NULL; -- FULL OUTER: everything from both sides SELECT FROM A FULL OUTER JOIN B ON A.Id = B.Id; -- SELF JOIN: employee and manager SELECT e.FullName AS Employee, m.FullName AS Manager FROM Employees e LEFT JOIN Employees m ON m.EmpId = e.ManagerId; -- CROSS JOIN: every combination SELECT s.Size, c.Color FROM Sizes s CROSS JOIN Colors c; -- CROSS APPLY / OUTER APPLY: run a correlated table expression per row (top 3 orders per customer) SELECT c.Name, o.OrderId, o.Total FROM Customers c CROSS APPLY (SELECT TOP (3) OrderId, Total FROM Orders WHERE CustomerId = c.CustomerId ORDER BY Total DESC) o; Physical join algorithms the optimizer picks: Nested Loops (small outer input + indexed inner), Merge Join (both inputs sorted on the key), Hash Match (large unsorted inputs)."},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"group-by-having-and-aggregates","title":"GROUP BY, HAVING and aggregates","body":"sql SELECT d.DeptName, COUNT( ) AS Headcount, AVG(e.Salary) AS AvgSalary, MAX(e.Salary) AS MaxSalary, SUM(e.Salary) AS Payroll FROM Employees e JOIN Departments d ON d.DeptId = e.DeptId WHERE e.IsActive = 1 -- filters rows BEFORE grouping GROUP BY d.DeptName HAVING COUNT( ) = 3 -- filters groups AFTER grouping ORDER BY Payroll DESC; -- ROLLUP / CUBE / GROUPING SETS for subtotals SELECT Region, Product, SUM(Amount) FROM Sales GROUP BY ROLLUP (Region, Product); -- STRING AGG (2017+) SELECT DeptId, STRING AGG(FullName, ', ') WITHIN GROUP (ORDER BY FullName) AS People FROM Employees GROUP BY DeptId; COUNT( ) counts rows; COUNT(col) ignores NULLs; COUNT(DISTINCT col) counts unique non-null values."},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"subqueries-exists-ctes-and-recursive-ctes","title":"Subqueries, EXISTS, CTEs and recursive CTEs","body":"sql -- Scalar subquery SELECT FullName, Salary FROM Employees WHERE Salary (SELECT AVG(Salary) FROM Employees); -- Correlated subquery: earn more than their department average SELECT e.FullName FROM Employees e WHERE e.Salary (SELECT AVG(x.Salary) FROM Employees x WHERE x.DeptId = e.DeptId); -- EXISTS / NOT EXISTS (NULL-safe, stops at first match) SELECT c.Name FROM Customers c WHERE NOT EXISTS (SELECT 1 FROM Orders o WHERE o.CustomerId = c.CustomerId); -- CTE WITH DeptPay AS ( SELECT DeptId, SUM(Salary) AS Payroll FROM Employees GROUP BY DeptId ) SELECT d.DeptName, p.Payroll FROM DeptPay p JOIN Departments d ON d.DeptId = p.DeptId; -- Recursive CTE: org hierarchy WITH Org AS ( SELECT EmpId, FullName, ManagerId, 0 AS Lvl FROM Employees WHERE ManagerId IS NULL -- anchor UNION ALL SELECT e.EmpId, e.FullName, e.ManagerId, o.Lvl + 1 -- recursive member FROM Employees e JOIN Org o ON e.ManagerId = o.EmpId ) SELECT FROM Org ORDER BY Lvl OPTION (MAXRECURSION 100); -- default limit is 100; 0 = unlimited NOT IN with a subquery that returns any NULL returns no rows — prefer NOT EXISTS ."},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"window-functions","title":"Window functions","body":"sql SELECT FullName, DeptId, Salary, ROW NUMBER() OVER (PARTITION BY DeptId ORDER BY Salary DESC) AS RowNum, -- 1,2,3,4 RANK() OVER (PARTITION BY DeptId ORDER BY Salary DESC) AS Rnk, -- 1,2,2,4 DENSE RANK() OVER (PARTITION BY DeptId ORDER BY Salary DESC) AS DenseRnk, -- 1,2,2,3 NTILE(4) OVER (ORDER BY Salary) AS Quartile, SUM(Salary) OVER (PARTITION BY DeptId) AS DeptPayroll, Salary 100.0 / SUM(Salary) OVER (PARTITION BY DeptId) AS PctOfDept, LAG(Salary) OVER (ORDER BY HireDate) AS PrevSalary, LEAD(Salary) OVER (ORDER BY HireDate) AS NextSalary, SUM(Salary) OVER (ORDER BY HireDate ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS RunningTotal, AVG(Salary) OVER (ORDER BY HireDate ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS MovingAvg3, FIRST VALUE(FullName) OVER (PARTITION BY DeptId ORDER BY Salary DESC) AS TopEarner FROM Employees; Window functions keep every row (unlike GROUP BY ). They are evaluated in the SELECT phase, so filter on them with a CTE/subquery: sql WITH r AS (SELECT , DENSE RANK() OVER (PARTITION BY DeptId ORDER BY Salary DESC) AS dr FROM Employees) SELECT FROM r WHERE dr = 1; -- top earner(s) per department"},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"set-operators-case-pivot-and-merge","title":"Set operators, CASE, PIVOT and MERGE","body":"sql SELECT Email FROM Customers UNION SELECT Email FROM Leads; -- distinct SELECT Email FROM Customers UNION ALL SELECT Email FROM Leads; -- keeps duplicates, faster SELECT Email FROM Customers INTERSECT SELECT Email FROM Leads; SELECT Email FROM Customers EXCEPT SELECT Email FROM Leads; SELECT FullName, CASE WHEN Salary = 150000 THEN 'Senior' WHEN Salary = 80000 THEN 'Mid' ELSE 'Junior' END AS Band FROM Employees; -- PIVOT SELECT FROM (SELECT Region, Quarter, Amount FROM Sales) s PIVOT (SUM(Amount) FOR Quarter IN ([Q1], [Q2], [Q3], [Q4])) p; -- MERGE (upsert) — target vs source MERGE dbo.Products AS t USING dbo.StagingProducts AS s ON t.Sku = s.Sku WHEN MATCHED AND t.Price < s.Price THEN UPDATE SET t.Price = s.Price WHEN NOT MATCHED BY TARGET THEN INSERT (Sku, Name, Price) VALUES (s.Sku, s.Name, s.Price) WHEN NOT MATCHED BY SOURCE THEN DELETE OUTPUT $action, inserted.Sku, deleted.Sku; MERGE has known concurrency caveats — use WITH (HOLDLOCK) on the target for concurrent upserts, or separate UPDATE + INSERT in a transaction."},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"stored-procedures","title":"Stored procedures","body":"sql CREATE OR ALTER PROCEDURE dbo.usp GetEmployeesByDept @DeptId INT, @MinSalary DECIMAL(12,2) = 0, -- default @TotalCount INT OUTPUT AS BEGIN SET NOCOUNT ON; -- suppress \"n rows affected\" messages SELECT EmpId, FullName, Salary FROM dbo.Employees WHERE DeptId = @DeptId AND Salary = @MinSalary ORDER BY Salary DESC; SELECT @TotalCount = @@ROWCOUNT; RETURN 0; -- return value: status code (INT only) END; GO DECLARE @n INT; EXEC dbo.usp GetEmployeesByDept @DeptId = 1, @MinSalary = 50000, @TotalCount = @n OUTPUT; SELECT @n; Benefits: plan reuse, security (grant EXECUTE without table access), fewer round trips, encapsulated logic, protection against injection (when not building dynamic SQL inside). Dynamic SQL inside a proc must use sp executesql with parameters."},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"functions-scalar-inline-tvf-multi-statement-tvf","title":"Functions: scalar, inline TVF, multi-statement TVF","body":"sql -- Scalar function CREATE OR ALTER FUNCTION dbo.fn TaxAmount (@Amount DECIMAL(12,2)) RETURNS DECIMAL(12,2) AS BEGIN RETURN @Amount 0.18; END; -- Inline table-valued function (best performing — expanded like a view) CREATE OR ALTER FUNCTION dbo.fn OrdersByCustomer (@CustomerId INT) RETURNS TABLE AS RETURN (SELECT OrderId, OrderDate, Total FROM dbo.Orders WHERE CustomerId = @CustomerId); SELECT FROM dbo.fn OrdersByCustomer(42); SELECT c.Name, o. FROM Customers c CROSS APPLY dbo.fn OrdersByCustomer(c.CustomerId) o; Stored procedure Function --- --- --- Returns 0..n result sets, OUTPUT params, INT return code Scalar or table (exactly one) Use in SELECT/WHERE/JOIN No Yes Modify data (INSERT/UPDATE) Yes No (no side effects) TRY...CATCH, transactions Yes No Call EXEC Inside queries Can call Functions and procs Only functions Scalar UDFs were notorious for row-by-row execution; SQL Server 2019 can inline many of them."},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"views-triggers-and-temporary-objects","title":"Views, triggers and temporary objects","body":"sql CREATE OR ALTER VIEW dbo.vw ActiveEmployees WITH SCHEMABINDING AS SELECT EmpId, FullName, DeptId FROM dbo.Employees WHERE IsActive = 1; -- Indexed (materialised) view: SCHEMABINDING + unique clustered index sql CREATE OR ALTER TRIGGER dbo.trg Employees Audit ON dbo.Employees AFTER UPDATE AS BEGIN SET NOCOUNT ON; INSERT INTO dbo.SalaryAudit (EmpId, OldSalary, NewSalary, ChangedAt) SELECT d.EmpId, d.Salary, i.Salary, SYSUTCDATETIME() FROM inserted i JOIN deleted d ON d.EmpId = i.EmpId WHERE i.Salary < d.Salary; -- handle MULTI-ROW updates, not just one row END; Triggers: AFTER (DML), INSTEAD OF (often on views), DDL triggers, logon triggers. Magic tables inserted / deleted . Keep them small; they hide logic and run inside the caller's transaction. Temp table t Table variable @t CTE --- --- --- --- Scope Session/proc (tempdb) Batch/proc Single statement Statistics Yes No column stats (2019: deferred compilation improves row estimates) n/a Indexes Any Inline PK/unique/index definitions n/a Transaction rollback Data rolled back Data not rolled back n/a Good for Larger intermediate sets Small sets Readability/recursion Global temp table t is visible to all sessions."},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"error-handling-and-transactions-in-t-sql","title":"Error handling and transactions in T-SQL","body":"sql CREATE OR ALTER PROCEDURE dbo.usp TransferFunds @From INT, @To INT, @Amount DECIMAL(12,2) AS BEGIN SET NOCOUNT ON; SET XACT ABORT ON; -- any runtime error rolls back the whole transaction BEGIN TRY BEGIN TRANSACTION; UPDATE dbo.Accounts SET Balance = Balance - @Amount WHERE AccountId = @From AND Balance = @Amount; IF @@ROWCOUNT = 0 THROW 50001, 'Insufficient funds or account not found', 1; UPDATE dbo.Accounts SET Balance = Balance + @Amount WHERE AccountId = @To; COMMIT TRANSACTION; END TRY BEGIN CATCH IF @@TRANCOUNT 0 ROLLBACK TRANSACTION; INSERT INTO dbo.ErrorLog (Number, Message, Proc, Line, LoggedAt) VALUES (ERROR NUMBER(), ERROR MESSAGE(), ERROR PROCEDURE(), ERROR LINE(), SYSUTCDATETIME()); THROW; -- re-raise to the caller END CATCH END; THROW (2012+) re-raises with the original number and line; RAISERROR is older (supports severity and formatting). @@ERROR is legacy."},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"clustered-non-clustered-covering-and-filtered-indexes","title":"Clustered, non-clustered, covering and filtered indexes","body":"- Clustered index — defines the physical order of rows (the table is the B-tree leaf level). One per table . Default on the PK. Best on narrow, unique, ever-increasing keys (INT IDENTITY). - Non-clustered index — separate B-tree with key columns + a row locator (clustered key, or RID for heaps). Up to 999 per table. - Covering index — contains all columns a query needs (keys + INCLUDE columns) → no key lookups. - Filtered index — index on a subset ( WHERE IsActive = 1 ). - Unique index , composite index (column order matters: equality columns first, then range/sort), columnstore (analytics, compression), full-text , XML/spatial . - Heap — table without a clustered index. sql CREATE NONCLUSTERED INDEX IX Orders Customer Date ON dbo.Orders (CustomerId, OrderDate DESC) INCLUDE (Total, Status) WHERE IsDeleted = 0; CREATE CLUSTERED COLUMNSTORE INDEX CCI FactSales ON dbo.FactSales; Costs: indexes speed reads but slow INSERT/UPDATE/DELETE and use storage. Find missing/unused ones with sys.dm db missing index details and sys.dm db index usage stats (validate suggestions — don't blindly create)."},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"execution-plans-seeks-vs-scans-and-sargability","title":"Execution plans, seeks vs scans and SARGability","body":"- Index Seek — navigates the B-tree to matching rows (good for selective predicates). - Index/Table Scan — reads everything (fine for small tables or returning most rows). - Key Lookup — after a non-clustered seek, fetch extra columns from the clustered index; many lookups → add INCLUDE columns. - SARGable (Search ARGument-able) predicates can use an index seek: sql -- ❌ Non-SARGable: function or calculation on the column WHERE YEAR(OrderDate) = 2026 WHERE LEFT(Name, 3) = 'Abc' WHERE Salary 1.1 100000 WHERE CONVERT(VARCHAR, Phone) = '98765' -- implicit/explicit conversion of the column -- ✅ SARGable WHERE OrderDate = '2026-01-01' AND OrderDate < '2027-01-01' WHERE Name LIKE 'Abc%' -- leading wildcard '%abc' is NOT sargable WHERE Salary 100000 / 1.1 Read plans right-to-left, top-to-bottom; look at thick arrows, estimated vs actual rows (bad estimates → stale statistics or parameter sniffing), warnings (spills, implicit conversions), and the most expensive operators. SET STATISTICS IO, TIME ON shows logical reads and CPU time."},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"statistics-parameter-sniffing-and-query-store","title":"Statistics, parameter sniffing and Query Store","body":"- Statistics — histograms of value distribution that the optimizer uses to estimate row counts. Auto-created/updated; refresh with UPDATE STATISTICS or maintenance jobs. - Parameter sniffing — the first execution's parameter values shape the cached plan; a plan good for a small customer can be terrible for a huge one. Fixes: OPTION (RECOMPILE) , OPTIMIZE FOR (@p UNKNOWN) or a specific value, splitting procs, plan forcing in Query Store, SQL 2022's Parameter Sensitive Plan optimisation. - Query Store (2016+) — records queries, plans and runtime stats over time; find regressed queries and force a known-good plan. - Index maintenance — fragmentation matters less on SSDs; prioritise statistics updates. Rebuild (offline/online) vs reorganise."},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"transactions-isolation-levels-and-locking","title":"Transactions, isolation levels and locking","body":"ACID: Atomicity (all or nothing), Consistency (constraints hold), Isolation (concurrent transactions don't interfere), Durability (committed = survives crashes). Isolation level Dirty read Non-repeatable read Phantom Notes --- --- --- --- --- READ UNCOMMITTED ( NOLOCK ) ✓ ✓ ✓ Can read uncommitted, even skip/duplicate rows READ COMMITTED (default) ✗ ✓ ✓ Shared locks released after each read REPEATABLE READ ✗ ✗ ✓ Holds shared locks till end of transaction SERIALIZABLE ✗ ✗ ✗ Range locks; most blocking SNAPSHOT ✗ ✗ ✗ Row versions in tempdb; readers don't block writers; update conflicts detected READ COMMITTED SNAPSHOT (RCSI) ✗ ✓ ✓ Database option; statement-level versioning — default in Azure SQL Database Lock modes: Shared (S) , Exclusive (X) , Update (U) , Intent (IS/IX) , schema locks. Granularity: row → page → table (lock escalation at ~5,000 locks). Blocking = one session waits for another's lock. Deadlock = two sessions wait on each other; SQL Server kills one (the victim, error 1205 ). Reduce deadlocks: access objects in the same order, keep transactions short, add proper indexes (fewer locks), use RCSI/SNAPSHOT, and retry on 1205."},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"partitioning-columnstore-temporal-and-security-features","title":"Partitioning, columnstore, temporal and security features","body":"- Table partitioning — split a large table by a range (e.g. month) on a partition function/scheme; enables partition elimination and fast SWITCH / TRUNCATE ... WITH (PARTITIONS (...)) for data retention. - Columnstore — column-wise compressed storage; huge gains for analytics/aggregates (data warehouses). - Temporal tables — SYSTEM VERSIONING = ON keeps full row history; query FOR SYSTEM TIME AS OF . - JSON — OPENJSON , JSON VALUE , JSON QUERY , FOR JSON PATH (2016+); native json type in SQL Server 2025. - Security — logins (server) vs users (database), roles, GRANT/DENY/REVOKE , schemas; Row-Level Security , Dynamic Data Masking , Always Encrypted , TDE (encryption at rest), auditing. - High availability / DR — Always On Availability Groups, Failover Cluster Instances, log shipping, backups: full , differential , transaction log (with FULL recovery model enables point-in-time restore)."},{"kind":"lesson","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"connection-strings-authentication-and-connecting-from-every-technology","title":"Connection strings, authentication and connecting from every technology","body":"Anatomy of a SQL Server connection string: text Server=tcp:myserver.database.windows.net,1433; ← host (or \".\\SQLEXPRESS\", \"localhost\", \"(localdb)\\MSSQLLocalDB\"), port 1433 Database=Shop; ← (= Initial Catalog) User ID=shop app;Password= ; ← SQL authentication OR Trusted Connection=True / Integrated Security=SSPI (Windows auth) Encrypt=True;TrustServerCertificate=False; ← TLS (Encrypt=True is the default since Microsoft.Data.SqlClient 4.0) Connection Timeout=30; ← seconds to wait for a connection MultipleActiveResultSets=False; ← MARS Application Name=Shop.Api; ← shows in sys.dm exec sessions — great for diagnostics Max Pool Size=100;Min Pool Size=0 ← connection pooling (on by default) Authentication When Connection string part --- --- --- Windows (Integrated) On-premises, domain/IIS app pool identity Trusted Connection=True SQL authentication Simple setups, non-Windows clients User ID=...;Password=... Microsoft Entra ID (Azure AD) — managed identity Azure SQL from Azure services — no password Authentication=Active Directory Managed Identity (or Active Directory Default ) Where to keep it: appsettings.json / web.config for non-secret parts, secrets in User Secrets (dev), environment variables, Azure Key Vault or managed identity (production). Never in source control or front-end code. Every technology at a glance: Technology How it connects Minimal example --- --- --- ADO.NET (.NET) Microsoft.Data.SqlClient ( System.Data.SqlClient in old Framework apps) using var cn = new SqlConnection(cs); cn.Open(); new SqlCommand(\"SELECT ...\", cn).ExecuteReader() Entity Framework Core UseSqlServer(cs) builder.Services.AddDbContext<ShopDb (o = o.UseSqlServer(builder.Configuration.GetConnectionString(\"Shop\"))) Entity Framework 6 DbContext(\"name=Shop\") + web.config connection string public ShopEntities() : base(\"name=ShopEntities\") { } Dapper Extension methods on SqlConnection conn.QueryAsync<Product (\"SELECT FROM dbo.Products\") ASP.NET Web Forms / MVC 5 web.config <connectionStrings + ConfigurationManager ConfigurationManager.ConnectionStrings[\"Shop\"].ConnectionString ASP.NET Core appsettings.json \"ConnectionStrings\" + GetConnectionString see EF Core / Dapper rows VB.NET Same ADO.NET classes Using cn As New SqlConnection(cs) : cn.Open() : End Using SSIS OLE DB / ADO.NET connection managers (MSOLEDBSQL provider) Connection manager + project parameters for environments SSRS Shared data sources (stored credentials or Windows integrated) Data source in Report Server Node.js mssql (tedious), Prisma, Sequelize new sql.ConnectionPool({ server, database, user, password, options: { encrypt: true } }) Next.js Server Components / route handlers with mssql or Prisma — never client code see the Next.js course React / Angular / Vue / AngularJS Through an HTTP API (ASP.NET Core / Node) — browsers never connect directly fetch('/api/products') / HttpClient.get(...) / $http.get(...) Python pyodbc / mssql-python with ODBC Driver 18 pyodbc.connect(\"DRIVER={ODBC Driver 18 for SQL Server};SERVER=...;DATABASE=Shop;Trusted Connection=yes;Encrypt=yes\") Java Microsoft JDBC driver jdbc:sqlserver://host:1433;databaseName=Shop;encrypt=true Power BI / Excel Built-in SQL Server connector (Import or DirectQuery) Server + database + credentials, on-premises data gateway for cloud refresh csharp // ADO.NET done right: async, parameterised, pooled, disposed await using var conn = new SqlConnection(cs); await conn.OpenAsync(ct); await using var cmd = new SqlCommand(\"SELECT Id, Name FROM dbo.Products WHERE CategoryId = @cat\", conn); cmd.Parameters.Add(\"@cat\", SqlDbType.Int).Value = categoryId; await using var reader = await cmd.ExecuteReaderAsync(ct); while (await reader.ReadAsync(ct)) Console.WriteLine($\"{reader.GetInt32(0)} {reader.GetString(1)}\"); Common connection errors: Error Cause / fix --- --- \"A network-related or instance-specific error… (error: 26/40)\" Wrong server/instance name, SQL Browser stopped (named instances), TCP/IP disabled in SQL Server Configuration Manager, firewall port 1433 closed \"Login failed for user\" (18456) Wrong credentials, SQL authentication not enabled (mixed mode), login has no access to the database, IIS app pool identity has no login \"The certificate chain was issued by an authority that is not trusted\" Encrypt=True with a self-signed server certificate — install a trusted certificate, or TrustServerCertificate=True for local development only \"Timeout expired… pool\" Connection leaks (not disposed) or too many concurrent requests — using / await using , check pool size, find long queries Azure SQL \"Cannot open server… not allowed\" Server firewall — add the client IP or use private endpoints / allow Azure services"},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"524","title":"What is the difference between DELETE, TRUNCATE and DROP?","body":"DELETE (DML) removes rows one by one, supports WHERE, fires triggers, logs each row and keeps the identity counter. TRUNCATE (DDL) removes all rows by deallocating pages, is minimally logged and much faster, resets IDENTITY, doesn't fire triggers and isn't allowed on tables referenced by a foreign key. DROP removes the whole table definition, data, indexes and permissions. In SQL Server all three can be rolled back inside an explicit transaction."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"525","title":"What are the different types of joins?","body":"INNER JOIN (matching rows in both), LEFT/RIGHT OUTER JOIN (all rows from one side + matches, NULLs otherwise), FULL OUTER JOIN (all rows from both), CROSS JOIN (Cartesian product), SELF JOIN (table joined to itself, e.g. employee–manager). T-SQL also has CROSS APPLY/OUTER APPLY for correlated table expressions. Physical algorithms: nested loops, merge, hash."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"526","title":"What is the difference between WHERE and HAVING?","body":"WHERE filters individual rows before grouping and can't use aggregates. HAVING filters groups after GROUP BY and can use aggregates ( HAVING COUNT( ) 5 ). Put non-aggregate conditions in WHERE for performance — fewer rows get grouped."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"527","title":"What is a primary key vs a unique key vs a foreign key?","body":"Primary key: uniquely identifies each row, NOT NULL, one per table, creates a clustered index by default. Unique key: enforces uniqueness on other columns, allows one NULL in SQL Server, many per table, creates a non-clustered index by default. Foreign key: a column referencing another table's primary/unique key to enforce referential integrity (with cascade options)."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"528","title":"What is normalisation? Explain 1NF, 2NF and 3NF.","body":"Organising tables to reduce redundancy and update anomalies. 1NF: atomic columns and no repeating groups. 2NF: 1NF and every non-key column depends on the whole primary key (no partial dependency — relevant for composite keys). 3NF: 2NF and no transitive dependency (non-key columns depend only on the key, e.g. move DeptName out of Employees into Departments). Data warehouses deliberately denormalise for read speed."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"529","title":"Clustered vs non-clustered index?","body":"A clustered index sorts and stores the table's data rows in key order — the leaf level is the data; only one per table. A non-clustered index is a separate structure with key columns and a pointer (clustered key or RID) back to the row; up to 999 per table. Clustered is ideal for range queries on the key; non-clustered for selective lookups on other columns, ideally covering with INCLUDE columns."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"530","title":"Write a query to find the second (or Nth) highest salary.","body":"sql -- Handles ties correctly; change 2 to N SELECT DISTINCT Salary FROM ( SELECT Salary, DENSE RANK() OVER (ORDER BY Salary DESC) AS rnk FROM dbo.Employees ) t WHERE rnk = 2; -- Alternative SELECT MAX(Salary) FROM dbo.Employees WHERE Salary < (SELECT MAX(Salary) FROM dbo.Employees); -- OFFSET/FETCH SELECT DISTINCT Salary FROM dbo.Employees ORDER BY Salary DESC OFFSET 1 ROWS FETCH NEXT 1 ROWS ONLY;"},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"531","title":"How do you find and delete duplicate rows?","body":"sql -- find SELECT Email, COUNT( ) AS Cnt FROM dbo.Customers GROUP BY Email HAVING COUNT( ) 1; -- delete all but one (keep lowest Id) WITH d AS ( SELECT , ROW NUMBER() OVER (PARTITION BY Email ORDER BY CustomerId) AS rn FROM dbo.Customers ) DELETE FROM d WHERE rn 1; Then add a UNIQUE constraint so it can't happen again."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"532","title":"What is the difference between UNION and UNION ALL?","body":"UNION combines result sets and removes duplicates (requires a sort/hash → slower). UNION ALL keeps all rows including duplicates and is faster. Both need the same number of columns with compatible types. Use UNION ALL unless you specifically need deduplication."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"533","title":"What is the difference between CHAR, VARCHAR, NCHAR and NVARCHAR?","body":"CHAR(n)/NCHAR(n) are fixed-length (padded with spaces); VARCHAR(n)/NVARCHAR(n) are variable-length. N-types store Unicode (UTF-16, 2 bytes per character for most), needed for Hindi, Chinese etc.; non-N types use 1 byte per character in the column's code page (or UTF-8 collations in 2019+). MAX variants hold up to 2 GB. Prefix Unicode literals with N'...' ."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"534","title":"Explain ROW_NUMBER, RANK and DENSE_RANK.","body":"All are window ranking functions. For salaries 100, 90, 90, 80: ROW NUMBER gives 1,2,3,4 (unique, arbitrary order among ties), RANK gives 1,2,2,4 (ties share a rank, gaps follow), DENSE RANK gives 1,2,2,3 (ties share, no gaps). Use ROW NUMBER for deduplication and paging, DENSE RANK for \"Nth highest\" with ties."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"535","title":"What is a CTE? When would you use a recursive CTE?","body":"A Common Table Expression ( WITH name AS (...) ) is a named temporary result set for a single statement — improves readability, can be referenced multiple times in that statement, and supports recursion. A recursive CTE has an anchor member UNION ALL a recursive member referencing the CTE; used for hierarchies (org charts, category trees, bill of materials) and generating sequences. Default max recursion 100 ( OPTION (MAXRECURSION n) )."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"536","title":"Stored procedure vs function?","body":"Procedures can return multiple result sets, output parameters and an integer return code; can modify data, use transactions and TRY/CATCH; are called with EXEC and can't be used inside SELECT. Functions return a scalar or a table, must be side-effect free (no INSERT/UPDATE to tables), can't use TRY/CATCH or transactions, and can be used in SELECT/WHERE/JOIN/APPLY. Prefer inline TVFs for reusable query logic."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"537","title":"What are the transaction isolation levels in SQL Server?","body":"READ UNCOMMITTED (dirty reads possible; NOLOCK ), READ COMMITTED (default; no dirty reads), REPEATABLE READ (no non-repeatable reads), SERIALIZABLE (no phantoms; range locks), SNAPSHOT (row versioning, consistent view as of transaction start, readers don't block writers), and READ COMMITTED SNAPSHOT (database setting making read committed use versioning per statement; default in Azure SQL Database). Higher isolation = more consistency, more blocking."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"538","title":"What is a deadlock and how do you handle it?","body":"Two (or more) transactions each hold locks the other needs, so neither can proceed. SQL Server's lock monitor detects it and kills the cheapest transaction (error 1205). Investigate with the system health Extended Events session (deadlock graphs). Prevent: access tables in a consistent order, keep transactions short, add indexes so fewer rows are locked, avoid user interaction inside transactions, use RCSI/SNAPSHOT for readers; and retry 1205 in the application."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"539","title":"Temp table vs table variable vs CTE?","body":"Temp tables ( t ) live in tempdb for the session/proc, have statistics, support any indexes, and are rolled back with transactions — good for larger intermediate data. Table variables ( @t ) are scoped to the batch, have no column statistics (estimates improved by 2019 deferred compilation), aren't affected by rollback, best for small sets. CTEs aren't stored at all — they're inlined into the single statement."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"540","title":"What makes a query non-SARGable? Give examples.","body":"Using functions, calculations or conversions on an indexed column in WHERE/JOIN prevents index seeks: WHERE YEAR(OrderDate) = 2026 , WHERE ISNULL(Col, 0) = 5 , WHERE Col + 1 = 10 , LIKE '%abc' , implicit conversions (nvarchar parameter vs varchar column). Rewrite as ranges or move the calculation to the parameter side: OrderDate = '2026-01-01' AND OrderDate < '2027-01-01' ."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"541","title":"What is the difference between ISNULL and COALESCE?","body":"ISNULL(expr, replacement) is T-SQL-specific, takes two arguments, and returns the data type of the first. COALESCE(a, b, c, ...) is ANSI standard, takes many arguments, returns the first non-NULL and uses data type precedence; it's internally a CASE expression (may evaluate subqueries twice). Nullability of computed results also differs."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"542","title":"What are the magic tables in triggers?","body":"inserted and deleted — virtual tables available inside DML triggers (and OUTPUT clauses). INSERT: inserted has new rows. DELETE: deleted has removed rows. UPDATE: deleted holds old values and inserted new values. Triggers fire once per statement, so always write set-based logic that handles multiple rows."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"543","title":"What is parameter sniffing and how do you fix it?","body":"When a parameterised query/proc compiles, the optimizer \"sniffs\" the first parameter values to estimate row counts and caches that plan. If data is skewed, later calls with different values reuse a plan that's bad for them (e.g. a nested-loop plan built for a customer with 5 orders reused for one with 5 million). Fixes: OPTION (RECOMPILE) for infrequent queries, OPTIMIZE FOR UNKNOWN /specific value, local variables (generic estimate), separate procedures for different data shapes, Query Store plan forcing, and SQL Server 2022's Parameter Sensitive Plan optimisation."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"544","title":"How do you approach tuning a slow query?","body":"1) Reproduce and measure ( SET STATISTICS IO, TIME ON , actual execution plan, Query Store history). 2) Read the plan: scans on large tables, key lookups, bad estimates, spills, implicit conversions, parallelism issues. 3) Fix the query: SARGable predicates, remove SELECT , avoid scalar UDFs/cursors (set-based), rewrite correlated subqueries, correct data types. 4) Fix indexes: covering/composite indexes in the right column order, filtered indexes, remove unused. 5) Update statistics; handle parameter sniffing. 6) Check blocking/waits ( sys.dm exec requests , sp WhoIsActive ). 7) Validate the improvement and watch write overhead."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"545","title":"What does NOLOCK do and why is it dangerous?","body":"WITH (NOLOCK) = READ UNCOMMITTED for that table: no shared locks, so it isn't blocked by writers. Dangers: dirty reads of uncommitted data that may roll back, missing or duplicate rows due to page splits during scans, and errors (601) on data movement. It isn't a performance fix for blocking — use READ COMMITTED SNAPSHOT isolation instead, which gives non-blocking reads of committed data."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"546","title":"Explain the backup types and recovery models.","body":"Recovery models: SIMPLE (log truncated at checkpoint, no log backups, restore only to the last full/diff), FULL (all logged, log backups required, point-in-time restore), BULK LOGGED (minimal logging for bulk ops, point-in-time limited). Backups: Full (whole DB), Differential (changes since the last full), Transaction log (log records since the last log backup — keeps the log from growing in FULL). Restore sequence: full → latest differential → all log backups in order ( STOPAT for point in time). Test restores regularly."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"547","title":"What is lock escalation?","body":"When a single statement acquires roughly 5,000+ row/page locks on one object, SQL Server may escalate to a table (or partition) lock to save memory, which increases blocking. Mitigate by batching large modifications (e.g. 4,000 rows at a time), proper indexes, ALTER TABLE ... SET (LOCK ESCALATION = AUTO) for partitioned tables, or row versioning isolation."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"548","title":"A report query that used to take 2 seconds now takes 2 minutes. Nothing in the code changed. What do you check?","body":"Something changed in data or plans. Check Query Store for a plan regression (different plan since date X) and force the old plan as a stopgap; check statistics staleness after big data loads (update them); parameter sniffing (different first-call parameters); data growth crossing a threshold; new blocking ( sp WhoIsActive , wait stats); index changes or dropped indexes; server pressure (memory grants, tempdb spills, CPU). Then fix permanently with indexes/query rewrite."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"549","title":"Write a query to get each department's top 3 earners.","body":"sql WITH ranked AS ( SELECT e. , DENSE RANK() OVER (PARTITION BY DeptId ORDER BY Salary DESC) AS rnk FROM dbo.Employees e ) SELECT d.DeptName, r.FullName, r.Salary, r.rnk FROM ranked r JOIN dbo.Departments d ON d.DeptId = r.DeptId WHERE r.rnk <= 3 ORDER BY d.DeptName, r.rnk; Use ROW NUMBER for exactly 3 rows per department regardless of ties; DENSE RANK to include ties."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"550","title":"Users report the Orders screen freezes at month-end when the finance job runs. How do you investigate and fix?","body":"Likely blocking: the finance job holds long locks (large UPDATEs, SERIALIZABLE, or lock escalation) while the screen's SELECTs wait. Investigate with sp WhoIsActive / sys.dm exec requests (blocking session id, wait types like LCK M S) during the window and the job's plans. Fixes: enable READ COMMITTED SNAPSHOT so readers don't block on writers, batch the job's updates into small transactions, add indexes so it locks fewer rows, schedule heavy parts off-hours, or read reports from a readable secondary/replica."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"551","title":"How would you design tables for an e-commerce order system?","body":"Customers(CustomerId PK, Name, Email UNIQUE), Addresses(AddressId, CustomerId FK, ...), Products(ProductId PK, Sku UNIQUE, Name, Price, CategoryId FK), Categories(self-referencing ParentId), Orders(OrderId PK, CustomerId FK, OrderDate, Status, ShippingAddressId FK, Total), OrderItems(OrderId FK, ProductId FK, Qty, UnitPrice — copy the price at order time; PK (OrderId, ProductId) or surrogate), Payments(PaymentId, OrderId FK, Amount, Method, Status, ProviderRef UNIQUE), Inventory(ProductId, WarehouseId, Qty, RowVersion). Indexes on FKs and common filters (Orders(CustomerId, OrderDate DESC)), CHECK constraints (Qty 0), rowversion for concurrency, audit columns."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"552","title":"You must load 50 million rows into a table that is queried 24/7. How do you avoid downtime?","body":"Load into a staging table with the same structure (bulk insert, minimal logging, no indexes during load, then build indexes), validate, then partition switch it into the main partitioned table (metadata-only, near-instant) or swap via sp rename inside a short transaction. Alternatively insert in small batches with throttling during low traffic. Use RCSI so readers aren't blocked, and keep statistics updated afterwards."},{"kind":"question","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"553","title":"What are the ACID properties of a transaction?","body":"Atomicity — all statements in a transaction succeed or none do (rollback on failure). Consistency — a transaction moves the database from one valid state to another, respecting constraints, keys and rules. Isolation — concurrent transactions don't see each other's uncommitted work, controlled by isolation levels and locks/row versions. Durability — once committed, changes survive crashes because the log is hardened to disk (write-ahead logging). Example: a money transfer debits one account and credits another inside one transaction so it can never half-complete."},{"kind":"cheat","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"1","title":"Logical processing order","body":"FROM → ON → JOIN → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → TOP/OFFSET."},{"kind":"cheat","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"2","title":"Joins","body":"INNER · LEFT · RIGHT · FULL · CROSS · SELF · CROSS APPLY · OUTER APPLY · anti-join ( LEFT JOIN ... WHERE b.Id IS NULL or NOT EXISTS )."},{"kind":"cheat","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"3","title":"Window functions","body":"sql ROW NUMBER()/RANK()/DENSE RANK()/NTILE(n) OVER (PARTITION BY a ORDER BY b) SUM(x) OVER (PARTITION BY a) -- group total on every row SUM(x) OVER (ORDER BY d ROWS UNBOUNDED PRECEDING) -- running total LAG(x, 1) / LEAD(x, 1) OVER (ORDER BY d) FIRST VALUE / LAST VALUE"},{"kind":"cheat","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"4","title":"Must-know queries","body":"Nth highest salary (DENSE RANK) · duplicates (GROUP BY HAVING) · delete duplicates (CTE + ROW NUMBER) · employee–manager (self join) · org chart (recursive CTE) · top N per group · running total · customers without orders (NOT EXISTS) · pivot (CASE/PIVOT) · upsert (MERGE)."},{"kind":"cheat","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"5","title":"Index rules","body":"One clustered (narrow, unique, increasing) · non-clustered for selective filters · equality columns first, then range · INCLUDE to cover · filtered for subsets · columnstore for analytics · SARGable predicates · every index costs writes."},{"kind":"cheat","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"6","title":"Isolation levels","body":"READ UNCOMMITTED → READ COMMITTED (default) → REPEATABLE READ → SERIALIZABLE; SNAPSHOT and RCSI use row versions (readers don't block writers)."},{"kind":"cheat","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"7","title":"Error handling template","body":"sql SET NOCOUNT ON; SET XACT ABORT ON; BEGIN TRY BEGIN TRAN; -- work COMMIT; END TRY BEGIN CATCH IF @@TRANCOUNT 0 ROLLBACK; THROW; END CATCH"},{"kind":"cheat","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"8","title":"Handy functions","body":"GETDATE() SYSUTCDATETIME() DATEADD DATEDIFF EOMONTH FORMAT CAST/CONVERT/TRY CONVERT ISNULL/COALESCE/NULLIF IIF CHOOSE LEN SUBSTRING CHARINDEX REPLACE TRIM STRING AGG STRING SPLIT CONCAT WS JSON VALUE OPENJSON @@ROWCOUNT SCOPE IDENTITY() NEWID() GREATEST/LEAST (2022)."},{"kind":"cheat","course_slug":"sqlserver","course_title":"SQL Server & T-SQL","ref":"9","title":"Diagnostics","body":"SET STATISTICS IO, TIME ON · actual execution plan · Query Store · sys.dm exec requests · sys.dm exec query stats · sys.dm db index usage stats · sys.dm db missing index details · sp WhoIsActive · Extended Events system health for deadlocks."},{"kind":"course","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"","title":"SQL Server Internals — How the Database Engine Really Works","body":"The SQL Server architecture (protocol layer, relational engine, storage engine, SQLOS), the life of a query from TDS packet to result, pages, extents and allocation maps, heaps vs clustered tables and B+ tree index structure, row layout, statistics and cardinality estimation, the query optimizer and plan cache, parameter sniffing, execution plan operators and join algorithms, buffer pool and memory grants, the transaction log, write-ahead logging, checkpoints and recovery, locking, latches, isolation levels, row versioning and tempdb, deadlocks, waits and DMVs, columnstore and In-Memory OLTP. SQL Server looks simple from outside — you send T-SQL and get rows — but inside it is an operating system of its own. Understanding it explains why indexes help, why a query is slow, why blocking and deadlocks happen and how data survives a crash. text Client (ADO.NET / EF / SSMS) │ TDS (Tabular Data Stream) over TCP 1433 ┌──▼──────────────────────────────────────────────────────────┐ │ PROTOCOL LAYER (SNI) — connections, TDS packets │ ├──────────────────────────────────────────────────────────────┤ │ RELATIONAL ENGINE (query processor) │ │ Parser → Algebrizer (binding) → Query Optimizer → Executor │ │ Plan cache │ ├──────────────────────────────────────────────────────────────┤ │ STORAGE ENGINE │ │ Access methods (scans, seeks, B-trees, heaps) │ │ Buffer manager (buffer pool) · Transaction manager │ │ Lock manager · Log manager │ ├──────────────────────────────────────────────────────────────┤ │ SQLOS — schedulers, workers, memory, waits, I/O, deadlock detection │ └──────────────────────────────────────────────────────────────┘ Data files (.mdf/.ndf, 8 KB pages) Log file (.ldf, sequential) tempdb Version Year Internals milestones --- --- --- SQL Server 7.0 1998 Rewritten storage engine: 8 KB pages, row-level locking, cost-based optimizer 2000 2000 Indexed views, user-defined functions 2005 2005 Row versioning (snapshot isolation, RCSI), DMVs, partitioning, SQLOS 2008 / R2 2008–2010 Data compression, filtered indexes, Extended Events, Resource Governor 2012 2012 Columnstore indexes, AlwaysOn Availability Groups 2014 2014 In-Memory OLTP (Hekaton), new cardinality estimator (CE 120) 2016 2016 Query Store , temporal tables, updatable columnstore improvements 2017 2017 Linux support, adaptive query processing 2019 2019 Intelligent Query Processing (scalar UDF inlining, table variable deferred compilation), Accelerated Database Recovery 2022 2022 Parameter Sensitive Plan optimisation, DOP/CE feedback, ledger tables, Query Store on by default for new DBs 2025 2025 Vector data type and vector search, native JSON type, regex functions, optimized locking Life of a query — SELECT Name FROM dbo.Customers WHERE Id = 42 : 1. Connect — the client opens a TCP connection (pooled by ADO.NET), authenticates, gets a session (SPID). 2. Send — the batch arrives as TDS packets; a worker thread on a scheduler (one per CPU core) picks it up. 3. Parse — syntax check → parse tree. 4. Algebrize (bind) — resolve names (tables, columns, types), check permissions → query tree. 5. Plan cache lookup — hash the query text; if a cached plan exists, reuse it (skip optimisation). 6. Optimize — cost-based optimizer uses statistics to estimate rows, explores alternatives (indexes, join orders and algorithms) and chooses the cheapest execution plan ; plan stored in cache. 7. Execute — the executor runs plan operators; the storage engine reads needed pages through the buffer pool (from memory if cached, otherwise physical reads from disk). 8. Lock — shared locks (or row versions) protect consistency according to the isolation level. 9. Return — rows are streamed back in TDS packets; locks released per isolation rules. For a write : the change is applied to pages in memory , the log record is written to the transaction log first (write-ahead logging), and on COMMIT the log is hardened to disk; dirty data pages are written later by checkpoint/lazy writer. - SSMS — actual/estimated execution plans, Live Query Statistics, Activity Monitor, Query Store reports. - DMVs — sys.dm exec requests , sys.dm exec sessions , sys.dm exec query stats , sys.dm os wait stats , sys.dm tran locks , sys.dm db index physical stats , sys.dm db index usage stats , sys.dm exec query plan . - Extended Events (replaces SQL Profiler), system health session (deadlock graphs). - Query Store — plan history, regressions, forcing plans. - DBCC — DBCC PAGE , DBCC IND (undocumented; learning), DBCC SHOW STATISTICS , DBCC CHECKDB , DBCC SQLPERF(LOGSPACE) . - Community: sp WhoIsActive , First Responder Kit ( sp Blitz , sp BlitzIndex , sp BlitzCache ), SentryOne Plan Explorer."},{"kind":"lesson","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"engine-components-and-sqlos-schedulers-workers-and-waits","title":"Engine components and SQLOS — schedulers, workers and waits","body":"Component Responsibility --- --- Protocol layer (SNI) Network connections, TDS protocol, shared memory/TCP/named pipes Command parser & algebrizer Syntax and name/type resolution Query optimizer Builds the execution plan from statistics and costs Query executor Runs plan operators, requests data from access methods Access methods Code that scans heaps, seeks/scans B-trees, inserts/updates rows Buffer manager Manages the buffer pool (cached data pages in RAM) Transaction manager / log manager Transactions, write-ahead logging, recovery Lock manager Locks for concurrency control; deadlock detection (every 5 s by default, faster when deadlocks are found) SQLOS SQL Server's \"OS layer\": cooperative scheduling, memory management, I/O, waits Scheduling: SQLOS creates one scheduler per logical CPU. Each task (a request or part of a parallel query) runs on a worker (thread). Workers yield cooperatively ; when a task must wait (for a page read, a lock, a log flush, memory, network), it goes to a waiting list with a wait type . When the resource is ready it moves to the runnable queue. text RUNNING ──needs resource──▶ SUSPENDED (wait type, e.g. PAGEIOLATCH SH) ──resource ready──▶ RUNNABLE (waiting for CPU = signal wait) ──▶ RUNNING Wait statistics tell you what SQL Server spends time waiting on: Wait type Means Typical cause --- --- --- PAGEIOLATCH Waiting to read data pages from disk Missing indexes (big scans), not enough memory, slow storage LCK M Waiting for a lock Blocking — long transactions, missing indexes WRITELOG Waiting for log flush on commit Slow log disk, many tiny transactions CXPACKET / CXCONSUMER Parallelism coordination Large parallel queries; tune MAXDOP/cost threshold SOS SCHEDULER YIELD CPU pressure CPU-heavy queries RESOURCE SEMAPHORE Waiting for a memory grant Big sorts/hashes, bad estimates ASYNC NETWORK IO Client isn't consuming results fast enough App reads rows slowly or fetches too much sql SELECT TOP 10 wait type, wait time ms / 1000.0 AS wait s, waiting tasks count FROM sys.dm os wait stats WHERE wait type NOT LIKE 'SLEEP%' AND wait type NOT IN ('BROKER TASK STOP','XE TIMER EVENT','REQUEST FOR DEADLOCK SEARCH','LAZYWRITER SLEEP','CHECKPOINT QUEUE') ORDER BY wait time ms DESC;"},{"kind":"lesson","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"pages-extents-files-and-allocation-maps","title":"Pages, extents, files and allocation maps","body":"- A database has at least one data file ( .mdf , plus optional .ndf in filegroups ) and one log file ( .ldf ). - Data files are divided into pages of 8 KB (8,192 bytes: 96-byte header, row data, row offset array at the end). Maximum in-row data ≈ 8,060 bytes per row. - 8 contiguous pages = an extent (64 KB). Mixed extents (shared by objects) vs uniform extents (one object; default for new allocations since SQL Server 2016). Page type Holds --- --- Data Rows of heaps and clustered index leaf level Index Non-leaf index levels and nonclustered index rows Text/Image (LOB), row-overflow NVARCHAR(MAX) , VARBINARY(MAX) , rows that exceed 8,060 bytes GAM / SGAM Global Allocation Map — which extents are free / mixed extents with free pages (each covers ~4 GB) PFS Page Free Space — how full each page is (covers ~64 MB) IAM Index Allocation Map — which extents belong to a given table/index partition DCM / BCM Changed extents since last full backup / bulk-logged operations Boot page, file header Database and file metadata Row structure (FixedVar format): status bits, fixed-length columns, null bitmap , variable-length column count and offset array, variable-length data. That's why fixed-length types ( INT , CHAR(10) ) are laid out first and VARCHAR columns need offsets. sql -- See how many pages a table uses and how full they are SELECT index id, index type desc, page count, avg page space used in percent, avg fragmentation in percent, record count FROM sys.dm db index physical stats(DB ID(), OBJECT ID('dbo.Orders'), NULL, NULL, 'DETAILED');"},{"kind":"lesson","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"heaps-clustered-and-nonclustered-indexes-b-tree-internals","title":"Heaps, clustered and nonclustered indexes — B+ tree internals","body":"Heap — a table without a clustered index: rows stored in no particular order, located by a RID (file:page:slot). Updates that grow a row may leave forwarding pointers . Fine for staging tables; usually bad for OLTP. Clustered index — the table itself is a B+ tree ordered by the clustering key: root page → intermediate pages → leaf pages containing the full rows . One per table. Nonclustered index — a separate B+ tree on chosen key columns; leaf rows contain the key + a row locator : the clustering key (if the table is clustered) or the RID (heap). Up to 999 per table. text Clustered index on Orders(OrderId) Nonclustered index on Orders(CustomerId) INCLUDE (Total) [Root: 1 50,001 100,001] [Root: ... ] / \\ / \\ [Intermediate ...] [Leaf: CustomerId, Total, OrderId(locator)] [Leaf pages: full rows ordered by OrderId] → \"key lookup\" into the clustered index for other columns Operation What it does Cost --- --- --- Index seek Navigate root → leaf to a key or range ~3–4 page reads for millions of rows Index/table scan Read all leaf pages Proportional to table size Key lookup (bookmark lookup) For each row found in a nonclustered index, fetch missing columns from the clustered index 1 seek per row — expensive for many rows Covering index Nonclustered index containing all needed columns (keys + INCLUDE ) No lookups Choosing a clustered key: narrow (it's copied into every nonclustered index), unique, static (never updated) and ever-increasing ( INT IDENTITY , BIGINT , sequential GUID) to avoid page splits . Random NEWID() GUID keys cause splits and fragmentation. Page splits and fill factor: inserting into a full page splits it into two half-full pages (expensive, logged, causes fragmentation). FILLFACTOR = 90 leaves 10 % free space on leaf pages at rebuild time for tables with random inserts. Fragmentation: logical order of pages ≠ physical order and/or low page density. Rebuild ( ALTER INDEX ... REBUILD ) or reorganise based on measurement; on SSDs, page density (wasted space) matters more than physical order. sql CREATE CLUSTERED INDEX CIX Orders ON dbo.Orders(OrderId); CREATE NONCLUSTERED INDEX IX Orders Customer Date ON dbo.Orders(CustomerId, OrderDate DESC) INCLUDE (Total, Status) WITH (FILLFACTOR = 95, ONLINE = ON); CREATE INDEX IX Orders Open ON dbo.Orders(OrderDate) WHERE Status = 'Open'; -- filtered index"},{"kind":"lesson","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"statistics-cardinality-estimation-and-the-query-optimizer","title":"Statistics, cardinality estimation and the query optimizer","body":"The optimizer is cost-based : it estimates how many rows each step will produce ( cardinality ) and picks the plan with the lowest estimated cost (CPU + I/O). Estimates come from statistics : - A histogram of up to 200 steps on the first column of the statistics object (values and row counts per range). - Density vectors for column combinations (average uniqueness). - Created automatically for indexes and for columns used in predicates ( AUTO CREATE STATISTICS ), updated automatically after enough changes ( AUTO UPDATE STATISTICS ; dynamic threshold ≈ √(1000 × rows) since SQL Server 2016 / compat level 130). sql DBCC SHOW STATISTICS ('dbo.Orders', 'IX Orders Customer Date') WITH HISTOGRAM; UPDATE STATISTICS dbo.Orders WITH FULLSCAN; -- after big data loads SELECT FROM sys.dm db stats properties(OBJECT ID('dbo.Orders'), 2); -- last updated, rows sampled, modification counter Optimisation phases: trivial plan (simple queries — no costing needed) → simplification (remove redundant joins, push predicates) → cost-based search in stages (transaction processing → quick plan → full optimisation), stopping when a \"good enough\" plan is found or a time budget ends. Things that break estimates: stale statistics, functions on columns ( WHERE YEAR(OrderDate) = 2026 ), implicit conversions (NVARCHAR parameter vs VARCHAR column), table variables (estimated 1 row before SQL Server 2019's deferred compilation), multi-statement table-valued functions, local variables (optimizer can't see the value), correlated columns, complex OR/LIKE predicates. SARGable predicates (Search ARGument-able) let the optimizer seek: sql -- ❌ Non-SARGable: function on the column → scan WHERE YEAR(OrderDate) = 2026 WHERE LEFT(Email, 3) = 'abc' WHERE CustomerCode = 12345 -- CustomerCode is VARCHAR → implicit conversion of the column -- ✅ SARGable rewrites → seek WHERE OrderDate = '2026-01-01' AND OrderDate < '2027-01-01' WHERE Email LIKE 'abc%' WHERE CustomerCode = '12345'"},{"kind":"lesson","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"plan-cache-parameter-sniffing-and-query-store","title":"Plan cache, parameter sniffing and Query Store","body":"Compiled plans are stored in the plan cache keyed by the exact query text (and SET options). Parameterised queries (stored procedures, sp executesql , ADO.NET/EF/Dapper parameters) are compiled once and reused. Parameter sniffing: the first execution's parameter values are used to optimise the plan; later executions with very different values reuse it. Example: @CustomerId = 1 (10 rows) gets a seek + key lookup plan; then a big customer with 2 million rows reuses it → millions of lookups → very slow. Fix Trade-off --- --- OPTION (RECOMPILE) Fresh plan every execution — CPU cost; great for rare, varied reports OPTION (OPTIMIZE FOR (@p = value / UNKNOWN)) Plan for typical/average values Better index (covering) Makes the plan good for all values — best fix Split procedures by case More code Query Store plan forcing Pins a known good plan SQL Server 2022 PSP optimisation Automatically keeps multiple plans per parameter range sql -- Top CPU queries currently in cache SELECT TOP 10 qs.total worker time / qs.execution count AS avg cpu, qs.execution count, SUBSTRING(st.text, (qs.statement start offset/2)+1, 200) AS query text, qp.query plan FROM sys.dm exec query stats qs CROSS APPLY sys.dm exec sql text(qs.sql handle) st CROSS APPLY sys.dm exec query plan(qs.plan handle) qp ORDER BY qs.total worker time DESC; Query Store (database-level flight recorder): stores queries, plans and runtime statistics over time; shows regressed queries after a deployment or stats update; lets you force a previous good plan. Enabled by default for new databases in SQL Server 2022 and in Azure SQL. Plan cache pollution: ad-hoc queries with literals ( WHERE Id = 1 , WHERE Id = 2 …) each get their own plan — use parameters; consider optimize for ad hoc workloads ."},{"kind":"lesson","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"reading-execution-plans-operators-and-join-algorithms","title":"Reading execution plans — operators and join algorithms","body":"Plans are read right to left (data flow) and top to bottom ; each arrow's thickness shows the row count. Compare estimated vs actual rows — big differences point to statistics/estimation problems. Operator Meaning --- --- Clustered Index Seek / Index Seek Navigated the B-tree to specific keys — good for selective predicates Clustered Index Scan / Table Scan Read the whole table/index — fine for small tables or when most rows are needed Key Lookup / RID Lookup Fetch extra columns per row — fix with a covering index if many rows Nested Loops join For each outer row, look up matching inner rows — best when outer input is small and inner side has an index Merge Join Both inputs sorted on the join key — stream and match; efficient for large sorted inputs Hash Match join/aggregate Build a hash table on the smaller input, probe with the other — good for large unsorted inputs; needs a memory grant Sort Orders rows — needs memory; spills to tempdb if under-estimated Stream Aggregate / Hash Aggregate GROUP BY on sorted / unsorted input Compute Scalar, Filter Expressions; filtering after reading (a late filter is a hint of non-SARGable predicates) Spool Stores intermediate results for reuse Parallelism (Gather/Repartition Streams) Parallel plan exchanges Warnings to look for: implicit conversion warnings, spills to tempdb (Sort/Hash warnings), missing index suggestions (evaluate, don't blindly create), huge estimated vs actual gaps, key lookups executed thousands of times. sql SET STATISTICS IO, TIME ON; -- logical reads per table + CPU/elapsed time SELECT o.OrderId, o.Total FROM dbo.Orders o WHERE o.CustomerId = 42 ORDER BY o.OrderDate DESC; -- Messages tab: Table 'Orders'. Scan count 1, logical reads 4 ... → compare before/after an index"},{"kind":"lesson","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"memory-buffer-pool-plan-cache-and-memory-grants","title":"Memory — buffer pool, plan cache and memory grants","body":"Memory area Holds --- --- Buffer pool 8 KB data/index pages read from disk (clean and dirty pages) — usually the largest consumer Plan cache Compiled execution plans Query workspace (memory grants) Sorts, hash joins/aggregates during execution Lock memory, connections, CLR, columnstore object pool, In-Memory OLTP Other components - Logical read = page read from the buffer pool; physical read = page had to come from disk first. Tuning aims to reduce logical reads (less data touched). - The lazy writer frees memory by writing dirty pages and evicting least-recently-used pages when memory is needed; Page Life Expectancy indicates how long pages stay cached. - SQL Server takes as much memory as allowed — always set max server memory to leave RAM for the OS and other processes. - Memory grants are reserved before a query runs based on estimates; under-estimates cause spills to tempdb , over-estimates waste memory and cause RESOURCE SEMAPHORE waits (memory grant feedback in 2019+ adjusts this automatically)."},{"kind":"lesson","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"the-transaction-log-write-ahead-logging-checkpoint-and-recovery","title":"The transaction log, write-ahead logging, checkpoint and recovery","body":"Write-ahead logging (WAL): every change is first recorded in the transaction log (sequential writes, each record with an LSN — log sequence number). A transaction is committed when its log records are hardened (flushed) to the log file. Data pages are changed in memory and written to data files later. Checkpoint periodically writes dirty data pages to disk (indirect checkpoints with a target recovery time, default 60 s for new databases), limiting how much log must be replayed after a crash. Crash recovery on startup (per database): 1. Analysis — read the log from the last checkpoint, find dirty pages and active transactions. 2. Redo — replay committed (and uncommitted) changes not yet in data files (roll forward). 3. Undo — roll back transactions that were active at the crash. Accelerated Database Recovery (ADR, 2019) keeps row versions in a persistent version store so undo is near-instant and long-running transaction rollbacks don't take hours. The log is divided into virtual log files (VLFs) ; space is reused (truncated) only when no longer needed by active transactions, replication, availability groups or — in the FULL model — until a log backup . Recovery model Log behaviour Point-in-time restore --- --- --- SIMPLE Log truncated at checkpoint No (only to full/differential backups) FULL Log kept until log backup Yes BULK LOGGED Minimal logging for bulk operations Limited during bulk ops Common problem: FULL recovery without log backups → log file grows until the disk is full . Check SELECT name, log reuse wait desc FROM sys.databases ."},{"kind":"lesson","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"locking-latches-isolation-levels-and-row-versioning","title":"Locking, latches, isolation levels and row versioning","body":"Locks protect logical consistency of data between transactions: Mode Used for Compatible with --- --- --- Shared (S) Reading S, U, IS Update (U) Reading a row you intend to update (prevents a common deadlock) S, IS Exclusive (X) Writing Nothing Intent (IS, IX, SIX) Signal locks at a lower level (on table/page above a row) Allows fast checks Schema (Sch-S, Sch-M) Compiling / altering objects Sch-M blocks everything Granularity: row (key/RID) → page → partition → table (object). Lock escalation converts many row/page locks (~5,000 on one object) into a table lock to save memory — can cause sudden blocking. Latches are lightweight internal locks protecting in-memory structures (pages in the buffer pool) for very short durations — e.g. PAGELATCH EX contention on the last page of an ever-increasing key under heavy inserts (fix: OPTIMIZE FOR SEQUENTIAL KEY , partitioning, hash keys). Isolation levels: Level Dirty read Non-repeatable read Phantom How --- --- --- --- --- READ UNCOMMITTED ( NOLOCK ) ✅ possible ✅ ✅ No shared locks — may read uncommitted, duplicated or missing rows READ COMMITTED (default) ❌ ✅ ✅ Shared locks released after each read REPEATABLE READ ❌ ❌ ✅ Shared locks held until commit SERIALIZABLE ❌ ❌ ❌ Key-range locks READ COMMITTED SNAPSHOT (RCSI) ❌ ✅ ✅ Readers read the last committed version — readers don't block writers SNAPSHOT ❌ ❌ ❌ Whole transaction sees a consistent snapshot; update conflicts raise an error Row versioning: with RCSI/SNAPSHOT, updates keep the previous row version in the version store (tempdb, or the persistent version store with ADR); readers follow the version chain. Benefit: far less blocking between readers and writers (Azure SQL Database uses RCSI by default). Cost: tempdb usage and a 14-byte versioning tag per row. sql ALTER DATABASE Shop SET READ COMMITTED SNAPSHOT ON WITH ROLLBACK IMMEDIATE; -- Who is blocking whom right now? SELECT r.session id, r.blocking session id, r.wait type, r.wait time, t.text FROM sys.dm exec requests r CROSS APPLY sys.dm exec sql text(r.sql handle) t WHERE r.blocking session id < 0;"},{"kind":"lesson","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"deadlocks-tempdb-and-how-they-relate-to-app-design","title":"Deadlocks, tempdb and how they relate to app design","body":"Deadlock: two sessions each hold a lock the other needs. The lock monitor detects the cycle and kills the cheaper transaction ( deadlock victim , error 1205 ); the application should retry. text Session A: UPDATE Orders (row 1, X lock) → then wants Customers (row 7) Session B: UPDATE Customers (row 7, X lock) → then wants Orders (row 1) → cycle → one is the victim Prevention: access tables in the same order , keep transactions short (no user interaction or HTTP calls inside), index foreign keys and search columns (fewer rows locked), use RCSI so reads don't take shared locks, use UPDLOCK for read-then-update patterns, and retry 1205 in code. Capture graphs from the system health Extended Events session. tempdb — shared by the whole instance: temporary tables ( t ), table variables, sort/hash spills, version store, index rebuilds with SORT IN TEMPDB , internal worktables. Best practices: multiple equally sized data files (typically 1 per core up to 8) to reduce allocation contention, fast storage, memory-optimised tempdb metadata (2019+)."},{"kind":"lesson","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"columnstore-in-memory-oltp-and-other-storage-options","title":"Columnstore, In-Memory OLTP and other storage options","body":"Columnstore indexes store data by column in compressed segments (rowgroups of ~1 million rows), with batch mode execution processing ~900 rows at a time. Huge gains (10× compression, 10–100× faster) for analytics and aggregations over millions of rows; less suited to single-row lookups and frequent small updates (delta store + tuple mover handle inserts). sql CREATE CLUSTERED COLUMNSTORE INDEX CCI FactSales ON dbo.FactSales; -- data warehouse fact table CREATE NONCLUSTERED COLUMNSTORE INDEX NCCI Orders ON dbo.Orders(OrderDate, Total, Status); -- real-time analytics on OLTP In-Memory OLTP (Hekaton): memory-optimised tables with lock- and latch-free structures (hash and range indexes), optimistic multi-versioning and natively compiled stored procedures — for extreme insert/update rates (session state, queues, IoT ingestion). Durable ( SCHEMA AND DATA ) or not. Partitioning: split a large table by a column (usually date) into partitions on filegroups — partition elimination, fast archiving with SWITCH , per-partition index maintenance. It's mainly a manageability feature; queries without the partition key don't get faster. Compression: row and page compression reduce I/O and memory at some CPU cost."},{"kind":"question","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"554","title":"What is the difference between a clustered and a nonclustered index?","body":"A clustered index defines the physical order of the table: its B+ tree leaf level contains the actual data rows, so there can be only one. A nonclustered index is a separate B+ tree whose leaf rows contain the index key plus a pointer (the clustering key or RID) to the data row; there can be many. Queries needing columns not in a nonclustered index do key lookups into the clustered index."},{"kind":"question","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"555","title":"What is a page and an extent in SQL Server?","body":"A page is the basic 8 KB unit of storage and I/O, holding rows (≈8,060 bytes max in-row data) with a header and a row offset array. An extent is 8 contiguous pages (64 KB); SQL Server allocates space in extents. Special pages (GAM, SGAM, PFS, IAM) track which extents and pages are free or belong to which object."},{"kind":"question","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"556","title":"What are the transaction isolation levels in SQL Server?","body":"READ UNCOMMITTED (dirty reads possible), READ COMMITTED (default; no dirty reads), REPEATABLE READ (rows you read can't change), SERIALIZABLE (no phantoms — range locks) plus row-versioning options READ COMMITTED SNAPSHOT (statement-level consistent versions, readers don't block writers) and SNAPSHOT (transaction-level consistent snapshot with update-conflict detection)."},{"kind":"question","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"557","title":"What is an execution plan and how do you read it?","body":"The step-by-step strategy the optimizer chose to run a query (operators like seeks, scans, joins, sorts). Read it right to left following the data flow, check the most expensive operators, compare estimated vs actual row counts, and look for scans on large tables, key lookups repeated many times, sorts/hash spills, implicit conversion and missing-index warnings. Use SET STATISTICS IO to measure logical reads before and after a change."},{"kind":"question","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"558","title":"How does SQL Server process a query internally?","body":"Connection and TDS packets → parser (syntax) → algebrizer (binding names and types) → plan cache lookup → cost-based optimizer using statistics to choose a plan (cached) → executor runs the operators → storage engine reads pages via the buffer pool (from disk if not cached), taking locks or reading row versions per isolation level → rows streamed back to the client."},{"kind":"question","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"559","title":"What are statistics and why do they matter?","body":"Objects with a histogram (up to 200 steps) and density information about column value distributions, used by the optimizer to estimate how many rows each operation returns. Good estimates → good plans (right join type, memory grant, index choice). Stale or missing statistics lead to bad plans; they're auto-created/updated, and can be updated manually ( UPDATE STATISTICS ... WITH FULLSCAN ) after large data changes."},{"kind":"question","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"560","title":"What is parameter sniffing? How do you fix it?","body":"SQL Server compiles a parameterised query or procedure using the parameter values of the first execution and reuses that plan for all later values. If data is skewed, the plan can be terrible for other values. Fixes: a covering index that suits all values, OPTION (RECOMPILE) , OPTIMIZE FOR , splitting logic, forcing a good plan with Query Store, or SQL Server 2022's Parameter Sensitive Plan optimisation."},{"kind":"question","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"561","title":"What is write-ahead logging and how does SQL Server recover after a crash?","body":"Every modification is written to the transaction log (with an LSN) before the data page changes reach disk, and a commit waits until its log records are hardened. After a crash, recovery runs analysis (find dirty pages and open transactions), redo (replay logged changes since the last checkpoint) and undo (roll back uncommitted transactions), returning the database to a consistent state."},{"kind":"question","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"562","title":"What causes blocking and how do you troubleshoot it?","body":"A session holding locks (usually a long or open transaction, or one scanning many rows because of missing indexes) blocks others needing incompatible locks. Find it with sys.dm exec requests ( blocking session id ), sp WhoIsActive , and the head blocker's query/plan; fix by shortening transactions, adding indexes, committing promptly from the app, and enabling RCSI so readers don't block writers."},{"kind":"question","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"563","title":"What is a key lookup and how do you remove it?","body":"When a nonclustered index finds rows but the query needs columns not in that index, SQL Server looks up each row in the clustered index (key lookup) or heap (RID lookup). For many rows it's very expensive. Remove it by adding the needed columns to the index with INCLUDE (covering index), or selecting fewer columns."},{"kind":"question","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"564","title":"What is the buffer pool?","body":"The main memory area where SQL Server caches 8 KB data and index pages. Queries read pages from the buffer pool (logical reads); if a page isn't there it's read from disk first (physical read). Modified (dirty) pages are written back by checkpoint and the lazy writer. Set max server memory so the buffer pool doesn't starve the OS."},{"kind":"question","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"565","title":"Latch vs lock?","body":"Locks protect logical data consistency between transactions (rows, pages, tables), are held according to isolation level (possibly until commit) and are visible in sys.dm tran locks . Latches are lightweight, short-term internal synchronisation for in-memory structures like buffer pages and aren't controlled by isolation levels. Latch contention ( PAGELATCH ) appears with hot pages such as the last page of an identity key under heavy inserts."},{"kind":"question","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"566","title":"Why can NOLOCK be dangerous?","body":"READ UNCOMMITTED doesn't take shared locks, so a query can read uncommitted data that later rolls back, read the same row twice or miss rows when pages split during an allocation-order scan, and still be blocked by schema locks. It's \"fast but wrong\". Use RCSI or SNAPSHOT for non-blocking consistent reads instead."},{"kind":"question","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"567","title":"When would you use a columnstore index?","body":"For analytical queries scanning and aggregating millions of rows — data warehouse fact tables (clustered columnstore) or real-time reporting on OLTP tables (nonclustered columnstore). Column-wise compressed storage and batch-mode execution dramatically reduce I/O and CPU. Avoid as the only index for workloads of single-row lookups and frequent small updates."},{"kind":"question","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"568","title":"Why does the transaction log keep growing?","body":"Log space can't be reused while something still needs it: in FULL/BULK LOGGED recovery without regular log backups, long-running open transactions, replication or availability-group replicas behind, CDC. Check log reuse wait desc in sys.databases ; schedule log backups, find and end long transactions, and avoid shrinking repeatedly (causes VLF fragmentation)."},{"kind":"question","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"569","title":"A query was fast yesterday and is slow today with no code change. How do you investigate?","body":"Check Query Store for a plan change (regressed query) — often due to a statistics update, parameter sniffing with a different first value, or an index change. Compare old and new plans (estimated vs actual rows, seek vs scan, join types). Quick fix: force the good plan in Query Store; real fix: update statistics, add/adjust a covering index, or rewrite non-SARGable predicates. Also rule out blocking ( LCK M waits) and resource pressure (waits, memory, I/O)."},{"kind":"question","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"570","title":"Users get \"Transaction was deadlocked … chosen as the deadlock victim\". What do you do?","body":"Capture the deadlock graph from the system health Extended Events session, identify the statements, objects and lock types. Typical fixes: access tables in a consistent order, keep transactions short, add indexes so fewer rows are locked (especially on foreign keys and WHERE columns), use UPDLOCK for read-then-write, enable RCSI to remove reader/writer conflicts — and add retry logic for error 1205 in the application."},{"kind":"question","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"571","title":"An insert-heavy table with an IDENTITY clustered key shows PAGELATCH_EX waits under load. Why and how to fix?","body":"All inserts go to the last page of the B-tree, so many threads compete for the latch on that single hot page. Options: OPTIMIZE FOR SEQUENTIAL KEY = ON (2019+), a hash-partitioned table, a different clustering key spreading inserts (with trade-offs like page splits), In-Memory OLTP for extreme rates, or batching inserts."},{"kind":"cheat","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"1","title":"Architecture","body":"Protocol (TDS) → Relational engine (parse, bind, optimise, execute, plan cache) → Storage engine (access methods, buffer pool, locks, log) → SQLOS (schedulers, workers, waits)."},{"kind":"cheat","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"2","title":"Storage","body":"Page 8 KB · extent 64 KB · GAM/SGAM/PFS/IAM · heap (RID) vs clustered B+ tree (rows at leaf) · nonclustered (key + locator) · INCLUDE = covering · good clustered key: narrow, unique, static, increasing."},{"kind":"cheat","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"3","title":"Optimizer","body":"Statistics (200-step histogram) → cardinality estimates → cheapest plan → plan cache · SARGable predicates · parameter sniffing fixes: index, RECOMPILE, OPTIMIZE FOR, Query Store forcing, PSP (2022)."},{"kind":"cheat","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"4","title":"Plans","body":"Right to left · seek vs scan · key lookup · nested loops (small outer) · merge (sorted) · hash (large unsorted, memory) · spills · implicit conversions · estimated vs actual rows."},{"kind":"cheat","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"5","title":"Transactions","body":"WAL + LSN · commit = log hardened · checkpoint · recovery: analysis, redo, undo · ADR · recovery models SIMPLE/FULL/BULK LOGGED · log backups in FULL."},{"kind":"cheat","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"6","title":"Concurrency","body":"Locks S/U/X/intent/schema · escalation ~5,000 locks · latches = internal · isolation RU/RC/RR/SER + RCSI/SNAPSHOT (version store) · deadlock = error 1205 → retry + same access order + short transactions."},{"kind":"cheat","course_slug":"sqlserver-internals","course_title":"SQL Server Internals — How the Database Engine Really Works","ref":"7","title":"Key waits","body":"PAGEIOLATCH (disk reads) · LCK M (blocking) · WRITELOG (log disk) · CXPACKET (parallelism) · SOS SCHEDULER YIELD (CPU) · RESOURCE SEMAPHORE (memory grants) · ASYNC NETWORK IO (client)."},{"kind":"course","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"","title":"ETL & Data Warehousing Concepts","body":"ETL vs ELT, staging, full vs incremental loads, change data capture, slowly changing dimensions, star and snowflake schemas, fact and dimension tables, data quality, error handling, orchestration and modern cloud data platforms. ETL = Extract data from sources, Transform it (clean, validate, conform, aggregate), Load it into a target — usually a data warehouse used for reporting and analytics. ELT = Extract, Load raw data first into a powerful target (cloud warehouse/lakehouse), then Transform inside it with SQL (dbt, Spark, Fabric). Modern cloud platforms favour ELT. ETL ELT --- --- --- Transform where Separate engine (SSIS, Informatica) Inside the target (Synapse, Fabric, Snowflake, Databricks) Raw data kept Often not Yes (data lake \"bronze\" layer) Scale Limited by ETL server Elastic cloud compute Typical tools SSIS, Informatica PowerCenter, Talend, DataStage Azure Data Factory/Fabric pipelines + dbt/Spark, Databricks, Snowflake OLTP vs OLAP: OLTP systems (orders, banking) handle many small transactions, normalised; OLAP systems (warehouses) handle large analytical queries, denormalised star schemas, historical data. Era Milestone --- --- 1970s–80s Batch file processing, COBOL jobs 1990s Bill Inmon (\"father of data warehousing\", top-down, 3NF enterprise DW, 1992) and Ralph Kimball (bottom-up, dimensional modelling , The Data Warehouse Toolkit 1996) 1990s–2000s Commercial ETL tools: Informatica PowerCenter, IBM DataStage, Ab Initio; Microsoft DTS (SQL Server 7/2000) 2005 SSIS replaces DTS in SQL Server 2005 2010s Hadoop, data lakes, Spark (2014); Azure Data Factory (2015, v2 2018) 2016–2020 Cloud warehouses (Snowflake, BigQuery, Synapse), ELT + dbt (2016), Lambda/Kappa streaming architectures 2020s Lakehouse (Delta Lake, Databricks), medallion architecture (bronze/silver/gold), Microsoft Fabric (GA Nov 2023), data mesh, real-time streaming (Kafka, Event Hubs) ETL process lifecycle: 1. Requirements — business questions, KPIs, sources, refresh frequency (SLA), history needs. 2. Source analysis / profiling — volumes, keys, data quality, how changes can be detected. 3. Design — target model (star schema), staging area, mappings (source-to-target document), load strategy (full/incremental), SCD types, error handling. 4. Build — packages/pipelines, transformations, lookups, logging. 5. Test — row counts, reconciliation with source, data quality checks, performance, rerun/idempotency. 6. Deploy — dev → test → prod (SSIS catalog, ADF CI/CD), with environment-specific parameters. 7. Schedule & orchestrate — SQL Agent, ADF triggers, Airflow; dependencies between jobs. 8. Monitor & support — alerts on failure, SLA tracking, audit tables, reprocessing failed batches. 9. Maintain — schema changes in sources, performance tuning, archiving. Data flow per run: Source → Extract (full or delta) → Staging (raw copy, truncated each run) → Transform (cleanse, standardise, deduplicate, lookup surrogate keys, apply business rules, SCD logic) → Load dimensions first → Load facts → Audit/log → Reconcile . Category Tools --- --- Microsoft on-prem SSIS , SQL Server Agent, T-SQL stored procedures Microsoft cloud Azure Data Factory , Microsoft Fabric (Data Factory pipelines, Dataflows Gen2, Lakehouse, Warehouse), Azure Synapse Analytics, Azure Databricks Enterprise ETL Informatica (IDMC / PowerCenter), IBM DataStage, Talend, Oracle Data Integrator, Ab Initio Open source Apache Airflow (orchestration), Apache Spark, Apache NiFi, Apache Hop, Airbyte, dbt Core Cloud warehouses Snowflake, BigQuery, Amazon Redshift, Fabric Warehouse, Databricks SQL Streaming Kafka, Azure Event Hubs, Azure Stream Analytics, Spark Structured Streaming Data quality Great Expectations, dbt tests, Soda Reporting on top Power BI, SSRS, Tableau"},{"kind":"lesson","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"what-etl-is-and-why-it-is-needed","title":"What ETL is and why it is needed","body":"Operational systems store data for running the business; they are not designed for analysis: - Data is spread across systems (ERP, CRM, Excel, APIs) with different formats and keys. - Running heavy reports on OLTP databases slows down the business. - History is overwritten in OLTP (customer moves city — old city lost). ETL creates a single, clean, integrated, historical copy optimised for analysis. [ERP SQL Server] ─┐ [CRM API] ─┼─ Extract ─► Staging ─► Transform ─► Data Warehouse (star schema) ─► Power BI / SSRS [Excel / CSV] ─┘ ▲ logs, audit, error tables"},{"kind":"lesson","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"full-load-vs-incremental-delta-load","title":"Full load vs incremental (delta) load","body":"Full load Incremental load --- --- --- What Reload everything each run Only new/changed rows since last run Simple? Very Needs change detection Volume/time Grows with data Small and fast Deletes Handled naturally (truncate + load) Must be detected separately Use Small tables, initial load, dimensions with no change tracking Large/fast-growing tables Change detection techniques: 1. Watermark column — ModifiedDate @LastLoadTime (store the high-water mark in a control table). 2. Rowversion/timestamp column. 3. Change Data Capture (CDC) — SQL Server reads the transaction log into change tables (inserts/updates/deletes with before/after values). 4. Change Tracking — lightweight: which rows changed (not the values). 5. Hash comparison — compare a hash (e.g. HASHBYTES('SHA2 256', ...) ) of columns between source and target. 6. Triggers writing to audit tables (adds OLTP overhead). sql -- Watermark pattern DECLARE @Last DATETIME2 = (SELECT LastLoaded FROM etl.Watermark WHERE TableName = 'Orders'); DECLARE @Now DATETIME2 = SYSUTCDATETIME(); INSERT INTO stg.Orders SELECT FROM src.Orders WHERE ModifiedAt @Last AND ModifiedAt <= @Now; -- transform + load ... UPDATE etl.Watermark SET LastLoaded = @Now WHERE TableName = 'Orders'; -- only after success"},{"kind":"lesson","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"staging-area-and-the-medallion-architecture","title":"Staging area and the medallion architecture","body":"Staging = a landing zone holding raw extracted data, usually truncated and reloaded each run. Benefits: decouples extraction from transformation, reduces load on sources (extract once), allows reprocessing, simplifies debugging and reconciliation. Medallion architecture (lakehouse): Layer Content --- --- Bronze Raw data as ingested (append-only, full history) Silver Cleaned, deduplicated, conformed, validated Gold Business-level aggregates and star schemas for reporting"},{"kind":"lesson","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"common-transformations","title":"Common transformations","body":"- Cleansing — trim, fix case, standardise formats (dates, phone numbers), handle NULLs/defaults. - Validation — reject or flag rows breaking rules (missing keys, invalid dates). - Deduplication — ROW NUMBER() OVER (PARTITION BY businessKey ORDER BY ModifiedAt DESC) . - Lookups — map business keys to surrogate keys of dimensions. - Derivations — calculated columns (Margin = Revenue − Cost). - Data type conversion — string → date/decimal (with error handling). - Aggregation , pivot/unpivot , split/merge columns, joins/merges across sources. - Conforming — same meaning and codes across sources (e.g. Gender 'M'/'Male'/1 → 'M')."},{"kind":"lesson","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"facts-dimensions-star-and-snowflake-schemas","title":"Facts, dimensions, star and snowflake schemas","body":"- Fact table — numeric, measurable events (sales amount, quantity) at a defined grain , with foreign keys to dimensions. Usually long and narrow. - Dimension table — descriptive context (who, what, where, when): Customer, Product, Date, Store. Wide, with attributes for filtering and grouping. - Star schema — fact in the middle, denormalised dimensions around it (one join per dimension) → simple and fast. - Snowflake schema — dimensions normalised into sub-dimensions (Product → Subcategory → Category) → less redundancy, more joins. - Galaxy / fact constellation — multiple facts sharing conformed dimensions (e.g. DimDate, DimCustomer used by FactSales and FactReturns). sql CREATE TABLE dw.DimDate (DateKey INT PRIMARY KEY, FullDate DATE, [Month] TINYINT, MonthName VARCHAR(10), [Quarter] TINYINT, [Year] SMALLINT, IsWeekend BIT); CREATE TABLE dw.DimProduct (ProductKey INT IDENTITY PRIMARY KEY, ProductId VARCHAR(20), Name NVARCHAR(100), Category NVARCHAR(50)); CREATE TABLE dw.DimCustomer (CustomerKey INT IDENTITY PRIMARY KEY, CustomerId VARCHAR(20), Name NVARCHAR(100), City NVARCHAR(50), ValidFrom DATE, ValidTo DATE, IsCurrent BIT); CREATE TABLE dw.FactSales ( DateKey INT REFERENCES dw.DimDate, ProductKey INT REFERENCES dw.DimProduct, CustomerKey INT REFERENCES dw.DimCustomer, OrderNumber VARCHAR(20), -- degenerate dimension Quantity INT, SalesAmount DECIMAL(18,2), CostAmount DECIMAL(18,2));"},{"kind":"lesson","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"types-of-facts-and-dimensions","title":"Types of facts and dimensions","body":"Fact types: Type Grain Example --- --- --- Transaction One row per event Each sale line Periodic snapshot One row per entity per period Daily account balance, month-end inventory Accumulating snapshot One row per process instance, updated as milestones happen Order: ordered → shipped → delivered dates Factless Events with no measures Student attendance, promotion coverage Measures: additive (sum across all dimensions: amount), semi-additive (not across time: balance, inventory), non-additive (ratios, percentages — store components instead). Dimension types: conformed (shared), role-playing (DimDate as OrderDate/ShipDate), junk (low-cardinality flags combined), degenerate (order number stored in the fact), slowly changing (see next lesson), outrigger (dimension referencing another). Surrogate key — meaningless integer key generated in the warehouse; isolates from source key changes, enables SCD Type 2 history, makes joins faster. Natural/business key — the source system's ID, kept as an attribute."},{"kind":"lesson","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"slowly-changing-dimensions-scd","title":"Slowly Changing Dimensions (SCD)","body":"Type Behaviour Example --- --- --- Type 0 Never changes (retain original) Date of birth Type 1 Overwrite — no history Fix a spelling mistake Type 2 New row per change with ValidFrom/ValidTo/IsCurrent — full history Customer moves city; past sales stay with old city Type 3 Extra column for previous value — limited history CurrentRegion, PreviousRegion Type 4 History in a separate table Mini-dimension for rapidly changing attributes Type 6 1 + 2 + 3 hybrid Current value on every historical row + full history sql -- SCD Type 2 with T-SQL (expire changed rows, then insert new versions) UPDATE d SET d.ValidTo = CAST(GETDATE() AS DATE), d.IsCurrent = 0 FROM dw.DimCustomer d JOIN stg.Customer s ON s.CustomerId = d.CustomerId WHERE d.IsCurrent = 1 AND (d.City < s.City OR d.Name < s.Name); INSERT INTO dw.DimCustomer (CustomerId, Name, City, ValidFrom, ValidTo, IsCurrent) SELECT s.CustomerId, s.Name, s.City, CAST(GETDATE() AS DATE), '9999-12-31', 1 FROM stg.Customer s LEFT JOIN dw.DimCustomer d ON d.CustomerId = s.CustomerId AND d.IsCurrent = 1 WHERE d.CustomerKey IS NULL; -- new customers + customers whose current row was just expired Fact loads must look up the surrogate key valid at the transaction date (or the current row for new facts)."},{"kind":"lesson","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"inmon-vs-kimball-data-marts-data-lakes-and-lakehouses","title":"Inmon vs Kimball, data marts, data lakes and lakehouses","body":"- Inmon (top-down) — build a normalised enterprise data warehouse (3NF) first, then dependent data marts. - Kimball (bottom-up) — build dimensional data marts per business process with conformed dimensions (the \"bus matrix\") — together they form the warehouse. - Data mart — subject-specific subset (Sales mart, Finance mart). - Data lake — cheap storage of raw data in any format (files: Parquet, CSV, JSON) — schema-on-read. - Lakehouse — data lake + warehouse features (ACID tables via Delta/Iceberg, SQL, governance) — e.g. Databricks, Microsoft Fabric OneLake. - Data Vault 2.0 — hubs (business keys), links (relationships), satellites (attributes with history); agile, auditable raw warehouse layer."},{"kind":"lesson","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"error-handling-logging-auditing-and-restartability","title":"Error handling, logging, auditing and restartability","body":"- Audit table per run: BatchId, Package/Pipeline, StartTime, EndTime, Status, RowsExtracted, RowsInserted, RowsUpdated, RowsRejected, ErrorMessage. - Error rows redirected to error tables with the reason (instead of failing the whole load). - Idempotency — rerunning the same batch gives the same result (truncate-and-reload staging; MERGE/upsert; delete batch by BatchId before reload). - Restartability / checkpoints — resume from the failed step (SSIS checkpoints, ADF rerun from failed activity). - Transactions — wrap dimension/fact loads so partial loads don't remain, or use batch-level delete-and-reload. - Alerts — email/Teams on failure; SLA monitoring. - Reconciliation — compare row counts and sums (e.g. total sales) between source and target."},{"kind":"lesson","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"data-quality","title":"Data quality","body":"Dimensions of data quality: accuracy, completeness, consistency, timeliness, validity, uniqueness . Checks to automate: - Not-null and allowed-value checks on key columns. - Referential integrity: every fact has a matching dimension member (use an \"Unknown\" member, key −1, for late or missing dimensions — late-arriving dimensions ). - Duplicate business keys. - Range checks (no negative quantities, dates not in the future). - Row count / total amount reconciliation against the source. - Freshness (data loaded within SLA). sql -- Unknown member pattern INSERT INTO dw.DimCustomer (CustomerKey, CustomerId, Name, City, ValidFrom, ValidTo, IsCurrent) VALUES (-1, 'UNKNOWN', 'Unknown', 'Unknown', '1900-01-01', '9999-12-31', 1); -- with IDENTITY INSERT ON"},{"kind":"lesson","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"performance-of-large-loads","title":"Performance of large loads","body":"- Extract only needed columns and only changed rows (incremental/CDC). - Bulk load (SSIS fast load, SqlBulkCopy , BULK INSERT , PolyBase/COPY INTO in cloud warehouses) with batch sizes and TABLOCK for minimal logging. - Drop/disable non-clustered indexes before huge loads and rebuild after (or load into an empty partition and switch in). - Set-based SQL instead of row-by-row (avoid cursors, OLE DB Command per row). - Parallelism — load independent tables concurrently. - Partitioning of large facts (by date) for fast loads/archival. - Push transformations to where data lives (ELT) when the target is powerful. - Avoid blocking transformations (sort, aggregate) on huge flows in SSIS; sort in the source query instead."},{"kind":"lesson","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"orchestration-and-scheduling","title":"Orchestration and scheduling","body":"- SQL Server Agent — schedules SSIS packages/T-SQL jobs on-prem, with steps, retries and notifications. - Azure Data Factory / Fabric pipelines — triggers (schedule, tumbling window, storage event), activities (Copy, Data Flow, Stored Procedure, Notebook), dependencies, parameters, integration runtimes (Azure, self-hosted for on-prem sources, Azure-SSIS IR to run SSIS packages in the cloud). - Apache Airflow — DAGs in Python. - Design for dependencies (dimensions before facts), retries with backoff, timeouts, and alerting."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"572","title":"What is ETL? Explain each step.","body":"ETL is the process of moving data from source systems into a target (usually a data warehouse). Extract : read data from databases, files, APIs — full or incremental. Transform : cleanse, validate, standardise, deduplicate, look up surrogate keys, apply business rules, aggregate. Load : write into dimension and fact tables (inserts, updates, SCD handling), then log and reconcile. Goal: consistent, integrated, historical data for reporting."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"573","title":"What is the difference between ETL and ELT?","body":"ETL transforms data in a separate engine before loading (SSIS, Informatica), good when the target is limited or data must be cleaned before landing. ELT loads raw data into a scalable target first and transforms it there with SQL/Spark (Synapse, Fabric, Snowflake, Databricks + dbt), keeping raw history and using elastic compute. Modern cloud architectures mostly use ELT with a medallion design."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"574","title":"What is a data warehouse? How is it different from an OLTP database?","body":"A data warehouse is a subject-oriented, integrated, time-variant, non-volatile store of data for analysis (Inmon's definition). OLTP databases serve day-to-day transactions: many small reads/writes, normalised, current data. Warehouses serve analytical queries over large volumes: denormalised star schemas, history, bulk loads, read-optimised (columnstore). Running analytics on OLTP harms the business application."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"575","title":"What are fact and dimension tables?","body":"Fact tables store measurable business events (quantity, amount) at a defined grain plus foreign keys to dimensions. Dimension tables store descriptive attributes (customer name, city; product category; date parts) used to filter and group facts. Example: FactSales(DateKey, ProductKey, CustomerKey, Qty, Amount) with DimDate, DimProduct, DimCustomer."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"576","title":"What is the difference between a star schema and a snowflake schema?","body":"In a star schema, each dimension is a single denormalised table directly joined to the fact — fewer joins, faster and simpler for BI tools. In a snowflake schema, dimensions are normalised into multiple related tables (Product → Subcategory → Category) — less redundancy but more joins and complexity. Kimball recommends star schemas; Power BI performs best with them."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"577","title":"What is a staging area and why use it?","body":"A temporary storage layer where extracted raw data lands before transformation. It minimises the time and load on source systems, allows transformations and validations with SQL, supports reruns without re-extracting, helps debugging and reconciliation, and decouples source availability from the warehouse load schedule. Usually truncated and reloaded each run (or kept as bronze history in lakehouses)."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"578","title":"Explain Slowly Changing Dimensions Types 1, 2 and 3.","body":"They control how dimension attribute changes are stored. Type 1 overwrites the old value (no history — corrections). Type 2 inserts a new row with a new surrogate key and validity columns (ValidFrom, ValidTo, IsCurrent), preserving full history so old facts keep pointing to the old version. Type 3 adds a column for the previous value (only one level of history). Type 0 never changes; Type 6 combines 1, 2 and 3."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"579","title":"What is a surrogate key and why use it in a warehouse?","body":"A system-generated integer key (IDENTITY/sequence) used as the dimension's primary key instead of the source's natural key. Reasons: integrates multiple sources with overlapping IDs, enables SCD Type 2 (several rows per business key), protects from source key changes/reuse, smaller and faster joins, supports special members like \"Unknown\" (-1)."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"580","title":"How do you implement an incremental load?","body":"Detect changes since the last successful run using a watermark (ModifiedDate/rowversion stored in a control table), CDC or Change Tracking, or hash comparison. Extract only those rows into staging, then upsert into the target (MERGE or UPDATE + INSERT; SCD logic for dimensions), handle deletes (soft-delete flags, CDC delete records, or periodic full compare), and update the watermark only after the load succeeds so failures don't skip data."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"581","title":"How do you handle errors and bad data in ETL?","body":"Validate early; redirect bad rows to error tables with the reason instead of failing the whole batch (unless the threshold is exceeded); use an \"Unknown\" dimension member for missing lookups (late-arriving dimensions) and fix later; log every run in an audit table (counts, durations, status); send alerts; make loads idempotent and restartable; reconcile counts and totals with the source; keep raw data for reprocessing."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"582","title":"What is the grain of a fact table and why is it important?","body":"The grain is what one row represents (one order line, one customer per day, one account per month-end). It must be declared before choosing dimensions and measures. Mixing grains causes double counting. The most atomic grain gives the most flexibility; aggregates can be built on top."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"583","title":"What are additive, semi-additive and non-additive measures?","body":"Additive measures can be summed across all dimensions (sales amount, quantity). Semi-additive can be summed across some dimensions but not time (account balance, inventory level — use last/average over time). Non-additive can't be summed at all (ratios, percentages, unit price) — store numerator and denominator and calculate in the report."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"584","title":"What is CDC (Change Data Capture)?","body":"A SQL Server feature (also in Azure SQL and other databases) that reads the transaction log asynchronously and records inserts, updates and deletes with column values into change tables ( cdc.<schema <table CT ), queried via cdc.fn cdc get all changes ... using LSN ranges. ETL reads only changes — including deletes — with low impact on the source. Change Tracking is lighter: it records which rows changed, not the values."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"585","title":"Inmon vs Kimball — which approach would you choose?","body":"Inmon builds a normalised enterprise DW first (top-down) — consistent, but long time-to-value. Kimball builds dimensional data marts per business process using conformed dimensions (bottom-up) — faster delivery and BI-friendly. Many organisations use a hybrid: a raw/normalised (or Data Vault) integration layer with Kimball star schemas for presentation — similar to the medallion bronze/silver/gold pattern."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"586","title":"What is a late-arriving dimension (early-arriving fact) and how do you handle it?","body":"A fact arrives referencing a dimension member that doesn't exist yet (e.g. sale for a new customer not yet loaded from CRM). Options: assign the \"Unknown\" member (-1) and update the fact later; or insert an inferred member (placeholder row with just the business key) and update its attributes when the real dimension data arrives (SSIS SCD wizard supports inferred members)."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"587","title":"The nightly ETL that used to take 1 hour now takes 5 hours and misses the SLA. How do you troubleshoot?","body":"Find which step slowed (audit log durations per task). Check data volume growth (switch full loads to incremental), source query plans and missing indexes, blocking on target tables during loads, row-by-row operations (OLE DB Command, cursors, SCD wizard on big dimensions → replace with set-based MERGE), blocking SSIS transformations (sort/aggregate), lookups in full-cache mode with huge reference tables, index maintenance on targets (disable/rebuild), log growth, server resources (memory, tempdb), and parallelism between independent loads."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"588","title":"Business reports show sales totals 3% higher than the ERP. How do you find the cause?","body":"Reconcile step by step: compare counts and sums source → staging → warehouse for the same period and filters. Typical causes: duplicate extraction (overlapping incremental windows, reruns without idempotency), join fan-out (fact joined to a dimension with duplicate business keys, SCD2 lookup not restricted to the valid row), different business rules (cancelled orders, returns, tax/currency, time zones/cut-off), late-arriving corrections not applied. Fix the logic, add automated reconciliation checks and uniqueness tests."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"589","title":"Design an ETL for daily sales from 50 store databases into a central warehouse.","body":"Parameterised pipeline looped over a store config table (ADF ForEach or SSIS Foreach with a project parameter for the connection). Incremental extract per store using a watermark/CDC into a staging table tagged with StoreId and BatchId. Transform centrally: conform codes, dedupe, look up surrogate keys (DimStore, DimProduct, DimDate, DimCustomer with SCD2). Load dimensions then FactSales (partitioned by date). Audit table per store per run, error rows redirected, alerts for stores that failed, rerun only failed stores. Schedule after stores close; monitor SLA."},{"kind":"question","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"590","title":"How do you test an ETL pipeline?","body":"Unit-test transformations (sample inputs → expected outputs), validate mappings against the source-to-target document, test row counts and sums (reconciliation), null/duplicate/RI checks, SCD behaviour (insert, change, no-change cases), incremental logic (no duplicates on rerun, late changes captured, deletes handled), error handling (bad rows go to error tables), performance with production-like volumes, and restart/idempotency. Automate with tSQLt, dbt tests or Great Expectations in CI."},{"kind":"cheat","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"1","title":"ETL vs ELT","body":"ETL: transform before load (SSIS). ELT: load raw, transform in the warehouse (ADF/Fabric + SQL/dbt/Spark)."},{"kind":"cheat","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"2","title":"Load types","body":"Full (truncate + reload) · Incremental (watermark, rowversion, CDC, Change Tracking, hash) · Upsert (MERGE) · Deletes (soft delete, CDC, full compare)."},{"kind":"cheat","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"3","title":"Dimensional model","body":"Fact (measures at a grain) + Dimensions (descriptive) · Star (denormalised) vs Snowflake (normalised dims) · Surrogate keys · Conformed, role-playing, junk, degenerate dimensions."},{"kind":"cheat","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"4","title":"Fact types","body":"Transaction · Periodic snapshot · Accumulating snapshot · Factless. Measures: additive, semi-additive, non-additive."},{"kind":"cheat","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"5","title":"SCD","body":"0 keep · 1 overwrite · 2 new row + ValidFrom/ValidTo/IsCurrent · 3 previous-value column · 4 history table · 6 hybrid."},{"kind":"cheat","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"6","title":"Reliability","body":"Staging · audit table · error tables · Unknown member (-1) · idempotent reruns · watermark updated after success · reconciliation counts/sums · alerts."},{"kind":"cheat","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"7","title":"Architectures","body":"Inmon (top-down 3NF) · Kimball (bottom-up stars) · Data Vault (hubs/links/satellites) · Data lake · Lakehouse · Medallion bronze → silver → gold."},{"kind":"cheat","course_slug":"etl","course_title":"ETL & Data Warehousing Concepts","ref":"8","title":"Tools","body":"SSIS · ADF · Fabric · Synapse · Databricks · Informatica · Talend · Airflow · dbt · Spark · Kafka."},{"kind":"course","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"","title":"SSIS — SQL Server Integration Services","body":"Packages, control flow and data flow, connection managers, variables and parameters, containers, transformations, lookups, SCD, error handling, logging, checkpoints, deployment models, SSISDB catalog, scheduling and performance tuning. SSIS (SQL Server Integration Services) is Microsoft's ETL and workflow platform, part of SQL Server. You build packages ( .dtsx XML files) visually in Visual Studio, then deploy them to the SSIS Catalog (SSISDB) and run them with SQL Server Agent. A package has two main designers: - Control Flow — the workflow: tasks (Execute SQL, Data Flow, File System, Script, Send Mail...) connected by precedence constraints , grouped in containers (Sequence, For Loop, Foreach Loop). - Data Flow — the row pipeline inside a Data Flow Task: sources → transformations → destinations , processed in memory buffers. Typical uses: loading data warehouses, migrating data, importing/exporting files, cleansing data, automating database maintenance. Release Notes --- --- DTS (SQL Server 7.0 / 2000) Data Transformation Services — predecessor SSIS 2005 First SSIS: control flow/data flow split, BIDS (Business Intelligence Development Studio) SSIS 2008 / R2 Improved Lookup (cache), pipeline performance, C scripts SSIS 2012 Project deployment model, SSISDB catalog, parameters, environments , SSDT replaces BIDS, ODBC, Change Data Capture components SSIS 2014–2019 Incremental improvements; Scale Out (2017); Linux runtime (2017); Azure Feature Pack; packages run in Azure via Azure-SSIS Integration Runtime in Azure Data Factory (2017) SSIS 2022 Supported with SQL Server 2022; Visual Studio 2022 \"SQL Server Integration Services Projects\" extension SSIS 2025 Ships with SQL Server 2025. SSIS is still supported, but Microsoft's strategic cloud direction is Azure Data Factory / Microsoft Fabric Data Factory. Some legacy features are marked deprecated, so check the official \"What's new in Integration Services\" page before relying on older components Design-time tooling has moved from BIDS (2005–2008 R2) → SSDT (2012–2017) → the \"SQL Server Integration Services Projects\" extension for Visual Studio 2019/2022/2026. Package development lifecycle: requirements → design (source-to-target mapping) → develop in Visual Studio (SSIS project) → debug with data viewers/breakpoints → configure parameters → build ( .ispac ) → deploy to SSISDB (dev → test → prod) → configure environments per server → schedule with SQL Agent → monitor via SSISDB reports → maintain. Package execution lifecycle: 1. Package loads; validation of tasks and connections (can be delayed with DelayValidation=True ). 2. Parameters/variables are set (from environment references, /SET options, or expressions). 3. OnPreExecute events fire; Control Flow executes tasks in order determined by precedence constraints (Success/Failure/Completion, optionally with expressions). 4. For each Data Flow Task : the pipeline engine allocates buffers, sources read rows, transformations process buffers, destinations write; error outputs redirect bad rows. 5. Event handlers (OnError, OnWarning, OnPostExecute, OnTaskFailed...) run when events bubble up. 6. Logging writes to SSISDB catalog views (or log providers). 7. Checkpoints (if enabled) record completed tasks so a restart resumes after the failure point. 8. Package completes with Success/Failure result. Data flow buffer lifecycle: source fills a buffer (default DefaultBufferMaxRows 10,000 rows / DefaultBufferSize 10 MB) → synchronous transformations modify the same buffer in place → asynchronous transformations copy rows into new buffers → destination writes the buffer → buffer reused. Tool Use --- --- Visual Studio 2022/2026 + SQL Server Integration Services Projects extension Design, debug, build packages SSMS → Integration Services Catalogs (SSISDB) Deploy, configure environments, run, view reports SQL Server Agent Schedule packages dtexec / dtutil / ISDeploymentWizard Command-line execution, package management, deployment Azure Data Factory + Azure-SSIS IR Lift-and-shift SSIS packages to Azure BIML (Business Intelligence Markup Language) Generate many packages from metadata Third-party components KingswaySoft, COZYROC, Task Factory (extra connectors) Integration Services Deployment Wizard / DevOps tasks CI/CD of .ispac"},{"kind":"lesson","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"package-anatomy-control-flow-vs-data-flow","title":"Package anatomy: control flow vs data flow","body":"Control Flow Data Flow --- --- Workflow of tasks Row-by-row pipeline inside one Data Flow Task Elements: tasks, containers, precedence constraints Elements: sources, transformations, destinations, paths Runs tasks one after another (or in parallel) Streams data through memory buffers Handles files, SQL commands, emails, loops Extracts, transforms, loads rows Common Control Flow tasks : Execute SQL Task, Data Flow Task, Execute Package Task, File System Task, FTP Task, Script Task (C ), Send Mail Task, Expression Task, Bulk Insert Task, Execute Process Task, Web Service Task, XML Task, CDC Control Task, Analysis Services Processing Task, maintenance plan tasks. Containers : Sequence (group tasks, scope variables, shared transactions), For Loop (counter-based), Foreach Loop (enumerators: File, ADO recordset, Item, Variable, SMO, Azure Blob...), and the implicit Task Host around each task."},{"kind":"lesson","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"connection-managers","title":"Connection managers","body":"Connection managers define how to connect; tasks and components reference them. - OLE DB (SQL Server via Microsoft OLE DB Driver for SQL Server — MSOLEDBSQL), ADO.NET , ODBC - Flat File (CSV, fixed width), Excel , Multiple Flat Files , Raw File - FTP , HTTP , SMTP , File , Cache (for lookups), Azure Storage / Data Lake (Azure Feature Pack) Project-level connection managers are shared by all packages in the project. Make connection strings configurable with parameters + expressions so the same package runs in dev/test/prod."},{"kind":"lesson","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"variables-parameters-and-expressions","title":"Variables, parameters and expressions","body":"Variables Parameters (2012+) --- --- --- Scope Package, container or task Package or project Change at runtime Yes, by tasks/scripts Read-only during execution; set before execution Use Store values between tasks (row counts, file names, result sets) Pass external values in (server names, folders, dates) Set from Execute SQL results, Script Task, expressions SSISDB environments, dtexec /Par , Agent job Expressions (SSIS expression language, C-like) make properties dynamic: @[User::FilePath] + \"\\\\Sales \" + (DT WSTR, 8) (YEAR(GETDATE()) 10000 + MONTH(GETDATE()) 100 + DAY(GETDATE())) + \".csv\" \"SELECT FROM dbo.Orders WHERE ModifiedAt '\" + (DT WSTR, 30) @[User::LastLoad] + \"'\" @[$Project::ServerName] -- project parameter ISNULL(Discount) ? 0 : Discount -- in Derived Column System variables: System::PackageName , System::StartTime , System::ExecutionInstanceGUID , System::ErrorDescription (in event handlers)."},{"kind":"lesson","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"precedence-constraints","title":"Precedence constraints","body":"Arrows between tasks that decide what runs next: - Success (green), Failure (red), Completion (blue — either way). - Expression or Expression and Constraint — e.g. run only if @[User::RowCount] 0 . - Multiple incoming constraints: Logical AND (all must be satisfied — default) or Logical OR (any one)."},{"kind":"lesson","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"sources-and-destinations","title":"Sources and destinations","body":"- Sources : OLE DB Source (table, SQL command, SQL command from variable), ADO.NET Source, Flat File Source, Excel Source, XML Source, Raw File Source, ODBC Source, CDC Source. - Destinations : OLE DB Destination ( Table or view – fast load uses bulk insert: set Rows per batch, Maximum insert commit size, Table lock, Check constraints), SQL Server Destination (local server only), Flat File, Excel, Raw File, ADO.NET, ODBC, Recordset Destination (to an object variable). Prefer a SQL command in sources that selects only needed columns and filters/sorts on the server, rather than \"Table or view\"."},{"kind":"lesson","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"transformations-and-their-types","title":"Transformations and their types","body":"Transformation Purpose Blocking type --- --- --- Derived Column New/replace column via expression Non-blocking (synchronous) Data Conversion Convert data types (e.g. DT STR → DT WSTR) Non-blocking Conditional Split Route rows by conditions (like CASE) Non-blocking Multicast Send all rows to many outputs Non-blocking Lookup Match against reference data Non-blocking (synchronous) Row Count Count rows into a variable Non-blocking Copy Column, Character Map, Audit Simple row operations Non-blocking OLE DB Command Run SQL per row (slow!) Non-blocking but row-by-row Script Component Custom C (source, transformation or destination) Depends Merge, Merge Join, Union All Combine inputs (Merge/Merge Join need sorted input) Semi-blocking Pivot / Unpivot Reshape columns/rows Semi-blocking Sort Sort rows (optionally remove duplicates) Fully blocking Aggregate GROUP BY, SUM, COUNT... Fully blocking Fuzzy Lookup / Fuzzy Grouping Approximate matching, dedup Fully blocking Slowly Changing Dimension SCD wizard (types 0, 1, 2) Row-by-row Percentage/Row Sampling, Term Extraction Sampling/text mining Varies Synchronous (non-blocking): output rows = input rows, same buffer, fastest. Asynchronous : new buffers; semi-blocking passes some rows before all input is read; fully blocking must read all input before output (Sort, Aggregate) → memory heavy."},{"kind":"lesson","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"lookup-transformation-and-cache-modes","title":"Lookup transformation and cache modes","body":"Lookup matches each input row against a reference dataset (e.g. get CustomerKey from DimCustomer by CustomerId ). Cache mode How When --- --- --- Full cache (default) Loads the entire reference query into memory before rows flow Reference fits in memory — fastest Partial cache Queries DB on cache miss, caches results Large reference, few distinct keys used No cache Queries DB for every row Reference changes during the load; tiny inputs Cache Connection Manager Cache built once (Cache Transform), reused by several lookups/packages Same reference used many times Outputs: Match , No Match (configure \"Redirect rows to no match output\" — e.g. to insert new dimension members), Error . Lookups are case-sensitive and type-sensitive in full cache mode — trim/upper both sides. Use a SQL query selecting only key + needed columns."},{"kind":"lesson","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"implementing-incremental-loads-and-scd-in-ssis","title":"Implementing incremental loads and SCD in SSIS","body":"Pattern 1: Lookup-based upsert OLE DB Source (changed rows since watermark) → Lookup on target by business key ├─ No Match → OLE DB Destination (fast load INSERT) └─ Match → Conditional Split (columns changed?) → OLE DB Destination to a staging \"updates\" table Execute SQL Task after the data flow: UPDATE target FROM staging updates (set-based) Pattern 2: Load staging, then MERGE — Data Flow loads staging; an Execute SQL Task runs a T-SQL MERGE or SCD2 statements. Usually the fastest and simplest for large volumes. SCD wizard — quick to configure (Fixed = Type 0, Changing = Type 1, Historical = Type 2, inferred members) but uses OLE DB Command per row → slow on big dimensions; replace with set-based SQL in production. Watermark — Execute SQL Task reads LastLoaded into a variable → source query uses it → final Execute SQL updates it on success. Or use CDC Control Task + CDC Source + CDC Splitter (2012+) with SQL Server CDC."},{"kind":"lesson","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"error-outputs-event-handlers-and-logging","title":"Error outputs, event handlers and logging","body":"- Data flow error outputs per component: Fail component (default), Ignore failure , or Redirect row — send bad rows (conversion errors, truncation) to an error table with ErrorCode and ErrorColumn (use GetErrorDescription in a Script Component to get the text). - Event handlers at package/container/task level: OnError (log error, send mail), OnPreExecute / OnPostExecute (audit timings), OnTaskFailed , OnWarning , OnVariableValueChanged . Use System::Propagate = False in a handler to stop an error bubbling up. - MaximumErrorCount — how many errors before the container fails (default 1). - Logging : in the project deployment model, SSISDB logs automatically at the chosen logging level (None, Basic — default, Performance, Verbose, RuntimeLineage, custom). Legacy log providers: SQL Server table ( sysssislog ), text file, Windows Event Log, XML. - Built-in SSMS reports: \"All Executions\", \"Execution Performance\", per-message details; catalog views catalog.executions , catalog.event messages , catalog.execution data statistics ."},{"kind":"lesson","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"checkpoints-and-transactions","title":"Checkpoints and transactions","body":"Checkpoints let a failed package restart from the failed task instead of the beginning: - Package properties: CheckpointFileName , CheckpointUsage = IfExists , SaveCheckpoints = True . - Each task to be a restart point: FailPackageOnFailure = True . - Data flow tasks restart from the beginning of that data flow (not mid-flow) — design them to be idempotent (truncate staging first). - Not supported well with Foreach Loops (the whole loop reruns) and don't combine checkpoints with transactions casually. Transactions : TransactionOption property — Required (start or join), Supported (join if exists — default), NotSupported . SSIS transactions use MSDTC (distributed) which must be running and configured. Alternative: native SQL transactions with Execute SQL Tasks ( BEGIN TRAN / COMMIT ) on a connection manager with RetainSameConnection = True ."},{"kind":"lesson","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"project-vs-package-deployment-model-and-ssisdb","title":"Project vs package deployment model and SSISDB","body":"Package deployment (legacy) Project deployment (2012+) --- --- --- Unit Individual .dtsx Whole project .ispac Stored File system or msdb SSISDB catalog Configuration Package configurations (XML, SQL table, env vars) Parameters + environments Logging Log providers you configure Automatic catalog logging + reports Versioning Manual Catalog keeps project versions; rollback SSISDB catalog workflow: 1. Create the catalog (SSMS → Integration Services Catalogs → Create Catalog; needs CLR enabled and a password for the encryption key). 2. Create a folder , deploy the .ispac (Deployment Wizard, SSMS, ISDeploymentWizard.exe , Azure DevOps task). 3. Create environments (DEV/QA/PROD) with variables (server name, file paths; sensitive values encrypted). 4. Add an environment reference to the project and map parameters to environment variables. 5. Execute via SSMS, catalog.create execution + catalog.start execution stored procedures, or a SQL Agent job step (type SQL Server Integration Services Package , select environment). sql DECLARE @exec id BIGINT; EXEC SSISDB.catalog.create execution @folder name = N'ETL', @project name = N'SalesDW', @package name = N'LoadFactSales.dtsx', @reference id = 1, @execution id = @exec id OUTPUT; EXEC SSISDB.catalog.set execution parameter value @exec id, @object type = 50, @parameter name = N'LOGGING LEVEL', @parameter value = 1; EXEC SSISDB.catalog.start execution @exec id; bat dtexec /ISServer \"\\SSISDB\\ETL\\SalesDW\\LoadFactSales.dtsx\" /Server \"PRODSQL01\" /Env 1 /Par \"$Project::LoadDate\";\"2026-10-20\""},{"kind":"lesson","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"script-task-and-script-component","title":"Script Task and Script Component","body":"- Script Task (Control Flow) — C /VB code for workflow logic: check if a file exists, call an API, move files, set variables ( Dts.Variables[\"User::FileName\"].Value = ... ), set Dts.TaskResult = (int)ScriptResults.Success . - Script Component (Data Flow) — as a source (generate rows from an API/JSON), transformation ( Input0 ProcessInputRow(Input0Buffer Row) to modify rows — e.g. complex regex cleansing), or destination . - Declare ReadOnlyVariables / ReadWriteVariables in the editor before using them. csharp public override void Input0 ProcessInputRow(Input0Buffer Row) { Row.PhoneClean = Regex.Replace(Row.Phone ?? \"\", @\"[^\\d]\", \"\"); if (Row.PhoneClean.Length != 10) Row.IsValid = false; }"},{"kind":"lesson","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"performance-tuning","title":"Performance tuning","body":"1. Source : SQL command with only needed columns, filters and ORDER BY on the server (set IsSorted / SortKeyPosition on the source output instead of a Sort transformation); use NOLOCK only if dirty reads are acceptable. 2. Avoid blocking transformations (Sort, Aggregate, Fuzzy) on big data — push to SQL. 3. Replace OLE DB Command (row-by-row) with staging + set-based UPDATE/MERGE. 4. Lookups : full cache with minimal columns; Cache Connection Manager for reuse. 5. Destination fast load : Table lock, sensible Rows per batch and Maximum insert commit size , disable/drop non-clustered indexes during large loads and rebuild after; check constraints off when safe. 6. Buffers : tune DefaultBufferMaxRows / DefaultBufferSize (or AutoAdjustBufferSize=True 2016+); narrow data types reduce row width = more rows per buffer. 7. Parallelism : MaxConcurrentExecutables (package) and EngineThreads (data flow); split independent loads into parallel tasks/packages. 8. Avoid unnecessary data conversion ; match types to destination early. 9. Run SSIS on/near the SQL Server to reduce network hops; ensure enough memory (buffer spooling to disk = slow — watch \"Buffers spooled\" counter). 10. Incremental loads instead of full reloads."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"591","title":"What is SSIS and what is it used for?","body":"SQL Server Integration Services is Microsoft's ETL and workflow tool shipped with SQL Server. It extracts data from many sources (SQL, Oracle, flat files, Excel, XML, APIs), transforms it in a high-performance in-memory pipeline, and loads it into targets such as data warehouses. Also used for data migration, file automation and database maintenance. Packages are built in Visual Studio and deployed to the SSISDB catalog."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"592","title":"What is the difference between Control Flow and Data Flow?","body":"Control Flow orchestrates the workflow: tasks (Execute SQL, Data Flow, File System, Script, Send Mail), containers and precedence constraints determining execution order. Data Flow is inside a Data Flow Task and moves rows from sources through transformations to destinations in memory buffers. Control Flow deals with tasks; Data Flow deals with rows."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"593","title":"What are the different types of containers?","body":"Sequence Container (groups tasks, scopes variables, shares transactions, lets you enable/disable a group), For Loop Container (repeats while a condition holds — counter-based), Foreach Loop Container (iterates over a collection: files in a folder, rows of an ADO recordset, items, nodes, blobs), and the Task Host container that wraps every single task."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"594","title":"What is a precedence constraint?","body":"A connector between control-flow executables that controls whether the next task runs, based on the outcome of the previous one: Success, Failure or Completion, optionally combined with an expression (e.g. only if @RowCount 0 ). With multiple constraints into one task, choose logical AND (all) or OR (any)."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"595","title":"What is the difference between variables and parameters?","body":"Parameters (introduced in 2012) pass values into a package or project from outside before execution — server names, folders, dates — and are set from SSISDB environments or dtexec . They are read-only during execution. Variables store values during execution (row counts, file names, result sets), can be changed by tasks/scripts, and are scoped to package, container or task."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"596","title":"What is a connection manager?","body":"A reusable object holding connection information (connection string, credentials) for a data source/destination — OLE DB, ADO.NET, Flat File, Excel, FTP, SMTP, Cache, Azure. Tasks and components reference it. Project-level connection managers are shared across packages. Make them dynamic with parameters/expressions for each environment."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"597","title":"What are synchronous and asynchronous transformations? Give examples of blocking transformations.","body":"Synchronous (non-blocking) transformations process rows in the same buffer and output exactly one row per input row — Derived Column, Data Conversion, Conditional Split, Lookup, Multicast, Row Count. Asynchronous transformations create new buffers. Semi-blocking ones (Merge, Merge Join, Union All, Pivot) can output before reading all input; fully blocking ones (Sort, Aggregate, Fuzzy Grouping/Lookup) must read all input first, consuming memory and slowing large flows."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"598","title":"Explain the Lookup transformation cache modes.","body":"Full cache loads the whole reference query into memory before processing (fastest, needs memory, reference must be stable). Partial cache starts empty and queries the database on misses, caching the results (good for large references with few used keys). No cache queries the database for every row (slowest; use when the reference changes during the load). A Cache Connection Manager can pre-build a cache from any source and reuse it across lookups/packages."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"599","title":"How do you handle errors in SSIS?","body":"At row level, configure component error outputs to redirect failing rows (conversion/truncation/lookup no-match) to error tables with ErrorCode/ErrorColumn instead of failing. At task level, use precedence constraints on Failure to run cleanup/notification tasks, event handlers (OnError logs to an audit table and sends email), MaximumErrorCount, and checkpoints for restart. Logging in SSISDB captures messages; SQL Agent alerts on job failure."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"600","title":"How do you implement an incremental load in SSIS?","body":"Store the last successful load watermark (date/rowversion) in a control table; Execute SQL Task reads it into a variable; the source query extracts rows changed since then; Lookup against the target splits new (No Match → insert) vs existing rows (Match → conditional split on changes → staging table → set-based UPDATE); final Execute SQL Task updates the watermark. Alternatives: CDC components, or load staging and run a T-SQL MERGE."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"601","title":"What is the difference between the project and package deployment models?","body":"The package deployment model (legacy) deploys individual .dtsx files to the file system or msdb and uses package configurations. The project deployment model (2012+) deploys the whole project as an .ispac to the SSISDB catalog, uses project/package parameters with environments per server, keeps versions, and provides built-in logging and execution reports. New work should use the project model."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"602","title":"What are checkpoints in SSIS?","body":"A restart mechanism: when enabled (CheckpointFileName, CheckpointUsage=IfExists, SaveCheckpoints=True, and FailPackageOnFailure=True on tasks), SSIS writes completed tasks to a checkpoint file; on rerun after failure it skips completed tasks and resumes from the failed one. Data flows restart from their beginning, so design them idempotently. The file is deleted after a successful run."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"603","title":"Merge vs Merge Join vs Union All?","body":"Union All combines multiple inputs into one without requiring sorted input (like SQL UNION ALL) — preferred. Merge combines exactly two sorted inputs into one sorted output. Merge Join joins two sorted inputs (inner, left outer, full outer) on keys, like a SQL join. Both Merge and Merge Join need sorted inputs — sort in the source queries, not with Sort transformations."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"604","title":"How do you deploy and schedule SSIS packages?","body":"Build the project to an .ispac; deploy to the SSISDB catalog with the Deployment Wizard, SSMS or a CI/CD pipeline (Azure DevOps SSIS deploy task); create environments with server-specific values and map parameters; schedule with a SQL Server Agent job step of type SSIS package referencing the catalog and environment; monitor through SSISDB reports and Agent job history. In Azure, run on an Azure-SSIS Integration Runtime triggered by Azure Data Factory."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"605","title":"How do you improve the performance of a slow SSIS package?","body":"Filter and select only needed columns at the source; sort in SQL and mark outputs as sorted; remove blocking transformations; replace OLE DB Command and SCD wizard with staging + set-based SQL; use full-cache lookups with minimal columns; fast-load destinations with table lock and batch settings; drop/disable indexes during huge loads; tune buffer size/rows (or AutoAdjustBufferSize); run independent flows in parallel (MaxConcurrentExecutables, EngineThreads); avoid unnecessary data conversions; check for buffer spooling and server memory; switch to incremental loads."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"606","title":"What are the SSISDB logging levels?","body":"None, Basic (default — errors, warnings, task start/finish), Performance (performance stats and errors/warnings, less detail), Verbose (all events including data flow component details — heavy), RuntimeLineage (lineage tracking data), plus custom levels (2016+) choosing specific events. Choose Basic for production; Verbose only for troubleshooting. Clean up old logs via the catalog retention settings ( Retention Period )."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"607","title":"How do you run SSIS in the cloud?","body":"Provision an Azure-SSIS Integration Runtime in Azure Data Factory (or Synapse) — a managed cluster of VMs that runs SSIS packages; host SSISDB in Azure SQL Database/Managed Instance or deploy packages to Azure Files; trigger with ADF's Execute SSIS Package activity. Use a self-hosted IR as proxy or VNet join to reach on-prem sources. Longer-term, migrate logic to native ADF/Fabric pipelines and dataflows."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"608","title":"A package that loads 10 million rows nightly suddenly fails with a truncation error on one column. How do you handle it?","body":"Identify the column from the error (ErrorColumn ID → lineage ID/name in the advanced editor or catalog messages). Short term: configure that component's error output to redirect truncated rows to an error table so the rest loads, and alert. Root cause: the source started sending longer values — confirm with data profiling, then widen the staging/target column and the SSIS metadata (refresh external columns), or apply a business rule (trim/substring) agreed with the business. Add a data-quality check that reports length violations."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"609","title":"You need to process every CSV file that lands in a folder, archive successfully processed files and move bad files to an error folder. Design it.","body":"Foreach Loop Container (File enumerator on the inbound folder, .csv , map the file name to a variable). Inside: Flat File connection manager with its ConnectionString set by an expression from the variable; Data Flow (Flat File Source → Data Conversion/validation → error output to an error table → OLE DB Destination fast-load to staging); Execute SQL to merge staging into targets and log the file name/BatchId; File System Task on Success moves the file to Archive (with timestamp), on Failure moves it to Error. Event handler for alerts. Set DelayValidation=True because the file doesn't exist at design validation time."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"610","title":"The same package must run against DEV, QA and PROD servers with different connection strings and file paths. How do you configure it?","body":"Use the project deployment model: create project parameters (ServerName, DatabaseName, InboundFolder) and use them in connection manager expressions; deploy the same .ispac to each server's SSISDB; create an environment per server with variables holding the values (mark passwords as sensitive); reference the environment from the project and map parameters; SQL Agent job steps choose the environment. No package edits between environments."},{"kind":"question","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"611","title":"Your Lookup returns \"No Match\" for values that clearly exist in the reference table. Why?","body":"Full-cache Lookup comparisons are case-sensitive, accent-sensitive and type/whitespace-sensitive (done in SSIS memory, not with the SQL collation). Differences in case, trailing spaces, data type (DT STR vs DT WSTR, int vs bigint) or code page cause misses. Fix: UPPER/TRIM both sides (in the reference query and a Derived Column), convert to identical types, or use partial/no cache so SQL's collation applies."},{"kind":"cheat","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"1","title":"Building blocks","body":"Package (.dtsx) · Project (.ispac) · Control Flow (tasks, containers, precedence constraints) · Data Flow (sources, transformations, destinations) · Connection managers · Variables · Parameters · Event handlers · Log/SSISDB."},{"kind":"cheat","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"2","title":"Key tasks","body":"Execute SQL · Data Flow · Execute Package · File System · FTP · Script · Send Mail · Expression · Bulk Insert · CDC Control."},{"kind":"cheat","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"3","title":"Transformations by blocking type","body":"- Non-blocking: Derived Column, Data Conversion, Conditional Split, Lookup, Multicast, Row Count, Copy Column, Audit. - Semi-blocking: Merge, Merge Join, Union All, Pivot/Unpivot. - Fully blocking: Sort, Aggregate , Fuzzy Lookup/Grouping."},{"kind":"cheat","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"4","title":"Lookup cache","body":"Full (default, fastest) · Partial · No cache · Cache Connection Manager. Case/space/type sensitive."},{"kind":"cheat","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"5","title":"Error handling","body":"Error output: Fail / Ignore / Redirect row · OnError event handler · MaximumErrorCount · Propagate=False · checkpoints · audit table."},{"kind":"cheat","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"6","title":"Deployment","body":"Project model → SSISDB → folder → environments (DEV/QA/PROD) → parameter mapping → SQL Agent job → reports. dtexec /ISServer ... /Env n /Par ... ."},{"kind":"cheat","course_slug":"ssis","course_title":"SSIS — SQL Server Integration Services","ref":"7","title":"Performance","body":"SQL source with filters · no Sort/Aggregate on big data · no OLE DB Command · full-cache lookups · fast load + table lock · buffer tuning · parallel tasks · staging + MERGE · incremental."},{"kind":"course","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"","title":"SSRS — SQL Server Reporting Services","body":"Report server architecture, data sources and datasets, tablix (table/matrix/list), parameters and cascading parameters, expressions, grouping, drill-down and drill-through, subreports, charts, subscriptions, security, performance and Power BI Report Server. SSRS (SQL Server Reporting Services) is Microsoft's server-based platform for paginated reports — pixel-perfect, printable reports (invoices, statements, operational lists) that page nicely to PDF, Excel, Word or print. Components: Component Role --- --- Report Designer (Visual Studio Reporting Services Projects) / Report Builder Author .rdl reports Report Server (Windows service) Processes and renders reports, runs subscriptions ReportServer + ReportServerTempDB databases Catalog (reports, data sources, security, schedules) and session/cache data Web portal ( /Reports ) Browse, run, manage reports, KPIs, mobile reports (retired in 2022) Web service ( /ReportServer ) SOAP/REST APIs, URL access Report Server Configuration Manager Configure URLs, service account, DB, email, encryption keys Report definitions are RDL (Report Definition Language) XML files. Shared data sources ( .rds ) and shared datasets ( .rsd ) are reusable. Paginated vs interactive: SSRS/paginated reports are for fixed-layout operational output; Power BI reports are for interactive analytics and dashboards. Power BI Report Server (on-prem) hosts both. Power BI Service also hosts paginated reports. Version Highlights --- --- SSRS 2000 / 2005 Introduced as an add-on for SQL Server 2000; 2005 added Report Builder 1.0 2008 / 2008 R2 Tablix (combines table/matrix/list), new charts, gauges; R2: maps, sparklines, data bars, shared datasets, Report Builder 3.0 2012 SharePoint integrated mode as a SharePoint service, data alerts, Excel/Word 2010 renderers 2016 Modern web portal (HTML5), mobile reports & KPIs, Power BI pinning, new charts 2017 Separate installer (no longer in SQL setup); REST API 2019 Azure SQL Managed Instance catalog support, Microsoft Entra (Azure AD) app proxy support, accessibility 2022 Updated portal (Angular), accessibility, security improvements; mobile reports and Pin to Power BI removed SQL Server 2025 era Microsoft announced that Power BI Report Server is the on-premises reporting solution going forward — no new SSRS version after 2022 (SSRS 2022 stays supported under its lifecycle). Existing RDL reports run on Power BI Report Server and in the Power BI service as paginated reports Report development lifecycle: requirements (layout, parameters, audience, delivery) → design data model/queries (stored procedures preferred) → create data source and datasets → design layout (tablix, groups, charts) → add parameters and expressions → preview/test (accuracy, page breaks, export formats) → deploy to the report server (dev → test → prod) → configure security, caching, snapshots, subscriptions → monitor execution log → maintain. Report processing lifecycle (when a user runs a report): 1. Request arrives via web portal or URL with parameters. 2. Authentication/authorisation — Windows (or custom/forms) authentication; role assignments checked on the item. 3. Data processing — the report processor executes dataset queries against data sources (unless served from cache/snapshot). 4. Report processing — combines data with the layout: grouping, sorting, aggregates, expressions → an intermediate format. 5. Rendering — the requested renderer produces HTML, PDF, Excel, Word, CSV, XML, TIFF/image, PowerPoint. 6. Delivery — returned to the browser, or for subscriptions emailed / written to a file share / SharePoint. 7. Logging — execution details go to ExecutionLog3 (time in data retrieval vs processing vs rendering). Expression evaluation order matters for things like RunningValue , page headers (can't reference dataset fields directly — use ReportItems!TextboxName.Value ) and visibility. Tool Use --- --- Visual Studio + Microsoft Reporting Services Projects extension Report projects, deploy to server Report Builder (standalone, free) Business-friendly authoring Power BI Report Builder Paginated reports for Power BI Service / Report Server Report Server Configuration Manager Server setup, backup encryption keys SSMS Connect to Reporting Services (jobs, roles), query ReportServer DB Web portal Manage folders, security, subscriptions, caching rs.exe utility, PowerShell ReportingServicesTools module, REST API Automated deployment and administration ReportViewer control (WinForms/ASP.NET WebForms) Embed reports in apps (no official ASP.NET Core viewer — use URL access/REST or third-party)"},{"kind":"lesson","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"data-sources-and-datasets","title":"Data sources and datasets","body":"- Data source — connection info (SQL Server, Azure SQL, Analysis Services, Oracle, ODBC, OLE DB, XML, SharePoint lists). Shared data sources live on the server and are reused; embedded ones live in one report. - Credentials : Windows integrated (Kerberos needed for double-hop), stored credentials (required for subscriptions and caching), prompt user, none. - Dataset — a query (text or stored procedure ) + fields + parameters + filters. Shared datasets can be cached and reused across reports. sql CREATE OR ALTER PROCEDURE rpt.usp SalesByRegion @StartDate DATE, @EndDate DATE, @RegionIds VARCHAR(MAX) AS SELECT r.RegionName, p.Category, SUM(s.Amount) AS Amount, COUNT( ) AS Orders FROM dbo.Sales s JOIN dbo.Regions r ON r.RegionId = s.RegionId JOIN dbo.Products p ON p.ProductId = s.ProductId WHERE s.SaleDate = @StartDate AND s.SaleDate < DATEADD(DAY, 1, @EndDate) AND s.RegionId IN (SELECT value FROM STRING SPLIT(@RegionIds, ',')) GROUP BY r.RegionName, p.Category; Best practice: keep heavy logic in SQL (stored procedures/views), return only the rows and columns the report shows."},{"kind":"lesson","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"report-items-tablix-table-matrix-list-charts","title":"Report items: tablix, table, matrix, list, charts","body":"- Tablix is the underlying data region; it appears as: - Table — fixed columns, dynamic rows (detail lists with row groups). - Matrix — dynamic rows and columns (cross-tab/pivot: regions × months). - List — free-form repeating layout (cards, labels, letters). - Chart , Gauge , Map , Data bar , Sparkline , Indicator . - Textbox , Image , Rectangle (container), Line , Subreport . - Header/Footer — page numbers ( Globals!PageNumber , Globals!TotalPages ), title, run time ( Globals!ExecutionTime )."},{"kind":"lesson","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"grouping-sorting-totals-and-page-breaks","title":"Grouping, sorting, totals and page breaks","body":"- Row groups and column groups (parent/child/adjacent), with group headers/footers for subtotals. - Group expressions like =Fields!Region.Value ; sorting per group; interactive sort on column headers. - Totals: right-click group → Add Total (Before/After). - Page breaks between group instances (e.g. one region per page), repeat header rows on each page ( RepeatOnNewPage via Advanced Mode in the Grouping pane), KeepTogether . - Recursive hierarchy (parent-child data, e.g. org chart) using a group with a recursive parent and Level() for indentation."},{"kind":"lesson","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"expressions-and-built-in-collections","title":"Expressions and built-in collections","body":"Expressions start with = and use VB.NET syntax. vb =Fields!Amount.Value ' field =Sum(Fields!Amount.Value) ' aggregate in current scope =Sum(Fields!Amount.Value, \"RegionGroup\") ' aggregate in a named scope =Fields!Amount.Value / Sum(Fields!Amount.Value, \"DataSet1\") ' % of total =IIf(Fields!Amount.Value < 0, \"Red\", \"Black\") ' conditional formatting (Color property) =Switch(Fields!Score.Value = 90, \"A\", Fields!Score.Value = 75, \"B\", True, \"C\") =Format(Fields!SaleDate.Value, \"dd-MMM-yyyy\") =RunningValue(Fields!Amount.Value, Sum, \"RegionGroup\") =RowNumber(Nothing) =IIf(RowNumber(Nothing) Mod 2 = 0, \"WhiteSmoke\", \"White\") ' green-bar (alternating) rows =Lookup(Fields!ProductId.Value, Fields!ProductId.Value, Fields!Name.Value, \"ProductsDS\") ' join another dataset =Parameters!Region.Label ' parameter display text =Globals!PageNumber & \" of \" & Globals!TotalPages =User!UserID ' current user =Join(Parameters!Regions.Label, \", \") ' multi-value parameter labels Built-in collections: Fields , Parameters , Globals , User , ReportItems , DataSources , DataSets , Variables . Custom code: Report Properties → Code (VB functions called as Code.MyFunction(...) ) or custom assemblies. Lookup , LookupSet and MultiLookup (2008 R2+) join datasets in the report — useful when data comes from two sources."},{"kind":"lesson","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"parameters-multi-value-and-cascading-parameters","title":"Parameters, multi-value and cascading parameters","body":"- Report parameters map to query parameters ( @StartDate ). - Data types: Text, Boolean, Date/Time, Integer, Float. Allow null/blank, multi-value , hidden, internal. - Available values from a dataset (drop-down) and default values (static, expression like =Today() , or a dataset). - Multi-value : in an embedded SQL query WHERE RegionId IN (@Regions) works automatically; for a stored procedure , pass =Join(Parameters!Regions.Value, \",\") and split it in SQL ( STRING SPLIT ). - Cascading parameters — the second parameter's available-values dataset uses the first (Country → State → City). Order matters in the parameter list. sql -- dataset for the State parameter (depends on @Country) SELECT StateId, StateName FROM dbo.States WHERE CountryId = @Country ORDER BY StateName;"},{"kind":"lesson","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"drill-down-drill-through-subreports-and-document-maps","title":"Drill-down, drill-through, subreports and document maps","body":"Feature What How --- --- --- Drill-down Expand/collapse detail rows in the same report Group visibility hidden, toggled by a textbox ( +/- ) Drill-through Click → open another report with parameters Textbox Action → Go to report + parameter mapping Subreport Embed a report inside another, executed per row/group Subreport item + parameters (can be slow for many rows) Go to URL Open a web page Action → Go to URL with an expression Bookmark / Document map Navigation within a long report Bookmark action; Document map label on groups Prefer drill-through or a joined dataset/ Lookup over subreports in large tables (each subreport instance runs its own query)."},{"kind":"lesson","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"deployment-and-security","title":"Deployment and security","body":"- Deploy from Visual Studio (project properties: TargetServerURL, folders), by uploading .rdl in the web portal, or scripting with rs.exe /PowerShell ReportingServicesTools/REST API in CI/CD. - Security model : role-based on folders/items, inherited down the folder tree. Item-level roles: Browser , Content Manager , Publisher , Report Builder , My Reports . System roles: System Administrator , System User . - Authentication: Windows (NTLM/Kerberos) by default; custom forms authentication via extension. - Row-level data security : pass =User!UserID to the query and filter by user, or rely on database security (Kerberos delegation). - Back up the encryption key (Configuration Manager) along with the ReportServer databases — without it stored credentials can't be decrypted after a restore."},{"kind":"lesson","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"subscriptions-caching-and-snapshots","title":"Subscriptions, caching and snapshots","body":"- Standard subscription — fixed recipients, schedule, format (e.g. PDF emailed every Monday 8 AM). - Data-driven subscription (Enterprise edition) — recipients, parameters and formats come from a query (e.g. each sales manager gets their own region's report). - Delivery extensions: email (SMTP configured), file share , SharePoint library, null (to pre-load cache). - Schedules run through SQL Server Agent jobs (named by GUIDs) — Agent must be running. - Caching — keep a temporary copy of a processed report for N minutes (per parameter combination) → faster repeated runs; requires stored credentials. - Snapshots — report executed at a scheduled time and stored; users see that point-in-time data; report history keeps old snapshots. - Shared dataset caching — cache the dataset for many reports."},{"kind":"lesson","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"performance-tuning-and-the-execution-log","title":"Performance tuning and the execution log","body":"sql SELECT TOP (50) ItemPath, UserName, Format, TimeStart, TimeDataRetrieval, TimeProcessing, TimeRendering, [RowCount], Status FROM ReportServer.dbo.ExecutionLog3 ORDER BY TimeStart DESC; - TimeDataRetrieval high → tune the SQL (indexes, stored procedures, return fewer rows, avoid SELECT ). - TimeProcessing high → too much grouping/sorting/filtering in the report, complex expressions, subreports per row, Lookup over large datasets — push work to SQL. - TimeRendering high → huge output, many pages, Excel exports of large data (consider CSV), images. - Use caching/snapshots for expensive reports, schedule heavy reports via subscriptions off-peak, filter with parameters (never \"all data by default\"), avoid dataset filters (applied after fetching all rows) — filter in the query instead."},{"kind":"lesson","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"ssrs-vs-power-bi-vs-power-bi-report-server","title":"SSRS vs Power BI vs Power BI Report Server","body":"SSRS / paginated Power BI (interactive) --- --- --- Purpose Pixel-perfect, printable, operational, many pages Interactive analysis, dashboards, self-service Authoring Report Builder / Visual Studio (RDL) Power BI Desktop (PBIX) Data Live queries per run Import (VertiPaq), DirectQuery, Direct Lake Exports PDF, Excel, Word, CSV, print-ready Limited pagination Hosting SSRS server, Power BI Report Server , Power BI Service (paginated) Power BI Service, Power BI Report Server Microsoft's direction: Power BI Report Server for on-prem (hosts RDL + PBIX), Power BI Service/Fabric in the cloud."},{"kind":"question","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"612","title":"What is SSRS and what are its main components?","body":"SQL Server Reporting Services is a server-based reporting platform for creating, deploying and delivering paginated reports. Components: report designers (Visual Studio Reporting Services Projects, Report Builder), the Report Server Windows service (processing, rendering, scheduling), the ReportServer and ReportServerTempDB databases, the web portal and web service, and Report Server Configuration Manager. Reports are RDL (XML) files."},{"kind":"question","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"613","title":"What is the difference between a table, matrix and list?","body":"All three are forms of the tablix data region. A table has fixed columns and dynamic rows (detail and group rows). A matrix has dynamic rows and dynamic columns based on groups — a pivot/cross-tab (e.g. products × months with totals). A list repeats a free-form layout per row or group — good for cards, labels or forms."},{"kind":"question","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"614","title":"What is the difference between a shared and an embedded data source?","body":"A shared data source (.rds) is stored once on the report server and reused by many reports; changing it (e.g. server name, credentials) updates all of them. An embedded data source belongs to a single report. Shared ones simplify environment changes and credential management; subscriptions and caching need stored credentials."},{"kind":"question","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"615","title":"What are report parameters? How do you create cascading parameters?","body":"Parameters let users filter reports (dates, region) and are passed into dataset queries. Cascading parameters are dependent: the available values of a child parameter come from a dataset that uses the parent parameter (Country → State → City). The parent must appear before the child in the parameter list; changing the parent refreshes the child's list."},{"kind":"question","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"616","title":"What rendering/export formats does SSRS support?","body":"HTML (web), PDF, Excel (XLSX), Word (DOCX), PowerPoint (PPTX, 2016+), CSV, XML, TIFF/image, MHTML (web archive). Data-only formats (CSV, XML) ignore layout. Page breaks, page size and hidden items behave differently per renderer — test each required format."},{"kind":"question","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"617","title":"What is the difference between drill-down and drill-through reports?","body":"Drill-down shows/hides detail rows within the same report by toggling group visibility (+/− icons) — all data is already retrieved. Drill-through opens a different (target) report when you click an item, passing parameters (e.g. click a region total → regional detail report) — the target runs its own query only when requested."},{"kind":"question","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"618","title":"How do you pass a multi-value parameter to a stored procedure?","body":"Stored procedures can't receive SSRS multi-value arrays directly. In the dataset parameter, pass =Join(Parameters!Region.Value, \",\") and split it in SQL using STRING SPLIT(@Regions, ',') (2016+), a table-valued function or XML/JSON. With an embedded text query, WHERE Region IN (@Region) works natively because SSRS expands the list."},{"kind":"question","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"619","title":"What are subscriptions? Standard vs data-driven?","body":"Subscriptions automatically deliver reports on a schedule or event to email, a file share or SharePoint. Standard subscriptions have fixed recipients, parameters and format defined by the user. Data-driven subscriptions (Enterprise edition) get recipients, delivery settings and parameter values from a query at runtime, so each person receives a personalised report. Both rely on SQL Server Agent and stored credentials."},{"kind":"question","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"620","title":"How do you improve SSRS report performance?","body":"Check ExecutionLog3 to see whether data retrieval, processing or rendering dominates. Optimise queries/stored procedures and indexes, return only needed rows/columns, filter in SQL rather than dataset filters, push aggregations to SQL, avoid subreports in detail rows (use joins/Lookup/drill-through), reduce complex expressions, use caching, snapshots or shared dataset caching for expensive reports, and schedule heavy reports via subscriptions."},{"kind":"question","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"621","title":"What is the difference between caching and snapshots?","body":"A cached report is a temporary copy of a processed report (per parameter set) kept for a configured time after the first user runs it; it expires and refreshes on demand. A snapshot is executed on a schedule and stored as a point-in-time copy that all users see until the next snapshot; report history can retain old snapshots. Both require stored credentials and reduce load on the source database."},{"kind":"question","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"622","title":"How do you show \"Page X of Y\" and alternating row colours?","body":"Footer textbox: =\"Page \" & Globals!PageNumber & \" of \" & Globals!TotalPages . Alternating rows: set the detail row's BackgroundColor to =IIf(RowNumber(Nothing) Mod 2 = 0, \"WhiteSmoke\", \"White\") ."},{"kind":"question","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"623","title":"How do you implement row-level security in SSRS?","body":"Pass the built-in User!UserID (domain\\user) to the dataset query or stored procedure and filter data by a user-to-region mapping table. Hide the parameter (or make it internal) so users can't change it. Alternatively use database-level security with Kerberos delegation (the user's identity flows to SQL Server with Row-Level Security). Item-level roles control who can open the report at all."},{"kind":"question","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"624","title":"What is the Lookup function? How is it different from a subreport?","body":"Lookup(source expr, dest expr, result expr, \"Dataset\") returns a value from another dataset by matching keys ( LookupSet returns many, MultiLookup takes many keys). It combines data from two datasets (even different data sources) within one tablix without a SQL join. A subreport is a whole separate report rendered inside the container and executes its own query per instance — heavier. Lookup works in memory, so very large lookup datasets are slow too."},{"kind":"question","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"625","title":"What happened to SSRS after SQL Server 2022?","body":"Microsoft announced that SQL Server 2022 Reporting Services is the last SSRS release; from SQL Server 2025, Power BI Report Server is the on-premises reporting solution, hosting both paginated (RDL) reports and Power BI reports. SSRS 2022 stays supported under its normal lifecycle. Cloud reporting moves to paginated reports in the Power BI service/Fabric. Existing RDL skills carry over."},{"kind":"question","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"626","title":"A report takes 3 minutes to open. ExecutionLog3 shows TimeDataRetrieval 170 seconds. What do you do?","body":"The bottleneck is the query. Capture the dataset's SQL (stored procedure) with the actual execution plan; look for scans, missing indexes, non-SARGable predicates on date parameters, parameter sniffing (the same proc fast in SSMS but slow from SSRS — use OPTION (RECOMPILE) or local variables), and returning far more rows than displayed. Add covering indexes, pre-aggregate in SQL, limit default parameter ranges, and consider caching/snapshots or a summary table refreshed by ETL."},{"kind":"question","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"627","title":"Managers want each region's sales report emailed to them every Monday, but only their region. How?","body":"Use a data-driven subscription (Enterprise edition): a query against a table of managers (Email, RegionId, Format) drives the subscription; map the Region parameter to RegionId and the To field to Email; schedule weekly Monday 8 AM; deliver as PDF. On Standard edition, create one standard subscription per manager, or use a SQL Agent job/.NET service that calls the SSRS REST/URL API to render per region and email it."},{"kind":"question","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"628","title":"A report looks fine in the browser but the PDF export has blank pages. Why?","body":"The report body width + left/right margins exceeds the page width (Report Properties → Page size), so the renderer spills onto extra pages; or there's empty space at the right edge of the body; or ConsumeContainerWhitespace is false. Fix: make body width ≤ page width − margins, set ConsumeContainerWhitespace = True, shrink the body to fit the content, and check page break settings."},{"kind":"question","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"629","title":"Subscriptions suddenly stopped sending emails. How do you troubleshoot?","body":"Check SQL Server Agent is running and the subscription jobs exist and succeed; review the subscription's status in the web portal; check the SSRS logs ( LogFiles folder) and ExecutionLog3 ; verify the SMTP settings in Configuration Manager (server, port, sender address, authentication) and that the SMTP server accepts relays from the report server; confirm stored credentials of the data source are still valid (expired passwords break unattended runs); and check whether the report's parameters changed and invalidated the subscription."},{"kind":"cheat","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"1","title":"Architecture","body":"Report Designer/Report Builder → RDL → Report Server (service) + ReportServer & ReportServerTempDB → web portal (/Reports) & web service (/ReportServer) → renderers → delivery."},{"kind":"cheat","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"2","title":"Data regions","body":"Tablix = Table (dynamic rows) · Matrix (dynamic rows + columns) · List (free-form) · Chart · Gauge · Map · Sparkline · Data bar · Indicator."},{"kind":"cheat","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"3","title":"Expressions","body":"vb =Sum(Fields!Amount.Value, \"GroupName\") =IIf(cond, a, b) / =Switch(...) =RunningValue(Fields!X.Value, Sum, Nothing) =RowNumber(Nothing) =Lookup(src, dest, result, \"DS\") =Join(Parameters!P.Value, \",\") =Globals!PageNumber & \" of \" & Globals!TotalPages =User!UserID =ReportItems!Textbox1.Value ' in header/footer"},{"kind":"cheat","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"4","title":"Parameters","body":"Single/multi-value · cascading (child dataset uses parent) · default =Today() · hidden/internal · SP multi-value via Join + STRING SPLIT."},{"kind":"cheat","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"5","title":"Interactivity","body":"Drill-down (toggle visibility) · Drill-through (Action → Go to report) · Subreport · Interactive sort · Document map · Bookmarks · Go to URL."},{"kind":"cheat","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"6","title":"Delivery & performance","body":"Standard vs data-driven subscriptions (Enterprise) · SQL Agent required · caching · snapshots · shared dataset cache · ExecutionLog3 (DataRetrieval / Processing / Rendering)."},{"kind":"cheat","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"7","title":"Security","body":"Folder/item roles: Browser, Content Manager, Publisher, Report Builder, My Reports · System Administrator/User · back up the encryption key · row-level via User!UserID."},{"kind":"cheat","course_slug":"ssrs","course_title":"SSRS — SQL Server Reporting Services","ref":"8","title":"Future","body":"SSRS 2022 = last SSRS · Power BI Report Server for on-prem going forward · paginated reports in Power BI Service."},{"kind":"course","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"","title":"IIS — Internet Information Services and Hosting .NET Applications","body":"How IIS works inside (HTTP.sys, WAS, W3SVC, worker processes), sites, bindings, applications and virtual directories, application pools (identity, pipeline mode, recycling, idle timeout), hosting ASP.NET Web Forms/MVC 5 and ASP.NET Core (in-process vs out-of-process, ASP.NET Core Module, Hosting Bundle), web.config, HTTPS certificates and SNI, authentication modes, URL Rewrite and ARR reverse proxy, compression and caching, logging and Failed Request Tracing, troubleshooting 500.x/502.5/503 errors, web farms and deployment with Web Deploy and PowerShell, security hardening, and IIS interview questions. IIS (Internet Information Services) is Microsoft's web server built into Windows and Windows Server. It hosts websites, ASP.NET Framework applications (Web Forms, MVC 5, Web API 2, WCF), ASP.NET Core apps (via the ASP.NET Core Module), static sites, PHP/Node (via modules) and acts as a reverse proxy. Concept Meaning --- --- Site A website with one or more bindings (protocol + IP + port + host name) and a physical path Application A sub-path of a site with its own application pool (e.g. /api ) Virtual directory A URL path mapped to another physical folder Application pool A group of apps served by the same worker process ( w3wp.exe ) — isolation boundary Bindings http :80 www.shop.com , https :443 www.shop.com + certificate Modules / handlers Pipeline components (authentication, compression, rewrite) and request processors (static files, ASP.NET, ASP.NET Core Module) IIS Windows Highlights --- --- --- 1.0–4.0 NT 3.51 / NT 4.0 Early web server, ASP classic (3.0) 5.0 / 5.1 Windows 2000 / XP ASP.NET 1.0 hosting (aspnet wp.exe) 6.0 Server 2003 Application pools , HTTP.sys kernel driver, w3wp.exe worker processes 7.0 Server 2008 / Vista Modular architecture, integrated pipeline , XML config ( applicationHost.config ), WAS 7.5 Server 2008 R2 / 7 ApplicationPoolIdentity default, PowerShell module 8.0 / 8.5 Server 2012 / 2012 R2 SNI (many HTTPS sites on one IP), centralised certificates, application initialization, dynamic IP restrictions 10.0 Server 2016 / 2019 / 2022 / 2025, Windows 10/11 HTTP/2 , HSTS support (1709+), HTTP/3 over QUIC (Server 2022+), TLS 1.3 (Server 2022+), IIS Administration API How IIS processes a request: 1. HTTP.sys (kernel-mode driver) receives the request on port 80/443, decrypts TLS (or the worker does), and checks its kernel-mode cache — cached static responses return immediately without user mode. 2. HTTP.sys routes the request to the request queue of the right application pool (based on the site binding and URL). 3. WAS (Windows Process Activation Service) and W3SVC manage configuration and start a worker process ( w3wp.exe ) for the pool if none is running (on-demand start). 4. The worker process runs the IIS integrated pipeline : native and managed modules handle events in order — BeginRequest → Authenticate → Authorize → ResolveCache → MapHandler → AcquireState → ExecuteHandler → ReleaseState → UpdateCache → Log → EndRequest. 5. The handler chosen by path/extension produces the response: StaticFileModule (files), ASP.NET ( System.Web for .aspx/MVC 5), or AspNetCoreModuleV2 (ASP.NET Core). 6. The response goes back through HTTP.sys to the client; the request is logged (W3C log). App pool lifecycle: started on first request (or always running) → serves requests → idle timeout (20 min default) shuts it down → recycled periodically (1,740 minutes default = 29 h), on config changes, memory limits or crashes (rapid-fail protection stops the pool after repeated crashes). - IIS Manager ( inetmgr ), PowerShell ( WebAdministration , IISAdministration modules), appcmd.exe ( %windir%\\system32\\inetsrv ). - Configuration files: %windir%\\System32\\inetsrv\\config\\applicationHost.config , site web.config . - Web Deploy (MSDeploy) , Visual Studio publish profiles, Azure DevOps \"IIS Web App Deploy\" task. - URL Rewrite and Application Request Routing (ARR) modules, Web Platform Installer (retired) → direct downloads. - Diagnostics: Event Viewer (Application/System logs), IIS logs ( %SystemDrive%\\inetpub\\logs\\LogFiles ), Failed Request Tracing (FREB) , Worker Processes view, DebugDiag, PerfMon counters."},{"kind":"lesson","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"installing-iis-and-its-core-components","title":"Installing IIS and its core components","body":"powershell Windows Server Install-WindowsFeature -Name Web-Server, Web-Asp-Net45, Web-Windows-Auth, Web-Http-Redirect, Web-Dyn-Compression -IncludeManagementTools Windows 10/11 Enable-WindowsOptionalFeature -Online -FeatureName IIS-WebServerRole, IIS-ASPNET45, IIS-ManagementConsole -All Component Mode Role --- --- --- HTTP.sys Kernel Listens on ports, request queues per app pool, kernel caching, TLS (with SChannel) WAS User (service) Reads configuration, manages app pools and worker process lifetime W3SVC User (service) Adapter between HTTP.sys and WAS for HTTP w3wp.exe User (process) Worker process: runs the pipeline, modules and your application applicationHost.config File Server-wide configuration (sites, pools, bindings, global modules) Default site: \"Default Web Site\" bound to :80 , physical path C:\\inetpub\\wwwroot ."},{"kind":"lesson","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"sites-bindings-applications-and-virtual-directories","title":"Sites, bindings, applications and virtual directories","body":"powershell Import-Module WebAdministration New-Item -ItemType Directory C:\\sites\\shop -Force New-WebAppPool -Name \"ShopPool\" New-Website -Name \"Shop\" -PhysicalPath \"C:\\sites\\shop\" -ApplicationPool \"ShopPool\" -Port 80 -HostHeader \"www.shop.com\" New-WebBinding -Name \"Shop\" -Protocol https -Port 443 -HostHeader \"www.shop.com\" -SslFlags 1 1 = SNI New-WebApplication -Site \"Shop\" -Name \"api\" -PhysicalPath \"C:\\sites\\shop-api\" -ApplicationPool \"ShopApiPool\" New-WebVirtualDirectory -Site \"Shop\" -Name \"downloads\" -PhysicalPath \"D:\\shared\\downloads\" - Binding = protocol + IP (or ) + port + host header. Several sites can share port 80/443 if host names differ. - SNI (Server Name Indication) lets many HTTPS sites with different certificates share one IP:443. - An application under a site ( /api ) can run in a different app pool and has its own web.config root for ASP.NET. - A virtual directory only maps a URL to a folder (no separate app/pool). - hosts file ( C:\\Windows\\System32\\drivers\\etc\\hosts ) can map www.shop.com to 127.0.0.1 for local testing."},{"kind":"lesson","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"application-pools-identity-pipeline-mode-recycling-and-isolation","title":"Application pools — identity, pipeline mode, recycling and isolation","body":"Setting Options / default Notes --- --- --- .NET CLR version v4.0 / v2.0 / No Managed Code ASP.NET Framework 4.x → v4.0; ASP.NET Core → No Managed Code Managed pipeline mode Integrated / Classic Integrated = ASP.NET modules in the IIS pipeline (use this); Classic = legacy ISAPI style Identity ApplicationPoolIdentity / NetworkService / LocalSystem / custom account ApplicationPoolIdentity = virtual account IIS AppPool\\ShopPool — grant folder permissions to it Enable 32-bit applications False True only for old 32-bit native dependencies Start mode OnDemand / AlwaysRunning AlwaysRunning + Application Initialization removes the first-request delay Idle timeout 20 minutes Set 0 for always-warm apps Regular recycling 1,740 minutes Schedule at a quiet time or disable if not needed Rapid-fail protection 5 failures in 5 minutes Pool stops → 503 Service Unavailable Maximum worker processes 1 1 = \"web garden\" (in-process session/cache not shared) powershell Set-ItemProperty IIS:\\AppPools\\ShopPool -Name managedRuntimeVersion -Value \"\" No Managed Code (ASP.NET Core) Set-ItemProperty IIS:\\AppPools\\ShopPool -Name startMode -Value AlwaysRunning Set-ItemProperty IIS:\\AppPools\\ShopPool -Name processModel.idleTimeout -Value \"00:00:00\" icacls C:\\sites\\shop /grant \"IIS AppPool\\ShopPool:(OI)(CI)RX\" read & execute for the pool identity icacls C:\\sites\\shop\\logs /grant \"IIS AppPool\\ShopPool:(OI)(CI)M\" modify for log folder Restart-WebAppPool -Name ShopPool Recycling starts a new worker process and drains the old one (overlapped recycle) — in-memory state (InProc session, caches, static variables) is lost. That's why web farms and recycles need out-of-process session (SQL/Redis). Database access with ApplicationPoolIdentity: with Windows authentication to SQL Server on the same machine, create a login for IIS AppPool\\ShopPool ; for a remote SQL Server, the machine account ( DOMAIN\\WEBSERVER$ ) is used — or run the pool as a domain service account / use SQL authentication."},{"kind":"lesson","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"hosting-aspdotnet-framework-apps-web-forms-mvc-5-web-api-2","title":"Hosting ASP.NET Framework apps (Web Forms, MVC 5, Web API 2)","body":"1. Install IIS with ASP.NET 4.x ( Web-Asp-Net45 ) — .NET Framework 4.8 is part of Windows Server. 2. App pool: .NET CLR v4.0, Integrated pipeline . 3. Publish from Visual Studio (Folder or Web Deploy profile) with Release configuration — Web.Release.config transforms apply (connection strings, compilation debug=\"false\" , customErrors On ). 4. Copy to the site folder; bin\\ contains your DLLs; web.config at the root. 5. Grant the pool identity read access; write access only to folders that need it (uploads, App Data , logs). xml <!-- web.config essentials for production -- <system.web <compilation debug=\"false\" targetFramework=\"4.8\" / <customErrors mode=\"RemoteOnly\" defaultRedirect=\"~/Error\" / <httpRuntime targetFramework=\"4.8\" enableVersionHeader=\"false\" maxRequestLength=\"10240\" / <sessionState mode=\"SQLServer\" sqlConnectionString=\"...\" / <!-- web farm -- </system.web <system.webServer <httpErrors errorMode=\"DetailedLocalOnly\" / <security <requestFiltering removeServerHeader=\"true\" <requestLimits maxAllowedContentLength=\"10485760\" / </requestFiltering </security <staticContent <clientCache cacheControlMode=\"UseMaxAge\" cacheControlMaxAge=\"7.00:00:00\" / </staticContent </system.webServer system.web = ASP.NET settings; system.webServer = IIS settings (integrated mode). Changing web.config or bin\\ contents restarts the application domain ."},{"kind":"lesson","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"hosting-aspdotnet-core-on-iis-in-process-vs-out-of-process","title":"Hosting ASP.NET Core on IIS — in-process vs out-of-process","body":"Prerequisite: install the .NET Hosting Bundle (runtime + ASP.NET Core Module V2) on the server, then restart IIS ( net stop was /y && net start w3svc ). text In-process (default, fastest): HTTP.sys → w3wp.exe [ ANCM → your app via IISHttpServer ] Out-of-process: HTTP.sys → w3wp.exe [ ANCM ] ──HTTP──▶ dotnet.exe/YourApp.exe [ Kestrel ] xml <!-- web.config generated by dotnet publish -- <configuration <location path=\".\" inheritInChildApplications=\"false\" <system.webServer <handlers <add name=\"aspNetCore\" path=\" \" verb=\" \" modules=\"AspNetCoreModuleV2\" resourceType=\"Unspecified\" / </handlers <aspNetCore processPath=\"dotnet\" arguments=\".\\Shop.Web.dll\" stdoutLogEnabled=\"false\" stdoutLogFile=\".\\logs\\stdout\" hostingModel=\"inprocess\" <environmentVariables <environmentVariable name=\"ASPNETCORE ENVIRONMENT\" value=\"Production\" / </environmentVariables </aspNetCore </system.webServer </location </configuration Steps: dotnet publish -c Release -o C:\\sites\\shop → app pool No Managed Code → site pointing to the publish folder → bindings + certificate → permissions → browse. For self-contained publishes, processPath is .\\Shop.Web.exe . In-process Out-of-process --- --- --- Server IIS HTTP server inside w3wp Kestrel in a separate process Performance Higher (no extra hop) Lower (loopback proxy) Apps per pool One ASP.NET Core app per app pool Several possible Use when Default Need Kestrel-specific features or multiple apps per pool Zero-downtime-ish deploys: drop an app offline.htm file in the site folder (ANCM shuts the app down and serves that page), copy new files, delete the file. Web Deploy can do this automatically ( -enableRule:AppOffline )."},{"kind":"lesson","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"https-certificates-authentication-and-security-hardening","title":"HTTPS, certificates, authentication and security hardening","body":"HTTPS: import the certificate (PFX) into Local Machine\\Personal (or use the Centralized Certificate Store), add an https binding with SNI, redirect HTTP → HTTPS (URL Rewrite rule or app-level UseHttpsRedirection ), enable HSTS. Free certificates: win-acme automates Let's Encrypt issuance and renewal for IIS. powershell $cert = Import-PfxCertificate -FilePath C:\\certs\\shop.pfx -CertStoreLocation Cert:\\LocalMachine\\My -Password (Read-Host -AsSecureString) New-WebBinding -Name Shop -Protocol https -Port 443 -HostHeader www.shop.com -SslFlags 1 (Get-WebBinding -Name Shop -Protocol https).AddSslCertificate($cert.Thumbprint, \"My\") Authentication options (IIS level): Mode Use --- --- Anonymous Public sites (app handles login with cookies/JWT) Windows Authentication (Negotiate/Kerberos, NTLM) Intranet apps with Active Directory — [Authorize] and User.Identity.Name = DOMAIN\\user Basic Avoid (only over HTTPS, legacy) Client certificate mapping Machine-to-machine Hardening checklist: remove unused modules/handlers and the default site, least-privilege pool identities, disable directory browsing, remove Server / X-Powered-By / X-AspNet-Version headers, request filtering (limits, blocked extensions like .config ), disable TLS 1.0/1.1 and weak ciphers (IIS Crypto tool), keep Windows patched, custom error pages, log retention, separate app pools per site."},{"kind":"lesson","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"url-rewrite-reverse-proxy-arr-compression-and-caching","title":"URL Rewrite, reverse proxy (ARR), compression and caching","body":"xml <system.webServer <rewrite <rules <!-- Force HTTPS -- <rule name=\"HTTPS redirect\" stopProcessing=\"true\" <match url=\"(. )\" / <conditions <add input=\"{HTTPS}\" pattern=\"off\" / </conditions <action type=\"Redirect\" url=\"https://{HTTP HOST}/{R:1}\" redirectType=\"Permanent\" / </rule <!-- SPA fallback: unknown paths → index.html (Angular/React hosted on IIS) -- <rule name=\"SPA fallback\" stopProcessing=\"true\" <match url=\". \" / <conditions logicalGrouping=\"MatchAll\" <add input=\"{REQUEST FILENAME}\" matchType=\"IsFile\" negate=\"true\" / <add input=\"{REQUEST FILENAME}\" matchType=\"IsDirectory\" negate=\"true\" / <add input=\"{REQUEST URI}\" pattern=\"^/api/\" negate=\"true\" / </conditions <action type=\"Rewrite\" url=\"/index.html\" / </rule <!-- Reverse proxy /node/ to a Node.js or Next.js app on port 3000 (requires ARR with proxy enabled) -- <rule name=\"Proxy to Node\" stopProcessing=\"true\" <match url=\"^node/(. )\" / <action type=\"Rewrite\" url=\"http://localhost:3000/{R:1}\" / </rule </rules </rewrite <urlCompression doStaticCompression=\"true\" doDynamicCompression=\"true\" / </system.webServer - Redirect (301/302 — browser goes to a new URL) vs Rewrite (server serves different content, URL unchanged). - ARR (Application Request Routing): reverse proxy and load balancer — server farms with health tests, sticky sessions; lets IIS front Node.js, Next.js, Kestrel or other servers. - Output caching / kernel caching for static and cacheable responses; clientCache sets Cache-Control for static files; static and dynamic compression (gzip; Brotli via the IIS Compression module)."},{"kind":"lesson","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"logging-failed-request-tracing-and-troubleshooting-http-errors","title":"Logging, Failed Request Tracing and troubleshooting HTTP errors","body":"Where to look: 1. IIS logs ( C:\\inetpub\\logs\\LogFiles\\W3SVC<siteId \\ ) — every request with status, sub-status and Win32 status ( sc-status , sc-substatus , sc-win32-status ) and time-taken . 2. Event Viewer → Windows Logs → Application/System — app crashes, ASP.NET Core startup failures, WAS pool stops. 3. Failed Request Tracing (FREB) — enable on the site, add a rule (e.g. status 500 or time 5 s) → detailed XML trace of every module step in inetpub\\logs\\FailedReqLogFiles . 4. ASP.NET Core stdout log ( stdoutLogEnabled=\"true\" , create the logs folder) and your app's own logs. 5. Worker Processes (IIS Manager) — currently executing requests per pool. Error Meaning Typical fix --- --- --- 401.1 / 401.2 Logon failed / auth method not enabled Enable the right authentication mode; check credentials 403.14 Directory listing denied Missing default document or app not deployed 404.0 / 404.3 Not found / MIME map missing Wrong path; add <mimeMap for e.g. .json , .woff2 , .webmanifest 404.13 Request too large Raise maxAllowedContentLength 500.19 Config error Invalid/duplicated web.config section, missing module (URL Rewrite, ANCM), locked section 500.21 Handler not recognised ASP.NET not installed or pool in Classic mode 500.30 ASP.NET Core app failed to start (in-process) Startup exception — stdout log, Event Viewer, run dotnet app.dll manually 500.31 / 500.32 Runtime not found / bitness mismatch Install the right .NET runtime/Hosting Bundle; 32/64-bit settings 502.5 Process failure (out-of-process) Same as 500.30 502.3 Bad gateway / timeout from backend Long requests, ARR/ANCM timeout settings 503 Service unavailable App pool stopped (rapid-fail, wrong identity password), queue full"},{"kind":"lesson","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"web-farms-deployment-automation-and-performance-tuning","title":"Web farms, deployment automation and performance tuning","body":"Web farm (multiple IIS servers): - Load balancer in front (hardware, Azure Load Balancer/Application Gateway, or ARR). - Same code and config on every node — deploy with Web Deploy, Azure DevOps or IIS Shared Configuration + DFS-replicated content. - Machine key (ASP.NET Framework: <machineKey for ViewState/Forms auth) or Data Protection keys (ASP.NET Core: shared folder/Redis/Blob) must be identical across nodes. - Session out-of-process (SQL Server/Redis) or sticky sessions. Deployment automation: powershell Web Deploy (msdeploy) from a build agent msdeploy.exe -verb:sync -source:contentPath=\"C:\\build\\publish\" -dest:contentPath=\"Shop\",computerName=\"https://web01:8172/msdeploy.axd\",userName=\"deploy\",password=\" \",authType=\"Basic\" -enableRule:AppOffline -allowUntrusted Azure DevOps: deployment group/agent on the server + \"IIS Web App Manage\" and \"IIS Web App Deploy\" tasks; GitHub Actions: self-hosted runner + PowerShell. Performance tuning: AlwaysRunning + Application Initialization (warm-up), disable idle timeout for busy apps, schedule recycling at off-peak times, enable compression and static caching, HTTP/2 (and HTTP/3 on Server 2022+), check queue length and Requests/Sec counters, avoid web gardens for stateful apps, use async code to avoid thread-pool starvation, keep debug=\"false\" ."},{"kind":"question","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"630","title":"What is IIS and what can it host?","body":"Microsoft's Windows web server. It hosts static sites, ASP.NET Framework apps (Web Forms, MVC 5, Web API 2, WCF), ASP.NET Core apps via the ASP.NET Core Module, and through modules/ARR can proxy to Node.js, Next.js or other servers. It provides bindings, HTTPS, authentication (including Windows auth), compression, caching, URL rewriting and logging."},{"kind":"question","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"631","title":"What is an application pool and why is it used?","body":"A group of one or more applications served by the same worker process ( w3wp.exe ) with shared settings: .NET CLR version, pipeline mode, identity, recycling and limits. Pools isolate applications — a crash, memory leak or recycle in one pool doesn't affect apps in other pools — and define the security identity the app runs as."},{"kind":"question","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"632","title":"What is w3wp.exe?","body":"The IIS worker process. Each application pool runs in its own w3wp.exe (or several in a web garden); it hosts the IIS pipeline, modules and your application code (including in-process ASP.NET Core apps). You attach the Visual Studio debugger to w3wp.exe to debug IIS-hosted apps and see it in Task Manager with the pool identity as the user."},{"kind":"question","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"633","title":"How do you deploy an ASP.NET Core app to IIS?","body":"Install the .NET Hosting Bundle on the server, dotnet publish -c Release , create an app pool with \"No Managed Code\", create a site pointing to the publish folder with bindings and a certificate, grant the pool identity read permissions (write for logs/uploads), set environment variables (ASPNETCORE ENVIRONMENT, connection strings) and browse. The published web.config configures the ASP.NET Core Module (in-process by default)."},{"kind":"question","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"634","title":"What is the difference between a site, an application and a virtual directory?","body":"A site is the top-level website with bindings and a root folder. An application is a sub-path that is its own ASP.NET application (own web.config root, can use a different app pool). A virtual directory just maps a URL path to a physical folder inside an application without being a separate app."},{"kind":"question","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"635","title":"In-process vs out-of-process hosting for ASP.NET Core in IIS?","body":"In-process runs the app inside the IIS worker process using IIS's HTTP server — no extra network hop, best performance, but only one ASP.NET Core app per pool. Out-of-process runs the app as a separate Kestrel process with IIS (ANCM) forwarding requests over loopback — slower, but multiple apps per pool and Kestrel-specific features. Configured with hostingModel in web.config / AspNetCoreHostingModel in the project."},{"kind":"question","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"636","title":"What is app pool recycling and what are its effects?","body":"IIS periodically (default every 29 hours), on configuration changes, memory/request limits or on demand starts a new worker process and shuts down the old one. It frees leaked memory and refreshes the app, but in-memory state is lost (InProc session, MemoryCache, static data) and the first request after startup may be slow. Schedule recycles off-peak, use out-of-process state and warm-up (Application Initialization)."},{"kind":"question","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"637","title":"What is ApplicationPoolIdentity and how do you give it permissions?","body":"A per-pool virtual account ( IIS AppPool\\<PoolName ) created automatically, with minimal privileges. Grant it NTFS rights on the site folders ( icacls ... /grant \"IIS AppPool\\ShopPool\":RX ), and for SQL Server with Windows authentication create a login for it locally or for the computer account ( DOMAIN\\SERVER$ ) when SQL is remote — or use a dedicated domain service account."},{"kind":"question","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"638","title":"How do you troubleshoot a 500.30 / 502.5 error with ASP.NET Core on IIS?","body":"The app failed to start. Check Event Viewer (Application log) for the ANCM and app exceptions, enable stdoutLogEnabled with a writable logs folder, run dotnet YourApp.dll from the publish folder on the server to see errors, verify the Hosting Bundle/runtime version and bitness, the app pool \"No Managed Code\", file permissions, environment-specific configuration (missing connection string, Key Vault access) and database connectivity at startup."},{"kind":"question","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"639","title":"What does HTTP.sys do?","body":"A kernel-mode HTTP listener used by IIS (and optionally ASP.NET Core directly). It accepts connections, parses requests, handles TLS with SChannel, maintains a request queue per application pool, serves cached responses from kernel mode and enforces limits — keeping IIS robust because requests queue in the kernel even while a worker process restarts."},{"kind":"question","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"640","title":"URL Rewrite vs Redirect? How do you host an Angular/React SPA on IIS?","body":"A redirect tells the browser to request a different URL (301/302, address bar changes); a rewrite serves a different resource internally with the URL unchanged. For SPAs, add a rewrite rule that sends every request that isn't an existing file, folder or /api/ path to /index.html , so deep links work on refresh; add MIME types if needed and cache static assets."},{"kind":"question","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"641","title":"How do you set up a web farm with IIS?","body":"Multiple IIS servers behind a load balancer with health checks; identical code and config deployed by automation or shared configuration; shared machine key / Data Protection keys so cookies and ViewState validate on any node; out-of-process session (SQL Server/Redis) or sticky sessions; centralised logging; shared or replicated file storage for uploads; rolling deployments one node at a time."},{"kind":"question","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"642","title":"What is a web garden and when should you avoid it?","body":"An application pool with more than one worker process. It can help apps limited by per-process locks, but in-process state (session, cache, static variables) isn't shared between the processes, causing inconsistent behaviour. Most apps should use one worker per pool and scale out across servers instead."},{"kind":"question","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"643","title":"After deployment the site returns 503 Service Unavailable. What do you check?","body":"The application pool is likely stopped: open IIS Manager → Application Pools; check Event Viewer System log for WAS errors — rapid-fail protection after repeated crashes, wrong or expired password for a custom identity, missing .NET version, or a crash at startup. Fix the cause and start the pool. Also check the request queue limit and that the binding/host name is correct."},{"kind":"question","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"644","title":"An intranet ASP.NET app on IIS must use Windows login and query SQL Server as the user. How do you configure it?","body":"Enable Windows Authentication (disable Anonymous) on the site, [Authorize] in the app, and either connect to SQL Server with the app pool identity (simplest — grant that account the needed DB permissions and use User.Identity.Name for auditing) or, if SQL must see the end user, configure Kerberos constrained delegation (SPNs for the service account, delegation to the SQL service) and impersonation — more complex, so usually avoided."},{"kind":"question","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"645","title":"The first request every morning takes 30 seconds. How do you fix it?","body":"The app pool shuts down after the idle timeout (20 min) or recycled overnight, so the first request starts the worker, JITs code and warms caches. Set the pool's Start Mode to AlwaysRunning, idle timeout to 0, enable Application Initialization with preloadEnabled on the site (and a warm-up URL), schedule recycling during low traffic, and consider ReadyToRun publishing to reduce JIT time."},{"kind":"cheat","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"1","title":"Request path","body":"HTTP.sys (kernel, queue, cache, TLS) → WAS/W3SVC → w3wp.exe (app pool) → integrated pipeline modules → handler (static / ASP.NET / AspNetCoreModuleV2) → logging → response."},{"kind":"cheat","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"2","title":"App pool settings","body":"CLR v4.0 (Framework) / No Managed Code (Core) · Integrated pipeline · ApplicationPoolIdentity · AlwaysRunning + idle 0 for warm apps · recycle off-peak · rapid-fail → 503."},{"kind":"cheat","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"3","title":"ASP.NET Core on IIS","body":"Hosting Bundle · dotnet publish · web.config aspNetCore (inprocess) · stdout log for 500.30 · app offline.htm for deploys · one in-process app per pool."},{"kind":"cheat","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"4","title":"Config & features","body":"applicationHost.config (server) · web.config (site/app) · bindings + SNI certificates · Windows auth for intranet · URL Rewrite (HTTPS, SPA fallback) · ARR reverse proxy/farms · compression · FREB tracing."},{"kind":"cheat","course_slug":"iis","course_title":"IIS — Internet Information Services and Hosting .NET Applications","ref":"5","title":"Error codes","body":"401 auth · 403.14 no default doc · 404.3 MIME · 500.19 config · 500.21 handler · 500.30/502.5 Core startup · 502.3 backend timeout · 503 pool stopped."},{"kind":"course","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"","title":"Git & GitHub — Version Control from Basics to Advanced","body":"How Git stores history, the daily commands, branching and merging, rebase, resolving conflicts, remotes and pull requests, branching strategies (GitFlow, trunk-based), undoing mistakes, tags and releases, hooks and the Git questions asked in every developer interview. Git is a distributed version control system: every developer has the full history locally, commits offline, and synchronises with a shared remote (GitHub, Azure Repos, GitLab, Bitbucket). Term Meaning --- --- Repository (repo) The project folder plus its full history ( .git directory) Commit A snapshot of the project with author, message and parent commit(s) Branch A movable pointer to a commit HEAD Pointer to what you have checked out (usually a branch) Working tree / staging area (index) / repository Edited files → git add → git commit Remote Another copy of the repo, usually origin Pull request (PR) / merge request A request to merge a branch, with review and CI checks Git vs older tools: TFVC and SVN are centralised (one server holds history, you check out files); Git is distributed , branching is cheap and merging is fast. Year Milestone --- --- 2005 Linus Torvalds creates Git for Linux kernel development 2008 GitHub launches 2014 Git 2.0 — push.default=simple 2018 Microsoft acquires GitHub; Azure Repos (Azure DevOps) supports Git 2019 Git 2.23 — git switch and git restore split the many jobs of checkout 2020 GitHub and Git default branch name moves to main (configurable via init.defaultBranch ) 2020+ git sparse-checkout , partial clone, git maintenance for big repos 2023 Git 2.42+ — SHA-256 repositories maturing 2025 Git 2.5x series; Git 3.0 planned (SHA-256 default, main default) File states: untracked → ( git add ) → staged → ( git commit ) → committed → (edit) → modified → staged again … Typical feature workflow: 1. git switch main && git pull — start from the latest main. 2. git switch -c feature/ORD-123-order-search — create a branch. 3. Edit, git add -p , git commit -m \"Add order search endpoint\" — small, focused commits. 4. git push -u origin feature/ORD-123-order-search . 5. Open a pull request ; CI runs build + tests; reviewers comment; you push fixes. 6. Update with main if needed ( git pull --rebase origin main or merge main in). 7. Merge (merge commit, squash or rebase-merge per team policy); delete the branch. 8. Release: tag ( v2.3.0 ) and deploy through CD. - CLI: git (Git for Windows includes Git Bash and Git Credential Manager). - IDEs: Visual Studio Git window, VS Code Source Control + GitLens, JetBrains Rider. - GUIs: GitHub Desktop, Sourcetree, GitKraken, Fork, TortoiseGit. - Hosting: GitHub (PRs, Actions, Codespaces), Azure Repos (PRs, branch policies), GitLab, Bitbucket. - Quality: pre-commit hooks, Husky (JS), commitlint, .gitattributes , .gitignore templates, Git LFS for big binaries."},{"kind":"lesson","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"setup-init-clone-and-the-three-areas","title":"Setup, init, clone and the three areas","body":"bash git config --global user.name \"Divakar Upadhyay\" git config --global user.email \"you@example.com\" git config --global init.defaultBranch main git init new repo in the current folder git clone https://github.com/org/repo.git copy an existing repo (all history) The three areas: text Working tree --git add-- Staging area (index) --git commit-- Repository (.git) (your files) (what goes in the next commit) (history) bash git status what changed, what is staged git add Program.cs stage one file git add -p stage chosen hunks interactively (great for clean commits) git commit -m \"Validate order quantity\" git log --oneline --graph --decorate --all git diff working tree vs staged git diff --staged staged vs last commit .gitignore — never commit build output, secrets or local settings: text bin/ obj/ node modules/ .user .vs/ appsettings.Development.json .env Interview tip: A good commit message: short imperative summary (≤ 50 chars), blank line, then why. \"Fix null reference when customer has no address\"."},{"kind":"lesson","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"branches-switching-and-merging","title":"Branches, switching and merging","body":"A branch is just a pointer to a commit — creating one is instant. bash git branch list local branches git switch -c feature/login create and switch (older: git checkout -b) git switch main go back git merge feature/login merge into the current branch git branch -d feature/login delete merged branch Fast-forward vs three-way merge: text Fast-forward (main has no new commits): main ──A──B feature: C──D result: main moves to D, no merge commit Three-way (both moved): main: A──B──E feature: A──B──C──D result: new merge commit M with parents E and D git merge --no-ff feature forces a merge commit even when fast-forward is possible (keeps the feature grouped in history)."},{"kind":"lesson","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"remotes-fetch-pull-push","title":"Remotes — fetch, pull, push","body":"bash git remote -v list remotes git fetch origin download new commits, do NOT change your branch git pull fetch + merge (or rebase if pull.rebase=true) git pull --rebase fetch + replay your local commits on top git push -u origin feature/login first push, set upstream git push later pushes git push --force-with-lease safe force-push after rebase (fails if someone else pushed) Command Changes your working branch? --- --- git fetch No — updates origin/ remote-tracking branches only git pull Yes — fetch then merge/rebase into your branch Interview tip: \"fetch is safe, pull integrates\" — and never use plain --force on a shared branch; use --force-with-lease ."},{"kind":"lesson","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"merge-conflicts-why-they-happen-and-how-to-resolve-them","title":"Merge conflicts — why they happen and how to resolve them","body":"A conflict happens when two branches change the same lines (or one edits a file the other deleted) and Git can't decide. text <<<<<<< HEAD decimal discount = 0.10m; ======= decimal discount = GetDiscount(customer); feature/discounts Steps: 1. git status — lists conflicted files. 2. Edit each file: keep one side, both, or write a new combination; remove the markers. 3. Build and run tests. 4. git add <file then git commit (merge) or git rebase --continue (rebase). 5. Changed your mind: git merge --abort / git rebase --abort . Reduce conflicts: small PRs, merge main into long branches often, agree formatting ( .editorconfig , Prettier), avoid giant files everyone edits."},{"kind":"lesson","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"rebase-vs-merge-squash-and-interactive-rebase","title":"Rebase vs merge, squash and interactive rebase","body":"text Before: main: A──B──E feature: A──B──C──D Merge: A──B──E──M (M joins E and D) — true history, extra merge commit Rebase: A──B──E──C'──D' — feature replayed on top of E, linear history, new commit ids bash git switch feature/search git rebase main replay my commits on top of main git rebase -i HEAD~4 interactive: squash, reword, reorder, drop commits Interactive rebase todo list: text pick 1a2b3c Add search endpoint squash 4d5e6f Fix typo squash 7a8b9c Address review comments reword 0c1d2e Add search UI Golden rule: never rebase commits that others have already pulled (shared/public branches) — rebase rewrites commit ids. PR merge options (GitHub/Azure Repos): merge commit, squash merge (whole PR becomes one commit on main — popular), rebase and merge (linear, keeps individual commits)."},{"kind":"lesson","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"pull-requests-code-review-and-branch-policies","title":"Pull requests, code review and branch policies","body":"A good PR: one purpose, small (< ~400 changed lines), descriptive title, linked work item, screenshots for UI, tests included. Branch protection / policies on main : - Require PR (no direct pushes), at least 1–2 reviewers, code owners for sensitive folders. - Require CI build + tests to pass (status checks). - Require linked work item and resolved comments (Azure Repos). - Require up-to-date branch / linear history; block force pushes. Review checklist: correctness, tests, naming, security (secrets, SQL injection), performance, error handling, readability — comment on code, not on people."},{"kind":"lesson","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"branching-strategies-gitflow-github-flow-trunk-based","title":"Branching strategies — GitFlow, GitHub Flow, trunk-based","body":"Strategy Branches Fits --- --- --- GitFlow main (releases), develop , feature/ , release/ , hotfix/ Scheduled versioned releases (installed software, mobile) GitHub Flow main + short-lived feature branches, deploy after merge Web apps with continuous delivery Trunk-based Everyone merges to main at least daily; feature flags hide unfinished work; release branches optional High-performing CI/CD teams (DORA research) Release branches main + release/2026.10 cut for stabilisation Enterprise apps with UAT cycles Hotfix in GitFlow: branch from main → fix → merge to main (tag) and develop ."},{"kind":"lesson","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"undoing-things-restore-reset-revert-reflog","title":"Undoing things — restore, reset, revert, reflog","body":"Situation Command --- --- Discard changes in a file git restore Program.cs Unstage a file git restore --staged Program.cs Fix the last commit message / add a forgotten file (not pushed) git commit --amend Undo last commit, keep changes staged git reset --soft HEAD~1 Undo last commit, keep changes unstaged git reset HEAD~1 (mixed, default) Throw away last commit and changes git reset --hard HEAD~1 (dangerous) Undo a commit that is already pushed/shared git revert <sha — new commit that reverses it \"I lost a commit / branch\" git reflog → find the sha → git switch -c rescue <sha Put work aside git stash push -m \"wip\" → git stash list → git stash pop reset vs revert: reset moves the branch pointer (rewrites history — only for local commits); revert adds a new commit (safe for shared history)."},{"kind":"lesson","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"cherry-pick-bisect-tags-blame-and-hooks","title":"Cherry-pick, bisect, tags, blame and hooks","body":"bash git cherry-pick 4d5e6f copy one commit onto the current branch (e.g. a hotfix into release) git tag -a v2.3.0 -m \"Release 2.3.0\" && git push origin v2.3.0 annotated tag for a release git blame -L 40,60 OrderService.cs who changed these lines and in which commit git log -S \"CalculateDiscount\" --oneline commits that added/removed this text git bisect start; git bisect bad; git bisect good v2.2.0 binary-search the commit that introduced a bug git bisect run dotnet test let tests decide good/bad automatically git bisect reset Hooks — scripts in .git/hooks (or managed by Husky / pre-commit): pre-commit (format, lint, block secrets), commit-msg (enforce message format), pre-push (run tests). Server-side checks belong in CI and branch policies, because local hooks can be skipped. Big repos: Git LFS for large binaries, shallow clone ( --depth 1 ) in CI, sparse-checkout for monorepos, git worktree to have two branches checked out at once."},{"kind":"lesson","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"how-git-stores-data-objects-sha-and-refs","title":"How Git stores data — objects, SHA and refs","body":"Git is a content-addressed store. Everything is an object named by its hash: Object Holds --- --- blob File contents tree A directory: names → blobs/trees commit Root tree + parent commit(s) + author + message tag (annotated) Points to a commit with tagger and message Branches and tags are refs — small files containing a commit id ( .git/refs/heads/main ). HEAD usually contains ref: refs/heads/main . \"Detached HEAD\" means HEAD points directly at a commit, not a branch — commits made there are easy to lose unless you create a branch. Because each commit includes its parent's id, changing any old commit changes every id after it — that's why rebase and amend create new commits and why rewriting shared history hurts teammates."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"646","title":"What is Git and how is it different from SVN/TFVC?","body":"Git is a distributed version control system: every clone has the full history, so commits, branches, diffs and logs work offline and are fast; you sync with remotes by push/pull. SVN and TFVC are centralised: history lives on one server, many operations need the server, and branching is heavier. Git's cheap branching enables feature branches and pull-request workflows."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"647","title":"What is the difference between git fetch and git pull?","body":"git fetch downloads new commits and updates remote-tracking branches ( origin/main ) without touching your working branch — safe to run anytime. git pull = fetch + integrate (merge by default, or rebase with --rebase / pull.rebase=true ) into your current branch, which can cause conflicts."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"648","title":"What is the staging area?","body":"The index between your working tree and the repository. git add puts selected changes into it and git commit records exactly what is staged. It lets you build clean, focused commits from a messy working tree ( git add -p to stage parts of a file)."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"649","title":"How do you resolve a merge conflict?","body":"Run git status to see conflicted files, open each, decide the correct code between the <<<<<<< , ======= , markers (keep one side, both, or rewrite), remove the markers, build and test, then git add the files and git commit (or git rebase --continue ). Use git merge --abort to back out. Prevent conflicts with small, frequent merges."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"650","title":"What does .gitignore do? A file is still tracked after adding it to .gitignore — why?","body":".gitignore stops untracked files from being added (bin/obj, node modules, secrets). It doesn't affect files already tracked; remove them from the index with git rm --cached <file and commit, and they will be ignored from then on (if it was a secret, rotate it — it is still in history)."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"651","title":"Merge vs rebase — differences and when to use each?","body":"Merge joins histories with a merge commit, keeps the true history and never rewrites commits — safe for shared branches. Rebase replays your commits on top of another branch, giving a linear history but new commit ids — use it for local/private branches to update with main or clean up before a PR. Never rebase commits others already have."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"652","title":"git reset vs git revert?","body":"reset moves the current branch pointer back (soft keeps changes staged, mixed keeps them unstaged, hard discards them) — it rewrites history, so only for unpushed commits. revert creates a new commit that undoes a previous commit — the safe way to undo something already pushed to a shared branch."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"653","title":"Which branching strategy have you used? Explain it.","body":"Describe yours concretely, e.g. \"GitFlow-like: main = production, develop for integration, feature/ per story with PRs into develop, release/ cut for UAT, hotfix/ from main merged back to both\" — or \"trunk-based: short-lived branches merged to main daily behind feature flags, every merge deploys to dev\". Mention branch policies (reviewers, CI checks) and how releases are tagged."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"654","title":"What is a pull request and what do you check in a code review?","body":"A request to merge a branch, where teammates review the diff and CI validates it before merge. Check: does it meet the requirement, tests, edge cases and error handling, security (secrets, injection, authorization), performance (N+1, missing indexes), naming and readability, consistency with architecture, and that the PR is small and focused."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"655","title":"What is git stash?","body":"Temporarily shelves uncommitted changes so you can switch context: git stash push -m \"msg\" (add -u for untracked files), git stash list , git stash pop (apply and drop) or git stash apply (keep in stash). Useful when an urgent bug arrives mid-feature."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"656","title":"What is cherry-pick and when would you use it?","body":"git cherry-pick <sha applies the changes of one commit onto the current branch as a new commit. Typical use: bring a hotfix from main into a release branch, or rescue a commit made on the wrong branch. Overuse creates duplicate commits — prefer merging when you need a whole branch."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"657","title":"What is a detached HEAD?","body":"HEAD points directly to a commit instead of a branch — after checking out a tag or a commit sha. You can look around and even commit, but new commits belong to no branch and can be garbage-collected once you switch away. Create a branch ( git switch -c fix-from-tag ) to keep them."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"658","title":"How does git bisect help find a bug?","body":"It binary-searches history between a known good and a known bad commit: Git checks out the midpoint, you mark it good or bad (or git bisect run <test script does it automatically), and in log2(n) steps it names the first bad commit. Great for regressions in long histories."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"659","title":"How does Git store data internally?","body":"As content-addressed objects (blob = file content, tree = directory, commit = tree + parents + metadata, annotated tag) named by their SHA-1 (SHA-256 optional) hash, compressed in .git/objects and packfiles. Branches/tags are refs pointing at commit ids; HEAD points at a ref. Changing any commit changes its hash and all descendants' hashes."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"660","title":"You committed a password and pushed it to GitHub. What do you do?","body":"First rotate/revoke the secret immediately — assume it is compromised (bots scan GitHub within minutes). Then remove it from the code (move to Key Vault/user secrets/environment variables), and purge it from history with git filter-repo or BFG, force-push and ask everyone to re-clone; on GitHub contact support to clear cached views. Prevent it next time: .gitignore , pre-commit secret scanning (gitleaks), GitHub push protection / secret scanning."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"661","title":"You made three commits on main by mistake instead of a feature branch (not pushed). Fix it.","body":"git branch feature/x (new branch points at your commits) → git reset --hard origin/main (move main back to the remote state) → git switch feature/x and continue. Nothing is lost; if anything goes wrong, git reflog shows the old position."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"662","title":"A bad commit is already deployed from main. How do you undo it without rewriting history?","body":"git revert <sha (for a merge commit git revert -m 1 <merge-sha ), push through the normal PR/pipeline so the revert is reviewed and deployed. Don't reset + force-push a shared branch — it breaks everyone's clones and the audit trail."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"663","title":"Your feature branch is two weeks behind main and has many conflicts. How do you bring it up to date?","body":"Fetch first. If the branch is only yours: git rebase origin/main , resolve conflicts commit by commit ( git rebase --continue ), run tests, git push --force-with-lease . If shared: git merge origin/main once and resolve in one merge commit. Afterwards keep it short-lived and sync daily; consider splitting the work into smaller PRs behind a feature flag."},{"kind":"question","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"664","title":"git push is rejected with \"non-fast-forward\". What does it mean?","body":"The remote branch has commits you don't have, so pushing would overwrite them. git pull --rebase (or git pull ), resolve any conflicts, test, then push. Only force-push ( --force-with-lease ) when you intentionally rewrote your own branch."},{"kind":"cheat","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"1","title":"Daily commands","body":"bash git status git add -p git commit -m \"msg\" git push git switch -c feature/x git switch main git pull --rebase git log --oneline --graph --all git diff --staged"},{"kind":"cheat","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"2","title":"Undo table","body":"Need Command --- --- Discard file edits git restore f Unstage git restore --staged f Edit last local commit git commit --amend Undo local commits git reset --soft/--mixed/--hard HEAD~n Undo pushed commit git revert sha Find lost work git reflog"},{"kind":"cheat","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"3","title":"Merge vs rebase","body":"Merge = true history, safe for shared branches. Rebase = linear history, rewrites ids — only on your own branches. Squash merge = one commit per PR on main."},{"kind":"cheat","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"4","title":"Branching strategies","body":"GitFlow (develop/release/hotfix, versioned releases) · GitHub Flow (main + short branches) · Trunk-based (daily merges + feature flags)."},{"kind":"cheat","course_slug":"git","course_title":"Git & GitHub — Version Control from Basics to Advanced","ref":"5","title":"Safety rules","body":"Never commit secrets (rotate if you do) · --force-with-lease , never --force on shared branches · protect main with PR + CI policies · small PRs, frequent syncs · tag every release."},{"kind":"course","course_slug":"docker","course_title":"Docker & Containers","ref":"","title":"Docker & Containers","body":"Containers vs VMs, images and layers, Dockerfile for .NET, multi-stage builds, volumes, networks, Docker Compose, registries, security, debugging and production best practices. Docker packages an application with everything it needs (runtime, libraries, config) into a container image that runs the same on a laptop, CI server or cloud. A container is a running instance of an image — an isolated process that shares the host's OS kernel. Virtual machine Container --- --- --- Isolation Full guest OS on a hypervisor Process isolation via kernel namespaces + cgroups Size GBs MBs Start time Minutes Seconds or less Density Few per host Many per host OS Any guest OS Shares host kernel (Linux containers on Linux; Windows containers on Windows) Key pieces: Docker Engine (daemon dockerd + CLI), images , containers , Dockerfile , registries (Docker Hub, Azure Container Registry, GitHub Container Registry), volumes , networks , Docker Compose . Standards: the OCI (Open Container Initiative) image and runtime specs; low-level runtimes containerd and runc . Year Milestone --- --- 2008 Linux Containers (LXC) 2013 Docker open-sourced by dotCloud (PyCon demo) 2014 Docker 1.0; Docker Compose (from Fig) 2015 Open Container Initiative (OCI) founded; Docker Swarm 2016 Docker for Mac/Windows; Windows Server containers 2017 Multi-stage builds (17.05); Moby project; containerd donated to CNCF; version scheme YY.MM 2019 Docker Enterprise sold to Mirantis 2020 BuildKit default path; Compose Specification 2021 Docker Desktop requires a paid subscription for larger companies ( 250 employees or $10M revenue) 2022 Kubernetes removes dockershim (v1.24) — Docker-built images still run fine 2023 Docker Compose v2 ( docker compose ) replaces docker-compose ; Docker Scout; Docker Init 2024–2025 Docker Engine 27/28: Docker Build Cloud, Docker Desktop AI features, hardened images .NET images: mcr.microsoft.com/dotnet/sdk (build), aspnet (ASP.NET Core runtime), runtime (console apps), runtime-deps (self-contained/AOT). Since .NET 8 they run as a non-root app user and default to port 8080 . Container lifecycle: docker create → Created → docker start → Running → docker pause → Paused → docker unpause → Running → docker stop (SIGTERM, then SIGKILL after 10 s) → Exited → docker start again or docker rm → Removed . docker run = create + start. docker kill sends SIGKILL immediately. Restart policies: no , on-failure , always , unless-stopped . Image lifecycle: write Dockerfile → docker build (each instruction creates a cached layer ) → docker tag → docker push to a registry → docker pull on the target → docker run → update → rebuild/retag → prune old images. Dev-to-prod flow: code → Dockerfile → CI builds and tests the image → scan for vulnerabilities → push with an immutable tag (git SHA) → deploy to Kubernetes/Azure Container Apps/App Service → monitor. Tool Use --- --- Docker Desktop (Windows/Mac), Docker Engine (Linux) Run containers locally Podman, Rancher Desktop, colima Docker alternatives Docker Compose Multi-container apps for dev/test BuildKit / docker buildx Fast, multi-platform builds Visual Studio container tools, VS Code Dev Containers / Container Tools Build, debug in containers .NET SDK container publishing ( dotnet publish -t:PublishContainer ) Build images without a Dockerfile Azure Container Registry, Docker Hub, GHCR Registries Docker Scout, Trivy, Grype, Microsoft Defender for Containers Vulnerability scanning Hadolint Dockerfile linting Dive Inspect image layers Testcontainers Real dependencies in integration tests"},{"kind":"lesson","course_slug":"docker","course_title":"Docker & Containers","ref":"images-containers-layers-and-registries","title":"Images, containers, layers and registries","body":"- Image — read-only template made of stacked layers (each Dockerfile instruction adds one). Identified by repository:tag (e.g. myacr.azurecr.io/shop-api:1.4.2 ) and an immutable digest ( @sha256:... ). - Container — image + a thin writable layer + runtime config (env vars, ports, mounts). Changes in the writable layer are lost when the container is removed. - Layer caching — unchanged layers are reused between builds and shared between images on disk (copy-on-write via the overlay2 storage driver). - Registry — stores images; repository — one image name with many tags. bash docker pull mcr.microsoft.com/dotnet/aspnet:10.0 docker images docker run -d --name web -p 8080:8080 -e ASPNETCORE ENVIRONMENT=Development shop-api:dev docker ps -a docker logs -f web docker exec -it web /bin/sh shell inside (if the image has one) docker stop web && docker rm web docker image prune -a remove unused images docker system df disk usage Interview tip: never use the latest tag in production — use immutable version tags or digests so deployments are reproducible."},{"kind":"lesson","course_slug":"docker","course_title":"Docker & Containers","ref":"dockerfile-instructions","title":"Dockerfile instructions","body":"Instruction Purpose --- --- FROM Base image (can appear multiple times for multi-stage) WORKDIR Set working directory COPY / ADD Copy files (ADD also extracts tar and fetches URLs — prefer COPY) RUN Execute a command at build time (creates a layer) ENV Environment variable (build + runtime) ARG Build-time variable only EXPOSE Document the listening port (doesn't publish it) USER Run as a non-root user ENTRYPOINT The executable that always runs CMD Default arguments (or command) — overridable at docker run HEALTHCHECK Command to test container health LABEL , VOLUME , STOPSIGNAL , SHELL Metadata, mount points, signals CMD vs ENTRYPOINT: ENTRYPOINT [\"dotnet\", \"Api.dll\"] fixes the program; CMD [\"--urls\", \"http://+:8080\"] supplies default args that docker run image <args replaces. Use the exec form (JSON array) so the app is PID 1 and receives SIGTERM for graceful shutdown."},{"kind":"lesson","course_slug":"docker","course_title":"Docker & Containers","ref":"multi-stage-dockerfile-for-aspdotnet-core","title":"Multi-stage Dockerfile for ASP.NET Core","body":"dockerfile syntax=docker/dockerfile:1 ---- build stage ---- FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build WORKDIR /src COPY [\"src/Shop.Api/Shop.Api.csproj\", \"src/Shop.Api/\"] COPY [\"src/Shop.Core/Shop.Core.csproj\", \"src/Shop.Core/\"] RUN dotnet restore \"src/Shop.Api/Shop.Api.csproj\" cached until a .csproj changes COPY . . RUN dotnet publish \"src/Shop.Api/Shop.Api.csproj\" -c Release -o /app/publish /p:UseAppHost=false ---- runtime stage ---- FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS final WORKDIR /app COPY --from=build /app/publish . USER app non-root user built into .NET 8+ images EXPOSE 8080 ENV ASPNETCORE HTTP PORTS=8080 ENTRYPOINT [\"dotnet\", \"Shop.Api.dll\"] Health checks: the aspnet images don't include curl / wget . In Kubernetes or Container Apps, use HTTP probes against app.MapHealthChecks(\"/health\") . For a plain Docker HEALTHCHECK , install a small tool in the final stage, or ship a tiny health-check executable. Why multi-stage: the final image contains only the runtime + published output (~100–200 MB) instead of the full SDK (~800 MB+), so it is smaller, faster to pull, and has a smaller attack surface. Copy .csproj files and restore before copying the source to maximise layer caching. .dockerignore (like .gitignore for the build context): bin/ , obj/ , .git , .vs , node modules , .user , secrets. Alternative without a Dockerfile: bash dotnet publish -t:PublishContainer -p:ContainerRepository=shop-api -p:ContainerImageTag=1.0.0 Even smaller images: -chiseled Ubuntu variants (distroless-style, no shell or package manager), Alpine variants, or Native AOT on runtime-deps ."},{"kind":"lesson","course_slug":"docker","course_title":"Docker & Containers","ref":"volumes-bind-mounts-and-networking","title":"Volumes, bind mounts and networking","body":"Storage What Use --- --- --- Named volume Managed by Docker ( docker volume create ) Database data, persistent app data Bind mount Host folder mapped into the container Source code during development, config files tmpfs In memory only Secrets/temp data that must not touch disk bash docker run -d --name sql -e ACCEPT EULA=Y -e MSSQL SA PASSWORD='<strong-password ' \\ -p 1433:1433 -v sqldata:/var/opt/mssql mcr.microsoft.com/mssql/server:2022-latest docker network create shopnet docker run -d --name api --network shopnet shop-api:1.0 reachable as http://api:8080 by other containers on shopnet Network drivers: bridge (default; user-defined bridges give DNS by container name), host (share host network stack), none , overlay (multi-host, Swarm), macvlan . -p 8080:80 publishes host port 8080 → container port 80."},{"kind":"lesson","course_slug":"docker","course_title":"Docker & Containers","ref":"compose-for-a-dotnet-api-sql-server-redis","title":"Compose for a .NET API + SQL Server + Redis","body":"yaml compose.yaml services: api: build: context: . dockerfile: src/Shop.Api/Dockerfile ports: - \"8080:8080\" environment: ASPNETCORE ENVIRONMENT: Development ConnectionStrings Db: \"Server=sql;Database=Shop;User Id=sa;Password=${SA PASSWORD};TrustServerCertificate=True\" ConnectionStrings Redis: \"redis:6379\" depends on: sql: condition: service healthy redis: condition: service started sql: image: mcr.microsoft.com/mssql/server:2022-latest environment: ACCEPT EULA: \"Y\" MSSQL SA PASSWORD: ${SA PASSWORD} volumes: - sqldata:/var/opt/mssql healthcheck: test: [\"CMD-SHELL\", \"/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P \\\"$$MSSQL SA PASSWORD\\\" -C -Q 'SELECT 1' exit 1\"] interval: 10s retries: 10 redis: image: redis:7-alpine volumes: sqldata: bash docker compose up -d --build build + start everything docker compose ps docker compose logs -f api docker compose exec api sh docker compose down stop and remove containers + network (add -v to delete volumes) Compose creates a default network so services reach each other by service name ( sql , redis ). ${SA PASSWORD} comes from a .env file (keep it out of Git). depends on controls start order; with condition: service healthy it waits for the health check."},{"kind":"lesson","course_slug":"docker","course_title":"Docker & Containers","ref":"image-size-security-and-best-practices","title":"Image size, security and best practices","body":"1. Multi-stage builds; minimal base images ( aspnet , chiseled, Alpine); pin versions ( aspnet:10.0 or a digest). 2. Run as non-root ( USER app ); read-only root filesystem where possible; drop Linux capabilities. 3. No secrets in images (not in ENV , ARG or copied files — they stay in layer history). Inject at runtime via environment/secret stores (Key Vault, Kubernetes Secrets, Docker secrets); use BuildKit --mount=type=secret for build-time secrets. 4. Order instructions from least to most frequently changing for cache hits; combine RUN steps and clean package caches in the same layer. 5. .dockerignore to keep the build context small and avoid leaking files. 6. Scan images in CI (Trivy, Docker Scout, Defender) and rebuild regularly to pick up base image patches. 7. One process (concern) per container; log to stdout/stderr . 8. Add HEALTHCHECK (Docker/Compose) or liveness/readiness probes (Kubernetes). 9. Handle SIGTERM for graceful shutdown (ASP.NET Core does by default; keep the exec form). 10. Sign images (Notation/cosign) and use immutable tags."},{"kind":"lesson","course_slug":"docker","course_title":"Docker & Containers","ref":"debugging-containers","title":"Debugging containers","body":"bash docker logs --tail 100 api docker inspect api config, env, mounts, IP, health status docker exec -it api sh look around (not available in chiseled images) docker stats live CPU/memory docker top api processes docker events daemon events (OOM kills, restarts) docker run --rm -it --entrypoint sh shop-api:1.0 override entrypoint to inspect an image docker cp api:/app/appsettings.json . copy files out docker history shop-api:1.0 layers and sizes Common issues: app listening on localhost instead of 0.0.0.0 inside the container (ASP.NET Core images listen on all interfaces on 8080); wrong port mapping (80 vs 8080 after .NET 8); exit code 137 = killed (OOM or SIGKILL); 139 = segfault; container exits immediately because the main process ended; file permission errors when running as non-root; DNS between containers needs a user-defined network."},{"kind":"lesson","course_slug":"docker","course_title":"Docker & Containers","ref":"where-containers-run-in-azure","title":"Where containers run in Azure","body":"Service When --- --- Azure Container Apps Serverless containers/microservices, scale to zero, KEDA autoscaling, Dapr — easiest Azure Kubernetes Service (AKS) Full Kubernetes control, complex platforms Azure App Service (Web App for Containers) Simple web apps/APIs from an image Azure Container Instances (ACI) Single containers, batch jobs, quick runs Azure Functions on Container Apps Event-driven functions in containers Azure Container Registry (ACR) Private registry, geo-replication, ACR Tasks builds"},{"kind":"question","course_slug":"docker","course_title":"Docker & Containers","ref":"665","title":"What is Docker and why use it?","body":"Docker is a platform to build, ship and run applications in containers. A container packages the app with its runtime and dependencies, so it runs identically everywhere (\"works on my machine\" disappears). Benefits: consistent environments across dev/test/prod, fast startup, high density, isolation between apps, easy scaling, and a standard artifact for CI/CD and orchestrators like Kubernetes."},{"kind":"question","course_slug":"docker","course_title":"Docker & Containers","ref":"666","title":"What is the difference between a container and a virtual machine?","body":"A VM virtualises hardware and runs a full guest OS with its own kernel on a hypervisor — strong isolation, GBs in size, minutes to boot. A container virtualises at the OS level: isolated processes sharing the host kernel using namespaces (isolation) and cgroups (resource limits) — MBs in size, starts in seconds, much higher density. Containers can run inside VMs (as in most clouds)."},{"kind":"question","course_slug":"docker","course_title":"Docker & Containers","ref":"667","title":"What is the difference between an image and a container?","body":"An image is a read-only, layered template (filesystem + metadata) built from a Dockerfile. A container is a running (or stopped) instance of an image with its own writable layer, network and process. One image can start many containers, just like a class and its objects."},{"kind":"question","course_slug":"docker","course_title":"Docker & Containers","ref":"668","title":"Explain the common Dockerfile instructions. CMD vs ENTRYPOINT? COPY vs ADD?","body":"FROM (base image), WORKDIR, COPY/ADD, RUN (build-time command), ENV/ARG, EXPOSE, USER, HEALTHCHECK, ENTRYPOINT and CMD. ENTRYPOINT defines the executable that always runs; CMD supplies default arguments (or a default command) that docker run arguments override. COPY copies local files; ADD also auto-extracts local tar archives and can download URLs — prefer COPY for clarity and security."},{"kind":"question","course_slug":"docker","course_title":"Docker & Containers","ref":"669","title":"What is a multi-stage build and why use it?","body":"A Dockerfile with several FROM stages: an early stage (e.g. .NET SDK) compiles and publishes the app; the final stage starts from a small runtime image and copies only the build output with COPY --from=build . Result: much smaller images without compilers or source code, faster deployments, smaller attack surface — all in one Dockerfile."},{"kind":"question","course_slug":"docker","course_title":"Docker & Containers","ref":"670","title":"What is the difference between a volume and a bind mount?","body":"Volumes are managed by Docker (stored under Docker's data directory), portable, easy to back up and the preferred way to persist container data like databases. Bind mounts map a specific host path into the container — great for live-editing source code in development but tied to the host's folder structure and permissions. Data in the container's writable layer disappears when the container is removed."},{"kind":"question","course_slug":"docker","course_title":"Docker & Containers","ref":"671","title":"What is Docker Compose and when would you use it?","body":"A tool for defining and running multi-container applications with a YAML file ( compose.yaml ): services, images/builds, ports, environment, volumes, networks, dependencies and health checks. docker compose up starts everything. Used for local development environments (API + SQL Server + Redis + RabbitMQ), integration tests and simple single-host deployments. For production clusters, use Kubernetes or Azure Container Apps."},{"kind":"question","course_slug":"docker","course_title":"Docker & Containers","ref":"672","title":"How do containers in Docker communicate with each other?","body":"Through Docker networks. On a user-defined bridge network (or Compose's default network), containers resolve each other by container/service name via Docker's embedded DNS ( http://api:8080 , Server=sql ). The default bridge network doesn't provide name resolution. Published ports ( -p ) are only needed for access from the host or outside, not between containers."},{"kind":"question","course_slug":"docker","course_title":"Docker & Containers","ref":"673","title":"How do you reduce Docker image size?","body":"Use multi-stage builds; small base images (aspnet runtime instead of SDK, chiseled/Alpine variants, runtime-deps with self-contained/AOT); a .dockerignore ; combine RUN commands and remove caches in the same layer; don't install unnecessary tools; publish trimmed/AOT apps where suitable. Check layers with docker history or Dive."},{"kind":"question","course_slug":"docker","course_title":"Docker & Containers","ref":"674","title":"How do you handle secrets with Docker?","body":"Never bake secrets into images (ENV, ARG, or copied files persist in layers and history). Supply them at runtime: environment variables from a secure source, mounted secret files (Docker/Compose secrets, Kubernetes Secrets), or fetch from Azure Key Vault using managed identity. For build-time secrets (private NuGet feed tokens), use BuildKit RUN --mount=type=secret . Keep .env files out of Git."},{"kind":"question","course_slug":"docker","course_title":"Docker & Containers","ref":"675","title":"What is layer caching? How do you write a cache-friendly Dockerfile?","body":"Each instruction produces a layer; Docker reuses a cached layer if the instruction and its inputs haven't changed, and invalidates all layers after the first change. Put rarely changing steps first: copy only .csproj files and run dotnet restore before copying the rest of the source, so code changes don't re-download packages. Use BuildKit cache mounts for package caches."},{"kind":"question","course_slug":"docker","course_title":"Docker & Containers","ref":"676","title":"What do container exit codes 0, 1, 137 and 143 mean?","body":"0 = normal exit; 1 = application error; 137 = killed with SIGKILL (128+9) — often out-of-memory (OOMKilled) or forced stop after timeout; 143 = terminated by SIGTERM (128+15) — normal graceful stop; 139 = segmentation fault. Check docker inspect (State.OOMKilled) and logs."},{"kind":"question","course_slug":"docker","course_title":"Docker & Containers","ref":"677","title":"How does Docker isolate containers under the hood?","body":"Linux namespaces isolate what a process can see — PID, network, mount, UTS (hostname), IPC, user and cgroup namespaces. cgroups limit and account resources (CPU, memory, I/O). Union/overlay filesystems provide layered images with copy-on-write. Security layers: capabilities, seccomp profiles, AppArmor/SELinux, user namespaces/rootless mode. containerd and runc (OCI runtime) actually create the containers."},{"kind":"question","course_slug":"docker","course_title":"Docker & Containers","ref":"678","title":"Why did Kubernetes \"remove Docker\" and does it matter?","body":"Kubernetes 1.24 removed dockershim , the adapter that let the kubelet talk to Docker Engine. Kubernetes now talks to CRI-compatible runtimes (containerd, CRI-O) directly. Images built with Docker are OCI images and run unchanged. It only matters if something relied on the Docker socket inside nodes (e.g. Docker-in-Docker builds) — use BuildKit/Kaniko/ACR Tasks instead."},{"kind":"question","course_slug":"docker","course_title":"Docker & Containers","ref":"679","title":"Your ASP.NET Core container starts but you get \"connection refused\" on http://localhost:8080. What do you check?","body":"Is the port published ( -p 8080:8080 )? Which port does the app listen on — .NET 8+ images default to 8080 ( ASPNETCORE HTTP PORTS ), older ones to 80. Is the app bound to 0.0.0.0 / + rather than localhost inside the container? Did the container crash ( docker ps -a , docker logs )? Is HTTPS redirection forcing 443 without a certificate? On Windows, is another process using the port? Check docker inspect for port bindings and health status."},{"kind":"question","course_slug":"docker","course_title":"Docker & Containers","ref":"680","title":"The image is 2.1 GB and deploys slowly. How do you shrink it?","body":"Inspect with docker history /Dive. Typical fixes: switch to a multi-stage build so the SDK and source aren't in the final image; use mcr.microsoft.com/dotnet/aspnet (or chiseled) as the final base; add .dockerignore (bin/obj/.git/node modules); remove build tools and caches in the same RUN layer; don't copy test projects; consider trimming/AOT. Target size: ~100–250 MB for a typical ASP.NET Core API."},{"kind":"question","course_slug":"docker","course_title":"Docker & Containers","ref":"681","title":"A container keeps restarting with exit code 137. What's happening?","body":"It's being killed — most often out of memory : the container exceeded its memory limit ( docker inspect shows OOMKilled: true , or Kubernetes shows OOMKilled ). Investigate memory usage ( docker stats , dotnet-counters), raise the limit appropriately, fix leaks, and make sure .NET respects container limits (it does by default; tune DOTNET GCHeapHardLimit or Server/Workstation GC if needed). It can also be a failing liveness probe or a forced stop after SIGTERM timeout."},{"kind":"question","course_slug":"docker","course_title":"Docker & Containers","ref":"682","title":"Developers need SQL Server, Redis and RabbitMQ locally to run the API. How do you make onboarding one command?","body":"Write a compose.yaml with the API (built from its Dockerfile), SQL Server (named volume + health check), Redis and RabbitMQ (management image), a shared network, and environment variables pointing the API at service names; put passwords in a .env file excluded from Git with a .env.example template; add a seed/migration step (EF migration bundle container or init script). Onboarding = git clone && docker compose up -d . Alternatively use .NET Aspire's AppHost to orchestrate the same dependencies."},{"kind":"cheat","course_slug":"docker","course_title":"Docker & Containers","ref":"1","title":"CLI","body":"bash docker build -t app:1.0 . docker run -d -p 8080:8080 --name a app:1.0 docker ps -a docker logs -f a docker exec -it a sh docker stop a && docker rm a docker images docker rmi app:1.0 docker tag app:1.0 myacr.azurecr.io/app:1.0 docker push myacr.azurecr.io/app:1.0 docker pull ... docker volume ls / create / rm docker network ls / create docker inspect a docker stats docker system prune -a docker history app:1.0"},{"kind":"cheat","course_slug":"docker","course_title":"Docker & Containers","ref":"2","title":"Compose","body":"bash docker compose up -d --build ps logs -f svc exec svc sh down [-v]"},{"kind":"cheat","course_slug":"docker","course_title":"Docker & Containers","ref":"3","title":"Dockerfile essentials","body":"FROM · WORKDIR · COPY (prefer) / ADD · RUN · ENV / ARG · EXPOSE · USER · HEALTHCHECK · ENTRYPOINT (exec form) + CMD (default args) · multi-stage COPY --from=build ."},{"kind":"cheat","course_slug":"docker","course_title":"Docker & Containers","ref":"4","title":".NET specifics","body":"Images: sdk / aspnet / runtime / runtime-deps · .NET 8+: port 8080 , non-root app user · dotnet publish -t:PublishContainer · chiseled images."},{"kind":"cheat","course_slug":"docker","course_title":"Docker & Containers","ref":"5","title":"Lifecycle","body":"Created → Running → Paused → Exited → Removed · stop = SIGTERM then SIGKILL (10 s) · restart policies: no / on-failure / always / unless-stopped."},{"kind":"cheat","course_slug":"docker","course_title":"Docker & Containers","ref":"6","title":"Exit codes","body":"0 ok · 1 app error · 137 SIGKILL/OOM · 139 segfault · 143 SIGTERM."},{"kind":"cheat","course_slug":"docker","course_title":"Docker & Containers","ref":"7","title":"Best practices","body":"Multi-stage · small pinned base · non-root · no secrets in layers · .dockerignore · cache-friendly order · scan images · logs to stdout · health checks · immutable tags."},{"kind":"course","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"","title":"Kubernetes (K8s) & AKS","body":"Cluster architecture, pods, deployments, services, ingress, ConfigMaps and Secrets, probes, resources and autoscaling, storage, StatefulSets, namespaces, RBAC, Helm, rolling updates, troubleshooting and Azure Kubernetes Service. Kubernetes is an open-source container orchestration platform: you declare the desired state (e.g. \"run 3 replicas of shop-api:1.4, expose them on port 80\"), and Kubernetes continuously makes the actual state match — scheduling containers onto machines, restarting failed ones, scaling, rolling out updates and load balancing. Created at Google (inspired by its internal Borg system), open-sourced in 2014, donated to the CNCF (Cloud Native Computing Foundation) in 2015. \"K8s\" = K + 8 letters + s. Managed offerings: AKS (Azure Kubernetes Service), EKS (AWS), GKE (Google). Local: kind, minikube, k3d, Docker Desktop's Kubernetes. What Kubernetes gives you: self-healing, horizontal scaling, service discovery and load balancing, rolling updates and rollbacks, config and secret management, storage orchestration, batch jobs, and an extensible API (CRDs and operators). Version Year Notable --- --- --- 1.0 Jul 2015 First stable release; CNCF formed 1.2–1.6 2016–2017 Deployments, ConfigMaps, DaemonSets, StatefulSets (1.5 beta → 1.9 GA), RBAC (1.6 beta, GA 1.8) 1.7–1.16 2017–2019 CRDs, CSI storage, Ingress v1beta1, CoreDNS default (1.13) 1.19 2020 Ingress networking.k8s.io/v1 GA; support window extended to 1 year 1.20 2020 Dockershim deprecated 1.24 May 2022 Dockershim removed (containerd/CRI-O) 1.25 2022 PodSecurityPolicy removed → Pod Security Admission 1.27–1.30 2023–2024 In-place pod resize (alpha), sidecar containers (beta 1.29), Gateway API v1.0 (separate project) 1.31–1.34 2024–2025 Sidecars GA (1.33), in-place pod resize beta, Dynamic Resource Allocation for GPUs (GA 1.34) Kubernetes releases three minor versions per year , each supported upstream for about 14 months (≈ the three latest minors). AKS supports roughly the latest three GA minor versions (plus Long-Term Support for selected versions on Premium tier) — clusters must be upgraded regularly. Pod lifecycle phases: Pending (accepted, waiting for scheduling/image pull) → Running (bound to a node, at least one container running) → Succeeded (all containers exited 0 — Jobs) or Failed (a container exited non-zero and won't restart) — plus Unknown (node unreachable). Container states: Waiting (e.g. ContainerCreating , ImagePullBackOff , CrashLoopBackOff ), Running, Terminated. Pod startup sequence: scheduler picks a node → kubelet pulls images → init containers run in order to completion → app containers (and sidecars) start → postStart hook → startup probe → readiness probe passes → pod added to Service endpoints → liveness probe keeps checking. Pod termination: pod marked Terminating → removed from Service endpoints → preStop hook → SIGTERM sent → app shuts down gracefully → after terminationGracePeriodSeconds (default 30 s ) → SIGKILL. Deployment rollout lifecycle: new ReplicaSet created → pods scaled up/old down according to maxSurge / maxUnavailable → readiness gates progress → rollout complete (or stuck → kubectl rollout undo ). Revision history kept ( revisionHistoryLimit , default 10). Cluster lifecycle (AKS): create cluster/node pools → deploy workloads → monitor → upgrade control plane then node pools (node image and Kubernetes version) → scale → eventually decommission. Tool Use --- --- kubectl CLI for everything Helm Package manager (charts, releases, values) Kustomize ( kubectl apply -k ) Template-free overlays per environment k9s, Lens/Headlamp, Kubernetes Dashboard Cluster UIs kind, minikube, k3d, Docker Desktop Local clusters Azure CLI ( az aks ), Azure portal AKS management Argo CD, Flux GitOps continuous delivery KEDA Event-driven autoscaling (queues, Kafka, cron) Prometheus + Grafana, Azure Monitor Container Insights Metrics and dashboards Istio, Linkerd Service mesh cert-manager, external-dns, ingress-nginx / Application Gateway for Containers TLS, DNS, ingress Trivy, Kubescape, kube-bench Security scanning"},{"kind":"lesson","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"cluster-architecture","title":"Cluster architecture","body":"Control plane (managed by Azure in AKS): Component Role --- --- kube-apiserver Front door — all reads/writes go through the REST API; authentication, authorisation, admission etcd Consistent key-value store holding all cluster state kube-scheduler Assigns new pods to nodes (resources, affinity, taints) kube-controller-manager Runs controllers (Deployment, ReplicaSet, Node, Job...) that reconcile desired vs actual state cloud-controller-manager Integrates with the cloud (load balancers, disks, routes) Worker nodes: Component Role --- --- kubelet Agent ensuring the pods assigned to the node are running and healthy kube-proxy Programs networking rules (iptables/IPVS) for Services (or replaced by eBPF, e.g. Cilium) Container runtime containerd / CRI-O run the containers Everything is declarative : you kubectl apply YAML manifests describing desired state; controllers loop forever to converge."},{"kind":"lesson","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"pods-replicasets-and-deployments","title":"Pods, ReplicaSets and Deployments","body":"- Pod — smallest deployable unit: one or more containers sharing network (same IP, localhost) and volumes. Pods are ephemeral — never manage them directly in production. - ReplicaSet — keeps N identical pods running. - Deployment — manages ReplicaSets for stateless apps; adds rolling updates, rollbacks and history. yaml apiVersion: apps/v1 kind: Deployment metadata: name: shop-api labels: { app: shop-api } spec: replicas: 3 selector: matchLabels: { app: shop-api } strategy: type: RollingUpdate rollingUpdate: { maxSurge: 1, maxUnavailable: 0 } template: metadata: labels: { app: shop-api } spec: containers: - name: api image: myacr.azurecr.io/shop-api:1.4.2 ports: - containerPort: 8080 env: - name: ASPNETCORE ENVIRONMENT value: Production resources: requests: { cpu: 250m, memory: 256Mi } limits: { memory: 512Mi } readinessProbe: httpGet: { path: /health/ready, port: 8080 } initialDelaySeconds: 5 periodSeconds: 10 livenessProbe: httpGet: { path: /health/live, port: 8080 } periodSeconds: 15 failureThreshold: 3 Labels (key/value tags) + selectors connect objects: the Deployment selects its pods, a Service selects pods to route to."},{"kind":"lesson","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"services-and-service-types","title":"Services and service types","body":"Pods come and go with changing IPs; a Service gives a stable virtual IP and DNS name ( shop-api.default.svc.cluster.local , or just shop-api in the same namespace) and load-balances to ready pods matching its selector. Type Exposes Use --- --- --- ClusterIP (default) Internal virtual IP only Service-to-service NodePort A port (30000–32767) on every node Testing, legacy LoadBalancer Cloud load balancer with external IP Expose a service directly (one LB per service) ExternalName DNS CNAME to an external host Alias external services Headless ( clusterIP: None ) DNS returns pod IPs StatefulSets, client-side discovery yaml apiVersion: v1 kind: Service metadata: { name: shop-api } spec: type: ClusterIP selector: { app: shop-api } ports: - port: 80 service port targetPort: 8080 container port"},{"kind":"lesson","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"ingress-and-the-gateway-api","title":"Ingress and the Gateway API","body":"An Ingress routes external HTTP(S) traffic to Services by host and path, with TLS termination — one load balancer for many services. It needs an ingress controller (ingress-nginx, Azure Application Gateway Ingress Controller / Application Gateway for Containers, Traefik, HAProxy). yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: shop annotations: cert-manager.io/cluster-issuer: letsencrypt spec: ingressClassName: nginx tls: - hosts: [shop.example.com] secretName: shop-tls rules: - host: shop.example.com http: paths: - path: /api pathType: Prefix backend: { service: { name: shop-api, port: { number: 80 } } } - path: / pathType: Prefix backend: { service: { name: shop-web, port: { number: 80 } } } The Gateway API (GatewayClass, Gateway, HTTPRoute) is the more expressive successor to Ingress (traffic splitting, header matching, role separation). Note: the community ingress-nginx project announced retirement (maintenance ends March 2026) — new clusters should evaluate Gateway API implementations or other controllers."},{"kind":"lesson","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"configmaps-and-secrets","title":"ConfigMaps and Secrets","body":"yaml apiVersion: v1 kind: ConfigMap metadata: { name: shop-config } data: Logging LogLevel Default: \"Information\" FeatureFlags NewCheckout: \"true\" --- apiVersion: v1 kind: Secret metadata: { name: shop-secrets } type: Opaque stringData: ConnectionStrings Db: \"Server=tcp:sql.example.net;Database=Shop;Authentication=Active Directory Workload Identity\" yaml in the container spec envFrom: - configMapRef: { name: shop-config } - secretRef: { name: shop-secrets } volumeMounts: - { name: cfg, mountPath: /app/config, readOnly: true } volumes: - name: cfg configMap: { name: shop-config } Secrets are only base64-encoded , not encrypted, by default — enable etcd encryption at rest, restrict access with RBAC, and prefer external secret stores: Azure Key Vault via the Secrets Store CSI Driver , External Secrets Operator, plus Workload Identity so pods authenticate to Azure without stored credentials. Env vars from ConfigMaps don't update in running pods (restart needed); mounted files do update."},{"kind":"lesson","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"probes-liveness-readiness-and-startup","title":"Probes: liveness, readiness and startup","body":"Probe Question On failure --- --- --- Liveness Is the process stuck/dead? Container restarted Readiness Can it serve traffic now? Removed from Service endpoints (not restarted) Startup Has it finished starting? Liveness/readiness wait until it succeeds; failure → restart Probe types: httpGet , tcpSocket , exec , grpc . In ASP.NET Core map separate endpoints: /health/live (process OK — don't check dependencies, or a DB blip restarts every pod) and /health/ready (dependencies like DB reachable)."},{"kind":"lesson","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"resources-qos-and-autoscaling","title":"Resources, QoS and autoscaling","body":"- requests — what the scheduler reserves (placement decisions). limits — the maximum: CPU over limit is throttled ; memory over limit → container OOMKilled . - QoS classes: Guaranteed (requests = limits for all), Burstable (requests < limits), BestEffort (none — evicted first). - HPA (Horizontal Pod Autoscaler) — scales replicas on CPU/memory or custom/external metrics. - VPA — recommends/adjusts requests. Cluster Autoscaler / AKS Node Auto Provisioning (Karpenter) — adds/removes nodes when pods can't be scheduled. - KEDA — scale on events (Service Bus queue length, Kafka lag, cron), including to zero. - PodDisruptionBudget — keep minimum replicas available during voluntary disruptions (node upgrades/drains). - ResourceQuota / LimitRange — per-namespace caps and defaults. yaml apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: { name: shop-api } spec: scaleTargetRef: { apiVersion: apps/v1, kind: Deployment, name: shop-api } minReplicas: 3 maxReplicas: 20 metrics: - type: Resource resource: { name: cpu, target: { type: Utilization, averageUtilization: 70 } }"},{"kind":"lesson","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"workload-types-statefulset-daemonset-job-cronjob","title":"Workload types: StatefulSet, DaemonSet, Job, CronJob","body":"Object Use --- --- Deployment Stateless apps (APIs, web) StatefulSet Stateful apps needing stable identity and storage: ordered pods db-0 , db-1 , each with its own PersistentVolumeClaim, stable DNS via a headless Service DaemonSet One pod per node: log collectors, monitoring agents, CNI Job Run to completion (migrations, batch) with retries CronJob Scheduled Jobs ( schedule: \"0 2 \" )"},{"kind":"lesson","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"storage-volumes-pv-pvc-and-storageclass","title":"Storage: volumes, PV, PVC and StorageClass","body":"- Volume types: emptyDir (scratch, lives with the pod), configMap , secret , hostPath (avoid), persistentVolumeClaim , CSI volumes. - PersistentVolume (PV) — a piece of storage in the cluster. PersistentVolumeClaim (PVC) — a pod's request for storage (size, access mode). StorageClass — how to provision dynamically (AKS: managed-csi Azure Disk, azurefile-csi Azure Files). - Access modes: ReadWriteOnce (one node), ReadOnlyMany, ReadWriteMany (Azure Files), ReadWriteOncePod. - Reclaim policy: Delete or Retain. For production databases, prefer managed services (Azure SQL, Cosmos DB, Azure Database for PostgreSQL) over running them in the cluster unless you have strong reasons."},{"kind":"lesson","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"namespaces-rbac-and-security","title":"Namespaces, RBAC and security","body":"- Namespaces — logical partitions (dev/test/team-a) for names, quotas, RBAC and network policies. - RBAC — Role / ClusterRole (verbs on resources) bound to users/groups/ServiceAccounts with RoleBinding / ClusterRoleBinding . AKS integrates with Microsoft Entra ID and Azure RBAC. - ServiceAccounts — identities for pods; with AKS Workload Identity they map to Entra managed identities to access Key Vault, Storage, SQL without secrets. - NetworkPolicies — firewall rules between pods (default: all pods can talk to each other). - Pod Security Standards (Privileged/Baseline/Restricted) via Pod Security Admission; run as non-root, read-only root FS, drop capabilities. - Image hygiene: private registry (ACR attached to AKS), scanning, admission policies (Azure Policy/Gatekeeper/Kyverno)."},{"kind":"lesson","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"kubectl-essentials","title":"kubectl essentials","body":"bash kubectl get nodes kubectl get pods -n shop -o wide kubectl get deploy,svc,ingress -A kubectl describe pod shop-api-7d9f8-abcde -n shop events: scheduling, image pulls, probe failures kubectl logs shop-api-7d9f8-abcde -n shop [-c api] [--previous] [-f] kubectl exec -it shop-api-7d9f8-abcde -n shop -- sh kubectl apply -f k8s/ declarative create/update kubectl delete -f k8s/deployment.yaml kubectl scale deploy shop-api --replicas=5 -n shop kubectl set image deploy/shop-api api=myacr.azurecr.io/shop-api:1.4.3 -n shop kubectl rollout status deploy/shop-api -n shop kubectl rollout history deploy/shop-api -n shop kubectl rollout undo deploy/shop-api -n shop [--to-revision=3] kubectl port-forward svc/shop-api 8080:80 -n shop kubectl top pods -n shop needs metrics-server kubectl get events -n shop --sort-by=.lastTimestamp kubectl config get-contexts / use-context aks-prod kubectl explain deployment.spec.strategy"},{"kind":"lesson","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"deployment-strategies","title":"Deployment strategies","body":"Strategy How Trade-off --- --- --- Rolling update (default) Replace pods gradually ( maxSurge , maxUnavailable ) Zero downtime; old and new run side by side briefly — keep APIs/DB backward compatible Recreate Kill all old, then start new Downtime; for apps that can't run two versions Blue-green Two full environments; switch the Service selector/ingress Instant switch and rollback; double resources Canary Send a small % of traffic to the new version, then increase Low-risk; needs ingress/mesh traffic splitting (Argo Rollouts, Flagger, Gateway API weights) A/B Route by header/user segment Experiments"},{"kind":"lesson","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"helm-and-gitops","title":"Helm and GitOps","body":"bash helm create shop-api chart skeleton: Chart.yaml, values.yaml, templates/ helm install shop ./shop-api -n shop -f values-prod.yaml --set image.tag=1.4.2 helm upgrade --install shop ./shop-api -n shop -f values-prod.yaml helm list -n shop helm history shop -n shop helm rollback shop 3 -n shop helm template ./shop-api -f values-prod.yaml render YAML locally yaml templates/deployment.yaml (excerpt) image: \"{{ .Values.image.repository }}:{{ .Values.image.tag }}\" replicas: {{ .Values.replicaCount }} GitOps (Argo CD, Flux): the desired state lives in Git; an in-cluster agent pulls and applies changes and reverts drift. Deployments become pull requests; rollback = git revert."},{"kind":"lesson","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"troubleshooting-common-pod-problems","title":"Troubleshooting common pod problems","body":"Status/symptom Likely cause Check --- --- --- Pending Not enough CPU/memory, node selector/taints, PVC not bound kubectl describe pod events, kubectl get nodes , quotas ImagePullBackOff / ErrImagePull Wrong image/tag, registry auth (ACR not attached), network describe pod , az aks check-acr CrashLoopBackOff App exits on start: bad config, missing secret, exception, failing liveness probe kubectl logs --previous , env/secret refs, probe settings OOMKilled Memory limit too low or a leak describe pod (Last State), kubectl top , raise limit/fix leak CreateContainerConfigError Missing ConfigMap/Secret key describe pod Running but not receiving traffic Readiness failing, Service selector/labels mismatch, wrong targetPort kubectl get endpoints svc , labels, probes 502/503 from ingress No ready endpoints, wrong service port, TLS/host mismatch ingress controller logs, endpoints Service DNS fails CoreDNS issues, wrong namespace in name nslookup svc.ns.svc.cluster.local from a debug pod kubectl debug -it pod/name --image=busybox --target=api attaches an ephemeral debug container."},{"kind":"lesson","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"aks-specifics","title":"AKS specifics","body":"bash az group create -n rg-shop -l centralindia az aks create -g rg-shop -n aks-shop --node-count 3 --enable-managed-identity \\ --attach-acr myacr --enable-oidc-issuer --enable-workload-identity --generate-ssh-keys az aks get-credentials -g rg-shop -n aks-shop az aks get-upgrades -g rg-shop -n aks-shop -o table az aks upgrade -g rg-shop -n aks-shop --kubernetes-version <version az aks nodepool add -g rg-shop --cluster-name aks-shop -n gpupool --node-vm-size Standard NC6s v3 --node-taints sku=gpu:NoSchedule - Control plane free tier vs Standard tier (financially backed SLA) vs Premium (LTS). - System node pool (critical add-ons) + user node pools; spot node pools for cheap batch. - Networking: kubenet (legacy), Azure CNI / Azure CNI Overlay, Cilium dataplane. - Integrations: ACR, Key Vault CSI driver, Workload Identity, Azure Monitor/Container Insights + Managed Prometheus/Grafana, Application Gateway for Containers, Azure Policy, Defender for Containers, KEDA and Dapr add-ons, AKS Automatic (opinionated, managed configuration). - Alternatives when you don't need full Kubernetes: Azure Container Apps (built on Kubernetes + KEDA + Envoy, fully managed)."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"683","title":"What is Kubernetes and what problems does it solve?","body":"Kubernetes is an open-source container orchestrator (from Google, now CNCF). It automates deploying, scaling and operating containers across a cluster: scheduling pods onto nodes, self-healing (restarting/rescheduling failed containers), service discovery and load balancing, rolling updates and rollbacks, horizontal autoscaling, configuration and secret management, and storage orchestration — all driven by declarative desired state."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"684","title":"Explain the Kubernetes architecture.","body":"Control plane: kube-apiserver (API front end), etcd (cluster state store), kube-scheduler (places pods on nodes), kube-controller-manager (reconciliation loops), cloud-controller-manager (cloud integration). Worker nodes: kubelet (runs and monitors pods), kube-proxy (service networking rules), and a container runtime (containerd/CRI-O). In AKS, Azure manages the control plane; you manage node pools and workloads."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"685","title":"What is a Pod? Why not run containers directly?","body":"A Pod is the smallest deployable unit: one or more tightly coupled containers sharing an IP address, port space and volumes, scheduled together on one node (e.g. app + sidecar). Pods are ephemeral and replaceable, so you manage them through higher-level controllers (Deployments, StatefulSets, Jobs) that recreate and scale them, instead of running bare containers or bare pods."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"686","title":"What is the difference between a Deployment, a ReplicaSet and a StatefulSet?","body":"A ReplicaSet keeps a set number of identical pod replicas running. A Deployment manages ReplicaSets to provide declarative updates, rolling updates, rollbacks and revision history for stateless apps — you normally use Deployments, not ReplicaSets directly. A StatefulSet is for stateful apps: pods get stable names ( app-0 , app-1 ), stable network identities via a headless Service, ordered start/stop, and their own persistent volumes."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"687","title":"What are the Service types in Kubernetes?","body":"ClusterIP (default; stable internal IP/DNS for pod-to-pod traffic), NodePort (exposes a port on each node), LoadBalancer (provisions a cloud load balancer with an external IP), ExternalName (DNS alias to an external name). A headless Service ( clusterIP: None ) returns pod IPs directly. Services select pods by labels and load-balance to ready endpoints."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"688","title":"What is a namespace?","body":"A virtual partition inside a cluster that scopes names and lets you apply RBAC, resource quotas, limit ranges and network policies per team or environment. Default namespaces: default , kube-system , kube-public , kube-node-lease . DNS for services includes the namespace ( svc.namespace.svc.cluster.local ). Nodes and PersistentVolumes are cluster-scoped."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"689","title":"What is the difference between ConfigMap and Secret?","body":"Both inject configuration into pods as environment variables or mounted files. ConfigMaps hold non-sensitive data. Secrets hold sensitive data (passwords, keys, certificates); they're base64-encoded (not encrypted by default), can be encrypted at rest in etcd, have tighter RBAC, and are mounted on tmpfs. In production, source secrets from Azure Key Vault (Secrets Store CSI driver / External Secrets) with Workload Identity."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"690","title":"Explain liveness, readiness and startup probes.","body":"Liveness checks whether the container is alive; failing it causes a restart (use for deadlocks/hangs; don't include dependency checks). Readiness checks whether it can serve traffic; failing removes the pod from Service endpoints without restarting (use for warm-up and dependency availability). Startup probes protect slow-starting apps — liveness and readiness don't run until the startup probe succeeds."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"691","title":"What is the difference between resource requests and limits? What happens when exceeded?","body":"Requests are the guaranteed amount used by the scheduler to place pods. Limits are the maximum a container may use. Exceeding the CPU limit causes throttling (slower, not killed); exceeding the memory limit gets the container OOMKilled. Requests/limits determine QoS (Guaranteed, Burstable, BestEffort), which affects eviction order under node pressure. Set requests based on observed usage; many teams set memory limits but avoid CPU limits to prevent throttling."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"692","title":"How does a rolling update work? How do you roll back?","body":"When the pod template changes (e.g. new image), the Deployment creates a new ReplicaSet and gradually scales it up while scaling the old one down, respecting maxSurge (extra pods allowed) and maxUnavailable , and waiting for readiness. If the new version is bad: kubectl rollout undo deployment/name (or --to-revision ), or helm rollback . Check with kubectl rollout status/history ."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"693","title":"What is an Ingress? How is it different from a LoadBalancer Service?","body":"A LoadBalancer Service exposes one service with its own cloud load balancer at layer 4. An Ingress is a layer-7 (HTTP/HTTPS) routing rule set — host and path based routing, TLS termination — handled by an ingress controller behind a single load balancer for many services. The Gateway API is the newer, more powerful successor."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"694","title":"What is Helm?","body":"The package manager for Kubernetes. A chart bundles templated manifests plus default values.yaml ; you install it as a release with environment-specific values, upgrade, view history and roll back. It removes copy-paste YAML across environments and lets you share apps (e.g. installing ingress-nginx, cert-manager, Prometheus from public charts)."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"695","title":"How does autoscaling work in Kubernetes?","body":"HPA adjusts the number of pod replicas based on metrics (CPU/memory via metrics-server, or custom/external metrics). VPA adjusts pod resource requests. Cluster Autoscaler (or Node Auto Provisioning/Karpenter) adds or removes nodes when pods are unschedulable or nodes are underused. KEDA scales on event sources like queue length, including to zero. Requests must be set for CPU-based HPA to work."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"696","title":"How do you secure a Kubernetes cluster?","body":"Entra ID integration and least-privilege RBAC; separate namespaces; NetworkPolicies (default deny); Pod Security Standards (non-root, read-only FS, no privilege escalation); private registry with image scanning and admission policies (Azure Policy/Gatekeeper/Kyverno); secrets in Key Vault via CSI + Workload Identity; etcd encryption; private cluster/API server authorised IP ranges; keep Kubernetes and node images patched; Defender for Containers; audit logs; limit cluster-admin ."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"697","title":"What is a sidecar container? Give examples.","body":"A helper container in the same pod as the main app, sharing its network and volumes, that adds functionality without changing the app: service mesh proxies (Envoy/Istio), log shippers, config reloaders, Dapr sidecar, auth proxies. Kubernetes 1.29+ supports native sidecars (init containers with restartPolicy: Always ) that start before and stop after the main container."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"698","title":"What happens when you run `kubectl apply -f deployment.yaml`?","body":"kubectl sends the manifest to the API server → authentication, authorisation (RBAC) and admission controllers (validation/mutation) → object stored in etcd → the Deployment controller sees it and creates/updates a ReplicaSet → the ReplicaSet controller creates Pod objects → the scheduler assigns each pod to a node → the kubelet on that node pulls images via the container runtime and starts containers → probes report health → endpoints controller adds ready pods to Services."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"699","title":"A pod is stuck in CrashLoopBackOff. How do you troubleshoot?","body":"kubectl describe pod (events, last state, exit code, probe failures); kubectl logs <pod --previous to see why the last run died. Common causes: unhandled exception at startup (bad connection string, missing env var/secret key), wrong command/entrypoint, liveness probe failing too early (add a startup probe/initialDelay), permission errors (non-root), OOMKilled (exit 137). Reproduce locally with the same image and env; fix config and redeploy."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"700","title":"After deploying a new version, users get errors for a few seconds on every release. How do you get true zero-downtime deployments?","body":"Ensure readiness probes reflect real readiness so traffic only reaches ready pods; set maxUnavailable: 0 and maxSurge: 1+ ; handle SIGTERM gracefully (ASP.NET Core does — finish in-flight requests) and add a short preStop sleep so endpoints are removed from load balancers before shutdown; set an adequate terminationGracePeriodSeconds ; run ≥ 2–3 replicas with a PodDisruptionBudget; keep API and DB changes backward compatible (expand-contract) because old and new versions overlap."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"701","title":"Pods are Pending with \"0/3 nodes are available: insufficient memory\". What do you do?","body":"Pod requests exceed free allocatable memory on all nodes. Options: check whether requests are oversized (right-size them using actual usage), scale the node pool or enable the cluster autoscaler/node auto-provisioning, add a node pool with larger VMs, remove unused workloads, check ResourceQuotas and taints/node selectors preventing placement. Verify with kubectl describe nodes (Allocated resources) and kubectl top nodes ."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"702","title":"The API in AKS must read secrets from Azure Key Vault without storing any credentials. How?","body":"Enable the OIDC issuer and Workload Identity on AKS; create a user-assigned managed identity with Key Vault access (RBAC role \"Key Vault Secrets User\"); create a federated credential linking the identity to the Kubernetes ServiceAccount; annotate the ServiceAccount and label pods to use it. Then either use the Secrets Store CSI Driver (mount secrets as files/sync to K8s Secrets) or call Key Vault from code with DefaultAzureCredential . No passwords stored anywhere."},{"kind":"question","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"703","title":"Should you run SQL Server inside Kubernetes for production?","body":"Usually no. Stateful databases need careful handling of storage, backups, HA, failover and upgrades; a managed service (Azure SQL Database/Managed Instance) gives backups, HA, patching and SLAs out of the box. Running databases in Kubernetes (StatefulSets, operators) is viable for teams with strong expertise or specific needs (portability, edge, dev/test). Keep the cluster for stateless services and connect to managed data stores."},{"kind":"cheat","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"1","title":"Architecture","body":"Control plane: API server · etcd · scheduler · controller manager · cloud controller. Nodes: kubelet · kube-proxy · container runtime."},{"kind":"cheat","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"2","title":"Objects","body":"Pod · ReplicaSet · Deployment · StatefulSet · DaemonSet · Job · CronJob · Service (ClusterIP/NodePort/LoadBalancer/ExternalName/headless) · Ingress / Gateway API · ConfigMap · Secret · PV / PVC / StorageClass · Namespace · ServiceAccount · Role/RoleBinding · NetworkPolicy · HPA · PDB · ResourceQuota."},{"kind":"cheat","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"3","title":"kubectl","body":"bash kubectl get pods -A -o wide kubectl describe pod <p kubectl logs <p --previous -f kubectl exec -it <p -- sh kubectl apply -f file.yaml kubectl delete -f file.yaml kubectl rollout status history undo deploy/<d kubectl scale deploy/<d --replicas=5 kubectl port-forward svc/<s 8080:80 kubectl top pods kubectl get events --sort-by=.lastTimestamp"},{"kind":"cheat","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"4","title":"Probes","body":"Liveness → restart · Readiness → remove from endpoints · Startup → delay others."},{"kind":"cheat","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"5","title":"Resources","body":"Requests (scheduling) · Limits (CPU throttle, memory OOMKill) · QoS: Guaranteed / Burstable / BestEffort."},{"kind":"cheat","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"6","title":"Pod phases & errors","body":"Pending · Running · Succeeded · Failed · Unknown — ImagePullBackOff · CrashLoopBackOff · OOMKilled · CreateContainerConfigError ."},{"kind":"cheat","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"7","title":"Deploy strategies","body":"Rolling (default) · Recreate · Blue-green · Canary · A/B. Rollback: kubectl rollout undo / helm rollback ."},{"kind":"cheat","course_slug":"kubernetes","course_title":"Kubernetes (K8s) & AKS","ref":"8","title":"AKS","body":"az aks create/get-credentials/upgrade/nodepool add · attach ACR · Workload Identity + Key Vault CSI · Azure CNI · Container Insights · KEDA · AKS Automatic · consider Azure Container Apps for simpler needs."},{"kind":"course","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"","title":"Azure DevOps & CI/CD","body":"Boards, Repos, Pipelines, Test Plans and Artifacts; YAML pipelines (stages, jobs, steps, templates, variables, environments, approvals), agents, service connections, branching and release strategies, and DevOps practices. DevOps is a culture and set of practices that unite development and operations to deliver software faster, more reliably and continuously — automation (CI/CD, infrastructure as code), collaboration, monitoring and feedback. Azure DevOps (cloud: Azure DevOps Services ; on-prem: Azure DevOps Server ) is Microsoft's suite of DevOps tools: Service Purpose --- --- Azure Boards Work tracking: Epics, Features, User Stories/PBIs, Tasks, Bugs; Kanban boards, sprints, backlogs, queries, dashboards Azure Repos Git repositories (and legacy TFVC), pull requests, branch policies Azure Pipelines CI/CD for any language/platform/cloud (YAML or classic) Azure Test Plans Manual and exploratory testing, test cases and suites Azure Artifacts Package feeds: NuGet, npm, Maven, Python, Universal packages Key DevOps terms: CI (continuous integration — every commit is built and tested), CD (continuous delivery — always releasable, deploy with approval; continuous deployment — automatically to production), IaC (infrastructure as code — Bicep, ARM, Terraform), shift-left (test and secure early), DORA metrics (deployment frequency, lead time for changes, change failure rate, time to restore service). Year Milestone --- --- 2005 Team Foundation Server (TFS) 2005 — on-prem ALM with TFVC 2012 Team Foundation Service (cloud preview) 2013 Git support in TFS; Visual Studio Online 2015 Renamed Visual Studio Team Services (VSTS) ; new build system 2017 YAML builds preview 2018 VSTS renamed Azure DevOps Services ; TFS → Azure DevOps Server (2019); multi-stage YAML pipelines introduced (GA 2020) 2019–2022 Azure DevOps Server 2019, 2020, 2022; environments, approvals and checks; deprecated classic release features in new orgs gradually 2023–2025 Workload identity federation for service connections (GA 2024), GitHub Advanced Security for Azure DevOps, Managed DevOps Pools (2024), Azure DevOps Server (2025, version-less \"modern lifecycle\" release) Microsoft also owns GitHub ; GitHub Actions is the other major CI/CD option — many organisations use GitHub repos with Azure Boards/Pipelines, or migrate to GitHub entirely. DevOps lifecycle (infinite loop): Plan → Code → Build → Test → Release → Deploy → Operate → Monitor → (feedback) Plan... Work item lifecycle (Agile process): User Story: New → Active → Resolved → Closed (Removed). Bug: New → Active → Resolved → Closed. Scrum process: PBI: New → Approved → Committed → Done. Pull request lifecycle: create branch → commits → open PR → branch policies run (build validation pipeline, minimum reviewers, linked work items, comment resolution, status checks) → review/approve → complete (merge/squash/rebase) → branch deleted → CI on main. YAML pipeline run lifecycle: 1. Trigger — CI (push to branch/path), PR trigger, schedule (cron), pipeline completion, manual. 2. Template expansion — compile-time expressions ${{ }} and templates are expanded. 3. Stages run (sequentially by default, or by dependsOn ). 4. Each job is queued to an agent pool ; the agent downloads the repo ( checkout ), runs steps (tasks/scripts), with runtime expressions $[ ] and macro variables $( ) . 5. Artifacts published between stages. 6. Deployment jobs target environments ; approvals and checks (manual approval, business hours, Azure Monitor alerts, required template) gate them. 7. Results, logs, tests and coverage published; notifications sent; retention policy applies. Tool Use --- --- Azure DevOps portal (dev.azure.com/{org}) Everything az devops / az pipelines / az repos / az boards CLI Scripting Microsoft-hosted agents ( ubuntu-latest , windows-latest , macos-latest ) Zero-maintenance build machines Self-hosted agents / Managed DevOps Pools / VM scale set agents Private network access, custom tools Visual Studio / VS Code / Git Repos, PRs, work item linking (AB 123) Bicep / ARM / Terraform / Pulumi Infrastructure as code SonarQube/SonarCloud, Microsoft Defender for DevOps, GitHub Advanced Security for Azure DevOps Quality and security scanning Azure Key Vault (variable groups linked) Secrets Azure Monitor / Application Insights Monitor deployments GitHub Actions Alternative CI/CD"},{"kind":"lesson","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"azure-boards-and-agile-planning","title":"Azure Boards and Agile planning","body":"- Process templates: Basic (Epic → Issue → Task), Agile (Epic → Feature → User Story → Task, Bug), Scrum (Epic → Feature → Product Backlog Item → Task, Bug, Impediment), CMMI (Requirement, Change Request, Risk). Inherited processes allow custom fields/states. - Backlogs (prioritised list), Boards (Kanban columns, WIP limits, swimlanes), Sprints (iteration paths, capacity, burndown), Area paths (teams/components), Queries (WIQL), Dashboards , Delivery plans . - Link commits/PRs to work items with AB 1234 (GitHub) or the work item ID in Azure Repos; PR completion can auto-resolve linked items."},{"kind":"lesson","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"azure-repos-branching-strategies-and-branch-policies","title":"Azure Repos, branching strategies and branch policies","body":"Branching strategies: Strategy Description Fits --- --- --- Trunk-based Short-lived feature branches merged to main daily; feature flags CI/CD, high deploy frequency GitHub flow main always deployable; feature branch → PR → merge → deploy Web apps, SaaS GitFlow main , develop , feature/ , release/ , hotfix/ Scheduled releases, multiple versions Release branches release/2026.10 cut for stabilisation, fixes cherry-picked Enterprise products Branch policies on main : require PR (no direct pushes), minimum number of reviewers (and reset votes on new pushes), linked work items, comment resolution, build validation (PR pipeline must pass), automatically included reviewers (CODEOWNERS-like by path), limit merge types (squash), status checks (SonarQube, security)."},{"kind":"lesson","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"yaml-pipeline-structure","title":"YAML pipeline structure","body":"yaml azure-pipelines.yml trigger: branches: { include: [main] } paths: { exclude: [docs/ , README.md] } pr: branches: { include: [main] } pool: vmImage: ubuntu-latest variables: buildConfiguration: Release dotnetVersion: 10.0.x stages: - stage: Build jobs: - job: BuildTest steps: - task: UseDotNet@2 inputs: { packageType: sdk, version: $(dotnetVersion) } - script: dotnet restore displayName: Restore - script: dotnet build --no-restore -c $(buildConfiguration) displayName: Build - script: dotnet test --no-build -c $(buildConfiguration) --logger trx --collect:\"XPlat Code Coverage\" displayName: Test - task: PublishTestResults@2 condition: succeededOrFailed() inputs: { testResultsFormat: VSTest, testResultsFiles: ' / .trx' } - script: dotnet publish src/Shop.Api -c $(buildConfiguration) -o $(Build.ArtifactStagingDirectory)/api displayName: Publish - publish: $(Build.ArtifactStagingDirectory)/api artifact: api Hierarchy: Pipeline → Stages → Jobs → Steps (tasks or scripts). A job runs on one agent; jobs in a stage can run in parallel; stages run in order unless dependsOn says otherwise."},{"kind":"lesson","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"multi-stage-cd-with-environments-and-approvals","title":"Multi-stage CD with environments and approvals","body":"yaml - stage: DeployDev dependsOn: Build condition: succeeded() jobs: - deployment: DeployApi environment: shop-dev environment = deployment target + history + checks strategy: runOnce: deploy: steps: - download: current artifact: api - task: AzureWebApp@1 inputs: azureSubscription: sc-shop-dev service connection (workload identity federation) appName: app-shop-dev package: $(Pipeline.Workspace)/api - stage: DeployProd dependsOn: DeployDev condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main')) jobs: - deployment: DeployApi environment: shop-prod approvals & checks configured on this environment in the UI strategy: runOnce: deploy: steps: - download: current artifact: api - task: AzureWebApp@1 inputs: azureSubscription: sc-shop-prod appName: app-shop-prod package: $(Pipeline.Workspace)/api deployToSlotOrASE: true resourceGroupName: rg-shop-prod slotName: staging - task: AzureAppServiceManage@0 inputs: { azureSubscription: sc-shop-prod, Action: Swap Slots, WebAppName: app-shop-prod, ResourceGroupName: rg-shop-prod, SourceSlot: staging } Deployment job strategies: runOnce , rolling (VMs), canary (with increments). Approvals and checks on environments: manual approvals, branch control, business hours, Azure Monitor alerts query, invoke REST/Azure Function, exclusive lock, required template."},{"kind":"lesson","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"variables-variable-groups-secrets-and-expressions","title":"Variables, variable groups, secrets and expressions","body":"yaml variables: - group: shop-prod-secrets variable group, optionally linked to Azure Key Vault - name: imageTag value: $(Build.BuildId) - ${{ if eq(variables['Build.SourceBranchName'], 'main') }}: - name: env value: prod Syntax Evaluated Example --- --- --- ${{ variables.x }} Compile time (template expansion) conditions in templates, parameters $[ variables.x ] Runtime , before a job/stage condition , variables based on dependencies $(x) Macro , just before a task runs task inputs, scripts - Secret variables are masked in logs and not passed to scripts automatically — map them via env: . - Predefined variables : Build.BuildId , Build.SourceBranch , Build.Reason , System.DefaultWorkingDirectory , Pipeline.Workspace , Agent.OS . - Set variables from scripts: echo \" vso[task.setvariable variable=ver;isOutput=true]1.2.3\" ; output variables are used across jobs via dependencies.Job.outputs['step.ver'] . - Runtime parameters ( parameters: at top) let users pick values when running manually (typed: string, boolean, number, object)."},{"kind":"lesson","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"templates-and-reuse","title":"Templates and reuse","body":"yaml templates/dotnet-build.yml parameters: - name: project type: string - name: configuration type: string default: Release steps: - script: dotnet build ${{ parameters.project }} -c ${{ parameters.configuration }} - script: dotnet test ${{ parameters.project }} -c ${{ parameters.configuration }} azure-pipelines.yml steps: - template: templates/dotnet-build.yml parameters: { project: src/Shop.sln } Template types: step , job , stage , variable templates, and extends templates (a pipeline must extend an approved template — enforce security/compliance via the \"required template\" check). Share templates across repos with resources: repositories: ."},{"kind":"lesson","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"agents-pools-and-service-connections","title":"Agents, pools and service connections","body":"- Microsoft-hosted agents — fresh VM per job, preinstalled tools, no maintenance; limited free minutes/parallel jobs; no access to private networks. - Self-hosted agents — your VM/container; persistent caches; reach on-prem/private resources; you patch them. Scale with VM scale set agents or Managed DevOps Pools . - Parallel jobs — licensed concurrency. - Service connections — secure, reusable credentials to external systems: Azure Resource Manager (prefer workload identity federation — no secrets to rotate), Docker registry, Kubernetes, GitHub, generic. Restrict per pipeline and add approvals. - Agent capabilities/demands — route jobs to agents with required tools."},{"kind":"lesson","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"container-and-kubernetes-pipelines","title":"Container and Kubernetes pipelines","body":"yaml - task: Docker@2 inputs: containerRegistry: sc-acr repository: shop-api command: buildAndPush Dockerfile: src/Shop.Api/Dockerfile tags: $(Build.BuildId) latest - task: KubernetesManifest@1 inputs: action: deploy connectionType: azureResourceManager azureSubscriptionConnection: sc-shop-prod azureResourceGroup: rg-shop kubernetesCluster: aks-shop namespace: shop manifests: k8s/ .yaml containers: myacr.azurecr.io/shop-api:$(Build.BuildId) Also: HelmDeploy@1 task, Kubernetes environments (resource view of pods per deployment), or GitOps (pipeline updates a manifest repo; Argo CD/Flux deploys)."},{"kind":"lesson","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"infrastructure-as-code-in-pipelines","title":"Infrastructure as Code in pipelines","body":"yaml - task: AzureCLI@2 inputs: azureSubscription: sc-shop-prod scriptType: bash scriptLocation: inlineScript inlineScript: az deployment group what-if -g rg-shop-prod -f infra/main.bicep -p env=prod az deployment group create -g rg-shop-prod -f infra/main.bicep -p env=prod - Bicep (Azure-native, compiles to ARM JSON), ARM templates , Terraform (multi-cloud, state file in Azure Storage with locking), Pulumi. - Practices: plan/what-if on PR, apply after approval, store state securely, use modules, separate environments by parameters, detect drift."},{"kind":"lesson","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"azure-artifacts-and-test-plans","title":"Azure Artifacts and Test Plans","body":"- Artifacts feeds host NuGet/npm/Maven/Python/Universal packages, with upstream sources (cache nuget.org/npmjs), views ( @local , @prerelease , @release ), retention policies. Authenticate in pipelines with NuGetAuthenticate@1 . - Test Plans : test plans → suites (static, requirement-based, query-based) → test cases with steps; manual test runner, exploratory testing (Test & Feedback extension), traceability to requirements; automated tests can be associated with test cases."},{"kind":"question","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"704","title":"What is DevOps? What are CI and CD?","body":"DevOps combines development and operations culture, practices and tools to deliver value faster and more reliably: automation, collaboration, small batches, fast feedback and monitoring. CI (Continuous Integration): developers merge frequently, and every change is automatically built and tested. CD: Continuous Delivery keeps every build releasable and deploys to production with a manual approval; Continuous Deployment deploys every passing change to production automatically."},{"kind":"question","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"705","title":"What services does Azure DevOps provide?","body":"Azure Boards (work tracking, Kanban, sprints), Azure Repos (Git repos, PRs, branch policies), Azure Pipelines (CI/CD for any platform/cloud), Azure Test Plans (manual/exploratory testing), Azure Artifacts (package feeds). Available as Azure DevOps Services (cloud) and Azure DevOps Server (on-prem, formerly TFS)."},{"kind":"question","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"706","title":"Explain the structure of a YAML pipeline.","body":"A pipeline has triggers, optional variables/parameters/resources, and stages (e.g. Build, DeployDev, DeployProd); each stage contains jobs that run on an agent; each job has steps — tasks (prebuilt, like DotNetCoreCLI@2 , AzureWebApp@1 ) or scripts. Deployment jobs target environments with approvals. Artifacts pass outputs between stages."},{"kind":"question","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"707","title":"YAML pipelines vs classic pipelines?","body":"Classic build and release pipelines are configured in the web UI (release pipelines with stages, artifacts and gates). YAML pipelines are pipelines-as-code stored in the repo: versioned, reviewed in PRs, branchable, reusable via templates, and support multi-stage CI/CD with environments and checks. Microsoft recommends YAML; some classic features are being retired or disabled for new organisations."},{"kind":"question","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"708","title":"What is an agent? Microsoft-hosted vs self-hosted?","body":"An agent is software on a machine that runs pipeline jobs. Microsoft-hosted agents are fresh VMs provided per job, preconfigured with common tools, no maintenance, but no private network access and cache isn't kept. Self-hosted agents run on your machines/containers: custom tools, persistent caches, access to on-prem/private resources, but you maintain and secure them. Managed DevOps Pools offer Microsoft-managed agents with private networking."},{"kind":"question","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"709","title":"What are branch policies and why use them?","body":"Rules on protected branches (e.g. main ) enforced on pull requests: require PRs, minimum reviewers, linked work items, resolved comments, successful build validation pipeline, required reviewers by path, allowed merge types, external status checks. They keep main always buildable and reviewed, enforce quality gates, and create traceability."},{"kind":"question","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"710","title":"How do you manage secrets in Azure Pipelines?","body":"Store them as secret variables or in variable groups linked to Azure Key Vault (or fetch with the AzureKeyVault@2 task). Secrets are masked in logs and must be mapped explicitly into scripts via env . Use service connections with workload identity federation (no stored client secrets), restrict pipeline permissions on variable groups/service connections, add approvals, and never commit secrets to the repo (enable secret scanning)."},{"kind":"question","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"711","title":"What are environments, approvals and checks?","body":"An environment represents a deployment target (dev, test, prod — or Kubernetes namespaces/VMs) with deployment history and traceability. Approvals and checks configured on the environment gate deployment jobs: manual approvers, branch control (only from main), business hours, Azure Monitor alert queries, REST/Function checks, exclusive lock (one deployment at a time), required templates. They replace classic release gates."},{"kind":"question","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"712","title":"What is the difference between `${{ }}`, `$[ ]` and `$( )`?","body":"${{ }} are template (compile-time) expressions, evaluated when the YAML is parsed — used for parameters, conditional insertion and template logic. $[ ] are runtime expressions evaluated before a job/stage runs — used in conditions and variables depending on other jobs' outputs. $( ) is macro syntax replaced just before a task executes — used in task inputs and scripts."},{"kind":"question","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"713","title":"How do you reuse pipeline logic across projects?","body":"YAML templates (step, job, stage, variable templates) with typed parameters, stored in a shared repository referenced via resources.repositories ; extends templates to enforce a standard pipeline skeleton (with the required-template check on environments); variable groups for shared settings; task groups in classic pipelines."},{"kind":"question","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"714","title":"What branching strategy would you recommend and why?","body":"For most web/cloud teams: trunk-based development or GitHub flow — short-lived branches, PRs with build validation, frequent merges to main, feature flags for incomplete work, automated deployment through environments with approvals. It reduces merge conflicts and supports CI/CD. GitFlow suits products with scheduled releases and multiple supported versions but adds overhead."},{"kind":"question","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"715","title":"How do you deploy database changes in a pipeline?","body":"Generate idempotent migration scripts in CI ( dotnet ef migrations script --idempotent , SSDT DACPAC, or DbUp/Flyway scripts), publish them as artifacts, review them, apply in each environment's deployment stage before the app ( SqlAzureDacpacDeployment@1 , sqlcmd , EF migration bundle), using backward-compatible (expand/contract) changes so old and new app versions work during rollout. Back up / use point-in-time restore for rollback."},{"kind":"question","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"716","title":"How would you design a CI/CD pipeline for a .NET microservice deployed to AKS?","body":"PR pipeline: restore, build, unit tests, coverage, SonarQube, dependency and secret scanning, Docker build (no push), Bicep/Helm lint. Main pipeline: build and test → build image tagged with commit SHA → scan with Trivy/Defender → push to ACR → deploy to dev via Helm (or update a GitOps repo) → integration/smoke tests → staging with approval → canary or blue-green to production with automated health checks (App Insights/Prometheus) and automatic rollback. Use templates, workload-identity service connections, Key Vault secrets, environments with approvals, and track DORA metrics."},{"kind":"question","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"717","title":"What are DORA metrics?","body":"Four key metrics from the DevOps Research and Assessment program: Deployment frequency , Lead time for changes (commit to production), Change failure rate (% of deployments causing failures), and Time to restore service (now often \"failed deployment recovery time\"). They measure delivery performance; elite teams deploy on demand with low failure rates and fast recovery."},{"kind":"question","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"718","title":"The build is green but production broke after deployment. How do you prevent this next time?","body":"Find the gap: missing tests (add integration/contract tests for the failure), environment differences (config, data, secrets — use the same artifact and IaC everywhere), no smoke tests (add post-deploy health checks that fail the stage), big-bang releases (use canary/blue-green or slot swaps with warm-up, feature flags), and no automatic rollback (monitor key metrics and roll back on alerts). Run a blameless post-mortem and add the fix to the pipeline."},{"kind":"question","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"719","title":"Pipelines take 40 minutes and developers are frustrated. How do you speed them up?","body":"Measure each step. Then: cache NuGet/npm packages ( Cache@2 ), run independent jobs in parallel (split test projects), use incremental builds and only build changed services (path filters), use faster/self-hosted or Managed DevOps Pool agents with warm caches, avoid rebuilding — build once and promote the same artifact, move slow end-to-end tests to a nightly or post-merge stage, use Docker layer caching, and remove redundant steps."},{"kind":"question","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"720","title":"A teammate committed a production connection string to the repo. What do you do?","body":"Treat it as compromised: rotate the credential immediately (change password/key, or switch to managed identity), check access logs, remove it from the code and move it to Key Vault/variable groups, rewrite history only if required by policy (history may already be cloned), enable secret scanning/push protection (GitHub Advanced Security for Azure DevOps) and pre-commit hooks, and run a short blameless review on the process."},{"kind":"question","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"721","title":"How do you achieve zero-downtime deployments to Azure App Service from a pipeline?","body":"Deploy to a staging slot , warm it up (application initialization / health check path), run smoke tests against the slot URL, then swap slots (the swap is instantaneous and warmed); keep slot-specific settings sticky; if issues appear, swap back. Combine with backward-compatible DB migrations and feature flags."},{"kind":"cheat","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"1","title":"Azure DevOps services","body":"Boards · Repos · Pipelines · Test Plans · Artifacts."},{"kind":"cheat","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"2","title":"YAML hierarchy","body":"trigger/pr/schedules → variables/parameters/resources → stages → jobs (job / deployment) → steps (task / script / template)."},{"kind":"cheat","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"3","title":"Common tasks","body":"UseDotNet@2 · DotNetCoreCLI@2 · PublishTestResults@2 · PublishPipelineArtifact@1 · Docker@2 · AzureWebApp@1 · AzureCLI@2 · AzureKeyVault@2 · KubernetesManifest@1 · HelmDeploy@1 · SqlAzureDacpacDeployment@1 · Cache@2 · NuGetAuthenticate@1 ."},{"kind":"cheat","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"4","title":"Expressions","body":"${{ }} compile-time · $[ ] runtime · $( ) macro. Conditions: succeeded() , failed() , always() , eq() , and() , or() , contains() ."},{"kind":"cheat","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"5","title":"Triggers","body":"CI ( trigger ) · PR ( pr ) · schedules (cron) · pipeline resources (on another pipeline completing) · manual."},{"kind":"cheat","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"6","title":"Security","body":"Workload identity federation service connections · Key Vault variable groups · secret masking · branch policies · environment approvals & checks · required templates · least-privilege pipeline permissions."},{"kind":"cheat","course_slug":"azure-devops","course_title":"Azure DevOps & CI/CD","ref":"7","title":"Strategies","body":"Trunk-based / GitHub flow / GitFlow · rolling / blue-green (slots) / canary · build once, deploy many · IaC (Bicep/Terraform) · DORA metrics."},{"kind":"course","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"","title":"Microsoft Azure for .NET Developers","body":"Cloud models, Azure hierarchy and regions, App Service, Functions, Container Apps, AKS, Storage, Azure SQL, Cosmos DB, Service Bus, Event Grid, Event Hubs, Key Vault, Entra ID, managed identities, API Management, networking, monitoring, cost, security and architecture. Microsoft Azure is Microsoft's cloud platform (launched as Windows Azure in 2010, renamed in 2014) with 200+ services across compute, data, integration, AI, security and DevOps, in 60+ regions worldwide (including Central India, South India, West India and others). Cloud service models: Model You manage Azure manages Examples --- --- --- --- IaaS OS, runtime, app, data Hardware, virtualisation Virtual Machines, VM Scale Sets PaaS App and data OS, patching, runtime, scaling App Service, Azure SQL, Functions, Container Apps SaaS Just use it Everything Microsoft 365, Dynamics 365 Serverless Code/functions Infrastructure, scaling to zero Functions, Logic Apps, Container Apps Deployment models: public, private, hybrid (Azure Arc, Azure Stack), multi-cloud. AZ-204 (Developing Solutions for Microsoft Azure) is the developer certification that maps closely to this course; AZ-900 covers fundamentals; AZ-305 covers architecture. Azure is continuously updated rather than versioned. Key milestones: Year Milestone --- --- 2008 \"Project Red Dog\" announced at PDC 2010 Windows Azure GA (Cloud Services, Storage, SQL Azure) 2012 IaaS VMs, Websites (later App Service) 2014 Renamed Microsoft Azure ; Azure Resource Manager (ARM) preview 2016 Azure Functions GA; ARM becomes the standard model 2017 Cosmos DB (from DocumentDB); AKS preview (GA 2018) 2019 Azure Arc 2020 Bicep project starts (v0.3 production-ready 2021) 2021 Azure Container Apps preview (GA 2022) 2023 Azure OpenAI Service GA; Microsoft Fabric GA; Entra ID rename 2024–2025 Azure AI Foundry, Flex Consumption plan for Functions, .NET Aspire integration, Azure Developer CLI updates Cloud Services (classic) were retired in August 2024 ; the classic deployment model and Azure AD Graph were retired too — always use ARM-based resources. Azure resource hierarchy: Microsoft Entra tenant → Management groups → Subscriptions (billing and access boundary) → Resource groups (lifecycle container — deploy, manage and delete together) → Resources . Resource lifecycle: plan (region, SKU, naming, tags) → provision via ARM (portal, CLI, PowerShell, Bicep/Terraform) → configure (identity, networking, scaling) → deploy app → monitor (Azure Monitor, alerts) → scale/optimise → update/patch (PaaS: automatic) → decommission (delete resource group). Request flow for a typical web app: user → Azure Front Door (global CDN, WAF) → App Service / Container Apps (behind private networking) → app reads secrets from Key Vault with a managed identity → Azure SQL / Cosmos DB through private endpoints → events to Service Bus → background processing by Functions → telemetry to Application Insights. Azure Well-Architected Framework pillars: Reliability, Security, Cost Optimization, Operational Excellence, Performance Efficiency . Tool Use --- --- Azure portal Web UI Azure CLI ( az ) / Azure PowerShell ( Az module) Scripting Azure Developer CLI ( azd ) Templates, provision + deploy ( azd up ) Bicep / ARM templates / Terraform Infrastructure as code Visual Studio / VS Code Azure extensions Publish, debug, Azure Functions Core Tools Azure SDK for .NET ( Azure. packages), Azure.Identity ( DefaultAzureCredential ) Code access to services Azurite Local Storage emulator Cosmos DB emulator, Service Bus emulator Local development Azure Storage Explorer Browse blobs, queues, tables Azure Monitor, Application Insights, Log Analytics (KQL) Observability Azure Advisor, Cost Management, Azure Pricing Calculator Optimisation and cost Microsoft Defender for Cloud, Azure Policy Security posture and governance .NET Aspire (Aspire) Local orchestration + Azure deployment for .NET apps"},{"kind":"lesson","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"regions-availability-zones-and-the-resource-hierarchy","title":"Regions, availability zones and the resource hierarchy","body":"- Region — a set of datacenters in a geography (e.g. Central India — Pune). Choose for latency, data residency, service availability, price. - Availability zones — physically separate datacenters within a region (own power, cooling, network); zone-redundant services survive a datacenter failure. - Region pairs — regions paired for disaster recovery and staggered updates. - Subscription — billing + access boundary; resource group — logical container (same lifecycle); management groups — apply policies across subscriptions. - Tags (env, owner, cost-centre), naming conventions , resource locks (CanNotDelete, ReadOnly), Azure Policy (enforce rules: allowed regions, required tags), RBAC (who can do what)."},{"kind":"lesson","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"identity-microsoft-entra-id-rbac-and-managed-identities","title":"Identity: Microsoft Entra ID, RBAC and managed identities","body":"- Microsoft Entra ID (formerly Azure Active Directory) — cloud identity provider: users, groups, app registrations (OAuth 2.0/OIDC), conditional access, MFA. Entra External ID for customer-facing apps (successor of Azure AD B2C for new projects). - Azure RBAC — role assignments = security principal + role definition (Owner, Contributor, Reader, or data roles like Storage Blob Data Reader , Key Vault Secrets User ) + scope (management group/subscription/RG/resource). - Managed identities — Azure-managed service principals for Azure resources; no secrets in code or config. System-assigned (tied to one resource's lifecycle) or user-assigned (standalone, shareable). csharp // Same code works locally (Visual Studio/Azure CLI login) and in Azure (managed identity) var credential = new DefaultAzureCredential(); var secrets = new SecretClient(new Uri(\"https://kv-shop.vault.azure.net/\"), credential); var blobs = new BlobServiceClient(new Uri(\"https://stshop.blob.core.windows.net/\"), credential); // ASP.NET Core: load Key Vault into IConfiguration builder.Configuration.AddAzureKeyVault(new Uri(\"https://kv-shop.vault.azure.net/\"), credential);"},{"kind":"lesson","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"azure-app-service","title":"Azure App Service","body":"PaaS for web apps and APIs (.NET, Java, Node, Python, PHP; Windows or Linux; code or containers). - App Service plan = the VMs you pay for (tier: Free/Basic/Standard/Premium v3/Isolated v2); many apps can share a plan. - Features: deployment slots (staging → swap for zero downtime), autoscale (scale out instances) and scale up (bigger SKU), custom domains + managed TLS certificates, Easy Auth (built-in authentication), VNet integration and private endpoints, health check path, always on, backups, WebJobs. - Configuration: App settings and connection strings become environment variables (override appsettings.json); Key Vault references @Microsoft.KeyVault(SecretUri=...) . bash az appservice plan create -g rg-shop -n plan-shop --sku P1v3 --is-linux az webapp create -g rg-shop -p plan-shop -n app-shop-api --runtime \"DOTNETCORE:10.0\" az webapp identity assign -g rg-shop -n app-shop-api az webapp config appsettings set -g rg-shop -n app-shop-api --settings ASPNETCORE ENVIRONMENT=Production az webapp deploy -g rg-shop -n app-shop-api --src-path publish.zip --type zip az webapp deployment slot swap -g rg-shop -n app-shop-api --slot staging"},{"kind":"lesson","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"azure-functions-serverless","title":"Azure Functions (serverless)","body":"Event-driven code that runs on triggers with declarative bindings (input/output), scaling automatically. Hosting plan Notes --- --- Flex Consumption (recommended for new apps) Serverless, scale to zero, fast scale, VNet support, per-execution + memory billing Consumption (classic) Serverless, cold starts, 5–10 min default/max timeout Premium (Elastic Premium) Pre-warmed instances (no cold start), VNet, longer runs Dedicated (App Service plan) Run on existing plan, predictable cost Container Apps Functions in containers .NET uses the isolated worker model (the in-process model ends support on 10 November 2026 ). csharp public class OrderFunctions(ILogger<OrderFunctions log) { [Function(\"ProcessOrder\")] [BlobOutput(\"receipts/{rand-guid}.json\", Connection = \"Storage\")] public string Run([ServiceBusTrigger(\"orders\", Connection = \"ServiceBus\")] OrderPlaced msg) { log.LogInformation(\"Processing order {OrderId}\", msg.OrderId); return JsonSerializer.Serialize(new Receipt(msg.OrderId, DateTime.UtcNow)); } [Function(\"Health\")] public IActionResult Health([HttpTrigger(AuthorizationLevel.Anonymous, \"get\")] HttpRequest req) = new OkObjectResult(\"ok\"); [Function(\"NightlyCleanup\")] public Task Cleanup([TimerTrigger(\"0 0 2 \")] TimerInfo timer) = Task.CompletedTask; // 6-field NCRONTAB (with seconds) } Triggers: HTTP, Timer, Queue Storage, Blob, Service Bus, Event Grid, Event Hubs, Cosmos DB change feed, SQL (change tracking), Kafka, RabbitMQ. Durable Functions add stateful orchestrations: function chaining, fan-out/fan-in, async HTTP APIs, monitors, human interaction (approval with timeout), entities."},{"kind":"lesson","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"containers-container-apps-aks-aci-and-choosing-compute","title":"Containers: Container Apps, AKS, ACI and choosing compute","body":"Need Choose --- --- Web app/API, minimal ops App Service Event-driven, short tasks Functions Microservices/containers, scale to zero, Dapr/KEDA, no cluster management Azure Container Apps Full Kubernetes control, complex platform, operators/CRDs AKS Single container/batch quickly Container Instances Legacy/full OS control, lift-and-shift Virtual Machines / VM Scale Sets Big parallel batch/HPC Azure Batch Static SPA + serverless API Static Web Apps"},{"kind":"lesson","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"azure-storage-account","title":"Azure Storage account","body":"Service Stores Use --- --- --- Blob Storage Objects (files) — block, append, page blobs Images, documents, backups, data lake (ADLS Gen2 with hierarchical namespace) Queue Storage Simple messages (64 KB) Basic background work Table Storage NoSQL key-attribute Cheap structured data Azure Files SMB/NFS file shares Lift-and-shift shared folders - Access tiers for blobs: Hot , Cool (30-day min), Cold (90-day min), Archive (180-day min, offline — rehydrate hours); lifecycle management policies move/delete automatically. - Redundancy: LRS (3 copies in one datacenter), ZRS (across zones), GRS/RA-GRS (plus secondary region), GZRS/RA-GZRS . - Secure access: Entra ID RBAC + managed identity (preferred), SAS tokens (time-limited, scoped; user delegation SAS best), account keys (avoid), private endpoints, firewall. csharp var container = new BlobContainerClient(new Uri(\"https://stshop.blob.core.windows.net/invoices\"), new DefaultAzureCredential()); await container.CreateIfNotExistsAsync(); await container.GetBlobClient($\"{invoiceId}.pdf\").UploadAsync(pdfStream, overwrite: true);"},{"kind":"lesson","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"azure-sql-and-cosmos-db","title":"Azure SQL and Cosmos DB","body":"Azure SQL family: Azure SQL Database (single DB or elastic pool; vCore or DTU; serverless auto-pause; Hyperscale up to 128 TB), Azure SQL Managed Instance (near-100% SQL Server compatibility — SQL Agent, cross-DB queries; lift-and-shift), SQL Server on Azure VMs (full control). Built-in HA, automated backups with point-in-time restore, geo-replication/failover groups, Entra authentication, Defender for SQL, read replicas. Azure Cosmos DB: globally distributed, multi-model NoSQL with single-digit-millisecond latency SLA. - APIs: NoSQL (native), MongoDB (RU and vCore), Apache Cassandra, Gremlin (graph), Table, plus PostgreSQL (distributed, Citus). - Partition key choice is critical: high cardinality, evenly distributed, used in most queries (avoid hot partitions; cross-partition queries cost more). - Request Units (RU/s) — throughput currency: provisioned (manual/autoscale) or serverless. - Consistency levels (strongest → weakest): Strong, Bounded Staleness, Session (default), Consistent Prefix, Eventual . - Change feed for event-driven processing; TTL; multi-region writes. csharp var client = new CosmosClient(\"https://cosmos-shop.documents.azure.com:443/\", new DefaultAzureCredential()); var container = client.GetContainer(\"shop\", \"orders\"); // partition key: /customerId await container.UpsertItemAsync(order, new PartitionKey(order.CustomerId)); var item = await container.ReadItemAsync<Order (order.id, new PartitionKey(order.CustomerId)); // point read: ~1 RU"},{"kind":"lesson","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"caching-azure-managed-redis-azure-cache-for-redis","title":"Caching: Azure Managed Redis / Azure Cache for Redis","body":"In-memory cache for sessions, hot data, rate limiting, distributed locks, pub/sub. Use with IDistributedCache ( AddStackExchangeRedisCache ) or HybridCache's L2. Patterns: cache-aside, write-through, expiration, cache stampede protection. Microsoft is moving customers from Azure Cache for Redis to Azure Managed Redis (newer offering based on Redis Enterprise)."},{"kind":"lesson","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"service-bus-vs-event-grid-vs-event-hubs-vs-storage-queues","title":"Service Bus vs Event Grid vs Event Hubs vs Storage Queues","body":"Service Bus Event Grid Event Hubs Storage Queue --- --- --- --- --- Type Enterprise message broker Event routing (pub/sub, push) Event streaming / telemetry ingestion Simple queue Pattern Queues + topics/subscriptions Discrete reactive events (\"blob created\") High-volume streams with partitions, replay Basic work queue Features FIFO via sessions, transactions, duplicate detection, dead-letter queue, scheduled messages, at-least-once / peek-lock Filtering, retries, dead-lettering, CloudEvents, MQTT Millions events/s, consumer groups, retention, Kafka endpoint, Capture to storage 64 KB msgs, huge queues, cheap Use Orders, payments, workflows between services React to Azure resource/app events, webhooks IoT telemetry, logs, clickstreams Simple background jobs csharp await using var client = new ServiceBusClient(\"sb-shop.servicebus.windows.net\", new DefaultAzureCredential()); await using var sender = client.CreateSender(\"orders\"); await sender.SendMessageAsync(new ServiceBusMessage(BinaryData.FromObjectAsJson(order)) { MessageId = order.Id.ToString() }); await using var processor = client.CreateProcessor(\"orders\", new ServiceBusProcessorOptions { MaxConcurrentCalls = 10, AutoCompleteMessages = false }); processor.ProcessMessageAsync += async args = { var o = args.Message.Body.ToObjectFromJson<Order (); await Handle(o); await args.CompleteMessageAsync(args.Message); // otherwise retried; after MaxDeliveryCount → dead-letter queue }; processor.ProcessErrorAsync += args = Task.CompletedTask; await processor.StartProcessingAsync(); Logic Apps — low-code workflows with hundreds of connectors (Office 365, SAP, Salesforce). API Management (APIM) — API gateway: publish, secure (JWT validation, subscription keys), throttle (rate-limit policies), transform, cache, version, developer portal."},{"kind":"lesson","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"key-vault-and-app-configuration","title":"Key Vault and app configuration","body":"- Azure Key Vault — secrets, keys (HSM-backed option) and certificates; RBAC access, soft delete + purge protection, versioning, rotation, private endpoint, logging. - Azure App Configuration — central feature flags and settings with labels per environment, dynamic refresh; reference Key Vault secrets. - Access with managed identity + DefaultAzureCredential ; App Service/Functions Key Vault references avoid code changes."},{"kind":"lesson","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"networking-basics","title":"Networking basics","body":"- Virtual Network (VNet) with subnets ; NSGs (network security groups: allow/deny rules); peering between VNets; VPN Gateway / ExpressRoute to on-prem. - Private Endpoint (private IP for a PaaS service inside your VNet) vs Service Endpoint (optimised route, service still public IP); Private DNS zones . - Load balancing: Azure Load Balancer (L4, regional), Application Gateway (L7 regional + WAF), Front Door (L7 global, CDN, WAF), Traffic Manager (DNS-based global). - Azure Firewall , DDoS Protection , Bastion (secure RDP/SSH without public IPs), NAT Gateway."},{"kind":"lesson","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"monitoring-with-azure-monitor-and-application-insights","title":"Monitoring with Azure Monitor and Application Insights","body":"- Azure Monitor — metrics and logs platform; Log Analytics workspace stores logs queried with KQL ; alerts (metric, log, activity log) → action groups (email, SMS, Teams, webhooks, Functions). - Application Insights — APM for apps: requests, dependencies (SQL/HTTP), exceptions, traces, live metrics, application map, availability tests, distributed tracing. In .NET use the Azure Monitor OpenTelemetry Distro ( builder.Services.AddOpenTelemetry().UseAzureMonitor() ). kusto requests where timestamp ago(1h) summarize count(), avg(duration), percentile(duration, 95) by name, resultCode order by count desc exceptions where timestamp ago(24h) summarize count() by type, outerMessage top 10 by count"},{"kind":"lesson","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"cost-management-and-governance","title":"Cost management and governance","body":"- Pricing levers: right-size SKUs, autoscale, reserved instances / savings plans (1 or 3 years), spot VMs , serverless/scale-to-zero, dev/test pricing, auto-shutdown of dev VMs, storage tiers and lifecycle rules, delete orphaned resources (disks, public IPs). - Azure Cost Management budgets and alerts, tags for chargeback, Azure Advisor recommendations, Pricing Calculator and TCO calculator. - Governance: Azure Policy , management groups, RBAC least privilege, resource locks, landing zones (Cloud Adoption Framework)."},{"kind":"lesson","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"reference-architecture-scalable-dotnet-web-application-on-azure","title":"Reference architecture: scalable .NET web application on Azure","body":"Users → Azure Front Door (WAF, CDN, TLS) → App Service (or Container Apps) — autoscale, deployment slots, managed identity → Azure SQL (zone-redundant, failover group to paired region) via private endpoint → Azure Managed Redis (cache, sessions) → Blob Storage (files) via private endpoint → Service Bus (orders topic) → Functions / Container Apps workers (KEDA scale) → Key Vault (secrets, certificates), App Configuration (feature flags) → Application Insights + Log Analytics (alerts → Teams/on-call) CI/CD: Azure DevOps / GitHub Actions + Bicep (IaC), workload identity federation Reliability: zones + multi-region (active-passive with Front Door failover), health probes, retries/circuit breakers, queues to absorb spikes. Security: Entra ID auth, managed identities, private endpoints, WAF, Defender for Cloud. Cost: autoscale, reserved capacity for baseline, serverless for spiky workloads."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"722","title":"What are IaaS, PaaS and SaaS? Give Azure examples.","body":"IaaS provides virtualised infrastructure — you manage OS and above (Azure VMs, VM Scale Sets). PaaS provides a managed platform — you deploy code and data, Azure handles OS, patching and scaling (App Service, Azure SQL Database, Functions, Container Apps). SaaS is complete software you just use (Microsoft 365). Serverless (Functions, Logic Apps) is PaaS that scales to zero and bills per use."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"723","title":"Explain the Azure resource hierarchy.","body":"Entra ID tenant → management groups (policy and RBAC across subscriptions) → subscriptions (billing and access boundary, quotas) → resource groups (containers for resources sharing a lifecycle) → resources (web apps, databases). RBAC and Azure Policy inherit downward. A resource belongs to exactly one resource group; resources in a group can be in different regions."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"724","title":"What is a managed identity and why use it?","body":"An automatically managed identity in Entra ID for an Azure resource (App Service, Functions, VM, AKS pod via workload identity) that lets code authenticate to other Azure services (Key Vault, Storage, SQL, Service Bus) without storing any credentials. Azure handles the credentials and rotation. System-assigned is tied to one resource's lifecycle; user-assigned is a standalone identity shared by several resources. In code, use DefaultAzureCredential ."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"725","title":"What are deployment slots in App Service?","body":"Live apps with their own hostnames (e.g. app-staging.azurewebsites.net ) within the same App Service plan (Standard tier and above). You deploy to staging, warm it up and test, then swap with production — near-zero downtime and instant rollback by swapping back. Slot-specific (sticky) settings stay with the slot (e.g. connection strings for staging)."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"726","title":"What are availability zones and region pairs?","body":"Availability zones are physically separate datacenters within a region with independent power, cooling and networking; deploying across zones (zone-redundant services) protects against a datacenter failure (99.99% SLA for VMs across zones). Region pairs are two regions in the same geography used for disaster recovery (geo-redundant storage replication, sequential platform updates, prioritised recovery)."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"727","title":"Service Bus vs Event Grid vs Event Hubs — when do you use each?","body":"Service Bus is for high-value business messages between services where every message must be processed: queues/topics, FIFO with sessions, transactions, duplicate detection, dead-lettering (orders, payments). Event Grid routes discrete events (something happened) to subscribers via push with filtering — reacting to blob uploads, resource changes or custom app events. Event Hubs ingests high-volume event streams (telemetry, logs, IoT) with partitions, retention and replay for stream processing."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"728","title":"What are Azure Functions triggers and bindings? Which hosting plan would you choose?","body":"A trigger starts the function (HTTP, Timer, Service Bus, Blob, Queue, Event Grid, Event Hubs, Cosmos DB change feed); exactly one per function. Bindings declaratively connect to data as inputs/outputs (read a blob, write to a queue) without SDK code. Plans: Flex Consumption (serverless, scale to zero, VNet — the default choice for new apps), Premium (pre-warmed, no cold start, long runs), Dedicated/App Service plan (predictable cost), Container Apps. For .NET, use the isolated worker model."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"729","title":"What are Durable Functions?","body":"An extension of Azure Functions for stateful workflows in code. An orchestrator function coordinates activity functions, and state is checkpointed automatically (event sourcing in storage), so workflows can run for days and survive restarts. Patterns: function chaining, fan-out/fan-in, async HTTP APIs (status endpoint), monitoring loops, human interaction (wait for an external event with timeout), durable entities. Orchestrator code must be deterministic (no DateTime.Now , no direct I/O)."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"730","title":"How do you choose between Azure SQL Database and Cosmos DB?","body":"Azure SQL: relational data, complex joins and transactions, strong consistency, reporting, existing SQL skills — most line-of-business apps. Cosmos DB: globally distributed apps needing low latency at any scale, flexible schema JSON documents, massive throughput with predictable performance, multi-region writes, tunable consistency — e.g. catalogues, IoT, user profiles, gaming. Cosmos requires careful partition key design and RU cost planning."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"731","title":"What are Cosmos DB consistency levels?","body":"From strongest to weakest: Strong (linearizable reads — always latest), Bounded Staleness (reads lag by at most K versions or T time), Session (default — read-your-own-writes within a session), Consistent Prefix (never see out-of-order writes), Eventual (no ordering guarantee, lowest latency/cost). Stronger consistency means higher latency and RU cost, and Strong limits multi-region writes."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"732","title":"What is the difference between blob access tiers?","body":"Hot (frequent access, highest storage cost, lowest access cost), Cool (infrequent, 30-day minimum), Cold (rare, 90-day minimum), Archive (offline, cheapest storage, 180-day minimum, rehydration takes hours). Lifecycle management rules can automatically move blobs between tiers or delete them based on age."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"733","title":"How do you secure secrets for an app hosted in Azure?","body":"Store them in Azure Key Vault; give the app a managed identity with the \"Key Vault Secrets User\" RBAC role; read them via the Key Vault configuration provider or App Service Key Vault references; enable soft delete and purge protection; use private endpoints; rotate secrets (or eliminate them by using managed identity auth to SQL, Storage and Service Bus directly); never store secrets in appsettings.json or source control."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"734","title":"What is Azure API Management used for?","body":"A managed API gateway in front of backend APIs (App Service, Functions, AKS, on-prem): central entry point, JWT/OAuth validation, subscription keys, rate limiting and quotas, request/response transformation, caching, versioning and revisions, mock responses, analytics, and a developer portal for consumers. Policies are XML snippets applied at global, product, API or operation scope."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"735","title":"How would you design a highly available, globally distributed web app on Azure?","body":"Deploy the stateless app tier to two or more regions (App Service/Container Apps/AKS), each zone-redundant; put Azure Front Door in front for global load balancing, failover, WAF and CDN; data: Azure SQL with auto-failover groups (or Cosmos DB with multi-region writes); geo-redundant storage; Service Bus geo-disaster recovery/replication; Key Vault per region; health probes and automated failover; IaC for identical environments; test failover regularly; monitor with Application Insights; define RTO/RPO targets and back up accordingly."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"736","title":"How do you reduce Azure costs for an application?","body":"Right-size SKUs using metrics and Advisor; autoscale with sensible minimums; use reserved instances/savings plans for steady workloads; serverless/scale-to-zero (Flex Consumption, Container Apps) for spiky ones; spot VMs for interruptible batch; storage lifecycle tiers; shut down dev/test outside hours; delete orphaned resources; use caching to reduce database tier needs; set budgets and alerts; tag resources for cost allocation; consider Azure Hybrid Benefit for Windows/SQL licences."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"737","title":"Your App Service API slows down every day at 9 AM and CPU hits 100%. What do you do?","body":"Short term: configure autoscale rules (scale out on CPU 70% and schedule-based scale-out before 9 AM). Investigate root cause with Application Insights (slow requests, dependencies, profiler): expensive queries (add indexes, caching), sync-over-async, chatty calls, large payloads. Consider caching hot data in Redis, moving heavy work to queues and background workers, and scaling up the plan if a single instance is undersized. Verify with load tests."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"738","title":"An order API must notify inventory, billing and email services reliably when an order is placed. Design it on Azure.","body":"The API saves the order and writes an outbox record in the same transaction; a background publisher sends an OrderPlaced message to a Service Bus topic . Inventory, billing and email each have their own subscription (with filters if needed), processed by Functions/Container Apps workers with peek-lock, retries, dead-letter queue monitoring and idempotent handlers (dedupe by MessageId). Managed identities for access, Application Insights distributed tracing across services, alerts on DLQ count."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"739","title":"A developer's connection string with the SQL admin password was found in appsettings.json in the repo. How do you fix the design?","body":"Rotate the password immediately. Switch the app to Entra ID authentication for Azure SQL with a managed identity ( Authentication=Active Directory Default in the connection string, create a contained user FROM EXTERNAL PROVIDER with minimal roles) — no password at all. Put any remaining secrets in Key Vault with Key Vault references. Enable secret scanning in the repo and remove SQL admin usage from apps."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"740","title":"Users in Europe complain the India-hosted site is slow. What can you do?","body":"Put Azure Front Door (CDN + global edge, TLS termination, caching static content and cacheable API responses) in front; serve static assets from the CDN; compress and optimise payloads; deploy a read-only or full secondary region in Europe with Front Door latency-based routing; replicate data (Cosmos DB multi-region or Azure SQL geo-replica for reads); check data residency requirements first."},{"kind":"question","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"741","title":"Blob uploads must trigger thumbnail generation automatically. Which services?","body":"Blob Storage (uploads via SAS or managed identity) → Event Grid BlobCreated event (filtered by container/suffix) → Azure Function (Event Grid trigger, Flex Consumption) that generates the thumbnail and writes it to a thumbnails container with an output binding. Add retries/dead-lettering on the Event Grid subscription, and Application Insights for monitoring. For high volume, put a Service Bus/Storage queue between them."},{"kind":"cheat","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"1","title":"Service map","body":"Need Service --- --- Web app/API App Service Serverless code Functions (Flex Consumption, isolated worker) Containers Container Apps / AKS / ACI VMs Virtual Machines, VM Scale Sets Relational DB Azure SQL Database / Managed Instance NoSQL Cosmos DB Files/objects Blob Storage / Azure Files Cache Azure Managed Redis Messages Service Bus Events Event Grid Streams Event Hubs Workflows Logic Apps / Durable Functions API gateway API Management Secrets Key Vault Config/flags App Configuration Identity Entra ID, managed identities Monitoring Azure Monitor, Application Insights, Log Analytics (KQL) Global entry Front Door (+WAF, CDN) IaC Bicep / ARM / Terraform"},{"kind":"cheat","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"2","title":"Key numbers & terms","body":"Storage redundancy: LRS · ZRS · GRS · RA-GRS · GZRS. Blob tiers: Hot · Cool (30d) · Cold (90d) · Archive (180d). Cosmos consistency: Strong · Bounded Staleness · Session (default) · Consistent Prefix · Eventual. Functions in-process model support ends 10 Nov 2026."},{"kind":"cheat","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"3","title":"CLI","body":"bash az login az account set -s <subscription az group create -n rg -l centralindia az webapp up / az webapp deploy az functionapp create az keyvault secret set --vault-name kv -n Db --value \"...\" az deployment group create -g rg -f main.bicep azd up"},{"kind":"cheat","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"4","title":"Well-Architected pillars","body":"Reliability · Security · Cost Optimization · Operational Excellence · Performance Efficiency."},{"kind":"cheat","course_slug":"azure","course_title":"Microsoft Azure for .NET Developers","ref":"5","title":"Golden rules","body":"Managed identity + DefaultAzureCredential · Key Vault · private endpoints · autoscale · deployment slots · IaC · Application Insights · tags + budgets · zones/multi-region for HA."},{"kind":"course","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"","title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","body":"Choosing a database on Azure; Azure SQL Database (single database, elastic pools, DTU vs vCore, General Purpose / Business Critical / Hyperscale, serverless), Azure SQL Managed Instance and SQL Server on Azure VMs; security (firewall, private endpoints, Microsoft Entra authentication, managed identity, TDE, Always Encrypted, auditing), high availability, geo-replication, failover groups and backups/point-in-time restore; performance (Query Store, automatic tuning, Intelligent Insights); Cosmos DB (APIs, partition keys, RU/s, consistency levels), Azure Database for PostgreSQL/MySQL, Azure Cache for Redis; migrating on-premises SQL Server (DMA, Azure Database Migration Service) and cost optimisation. Service Type Choose when --- --- --- Azure SQL Database PaaS, one database (or elastic pool) New cloud apps on SQL Server — no server to manage Azure SQL Managed Instance PaaS, near-100 % SQL Server instance compatibility Lift-and-shift of on-prem SQL Server using SQL Agent, cross-database queries, CLR, Service Broker, linked servers SQL Server on Azure VM IaaS Need full OS/instance control, SSRS/SSIS/SSAS on the same box, unsupported features Azure Cosmos DB Globally distributed NoSQL (multi-API) Massive scale, single-digit-ms reads, flexible JSON, multi-region writes Azure Database for PostgreSQL (Flexible Server) / MySQL Managed open-source databases Apps built for Postgres/MySQL Azure Cache for Redis / Azure Managed Redis In-memory cache Caching, sessions, leaderboards Azure Synapse / Microsoft Fabric warehouse Analytics Data warehousing and BI at scale Azure SQL Database runs the same SQL Server engine (always the latest version), so T-SQL skills transfer directly — but some instance-level features differ (no SQL Agent in single databases — use Elastic Jobs/Azure Functions/Logic Apps; no cross-database queries without elastic query; no USE to switch databases). Year Milestone --- --- 2010 SQL Azure (first cloud SQL Server service) 2014–2016 Azure SQL Database service tiers (Basic/Standard/Premium, DTU), elastic pools, geo-replication, Query Store, TDE by default 2017 Cosmos DB (from DocumentDB), Azure Database for PostgreSQL/MySQL 2018 SQL Managed Instance GA, vCore purchasing model, Hyperscale preview 2019 Serverless compute tier, Hyperscale GA 2020–2022 Azure SQL \"family\" branding, ledger, Azure AD-only auth, Cosmos DB serverless and autoscale 2023–2024 Managed Instance next-gen General Purpose, free Azure SQL Database offer (per subscription), Hyperscale price reductions, vector search previews 2025 Native vector type and JSON type in Azure SQL, SQL database in Microsoft Fabric, Cosmos DB vector search GA Moving a .NET app's database to Azure SQL: 1. Assess the on-prem database (Azure Migrate / Data Migration Assistant / SQL Server migration extension in Azure Data Studio's successor tools) for compatibility and target size. 2. Choose the target : Azure SQL Database (new/modern apps), Managed Instance (instance features), VM (full control). 3. Provision with Bicep/Terraform/CLI: logical server, database, service tier, networking (private endpoint), Entra admin. 4. Migrate schema + data: Azure Database Migration Service (online/offline), BACPAC import, transactional replication or log shipping (MI link) for minimal downtime. 5. Switch the app : new connection string (managed identity), retry logic for transient faults, test performance. 6. Operate : monitoring (Azure Monitor, Query Store), automatic tuning, alerts, backups/PITR, geo-replication/failover groups, cost reviews. - Azure Portal, Azure CLI ( az sql ), PowerShell ( Az.Sql ), Bicep/Terraform. - SSMS, VS Code MSSQL extension, sqlcmd / sqlpackage (BACPAC/DACPAC), SQL database projects (SDK-style) for schema CI/CD. - Azure Database Migration Service, Azure Migrate, Data Migration Assistant. - Monitoring: Query Performance Insight, Query Store, Azure Monitor metrics/alerts, Database Watcher, Defender for SQL. - Cosmos DB: Data Explorer, .NET SDK v3, Cosmos DB emulator."},{"kind":"lesson","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"azure-sql-database-managed-instance-and-sql-on-vm-choosing","title":"Azure SQL Database, Managed Instance and SQL on VM — choosing","body":"Azure SQL Database SQL Managed Instance SQL Server on Azure VM --- --- --- --- Model PaaS database PaaS instance IaaS Compatibility Database-scoped features Near-full instance features (SQL Agent, cross-DB queries, CLR, DB Mail, linked servers) 100 % Patching, backups, HA Automatic Automatic You (with helpers like SQL IaaS Agent extension) Networking Public endpoint + firewall or private endpoint Inside your VNet Your VNet Max size Up to 4 TB (GP/BC), 128 TB Hyperscale Up to 16 TB (instance storage) Disk limits Typical use New apps, SaaS (database per tenant), microservices Migrating many existing databases with minimal change Legacy apps, SSRS/SSIS on the same server, special configs A logical server ( myserver.database.windows.net ) is just a management/connection endpoint holding logins, firewall rules and Entra admin — databases on it are independent."},{"kind":"lesson","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"purchasing-models-and-service-tiers-dtu-vcore-serverless-hyperscale-elastic-pool","title":"Purchasing models and service tiers — DTU, vCore, serverless, Hyperscale, elastic pools","body":"Model What you buy --- --- DTU (Basic, Standard, Premium) A bundled measure of CPU + memory + I/O — simple, older vCore Choose CPU cores, memory and storage separately; Azure Hybrid Benefit to reuse SQL Server licences; reserved capacity discounts vCore tier Storage & HA Use --- --- --- General Purpose Remote premium storage, standby compute takes over on failure Most business workloads Business Critical Local SSD, Always On replicas (incl. a free readable secondary), lowest latency High I/O OLTP, low latency, read scale-out Hyperscale Distributed storage up to 128 TB, fast backups/restores, up to 4 read replicas (named replicas too) Large or fast-growing databases Serverless (General Purpose / Hyperscale): compute auto-scales between min and max vCores and can auto-pause when idle (GP) — you pay per second of compute used. Great for dev/test and intermittent workloads; first query after pause has a resume delay. Elastic pools: many databases share a pool of resources — ideal for SaaS with a database per tenant where each tenant's usage peaks at different times."},{"kind":"lesson","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"security-networking-entra-authentication-managed-identity-encryption-auditing","title":"Security — networking, Entra authentication, managed identity, encryption, auditing","body":"Network: server-level and database-level firewall rules (allowed IP ranges), \"Allow Azure services\" switch (broad — prefer narrower options), private endpoints (database gets a private IP in your VNet; public access disabled), VNet service endpoints. Authentication: SQL logins, or Microsoft Entra ID users/groups and managed identities (recommended — no passwords). Entra-only authentication can be enforced. sql -- In the user database, as the Entra admin: create a user for the App Service's managed identity CREATE USER [shop-api-prod] FROM EXTERNAL PROVIDER; ALTER ROLE db datareader ADD MEMBER [shop-api-prod]; ALTER ROLE db datawriter ADD MEMBER [shop-api-prod]; json // appsettings.json in the App Service — no password anywhere \"ConnectionStrings\": { \"Shop\": \"Server=tcp:shop-sql.database.windows.net,1433;Database=Shop;Authentication=Active Directory Default;Encrypt=True;\" } Active Directory Default uses the managed identity in Azure and your Visual Studio/Azure CLI login locally (via DefaultAzureCredential ). Data protection: Feature Protects --- --- TLS (Encrypt=True) Data in transit TDE (Transparent Data Encryption) — on by default Data files and backups at rest (service-managed or customer-managed keys in Key Vault) Always Encrypted (with secure enclaves) Sensitive columns encrypted in the client driver — even DBAs can't see plaintext Dynamic Data Masking Hides values from non-privileged users in query results (not encryption) Row-Level Security Users see only their rows (multi-tenant filters) Auditing, Microsoft Defender for SQL Audit logs, vulnerability assessment, threat detection (SQL injection, unusual access) Ledger Tamper-evident tables"},{"kind":"lesson","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"high-availability-geo-replication-failover-groups-and-backups","title":"High availability, geo-replication, failover groups and backups","body":"- Built-in HA: every database has an availability SLA (99.99 %; up to 99.995 % with zone redundancy on Business Critical/Premium). Replicas/standby compute handle hardware failures automatically — apps must retry transient errors during failovers. - Zone redundancy: replicas spread across availability zones in the region. - Active geo-replication: up to 4 readable secondaries in other regions (single database). - Failover groups: group of databases replicated to another region with a listener endpoint ( shop-fg.database.windows.net read-write, shop-fg.secondary... read-only) — connection strings don't change after failover. - Backups: automatic full (weekly), differential (12–24 h) and log backups (every ~5–10 min); point-in-time restore (PITR) within the retention period (1–35 days); long-term retention (LTR) up to 10 years; geo-redundant backup storage for geo-restore . - RPO/RTO: geo-replication gives RPO of seconds; PITR is for \"oops, someone deleted data\" (restores to a new database). bash az sql db restore --resource-group rg-shop --server shop-sql --name Shop --dest-name Shop restored --time \"2026-10-24T09:30:00Z\" csharp // EF Core: retry transient faults (failovers, throttling) options.UseSqlServer(cs, sql = sql.EnableRetryOnFailure(maxRetryCount: 6, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null));"},{"kind":"lesson","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"performance-monitoring-and-tuning-in-azure-sql","title":"Performance monitoring and tuning in Azure SQL","body":"- Query Store — on by default: top resource-consuming queries, regressed plans, plan forcing. - Automatic tuning — FORCE LAST GOOD PLAN (on by default), optional automatic CREATE INDEX / DROP INDEX recommendations. - Query Performance Insight and Intelligent Insights in the portal; Azure Monitor metrics (CPU %, Data IO %, Log IO %, DTU/vCore usage, deadlocks, connection failures, storage). - DMVs work as on-prem ( sys.dm exec requests , sys.dm db resource stats for the last hour at 15-second granularity). - Typical fixes are the same as SQL Server (indexes, SARGable queries, parameter sniffing) — plus right-sizing the tier, read scale-out for reports ( ApplicationIntent=ReadOnly ), and connection pooling (many short-lived connections from serverless functions can exhaust limits). - Resource limits: each tier caps CPU, I/O, log rate, workers and sessions — \"throttling\" shows up as LOG RATE GOVERNOR , RESOURCE SEMAPHORE waits or error 10928/10936 (worker/session limits)."},{"kind":"lesson","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"azure-cosmos-db-apis-partitioning-ru-s-and-consistency","title":"Azure Cosmos DB — APIs, partitioning, RU/s and consistency","body":"Cosmos DB is a globally distributed, multi-model NoSQL database with single-digit-millisecond latency and automatic indexing. API Model --- --- NoSQL (core) JSON documents queried with a SQL-like language — most common, newest features MongoDB (RU or vCore) Use MongoDB drivers Cassandra, Gremlin (graph), Table Compatibility with those ecosystems PostgreSQL (Citus) Distributed PostgreSQL Key concepts: - Account → database → container → items (JSON documents). - Partition key — chooses how data is spread across physical partitions. Pick a property with high cardinality and even access (e.g. /customerId , /tenantId ); queries that include the partition key are cheap, cross-partition queries cost more. A hot partition limits throughput. - Request Units (RU/s) — the currency of throughput: a 1 KB point read ≈ 1 RU; writes and queries cost more. Provisioned (manual or autoscale ) or serverless (pay per RU consumed). - Consistency levels (strongest → weakest): Strong , Bounded staleness , Session (default — read-your-own-writes per session), Consistent prefix , Eventual . Weaker = lower latency and cost, higher availability. - Global distribution: add regions with one click, optional multi-region writes, automatic failover. - Change feed — ordered stream of changes for event-driven processing (Azure Functions trigger), materialised views, sync to search. csharp var client = new CosmosClient(endpoint, new DefaultAzureCredential()); var container = client.GetContainer(\"shop\", \"orders\"); // partition key /customerId await container.CreateItemAsync(new { id = Guid.NewGuid().ToString(), customerId = \"c42\", total = 4500 }, new PartitionKey(\"c42\")); var order = await container.ReadItemAsync<Order (\"order-id\", new PartitionKey(\"c42\")); // point read: cheapest var query = container.GetItemQueryIterator<Order (new QueryDefinition(\"SELECT FROM o WHERE o.customerId = @c AND o.total 1000\") .WithParameter(\"@c\", \"c42\"));"},{"kind":"lesson","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"azure-database-for-postgresql-mysql-azure-cache-for-redis-and-choosing-storage","title":"Azure Database for PostgreSQL/MySQL, Azure Cache for Redis and choosing storage","body":"- Azure Database for PostgreSQL – Flexible Server / MySQL – Flexible Server: managed open-source engines with zone-redundant HA, automated backups/PITR, read replicas, stop/start to save cost, extensions (PostGIS, pgvector). - Azure Cache for Redis / Azure Managed Redis: in-memory key-value store — cache-aside for DB queries, session state, distributed locks, rate limiting, pub/sub. Use with IDistributedCache / HybridCache in ASP.NET Core. - Azure Storage: Blob (files, images, backups), Table (simple key-value), Queue; Azure Data Lake Storage Gen2 for analytics. - Azure Data Explorer / Fabric Real-Time Intelligence: time-series and log analytics with KQL (IoT, telemetry). Data Store --- --- Orders, invoices, inventory (relational, transactions) Azure SQL Product catalog, user profiles at global scale Cosmos DB Images, PDFs, exports Blob Storage Cache, sessions Redis Telemetry, logs Data Explorer / Log Analytics BI warehouse Fabric / Synapse"},{"kind":"lesson","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"migrating-on-premises-sql-server-to-azure","title":"Migrating on-premises SQL Server to Azure","body":"Method Downtime Notes --- --- --- Azure Database Migration Service (offline/online) Offline: hours; online: minutes Assessment + migration orchestration; online uses continuous sync then cutover BACPAC export/import ( sqlpackage ) Hours (size-dependent) Simple for small databases into Azure SQL Database Backup to URL + restore (Managed Instance) Restore time Native .bak restore to MI Managed Instance link / log replay service Minimal Near real-time replication to MI, then failover Transactional replication Minimal Publisher on-prem → subscriber in Azure SQL Database Pre-migration checklist: compatibility assessment (unsupported features: cross-database queries, SQL Agent jobs, CLR, linked servers, Windows logins), size and performance baseline (choose tier from actual CPU/IO), network path (VPN/ExpressRoute), application changes (connection strings, retry logic, Entra auth), jobs moved to Elastic Jobs/Functions, SSIS to Azure Data Factory (SSIS integration runtime), reports to Power BI or SSRS on a VM, test restore and rollback plan."},{"kind":"lesson","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"cost-optimisation-for-azure-databases","title":"Cost optimisation for Azure databases","body":"- Right-size from metrics (many databases are over-provisioned); scale down at night with automation for non-production. - Serverless for dev/test and intermittent workloads (auto-pause). - Elastic pools for many small databases with uneven usage. - Reserved capacity (1 or 3 years) and Azure Hybrid Benefit for steady production workloads. - Read replicas for reporting instead of scaling the primary. - Cosmos DB: choose a good partition key (fewer RUs), autoscale or serverless, index only needed paths, use point reads. - Delete unused databases/backups; set LTR policies deliberately; monitor with Cost Management budgets and alerts."},{"kind":"question","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"742","title":"Azure SQL Database vs Managed Instance vs SQL Server on a VM?","body":"Azure SQL Database is a fully managed single database (or elastic pool) — best for new cloud apps, with database-scoped features. Managed Instance is a fully managed SQL Server instance in your VNet with near-complete compatibility (SQL Agent, cross-database queries, CLR, linked servers) — best for lift-and-shift migrations. SQL Server on an Azure VM is IaaS with full control and 100 % compatibility but you manage patching, backups and HA."},{"kind":"question","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"743","title":"What is the difference between DTU and vCore models?","body":"DTU bundles CPU, memory and I/O into one measure with fixed tiers (Basic, Standard, Premium) — simple but less flexible. vCore lets you choose cores, memory and storage independently, pick hardware generations and tiers (General Purpose, Business Critical, Hyperscale), use serverless compute, and save with Azure Hybrid Benefit and reserved capacity. Most new deployments use vCore."},{"kind":"question","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"744","title":"How do you connect an App Service to Azure SQL without storing a password?","body":"Enable a managed identity on the App Service, set an Entra admin on the SQL server, create a contained database user FROM EXTERNAL PROVIDER for the identity and grant roles, and use a connection string with Authentication=Active Directory Default (or Managed Identity). Locally the same code uses your developer login through DefaultAzureCredential."},{"kind":"question","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"745","title":"What are failover groups and how are they different from active geo-replication?","body":"Active geo-replication replicates a single database to up to four readable secondaries in other regions, and failover is per database with connection strings pointing to specific servers. Failover groups manage a group of databases (or a whole managed instance) together and provide stable listener endpoints for read-write and read-only traffic that follow the primary after failover, so applications don't need connection-string changes. Failover can be automatic or manual."},{"kind":"question","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"746","title":"How does backup and restore work in Azure SQL Database?","body":"Backups are automatic: weekly full, differential every 12–24 hours and log backups every 5–10 minutes, stored in geo-redundant (or zone/locally redundant) storage. You can restore to any point in time within the retention period (1–35 days) as a new database, keep long-term retention backups up to 10 years, and geo-restore to another region if the primary region is unavailable."},{"kind":"question","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"747","title":"What is a partition key in Cosmos DB and how do you choose it?","body":"The property used to distribute items across logical and physical partitions; all items with the same value form a logical partition (max 20 GB). Choose a key with high cardinality and evenly spread reads/writes that is present in most queries (e.g. customerId, tenantId, deviceId) — so queries hit one partition and throughput isn't limited by a hot partition. It can't be changed later without migrating data."},{"kind":"question","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"748","title":"What are Request Units (RU/s) and consistency levels in Cosmos DB?","body":"RUs are the normalised cost of operations (CPU, IO, memory): a 1 KB point read ≈ 1 RU, writes and queries cost more; you provision RU/s (manual/autoscale) or pay per RU in serverless. Consistency levels trade latency/availability for freshness: Strong, Bounded staleness, Session (default, read-your-writes), Consistent prefix and Eventual."},{"kind":"question","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"749","title":"What is serverless compute in Azure SQL Database?","body":"A compute tier that automatically scales vCores between a minimum and maximum based on load and bills per second of compute used; in General Purpose it can auto-pause after an idle period, charging only for storage, and resumes on the next connection (with a short delay). Ideal for dev/test and intermittent workloads, not for latency-sensitive always-on production."},{"kind":"question","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"750","title":"How do you secure Azure SQL Database?","body":"Private endpoints and disabled public access (or tight firewall rules), Entra-only authentication with managed identities, least-privilege database roles, TDE (on by default) and TLS, Always Encrypted for highly sensitive columns, Row-Level Security for tenant isolation, Dynamic Data Masking for non-privileged users, auditing to Log Analytics, Microsoft Defender for SQL, and secrets (if any) in Key Vault."},{"kind":"question","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"751","title":"What is Hyperscale and when would you use it?","body":"A vCore service tier with a distributed architecture separating compute, page servers and log service, supporting databases up to 128 TB with near-constant-time backups and fast restores, rapid scale up/down, and up to four HA replicas plus named read replicas. Use it for large or fast-growing OLTP databases and mixed workloads needing read scale-out."},{"kind":"question","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"752","title":"Why must applications use retry logic with Azure SQL?","body":"Cloud databases have transient faults: failovers during maintenance or hardware failure, load balancing, throttling when resource limits are hit (errors such as 40613, 40501, 40197, 10928). A short retry with exponential backoff (EF Core EnableRetryOnFailure , Polly, SqlClient configurable retry logic) makes these invisible to users; make operations idempotent so retries are safe."},{"kind":"question","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"753","title":"What is an elastic pool and when should you not use it?","body":"A shared pool of compute (vCores or eDTUs) and storage used by many Azure SQL databases, each scaling within per-database min/max limits — cost-effective when databases have low average and uneven peak usage (SaaS database-per-tenant). Avoid it when databases peak at the same time or one database needs consistently high resources — that database belongs in its own single database or a separate pool."},{"kind":"question","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"754","title":"You need to migrate a 500 GB on-prem SQL Server database with SQL Agent jobs and cross-database queries to Azure with minimal downtime. What do you choose?","body":"Azure SQL Managed Instance, because it supports SQL Agent and cross-database queries. Assess with the migration tools, provision MI in a VNet connected by VPN/ExpressRoute, use the online migration (Database Migration Service or the MI link/log replay) to keep the target in sync, test the application against MI, then cut over during a short window by stopping writes, completing the sync and switching connection strings."},{"kind":"question","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"755","title":"An Azure SQL database is at 100 % CPU after a release. What do you do?","body":"Check Query Store/Query Performance Insight for the top CPU queries and regressed plans; force the last good plan (or rely on automatic tuning) as an immediate fix; fix the query/indexes (missing index, non-SARGable predicate, parameter sniffing); temporarily scale up the tier if users are impacted; add caching or read replicas for heavy reads; set alerts on CPU and log IO for early warning."},{"kind":"question","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"756","title":"A multi-tenant SaaS has 300 small customer databases with different peak times. How do you host them cost-effectively?","body":"Put them in one or more elastic pools so they share a pool of vCores/eDTUs sized for combined peak, not each database's peak; monitor per-database usage and move noisy tenants to their own database or pool; use Elastic Jobs for schema updates across all databases and a catalog database to map tenants to databases."},{"kind":"cheat","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"1","title":"Choose the service","body":"New app → Azure SQL Database · lift-and-shift with Agent/cross-DB → Managed Instance · full control/SSRS on box → SQL VM · global NoSQL → Cosmos DB · Postgres/MySQL → Flexible Server · cache → Redis."},{"kind":"cheat","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"2","title":"Azure SQL tiers","body":"DTU (Basic/Standard/Premium) or vCore (General Purpose, Business Critical, Hyperscale) · serverless (auto-scale, auto-pause) · elastic pools (many DBs) · Hybrid Benefit + reservations."},{"kind":"cheat","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"3","title":"Security","body":"Private endpoint · Entra-only auth + managed identity ( Authentication=Active Directory Default ) · TDE · Always Encrypted · RLS · auditing · Defender for SQL."},{"kind":"cheat","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"4","title":"HA/DR","body":"Built-in HA (99.99 %) · zone redundancy · geo-replication · failover groups (listener endpoints) · PITR 1–35 days · LTR up to 10 years · geo-restore · retry transient faults."},{"kind":"cheat","course_slug":"azure-databases","course_title":"Azure Databases — Azure SQL, Managed Instance, Cosmos DB, PostgreSQL and Migration","ref":"5","title":"Cosmos DB","body":"Partition key (high cardinality, in queries) · RU/s (autoscale/serverless) · consistency: Strong → Bounded → Session (default) → Prefix → Eventual · change feed · point reads cheapest."},{"kind":"course","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"","title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","body":"AWS fundamentals — regions and AZs, IAM, the shared responsibility model; compute (EC2, Elastic Beanstalk, ECS/Fargate, EKS, Lambda, App Runner), storage (S3, EBS, EFS), databases (RDS for SQL Server, Aurora, DynamoDB, ElastiCache), networking (VPC, subnets, security groups, Route 53, CloudFront, ALB/NLB, API Gateway), messaging (SQS, SNS, EventBridge, Kinesis), security (KMS, Secrets Manager, Cognito, WAF), monitoring (CloudWatch, X-Ray, CloudTrail), infrastructure as code (CloudFormation, CDK, Terraform), CI/CD (CodePipeline, GitHub Actions), deploying .NET apps, cost management, the Azure ↔ AWS service map and AWS interview questions. Amazon Web Services (AWS) is the largest public cloud provider (since 2006), with 200+ services across 30+ regions. As a .NET/full stack developer you mainly need: IAM , compute to run APIs, databases , storage , networking , messaging , monitoring and deployment automation . Azure ↔ AWS ↔ GCP service map: Need Azure AWS GCP --- --- --- --- Virtual machines Virtual Machines EC2 Compute Engine Web app PaaS App Service Elastic Beanstalk , App Runner App Engine, Cloud Run Containers (serverless) Container Apps ECS on Fargate , App Runner Cloud Run Kubernetes AKS EKS GKE Functions Azure Functions Lambda Cloud Functions / Cloud Run functions Object storage Blob Storage S3 Cloud Storage Managed SQL Server Azure SQL / Managed Instance RDS for SQL Server Cloud SQL for SQL Server Cloud-native relational Azure SQL Hyperscale / PostgreSQL Aurora (MySQL/PostgreSQL) AlloyDB, Spanner NoSQL Cosmos DB DynamoDB Firestore, Bigtable Cache Azure Cache for Redis ElastiCache / MemoryDB Memorystore Queue / pub-sub Service Bus, Storage Queues / Event Grid SQS / SNS , EventBridge Pub/Sub Streaming Event Hubs Kinesis , MSK (Kafka) Pub/Sub, Dataflow API gateway API Management API Gateway API Gateway / Apigee CDN Front Door / CDN CloudFront Cloud CDN DNS Azure DNS Route 53 Cloud DNS Identity for apps Entra ID / B2C Cognito Identity Platform Access control Entra ID + RBAC IAM Cloud IAM Secrets Key Vault Secrets Manager , Parameter Store, KMS Secret Manager, Cloud KMS Monitoring Azure Monitor / App Insights CloudWatch , X-Ray Cloud Monitoring/Logging/Trace IaC ARM / Bicep CloudFormation , CDK Deployment Manager → Infrastructure Manager (Terraform) CI/CD Azure DevOps CodePipeline / CodeBuild / CodeDeploy Cloud Build / Cloud Deploy Year Milestone --- --- 2006 S3 and EC2 launch — AWS public cloud begins 2008–2009 EBS, CloudFront, RDS (MySQL first), VPC 2010–2012 Route 53, CloudFormation, Elastic Beanstalk (.NET support 2012), DynamoDB , RDS for SQL Server 2014 Lambda , Aurora, ECS, KMS 2015–2017 API Gateway, Elastic Container Registry, Fargate , Aurora PostgreSQL 2018 EKS , Lambda custom runtimes 2019–2021 Graviton (ARM) instances, CDK GA, App Runner, Lambda container images 2022–2024 Lambda SnapStart, .NET 8 Lambda runtime, Amazon Q (AI assistant), Bedrock (generative AI) 2025 .NET 10 support on Lambda/Beanstalk, continued AI services (Bedrock agents), Aurora DSQL Deploying a .NET API to AWS (typical path): 1. Account setup — organisation, root user locked down with MFA, IAM Identity Center users/roles, budgets. 2. Network — a VPC with public subnets (load balancer) and private subnets (app, database) across 2–3 AZs. 3. Data — RDS for SQL Server (Multi-AZ) or Aurora PostgreSQL in private subnets; credentials in Secrets Manager. 4. Compute — container image in ECR → ECS Fargate service behind an Application Load Balancer (or Elastic Beanstalk / Lambda). 5. Edge — Route 53 DNS → CloudFront (CDN, TLS via ACM certificate) → ALB. 6. CI/CD — GitHub Actions/CodePipeline: build, test, push image, deploy new task definition. 7. Operate — CloudWatch logs/metrics/alarms, X-Ray/OpenTelemetry traces, CloudTrail audit, cost alerts. - AWS Management Console, AWS CLI ( aws configure , aws s3 ls ), AWS Tools for PowerShell. - AWS Toolkit for Visual Studio / VS Code / Rider; AWS SDK for .NET ( AWSSDK.S3 , AWSSDK.DynamoDBv2 …); Amazon.Lambda.AspNetCoreServer to run ASP.NET Core on Lambda; dotnet lambda CLI. - IaC: CloudFormation, AWS CDK (C /TypeScript), Terraform, SAM (serverless). - Containers: ECR, Copilot CLI, Docker. - Learning: AWS Skill Builder, AWS Free Tier, Well-Architected Framework."},{"kind":"lesson","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"regions-availability-zones-the-shared-responsibility-model-and-iam","title":"Regions, availability zones, the shared responsibility model and IAM","body":"- Region — a geographic area (e.g. ap-south-1 Mumbai, ap-northeast-1 Tokyo, us-east-1 N. Virginia) with multiple Availability Zones (AZs) — separate data centres with independent power/network. Deploy across ≥2 AZs for high availability. - Edge locations — CloudFront/Route 53 points of presence close to users. - Shared responsibility: AWS secures the cloud (hardware, facilities, hypervisor, managed service internals); you secure what's in the cloud (IAM, data, OS patches on EC2, network rules, app code, encryption settings). IAM (Identity and Access Management): Concept Meaning --- --- User / group People (prefer IAM Identity Center/SSO for humans) Role Identity assumed by services or people for temporary credentials — EC2 instance roles, ECS task roles, Lambda execution roles Policy JSON document allowing/denying actions on resources Least privilege Grant only needed actions/resources Root user Only for account-level tasks; MFA, no access keys json { \"Version\": \"2012-10-17\", \"Statement\": [{ \"Effect\": \"Allow\", \"Action\": [\"s3:GetObject\", \"s3:PutObject\"], \"Resource\": \"arn:aws:s3:::shop-uploads-prod/ \" }] } Applications on AWS should use roles (temporary credentials provided automatically to the SDK) — never hard-coded access keys."},{"kind":"lesson","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"ec2-elastic-beanstalk-ecs-fargate-eks-app-runner-and-lambda","title":"EC2, Elastic Beanstalk, ECS/Fargate, EKS, App Runner and Lambda","body":"Service You manage Good for .NET --- --- --- EC2 VM: OS, IIS/Kestrel, patches, scaling (Auto Scaling groups) Lift-and-shift .NET Framework/IIS apps (Windows AMIs) Elastic Beanstalk Just upload the app; Beanstalk creates EC2, load balancer, auto scaling Quick hosting of ASP.NET Core (Linux) or .NET Framework on IIS (Windows) App Runner Container image or source; fully managed HTTPS service Simple containerised APIs ECS + Fargate Container task definitions and services; no servers Most containerised .NET microservices EKS Kubernetes cluster (managed control plane) Teams standardised on Kubernetes Lambda Functions; pay per request and duration; scales to zero Event-driven code, APIs with spiky traffic bash ASP.NET Core on Lambda behind API Gateway (Amazon.Lambda.AspNetCoreServer.Hosting) dotnet new install Amazon.Lambda.Templates dotnet new serverless.AspNetCoreMinimalAPI -n ShopApi Program.cs: builder.Services.AddAWSLambdaHosting(LambdaEventSource.HttpApi); dotnet lambda deploy-serverless csharp // A plain Lambda function handler (S3 upload event → create thumbnail) public class Function { public async Task Handler(S3Event evt, ILambdaContext ctx) { foreach (var record in evt.Records) ctx.Logger.LogInformation($\"New file {record.S3.Object.Key} in {record.S3.Bucket.Name}\"); } } Auto Scaling: EC2 Auto Scaling groups or ECS service auto scaling based on CPU, request count or SQS queue depth; place instances/tasks in multiple AZs behind an ALB."},{"kind":"lesson","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"s3-ebs-and-efs","title":"S3, EBS and EFS","body":"Service Type Use --- --- --- S3 Object storage (buckets, keys) — 11 nines durability Uploads, images, static websites, backups, data lake EBS Block storage volumes attached to one EC2 instance OS and database disks EFS / FSx Shared file systems (NFS / Windows SMB with FSx for Windows) Shared content across servers S3 features: storage classes (Standard, Intelligent-Tiering, Standard-IA, Glacier tiers for archives), lifecycle rules , versioning , pre-signed URLs (temporary upload/download links), server-side encryption (SSE-S3/SSE-KMS, on by default), Block Public Access (keep on unless hosting public content via CloudFront). csharp var s3 = new AmazonS3Client(); // credentials from the IAM role await s3.PutObjectAsync(new PutObjectRequest { BucketName = \"shop-uploads-prod\", Key = $\"invoices/{id}.pdf\", FilePath = path }); var url = await s3.GetPreSignedURLAsync(new GetPreSignedUrlRequest { BucketName = \"shop-uploads-prod\", Key = $\"invoices/{id}.pdf\", Expires = DateTime.UtcNow.AddMinutes(15) });"},{"kind":"lesson","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"databases-rds-for-sql-server-aurora-dynamodb-and-elasticache","title":"Databases — RDS for SQL Server, Aurora, DynamoDB and ElastiCache","body":"Amazon RDS — managed relational databases: SQL Server (Express, Web, Standard, Enterprise editions; licence included or BYOL on RDS Custom), PostgreSQL, MySQL, MariaDB, Oracle, Db2. - Multi-AZ — synchronous standby in another AZ, automatic failover (HA). - Read replicas — asynchronous copies for read scaling (SQL Server Enterprise supports read replicas). - Automated backups (point-in-time restore, 1–35 days) and manual snapshots. - Runs in private subnets; access controlled by security groups ; encryption with KMS. - RDS for SQL Server has no sysadmin — some features (some SQL Agent features, native backup to S3 via stored procedures, SSIS/SSRS support with options) differ from on-prem. json // appsettings.Production.json — connection string with credentials loaded from Secrets Manager at startup \"ConnectionStrings\": { \"Shop\": \"Server=shop-db.abc123.ap-south-1.rds.amazonaws.com,1433;Database=Shop;Encrypt=True;\" } Aurora — AWS's cloud-native MySQL/PostgreSQL-compatible engine: storage replicated 6 ways across 3 AZs, up to 15 low-latency read replicas, fast failover, Aurora Serverless v2 (scales capacity automatically), Global Database for multi-region. DynamoDB — fully managed key-value/document NoSQL with single-digit-ms latency at any scale: - Tables with a partition key (and optional sort key ); access patterns designed up front (single-table design). - Capacity modes: on-demand (pay per request) or provisioned (with auto scaling). - GSIs/LSIs (secondary indexes), DynamoDB Streams (change events → Lambda), TTL, transactions, global tables (multi-region). ElastiCache (Redis/Valkey/Memcached) — managed in-memory cache for sessions and query caching; MemoryDB for durable Redis."},{"kind":"lesson","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"vpc-security-groups-load-balancers-route-53-cloudfront-and-api-gateway","title":"VPC, security groups, load balancers, Route 53, CloudFront and API Gateway","body":"text Route 53 (DNS) → CloudFront (CDN, WAF, TLS) → Application Load Balancer (public subnets, 2+ AZs) → ECS tasks / EC2 instances (private subnets) → RDS (private subnets, Multi-AZ) NAT Gateway in public subnet gives private resources outbound internet access Component Meaning --- --- VPC Your private network (CIDR range, e.g. 10.0.0.0/16) in a region Subnets Public (route to an Internet Gateway) or private; one per AZ Security group Stateful firewall on instances/ENIs — allow rules only (e.g. RDS SG allows 1433 only from the app SG) Network ACL Stateless subnet-level firewall (allow/deny) NAT Gateway Outbound internet for private subnets VPC endpoints Private access to S3/DynamoDB/other services without internet ALB Layer 7 load balancer (HTTP routing, host/path rules, TLS) — for web apps NLB Layer 4 (TCP/UDP), very high throughput, static IPs Route 53 DNS + health checks + routing policies (latency, weighted, failover, geolocation) CloudFront CDN with edge caching, TLS (ACM certificates), origin access to S3 API Gateway Managed API front door: REST/HTTP/WebSocket APIs, auth (Cognito/JWT/IAM), throttling, Lambda integration"},{"kind":"lesson","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"messaging-and-events-sqs-sns-eventbridge-kinesis-and-step-functions","title":"Messaging and events — SQS, SNS, EventBridge, Kinesis and Step Functions","body":"Service Pattern Use --- --- --- SQS Queue (standard: at-least-once, best-effort order; FIFO: exactly-once processing, ordered) Decouple services, background jobs, buffering SNS Pub/sub topic → many subscribers (SQS, Lambda, HTTP, email, SMS) Fan-out notifications EventBridge Event bus with rules routing events (AWS services, SaaS, your apps), scheduler Event-driven architectures, cron jobs Kinesis Data Streams / MSK Ordered, replayable streams Clickstreams, IoT telemetry, analytics Step Functions Workflow/state machine orchestration Sagas, multi-step processes with retries csharp var sqs = new AmazonSQSClient(); await sqs.SendMessageAsync(queueUrl, JsonSerializer.Serialize(new OrderPlaced(orderId))); var resp = await sqs.ReceiveMessageAsync(new ReceiveMessageRequest { QueueUrl = queueUrl, MaxNumberOfMessages = 10, WaitTimeSeconds = 20 }); // long polling foreach (var m in resp.Messages) { await HandleAsync(m.Body); // idempotent handler await sqs.DeleteMessageAsync(queueUrl, m.ReceiptHandle); // delete only after success; otherwise it reappears after the visibility timeout } Dead-letter queues capture messages that fail repeatedly ( maxReceiveCount )."},{"kind":"lesson","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"security-secrets-monitoring-and-governance","title":"Security, secrets, monitoring and governance","body":"- KMS — encryption keys for S3, EBS, RDS, Secrets Manager; envelope encryption. - Secrets Manager (rotation for RDS passwords) / SSM Parameter Store — load secrets into .NET configuration ( Amazon.Extensions.Configuration.SystemsManager ) via the task/instance role. - ACM — free TLS certificates for ALB/CloudFront/API Gateway with auto-renewal. - Cognito — user sign-up/sign-in (user pools) issuing JWTs, social/SAML federation. - WAF + Shield — web application firewall and DDoS protection on CloudFront/ALB/API Gateway. - CloudWatch — metrics, logs (Logs Insights queries), alarms, dashboards; X-Ray /ADOT (OpenTelemetry) for traces. - CloudTrail — audit log of every API call in the account; Config — resource compliance history; GuardDuty — threat detection; Security Hub — findings overview. - Organizations + SCPs , tagging, Budgets and Cost Explorer for governance."},{"kind":"lesson","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"infrastructure-as-code-and-ci-cd-cloudformation-cdk-codepipeline-github-actions","title":"Infrastructure as code and CI/CD — CloudFormation, CDK, CodePipeline, GitHub Actions","body":"csharp // AWS CDK in C — a Fargate service behind a load balancer in ~10 lines public class ShopStack : Stack { public ShopStack(Construct scope, string id) : base(scope, id) { var vpc = new Vpc(this, \"Vpc\", new VpcProps { MaxAzs = 2 }); var cluster = new Cluster(this, \"Cluster\", new ClusterProps { Vpc = vpc }); new ApplicationLoadBalancedFargateService(this, \"Api\", new ApplicationLoadBalancedFargateServiceProps { Cluster = cluster, DesiredCount = 2, Cpu = 512, MemoryLimitMiB = 1024, TaskImageOptions = new ApplicationLoadBalancedTaskImageOptions { Image = ContainerImage.FromAsset(\"../src/Shop.Api\"), ContainerPort = 8080 } }); } } // cdk deploy yaml GitHub Actions — build and deploy to ECS using OIDC (no stored AWS keys) permissions: { id-token: write, contents: read } steps: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 with: { role-to-assume: arn:aws:iam::123456789012:role/github-deploy, aws-region: ap-south-1 } - uses: aws-actions/amazon-ecr-login@v2 - run: docker build -t $ECR REPO:${{ github.sha }} . && docker push $ECR REPO:${{ github.sha }} - uses: aws-actions/amazon-ecs-deploy-task-definition@v2 with: { task-definition: taskdef.json, service: shop-api, cluster: shop, wait-for-service-stability: true } AWS-native alternative: CodePipeline (orchestration) + CodeBuild (build/test) + CodeDeploy (blue/green for EC2/ECS/Lambda)."},{"kind":"lesson","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"well-architected-framework-and-cost-management","title":"Well-Architected Framework and cost management","body":"AWS Well-Architected Framework — six pillars: Operational excellence, Security, Reliability, Performance efficiency, Cost optimisation, Sustainability. Cost levers: right-size instances (Compute Optimizer), Savings Plans/Reserved Instances for steady load, Spot instances for interruptible work, Graviton (ARM) instances for .NET (cheaper per performance), Lambda/Fargate for spiky workloads, S3 lifecycle to cheaper tiers, turn off non-prod at night, delete idle resources (unattached EBS, old snapshots, idle NAT gateways and load balancers), Budgets with alerts, cost allocation tags."},{"kind":"question","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"757","title":"What are regions and availability zones?","body":"A region is a geographic area (Mumbai, Singapore, Tokyo…) containing multiple isolated availability zones — separate data centres with independent power, cooling and networking connected by low-latency links. Deploying across at least two AZs protects against a data-centre failure; multiple regions protect against regional outages and serve global users."},{"kind":"question","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"758","title":"Explain the shared responsibility model.","body":"AWS is responsible for security of the cloud — physical data centres, hardware, networking, virtualisation and the internals of managed services. The customer is responsible for security in the cloud — IAM users and policies, data and its encryption, network configuration (security groups), OS patching on EC2, application code and secrets. The split shifts with the service: more customer responsibility on EC2, less on Lambda/S3."},{"kind":"question","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"759","title":"What is IAM and what is the difference between a user and a role?","body":"IAM controls who can do what on which AWS resources using JSON policies. A user is a long-term identity (person or legacy app) with credentials; a role is an identity without permanent credentials that is assumed to obtain temporary credentials — used by EC2 instances, ECS tasks, Lambda functions, other accounts and federated users. Applications should use roles, not access keys."},{"kind":"question","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"760","title":"EC2 vs Elastic Beanstalk vs ECS/Fargate vs Lambda for hosting a .NET API?","body":"EC2: full VMs you manage (good for legacy IIS apps). Elastic Beanstalk: PaaS that provisions EC2, load balancing and scaling for you — quick hosting. ECS on Fargate: run containers without managing servers — the common choice for containerised ASP.NET Core microservices. Lambda: functions billed per request that scale to zero — great for event-driven or spiky APIs, with cold starts and time limits (15 min)."},{"kind":"question","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"761","title":"What is S3 and what are storage classes?","body":"Simple Storage Service: object storage for files of any size in buckets, highly durable (11 nines), accessed over HTTPS/SDK. Storage classes trade price vs access speed: Standard (frequent), Intelligent-Tiering (automatic), Standard-IA/One Zone-IA (infrequent), Glacier Instant/Flexible/Deep Archive (archives). Lifecycle rules move objects between classes automatically."},{"kind":"question","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"762","title":"How do you host SQL Server on AWS?","body":"Amazon RDS for SQL Server (managed: backups, patching, Multi-AZ failover, read replicas on Enterprise; licence included), RDS Custom for SQL Server (OS access, BYOL), or SQL Server on EC2 (full control, Always On, SSIS/SSRS on the box). Place databases in private subnets, restrict security groups to the app tier, encrypt with KMS and store credentials in Secrets Manager."},{"kind":"question","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"763","title":"Security group vs network ACL?","body":"Security groups are stateful firewalls attached to instances/network interfaces with allow rules only — return traffic is automatically allowed. Network ACLs are stateless rules on subnets with both allow and deny, evaluated in order, requiring explicit rules for return traffic. Security groups are the primary control; NACLs add coarse subnet-level protection."},{"kind":"question","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"764","title":"SQS vs SNS vs EventBridge?","body":"SQS is a message queue — consumers pull messages, each processed by one consumer, with retries and DLQs (decoupling and buffering). SNS is pub/sub — a message published to a topic is pushed to all subscribers (fan-out, notifications). EventBridge is an event bus with content-based routing rules from AWS services, SaaS and apps, plus a scheduler — for event-driven architectures. Common combination: SNS/EventBridge fan-out to several SQS queues."},{"kind":"question","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"765","title":"What is DynamoDB and how do you design keys?","body":"A fully managed NoSQL key-value/document database with consistent single-digit-ms latency at any scale. Items are stored by partition key (and optional sort key); design starts from access patterns — choose a high-cardinality partition key to spread load, a sort key for ranges/ordering, and GSIs for other access patterns (often single-table design). Use on-demand or provisioned capacity with auto scaling."},{"kind":"question","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"766","title":"ALB vs NLB vs API Gateway?","body":"ALB is a layer-7 HTTP/HTTPS load balancer with host/path routing, WebSockets and TLS termination — for web apps and containers. NLB is layer 4 (TCP/UDP), extremely fast with static IPs — for non-HTTP protocols or extreme throughput. API Gateway is a managed API front door with authentication, throttling, API keys, request validation and direct Lambda integration — for public/serverless APIs."},{"kind":"question","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"767","title":"How do you manage secrets for a .NET app on AWS?","body":"Store them in Secrets Manager (with rotation for database credentials) or SSM Parameter Store (SecureString), grant the app's IAM role permission to read only those secrets, and load them into IConfiguration at startup with the AWS configuration provider or SDK. No secrets in appsettings, environment files in source control or container images."},{"kind":"question","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"768","title":"How do you make an application highly available on AWS?","body":"Run stateless app instances/tasks in at least two AZs behind an ALB with health checks and auto scaling; use Multi-AZ databases (RDS/Aurora) and replicated storage (S3); externalise sessions (ElastiCache/DynamoDB); use queues to absorb spikes; Route 53 health checks and failover routing to a second region for disaster recovery; automate infrastructure with IaC and test failures."},{"kind":"question","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"769","title":"What are the pillars of the AWS Well-Architected Framework?","body":"Operational excellence (automation, observability, runbooks), Security (identity, protection, detection), Reliability (recover from failure, scale), Performance efficiency (right resources, experiment), Cost optimisation (pay for what you need) and Sustainability (minimise environmental impact). AWS offers a Well-Architected Tool to review workloads against them."},{"kind":"question","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"770","title":"Your ASP.NET Core API on ECS must read files from S3 and connect to RDS SQL Server. How do you set up access securely?","body":"Give the ECS task a task IAM role with a least-privilege policy for the specific S3 bucket/prefix; the AWS SDK picks up temporary credentials automatically. Put RDS in private subnets with a security group allowing port 1433 only from the ECS service's security group; store the DB credentials in Secrets Manager (readable by the task role) and load them at startup; enforce TLS ( Encrypt=True ) and KMS encryption at rest."},{"kind":"question","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"771","title":"A company is moving from Azure to AWS. How would you map their stack (App Service, Azure SQL, Blob, Service Bus, Key Vault, App Insights)?","body":"App Service → Elastic Beanstalk, App Runner or ECS Fargate; Azure SQL → RDS for SQL Server (or Aurora PostgreSQL if re-platforming); Blob Storage → S3; Service Bus queues/topics → SQS/SNS (or Amazon MQ for AMQP compatibility); Key Vault → Secrets Manager + KMS; Application Insights → CloudWatch + X-Ray/OpenTelemetry; Azure DevOps pipelines can deploy to AWS or move to GitHub Actions/CodePipeline. Migrate data with AWS DMS and test performance and IAM thoroughly."},{"kind":"question","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"772","title":"Your AWS bill doubled this month. How do you investigate and reduce it?","body":"Use Cost Explorer grouped by service, account and tags to find the jump (often data transfer, NAT gateway traffic, oversized RDS/EC2, forgotten resources or logging volume). Fix: right-size or stop idle resources, Savings Plans for steady compute, S3 lifecycle policies, VPC endpoints to avoid NAT charges for S3/DynamoDB traffic, reduce CloudWatch log retention, set Budgets alerts and tagging policies to prevent recurrence."},{"kind":"cheat","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"1","title":"Core services","body":"IAM (roles!) · EC2 · Elastic Beanstalk · ECS/Fargate · EKS · Lambda · S3 · EBS/EFS · RDS (SQL Server) · Aurora · DynamoDB · ElastiCache · VPC · ALB/NLB · Route 53 · CloudFront · API Gateway · SQS/SNS/EventBridge · CloudWatch · CloudTrail · KMS/Secrets Manager · Cognito."},{"kind":"cheat","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"2","title":"Azure ↔ AWS","body":"App Service ↔ Beanstalk/App Runner · Container Apps ↔ Fargate · AKS ↔ EKS · Functions ↔ Lambda · Blob ↔ S3 · Azure SQL ↔ RDS · Cosmos DB ↔ DynamoDB · Service Bus ↔ SQS/SNS · Key Vault ↔ Secrets Manager · Monitor ↔ CloudWatch · Bicep ↔ CloudFormation/CDK."},{"kind":"cheat","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"3","title":"HA basics","body":"2+ AZs · ALB + auto scaling · Multi-AZ RDS · stateless apps · queues for spikes · Route 53 failover for DR."},{"kind":"cheat","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"4","title":"Security basics","body":"Root MFA, no keys · least-privilege policies · roles for apps · private subnets for data · security groups chain · KMS encryption · Secrets Manager · CloudTrail on · WAF on public endpoints."},{"kind":"cheat","course_slug":"aws","course_title":"Amazon Web Services (AWS) for .NET and Full Stack Developers","ref":"5","title":"Cost basics","body":"Right-size · Savings Plans/RIs · Spot for batch · Graviton · serverless for spiky · S3 lifecycle · VPC endpoints · Budgets + tags."},{"kind":"course","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"","title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","body":"GCP fundamentals — resource hierarchy (organisation, folders, projects), regions and zones, Cloud IAM and service accounts; compute (Compute Engine, Cloud Run, GKE, App Engine, Cloud Functions), storage (Cloud Storage), databases (Cloud SQL for SQL Server/PostgreSQL/MySQL, AlloyDB, Spanner, Firestore, Bigtable, Memorystore), analytics (BigQuery, Pub/Sub, Dataflow), networking (VPC, Cloud Load Balancing, Cloud CDN, Cloud DNS), security (Secret Manager, Cloud KMS, Identity Platform), operations (Cloud Logging, Monitoring, Trace), CI/CD (Cloud Build, Artifact Registry, Cloud Deploy), deploying ASP.NET Core to Cloud Run, Vertex AI, cost management and GCP interview questions. Google Cloud Platform (GCP) is Google's public cloud. Its strengths are data and analytics (BigQuery), Kubernetes (GKE — Google created Kubernetes), a global network (premium tier, global load balancing), serverless containers (Cloud Run) and AI (Vertex AI, Gemini). For a .NET/full stack developer the most common setup is: ASP.NET Core in a container on Cloud Run + Cloud SQL (SQL Server or PostgreSQL) + Cloud Storage + Secret Manager + Cloud Logging/Monitoring , built with Cloud Build . See the Azure ↔ AWS ↔ GCP service map in the AWS course. Key GCP names: Compute Engine (VMs), Cloud Run (serverless containers), GKE (Kubernetes), Cloud Storage (objects), Cloud SQL (managed relational), Firestore (documents), Pub/Sub (messaging), BigQuery (warehouse), Cloud Load Balancing, Cloud CDN, Cloud DNS, Secret Manager, Cloud KMS, Cloud Logging/Monitoring/Trace, Cloud Build, Artifact Registry. Year Milestone --- --- 2008 App Engine — Google's first cloud platform (PaaS) 2010–2012 Cloud Storage, BigQuery , Cloud SQL, Compute Engine (2012 preview, GA 2013) 2014–2015 Kubernetes open-sourced (2014); GKE GA (2015); Pub/Sub 2016–2017 Cloud Functions, Spanner GA, Firestore (2017), Cloud SQL PostgreSQL 2019 Cloud Run GA (serverless containers), Anthos, Cloud SQL for SQL Server 2021–2022 Vertex AI, AlloyDB for PostgreSQL, GKE Autopilot 2023–2025 Gemini models across GCP, Cloud Run jobs/GPUs, Cloud Functions merged into Cloud Run functions , Infrastructure Manager (Terraform-based) Deploying an ASP.NET Core API on GCP: 1. Create a project (billing account linked), enable APIs ( run.googleapis.com , sqladmin.googleapis.com , secretmanager.googleapis.com ). 2. Database: Cloud SQL instance (SQL Server or PostgreSQL) with private IP or the Cloud SQL Auth Proxy/connector; HA (regional) and automated backups. 3. Secrets: store the DB password/connection string in Secret Manager. 4. Build: gcloud builds submit (Cloud Build) or GitHub Actions → container image in Artifact Registry . 5. Deploy: gcloud run deploy — Cloud Run gives an HTTPS URL, autoscaling (including to zero), revisions and traffic splitting. 6. Edge: custom domain + global external HTTPS load balancer with Cloud CDN and Cloud Armor (WAF) if needed. 7. Operate: Cloud Logging (stdout JSON logs collected automatically), Cloud Monitoring alerts, Cloud Trace (OpenTelemetry), Error Reporting, budgets. - Google Cloud Console, gcloud CLI ( gcloud init , gcloud run deploy ), Cloud Shell (browser terminal with tools pre-installed). - Google Cloud .NET client libraries ( Google.Cloud.Storage.V1 , Google.Cloud.PubSub.V1 , Google.Cloud.SecretManager.V1 , Google.Cloud.Diagnostics.AspNetCore3 ), Cloud Code extensions for VS Code/JetBrains. - IaC: Terraform (most common), Infrastructure Manager, Config Connector (Kubernetes CRDs). - Learning: Google Cloud Skills Boost, free tier ($300 credit for new accounts + always-free usage limits), Architecture Framework."},{"kind":"lesson","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"resource-hierarchy-regions-zones-and-cloud-iam","title":"Resource hierarchy, regions/zones and Cloud IAM","body":"text Organisation (company.com) └── Folders (Production, Non-production, Teams) └── Projects (shop-prod, shop-dev) ← billing, APIs, quotas and resources live in projects └── Resources (Cloud Run services, Cloud SQL instances, buckets) - Region (e.g. asia-south1 Mumbai, asia-east1 Taiwan, us-central1 ) contains zones ( asia-south1-a/b/c ). Resources are zonal (VMs, disks), regional (Cloud Run, regional Cloud SQL, regional GKE) or multi-regional/global (Cloud Storage multi-region, global load balancer, BigQuery multi-region). - Cloud IAM: grant roles (collections of permissions) to principals (Google accounts, groups, service accounts , workforce/workload identity) on a resource; policies inherit down the hierarchy. - Basic roles (Owner/Editor/Viewer) — too broad for production. - Predefined roles ( roles/run.invoker , roles/cloudsql.client , roles/storage.objectViewer ) — use these. - Custom roles when needed. - Service accounts are identities for workloads (a Cloud Run service runs as a service account); use Workload Identity Federation for GitHub Actions/AWS/Azure to avoid service account keys. bash gcloud projects add-iam-policy-binding shop-prod \\ --member=\"serviceAccount:shop-api@shop-prod.iam.gserviceaccount.com\" --role=\"roles/cloudsql.client\""},{"kind":"lesson","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"compute-engine-cloud-run-gke-app-engine-and-cloud-run-functions","title":"Compute Engine, Cloud Run, GKE, App Engine and Cloud Run functions","body":"Service Model .NET use --- --- --- Compute Engine VMs (Windows Server images with IIS available; managed instance groups for autoscaling) Lift-and-shift .NET Framework/IIS apps Cloud Run Serverless containers (HTTP services and jobs), scale to zero, per-request billing ASP.NET Core APIs and web apps — the default choice GKE (Standard / Autopilot ) Managed Kubernetes Many microservices, teams on Kubernetes App Engine (Standard/Flexible) Original PaaS Legacy; Flexible supports .NET via containers Cloud Run functions (formerly Cloud Functions) Event-driven functions (.NET supported) Triggers from Pub/Sub, Storage, Eventarc bash Build and deploy an ASP.NET Core API to Cloud Run from source (uses Cloud Build + buildpacks or your Dockerfile) gcloud run deploy shop-api --source . --region asia-south1 --allow-unauthenticated \\ --service-account shop-api@shop-prod.iam.gserviceaccount.com \\ --set-secrets \"ConnectionStrings Shop=shop-db-cs:latest\" --min-instances 0 --max-instances 20 csharp // Program.cs — Cloud Run sends the port in the PORT environment variable var port = Environment.GetEnvironmentVariable(\"PORT\") ?? \"8080\"; builder.WebHost.UseUrls($\"http://0.0.0.0:{port}\"); Cloud Run facts: each revision is immutable; traffic splitting for canary releases; concurrency (default up to 80 requests per instance); request timeout up to 60 minutes; min instances to avoid cold starts; VPC access for private Cloud SQL/Memorystore."},{"kind":"lesson","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"cloud-storage","title":"Cloud Storage","body":"Object storage in buckets (globally unique names), classes Standard , Nearline (≥30 days), Coldline (≥90 days), Archive (≥365 days); Autoclass moves objects automatically; lifecycle rules; object versioning; signed URLs for temporary access; uniform bucket-level access with IAM; encryption by default (Google-managed or customer-managed keys in Cloud KMS). csharp var storage = await StorageClient.CreateAsync(); // credentials from the service account automatically await using var file = File.OpenRead(path); await storage.UploadObjectAsync(\"shop-uploads-prod\", $\"invoices/{id}.pdf\", \"application/pdf\", file); var signer = UrlSigner.FromCredential(await GoogleCredential.GetApplicationDefaultAsync()); string url = await signer.SignAsync(\"shop-uploads-prod\", $\"invoices/{id}.pdf\", TimeSpan.FromMinutes(15));"},{"kind":"lesson","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"databases-cloud-sql-sql-server-alloydb-spanner-firestore-bigtable-memorystore","title":"Databases — Cloud SQL (SQL Server), AlloyDB, Spanner, Firestore, Bigtable, Memorystore","body":"Service Type Use --- --- --- Cloud SQL Managed SQL Server , PostgreSQL, MySQL Most business apps; lift-and-shift SQL Server AlloyDB PostgreSQL-compatible, high performance (columnar engine for analytics) Demanding PostgreSQL workloads Spanner Globally distributed, strongly consistent relational (SQL) with horizontal scale Global financial/inventory systems needing scale + consistency Firestore Serverless document database with real-time listeners and offline mobile sync Mobile/web apps, user profiles Bigtable Wide-column NoSQL for huge throughput (HBase API) Time series, IoT, analytics at petabyte scale Memorystore Managed Redis/Valkey/Memcached Caching, sessions BigQuery Serverless data warehouse (SQL over petabytes) Analytics, BI, ML Cloud SQL for SQL Server: editions Express/Web/Standard/Enterprise (licence included), high availability (regional instance with a standby in another zone, automatic failover), automated backups + point-in-time recovery, read replicas, private IP, maintenance windows. Connect with: - Private IP from Cloud Run/GKE via VPC (Direct VPC egress or Serverless VPC Access). - Cloud SQL Auth Proxy / language connectors — IAM-authorised, encrypted tunnel without managing IP allow-lists (for SQL Server, run the proxy as a sidecar or locally). text Server=10.20.0.5;Database=Shop;User Id=shop app;Password=<from Secret Manager ;Encrypt=True;TrustServerCertificate=False"},{"kind":"lesson","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"pub-sub-eventarc-cloud-tasks-and-bigquery","title":"Pub/Sub, Eventarc, Cloud Tasks and BigQuery","body":"- Pub/Sub — global messaging: publishers send to a topic ; each subscription gets every message (pull or push to an HTTPS endpoint such as Cloud Run); at-least-once delivery (exactly-once option for pull), ordering keys, dead-letter topics, retention and replay. - Eventarc — routes events from Google services (Cloud Storage object finalised, audit logs) and Pub/Sub to Cloud Run. - Cloud Tasks — queue of HTTP tasks with rate limits and retries (like a background job queue for one service). - Cloud Scheduler — cron jobs calling HTTP endpoints/Pub/Sub. - Workflows — orchestrate services/APIs (sagas). - Dataflow (Apache Beam) — stream/batch processing; BigQuery — load or stream data and query with SQL; Looker/Looker Studio for dashboards. csharp var publisher = await PublisherClient.CreateAsync(TopicName.FromProjectTopic(\"shop-prod\", \"order-placed\")); await publisher.PublishAsync(JsonSerializer.Serialize(new { orderId, total }));"},{"kind":"lesson","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"vpc-load-balancing-cloud-cdn-cloud-dns-and-cloud-armor","title":"VPC, load balancing, Cloud CDN, Cloud DNS and Cloud Armor","body":"- VPC networks are global in GCP (subnets are regional) — one VPC can span regions. - Firewall rules/policies on VPCs target instances by tags or service accounts. - Cloud Load Balancing: global external Application Load Balancer (single anycast IP worldwide, routes to the nearest healthy backend — Cloud Run, GKE, instance groups, buckets), regional and internal load balancers. - Cloud CDN on the load balancer; Cloud Armor for WAF/DDoS protection; Cloud DNS for managed zones; Certificate Manager / Google-managed SSL certificates. - Private Service Connect / Private Google Access to reach Google APIs without public IPs; Cloud NAT for outbound internet from private resources."},{"kind":"lesson","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"security-and-operations-secret-manager-kms-logging-monitoring","title":"Security and operations — Secret Manager, KMS, Logging, Monitoring","body":"- Secret Manager — versioned secrets, IAM-controlled; Cloud Run mounts them as env vars or files ( --set-secrets ). - Cloud KMS — encryption keys (CMEK for Storage, Cloud SQL, BigQuery); HSM-backed keys. - Identity Platform / Firebase Authentication — end-user sign-in; Identity-Aware Proxy (IAP) — protect internal apps with Google identity without a VPN. - Security Command Center , Organization Policies (e.g. disallow public buckets, restrict regions), VPC Service Controls (data exfiltration perimeters). - Cloud Logging (stdout/stderr JSON from Cloud Run/GKE is ingested automatically; Logs Explorer queries; log sinks to BigQuery/Storage), Cloud Monitoring (metrics, uptime checks, alerting, SLOs), Cloud Trace / Profiler , Error Reporting . ASP.NET Core: write structured JSON logs to stdout or use Google.Cloud.Diagnostics.AspNetCore3 ; OpenTelemetry exporters for traces."},{"kind":"lesson","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"ci-cd-cloud-build-artifact-registry-cloud-deploy-and-github-actions","title":"CI/CD — Cloud Build, Artifact Registry, Cloud Deploy and GitHub Actions","body":"yaml cloudbuild.yaml — build, push and deploy on every commit (trigger from GitHub) steps: - name: gcr.io/cloud-builders/docker args: [\"build\", \"-t\", \"asia-south1-docker.pkg.dev/$PROJECT ID/shop/api:$SHORT SHA\", \".\"] - name: gcr.io/cloud-builders/docker args: [\"push\", \"asia-south1-docker.pkg.dev/$PROJECT ID/shop/api:$SHORT SHA\"] - name: gcr.io/google.com/cloudsdktool/cloud-sdk entrypoint: gcloud args: [\"run\", \"deploy\", \"shop-api\", \"--image\", \"asia-south1-docker.pkg.dev/$PROJECT ID/shop/api:$SHORT SHA\", \"--region\", \"asia-south1\"] images: [\"asia-south1-docker.pkg.dev/$PROJECT ID/shop/api:$SHORT SHA\"] GitHub Actions alternative: google-github-actions/auth with Workload Identity Federation (no JSON keys) + google-github-actions/deploy-cloudrun . Cloud Deploy manages promotion pipelines (dev → staging → prod) for GKE and Cloud Run with approvals and rollbacks."},{"kind":"lesson","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"cost-management-and-the-google-cloud-architecture-framework","title":"Cost management and the Google Cloud Architecture Framework","body":"- Pricing perks: sustained use discounts (automatic for VMs running much of the month), committed use discounts (1/3 years), Spot VMs , per-second billing, Cloud Run scale-to-zero, free tier. - Controls: budgets and alerts, billing export to BigQuery for analysis, labels for cost allocation, recommender (idle VMs, oversized instances), lifecycle rules on buckets, BigQuery cost control (partitioned/clustered tables, maximum bytes billed , avoid SELECT ). - Architecture Framework pillars: system design, operational excellence, security/privacy/compliance, reliability, cost optimisation, performance optimisation (plus sustainability guidance)."},{"kind":"question","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"773","title":"What is the GCP resource hierarchy?","body":"Organisation (your domain) → folders (departments/environments) → projects → resources. Projects are the core unit: they hold resources, enabled APIs, quotas and are linked to a billing account. IAM policies and organisation policies set at higher levels are inherited by everything below."},{"kind":"question","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"774","title":"What is Cloud Run and why is it popular for .NET APIs?","body":"A fully managed platform that runs any stateless HTTP container: you deploy an image (or source), get an HTTPS endpoint, automatic scaling from zero to many instances, per-request billing, revisions with traffic splitting, and integration with Secret Manager, Cloud SQL and Pub/Sub. ASP.NET Core containers run unchanged — just listen on the PORT environment variable."},{"kind":"question","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"775","title":"What are service accounts?","body":"Identities for workloads rather than people. A Cloud Run service, VM or GKE workload runs as a service account, and IAM roles granted to that account decide what Google APIs it can call (e.g. roles/cloudsql.client , roles/secretmanager.secretAccessor ). Client libraries pick up its credentials automatically; avoid downloading service account keys — use Workload Identity (Federation) instead."},{"kind":"question","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"776","title":"Compute Engine vs Cloud Run vs GKE vs App Engine?","body":"Compute Engine: VMs with full control (legacy/IIS apps). Cloud Run: serverless containers — simplest for HTTP services and jobs. GKE: managed Kubernetes for complex microservice platforms (Autopilot reduces node management). App Engine: the original PaaS, now mostly replaced by Cloud Run for new work."},{"kind":"question","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"777","title":"How do you connect a Cloud Run service to Cloud SQL for SQL Server securely?","body":"Use a private IP Cloud SQL instance and connect from Cloud Run through VPC egress (Direct VPC egress or a Serverless VPC Access connector), or use the Cloud SQL Auth Proxy/connector which authorises with IAM and encrypts the connection. Run Cloud Run as a dedicated service account with roles/cloudsql.client , keep the password/connection string in Secret Manager mounted as an environment variable, and enable HA and backups on the instance."},{"kind":"question","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"778","title":"Pub/Sub vs Cloud Tasks?","body":"Pub/Sub is many-to-many event messaging: publishers send to topics and every subscription receives each message (fan-out, decoupling, streaming). Cloud Tasks is a queue of individual HTTP tasks targeted at one handler with explicit rate limits, scheduling and retries — like a background job queue. Use Pub/Sub for events, Cloud Tasks for controlled work dispatch."},{"kind":"question","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"779","title":"What is BigQuery and when would you use it?","body":"A serverless, columnar data warehouse that runs SQL over terabytes–petabytes without managing servers, billed by storage and bytes scanned (or reserved slots). Use it for analytics, reporting, log analysis and ML (BigQuery ML) — not for OLTP. Partition and cluster tables and avoid SELECT to control cost."},{"kind":"question","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"780","title":"Cloud SQL vs Spanner vs Firestore vs Bigtable?","body":"Cloud SQL: managed SQL Server/PostgreSQL/MySQL for typical regional relational apps. Spanner: horizontally scalable, globally consistent relational database for very large or global systems. Firestore: serverless document database with real-time sync for web/mobile. Bigtable: wide-column NoSQL for massive throughput time-series/analytical workloads."},{"kind":"question","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"781","title":"How is a GCP VPC different from AWS/Azure networks?","body":"GCP VPC networks are global resources — one VPC spans all regions with regional subnets, and instances in different regions communicate over Google's private network without peering. AWS VPCs and Azure VNets are regional and need peering or transit gateways to connect regions. Firewall rules in GCP apply at the VPC level and can target network tags or service accounts."},{"kind":"question","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"782","title":"How do you avoid service account keys in CI/CD?","body":"Use Workload Identity Federation: configure a workload identity pool and provider trusting GitHub Actions' (or Azure DevOps') OIDC tokens, allow it to impersonate a deploy service account with minimal roles, and authenticate in the pipeline with google-github-actions/auth — short-lived tokens, nothing secret stored in the CI system."},{"kind":"question","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"783","title":"You need to deploy an ASP.NET Core API with a SQL Server database on GCP with minimal operations work. What do you build?","body":"Containerise the API (Dockerfile listening on PORT), push to Artifact Registry with Cloud Build, deploy to Cloud Run with a dedicated service account, min instances 1 for low latency, secrets from Secret Manager; Cloud SQL for SQL Server (HA, backups, PITR, private IP) reached via VPC egress; Cloud Logging/Monitoring alerts on errors and latency; a global HTTPS load balancer with Cloud Armor if a custom domain and WAF are needed; budgets for cost control."},{"kind":"question","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"784","title":"Logs from your .NET app on Cloud Run show up as plain text without severity. How do you fix it?","body":"Write structured JSON logs to stdout with a severity field (and message , trace fields) — e.g. use a JSON console formatter or Google.Cloud.Diagnostics.AspNetCore3 — so Cloud Logging parses levels and fields, and include the logging.googleapis.com/trace field to correlate logs with Cloud Trace requests."},{"kind":"question","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"785","title":"BigQuery costs are high because analysts run large queries. How do you reduce them?","body":"Partition tables by date and cluster by common filters, require partition filters, avoid SELECT , use materialised views and BI Engine for dashboards, set per-user/per-project custom quotas and maximum bytes billed , consider slot reservations (editions) for predictable spend, and review the most expensive queries in INFORMATION SCHEMA jobs views."},{"kind":"question","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"786","title":"What are regions, zones and multi-regions in GCP?","body":"A region is a geographic location (asia-south1 Mumbai) with three or more zones — isolated deployment areas within the region. Zonal resources (VMs, disks) live in one zone; regional resources replicate across zones (regional Cloud SQL HA, Cloud Run); multi-regional resources (Cloud Storage multi-region, BigQuery US/EU) replicate across regions for availability and proximity."},{"kind":"question","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"787","title":"How do you control access to a Cloud Run service?","body":"Public services allow allUsers the roles/run.invoker role; private services require callers with run.invoker (service accounts for service-to-service with ID tokens), Identity-Aware Proxy for employees, or ingress settings restricting traffic to internal/load balancer only. Combine with application-level auth (JWT from Identity Platform/Entra) for end users."},{"kind":"cheat","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"1","title":"Key services","body":"Compute Engine · Cloud Run · GKE (Autopilot) · Cloud Run functions · Cloud Storage · Cloud SQL (SQL Server/Postgres/MySQL) · AlloyDB · Spanner · Firestore · Bigtable · Memorystore · BigQuery · Pub/Sub · Eventarc · Cloud Tasks · Load Balancing · Cloud CDN · Cloud Armor · Secret Manager · Cloud KMS · Logging/Monitoring/Trace · Cloud Build · Artifact Registry · Vertex AI."},{"kind":"cheat","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"2","title":"Hierarchy & IAM","body":"Org → folders → projects → resources · predefined roles · service accounts for workloads · Workload Identity Federation (no keys) · org policies."},{"kind":"cheat","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"3","title":".NET on GCP","body":"Container on Cloud Run (listen on PORT) · Cloud SQL via private IP or Auth Proxy · secrets via --set-secrets · JSON logs to stdout · Cloud Build/GitHub Actions deploy."},{"kind":"cheat","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"4","title":"Cost","body":"Sustained & committed use discounts · Spot VMs · scale to zero · budgets · BigQuery partition/cluster · lifecycle rules."},{"kind":"cheat","course_slug":"gcp","course_title":"Google Cloud Platform (GCP) for .NET and Full Stack Developers","ref":"5","title":"Compared with Azure/AWS","body":"Global VPC · global load balancer with one anycast IP · strongest analytics (BigQuery) · Kubernetes origin (GKE) · per-second billing."},{"kind":"course","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"","title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","body":"Document structure, semantic HTML, forms and accessibility, the CSS cascade and specificity, the box model, Flexbox and Grid, responsive design with media and container queries, CSS variables, Bootstrap/Tailwind and the HTML/CSS interview questions. HTML (HyperText Markup Language) describes the structure and meaning of a page; CSS (Cascading Style Sheets) describes how it looks ; JavaScript adds behaviour. Every frontend framework (Angular, React, Vue) still renders HTML and CSS, so these basics are asked in every frontend and full stack interview. Topic What interviewers check --- --- Semantic HTML header , nav , main , article , section , footer instead of div soup Forms Labels, input types, validation attributes Accessibility (a11y) Alt text, labels, keyboard use, ARIA only when needed Cascade & specificity Why a style does or doesn't apply Box model content-box vs border-box , margin collapsing Layout Flexbox (1-D) vs Grid (2-D), positioning Responsive design Mobile-first media queries, fluid units, container queries Year Milestone --- --- 1991–1999 HTML 1 → HTML 4.01; CSS1 (1996), CSS2 (1998) 2000s XHTML; table layouts give way to floats 2011–2012 CSS split into modules (\"CSS3\"): media queries, flexbox drafts, transitions 2014 HTML5 a W3C Recommendation; now the HTML Living Standard (WHATWG) 2017 CSS Grid ships in all major browsers; CSS custom properties widely supported 2022–2023 Container queries, :has() , cascade layers ( @layer ), native CSS nesting 2024–2025 Popover API, <dialog , anchor positioning, view transitions, @scope reaching browsers Frameworks: Bootstrap 5 (2021, no jQuery), Tailwind CSS 4 (2025, CSS-first config). How the browser turns HTML + CSS into pixels (critical rendering path): 1. Download HTML → parse into the DOM tree. 2. Download CSS → parse into the CSSOM . 3. Combine into the render tree (only visible nodes with computed styles). 4. Layout (reflow) — compute size and position of every box. 5. Paint — fill pixels (text, colours, borders, shadows). 6. Composite — layers combined on the GPU. CSS is render-blocking and synchronous <script is parser-blocking — so put CSS in <head , use defer / type=\"module\" for scripts, and animate transform / opacity (composite only) rather than width / top (layout every frame). - Browser DevTools — Elements (box model, computed styles, Flexbox/Grid overlays), Lighthouse (performance, accessibility, SEO), device toolbar for responsive testing. - Editors — VS Code with Emmet, Prettier, stylelint. - CSS tooling — Sass/SCSS, PostCSS + Autoprefixer, CSS Modules. - Frameworks — Bootstrap, Tailwind CSS, Angular Material, MUI. - Accessibility — axe DevTools, WAVE, screen readers (NVDA, VoiceOver). - Reference — MDN Web Docs, caniuse.com."},{"kind":"lesson","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"document-structure-and-semantic-html","title":"Document structure and semantic HTML","body":"html <!DOCTYPE html <html lang=\"en\" <head <meta charset=\"utf-8\" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" <title Orders — Divakar Shop</title <link rel=\"stylesheet\" href=\"styles.css\" <script src=\"app.js\" defer </script </head <body <header <nav aria-label=\"Main\" <a href=\"/\" Home</a <a href=\"/orders\" Orders</a </nav </header <main <article <h1 Order 1001</h1 <section <h2 Items</h2 …</section </article <aside Related offers</aside </main <footer © 2026</footer </body </html Why semantic tags matter: screen readers use them as landmarks, search engines understand the content, and code is easier to read. <div and <span have no meaning — use them only for styling hooks. Element Meaning --- --- header / footer Intro / closing content of a page or section nav Major navigation links main The unique main content (one per page) article Self-contained content (post, product card) section Thematic group with a heading aside Related but secondary content h1 – h6 Heading hierarchy — don't skip levels for styling Block vs inline: block elements ( div , p , h1 , section ) start on a new line and take full width; inline elements ( span , a , strong ) flow within text and ignore width/height; inline-block flows inline but accepts width/height."},{"kind":"lesson","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"forms-input-types-and-validation","title":"Forms, input types and validation","body":"html <form action=\"/api/register\" method=\"post\" novalidate <label for=\"email\" Email</label <input id=\"email\" name=\"email\" type=\"email\" required autocomplete=\"email\" <label for=\"age\" Age</label <input id=\"age\" name=\"age\" type=\"number\" min=\"18\" max=\"99\" <label for=\"phone\" Phone</label <input id=\"phone\" name=\"phone\" type=\"tel\" pattern=\"[0-9]{10}\" placeholder=\"10 digits\" <fieldset <legend Plan</legend <label <input type=\"radio\" name=\"plan\" value=\"basic\" checked Basic</label <label <input type=\"radio\" name=\"plan\" value=\"pro\" Pro</label </fieldset <select name=\"country\" <option value=\"IN\" India</option <option value=\"TW\" Taiwan</option </select <textarea name=\"notes\" rows=\"3\" </textarea <button type=\"submit\" Register</button </form - Every input needs a <label ( for = input id ) — clicking the label focuses the input and screen readers announce it. - HTML5 types ( email , number , date , tel , url ) give mobile keyboards and built-in validation. - Constraint attributes: required , min , max , minlength , maxlength , pattern . - GET puts data in the URL (search forms); POST sends it in the body (create/change data). - Client-side validation is for UX only — always validate again on the server."},{"kind":"lesson","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"accessibility-essentials","title":"Accessibility essentials","body":"- Meaningful alt text on images ( alt=\"\" for decorative ones). - Use real <button for actions and <a href for navigation — they work with the keyboard for free. - Visible focus styles; logical tab order; never outline: none without a replacement. - Colour contrast at least 4.5:1 for normal text (WCAG AA). - Headings in order; lang on <html ; labels on all form fields. - ARIA only when native HTML can't express it: aria-label , aria-expanded , aria-live=\"polite\" for status messages, role=\"dialog\" . \"No ARIA is better than bad ARIA.\" html <button aria-expanded=\"false\" aria-controls=\"menu\" Menu</button <ul id=\"menu\" hidden …</ul <div aria-live=\"polite\" id=\"status\" </div <!-- screen readers announce updates --"},{"kind":"lesson","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"selectors-the-cascade-and-specificity","title":"Selectors, the cascade and specificity","body":"css p { } / type / .card { } / class / main { } / id / a:hover { } / pseudo-class / p::first-line { } / pseudo-element / nav a { } / direct child / h2 + p { } / adjacent sibling / input[type=\"email\"] { } / attribute / .card:has(img) { } / parent selector (modern) / Which rule wins? The cascade, in order: 1. Origin and importance ( !important beats normal; user-agent < author). 2. Cascade layers ( @layer ) order. 3. Specificity — (ids, classes/attributes/pseudo-classes, elements): Selector Specificity --- --- p 0,0,1 .card p 0,1,1 main .card p 1,1,1 inline style=\"\" beats all selectors 4. Source order — later wins when specificity is equal. Inheritance: text properties ( color , font- , line-height ) inherit; box properties ( margin , border , width ) don't. Interview tip: Avoid !important and id selectors for styling — keep specificity low and flat (classes), so styles are easy to override."},{"kind":"lesson","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"the-box-model-units-and-positioning","title":"The box model, units and positioning","body":"Every element is a box: content → padding → border → margin . css , ::before, ::after { box-sizing: border-box; } / width includes padding + border — the modern default / .card { width: 300px; padding: 16px; border: 1px solid ddd; margin: 12px; } / content-box: rendered width = 300 + 32 + 2 = 334px; border-box: rendered width = 300px / Margin collapsing: vertical margins of adjacent blocks combine into the larger one (not in flex/grid containers). Unit Relative to Use --- --- --- px Fixed Borders, small details rem Root font size Font sizes, spacing (respects user zoom settings) em Parent/element font size Padding that scales with its text % Parent Fluid widths vw / vh / dvh Viewport (dynamic viewport for mobile bars) Full-screen sections fr Free space in Grid Grid columns ch Width of \"0\" Readable line length ( max-width: 70ch ) Position: Value Behaviour --- --- static Normal flow (default) relative Offset from its normal place; becomes containing block for absolute children absolute Removed from flow; positioned to nearest positioned ancestor fixed Relative to the viewport (stays when scrolling) sticky Normal until a scroll threshold, then sticks ( top: 0 ) z-index works only on positioned (or flex/grid) elements and within its stacking context ."},{"kind":"lesson","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"flexbox-one-dimensional-layout","title":"Flexbox — one-dimensional layout","body":"css .toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; } .toolbar .search { flex: 1; min-width: 200px; } / grow to fill free space / Property (container) Does --- --- flex-direction row / column — sets the main axis justify-content Align on the main axis ( flex-start , center , space-between ) align-items Align on the cross axis ( stretch , center ) flex-wrap Allow items onto new lines gap Space between items Property (item) Does --- --- flex: 1 Shorthand for grow 1, shrink 1, basis 0 — share space equally flex: 0 0 200px Fixed 200px, no grow/shrink align-self / order Override alignment / visual order Classic: perfectly centre anything — display:flex; justify-content:center; align-items:center; (or Grid place-items:center )."},{"kind":"lesson","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"css-grid-two-dimensional-layout","title":"CSS Grid — two-dimensional layout","body":"css .page { display: grid; grid-template-columns: 240px 1fr; grid-template-rows: auto 1fr auto; grid-template-areas: \"header header\" \"sidebar main\" \"footer footer\"; min-height: 100dvh; } header { grid-area: header; } aside { grid-area: sidebar; } main { grid-area: main; } footer { grid-area: footer; } / Responsive card grid with no media queries / .cards { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); } Flexbox vs Grid: Flexbox lays out along one axis and sizes from the content (toolbars, nav bars, button groups). Grid controls rows and columns together from the container (page layouts, card grids, forms). They combine well: Grid for the page, Flexbox inside components."},{"kind":"lesson","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"responsive-design-mobile-first-media-and-container-queries","title":"Responsive design — mobile first, media and container queries","body":"1. <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" — without it phones render a zoomed-out desktop page. 2. Mobile first: base styles for small screens, then min-width media queries add layout for larger ones. 3. Fluid layouts: % , fr , minmax() , clamp() , max-width instead of fixed widths. 4. Responsive images: max-width: 100%; height: auto; , srcset / sizes , <picture , loading=\"lazy\" . css .layout { display: grid; gap: 16px; } / phone: one column / @media (min-width: 768px) { .layout { grid-template-columns: 1fr 1fr; } } / tablet / @media (min-width: 1200px) { .layout { grid-template-columns: 250px 1fr 300px; } } / desktop / h1 { font-size: clamp(1.5rem, 1rem + 2vw, 2.5rem); } / fluid type, no breakpoints / / Container query: a card adapts to the space it is placed in, not the viewport / .card-wrap { container-type: inline-size; } @container (min-width: 400px) { .card { display: flex; gap: 12px; } } @media (prefers-color-scheme: dark) { :root { --bg: 111; --text: eee; } } @media (prefers-reduced-motion: reduce) { { animation: none !important; transition: none !important; } } Common breakpoints (Bootstrap 5): 576, 768, 992, 1200, 1400 px — but choose breakpoints where your content breaks."},{"kind":"lesson","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"variables-transitions-animations-and-modern-selectors","title":"Variables, transitions, animations and modern selectors","body":"css :root { --brand: 3b5bdb; --radius: 12px; --space: 16px; } .btn { background: var(--brand); border-radius: var(--radius); padding: calc(var(--space) / 2) var(--space); transition: transform .15s ease, box-shadow .15s ease; } .btn:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgb(0 0 0 / 15%); } @keyframes spin { to { transform: rotate(360deg); } } .loader { animation: spin 1s linear infinite; } / Native nesting and :has() / .card { padding: var(--space); & h3 { margin: 0; } &:has(img) { padding-top: 0; } } Custom properties vs Sass variables: CSS variables are live at runtime (change them with JS or media queries, they inherit and cascade — ideal for theming/dark mode); Sass variables are replaced at compile time. Hiding things: display: none (removed from layout and accessibility tree), visibility: hidden (keeps space), opacity: 0 (keeps space, still clickable), visually-hidden class (hidden visually, still read by screen readers)."},{"kind":"lesson","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"bootstrap-tailwind-and-css-architecture","title":"Bootstrap, Tailwind and CSS architecture","body":"Approach Example Pros Cons --- --- --- --- Component framework Bootstrap 5 Fast, consistent grid and components Sites look alike, heavier CSS Utility-first Tailwind CSS No naming, small production CSS, design tokens Long class lists in markup Methodology BEM ( .card title--active ) Predictable, low specificity Verbose names Scoped CSS CSS Modules, Angular view encapsulation, Vue scoped No global leaks Tooling-specific html <!-- Bootstrap grid -- <div class=\"container\" <div class=\"row\" <div class=\"col-12 col-md-6 col-lg-4\" Card</div </div </div <!-- Tailwind -- <div class=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-3\" <div class=\"rounded-xl p-4 shadow\" Card</div </div"},{"kind":"lesson","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"performance-and-seo-for-html-css","title":"Performance and SEO for HTML/CSS","body":"- Critical CSS inline / small CSS bundles; remove unused CSS (Tailwind does this automatically). - <script defer or type=\"module\" ; avoid render-blocking third-party scripts. - Images: modern formats (WebP/AVIF), correct sizes, width / height attributes to prevent layout shift, loading=\"lazy\" below the fold. - Fonts: font-display: swap , preload the main font, limit weights. - Core Web Vitals: LCP (largest content paint ≤ 2.5 s), INP (interaction to next paint ≤ 200 ms), CLS (layout shift ≤ 0.1). - SEO basics: unique <title and meta description, one h1 , semantic structure, descriptive link text, alt text, canonical URLs, Open Graph tags for sharing."},{"kind":"question","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"788","title":"What is semantic HTML and why is it important?","body":"Using elements that describe meaning — header , nav , main , article , section , aside , footer , button , headings — instead of generic div / span . Benefits: accessibility (screen readers use landmarks and roles), SEO (search engines understand structure), built-in behaviour (buttons are focusable and keyboard-operable), and readable code."},{"kind":"question","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"789","title":"Explain the CSS box model. What does box-sizing: border-box do?","body":"Each element is content + padding + border + margin. With the default content-box , width sets only the content, so padding and border are added on top. With border-box , width includes content, padding and border, which makes sizing predictable — most projects set it globally."},{"kind":"question","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"790","title":"What is CSS specificity? Which rule wins?","body":"Specificity scores selectors as (ids, classes/attributes/pseudo-classes, elements); higher wins, inline styles beat selectors, !important beats normal declarations, and with equal specificity the later rule wins. Example: nav a (1,0,1) beats .menu a.active (0,2,1). Keep specificity low with classes to avoid override wars."},{"kind":"question","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"791","title":"Flexbox vs Grid — when do you use each?","body":"Flexbox is one-dimensional (a row or a column), content-driven — nav bars, toolbars, centring, distributing items. Grid is two-dimensional (rows and columns together), container-driven — page layouts, card galleries, forms. Often Grid for the overall layout and Flexbox inside components."},{"kind":"question","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"792","title":"How do you centre a div horizontally and vertically?","body":"Flexbox: parent display:flex; justify-content:center; align-items:center; . Grid: parent display:grid; place-items:center; . Horizontal only for a block with a width: margin: 0 auto . Absolute: position:absolute; inset:0; margin:auto; with a set size, or top:50%; left:50%; transform:translate(-50%,-50%) ."},{"kind":"question","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"793","title":"Difference between display: none, visibility: hidden and opacity: 0?","body":"display:none removes the element from layout and the accessibility tree. visibility:hidden hides it but keeps its space and it can't be clicked. opacity:0 makes it transparent but it keeps its space and still receives clicks and focus."},{"kind":"question","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"794","title":"What are the different position values?","body":"static (default flow), relative (offset from its normal place, anchor for absolute children), absolute (out of flow, relative to nearest positioned ancestor), fixed (relative to the viewport), sticky (behaves relative until a scroll offset, then fixed within its container)."},{"kind":"question","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"795","title":"How do you make a website responsive?","body":"Viewport meta tag, mobile-first CSS with min-width media queries, fluid layouts (Flexbox/Grid, % , fr , minmax , clamp ), responsive images ( max-width:100% , srcset , <picture ), relative units ( rem ), container queries for reusable components, testing on real devices and DevTools device mode, and avoiding fixed widths and horizontal scroll."},{"kind":"question","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"796","title":"What are media queries and container queries?","body":"Media queries apply styles based on the viewport/device ( @media (min-width: 768px) , prefers-color-scheme , prefers-reduced-motion , print). Container queries apply styles based on the size of a parent container ( container-type: inline-size; @container (min-width: 400px) ), so a component adapts wherever it is placed — e.g. a card in a narrow sidebar vs a wide main area."},{"kind":"question","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"797","title":"How do you make a web page accessible?","body":"Semantic HTML, labels for inputs, alt text, real buttons/links, keyboard navigation with visible focus, colour contrast ≥ 4.5:1, logical heading order, lang attribute, ARIA only where native HTML can't (live regions, expanded states), respect reduced motion, and test with Lighthouse/axe and a screen reader. Target WCAG 2.1/2.2 AA."},{"kind":"question","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"798","title":"What is the difference between em, rem, %, vw and px?","body":"px is fixed; em is relative to the element's/parent's font size (compounds when nested); rem is relative to the root font size (predictable, respects user font settings); % is relative to the parent dimension; vw / vh are 1% of the viewport width/height ( dvh accounts for mobile browser bars)."},{"kind":"question","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"799","title":"CSS variables vs Sass variables?","body":"CSS custom properties exist at runtime: they cascade and inherit, can be changed by media queries, classes or JavaScript — perfect for themes and dark mode. Sass variables are compile-time constants, replaced in the output CSS; useful for build-time logic (loops, mixins), but cannot change in the browser."},{"kind":"question","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"800","title":"What is the critical rendering path and how do you optimise it?","body":"HTML → DOM, CSS → CSSOM, combined into the render tree → layout → paint → composite. CSS blocks rendering and sync scripts block parsing. Optimise: small/critical CSS first, defer scripts, preload key fonts/images, compress and size images, avoid layout shifts by setting dimensions, animate transform / opacity ."},{"kind":"question","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"801","title":"What is a stacking context and why does z-index sometimes not work?","body":"A stacking context is an isolated layering group; z-index only compares elements within the same context. New contexts are created by positioned elements with z-index , opacity < 1 , transform , filter , isolation: isolate and others. A child with z-index: 9999 can't escape a parent context that is below another element — fix the parent's stacking, not the child's number."},{"kind":"question","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"802","title":"What are Core Web Vitals?","body":"Google's user-experience metrics: LCP (Largest Contentful Paint — loading, good ≤ 2.5 s), INP (Interaction to Next Paint — responsiveness, good ≤ 200 ms; replaced FID in 2024) and CLS (Cumulative Layout Shift — visual stability, good ≤ 0.1). Improve with optimised images and fonts, less JavaScript, and fixed dimensions for media and ads."},{"kind":"question","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"803","title":"The layout looks fine on desktop but has a horizontal scrollbar on mobile. How do you find and fix it?","body":"Use DevTools device mode and find the element wider than the viewport (temporarily { outline: 1px solid red } , or check elements whose right edge exceeds the width). Usual causes: fixed widths ( width: 500px ), long unbroken text/URLs ( overflow-wrap: anywhere ), images without max-width:100% , 100vw with a scrollbar, negative margins, tables and code blocks (wrap them in an overflow-x:auto container), and grid/flex children that can't shrink ( min-width: 0 on grid/flex items, minmax(0, 1fr) )."},{"kind":"question","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"804","title":"A designer wants a card grid that shows 1 column on phones, 2 on tablets and 4 on desktop. Write the CSS.","body":"css .cards { display: grid; gap: 16px; grid-template-columns: 1fr; } @media (min-width: 640px) { .cards { grid-template-columns: repeat(2, 1fr); } } @media (min-width: 1100px) { .cards { grid-template-columns: repeat(4, 1fr); } } Or without breakpoints: grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); — columns appear as space allows."},{"kind":"question","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"805","title":"Your page jumps around while loading (high CLS). What do you fix?","body":"Set width / height (or aspect-ratio ) on images, videos and iframes; reserve space for ads, banners and late-loading components (skeletons); use font-display: swap with similar fallback fonts or size-adjust ; don't insert content above existing content after load; animate with transform instead of changing layout properties."},{"kind":"cheat","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"1","title":"Semantic skeleton","body":"header nav · main article section · aside · footer · one h1 , headings in order · button for actions, a for navigation · labels for every input."},{"kind":"cheat","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"2","title":"Specificity","body":"inline id (1,0,0) class/attr/pseudo-class (0,1,0) element (0,0,1); equal → last wins; !important overrides; @layer order before specificity."},{"kind":"cheat","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"3","title":"Layout picks","body":"Need Use --- --- Row of items, centring Flexbox Page layout, card grid Grid Auto-responsive grid repeat(auto-fill, minmax(220px, 1fr)) Sticky header position: sticky; top: 0 Fluid font clamp(min, preferred, max)"},{"kind":"cheat","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"4","title":"Responsive checklist","body":"Viewport meta · mobile-first min-width queries · no fixed widths · max-width:100% images · min-width:0 on grid/flex children · overflow wrappers for tables/code · container queries for components · test 320 → 1920 px."},{"kind":"cheat","course_slug":"html-css","course_title":"HTML5 & CSS3 — Semantic Markup to Responsive Layouts","ref":"5","title":"Accessibility checklist","body":"Alt text · labels · keyboard + visible focus · contrast 4.5:1 · lang · landmarks · ARIA only when needed · prefers-reduced-motion ."},{"kind":"course","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"","title":"JavaScript (ES5 → ES2025) & TypeScript Basics","body":"Types, scope, hoisting, closures, this, prototypes, classes, the event loop, promises and async/await, modules, DOM and events, fetch, ES6+ features, error handling, performance, security and TypeScript essentials. JavaScript is the programming language of the web: it runs in every browser and, through Node.js , on servers, CLIs and build tools. It is dynamically typed, single-threaded with an event loop , prototype-based, and supports functional and object-oriented styles. The language standard is ECMAScript (ECMA-262), maintained by TC39 . Browsers implement it in engines: V8 (Chrome, Edge, Node.js), SpiderMonkey (Firefox), JavaScriptCore (Safari). TypeScript (Microsoft, 2012) is a typed superset of JavaScript that compiles to JS — the default for Angular and widely used with React, Vue and Node. Every frontend framework interview (jQuery, Angular, React, Vue) starts with JavaScript fundamentals: closures, this , the event loop, promises, var / let / const , prototypes and array methods. Version Year Key features --- --- --- ES1 1997 First standard (language created by Brendan Eich at Netscape in 10 days, 1995) ES3 1999 Regex, try/catch ES5 2009 \"use strict\" , JSON, Array.prototype.forEach/map/filter/reduce , getters/setters, Object.create ES6 / ES2015 2015 let / const , arrow functions, classes, modules, promises, template literals, destructuring, default/rest/spread, Map / Set , symbols, iterators, generators ES2016 2016 Array.prototype.includes , ES2017 2017 async/await , Object.entries/values , string padding ES2018 2018 Object rest/spread, async iteration, Promise.finally , regex named groups ES2019 2019 Array.flat/flatMap , Object.fromEntries , optional catch binding ES2020 2020 Optional chaining ?. , nullish coalescing ?? , BigInt , Promise.allSettled , dynamic import() , globalThis ES2021 2021 String.replaceAll , Promise.any , logical assignment ??= = &&= , numeric separators 1 000 ES2022 2022 Class fields and private , top-level await , .at() , Object.hasOwn , error cause ES2023 2023 toSorted/toReversed/toSpliced/with (non-mutating), findLast ES2024 2024 Object.groupBy / Map.groupBy , Promise.withResolvers , resizable ArrayBuffer ES2025 2025 Iterator helpers ( .map/.filter/.take on iterators), Set methods ( union , intersection , difference ...), Promise.try , JSON modules / import attributes, RegExp.escape TypeScript: 1.0 (2014), 2.0 (2016, strict null checks), 3.x, 4.x (2020–2023), 5.0 (2023, decorators standard), then regular 5.x releases. TypeScript 7 is a native port of the compiler to Go (codename \"Project Corsa\", previewed since 2025) that makes builds roughly 10× faster. How a browser runs JavaScript (page lifecycle): 1. HTML parsed → DOM built; CSS → CSSOM; <script without defer / async blocks parsing while it downloads and runs. 2. defer scripts run in order after parsing; async scripts run as soon as downloaded (any order); type=\"module\" is deferred by default. 3. DOMContentLoaded — DOM ready (deferred scripts done). 4. load — all images, styles, iframes loaded. 5. User interaction → events → event loop runs handlers. 6. visibilitychange / pagehide → beforeunload → unload (avoid unload; use pagehide/visibilitychange). Execution lifecycle of code: the engine parses source → creates the global execution context (creation phase: memory for variables/functions = hoisting ; execution phase: runs line by line) → each function call pushes a new execution context on the call stack → returns pop it. Async callbacks wait in task queues until the stack is empty (the event loop ). Event loop order: run the current script (macrotask) → drain all microtasks (promise callbacks, queueMicrotask , MutationObserver ) → render (requestAnimationFrame, style, layout, paint) → next macrotask ( setTimeout , setInterval , I/O, UI events, MessageChannel ). Tool Use --- --- Browser DevTools (Chrome/Edge/Firefox) Console, debugger, network, performance, memory VS Code Editor with built-in JS/TS IntelliSense Node.js + npm / pnpm / yarn / Bun Runtime and package managers Vite , webpack, esbuild, Rollup, Turbopack Bundlers/dev servers TypeScript ( tsc ) Type checking ESLint, Prettier, Biome Linting and formatting Vitest, Jest, Mocha Unit testing Playwright, Cypress End-to-end testing Babel Transpile modern JS for old browsers Lighthouse, WebPageTest Performance audits caniuse.com, MDN Compatibility and reference"},{"kind":"lesson","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"data-types-typeof-and-equality","title":"Data types, typeof and equality","body":"Primitive types (immutable, compared by value): string , number , bigint , boolean , undefined , symbol , null . Everything else is an object (objects, arrays, functions, dates, maps), compared by reference. js typeof \"hi\" // \"string\" typeof 42 // \"number\" typeof 10n // \"bigint\" typeof undefined // \"undefined\" typeof null // \"object\" ← historical bug typeof [] // \"object\" → use Array.isArray([]) typeof function(){} // \"function\" 0.1 + 0.2 === 0.3 // false (floating point) → compare with Number.EPSILON or use integers (paise) NaN === NaN // false → Number.isNaN(x) // == converts types (coercion); === compares type and value \"5\" == 5 // true \"5\" === 5 // false null == undefined // true null === undefined // false [] == false // true (weird coercion) → always use === Falsy values: false , 0 , -0 , 0n , \"\" , null , undefined , NaN . Everything else is truthy (including \"0\" , [] , {} )."},{"kind":"lesson","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"var-let-and-const-scope-and-hoisting","title":"var, let and const; scope and hoisting","body":"var let const --- --- --- --- Scope Function Block {} Block Hoisted Yes, initialised to undefined Yes, but in the Temporal Dead Zone until declared Same as let Re-declare Allowed Not allowed Not allowed Re-assign Yes Yes No (but object contents can change) Global object property Yes ( window.x ) No No js console.log(a); // undefined (hoisted var) var a = 1; console.log(b); // ReferenceError: Cannot access 'b' before initialization (TDZ) let b = 2; const user = { name: \"Asha\" }; user.name = \"Ravi\"; // allowed — the binding is constant, not the object // user = {}; // TypeError Object.freeze(user); // shallow immutability sayHi(); // works — function declarations are fully hoisted function sayHi() { console.log(\"hi\"); } // sayBye(); // TypeError — function expressions follow variable rules var sayBye = function () {}; Scopes: global, function, block, module. Lexical scoping : a function's scope is determined by where it is written, not where it is called."},{"kind":"lesson","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"functions-declarations-expressions-arrows-default-rest-spread","title":"Functions: declarations, expressions, arrows, default/rest/spread","body":"js function add(a, b = 0) { return a + b; } // declaration + default parameter const mul = function (a, b) { return a b; }; // expression const square = x = x x; // arrow function const sum = (...nums) = nums.reduce((t, n) = t + n, 0); // rest parameters Math.max(...[3, 9, 2]); // spread into arguments const copy = [...arr, 4]; // spread array const merged = { ...defaults, ...options }; // spread object (later wins) // IIFE — immediately invoked function expression (old module pattern) (function () { const secret = 1; })(); Arrow functions: no own this , arguments , super or prototype ; can't be used with new ; implicit return for single expressions. Great for callbacks; avoid as object methods that need this . Higher-order functions take or return functions ( map , filter , setTimeout , debounce). Pure functions return the same output for the same input with no side effects."},{"kind":"lesson","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"arrays-and-objects-the-essential-methods","title":"Arrays and objects — the essential methods","body":"js const orders = [ { id: 1, customer: \"Asha\", total: 1200, status: \"paid\" }, { id: 2, customer: \"Ravi\", total: 300, status: \"pending\" }, { id: 3, customer: \"Asha\", total: 450, status: \"paid\" }, ]; orders.map(o = o.total); // [1200, 300, 450] orders.filter(o = o.status === \"paid\"); // 2 items orders.reduce((sum, o) = sum + o.total, 0); // 1950 orders.find(o = o.id === 2); // object or undefined orders.findIndex(o = o.id === 2); // 1 orders.some(o = o.total 1000); // true orders.every(o = o.total 100); // true orders.forEach(o = console.log(o.id)); // returns undefined [3, 1, 2].sort((a, b) = a - b); // MUTATES; default sort is by string! [3, 1, 2].toSorted((a, b) = a - b); // non-mutating (ES2023) [[1, 2], [3]].flat(); // [1, 2, 3] Object.groupBy(orders, o = o.customer); // { Asha: [...], Ravi: [...] } (ES2024) orders.at(-1); // last item // Mutating: push, pop, shift, unshift, splice, sort, reverse, fill // Non-mutating: map, filter, slice, concat, toSorted, toReversed, toSpliced, with // Objects const { customer, total = 0, ...rest } = orders[0]; // destructuring with default + rest Object.keys(obj); Object.values(obj); Object.entries(obj); Object.fromEntries([[\"a\", 1]]); structuredClone(obj); // deep copy (no functions) user?.address?.city ?? \"Unknown\"; // optional chaining + nullish coalescing ?? falls back only on null / undefined ; falls back on any falsy value ( 0 10 → 10, 0 ?? 10 → 0)."},{"kind":"lesson","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"closures","title":"Closures","body":"A closure is a function bundled with references to the variables of the scope in which it was created; it keeps them alive after that scope has returned. js function createCounter() { let count = 0; // private state return { increment: () = ++count, getCount: () = count, }; } const counter = createCounter(); counter.increment(); counter.increment(); counter.getCount(); // 2 — count is not accessible directly // Function factory const multiplier = factor = n = n factor; const double = multiplier(2); double(5); // 10 // Classic loop problem for (var i = 0; i < 3; i++) setTimeout(() = console.log(i)); // 3 3 3 — one shared 'i' for (let j = 0; j < 3; j++) setTimeout(() = console.log(j)); // 0 1 2 — new 'j' per iteration Uses: data privacy/encapsulation, function factories, memoisation, debounce/throttle, event handlers, module pattern, partial application/currying. Risk: unintentionally retaining large objects (memory leaks)."},{"kind":"lesson","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"the-this-keyword-call-apply-and-bind","title":"The `this` keyword, call, apply and bind","body":"this is decided by how a function is called (except arrow functions, which take this from their enclosing scope). Call style this --- --- obj.method() obj Plain call fn() undefined in strict mode / modules; global object in sloppy mode new Fn() The new object fn.call(ctx, a, b) / fn.apply(ctx, [a, b]) ctx fn.bind(ctx) Returns a new function permanently bound to ctx Arrow function Lexical this (from where it's defined) DOM event handler ( function ) The element ( event.currentTarget ) js const user = { name: \"Divakar\", greet() { return Hi ${this.name} ; }, greetLater() { setTimeout(() = console.log(this.name), 100); }, // arrow keeps 'this' }; const greet = user.greet; greet(); // \"Hi undefined\" (lost 'this') in non-strict; TypeError in strict greet.call({ name: \"Asha\" }); // \"Hi Asha\" const bound = user.greet.bind(user); bound(); // \"Hi Divakar\""},{"kind":"lesson","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"prototypes-inheritance-and-classes","title":"Prototypes, inheritance and classes","body":"Every object has an internal link [[Prototype]] (accessible via Object.getPrototypeOf(obj) or proto ). Property lookup walks the prototype chain until found or null . js function Person(name) { this.name = name; } Person.prototype.hello = function () { return I am ${this.name} ; }; const p = new Person(\"Asha\"); p.hello(); // found on Person.prototype // ES6 classes — syntax over prototypes class Animal { sound; // private field (ES2022) static count = 0; constructor(name, sound) { this.name = name; this. sound = sound; Animal.count++; } speak() { return ${this.name} says ${this. sound} ; } get label() { return this.name.toUpperCase(); } } class Dog extends Animal { constructor(name) { super(name, \"woof\"); } speak() { return super.speak() + \"!\"; } } new Dog(\"Rex\").speak(); // \"Rex says woof!\" What new does: creates an empty object, sets its prototype to Constructor.prototype , calls the constructor with this = the object, returns the object (unless the constructor returns another object)."},{"kind":"lesson","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"the-event-loop-microtasks-and-macrotasks","title":"The event loop, microtasks and macrotasks","body":"js console.log(\"1: script start\"); setTimeout(() = console.log(\"6: timeout\"), 0); Promise.resolve() .then(() = console.log(\"3: promise 1\")) .then(() = console.log(\"5: promise 2\")); queueMicrotask(() = console.log(\"4: microtask\")); console.log(\"2: script end\"); // Order: 1, 2, 3, 4, 5, 6 - JavaScript runs on one main thread with a call stack . - Web APIs (timers, fetch, DOM events) run outside JS and enqueue callbacks. - After the current task finishes, the engine drains the microtask queue completely, then may render, then takes the next macrotask . - Long synchronous work blocks rendering and input → use async chunks, requestIdleCallback , or Web Workers for CPU-heavy work. - Node.js has a similar loop with phases (timers, poll, check) and process.nextTick (runs before promise microtasks)."},{"kind":"lesson","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"promises-and-async-await","title":"Promises and async/await","body":"js // Promise states: pending → fulfilled rejected (settled once) function delay(ms) { return new Promise(resolve = setTimeout(resolve, ms)); } fetch(\"/api/orders/1\") .then(r = { if (!r.ok) throw new Error( HTTP ${r.status} ); return r.json(); }) .then(order = console.log(order)) .catch(err = console.error(err)) .finally(() = hideSpinner()); async function loadDashboard(userId) { try { const [user, orders] = await Promise.all([ // run in parallel fetch( /api/users/${userId} ).then(r = r.json()), fetch( /api/orders?user=${userId} ).then(r = r.json()), ]); return { user, orders }; } catch (err) { console.error(\"Dashboard failed\", err); throw err; } } // Timeout / cancellation with AbortController const controller = new AbortController(); setTimeout(() = controller.abort(), 5000); const res = await fetch(\"/api/report\", { signal: controller.signal }); // or AbortSignal.timeout(5000) Combinator Resolves when Rejects when --- --- --- Promise.all All fulfil (array of values) First rejection Promise.allSettled All settle (status objects) Never Promise.race First to settle (value) First to settle is a rejection Promise.any First to fulfil All reject ( AggregateError ) async functions always return a promise; await pauses the function (not the thread) until the promise settles. Sequential await s in a loop run one by one — use Promise.all for independent work."},{"kind":"lesson","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"modules-esm-vs-commonjs","title":"Modules (ESM vs CommonJS)","body":"js // math.js (ES module) export const PI = 3.14159; export function area(r) { return PI r r; } export default class Calculator {} // app.js import Calculator, { area, PI as pi } from \"./math.js\"; const { heavy } = await import(\"./heavy.js\"); // dynamic import → code splitting // CommonJS (Node legacy) const fs = require(\"fs\"); module.exports = { area }; ES modules: static structure (enables tree-shaking), strict mode by default, deferred in browsers ( <script type=\"module\" ), top-level await , live bindings. CommonJS: synchronous require , used by older Node packages."},{"kind":"lesson","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"dom-manipulation-and-events","title":"DOM manipulation and events","body":"js const list = document.querySelector(\" orders\"); const items = document.querySelectorAll(\".order\"); // static NodeList const li = document.createElement(\"li\"); li.textContent = \"Order 42\"; // safe — no HTML parsing (prevents XSS) li.classList.add(\"order\", \"new\"); li.dataset.id = \"42\"; // data-id=\"42\" list.append(li); // Event handling button.addEventListener(\"click\", e = { e.preventDefault(); // stop default action (form submit, link navigation) e.stopPropagation(); // stop bubbling }, { once: true }); // Event delegation — one listener for many (and future) children list.addEventListener(\"click\", e = { const item = e.target.closest(\".order\"); if (item) openOrder(item.dataset.id); }); Event propagation phases: capture (window → target) → target → bubble (target → window). Listeners run in the bubble phase by default ( { capture: true } for capture). e.target = element clicked; e.currentTarget = element the listener is on. Performance: batch DOM writes (DocumentFragment, append(...nodes) ), avoid layout thrashing (reading offsetHeight after writes in a loop), use requestAnimationFrame for visual updates."},{"kind":"lesson","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"storage-fetch-cors-and-browser-apis","title":"Storage, fetch, CORS and browser APIs","body":"Storage Capacity Lifetime Sent to server --- --- --- --- Cookies ~4 KB Expiry date Yes , with every request localStorage ~5–10 MB Until cleared No sessionStorage ~5 MB Tab session No IndexedDB Large (quota-based) Until cleared No — async, structured data Cache API Large Until cleared No — service workers/PWA Never store auth tokens in localStorage if you can avoid it (readable by any XSS); prefer HttpOnly; Secure; SameSite cookies or a BFF. Other APIs: fetch , AbortController , IntersectionObserver (lazy load, infinite scroll), ResizeObserver , MutationObserver , Web Workers, Service Workers (offline/PWA), WebSockets, history.pushState (SPA routing), Clipboard, Geolocation, Notifications. CORS — the browser blocks reading cross-origin responses unless the server sends Access-Control-Allow-Origin ; preflight OPTIONS for non-simple requests. It's fixed on the server , not in JS."},{"kind":"lesson","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"debounce-throttle-memoisation-and-other-utilities","title":"Debounce, throttle, memoisation and other utilities","body":"js function debounce(fn, ms) { // run after the user STOPS for ms (search box) let timer; return function (...args) { clearTimeout(timer); timer = setTimeout(() = fn.apply(this, args), ms); }; } function throttle(fn, ms) { // run at most once per ms (scroll, resize) let last = 0; return function (...args) { const now = Date.now(); if (now - last = ms) { last = now; fn.apply(this, args); } }; } function memoize(fn) { const cache = new Map(); return arg = cache.has(arg) ? cache.get(arg) : (cache.set(arg, fn(arg)), cache.get(arg)); } const curry = fn = function curried(...args) { return args.length = fn.length ? fn(...args) : (...more) = curried(...args, ...more); };"},{"kind":"lesson","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"generators-iterators-map-set-weakmap-and-proxy","title":"Generators, iterators, Map/Set, WeakMap and Proxy","body":"js function idGenerator() { let id = 1; while (true) yield id++; } const ids = idGenerator(); ids.next().value; // 1 const map = new Map([[\"a\", 1]]); // any key type, keeps insertion order, .size const set = new Set([1, 2, 2, 3]); // unique values → [...set] = [1, 2, 3] new Set([1, 2]).union(new Set([2, 3])); // ES2025 Set methods const meta = new WeakMap(); // keys must be objects; doesn't prevent garbage collection meta.set(domNode, { clicks: 0 }); const validator = new Proxy({}, { set(target, key, value) { if (key === \"age\" && typeof value !== \"number\") throw new TypeError(\"age must be a number\"); target[key] = value; return true; }, });"},{"kind":"lesson","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"memory-leaks-performance-and-security","title":"Memory leaks, performance and security","body":"- Memory leaks : forgotten timers/intervals, event listeners on removed elements, global variables, closures holding large data, detached DOM nodes, growing caches. Find with DevTools Memory → heap snapshots. - Performance : code splitting and lazy loading, tree shaking, minification, compression, caching (HTTP + service worker), avoid long tasks ( 50 ms), virtualise long lists, debounce input, use defer , optimise images, measure Core Web Vitals ( LCP , INP , CLS ). - Security : XSS (never insert untrusted HTML — use textContent , sanitise with DOMPurify, Content-Security-Policy), CSRF (SameSite cookies, tokens), avoid eval / new Function , validate on the server, keep dependencies patched ( npm audit ), Subresource Integrity for CDN scripts."},{"kind":"lesson","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"typescript-essentials","title":"TypeScript essentials","body":"ts type Status = \"pending\" \"paid\" \"shipped\"; // union of literal types interface Order { id: number; customer: string; total: number; status: Status; notes?: string } function totalPaid(orders: Order[]): number { return orders.filter(o = o.status === \"paid\").reduce((s, o) = s + o.total, 0); } // Generics function first<T (items: T[]): T undefined { return items[0]; } // Utility types type OrderPreview = Pick<Order, \"id\" \"total\" ; type OrderUpdate = Partial<Omit<Order, \"id\" ; type ReadonlyOrder = Readonly<Order ; type ById = Record<number, Order ; // Narrowing function format(x: string number) { return typeof x === \"string\" ? x.toUpperCase() : x.toFixed(2); } // unknown vs any: unknown must be narrowed before use; any disables checking function parse(json: string): unknown { return JSON.parse(json); } interface vs type : both describe object shapes; interfaces can be re-opened (declaration merging) and extended; types support unions, intersections, mapped and conditional types. Enable \"strict\": true in tsconfig.json . TypeScript types disappear at runtime — validate external data with libraries like Zod."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"806","title":"What is the difference between `==` and `===`?","body":"=== (strict equality) compares type and value without conversion. == (loose equality) converts operands to a common type first, which produces surprises ( \"\" == 0 is true, null == undefined is true, [] == false is true). Always use === (except, by some style guides, x == null to check null or undefined)."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"807","title":"What is the difference between `var`, `let` and `const`?","body":"var is function-scoped, hoisted and initialised as undefined , can be re-declared, and creates a property on the global object at top level. let and const are block-scoped and hoisted but in the Temporal Dead Zone until their declaration (accessing them earlier throws). Neither can be re-declared in the same scope. const can't be reassigned, but the object it references can still be mutated. Default to const , use let when reassigning, avoid var ."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"808","title":"What is hoisting?","body":"During the creation phase of an execution context, declarations are registered before code runs. var variables are hoisted and initialised to undefined . Function declarations are hoisted with their body (callable before the line they appear on). let , const and class are hoisted but uninitialised (TDZ → ReferenceError if used early). Function expressions and arrow functions follow the rules of the variable they're assigned to."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"809","title":"What are the primitive data types in JavaScript?","body":"string , number , bigint , boolean , undefined , null and symbol . They are immutable and compared by value. Everything else (objects, arrays, functions, dates) is an object compared by reference. typeof null returns \"object\" due to a historical bug."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"810","title":"What is the difference between `null` and `undefined`?","body":"undefined means a variable has been declared but not assigned, a missing property, or a function with no return value — set by the engine. null is an intentional \"no value\" assigned by the programmer. typeof undefined is \"undefined\", typeof null is \"object\"; null == undefined is true but null === undefined is false. ?? and ?. treat both as nullish."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"811","title":"What are arrow functions and how are they different from regular functions?","body":"A concise function syntax ( x = x 2 ). Differences: no own this (lexically inherited — great for callbacks), no arguments object, can't be used as constructors with new , no prototype , and implicit return for single expressions. Don't use them as object methods or prototype methods that need dynamic this ."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"812","title":"What is a closure? Give a practical example.","body":"A closure is a function that remembers the variables from the scope where it was created, even after that scope has finished executing. Example: function counter() { let c = 0; return () = ++c; } — each returned function has its own private c . Practical uses: data privacy, function factories, memoisation caches, debounce/throttle timers, partial application, event handlers capturing loop values (with let )."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"813","title":"Explain the event loop.","body":"JavaScript executes on a single thread with a call stack. Asynchronous operations (timers, network, events) are handled by the browser/Node APIs, which queue callbacks when done. When the call stack is empty, the event loop first runs all microtasks (promise reactions, queueMicrotask ), then (in browsers) lets rendering happen, then picks the next macrotask (setTimeout, I/O, UI events). That's why a resolved promise's .then runs before a setTimeout(..., 0) callback."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"814","title":"What is a Promise? Explain Promise.all, allSettled, race and any.","body":"A Promise represents the eventual result of an asynchronous operation, in state pending, fulfilled or rejected; .then/.catch/.finally register reactions. Promise.all waits for all and rejects on the first failure. allSettled waits for all and returns each outcome. race settles with the first settled promise (success or failure). any fulfils with the first success and rejects with AggregateError only if all fail."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"815","title":"How does `this` work in JavaScript?","body":"It depends on the call site: method call → the object before the dot; plain function call → undefined in strict mode (global object otherwise); constructor with new → the new instance; call/apply/bind → explicitly set; event listeners with regular functions → the element; arrow functions → this of the enclosing lexical scope. Losing this when passing methods as callbacks is fixed with bind or arrow functions."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"816","title":"What is the difference between `call`, `apply` and `bind`?","body":"All set this explicitly. call(thisArg, a, b) invokes immediately with individual arguments. apply(thisArg, [a, b]) invokes immediately with an array of arguments. bind(thisArg, a) doesn't invoke — it returns a new function with this (and optionally leading arguments) permanently bound, useful for callbacks and event handlers."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"817","title":"What is prototypal inheritance?","body":"Objects inherit directly from other objects through the internal [[Prototype]] link. When a property isn't found on an object, the engine looks up its prototype chain. Constructor functions share methods via Constructor.prototype ; Object.create(proto) creates objects with a chosen prototype; ES6 class / extends is syntax over the same mechanism ( Dog.prototype. proto === Animal.prototype )."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"818","title":"What is event delegation and why use it?","body":"Attaching a single event listener to a common ancestor instead of each child, using event bubbling and event.target (often with closest() ) to identify which child was interacted with. Benefits: fewer listeners (memory/performance), works for elements added later dynamically, simpler cleanup. Note: some events don't bubble ( focus , blur — use focusin / focusout )."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"819","title":"Debounce vs throttle — implement one.","body":"Debounce delays execution until calls stop for a given time (search-as-you-type, auto-save, resize end). Throttle guarantees execution at most once per interval (scroll position, mousemove, rate-limited API calls). js const debounce = (fn, ms) = { let t; return (...a) = { clearTimeout(t); t = setTimeout(() = fn(...a), ms); }; }; const throttle = (fn, ms) = { let last = 0; return (...a) = { const now = Date.now(); if (now - last = ms) { last = now; fn(...a); } }; };"},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"820","title":"What is the difference between shallow copy and deep copy?","body":"A shallow copy duplicates top-level properties, but nested objects are still shared references ( {...obj} , Object.assign , arr.slice() , [...arr] ). A deep copy duplicates everything recursively: structuredClone(obj) (modern, handles Dates/Maps/cycles, not functions/DOM nodes), or JSON.parse(JSON.stringify(obj)) (loses Dates, undefined, functions, Infinity), or lodash cloneDeep ."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"821","title":"What is the difference between `map`, `forEach`, `filter` and `reduce`?","body":"forEach iterates for side effects and returns undefined . map returns a new array of the same length with transformed items. filter returns a new array with items that pass a test. reduce accumulates the array into a single value (sum, object, grouped map). None of them mutate the original array (unless your callback does). forEach can't be stopped early — use for...of with break , or some / find ."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"822","title":"What are `async` and `defer` on script tags?","body":"Both download the script without blocking HTML parsing. async executes as soon as it's downloaded — order not guaranteed, may run before the DOM is complete (good for independent scripts like analytics). defer executes after parsing finishes, in document order, before DOMContentLoaded (good for app scripts). Module scripts are deferred by default."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"823","title":"What causes memory leaks in JavaScript and how do you find them?","body":"Unremoved event listeners and timers ( setInterval never cleared), references to detached DOM nodes, accidental globals, closures capturing large objects, ever-growing caches/maps, and subscriptions not unsubscribed in SPA components. Find them with Chrome DevTools: Performance monitor (JS heap growing), Memory tab heap snapshots compared over time, \"Detached elements\" panel, and allocation timelines. Fix with cleanup on unmount, WeakMap / WeakRef for metadata, and bounded caches."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"824","title":"What is the output of this code and why? `for (var i=0;i<3;i++){ setTimeout(()=>console.log(i),0) }`","body":"It prints 3 3 3 . var is function-scoped, so all three callbacks close over the same i , and by the time the timers run (after the loop completes), i is 3. Fixes: use let (a new binding per iteration → 0 1 2 ), or an IIFE/ bind to capture the current value."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"825","title":"What is the difference between `interface` and `type` in TypeScript?","body":"Both can describe object shapes and can be extended (interfaces via extends , types via intersections & ). Interfaces support declaration merging (re-opening to add members, used to augment library types) and give clearer error messages for object shapes. Type aliases can represent anything: unions, tuples, primitives, mapped and conditional types. Common guidance: interfaces for public object contracts, types for unions and type-level programming."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"826","title":"A search box calls the API on every keystroke and floods the server. How do you fix it?","body":"Debounce the input (e.g. 300 ms) so the request fires only after typing pauses; ignore queries shorter than 2–3 characters; cancel the previous in-flight request with AbortController so stale responses don't overwrite newer results (or track the latest request id); cache recent results; show a loading state. On the server, add rate limiting and make the search endpoint efficient (indexes, paging)."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"827","title":"A page becomes unresponsive while processing a 50 MB JSON file in the browser. What do you do?","body":"The main thread is blocked by long synchronous work. Move parsing/processing into a Web Worker (postMessage the data or a File/Blob, return results); stream the file with ReadableStream / process in chunks; better, process it on the server and fetch paginated or aggregated results; virtualise large lists when rendering; show progress. Measure with the DevTools Performance panel (long tasks)."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"828","title":"Users report the app gets slower the longer it's open. How do you investigate?","body":"Suspect a memory leak. Reproduce the flow repeatedly while taking heap snapshots in DevTools and comparing them (look for growing arrays, detached DOM nodes, listeners). Check for intervals not cleared, event listeners/subscriptions not removed when views are destroyed, global caches growing unbounded, and large closures. Fix cleanup paths (component unmount/destroy hooks), use AbortController to remove listeners, bound caches, and verify the heap stabilises."},{"kind":"question","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"829","title":"You need to call 3 independent APIs and show the page when all are done, but still show partial data if one fails. How?","body":"Start all requests in parallel and use Promise.allSettled , then render the fulfilled results and show an error placeholder for rejected ones. Add timeouts with AbortSignal.timeout(ms) so a slow API doesn't hang the page, and retry idempotent failures with backoff. If any single failure must fail the whole page, use Promise.all instead."},{"kind":"cheat","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"1","title":"Types & equality","body":"Primitives: string, number, bigint, boolean, undefined, null, symbol. Falsy: false, 0, -0, 0n, \"\", null, undefined, NaN. Use === . Array.isArray , Number.isNaN , typeof null === \"object\" ."},{"kind":"cheat","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"2","title":"Declarations","body":"const by default · let when reassigning · no var · TDZ for let/const · function declarations fully hoisted."},{"kind":"cheat","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"3","title":"this","body":"method → object · plain → undefined (strict) · new → instance · call/apply/bind → explicit · arrow → lexical."},{"kind":"cheat","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"4","title":"Event loop","body":"Sync code → all microtasks (promises, queueMicrotask) → render → next macrotask (setTimeout, events, I/O)."},{"kind":"cheat","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"5","title":"Promises","body":"all (fail fast) · allSettled (all outcomes) · race (first settled) · any (first success) · async/await + try/catch · AbortController ."},{"kind":"cheat","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"6","title":"Array methods","body":"map · filter · reduce · find · findIndex · some · every · includes · flat · flatMap · at · toSorted · Object.groupBy · sort((a,b)= a-b) (default sort is lexicographic!)."},{"kind":"cheat","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"7","title":"Modern syntax","body":"?. · ?? · ??= · destructuring · spread/rest · template literals · classes with private · modules · top-level await · structuredClone ."},{"kind":"cheat","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"8","title":"DOM","body":"querySelector(All) · textContent (safe) vs innerHTML (XSS risk) · addEventListener · delegation with closest · bubbling vs capturing · preventDefault / stopPropagation ."},{"kind":"cheat","course_slug":"javascript","course_title":"JavaScript (ES5 → ES2025) & TypeScript Basics","ref":"9","title":"Snippets","body":"js const debounce = (f, ms) = { let t; return (...a) = { clearTimeout(t); t = setTimeout(() = f(...a), ms); }; }; const unique = arr = [...new Set(arr)]; const sleep = ms = new Promise(r = setTimeout(r, ms)); const sum = arr = arr.reduce((s, x) = s + x, 0); const groupBy = (arr, key) = arr.reduce((acc, x) = ((acc[x[key]] ??= []).push(x), acc), {});"},{"kind":"course","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"","title":"TypeScript — Types, Generics and Real-World Patterns","body":"Why TypeScript, basic and object types, interfaces vs type aliases, unions and narrowing, functions, classes, generics, utility types, mapped and conditional types, modules, tsconfig and strict mode, typing API calls for Angular/React, and the TypeScript interview questions. TypeScript is JavaScript with a static type system, created by Microsoft (lead designer Anders Hejlsberg, also the designer of C ). TypeScript code is compiled (transpiled) to plain JavaScript ; types exist only at compile time and are erased at runtime. Why teams use it: - Catches errors before running (typos, wrong argument types, undefined access). - IntelliSense, safe refactoring and self-documenting APIs. - Required by Angular; the default for React (Vite, Next.js) and Vue 3 projects; familiar to C developers. C concept TypeScript equivalent --- --- class , interface , access modifiers Same keywords (interfaces are structural, not nominal) Generics List<T Generics Array<T , Promise<T enum enum or (preferred) union of string literals Nullable string? string \\ undefined , optional prop?: async/await + Task<T async/await + Promise<T LINQ Array methods map , filter , reduce Year Version Highlights --- --- --- 2012 0.8 First public release 2016 2.0 strictNullChecks , never , control-flow analysis 2018 3.0 unknown , tuples in rest parameters, project references 2020 4.0–4.1 Variadic tuples, template literal types, key remapping 2022 4.9 satisfies operator 2023 5.0 Standard (TC39) decorators, const type parameters, faster builds 2024 5.4–5.7 NoInfer , inferred type predicates, --erasableSyntaxOnly prep 2025 5.8–5.9 Node 18+ module modes, import defer ; TypeScript 7 native compiler (Go port, ~10× faster) in preview Node.js 22.6+/23+ can run .ts files directly by stripping types (no type checking) — type-check with tsc --noEmit . From .ts file to running code: 1. Write .ts / .tsx with types. 2. The type checker ( tsc or the editor's language service) reports errors using tsconfig.json settings. 3. Transpile to JavaScript ( tsc , esbuild, SWC, Babel, Vite, Angular CLI) — types are erased; syntax down-levelled to the target . 4. Bundle (Vite/Rollup/webpack/esbuild) with imports resolved per module / moduleResolution . 5. Run in the browser or Node.js. At runtime there are no types — validate external data (API responses, forms) with code or a schema library (Zod). - tsc compiler, tsconfig.json , ts-node / tsx to run TS in Node. - VS Code (built-in TS language service), TypeScript Playground (typescriptlang.org/play). - Bundlers: Vite, esbuild, SWC, Angular CLI, Next.js. - Lint: ESLint + typescript-eslint ; format: Prettier. - Runtime validation: Zod, Valibot; API types from OpenAPI: openapi-typescript, NSwag, Orval. - Testing: Vitest, Jest (ts-jest), Playwright."},{"kind":"lesson","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"basic-types-inference-and-type-annotations","title":"Basic types, inference and type annotations","body":"typescript let name: string = \"Divakar\"; let age = 34; // inferred as number — annotate only when inference can't help let active: boolean = true; let ids: number[] = [1, 2, 3]; // or Array<number let pair: [string, number] = [\"qty\", 5]; // tuple let anything: any = 4; // turns type checking OFF — avoid let input: unknown = JSON.parse(\"{}\"); // safe \"any\": must narrow before use function fail(msg: string): never { throw new Error(msg); } // never returns function log(msg: string): void { console.log(msg); } let maybe: string undefined; // with strictNullChecks, undefined must be explicit const status = \"open\" as const; // literal type \"open\", not string Type Meaning --- --- any Opt out of checking — errors spread silently unknown Anything, but you must check the type before using it never No value possible (functions that throw, exhaustive checks) void Function returns nothing useful null / undefined Separate types under strict Interview tip: \"Prefer unknown over any for data from outside (JSON, errors in catch ) — it forces you to validate.\""},{"kind":"lesson","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"object-types-interfaces-vs-type-aliases","title":"Object types — interfaces vs type aliases","body":"typescript interface Customer { readonly id: number; name: string; email?: string; // optional [key: string]: unknown; // index signature (extra props) } type OrderStatus = \"draft\" \"submitted\" \"shipped\"; // only a type alias can name a union type Order = { id: number; customer: Customer; status: OrderStatus; lines: OrderLine[]; }; interface Employee extends Customer { salary: number; } // extend an interface type Manager = Employee & { reports: Employee[] }; // intersect types interface type --- --- --- Object shapes ✅ ✅ Unions, tuples, primitives, mapped/conditional types ❌ ✅ Extend extends & intersection Declaration merging (same name declared twice merges) ✅ ❌ Common guidance: interface for public object contracts (and library augmentation), type for unions and computed types. Be consistent. Structural typing: TypeScript compares shapes , not names — any object with the right properties is assignable, unlike C 's nominal types."},{"kind":"lesson","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"functions-unions-and-narrowing","title":"Functions, unions and narrowing","body":"typescript function total(lines: { qty: number; price: number }[], discount = 0): number { return lines.reduce((s, l) = s + l.qty l.price, 0) (1 - discount); } const greet = (name: string, title?: string) = Hello ${title ?? \"\"} ${name} ; function format(value: string number Date): string { if (typeof value === \"string\") return value.trim(); // narrowed to string if (typeof value === \"number\") return value.toFixed(2); // narrowed to number return value.toISOString(); // must be Date } // Discriminated union + exhaustive check type Shape = { kind: \"circle\"; r: number } { kind: \"rect\"; w: number; h: number }; function area(s: Shape): number { switch (s.kind) { case \"circle\": return Math.PI s.r 2; case \"rect\": return s.w s.h; default: { const never: never = s; return never; } // compile error if a new kind is added } } // Custom type guard function isOrder(x: unknown): x is Order { return typeof x === \"object\" && x !== null && \"id\" in x && \"lines\" in x; } Narrowing tools: typeof , instanceof , in , equality checks, truthiness, discriminant property, type predicates ( x is T ), assertion functions ( asserts x is T )."},{"kind":"lesson","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"classes-access-modifiers-and-enums","title":"Classes, access modifiers and enums","body":"typescript abstract class Account { private static nextId = 1; readonly id = Account.nextId++; constructor(public owner: string, protected balance = 0) {} // parameter properties deposit(amount: number) { if (amount <= 0) throw new Error(\"Invalid\"); this.balance += amount; } abstract monthlyFee(): number; } class Savings extends Account implements Printable { monthlyFee() { return this.balance 10 000 ? 0 : 5; } print() { return ${this.owner}: ${this.balance} ; } } interface Printable { print(): string; } // enum vs union enum Role { Admin = \"ADMIN\", User = \"USER\" } // generates runtime JS object type RoleU = \"ADMIN\" \"USER\"; // zero runtime cost — usually preferred - private (TS-only, compile-time) vs field (JavaScript private, enforced at runtime). - readonly vs const : readonly for properties, const for variables. - implements checks a class matches an interface; it doesn't add code."},{"kind":"lesson","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"generics","title":"Generics","body":"typescript function first<T (items: T[]): T undefined { return items[0]; } const n = first([1, 2, 3]); // T inferred as number interface ApiResult<T { data: T; error?: string; } interface Paged<T { items: T[]; total: number; page: number; } // Constraint: T must have an id function byId<T extends { id: number } (items: T[], id: number): T undefined { return items.find(i = i.id === id); } // keyof constraint: safe property access function pluck<T, K extends keyof T (items: T[], key: K): T[K][] { return items.map(i = i[key]); } pluck(orders, \"status\"); // OrderStatus[] — \"statuz\" would be a compile error // Generic class class Cache<K, V { private map = new Map<K, V (); get(key: K) { return this.map.get(key); } set(key: K, value: V) { this.map.set(key, value); } } Generics let one function/type work with many types while keeping type information — unlike any , which loses it."},{"kind":"lesson","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"utility-types","title":"Utility types","body":"Utility Result Typical use --- --- --- Partial<T All properties optional PATCH/update models Required<T All required Normalised config Readonly<T All readonly Immutable state Pick<T, K Only keys K DTO with a few fields Omit<T, K Without keys K Create model without id Record<K, V Object with keys K of type V Lookup maps Exclude<U, X / Extract<U, X Filter a union Narrow status lists NonNullable<T Remove null/undefined After validation ReturnType<F / Parameters<F Function types Reuse inferred types Awaited<T Unwrap Promise Result of async function typescript type CreateOrder = Omit<Order, \"id\" \"status\" ; type OrderPatch = Partial<Pick<Order, \"status\" \"lines\" ; const labels: Record<OrderStatus, string = { draft: \"Draft\", submitted: \"Submitted\", shipped: \"Shipped\" }; type Loaded = Awaited<ReturnType<typeof loadOrders ;"},{"kind":"lesson","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"mapped-conditional-and-template-literal-types","title":"Mapped, conditional and template literal types","body":"typescript // Mapped type: make every property a getter function type Getters<T = { [K in keyof T as get${Capitalize<string & K } ]: () = T[K] }; type CustomerGetters = Getters<{ name: string; age: number } ; // { getName(): string; getAge(): number } // Conditional type with infer type ElementOf<T = T extends (infer U)[] ? U : never; type X = ElementOf<string[] ; // string // Template literal types type HttpMethod = \"GET\" \"POST\"; type Route = /api/${\"orders\" \"customers\"} ; type Endpoint = ${HttpMethod} ${Route} ; // \"GET /api/orders\" ... // satisfies: check against a type but keep the precise inferred type const config = { api: \"https://api.example.com\", retries: 3 } satisfies Record<string, string number ; config.retries.toFixed(); // still known to be number"},{"kind":"lesson","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"tsconfig-strict-mode-and-modules","title":"tsconfig, strict mode and modules","body":"json { \"compilerOptions\": { \"target\": \"ES2022\", \"module\": \"ESNext\", \"moduleResolution\": \"Bundler\", \"strict\": true, \"noUncheckedIndexedAccess\": true, \"noImplicitOverride\": true, \"esModuleInterop\": true, \"skipLibCheck\": true, \"jsx\": \"react-jsx\", \"baseUrl\": \".\", \"paths\": { \"@/ \": [\"src/ \"] } }, \"include\": [\"src\"] } strict: true turns on noImplicitAny , strictNullChecks , strictFunctionTypes , strictPropertyInitialization , useUnknownInCatchVariables and more — always enable it in new projects. Modules: ES modules ( import / export ); import type { Order } from \"./models\" imports types only (erased); declaration files ( .d.ts ) describe JavaScript libraries — types come from the package itself or @types/ (DefinitelyTyped)."},{"kind":"lesson","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"typing-real-api-calls-in-angular-and-react","title":"Typing real API calls in Angular and React","body":"typescript // models.ts — generated from the backend OpenAPI or written by hand export interface OrderDto { id: number; orderDate: string; status: OrderStatus; total: number; } // Angular service @Injectable({ providedIn: \"root\" }) export class OrdersApi { private http = inject(HttpClient); list(page: number) { return this.http.get<Paged<OrderDto (\"/api/orders\", { params: { page } }); } } // React with fetch + runtime validation (types alone don't check the server response) import { z } from \"zod\"; const OrderSchema = z.object({ id: z.number(), orderDate: z.string(), status: z.enum([\"draft\", \"submitted\", \"shipped\"]), total: z.number() }); type Order = z.infer<typeof OrderSchema ; async function getOrders(): Promise<Order[] { const res = await fetch(\"/api/orders\"); if (!res.ok) throw new Error( HTTP ${res.status} ); return z.array(OrderSchema).parse(await res.json()); // throws if the API shape changed } // Typed React props and state type Props = { orders: Order[]; onSelect: (id: number) = void }; function OrderTable({ orders, onSelect }: Props) { / … / } const [selected, setSelected] = useState<Order null (null); Interview tip: http.get<T () and as T are promises to the compiler, not checks . Mention generating types from OpenAPI and validating at the boundary."},{"kind":"question","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"830","title":"What is TypeScript and why use it over JavaScript?","body":"A typed superset of JavaScript that compiles to plain JavaScript. Static types catch errors at compile time, give IntelliSense and safe refactoring, document APIs and scale better for large teams. Types are erased at runtime, so there is no runtime cost — and no runtime checking."},{"kind":"question","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"831","title":"What is the difference between interface and type?","body":"Both describe object shapes. type can also name unions, intersections, tuples, primitives and mapped/conditional types; interface supports declaration merging and extends , and is often preferred for public object contracts. Interfaces can't express unions; types can't be reopened."},{"kind":"question","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"832","title":"any vs unknown vs never?","body":"any disables type checking for that value (errors pass silently). unknown accepts any value but must be narrowed (typeof/guards/schema) before use — the safe choice for external data and catch errors. never represents values that never occur — functions that always throw, or the impossible branch in an exhaustive switch."},{"kind":"question","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"833","title":"What are union types and how do you narrow them?","body":"A union A B means the value is one of several types. Narrow with typeof , instanceof , in , equality on a discriminant property ( kind ), truthiness, or custom type guards ( x is T ) so TypeScript knows which member you have in each branch."},{"kind":"question","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"834","title":"What is type inference?","body":"The compiler works out types without annotations: let n = 5 is number , a function's return type comes from its return statements, generic arguments come from the values passed. Annotate function parameters and public APIs; let inference handle locals."},{"kind":"question","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"835","title":"What are generics? Give an example.","body":"Type parameters that make code reusable while keeping types: function first<T (xs: T[]): T undefined . With constraints ( T extends { id: number } ) and keyof ( K extends keyof T ) you get type-safe helpers such as pluck(items, \"name\") . Common built-ins: Array<T , Promise<T , Record<K,V ."},{"kind":"question","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"836","title":"Explain Partial, Pick, Omit and Record with use cases.","body":"Partial<T makes all props optional (update/PATCH payloads). Pick<T,K keeps chosen keys (summary DTO). Omit<T,K removes keys (create payload without id ). Record<K,V builds an object type with keys K (lookup tables like Record<Status, string )."},{"kind":"question","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"837","title":"What does strict mode enable and why should it be on?","body":"strict: true enables noImplicitAny , strictNullChecks , strictFunctionTypes , strictBindCallApply , strictPropertyInitialization , alwaysStrict , useUnknownInCatchVariables and others. It catches the most common bugs — especially null/undefined access. New projects should always use it; legacy projects can turn flags on gradually."},{"kind":"question","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"838","title":"What is a discriminated union?","body":"A union of object types that share a literal \"tag\" property ( kind , type , status ). Switching on the tag narrows to the exact member, and a never check in default makes the switch exhaustive — adding a new member produces compile errors wherever it isn't handled. Ideal for state ( { status: \"loading\" } { status: \"error\"; error: string } { status: \"ok\"; data: T } ) and Redux/NgRx actions."},{"kind":"question","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"839","title":"What is the difference between `as` (type assertion) and `satisfies`?","body":"as T tells the compiler \"trust me, it's T\" — no runtime check and it can hide mistakes. satisfies T checks that a value matches T but keeps the more precise inferred type, so you get validation without losing literal types. Prefer satisfies for config objects and avoid as except at well-validated boundaries."},{"kind":"question","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"840","title":"What are declaration files (.d.ts)?","body":"Files containing only type declarations that describe JavaScript code — they let TypeScript type-check calls into JS libraries. Libraries ship their own ( \"types\" in package.json) or come from DefinitelyTyped ( npm i -D @types/lodash ). You can write declare module \"x\" or augment globals (e.g. Window ) in your own .d.ts ."},{"kind":"question","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"841","title":"What are mapped and conditional types?","body":"Mapped types transform each property of another type: { [K in keyof T]: Readonly<T[K] } (with as to rename keys). Conditional types choose a type by condition: T extends U ? X : Y , with infer to extract parts ( T extends Promise<infer R ? R : T ). Built-in utilities like Partial , ReturnType and Awaited are implemented with them."},{"kind":"question","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"842","title":"Structural vs nominal typing — what does TypeScript use?","body":"Structural: types are compatible if their shapes match, regardless of names, so { id: 1, name: \"x\" } is assignable to any interface with those members. C and Java are nominal. To simulate nominal types (e.g. UserId vs OrderId both numbers), use branded types: type UserId = number & { readonly brand: \"UserId\" } ."},{"kind":"question","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"843","title":"The API returned a different JSON shape and the app crashed even though it compiled. Why, and how do you prevent it?","body":"Types are erased at runtime; http.get<Order[] () or as Order[] only told the compiler what to expect. Prevent: generate client types from the backend OpenAPI document in the build (so contract changes show up as compile errors), validate responses at the boundary with Zod/Valibot, version the API, and add contract/end-to-end tests."},{"kind":"question","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"844","title":"You are migrating a large JavaScript project to TypeScript. How do you do it?","body":"Incrementally: add tsconfig with allowJs and checkJs off, rename files to .ts module by module starting from leaves (utilities, models), add @types packages, use any / unknown temporarily with TODOs, then turn on strict flags one by one ( noImplicitAny , then strictNullChecks ). Add type-checking ( tsc --noEmit ) to CI so coverage only grows."},{"kind":"question","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"845","title":"Write a type-safe function that groups an array by a key.","body":"typescript function groupBy<T, K extends PropertyKey (items: T[], key: (item: T) = K): Record<K, T[] { return items.reduce((acc, item) = { const k = key(item); (acc[k] ??= []).push(item); return acc; }, {} as Record<K, T[] ); } const byStatus = groupBy(orders, o = o.status); // Record<OrderStatus, Order[] (Modern runtimes also have Object.groupBy(items, fn) from ES2024.)"},{"kind":"cheat","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"1","title":"Core types","body":"string number boolean bigint symbol · T[] / Array<T · tuple [A, B] · unknown (safe) vs any (unsafe) · never · void · literal types \"a\" \"b\" · as const ."},{"kind":"cheat","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"2","title":"Interface vs type","body":"Interface: object contracts, extends , declaration merging. Type: unions, tuples, mapped/conditional types, & intersections."},{"kind":"cheat","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"3","title":"Narrowing","body":"typeof · instanceof · in · discriminant switch + never default · x is T guards · asserts x is T ."},{"kind":"cheat","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"4","title":"Utility types","body":"Partial Required Readonly Pick Omit Record Exclude Extract NonNullable ReturnType Parameters Awaited ."},{"kind":"cheat","course_slug":"typescript","course_title":"TypeScript — Types, Generics and Real-World Patterns","ref":"5","title":"Safety rules","body":"strict: true · avoid any and as · unknown for external data · validate API responses (Zod) · generate types from OpenAPI · import type for type-only imports · tsc --noEmit in CI."},{"kind":"course","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"","title":"Node.js — Runtime Internals, Express, APIs and SQL Server","body":"What Node.js is and how it works inside (V8, libuv, the event loop phases, thread pool, non-blocking I/O), modules (CommonJS vs ES modules), npm and package.json, the core modules (fs, path, http, events, streams, buffer), asynchronous patterns (callbacks, promises, async/await), Express.js REST APIs with middleware and error handling, project folder structure, connecting to SQL Server (mssql, Prisma, Sequelize), authentication with JWT, worker threads and clustering, testing, security, performance, deployment and the Node.js interview questions. Node.js is a JavaScript runtime that runs JavaScript outside the browser — on servers, build tools and CLIs. It uses Google's V8 engine to execute JavaScript and libuv to provide non-blocking I/O through an event loop , so one process can handle thousands of concurrent connections with a single main thread. Used for Examples --- --- Web APIs and backends Express, Fastify, NestJS, Koa Full stack frameworks Next.js, Nuxt, Remix, SvelteKit Real-time apps Chat, live dashboards with Socket.IO/WebSockets Tooling npm, Vite, webpack, Angular CLI, ESLint, TypeScript compiler Serverless AWS Lambda, Azure Functions, Vercel Functions Node.js vs ASP.NET Core: both are fast, cross-platform backends. Node shares one language (JavaScript/TypeScript) with the frontend and has the largest package ecosystem (npm); .NET offers strong typing by default, multithreaded CPU performance and a richer built-in framework. Version Year Highlights --- --- --- 0.1 2009 Ryan Dahl creates Node.js (V8 + event loop) 0.x / io.js 2010–2015 npm (2010), Express (2010); io.js fork merges back → Node.js Foundation (2015) 4–8 2015–2017 ES2015+ support, LTS releases begin, async/await (v7.6/8) 10–12 2018–2019 Worker threads, HTTP/2, N-API stable 14–16 2020–2021 ES modules stable, optional chaining, Apple Silicon support 18 2022 Global fetch , built-in test runner ( node:test ), watch mode later 20 2023 Permission model (experimental), stable test runner, single executable apps 22 2024 (LTS) require() of ES modules, WebSocket client, --experimental-strip-types (run TypeScript) 24 2025 (LTS from Oct 2025) npm 11, V8 13.x, URLPattern global, TypeScript type stripping on by default 25 2025 (Current) Next \"current\" line; even versions become LTS each October Release model: a new major every April and October; even-numbered releases become LTS (30 months of support). Use an Active/Maintenance LTS version in production. How Node.js handles a request: 1. node server.js starts the process: V8 is initialised, your module is loaded and executed top to bottom (synchronous setup), then the event loop starts. 2. http.createServer(...).listen(3000) registers a listening socket with the OS via libuv. 3. A request arrives → the OS notifies libuv (epoll/kqueue/IOCP) → the event loop runs your request callback on the main thread . 4. Your handler calls await db.query(...) → the query is sent on a socket (non-blocking) and the handler yields ; the main thread serves other requests. 5. When the DB answers, the promise resolves; its continuation is queued as a microtask and runs on the main thread. 6. File-system operations, DNS lookups, crypto and zlib run on libuv's thread pool (4 threads by default) and report back to the loop. 7. The response is written; when there is nothing left to do (no timers, sockets or pending work), the process exits. Event loop phases (libuv): text ┌───────────────────────────┐ ┌─ │ timers │ setTimeout / setInterval callbacks whose time has come │ ├───────────────────────────┤ │ │ pending callbacks │ some deferred system callbacks (e.g. TCP errors) │ ├───────────────────────────┤ │ │ idle, prepare │ internal │ ├───────────────────────────┤ │ │ poll │ retrieve new I/O events; run I/O callbacks; may block here waiting │ ├───────────────────────────┤ │ │ check │ setImmediate callbacks │ ├───────────────────────────┤ └──┤ close callbacks │ socket.on('close') etc. └───────────────────────────┘ Between every callback: process.nextTick queue, then the Promise microtask queue are drained. - Runtime & package managers: Node.js (nvm / nvm-windows / fnm to switch versions), npm, pnpm, yarn; npx. - Frameworks: Express, Fastify, NestJS (Angular-like structure, DI), Koa, Hono. - Data: mssql (SQL Server via tedious), Prisma ORM, Sequelize, TypeORM, Knex, pg , mysql2 , Mongoose. - Dev tools: nodemon / node --watch , ts-node / tsx, ESLint, Prettier, Chrome DevTools ( node --inspect ), VS Code debugger. - Testing: node:test , Jest, Vitest, Supertest (HTTP), Playwright. - Production: PM2, Docker, clinic.js (performance), OpenTelemetry, pino/winston (logging)."},{"kind":"lesson","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"what-node-js-is-v8-libuv-and-the-single-threaded-event-loop","title":"What Node.js is — V8, libuv and the single-threaded event loop","body":"text Your JavaScript │ ┌────▼─────────────── Node.js ────────────────────────────┐ │ Core modules (fs, http, crypto, stream …) — JS + C++ bindings │ ├───────────────┬──────────────────────────────────────────┤ │ V8 │ libuv │ │ JS engine: │ event loop, non-blocking network I/O, │ │ parse, JIT, │ thread pool (fs, dns.lookup, crypto, zlib),│ │ GC │ timers, signals, child processes │ └───────────────┴──────────────────────────────────────────┘ Operating system (epoll / kqueue / IOCP) - Single-threaded for your JavaScript: only one callback runs at a time — no locks needed for shared variables. - Non-blocking I/O: waiting for the network/disk doesn't block the thread; Node continues with other work. - Great for I/O-bound work (APIs, proxies, real-time). CPU-bound work (image processing, big JSON parsing, heavy loops) blocks the event loop for everyone — move it to worker threads , a separate service, or a queue. js // Blocking vs non-blocking const fs = require('node:fs'); const data = fs.readFileSync('big.log'); // ❌ blocks the event loop until the file is read fs.readFile('big.log', (err, d) = { / … / }); // ✅ callback when done; loop keeps serving requests const text = await fs.promises.readFile('big.log', 'utf8'); // ✅ promise version"},{"kind":"lesson","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"modules-commonjs-vs-es-modules-npm-and-package-json","title":"Modules — CommonJS vs ES modules, npm and package.json","body":"js // CommonJS (default for .js unless \"type\": \"module\") const path = require('node:path'); module.exports = { add: (a, b) = a + b }; // ES modules (.mjs, or \"type\": \"module\" in package.json) import path from 'node:path'; import { readFile } from 'node:fs/promises'; export function add(a, b) { return a + b; } export default add; CommonJS ES modules --- --- --- Syntax require / module.exports import / export Loading Synchronous, at runtime Static analysis, async loading, top-level await dirname Available Use import.meta.dirname (Node 20.11+) Interop Can require() ESM since Node 22 (sync graphs) Can import CommonJS json { \"name\": \"shop-api\", \"version\": \"1.0.0\", \"type\": \"module\", \"main\": \"src/server.js\", \"engines\": { \"node\": \" =22\" }, \"scripts\": { \"dev\": \"node --watch src/server.js\", \"start\": \"node src/server.js\", \"test\": \"node --test\", \"lint\": \"eslint .\" }, \"dependencies\": { \"express\": \"^5.1.0\", \"mssql\": \"^11.0.1\", \"zod\": \"^3.24.0\" }, \"devDependencies\": { \"eslint\": \"^9.0.0\", \"supertest\": \"^7.0.0\" } } - dependencies ship to production; devDependencies only for development/build. - Semantic versioning: ^5.1.0 allows 5.x.x updates, ~5.1.0 allows 5.1.x, exact 5.1.0 pins. - package-lock.json records exact installed versions — commit it; use npm ci in CI for reproducible installs. - npm audit checks known vulnerabilities; npm outdated shows updates."},{"kind":"lesson","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"core-modules-fs-path-http-events-buffer-and-process","title":"Core modules — fs, path, http, events, buffer and process","body":"js import http from 'node:http'; import { EventEmitter } from 'node:events'; import path from 'node:path'; // Minimal HTTP server without frameworks const server = http.createServer((req, res) = { if (req.method === 'GET' && req.url === '/health') { res.writeHead(200, { 'Content-Type': 'application/json' }); return res.end(JSON.stringify({ status: 'ok' })); } res.writeHead(404).end(); }); server.listen(process.env.PORT ?? 3000, () = console.log('listening')); // EventEmitter — the pattern behind streams, servers and sockets class OrderEvents extends EventEmitter {} const events = new OrderEvents(); events.on('placed', (order) = console.log('send email for', order.id)); events.emit('placed', { id: 1001 }); // path and process const file = path.join(import.meta.dirname, 'data', 'orders.json'); console.log(process.env.NODE ENV, process.argv, process.memoryUsage().heapUsed); process.on('SIGTERM', () = server.close(() = process.exit(0))); // graceful shutdown // Buffer — raw binary data const buf = Buffer.from('₹100', 'utf8'); console.log(buf.length, buf.toString('base64'));"},{"kind":"lesson","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"asynchronous-javascript-in-node-callbacks-promises-async-await-and-the-microtask","title":"Asynchronous JavaScript in Node — callbacks, promises, async/await and the microtask queue","body":"js // 1. Callbacks (error-first convention) fs.readFile('a.txt', 'utf8', (err, text) = { if (err) return console.error(err); console.log(text); }); // 2. Promises fs.promises.readFile('a.txt', 'utf8').then(console.log).catch(console.error); // 3. async/await — cleanest async function loadAll() { try { const [a, b] = await Promise.all([readFile('a.txt', 'utf8'), readFile('b.txt', 'utf8')]); // in parallel return a + b; } catch (err) { console.error('load failed', err); throw err; } } // Execution order puzzle — a classic interview question console.log('1 sync'); setTimeout(() = console.log('5 timeout'), 0); setImmediate(() = console.log('6 immediate')); Promise.resolve().then(() = console.log('4 promise microtask')); process.nextTick(() = console.log('3 nextTick')); console.log('2 sync'); // Output: 1, 2, 3, 4, then 5 and 6 (timeout vs immediate order can vary at top level; inside an I/O callback, immediate runs first) API Runs --- --- process.nextTick Right after the current operation, before promises Promise .then / await continuation Microtask queue, after nextTick queue setTimeout(fn, 0) Timers phase of the next loop iteration (≥ ~1 ms) setImmediate Check phase (after poll) Unhandled promise rejections crash the process (default since Node 15) — always await or .catch , and add process.on('unhandledRejection', …) logging."},{"kind":"lesson","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"streams-and-buffers-processing-large-data","title":"Streams and buffers — processing large data","body":"Streams process data piece by piece — constant memory regardless of file size. Type Example --- --- Readable fs.createReadStream , HTTP request, DB cursor Writable fs.createWriteStream , HTTP response Duplex TCP socket Transform zlib.createGzip() , CSV parser js import { createReadStream, createWriteStream } from 'node:fs'; import { createGzip } from 'node:zlib'; import { pipeline } from 'node:stream/promises'; await pipeline(createReadStream('orders.csv'), createGzip(), createWriteStream('orders.csv.gz')); // handles errors + backpressure // Stream a large file to an HTTP client app.get('/export', (req, res) = { res.setHeader('Content-Type', 'text/csv'); createReadStream('export.csv').pipe(res); }); Backpressure: when the writer is slower than the reader, write() returns false ; pipe / pipeline pause and resume the source automatically so memory doesn't explode."},{"kind":"lesson","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"express-js-routing-middleware-and-error-handling","title":"Express.js — routing, middleware and error handling","body":"js import express from 'express'; import helmet from 'helmet'; import cors from 'cors'; const app = express(); app.use(helmet()); // security headers app.use(cors({ origin: ['http://localhost:4200'] })); app.use(express.json({ limit: '1mb' })); // parse JSON bodies app.use((req, res, next) = { // custom middleware (logging) const start = Date.now(); res.on('finish', () = console.log( ${req.method} ${req.originalUrl} ${res.statusCode} ${Date.now() - start}ms )); next(); }); app.get('/api/products', async (req, res) = { const page = Number(req.query.page ?? 1); res.json(await productService.list(page)); }); app.get('/api/products/:id', async (req, res) = { const p = await productService.get(Number(req.params.id)); if (!p) return res.status(404).json({ title: 'Not found' }); res.json(p); }); app.post('/api/products', async (req, res) = { const created = await productService.create(req.body); res.status(201).location( /api/products/${created.id} ).json(created); }); app.use((req, res) = res.status(404).json({ title: 'Route not found' })); // 404 handler app.use((err, req, res, next) = { // error handler: 4 parameters console.error(err); res.status(err.status ?? 500).json({ title: err.status ? err.message : 'Unexpected error' }); }); app.listen(3000); - Middleware runs in registration order ; each calls next() or ends the response. - Express 5 (stable 2024) forwards rejected promises from async handlers to the error middleware automatically (Express 4 needed try/catch or express-async-errors ). - Validate input (zod/Joi/express-validator) — never trust req.body ."},{"kind":"lesson","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"node-js-express-project-folder-structure-with-sample-files","title":"Node.js / Express project folder structure (with sample files)","body":"text shop-api/ ├── src/ │ ├── server.js starts the HTTP server, graceful shutdown │ ├── app.js creates the Express app: middleware, routes, error handler (exported for tests) │ ├── config/ │ │ └── index.js reads environment variables (dotenv / process.env) and validates them │ ├── db/ │ │ ├── pool.js SQL Server connection pool (mssql) │ │ └── migrations/ SQL scripts or Prisma migrations │ ├── modules/ feature folders (vertical slices) │ │ ├── products/ │ │ │ ├── product.routes.js Express router: URL → controller │ │ │ ├── product.controller.js HTTP layer: read req, call service, send res │ │ │ ├── product.service.js business logic │ │ │ ├── product.repository.js SQL queries │ │ │ ├── product.schema.js zod validation schemas │ │ │ └── product.test.js │ │ └── orders/ … │ ├── middleware/ │ │ ├── auth.js JWT verification │ │ ├── validate.js validation middleware │ │ └── errorHandler.js │ └── utils/ │ └── logger.js pino/winston logger ├── tests/ integration tests (supertest) ├── .env.example documented environment variables (never commit .env) ├── .gitignore node modules, .env, dist ├── Dockerfile ├── package.json / package-lock.json └── README.md js // src/app.js import express from 'express'; import { productRouter } from './modules/products/product.routes.js'; import { errorHandler } from './middleware/errorHandler.js'; export const app = express(); app.use(express.json()); app.use('/api/products', productRouter); app.use(errorHandler); // src/modules/products/product.routes.js import { Router } from 'express'; import as controller from './product.controller.js'; export const productRouter = Router(); productRouter.get('/', controller.list); productRouter.get('/:id', controller.getById); productRouter.post('/', controller.create); // src/modules/products/product.controller.js import as service from './product.service.js'; export async function list(req, res) { res.json(await service.list(Number(req.query.page ?? 1))); } export async function getById(req, res) { const product = await service.getById(Number(req.params.id)); return product ? res.json(product) : res.status(404).json({ title: 'Not found' }); } export async function create(req, res) { res.status(201).json(await service.create(req.body)); } // src/server.js import { app } from './app.js'; import { config } from './config/index.js'; const server = app.listen(config.port, () = console.log( API on :${config.port} )); process.on('SIGTERM', () = server.close()); NestJS projects use a similar feature structure with .module.ts , .controller.ts , .service.ts and decorators (Angular-style DI)."},{"kind":"lesson","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"connecting-node-js-to-sql-server-mssql-prisma-sequelize","title":"Connecting Node.js to SQL Server (mssql, Prisma, Sequelize)","body":"1. mssql package (most common, uses the tedious driver): js // src/db/pool.js import sql from 'mssql'; const config = { server: process.env.DB SERVER, // e.g. \"localhost\" or \"myserver.database.windows.net\" database: process.env.DB NAME, user: process.env.DB USER, // SQL authentication password: process.env.DB PASSWORD, port: 1433, pool: { max: 10, min: 0, idleTimeoutMillis: 30000 }, options: { encrypt: true, // required for Azure SQL trustServerCertificate: process.env.NODE ENV !== 'production', // local dev with self-signed cert }, }; export const poolPromise = new sql.ConnectionPool(config).connect(); // ONE pool for the whole app export { sql }; // src/modules/products/product.repository.js import { poolPromise, sql } from '../../db/pool.js'; export async function findById(id) { const pool = await poolPromise; const result = await pool.request() .input('id', sql.Int, id) // parameterised — prevents SQL injection .query('SELECT Id, Name, Price FROM dbo.Products WHERE Id = @id'); return result.recordset[0] ?? null; } export async function searchByProc(customerId) { const pool = await poolPromise; const r = await pool.request() .input('CustomerId', sql.Int, customerId) .output('Total', sql.Int) .execute('dbo.usp GetCustomerOrders'); // stored procedure return { orders: r.recordset, total: r.output.Total }; } export async function placeOrder(order) { // transaction const pool = await poolPromise; const tx = new sql.Transaction(pool); await tx.begin(); try { const r = await new sql.Request(tx).input('cid', sql.Int, order.customerId) .query('INSERT INTO dbo.Orders (CustomerId) OUTPUT INSERTED.Id VALUES (@cid)'); for (const l of order.lines) await new sql.Request(tx).input('oid', sql.Int, r.recordset[0].Id).input('pid', sql.Int, l.productId).input('qty', sql.Int, l.qty) .query('INSERT INTO dbo.OrderLines (OrderId, ProductId, Qty) VALUES (@oid, @pid, @qty)'); await tx.commit(); } catch (e) { await tx.rollback(); throw e; } } bash .env (never commit) DB SERVER=localhost DB NAME=Shop DB USER=shop app DB PASSWORD=change-me Windows authentication from Node needs the msnodesqlv8 driver ( mssql/msnodesqlv8 , Windows only); for Azure SQL prefer Microsoft Entra ID auth ( authentication: { type: 'azure-active-directory-default' } ) so no password is stored. 2. Prisma ORM: prisma // prisma/schema.prisma datasource db { provider = \"sqlserver\" url = env(\"DATABASE URL\") } generator client { provider = \"prisma-client-js\" } model Product { id Int @id @default(autoincrement()) name String @db.NVarChar(200) price Decimal @db.Decimal(18, 2) } bash DATABASE URL=\"sqlserver://localhost:1433;database=Shop;user=shop app;password=change-me;encrypt=true;trustServerCertificate=true\" npx prisma migrate dev --name init or: npx prisma db pull (database-first) js import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); const cheap = await prisma.product.findMany({ where: { price: { lt: 100 } }, orderBy: { name: 'asc' } }); 3. Sequelize: new Sequelize(db, user, pass, { dialect: 'mssql', host, dialectOptions: { options: { encrypt: true } } }) , define models, findAll({ where }) ."},{"kind":"lesson","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"authentication-with-jwt-configuration-and-security","title":"Authentication with JWT, configuration and security","body":"js import jwt from 'jsonwebtoken'; export function requireAuth(req, res, next) { const header = req.headers.authorization ?? ''; const token = header.startsWith('Bearer ') ? header.slice(7) : null; if (!token) return res.status(401).json({ title: 'Missing token' }); try { req.user = jwt.verify(token, process.env.JWT SECRET, { algorithms: ['HS256'], audience: 'shop-api' }); next(); } catch { res.status(401).json({ title: 'Invalid token' }); } } export const requireRole = (role) = (req, res, next) = (req.user?.roles?.includes(role) ? next() : res.status(403).json({ title: 'Forbidden' })); router.delete('/:id', requireAuth, requireRole('Admin'), controller.remove); Security checklist: helmet (headers), CORS allow-list, input validation (zod), parameterised SQL, rate limiting ( express-rate-limit ), hash passwords with bcrypt/argon2, secrets in environment variables/Key Vault, npm audit and Dependabot, avoid eval /dynamic require of user input, limit body size, don't leak stack traces, keep Node on a supported LTS."},{"kind":"lesson","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"scaling-node-cluster-worker-threads-child-processes-and-pm2","title":"Scaling Node — cluster, worker threads, child processes and PM2","body":"Tool Use --- --- cluster module / PM2 cluster mode Run one Node process per CPU core sharing the port — scale an API on one machine worker threads Run CPU-heavy JavaScript in parallel threads (separate V8 isolates) without blocking the event loop child process ( spawn , exec , fork ) Run other programs/scripts as separate processes Horizontal scaling Many containers behind a load balancer (Kubernetes, App Service, ECS) — keep the app stateless js // CPU-heavy work in a worker thread import { Worker } from 'node:worker threads'; function hashInWorker(data) { return new Promise((resolve, reject) = { const w = new Worker(new URL('./hash-worker.js', import.meta.url), { workerData: data }); w.once('message', resolve); w.once('error', reject); }); } bash pm2 start src/server.js -i max --name shop-api cluster mode, one process per core, auto-restart pm2 logs; pm2 reload shop-api zero-downtime reload Performance tips: never block the event loop (sync fs/crypto in request paths, huge JSON.stringify), use streams for big data, connection pooling, caching (Redis), compression, UV THREADPOOL SIZE for heavy fs/crypto, measure with clinic doctor / --prof , watch event-loop lag and heap usage, avoid memory leaks (global caches, listeners never removed — MaxListenersExceededWarning )."},{"kind":"lesson","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"testing-logging-and-deploying-node-js-apps","title":"Testing, logging and deploying Node.js apps","body":"js // tests/products.test.js — node:test + supertest import { test } from 'node:test'; import assert from 'node:assert/strict'; import request from 'supertest'; import { app } from '../src/app.js'; test('GET /api/products returns a list', async () = { const res = await request(app).get('/api/products').expect(200); assert.ok(Array.isArray(res.body.items)); }); dockerfile FROM node:22-alpine WORKDIR /app COPY package .json ./ RUN npm ci --omit=dev COPY src ./src USER node ENV NODE ENV=production EXPOSE 3000 CMD [\"node\", \"src/server.js\"] Deploy targets: Docker on any cloud, Azure App Service (Linux, Node runtime), AWS Elastic Beanstalk/ECS/Lambda, Vercel/Netlify functions, or IIS with iisnode / reverse proxy (IIS + URL Rewrite → Node on a port) on Windows servers. Logging: pino (fast JSON) or winston; set NODE ENV=production (Express caches views and reduces error detail)."},{"kind":"question","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"846","title":"What is Node.js and why is it fast for I/O-heavy apps?","body":"A JavaScript runtime built on Chrome's V8 engine and libuv. It runs your JavaScript on a single main thread with an event loop and performs I/O (network, disk) asynchronously, so while one request waits for the database the thread serves other requests. Without thread-per-request overhead it handles many concurrent connections efficiently — ideal for APIs, proxies and real-time apps."},{"kind":"question","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"847","title":"Explain the event loop in Node.js.","body":"The event loop is libuv's loop that repeatedly checks for completed work and runs callbacks on the main thread in phases: timers (setTimeout/setInterval), pending callbacks, poll (I/O events), check (setImmediate), close callbacks. Between callbacks Node drains the process.nextTick queue and then the promise microtask queue. Blocking the loop with long synchronous code delays every other request."},{"kind":"question","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"848","title":"Is Node.js single-threaded?","body":"Your JavaScript runs on one main thread, but Node itself is not: libuv uses a thread pool (default 4) for file system, DNS lookup, crypto and compression, and the OS handles network I/O asynchronously. You can also use worker threads for CPU-heavy JavaScript and the cluster module or multiple containers to use all CPU cores."},{"kind":"question","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"849","title":"What is the difference between CommonJS and ES modules?","body":"CommonJS uses require() / module.exports , loads synchronously at runtime and was Node's original system. ES modules use import / export , are statically analysable (tree-shaking), support top-level await and are the JavaScript standard — enabled with .mjs or \"type\": \"module\" . Modern Node supports both and recent versions can require() ES modules."},{"kind":"question","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"850","title":"What is middleware in Express?","body":"A function (req, res, next) in the request pipeline that can read/modify the request and response, end the response, or call next() to pass control on. Used for logging, parsing bodies, authentication, CORS, validation and error handling (error middleware has four parameters (err, req, res, next) ). Middleware runs in the order it's registered."},{"kind":"question","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"851","title":"What are package.json, package-lock.json, dependencies and devDependencies?","body":"package.json describes the project: name, scripts, engines, dependency ranges. package-lock.json records the exact resolved versions of the whole dependency tree so installs are reproducible ( npm ci ). dependencies are needed at runtime in production; devDependencies only for development, testing and building."},{"kind":"question","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"852","title":"process.nextTick vs setImmediate vs setTimeout(fn, 0)?","body":"process.nextTick callbacks run immediately after the current operation, before promise microtasks and before the event loop continues. setTimeout(fn, 0) runs in the timers phase of a later loop iteration (minimum ~1 ms). setImmediate runs in the check phase right after the poll phase. Inside an I/O callback, setImmediate always fires before a zero timeout. Overusing nextTick can starve I/O."},{"kind":"question","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"853","title":"How do you handle errors in async Node.js code?","body":"Use try/catch around await , .catch() on promises, and error-first callbacks for callback APIs. In Express 5 rejected async handlers reach the error middleware automatically (Express 4: wrap or use express-async-errors). Add a central error middleware, log unhandledRejection and uncaughtException (then exit and let the process manager restart), validate input to avoid predictable errors, and never swallow errors silently."},{"kind":"question","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"854","title":"How do you connect Node.js to SQL Server?","body":"Use the mssql package (tedious driver): create one ConnectionPool at startup with server, database, credentials and encrypt: true , then run parameterised queries with request().input(...).query(...) , stored procedures with .execute() , and transactions with sql.Transaction . Alternatives: Prisma ( provider = \"sqlserver\" ) or Sequelize/TypeORM. Keep credentials in environment variables or use Entra ID authentication for Azure SQL."},{"kind":"question","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"855","title":"What are streams and why are they useful?","body":"Objects for reading or writing data in chunks (Readable, Writable, Duplex, Transform). They keep memory constant for large files or responses, start delivering data before everything is loaded, and handle backpressure. Use stream.pipeline to connect streams with proper error handling — e.g. read a CSV, gzip it, write it to the HTTP response."},{"kind":"question","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"856","title":"What is the cluster module and how is it different from worker threads?","body":"Cluster forks multiple Node processes (one per core) that share the same server port, each with its own event loop and memory — scaling a stateless HTTP server on one machine (PM2 does this). Worker threads run JavaScript in parallel threads inside one process (separate V8 isolates, can share memory via SharedArrayBuffer) — for CPU-heavy tasks without blocking the main event loop."},{"kind":"question","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"857","title":"How do you secure an Express API?","body":"Helmet for security headers, strict CORS, HTTPS, input validation (zod/Joi), parameterised queries/ORM against injection, authentication (JWT/OAuth with libraries like passport or jose) and role checks, rate limiting, body size limits, password hashing (bcrypt/argon2), secrets in env/Key Vault, dependency scanning ( npm audit , Dependabot), no stack traces in responses, and keeping Node and packages updated."},{"kind":"question","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"858","title":"What causes event-loop blocking and how do you detect and fix it?","body":"Long synchronous operations: big loops, synchronous fs/crypto ( readFileSync , pbkdf2Sync ), huge JSON.parse/stringify , regex catastrophes, sorting large arrays per request. Detect with event-loop lag metrics ( perf hooks.monitorEventLoopDelay ), clinic.js, profiling with --inspect / --prof . Fix by using async APIs, streaming, chunking work with setImmediate , moving CPU work to worker threads or another service, and caching results."},{"kind":"question","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"859","title":"How do memory leaks happen in Node and how do you find them?","body":"Objects kept reachable: growing global arrays/maps used as caches without limits, event listeners added per request and never removed, closures capturing large data, timers not cleared, unclosed DB connections. Find them by watching heap usage over time, taking heap snapshots ( --inspect + Chrome DevTools, heapdump ) and comparing retained objects; fix by bounding caches (LRU), removing listeners and cleaning up timers."},{"kind":"question","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"860","title":"Node.js vs ASP.NET Core — when would you choose each?","body":"Node.js: JavaScript/TypeScript across front and back end, huge npm ecosystem, great for I/O-heavy APIs, real-time apps, BFFs and serverless functions, fast prototyping. ASP.NET Core: strong typing and tooling by default, true multithreading for CPU-heavy work, rich built-in framework (DI, auth, EF Core), excellent performance and long-term support — common in enterprises with SQL Server/Azure. Choose based on team skills, workload and ecosystem."},{"kind":"question","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"861","title":"Your Node API becomes very slow when a user uploads a large CSV for import. What's wrong and how do you fix it?","body":"The upload is probably read and parsed synchronously in memory ( readFileSync , JSON/CSV parse of the whole file) on the main thread, blocking the event loop for all users. Stream the upload (multer/busboy to disk or Blob storage), parse it with a streaming CSV parser, insert in batches (bulk insert/TVP), and ideally move the import to a background job/queue with a worker, returning 202 Accepted and a status endpoint."},{"kind":"question","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"862","title":"The production Node process crashes occasionally with \"UnhandledPromiseRejection\". What do you do?","body":"Find the promise without await / .catch from the stack trace and logs; fix it by awaiting or handling the error; add a global process.on('unhandledRejection') handler that logs (then exits for safety), run under a process manager (PM2/containers) that restarts the app, and add lint rules ( @typescript-eslint/no-floating-promises ) to prevent new ones."},{"kind":"cheat","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"1","title":"Architecture","body":"V8 (JS engine) + libuv (event loop, thread pool of 4, async I/O) · your JS on one main thread · I/O non-blocking · CPU work → worker threads."},{"kind":"cheat","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"2","title":"Event loop order","body":"sync code → process.nextTick → promise microtasks → timers → pending → poll (I/O) → check ( setImmediate ) → close callbacks."},{"kind":"cheat","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"3","title":"Express essentials","body":"express.json() · routers per feature · middleware order matters · (err, req, res, next) error handler · Express 5 async errors · helmet, cors, rate limit, validation."},{"kind":"cheat","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"4","title":"SQL Server from Node","body":"mssql ConnectionPool once · .input(name, type, value) parameters · .execute(proc) · sql.Transaction · encrypt: true (Azure) · Prisma provider = \"sqlserver\" · secrets in env vars."},{"kind":"cheat","course_slug":"nodejs","course_title":"Node.js — Runtime Internals, Express, APIs and SQL Server","ref":"5","title":"Production","body":"LTS (even) versions · npm ci · NODE ENV=production · PM2/cluster or containers · graceful SIGTERM shutdown · pino logging · monitor event-loop lag and heap."},{"kind":"course","course_slug":"jquery","course_title":"jQuery","ref":"","title":"jQuery","body":"Selectors, traversal, DOM manipulation, events and delegation, effects, AJAX, deferreds, plugins, jQuery with ASP.NET MVC validation, performance and migrating from jQuery to modern JavaScript. jQuery is a small JavaScript library (created by John Resig , 2006) that made DOM manipulation, event handling, animation and AJAX simple and cross-browser with a concise API: $(\"selector\").action() . \"Write less, do more.\" It is still found in a huge number of existing websites, WordPress, Bootstrap 3/4 sites and classic ASP.NET MVC / Web Forms apps (jQuery Validation + Unobtrusive Validation). New projects usually use plain modern JavaScript or a framework (React/Angular/Vue), so interviews focus on maintaining existing jQuery code and knowing the modern equivalents. Core ideas: - $ (alias of jQuery ) wraps DOM elements in a jQuery object (array-like collection). - Implicit iteration — methods apply to every matched element. - Chaining — most methods return the jQuery object. - $(document).ready() / $(function(){ }) runs code when the DOM is ready. Version Year Notes --- --- --- 1.0 Aug 2006 First release 1.3 / 1.4 2009 / 2010 Sizzle selector engine; .live() (later removed) 1.5 2011 Deferred objects , rewritten AJAX 1.7 2011 .on() / .off() unified event API 1.9 / 2.0 2013 Removal of deprecated APIs; 2.x dropped IE 6–8 3.0 2016 Promises/A+ compatible deferreds, requestAnimationFrame , strict mode compatible 3.5 2020 Security fix for htmlPrefilter (XSS in .html() ) — upgrade if below 3.5 3.7.1 2023 Last 3.x feature release 4.0 2026 Drops IE ≤ 10 and old Edge, removes deprecated APIs (e.g. jQuery.trim , isArray ), ES modules, Trusted Types support Companion projects: jQuery UI (widgets, interactions; maintenance mode), jQuery Mobile (deprecated 2021), jQuery Migrate (plugin that warns about deprecated APIs during upgrades), jQuery Validation (third-party plugin). Page and jQuery lifecycle: 1. Browser loads HTML; <script src=\"jquery.min.js\" defines window.jQuery / $ (load before plugins and your code). 2. Plugins ( jquery.validate.js , jquery.validate.unobtrusive.js , Bootstrap JS) attach to $.fn . 3. $(function () { ... }) — the DOM ready callback runs after the DOM is parsed (before images load). 4. Your code selects elements, binds events ( .on() ), initialises plugins. 5. User interacts → event handlers → DOM updates / AJAX calls. 6. AJAX lifecycle: beforeSend → request → done/success or fail/error → always/complete ; global events ajaxStart , ajaxStop , ajaxError . 7. $(window).on(\"load\", ...) fires when all resources including images are loaded. 8. When removing elements use .remove() (cleans up jQuery data and events) rather than raw DOM removal to avoid leaks. - CDN (code.jquery.com, cdnjs) or npm ( npm install jquery ) / LibMan in ASP.NET projects. - jQuery Migrate for upgrading between majors. - Browser DevTools (inspect handlers in Elements → Event Listeners). - jQuery UI , jQuery Validation + Microsoft jQuery Unobtrusive Validation , DataTables, Select2, Bootstrap (≤ 4). - You Might Not Need jQuery (website) — modern JavaScript equivalents. - ESLint plugin eslint-plugin-jquery / no-jquery to find and remove jQuery usage."},{"kind":"lesson","course_slug":"jquery","course_title":"jQuery","ref":"including-jquery-and-document-ready","title":"Including jQuery and document ready","body":"html <script src=\"https://code.jquery.com/jquery-3.7.1.min.js\" integrity=\"sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=\" crossorigin=\"anonymous\" </script <script $(function () { // shorthand for $(document).ready(function () { ... }) $(\" greeting\").text(\"DOM is ready\"); }); jQuery(function ($) { // safe '$' even if another library uses it (with $.noConflict()) // ... }); </script $(document).ready() fires when the DOM is ready; window.onload waits for images and other resources. If the script is placed at the end of <body or uses defer , the DOM is already parsed."},{"kind":"lesson","course_slug":"jquery","course_title":"jQuery","ref":"selectors-and-filtering","title":"Selectors and filtering","body":"js $(\" orderForm\") // id $(\".order-row\") // class $(\"table tr:even\") // jQuery extension pseudo-selector (avoid for performance; use CSS where possible) $(\"input[type='email']\") // attribute $(\"ul li:first-child\") // CSS $(\" orders\").find(\".paid\") // descendant search — faster than one complex selector $(\".item\").filter(\".active\") // narrow a set $(\".item\").not(\".disabled\") $(\".item\").eq(2) // third element $(\".item\").first() / .last() $(\"li\").has(\"ul\") // contains matching descendants $(\" el\").is(\":visible\") // test → boolean const $rows = $(\".order-row\"); // cache selections (prefix $ by convention) const raw = $rows[0]; // or $rows.get(0) → plain DOM element $(raw) // wrap a DOM element"},{"kind":"lesson","course_slug":"jquery","course_title":"jQuery","ref":"dom-traversal-and-manipulation","title":"DOM traversal and manipulation","body":"js // Traversal $(this).parent(); $(this).parents(\".card\"); $(this).closest(\"tr\"); $(this).children(); $(this).siblings(); $(this).next(); $(this).prev(); // Content $(\" title\").text(\"New title\"); // safe text $(\" box\").html(\"<b Bold</b \"); // parses HTML — never with untrusted input (XSS) $(\" name\").val(); // get form value $(\" name\").val(\"Divakar\"); // set // Attributes and properties $(\"img\").attr(\"alt\", \"Logo\"); $(\" agree\").prop(\"checked\", true); // use .prop for checked/disabled/selected (live state) $(\" box\").data(\"id\"); // reads data-id (cached by jQuery) // Classes and CSS $(\" box\").addClass(\"active\").removeClass(\"hidden\").toggleClass(\"open\"); $(\" box\").css({ color: \"red\", \"font-weight\": \"bold\" }); // Insert / remove $(\" list\").append(\"<li Last</li \").prepend(\"<li First</li \"); $(\"<li \", { text: \"Safe item\", class: \"item\" }).appendTo(\" list\"); $(\" old\").remove(); // removes element + its jQuery data/events $(\" list\").empty(); // removes children $(\" tmp\").detach(); // removes but keeps data/events to re-insert attr vs prop: attr reads/writes the HTML attribute (initial value); prop reads/writes the DOM property (current state). For checked , disabled , selected use prop ."},{"kind":"lesson","course_slug":"jquery","course_title":"jQuery","ref":"events-and-event-delegation","title":"Events and event delegation","body":"js $(\" save\").on(\"click\", function (e) { e.preventDefault(); $(this).prop(\"disabled\", true); // 'this' = the DOM element }); // Delegation: handler on a static parent, works for rows added later $(\" ordersTable\").on(\"click\", \".delete-btn\", function () { const id = $(this).closest(\"tr\").data(\"id\"); deleteOrder(id); }); $(\" search\").on(\"input\", debounce(function () { search($(this).val()); }, 300)); $(\" name\").on(\"keyup change\", handler); // multiple events $(\" btn\").one(\"click\", handler); // runs once $(\" btn\").off(\"click\"); // remove handlers $(\".item\").on(\"click.analytics\", track); // namespaced event $(\".item\").off(\".analytics\"); // remove only namespaced handlers $(\" form\").trigger(\"submit\"); // trigger programmatically Old APIs: .bind() , .delegate() , .live() (removed in 1.9) → all replaced by .on() . return false in a jQuery handler = preventDefault() + stopPropagation() ."},{"kind":"lesson","course_slug":"jquery","course_title":"jQuery","ref":"ajax-with-ajax-get-post-and-deferreds","title":"AJAX with $.ajax, $.get, $.post and deferreds","body":"js $.ajax({ url: \"/api/orders\", method: \"POST\", contentType: \"application/json\", data: JSON.stringify({ customerId: 5, items: [{ productId: 1, qty: 2 }] }), dataType: \"json\", headers: { RequestVerificationToken: $(\"input[name=' RequestVerificationToken']\").val() }, timeout: 10000, }) .done(order = showToast( Order ${order.id} created )) .fail((xhr, status, err) = showError(xhr.responseJSON?.title ?? err)) .always(() = $(\" spinner\").hide()); $.get(\"/api/products\", { category: \"laptops\" }).done(render); $.getJSON(\"/api/products/5\").done(p = $(\" name\").text(p.name)); $(\" result\").load(\"/Orders/Summary summaryPanel\"); // load HTML fragment into element // Parallel requests $.when($.getJSON(\"/api/user\"), $.getJSON(\"/api/orders\")).done((userRes, ordersRes) = { const user = userRes[0], orders = ordersRes[0]; }); // Global AJAX events $(document).ajaxStart(() = $(\" spinner\").show()).ajaxStop(() = $(\" spinner\").hide()); jqXHR objects are thenable (Promises/A+ compatible since 3.0), so they work with await . .success/.error/.complete callbacks were removed in 3.0 — use .done/.fail/.always ."},{"kind":"lesson","course_slug":"jquery","course_title":"jQuery","ref":"effects-and-animations","title":"Effects and animations","body":"js $(\" panel\").hide(); $(\" panel\").show(); $(\" panel\").toggle(); $(\" msg\").fadeIn(300).delay(2000).fadeOut(300); $(\" menu\").slideToggle(\"fast\"); $(\" box\").animate({ left: \"+=50px\", opacity: 0.5 }, 400, \"swing\", () = console.log(\"done\")); $(\" box\").stop(true, true); // stop queued animations Modern alternative: CSS transitions/animations toggled with classes ( classList.toggle ) — smoother (GPU) and easier to maintain."},{"kind":"lesson","course_slug":"jquery","course_title":"jQuery","ref":"writing-a-jquery-plugin","title":"Writing a jQuery plugin","body":"js (function ($) { $.fn.highlight = function (options) { const settings = $.extend({ color: \"yellow\", duration: 1000 }, options); return this.each(function () { // implicit iteration + chainable const $el = $(this); const original = $el.css(\"background-color\"); $el.css(\"background-color\", settings.color); setTimeout(() = $el.css(\"background-color\", original), settings.duration); }); }; })(jQuery); $(\".new-row\").highlight({ color: \" d3f9d8\" }).addClass(\"seen\"); $.fn is jQuery.prototype ; $.extend merges objects (deep merge with $.extend(true, ...) )."},{"kind":"lesson","course_slug":"jquery","course_title":"jQuery","ref":"jquery-validation-in-aspdotnet-mvc","title":"jQuery validation in ASP.NET MVC","body":"ASP.NET MVC tag helpers emit data-val- attributes from data annotations; jQuery Validation + jQuery Unobtrusive Validation read them and validate on the client. cshtml @section Scripts { <partial name=\" ValidationScriptsPartial\" / @ jquery.validate + jquery.validate.unobtrusive @ } js // Re-parse validation after injecting a form via AJAX const $form = $(\" dynamicForm\"); $form.removeData(\"validator\").removeData(\"unobtrusiveValidation\"); $.validator.unobtrusive.parse($form); // Custom client rule paired with a server-side ValidationAttribute $.validator.addMethod(\"notweekend\", value = { const d = new Date(value).getDay(); return d !== 0 && d !== 6; }); $.validator.unobtrusive.adapters.addBool(\"notweekend\"); if ($form.valid()) { / submit via AJAX / } Server-side validation must still run — client validation is just for UX."},{"kind":"lesson","course_slug":"jquery","course_title":"jQuery","ref":"performance-and-best-practices","title":"Performance and best practices","body":"- Cache selectors ( const $list = $(\" list\") ) instead of re-querying in loops. - Use ID selectors or scope searches with .find() ; avoid jQuery-only pseudo-selectors ( :visible , :even ) on large sets. - Batch DOM changes — build an HTML string/fragment and append once instead of appending in a loop. - Use event delegation for lists and tables. - Use .text() and $(\"<tag \", { text }) for user content (XSS-safe); avoid .html() with untrusted data; keep jQuery ≥ 3.5. - Prefer CSS classes over many .css() calls. - Detach elements ( .detach() ) before heavy manipulation, then re-insert. - Use $.noConflict() if another library uses $ ."},{"kind":"lesson","course_slug":"jquery","course_title":"jQuery","ref":"migrating-from-jquery-to-modern-javascript","title":"Migrating from jQuery to modern JavaScript","body":"jQuery Modern JavaScript --- --- $(\" id\") , $(\".cls\") document.getElementById(\"id\") , document.querySelectorAll(\".cls\") $(fn) document.addEventListener(\"DOMContentLoaded\", fn) or <script defer .addClass/.removeClass/.toggleClass el.classList.add/remove/toggle .text() / .html() el.textContent / el.innerHTML .attr() / .data() el.getAttribute() / el.dataset .on(\"click\", \".child\", fn) parent.addEventListener(\"click\", e = { const c = e.target.closest(\".child\"); if (c) fn(c); }) $.ajax , $.getJSON fetch() + async/await .closest() , .parent() el.closest() , el.parentElement .fadeIn() CSS transitions / Web Animations API $.each , $.map , $.extend forEach , map , Object.assign / spread Strategy: upgrade to jQuery 3.x/4.x with jQuery Migrate first; stop adding new jQuery code; replace module by module (or move UI to a framework component by component); remove plugins with framework-native or vanilla equivalents; finally drop the dependency."},{"kind":"question","course_slug":"jquery","course_title":"jQuery","ref":"863","title":"What is jQuery and why was it popular?","body":"A fast, small JavaScript library that simplifies HTML DOM traversal and manipulation, event handling, animation and AJAX with a concise, chainable API that worked consistently across browsers (especially old IE). It also had a large plugin ecosystem. Modern browsers now offer standard APIs ( querySelector , fetch , classList ), so new projects often don't need it, but many existing apps still do."},{"kind":"question","course_slug":"jquery","course_title":"jQuery","ref":"864","title":"What is the difference between `$(document).ready()` and `window.onload`?","body":"$(document).ready() (or $(fn) ) runs as soon as the DOM is parsed and ready to manipulate, before images and stylesheets finish loading; you can have many ready handlers. window.onload (or $(window).on(\"load\") ) waits until all resources, including images and iframes, have loaded — later. Use ready for DOM setup, load for things needing image dimensions."},{"kind":"question","course_slug":"jquery","course_title":"jQuery","ref":"865","title":"What is the `$` sign in jQuery? What does `noConflict` do?","body":"$ is an alias for the jQuery function, used to select elements, create elements and run code on DOM ready. Other libraries (old Prototype.js) also use $ ; jQuery.noConflict() releases $ back to them, and you can use jQuery(...) or wrap your code in (function ($) { ... })(jQuery) to keep using $ locally."},{"kind":"question","course_slug":"jquery","course_title":"jQuery","ref":"866","title":"What is the difference between `.text()`, `.html()` and `.val()`?","body":".text() gets/sets the text content (HTML-escaped, safe for user input). .html() gets/sets inner HTML (parses markup — XSS risk with untrusted data). .val() gets/sets the value of form elements (input, select, textarea)."},{"kind":"question","course_slug":"jquery","course_title":"jQuery","ref":"867","title":"What is method chaining?","body":"Most jQuery methods return the same jQuery object, so you can call multiple methods in sequence on one selection: $(\" box\").addClass(\"active\").fadeIn(200).text(\"Hello\") . It avoids repeated DOM queries and keeps code concise. Getter methods (like .text() with no args) return values and end the chain."},{"kind":"question","course_slug":"jquery","course_title":"jQuery","ref":"868","title":"What is the difference between `.on()`, `.bind()`, `.live()` and `.delegate()`?","body":".bind() attached handlers directly to existing elements; .live() attached to the document for current and future elements (removed in 1.9, slow); .delegate() attached to a chosen ancestor for matching descendants. .on() (1.7+) unified all of them: .on(\"click\", handler) for direct binding and .on(\"click\", \".child\", handler) for delegation. Use .on() / .off() only."},{"kind":"question","course_slug":"jquery","course_title":"jQuery","ref":"869","title":"What is event delegation in jQuery and why use it?","body":"Binding a handler to a static ancestor with a selector argument — $(\" table\").on(\"click\", \".delete\", fn) — so events bubbling from matching descendants are handled. It works for elements added dynamically after binding (e.g. rows inserted via AJAX) and uses one handler instead of hundreds."},{"kind":"question","course_slug":"jquery","course_title":"jQuery","ref":"870","title":"What is the difference between `.attr()` and `.prop()`?","body":".attr() works with HTML attributes as written in markup (initial values, strings). .prop() works with DOM properties reflecting the current state (booleans like checked , disabled , selected ). E.g. after a user ticks a checkbox, .prop(\"checked\") is true but .attr(\"checked\") may still be undefined. Use .prop for boolean state since jQuery 1.6."},{"kind":"question","course_slug":"jquery","course_title":"jQuery","ref":"871","title":"How do you make AJAX calls with jQuery? What are deferreds?","body":"$.ajax({ url, method, data, contentType, dataType }) or shortcuts $.get , $.post , $.getJSON , .load() . They return jqXHR objects implementing the Deferred/Promise interface: chain .done() , .fail() , .always() , .then() , and combine with $.when() for parallel calls. Since 3.0 deferreds are Promises/A+ compatible, so they can be awaited. For ASP.NET Core POSTs, send the antiforgery token in a header."},{"kind":"question","course_slug":"jquery","course_title":"jQuery","ref":"872","title":"What is the difference between `.remove()`, `.detach()` and `.empty()`?","body":".remove() removes the elements and their jQuery data and event handlers. .detach() removes elements but keeps data and handlers so they can be re-inserted later. .empty() removes only the child nodes of the selected elements, keeping the elements themselves."},{"kind":"question","course_slug":"jquery","course_title":"jQuery","ref":"873","title":"How do you write a jQuery plugin?","body":"Add a function to $.fn (jQuery.prototype), merge default options with $.extend , iterate with this.each() and return this so it's chainable, and wrap it in an IIFE receiving jQuery as $ to avoid conflicts: (function($){ $.fn.myPlugin = function(opts){ const s = $.extend({}, defaults, opts); return this.each(function(){ / ... / }); }; })(jQuery); ."},{"kind":"question","course_slug":"jquery","course_title":"jQuery","ref":"874","title":"How do you re-enable unobtrusive validation for a form loaded via AJAX?","body":"The unobtrusive adapter parses forms only on page load. After inserting new HTML, remove the cached validator data and re-parse: $form.removeData(\"validator\").removeData(\"unobtrusiveValidation\"); $.validator.unobtrusive.parse($form); . Then call $form.valid() before submitting."},{"kind":"question","course_slug":"jquery","course_title":"jQuery","ref":"875","title":"Should a new project use jQuery? How would you migrate away from it?","body":"Usually not: modern browsers have standard equivalents (querySelector, classList, fetch, closest, dataset, CSS transitions), and frameworks provide components and state management. jQuery is still reasonable for small enhancements on server-rendered pages or when a needed plugin depends on it. To migrate: upgrade with jQuery Migrate, freeze new jQuery usage via lint rules, replace utilities with native APIs, swap plugins, migrate UI screens to components incrementally, then remove the library."},{"kind":"question","course_slug":"jquery","course_title":"jQuery","ref":"876","title":"Click handlers don't work for table rows added after an AJAX refresh. Why and how to fix?","body":"The handlers were bound directly ( $(\".delete\").on(\"click\", ...) ) to rows existing at bind time; new rows don't have them. Use delegation on a static container: $(\" ordersTable\").on(\"click\", \".delete\", handler) — or rebind after each refresh (worse). Make sure the container itself isn't replaced by the AJAX refresh."},{"kind":"question","course_slug":"jquery","course_title":"jQuery","ref":"877","title":"An old site uses jQuery 1.11 and a security scan flags XSS vulnerabilities. What do you do?","body":"Upgrade to the latest jQuery 3.x/4.x (3.5+ fixed the htmlPrefilter XSS issues), using jQuery Migrate in development to find deprecated API usage and fix it (e.g. .size() , .bind() , .success() callbacks); update plugins to compatible versions; review code that passes user data into .html() , .append() with strings or $(userInput) and switch to .text() /element creation; add a Content-Security-Policy; retest the UI."},{"kind":"question","course_slug":"jquery","course_title":"jQuery","ref":"878","title":"A page with 5,000 rows is slow when appending rows in a loop with `$(\"#tbody\").append(...)`. How do you speed it up?","body":"Each .append() triggers DOM work and possibly layout. Build all rows as one HTML string (with escaped values) or a DocumentFragment and append once; cache $(\" tbody\") ; detach the table during the build; use event delegation instead of per-row handlers; better yet, paginate or virtualise the table (DataTables with server-side processing) instead of rendering 5,000 rows."},{"kind":"cheat","course_slug":"jquery","course_title":"jQuery","ref":"1","title":"Core","body":"$(fn) DOM ready · $(\"css\") select · $(el) wrap · $(\"<li \", {text}) create · chaining · implicit iteration · $.noConflict() ."},{"kind":"cheat","course_slug":"jquery","course_title":"jQuery","ref":"2","title":"Traversal","body":"find · filter · not · eq · first/last · parent/parents/closest · children/siblings/next/prev · is · has ."},{"kind":"cheat","course_slug":"jquery","course_title":"jQuery","ref":"3","title":"Manipulation","body":"text · html · val · attr · prop · data · addClass/removeClass/toggleClass · css · append/prepend/after/before · appendTo · remove/detach/empty · clone ."},{"kind":"cheat","course_slug":"jquery","course_title":"jQuery","ref":"4","title":"Events","body":"on(event, [selector], handler) · off · one · trigger · namespaces click.ns · e.preventDefault() · return false = prevent + stop."},{"kind":"cheat","course_slug":"jquery","course_title":"jQuery","ref":"5","title":"AJAX","body":"$.ajax({url, method, data, contentType, dataType}) · $.get · $.post · $.getJSON · .load() · .done/.fail/.always/.then · $.when · ajaxStart/ajaxStop ."},{"kind":"cheat","course_slug":"jquery","course_title":"jQuery","ref":"6","title":"Effects","body":"show/hide/toggle · fadeIn/fadeOut/fadeToggle · slideUp/slideDown/slideToggle · animate · stop · delay ."},{"kind":"cheat","course_slug":"jquery","course_title":"jQuery","ref":"7","title":"Versions to remember","body":"1.7 .on() · 1.9 removed .live() · 3.0 Promises/A+ · 3.5 XSS fix · 4.0 (2026) drops old IE, ES modules."},{"kind":"cheat","course_slug":"jquery","course_title":"jQuery","ref":"8","title":"Modern equivalents","body":"querySelector · classList · textContent · dataset · addEventListener + closest · fetch · CSS transitions."},{"kind":"course","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"","title":"AngularJS (1.x) — Legacy","body":"Modules, controllers, $scope, two-way data binding, directives, filters, services/factories/providers, dependency injection, digest cycle, routing, $http and promises, custom directives, components, performance and migration to Angular. AngularJS (Angular 1.x) is the original JavaScript MVC/MVVM framework from Google (2010) that popularised two-way data binding , directives and dependency injection in the browser. Important fact: AngularJS reached end of life on 31 December 2021 — Google no longer provides updates or security fixes. It is different from Angular (2+), a complete TypeScript rewrite. Interviews ask about AngularJS when a company maintains or is migrating a legacy app. Core building blocks: Concept Purpose --- --- Module ( angular.module ) Container for app parts and dependencies Controller Sets up $scope state and behaviour for a view $scope The model object that binds controller and view Directives Extend HTML: ng-model , ng-repeat , ng-if , custom directives Expressions / interpolation {{ order.total currency }} Filters Format/transform data in views Services (service, factory, provider, value, constant) Shared logic and data (singletons) Dependency injection Injector supplies $http , $scope , custom services Routing ( ngRoute or UI-Router) SPA views by URL Digest cycle Change detection by dirty checking watchers Version Year Notes --- --- --- 0.9 / 1.0 2010 / 2012 Created by Miško Hevery and Adam Abrons; 1.0 released June 2012 1.2 2013 ngAnimate , controller-as syntax, $sce strict contextual escaping 1.3 2014 One-time binding :: , dropped IE8, ngMessages , performance 1.4 2015 New router attempts, ngCookies rewrite 1.5 2016 .component() API, one-way bindings < , lifecycle hooks ( $onInit , $onChanges , $onDestroy ) — eases migration to Angular 1.6 2016 $http success/error removed, hash prefix ! default, pre-assigned bindings off 1.7 2018 Long Term Support period started (July 2018) 1.8.x 2020–2022 Final versions (1.8.3); end of LTS: 31 December 2021 After EOL, commercial extended support exists from third parties (e.g. HeroDevs \"Never-Ending Support\"). Application bootstrap lifecycle: 1. Browser loads angular.js , then app scripts. 2. On DOMContentLoaded, AngularJS finds ng-app (or you call angular.bootstrap(element, [\"app\"]) ). 3. The injector is created; module config blocks run (providers only), then run blocks. 4. Compile phase — $compile walks the DOM, collects directives, runs their compile functions (template manipulation). 5. Link phase — each directive's link function (pre-link and post-link) connects scope to DOM and sets up $watch es and event listeners. 6. Runtime — events ( ng-click , $http response, $timeout ) trigger $scope.$apply() → $digest loop : all watchers are dirty-checked repeatedly until no values change (max 10 iterations, otherwise infdig error) → DOM updated. 7. Destroy — when a scope is removed (route change, ng-if false), $destroy event fires; clean up listeners/timers. Component lifecycle hooks (1.5+): $onInit → $onChanges(changesObj) (one-way binding changes) → $doCheck → $postLink → $onDestroy . - angular.js / angular.min.js (CDN or npm angular ), modules angular-route , angular-animate , angular-messages , angular-sanitize . - UI-Router ( @uirouter/angularjs ) — state-based routing (more popular than ngRoute). - Batarang (old Chrome extension) and browser DevTools ( angular.element($0).scope() in the console). - Karma (test runner) + Jasmine + angular-mocks ( ngMock , $httpBackend ); Protractor for E2E (deprecated in 2022–2023 — use Playwright/Cypress). - Grunt/Gulp/Bower historically; webpack later. - ngUpgrade / @angular/upgrade — run AngularJS and Angular side by side during migration."},{"kind":"lesson","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"module-controller-scope-and-two-way-binding","title":"Module, controller, $scope and two-way binding","body":"html <!DOCTYPE html <html ng-app=\"shopApp\" <body ng-controller=\"OrderController as vm\" <input ng-model=\"vm.customer\" placeholder=\"Customer\" <p Hello {{ vm.customer }}</p <!-- updates as you type: two-way binding -- <ul <li ng-repeat=\"o in vm.orders filter:{status:'paid'} orderBy:'-total' track by o.id\" {{ o.id }} — {{ o.total currency:'₹' }} </li </ul <button ng-click=\"vm.add()\" ng-disabled=\"!vm.customer\" Add</button <script src=\"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.3/angular.min.js\" </script <script angular.module(\"shopApp\", []) .controller(\"OrderController\", function () { const vm = this; // \"controller as\" syntax (preferred over $scope) vm.customer = \"\"; vm.orders = [{ id: 1, total: 1200, status: \"paid\" }, { id: 2, total: 300, status: \"pending\" }]; vm.add = () = vm.orders.push({ id: vm.orders.length + 1, total: 500, status: \"paid\" }); }); </script </body </html Two-way binding : ng-model updates the model when the user types, and the view updates when the model changes (via the digest cycle). Controller-as avoids $scope prototype inheritance pitfalls (\"always have a dot in ng-model\")."},{"kind":"lesson","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"built-in-directives","title":"Built-in directives","body":"Directive Purpose --- --- ng-app Bootstraps the app ng-controller Attaches a controller ng-model Two-way binding for inputs ng-bind / {{ }} One-way output ( ng-bind avoids flicker of {{ }} ; ng-cloak hides until compiled) ng-repeat Loop ( track by for performance) ng-if Adds/removes DOM (creates a child scope) ng-show / ng-hide Toggles CSS display (element stays in DOM) ng-switch Switch-case rendering ng-class , ng-style Dynamic classes/styles ng-click , ng-change , ng-submit , ng-blur Events ng-include Include external HTML template ng-options Build <select options ng-disabled , ng-checked , ng-readonly Boolean attributes ng-form , ng-messages Forms and validation messages ng-if vs ng-show: ng-if removes the element and its scope/watchers (cheaper when hidden, re-creates on show); ng-show only hides with CSS (watchers stay active, cheaper toggling)."},{"kind":"lesson","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"expressions-and-filters","title":"Expressions and filters","body":"html {{ price qty number:2 }} {{ name uppercase }} {{ today date:'dd-MMM-yyyy' }} {{ amount currency:'₹':0 }} {{ items limitTo:5 }} {{ items orderBy:'name':true }} {{ items filter:searchText }} {{ data json }} Custom filter: js angular.module(\"shopApp\").filter(\"statusLabel\", () = status = ({ paid: \"✅ Paid\", pending: \"⏳ Pending\" }[status] status)); Filters in templates run on every digest — expensive filters on large ng-repeat lists hurt performance; pre-compute in the controller instead."},{"kind":"lesson","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"angularjs-1-x-project-folder-structure-with-sample-files","title":"AngularJS (1.x) project folder structure — with sample files","body":"AngularJS apps (2010–2021) usually have no CLI; files are loaded by <script tags or bundled with Gulp/Grunt/webpack. Two common layouts: by type (small apps) and by feature (recommended by the John Papa style guide). text shop-web/ (often inside an ASP.NET MVC 5 project's Scripts/app folder) ├── index.html ng-app=\"shopApp\", <div ng-view , script tags ├── app/ │ ├── app.module.js angular.module('shopApp', ['ngRoute']) │ ├── app.config.js $routeProvider routes, $httpProvider interceptors │ ├── app.constants.js API base URL │ ├── core/ │ │ ├── auth.interceptor.js adds Authorization header │ │ └── logger.service.js │ ├── products/ feature folder │ │ ├── products.controller.js ProductsController (controllerAs syntax) │ │ ├── products.service.js productService — $http calls │ │ ├── products.html view template │ │ └── product-card.directive.js (or .component.js in 1.5+) │ └── orders/ … ├── content/css/site.css ├── lib/angular/angular.min.js, angular-route.min.js (or node modules + bundler) └── tests/ (Karma + Jasmine) js // app/app.module.js angular.module('shopApp', ['ngRoute']); // app/app.config.js angular.module('shopApp') .constant('API URL', '/api') .config(['$routeProvider', function ($routeProvider) { $routeProvider .when('/products', { templateUrl: 'app/products/products.html', controller: 'ProductsController', controllerAs: 'vm' }) .otherwise({ redirectTo: '/products' }); }]); // app/products/products.controller.js angular.module('shopApp').controller('ProductsController', ['productService', function (productService) { var vm = this; vm.products = []; vm.loading = true; productService.getAll() .then(function (products) { vm.products = products; }) .catch(function () { vm.error = 'Could not load products'; }) .finally(function () { vm.loading = false; }); }]); html <!-- index.html -- <html ng-app=\"shopApp\" <body <div ng-view </div <script src=\"lib/angular/angular.min.js\" </script <script src=\"lib/angular/angular-route.min.js\" </script <script src=\"app/app.module.js\" </script <script src=\"app/app.config.js\" </script <script src=\"app/products/products.service.js\" </script <script src=\"app/products/products.controller.js\" </script </body </html <!-- app/products/products.html -- <p ng-if=\"vm.loading\" Loading…</p <ul <li ng-repeat=\"p in vm.products track by p.id\" {{ p.name }} — {{ p.price currency:'₹' }}</li </ul Script order matters: the module file first, then everything that registers into it."},{"kind":"lesson","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"connecting-angularjs-to-sql-server-through-aspdotnet-web-api","title":"Connecting AngularJS to SQL Server (through ASP.NET Web API)","body":"The classic stack: AngularJS → ASP.NET Web API 2 (or MVC 5 JSON actions) → ADO.NET/EF6 → SQL Server , often hosted together in one IIS site. csharp // ASP.NET Web API 2 (.NET Framework) — Controllers/ProductsController.cs public class ProductsController : ApiController { private readonly string cs = ConfigurationManager.ConnectionStrings[\"Shop\"].ConnectionString; // Web.config [HttpGet, Route(\"api/products\")] public IHttpActionResult Get() { var list = new List<object (); using (var conn = new SqlConnection( cs)) using (var cmd = new SqlCommand(\"SELECT Id, Name, Price FROM dbo.Products ORDER BY Name\", conn)) { conn.Open(); using (var r = cmd.ExecuteReader()) while (r.Read()) list.Add(new { id = r.GetInt32(0), name = r.GetString(1), price = r.GetDecimal(2) }); } return Ok(list); } } xml <!-- Web.config -- <connectionStrings <add name=\"Shop\" connectionString=\"Data Source=.;Initial Catalog=Shop;Integrated Security=True\" providerName=\"System.Data.SqlClient\" / </connectionStrings js // app/products/products.service.js angular.module('shopApp').factory('productService', ['$http', 'API URL', function ($http, API URL) { return { getAll: function () { return $http.get(API URL + '/products').then(function (res) { return res.data; }); }, create: function (p) { return $http.post(API URL + '/products', p).then(function (res) { return res.data; }); } }; }]); Same origin (AngularJS files served by the same IIS site as the API) means no CORS configuration is needed; otherwise enable CORS in Web API ( config.EnableCors() ). When migrating, the Web API backend can usually be kept while the AngularJS front end is rewritten in Angular or React."},{"kind":"lesson","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"service-vs-factory-vs-provider-vs-value-vs-constant","title":"Service vs factory vs provider vs value vs constant","body":"All create singletons registered with the injector. js const app = angular.module(\"shopApp\", []); app.constant(\"API URL\", \"/api\"); // available in config blocks app.value(\"pageSize\", 20); // simple value (not in config) app.factory(\"orderApi\", function ($http, API URL) { // factory: returns an object you build return { list: () = $http.get( ${API URL}/orders ).then(r = r.data), save: order = $http.post( ${API URL}/orders , order).then(r = r.data), }; }); app.service(\"cart\", function () { // service: constructor function, called with 'new' this.items = []; this.add = item = this.items.push(item); }); app.provider(\"theme\", function () { // provider: configurable before the app runs let color = \"blue\"; this.setColor = c = (color = c); // used in config() this.$get = () = ({ color: () = color }); // the actual service }); app.config(themeProvider = themeProvider.setColor(\"green\")); Registered with Injectable in config? Use --- --- --- --- constant value Yes Settings needed during config value value No Simple values factory function returning an object No Most common for logic/API wrappers service constructor ( new ) No Class-style services provider object with $get Provider yes , service no Configurable reusable services"},{"kind":"lesson","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"dependency-injection-and-minification","title":"Dependency injection and minification","body":"AngularJS reads function parameter names to know what to inject. Minifiers rename parameters, which breaks DI — use an annotation style: js // Inline array annotation (most common) app.controller(\"OrderController\", [\"$scope\", \"orderApi\", function ($scope, orderApi) { / ... / }]); // $inject property function OrderController(orderApi) { / ... / } OrderController.$inject = [\"orderApi\"]; // Build-time: ng-annotate / babel-plugin-angularjs-annotate; strict mode: <html ng-app=\"app\" ng-strict-di"},{"kind":"lesson","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"http-promises-and-q","title":"$http, promises and $q","body":"js app.factory(\"productApi\", [\"$http\", \"$q\", function ($http, $q) { const cache = {}; return { get(id) { if (cache[id]) return $q.resolve(cache[id]); // $q promise, integrates with the digest return $http.get( /api/products/${id} , { timeout: 10000 }) .then(res = (cache[id] = res.data)) .catch(err = $q.reject(err.status === 404 ? \"Not found\" : \"Server error\")); }, all: ids = $q.all(ids.map(id = this.get(id))), }; }]); // Interceptor: add auth header and handle 401 globally app.factory(\"authInterceptor\", [\"$q\", \"$window\", function ($q, $window) { return { request: config = { config.headers.Authorization = Bearer ${$window.sessionStorage.token} ; return config; }, responseError: rejection = { if (rejection.status === 401) $window.location = \"/login\"; return $q.reject(rejection); }, }; }]); app.config([\"$httpProvider\", $httpProvider = $httpProvider.interceptors.push(\"authInterceptor\")]); $http 's .success() / .error() were removed in 1.6 — use .then() . Use $q , $timeout , $interval (not native promises/setTimeout) so changes trigger a digest — or call $scope.$applyAsync() ."},{"kind":"lesson","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"the-digest-cycle-watch-and-apply","title":"The digest cycle, $watch and $apply","body":"- Each binding ( {{ }} , ng-model , $watch ) registers a watcher . - $digest() loops over all watchers on a scope and its children, comparing current vs last values ( dirty checking ); if anything changed, it runs listeners and loops again until stable (max 10 → 10 $digest() iterations reached error). - $apply(fn) runs fn then $rootScope.$digest() — needed when changing the model outside AngularJS (jQuery events, setTimeout , third-party callbacks). - $watch(expr, listener) — reference/value check; $watchCollection — shallow array/object; $watch(expr, fn, true) — deep (expensive). - $scope.$on/$emit/$broadcast — events up ( $emit ) or down ( $broadcast ) the scope tree. js $scope.$watch(() = vm.filter, (newVal, oldVal) = { if (newVal !== oldVal) vm.reload(); }); someJQueryWidget.on(\"change\", value = $scope.$apply(() = (vm.value = value))); const off = $rootScope.$on(\"cart:updated\", handler); $scope.$on(\"$destroy\", off); // always unregister Rule of thumb: keep watchers under ~2,000 per page for smooth performance."},{"kind":"lesson","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"custom-directives-and-components","title":"Custom directives and components","body":"js // Component (1.5+) — preferred: isolated scope, controller-as, lifecycle hooks app.component(\"orderCard\", { bindings: { order: \"<\", onSelect: \"&\" }, // < one-way, @ string, & callback, = two-way (avoid) template: <div class=\"card\" ng-click=\"$ctrl.onSelect({ id: $ctrl.order.id })\" {{ $ctrl.order.id }} — {{ $ctrl.order.total currency }} </div , controller: function () { this.$onInit = () = { / init / }; this.$onChanges = changes = { if (changes.order) { / react / } }; this.$onDestroy = () = { / cleanup / }; }, }); // <order-card order=\"o\" on-select=\"vm.open(id)\" </order-card // Directive — for DOM manipulation / attribute behaviour app.directive(\"autoFocus\", [\"$timeout\", function ($timeout) { return { restrict: \"A\", // E element, A attribute, C class, M comment link(scope, element) { $timeout(() = element[0].focus()); }, }; }]); Scope options for directives: scope: false (share parent), scope: true (child scope, prototypal inheritance), scope: {} ( isolated ). transclude: true lets a directive wrap content ( <ng-transclude ). require accesses other directive controllers (e.g. ngModel )."},{"kind":"lesson","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"routing-with-ngroute-and-ui-router","title":"Routing with ngRoute and UI-Router","body":"js angular.module(\"shopApp\", [\"ngRoute\"]) .config([\"$routeProvider\", \"$locationProvider\", function ($routeProvider, $locationProvider) { $routeProvider .when(\"/orders\", { template: \"<order-list </order-list \" }) .when(\"/orders/:id\", { templateUrl: \"views/order-detail.html\", controller: \"OrderDetailController as vm\", resolve: { order: [\"$route\", \"orderApi\", ($route, api) = api.get($route.current.params.id)] }, }) .otherwise(\"/orders\"); $locationProvider.html5Mode(true); // URLs without ! (needs server rewrite + <base href=\"/\" ) }]); UI-Router uses states ( $stateProvider.state(\"orders.detail\", {...}) ), nested views and named views — better for complex apps. resolve loads data before the route activates."},{"kind":"lesson","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"forms-and-validation","title":"Forms and validation","body":"html <form name=\"orderForm\" ng-submit=\"orderForm.$valid && vm.save()\" novalidate <input name=\"email\" type=\"email\" ng-model=\"vm.email\" required <div ng-messages=\"orderForm.email.$error\" ng-if=\"orderForm.email.$touched\" <p ng-message=\"required\" Email is required</p <p ng-message=\"email\" Enter a valid email</p </div <button ng-disabled=\"orderForm.$invalid\" Save</button </form Form/field states: $pristine/$dirty , $valid/$invalid , $touched/$untouched , $submitted , $error . Custom validators via ngModel.$validators / $asyncValidators in a directive."},{"kind":"lesson","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"performance-and-migration-to-angular","title":"Performance and migration to Angular","body":"Performance: reduce watchers (one-time binding :: , avoid deep watches), track by in ng-repeat , ng-if over ng-show for heavy hidden sections, avoid filters in large repeats, paginate/virtualise lists, $applyAsync / $httpProvider.useApplyAsync(true) , disable debug info in production ( $compileProvider.debugInfoEnabled(false) ), $scope.$digest() locally instead of global $apply in hot paths. Migration paths: 1. Prepare: upgrade to 1.8, use components + controller-as + one-way bindings, TypeScript and a bundler, remove $scope soup. 2. Hybrid app with ngUpgrade ( UpgradeModule ): bootstrap both frameworks; downgrade new Angular components/services to use in AngularJS, upgrade AngularJS services to inject in Angular; migrate feature by feature, route by route. 3. Or rewrite incrementally behind a reverse proxy / micro-frontends (different routes served by different apps). 4. Remove AngularJS when the last feature moves. Because AngularJS is EOL, also consider migrating to React or Vue; the strategy (strangler pattern by route/feature) is the same."},{"kind":"question","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"879","title":"What is AngularJS and how is it different from Angular?","body":"AngularJS (1.x, 2010) is a JavaScript MVC/MVVM framework using controllers, $scope , two-way binding through dirty-checking digest cycles and directives; it reached end of life on 31 Dec 2021. Angular (2+, 2016) is a complete rewrite in TypeScript with components, a hierarchical DI system, RxJS, a CLI, AOT compilation, zone.js/signals-based change detection, mobile-friendly performance and regular releases. There's no direct upgrade path; migration is a rewrite (often incremental with ngUpgrade)."},{"kind":"question","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"880","title":"What is two-way data binding in AngularJS?","body":"Synchronisation between the model and the view in both directions: ng-model updates the scope when the user changes input, and any change to the scope model updates the view during the next digest cycle. It's implemented with watchers and dirty checking. Convenient, but many two-way bindings slow down large apps."},{"kind":"question","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"881","title":"What are directives? Name some built-in ones.","body":"Directives are markers on DOM elements (attributes, elements, classes, comments) that tell the AngularJS compiler to attach behaviour or transform the DOM. Built-in: ng-app , ng-controller , ng-model , ng-bind , ng-repeat , ng-if , ng-show/ng-hide , ng-click , ng-class , ng-include , ng-switch , ng-options , ng-submit . You can write custom directives and components."},{"kind":"question","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"882","title":"What is $scope? What is $rootScope?","body":"$scope is the object that glues a controller to its view — properties and functions on it are available in the template. Scopes form a hierarchy mirroring the DOM, with prototypal inheritance (child scopes from ng-repeat , ng-if , ng-include ). $rootScope is the top-level scope of the app; every other scope descends from it. Avoid storing state on $rootScope — use services."},{"kind":"question","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"883","title":"What is the difference between ng-if and ng-show?","body":"ng-if adds or removes the element (and creates/destroys its child scope and watchers) based on the condition. ng-show / ng-hide keep the element in the DOM and toggle display: none via a CSS class, so its watchers remain active. Use ng-if for heavy content that's rarely shown, ng-show for frequent toggling of light content."},{"kind":"question","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"884","title":"What is the difference between service, factory and provider?","body":"All produce injectable singletons. A factory is a function whose returned value is the service. A service is a constructor function instantiated with new (methods on this ). A provider is the most configurable: an object with a $get method, plus configuration methods available in config() blocks before the app runs (factory and service are shorthands built on providers). Constants are injectable in config; values are not."},{"kind":"question","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"885","title":"Explain the digest cycle. When do you need $apply?","body":"When something inside AngularJS's context happens (ng-click, $http, $timeout), AngularJS calls $apply → $digest , which dirty-checks all watchers, runs listeners for changed values, and repeats until nothing changes (max 10 loops), then the view reflects the model. If you change the model outside AngularJS (native setTimeout , jQuery plugin callbacks, WebSocket events), AngularJS doesn't know, so wrap the change in $scope.$apply() (or use $timeout / $applyAsync )."},{"kind":"question","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"886","title":"How does dependency injection work in AngularJS? What breaks it during minification?","body":"The $injector looks at a function's parameter names (or explicit annotations) and supplies registered services. Minification renames parameters ( $http → a ), so implicit DI breaks. Fix with inline array annotation [\"$http\", function ($http) {}] , the $inject property, build tools like ng-annotate, and enable ng-strict-di to catch missing annotations."},{"kind":"question","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"887","title":"What are the scope binding types in a component/directive (@, =, <, &)?","body":"@ — one-way string/interpolated attribute value. = — two-way binding (expensive, avoid in components). < — one-way binding of an expression (1.5+, preferred for inputs). & — callback expression bound to the parent's function, used for outputs ( on-select=\"vm.open(id)\" invoked as $ctrl.onSelect({ id: 5 }) )."},{"kind":"question","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"888","title":"What is the difference between $emit and $broadcast?","body":"Both dispatch scope events. $emit sends an event upwards from the current scope through its parents to $rootScope . $broadcast sends it downwards to all child scopes. Listen with $on . Overusing events makes data flow hard to follow — prefer services or component bindings; always deregister $rootScope.$on listeners on $destroy ."},{"kind":"question","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"889","title":"What are filters? How do you create a custom filter?","body":"Filters format data in templates ( currency , date , uppercase , limitTo , orderBy , filter , json , number ) and can be chained with . Create one with module.filter(\"name\", () = input = transformed) . Filters in templates execute on every digest, so keep them cheap."},{"kind":"question","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"890","title":"How do you improve the performance of a slow AngularJS app?","body":"Reduce the number of watchers (one-time bindings :: , fewer two-way bindings, avoid deep $watch ), use track by in ng-repeat , paginate or virtualise large lists, prefer ng-if for hidden heavy sections, move filters out of templates, debounce ng-model ( ng-model-options=\"{ debounce: 300 }\" ), use $applyAsync and $httpProvider.useApplyAsync , disable debug info in production, and profile digest time with DevTools."},{"kind":"question","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"891","title":"How would you migrate a large AngularJS app to Angular?","body":"Prepare the codebase (latest 1.8, components with one-way bindings, controller-as, services instead of $rootScope , TypeScript, module bundler). Then create a hybrid app with @angular/upgrade (UpgradeModule): Angular bootstraps and boots AngularJS; migrate leaf components and services first, downgrading Angular components for use in AngularJS templates and upgrading AngularJS services for Angular. Move routes one by one (or split by routes behind a proxy), test continuously, and finally remove AngularJS. Budget for the fact that AngularJS is EOL and has no security patches."},{"kind":"question","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"892","title":"You change a model value inside a jQuery datepicker callback but the view doesn't update. Why?","body":"The callback runs outside AngularJS's digest, so no dirty check happens. Wrap the update in $scope.$apply(() = vm.date = value) (or $scope.$applyAsync ), or better, wrap the datepicker in a custom directive that uses ngModel.$setViewValue inside $apply . Avoid calling $apply when a digest is already in progress ( $digest already in progress error) — $applyAsync or $timeout avoids that."},{"kind":"question","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"893","title":"An ng-repeat over 3,000 rows makes the page freeze on every keystroke in a search box. Fix it.","body":"Each keystroke triggers a digest over thousands of watchers plus filter re-evaluation. Fixes: debounce the input with ng-model-options=\"{ debounce: 300 }\" ; filter in the controller once per change instead of a template filter; add track by row.id ; use one-time bindings ( :: ) for row fields that don't change; paginate or virtualise (e.g. ui-grid or a virtual-repeat directive); reduce per-row bindings and directives."},{"kind":"question","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"894","title":"Your company still runs a business-critical AngularJS app. What risks do you raise and what plan do you propose?","body":"Risks: no security patches since Dec 2021 (compliance/pen-test findings), dwindling developer pool, incompatible modern libraries, browser changes. Plan: short-term — upgrade to 1.8.3, add a strict Content-Security-Policy, review $sce / ng-bind-html usage, consider commercial extended support; medium-term — incremental migration (Angular via ngUpgrade, or React/Vue via micro-frontends/route-by-route strangler), starting with the most-changed or riskiest screens; keep feature parity tests (Playwright) as a safety net."},{"kind":"cheat","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"1","title":"Building blocks","body":"module · controller (controller-as vm ) · $scope / $rootScope · directives · components (1.5+) · filters · services · DI · routing · digest cycle."},{"kind":"cheat","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"2","title":"Directives","body":"ng-app · ng-controller · ng-model · ng-bind · ng-repeat (track by) · ng-if · ng-show/hide · ng-switch · ng-class · ng-click · ng-submit · ng-options · ng-include · ng-cloak · ng-messages."},{"kind":"cheat","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"3","title":"Services","body":"constant (config-safe) · value · factory (returns object) · service ( new ) · provider ( $get , configurable)."},{"kind":"cheat","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"4","title":"Bindings","body":"@ string · < one-way · = two-way · & callback. Component hooks: $onInit , $onChanges , $doCheck , $postLink , $onDestroy ."},{"kind":"cheat","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"5","title":"Digest","body":"watchers + dirty checking · $apply (outside AngularJS) · $applyAsync · $watch / $watchCollection / deep watch · max 10 iterations · $emit up / $broadcast down / $on ."},{"kind":"cheat","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"6","title":"Key facts","body":"1.0 2012 · 1.5 components · 1.6 removed .success/.error · 1.8.3 last · EOL 31 Dec 2021 · migrate with ngUpgrade."},{"kind":"cheat","course_slug":"angularjs","course_title":"AngularJS (1.x) — Legacy","ref":"7","title":"Performance","body":":: one-time binding · track by · fewer watchers · debounce ng-model · no heavy template filters · debugInfoEnabled(false) ."},{"kind":"course","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"","title":"Angular (2 → 21)","body":"Angular CLI, standalone components, templates and new control flow, data binding, directives and pipes, signals, services and DI, routing and guards, forms, HttpClient and interceptors, RxJS, change detection and zoneless, lifecycle hooks, state management, testing and performance. Angular is Google's full-featured, TypeScript-based framework for building single-page applications. It includes everything out of the box: components, templates, dependency injection, router, forms, HTTP client, testing utilities, build tooling (Angular CLI), server-side rendering and internationalisation. Key characteristics: - Component-based — UI built from components (TypeScript class + HTML template + styles). - TypeScript-first with decorators ( @Component , @Injectable , @Input ...). - Dependency injection built in, hierarchical. - RxJS observables for async streams; Signals (v16+) for fine-grained reactivity. - Opinionated structure — great for large enterprise teams. - Standalone components (default since v19) replace NgModules for most apps. Angular ≠ AngularJS: Angular (2016+) is a complete rewrite of AngularJS (1.x, EOL Dec 2021). Version Date Highlights --- --- --- 2 Sep 2016 Rewrite: components, TypeScript, RxJS, DI 4 Mar 2017 Skipped v3 (router package was already v3); ngIf; else , smaller builds 5–8 2017–2019 HttpClient (4.3/5), CLI ng update & Angular Elements (6), CLI prompts (7), differential loading (8) 9 Feb 2020 Ivy compiler/renderer by default — smaller bundles, faster builds 12–13 2021 View Engine deprecated then removed; IE11 support dropped (13) 14 Jun 2022 Standalone components (preview), strictly typed reactive forms 15 Nov 2022 Standalone APIs stable, directive composition, NgOptimizedImage 16 May 2023 Signals (preview), takeUntilDestroyed , required inputs, non-destructive hydration 17 Nov 2023 Built-in control flow ( @if , @for , @switch ), deferrable views ( @defer ), Vite + esbuild dev server/builder, new docs angular.dev 18 May 2024 Zoneless change detection (experimental), Material 3, event replay, @let (18.1) 19 Nov 2024 Standalone by default , linkedSignal , resource() API, incremental hydration, HMR 20 May 2025 Signal APIs stable ( effect , linkedSignal , toSignal ), zoneless promoted, ngIf/ ngFor/ ngSwitch deprecated in favour of control flow 21 Nov 2025 Zoneless by default for new apps, experimental Signal Forms , Vitest as default test runner, Angular Aria (accessible headless components) Release cadence: a major version roughly every 6 months (May and November). Each major gets 6 months active support + 12 months LTS = 18 months . Upgrade with ng update (guide at angular.dev/update-guide). Application bootstrap: main.ts → bootstrapApplication(AppComponent, appConfig) (standalone) or platformBrowserDynamic().bootstrapModule(AppModule) (NgModule) → providers registered (router, HttpClient, zoneless/zone.js change detection) → root component rendered into <app-root → router activates the initial route. Component lifecycle hooks (in order): Hook When --- --- constructor Class instantiated; DI happens (don't do heavy work or touch inputs) ngOnChanges(changes) Before ngOnInit and whenever an @Input reference changes ngOnInit Once, after first ngOnChanges — fetch data, initialise ngDoCheck Every change detection run — custom change detection (use sparingly) ngAfterContentInit / ngAfterContentChecked After projected content ( <ng-content ) is initialised / checked ngAfterViewInit / ngAfterViewChecked After the component's view and child views are initialised / checked — @ViewChild available ngOnDestroy Before destroy — unsubscribe, clear timers Newer alternatives: afterNextRender / afterEveryRender (DOM work after rendering), DestroyRef + takeUntilDestroyed() for cleanup, signal inputs instead of ngOnChanges . Change detection lifecycle: an event (click, HTTP response, timer) → with zone.js , Angular detects that async work finished and runs change detection from the root down (all components with Default strategy; OnPush components only if inputs changed, an event fired in them, an async pipe emitted or a signal they read changed) → DOM updated. Zoneless (default for new apps in v21): change detection is scheduled by signals, markForCheck , events and the async pipe — no zone.js. Tool Use --- --- Angular CLI ( ng ) new, generate, serve, build, test, update, add VS Code + Angular Language Service Template IntelliSense and errors Angular DevTools (browser extension) Component tree, profiler, signals graph RxJS Observables and operators Angular Material / CDK, PrimeNG, ng-zorro UI component libraries NgRx (Store, Effects, Signal Store), NGXS, Akita/Elf State management Vitest / Karma + Jasmine (older), Jest Unit tests Playwright, Cypress E2E (Protractor deprecated) Nx Monorepos and build tooling Angular SSR ( @angular/ssr ) Server-side rendering, hydration, prerendering ESLint ( angular-eslint ), Prettier Lint/format"},{"kind":"lesson","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"angular-cli-and-project-structure","title":"Angular CLI and project structure","body":"bash npm install -g @angular/cli ng new shop --style=scss --ssr=false cd shop ng serve -o dev server on http://localhost:4200 ng generate component orders/order-list ng g c ng generate service core/order ng g s ng generate pipe shared/status-label ng generate guard core/auth ng build production build by default → dist/ ng test ng update @angular/core @angular/cli upgrade versions ng add @angular/material src/ main.ts bootstrapApplication(App, appConfig) app/ app.config.ts providers: provideRouter(routes), provideHttpClient(), ... app.routes.ts route definitions app.ts / app.html root component orders/ feature folder (components, services) styles.scss angular.json workspace/build configuration tsconfig.json"},{"kind":"lesson","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"components-templates-and-data-binding","title":"Components, templates and data binding","body":"ts import { Component, input, output, signal, computed } from \"@angular/core\"; import { CurrencyPipe } from \"@angular/common\"; @Component({ selector: \"app-order-card\", imports: [CurrencyPipe], // standalone: import what the template uses template: <div class=\"card\" [class.paid]=\"order().status === 'paid'\" <h3 {{ order().id }} — {{ order().customer }}</h3 <p {{ order().total currency:'INR' }}</p <input [value]=\"note()\" (input)=\"note.set($any($event.target).value)\" / <button (click)=\"select.emit(order().id)\" [disabled]=\"busy()\" Open</button </div , styleUrl: \"./order-card.scss\", }) export class OrderCard { order = input.required<Order (); // signal input (v17.1+) select = output<number (); // output (v17.3+) note = signal(\"\"); busy = signal(false); isBig = computed(() = this.order().total 10000); } Binding Syntax Direction --- --- --- Interpolation {{ value }} Component → view Property binding [disabled]=\"isBusy\" Component → view Attribute/class/style [attr.aria-label] , [class.active] , [style.width.px] Component → view Event binding (click)=\"save()\" View → component Two-way binding [(ngModel)]=\"name\" or [(value)] with model() Both (\"banana in a box\") Classic decorators still work: @Input() , @Output() select = new EventEmitter<number () ."},{"kind":"lesson","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"built-in-control-flow-directives-and-pipes","title":"Built-in control flow, directives and pipes","body":"html @if (orders().length 0) { <ul @for (o of orders(); track o.id; let i = $index) { <li {{ i + 1 }}. {{ o.customer }} — {{ o.total currency:'INR' }}</li } @empty { <li No orders</li } </ul } @else { <p Loading…</p } @switch (status()) { @case ('paid') { <span class=\"ok\" Paid</span } @default { <span Pending</span } } @defer (on viewport) { <app-sales-chart / } @placeholder { <p Chart loads when visible</p } @let total = order().qty order().price; Legacy structural directives (deprecated in v20, still common in existing code): ngIf=\"cond; else loading\" , ngFor=\"let o of orders; trackBy: trackById\" , [ngSwitch] . Attribute directives: [ngClass] , [ngStyle] , [(ngModel)] . Pipes transform values in templates: date , currency , number , percent , uppercase , lowercase , titlecase , json , slice , keyvalue , async (subscribes to an Observable/Promise and unsubscribes automatically). Pipes are pure by default (re-run only when inputs change). ts @Pipe({ name: \"statusLabel\" }) export class StatusLabelPipe implements PipeTransform { transform(status: string): string { return { paid: \"Paid\", pending: \"Pending\" }[status] ?? status; } }"},{"kind":"lesson","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"angular-workspace-folder-structure-explained-with-sample-files","title":"Angular workspace folder structure explained — with sample files","body":"A real Angular 17+ application (standalone components, no NgModules) organised by core / shared / features : text shop-ui/ ├── angular.json workspace config: build/serve/test targets, assets, styles, budgets ├── package.json · tsconfig.json · tsconfig.app.json ├── proxy.conf.json dev-server proxy: /api → https://localhost:7001 (avoids CORS in dev) ├── public/ static assets copied to the build (favicon, images) └── src/ ├── index.html <app-root </app-root ├── main.ts bootstrapApplication(App, appConfig) ├── styles.scss global styles ├── environments/ │ ├── environment.ts { production: false, apiUrl: '/api' } │ └── environment.prod.ts { production: true, apiUrl: 'https://api.shop.com/api' } └── app/ ├── app.ts / app.html / app.scss root component (shell: header, <router-outlet ) ├── app.config.ts providers: router, HttpClient + interceptors, animations ├── app.routes.ts top-level routes with lazy-loaded features ├── core/ singletons used once app-wide │ ├── interceptors/auth.interceptor.ts, error.interceptor.ts │ ├── guards/auth.guard.ts │ ├── services/auth.service.ts │ └── layout/header/header.ts ├── shared/ reusable dumb components, pipes, directives │ ├── components/spinner/spinner.ts │ └── pipes/inr-currency.pipe.ts └── features/ ├── products/ │ ├── products.routes.ts feature routes (lazy) │ ├── data/product.service.ts HTTP calls │ ├── data/product.model.ts interfaces │ ├── product-list/product-list.ts + .html + .scss + .spec.ts │ └── product-detail/product-detail.ts └── orders/ … ts // src/app/app.config.ts export const appConfig: ApplicationConfig = { providers: [ provideZonelessChangeDetection(), // Angular 20+ (zoneless) provideRouter(routes, withComponentInputBinding()), provideHttpClient(withInterceptors([authInterceptor, errorInterceptor])), ], }; // src/app/app.routes.ts export const routes: Routes = [ { path: '', redirectTo: 'products', pathMatch: 'full' }, { path: 'products', loadChildren: () = import('./features/products/products.routes').then((m) = m.PRODUCT ROUTES) }, { path: 'orders', canActivate: [authGuard], loadChildren: () = import('./features/orders/orders.routes').then((m) = m.ORDER ROUTES) }, { path: ' ', loadComponent: () = import('./shared/components/not-found/not-found').then((m) = m.NotFound) }, ]; // src/app/features/products/products.routes.ts export const PRODUCT ROUTES: Routes = [ { path: '', component: ProductList }, { path: ':id', component: ProductDetail }, // :id bound to an input() via withComponentInputBinding ]; Rules of thumb: core = provided once (interceptors, guards, auth), shared = imported by many features (no business logic), features = lazy-loaded business areas; one component per folder with its template, styles and spec."},{"kind":"lesson","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"connecting-angular-to-sql-server-through-an-aspdotnet-core-api","title":"Connecting Angular to SQL Server (through an ASP.NET Core API)","body":"The usual enterprise stack: Angular → ASP.NET Core Web API → EF Core/Dapper → SQL Server . csharp // ASP.NET Core API — ProductsController.cs (EF Core) [ApiController, Route(\"api/[controller]\")] public class ProductsController(ShopDbContext db) : ControllerBase { [HttpGet] public async Task<IEnumerable<ProductDto Get(CancellationToken ct) = await db.Products.AsNoTracking().OrderBy(p = p.Name).Select(p = new ProductDto(p.Id, p.Name, p.Price)).ToListAsync(ct); } // Program.cs: builder.Services.AddDbContext<ShopDbContext (o = o.UseSqlServer(builder.Configuration.GetConnectionString(\"Shop\"))); // appsettings.json: \"ConnectionStrings\": { \"Shop\": \"Server=.;Database=Shop;Trusted Connection=True;TrustServerCertificate=True\" } ts // src/app/features/products/data/product.model.ts export interface Product { id: number; name: string; price: number; } // src/app/features/products/data/product.service.ts @Injectable({ providedIn: 'root' }) export class ProductService { private http = inject(HttpClient); private base = ${environment.apiUrl}/products ; list() { return this.http.get<Product[] (this.base); } get(id: number) { return this.http.get<Product ( ${this.base}/${id} ); } create(p: Omit<Product, 'id' ) { return this.http.post<Product (this.base, p); } } // src/app/features/products/product-list/product-list.ts @Component({ selector: 'app-product-list', template: @if (products.isLoading()) { <p Loading…</p } @else if (products.error()) { <p Could not load products.</p } @else { <ul @for (p of products.value(); track p.id) { <li {{ p.name }} — {{ p.price currency:'INR' }}</li }</ul } , imports: [CurrencyPipe], }) export class ProductList { private service = inject(ProductService); products = rxResource({ stream: () = this.service.list() }); // signal-based resource (Angular 19+/20) } json // proxy.conf.json — referenced from angular.json \"serve\" options (\"proxyConfig\": \"proxy.conf.json\") { \"/api\": { \"target\": \"https://localhost:7001\", \"secure\": false, \"changeOrigin\": true } } Production: build with ng build , host the dist/ files on IIS/Static Web Apps/CDN (SPA fallback rewrite to index.html ), and either serve the API on the same domain or enable CORS for the Angular origin. The connection string lives only in the API (appsettings / Key Vault), never in Angular environment files — those ship to the browser."},{"kind":"lesson","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"services-and-dependency-injection","title":"Services and dependency injection","body":"ts @Injectable({ providedIn: \"root\" }) // app-wide singleton, tree-shakable export class OrderService { private http = inject(HttpClient); // inject() function (or constructor injection) list() { return this.http.get<Order[] (\"/api/orders\"); } } // Component-level provider: a new instance per component instance @Component({ selector: \"app-wizard\", providers: [WizardState], template: \"\" }) export class Wizard { state = inject(WizardState); } // Injection tokens for non-class values export const API URL = new InjectionToken<string (\"API URL\"); // app.config.ts: providers: [{ provide: API URL, useValue: \"https://api.example.com\" }] Provider recipes: useClass , useValue , useFactory , useExisting . Hierarchical injectors : environment (root/platform/route) injectors and element (component) injectors — Angular looks up from the component to its ancestors to the root. Resolution modifiers: { optional: true } , { self: true } , { skipSelf: true } , { host: true } ."},{"kind":"lesson","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"httpclient-interceptors-and-error-handling","title":"HttpClient, interceptors and error handling","body":"ts // app.config.ts export const appConfig: ApplicationConfig = { providers: [ provideRouter(routes, withComponentInputBinding()), provideHttpClient(withInterceptors([authInterceptor, errorInterceptor])), ], }; export const authInterceptor: HttpInterceptorFn = (req, next) = { const token = inject(AuthService).token(); return next(token ? req.clone({ setHeaders: { Authorization: Bearer ${token} } }) : req); }; export const errorInterceptor: HttpInterceptorFn = (req, next) = next(req).pipe( retry({ count: 2, delay: 500 }), // only for idempotent GETs in practice catchError((err: HttpErrorResponse) = { if (err.status === 401) inject(Router).navigate([\"/login\"]); return throwError(() = err); }), ); // In a service getOrder(id: number) { return this.http.get<Order ( /api/orders/${id} , { params: { include: \"lines\" } }); } HttpClient returns cold observables — nothing happens until you subscribe (or use the async pipe / toSignal ). Newer: httpResource() (signal-based HTTP resource, v19.2+)."},{"kind":"lesson","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"rxjs-essentials","title":"RxJS essentials","body":"ts search = new FormControl(\"\"); results$ = this.search.valueChanges.pipe( debounceTime(300), map(v = v?.trim() ?? \"\"), distinctUntilChanged(), filter(term = term.length = 2), switchMap(term = this.api.search(term).pipe(catchError(() = of([])))), // cancels the previous request shareReplay({ bufferSize: 1, refCount: true }), ); Operator Use --- --- map , filter , tap Transform, filter, side effects switchMap Switch to a new inner observable, cancel the previous (search, route params) mergeMap Run inner observables concurrently (fire-and-forget saves) concatMap Run in order , one at a time (queue of writes) exhaustMap Ignore new values while busy (login button double-click) combineLatest , forkJoin , zip , withLatestFrom Combine streams ( forkJoin = like Promise.all, completes once) debounceTime , throttleTime , distinctUntilChanged Rate control catchError , retry Error handling takeUntil , takeUntilDestroyed , take(1) , first Completion/unsubscription shareReplay Multicast and cache the last value Subjects : Subject (no initial value), BehaviorSubject (has current value — simple state), ReplaySubject(n) , AsyncSubject . Cold observables start per subscriber (HTTP); hot share one source (DOM events, Subjects). Unsubscribing : the async pipe, takeUntilDestroyed() , toSignal() — avoid manual subscriptions that leak."},{"kind":"lesson","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"signals","title":"Signals","body":"ts count = signal(0); // writable signal double = computed(() = this.count() 2); // derived, memoised, lazy constructor() { effect(() = console.log(\"count is\", this.count())); // side effects when dependencies change } increment() { this.count.update(c = c + 1); } // or .set(5) // Interop with RxJS orders = toSignal(this.orderService.list(), { initialValue: [] }); count$ = toObservable(this.count); // linkedSignal: writable state that resets when a source changes (v19) selectedId = linkedSignal(() = this.orders()[0]?.id); // resource: async data as signals (v19, experimental → evolving) user = resource({ params: () = ({ id: this.userId() }), loader: ({ params }) = fetchUser(params.id) }); Signals tell Angular exactly which components depend on which state, enabling fine-grained, zoneless change detection. Read a signal by calling it: count() . Signal inputs ( input() ), outputs ( output() ), model() for two-way, and viewChild() / contentChild() queries are signal-based too."},{"kind":"lesson","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"change-detection-default-vs-onpush-zone-js-vs-zoneless","title":"Change detection: Default vs OnPush, zone.js vs zoneless","body":"- Default strategy : after any async event, Angular checks the whole component tree. - ChangeDetectionStrategy.OnPush : a component is checked only when an input reference changes, an event originates in it (or children), an async pipe emits, a signal it reads changes, or markForCheck() is called. Use immutable data. Big performance win. - zone.js patches async APIs (setTimeout, promises, events) to know when to run change detection. - Zoneless ( provideZonelessChangeDetection() , default for new apps in v21): no zone.js; change detection is triggered by signals, markForCheck , template events, async pipe → smaller bundles, better performance, clearer stack traces. Third-party code that mutates state outside Angular needs signals or markForCheck . - ChangeDetectorRef : markForCheck() , detectChanges() , detach() . - ExpressionChangedAfterItHasBeenCheckedError (dev mode): a binding value changed during the same check cycle (e.g. changing state in ngAfterViewInit ) — fix the data flow (compute earlier, use signals, or schedule)."},{"kind":"lesson","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"component-communication-and-content-projection","title":"Component communication and content projection","body":"Pattern How --- --- Parent → child input() / @Input() Child → parent output() / @Output() + EventEmitter Two-way model() / [(x)] Parent accesses child viewChild() / @ViewChild() Siblings / unrelated Shared service with signals or BehaviorSubject Global State management store (NgRx, Signal Store) Router Route params, query params, withComponentInputBinding() html <!-- card.component.html: content projection -- <div class=\"card\" <header <ng-content select=\"[card-title]\" / </header <ng-content / </div <!-- usage -- <app-card <h3 card-title Orders</h3 <p Body</p </app-card ng-template (not rendered until used), ng-container (grouping without an extra element), ngTemplateOutlet (render a template dynamically)."},{"kind":"lesson","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"state-management-services-with-signals-ngrx","title":"State management: services with signals, NgRx","body":"- Small/medium apps: services with signals (or BehaviorSubject) exposing read-only state and methods. - Large apps: NgRx Store (Redux pattern): Actions (events) → Reducers (pure functions producing new state) → Store (single immutable state tree) → Selectors (memoised queries); Effects handle side effects (HTTP) and dispatch new actions. Redux DevTools for time-travel debugging. - NgRx Signal Store — lighter, signal-based store ( signalStore , withState , withComputed , withMethods ). ts @Injectable({ providedIn: \"root\" }) export class CartStore { private readonly items = signal<CartItem[] ([]); readonly items = this. items.asReadonly(); readonly total = computed(() = this. items().reduce((s, i) = s + i.price i.qty, 0)); add(item: CartItem) { this. items.update(items = [...items, item]); } // immutable update }"},{"kind":"lesson","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"routing-lazy-loading-guards-and-resolvers","title":"Routing, lazy loading, guards and resolvers","body":"ts export const routes: Routes = [ { path: \"\", component: Home }, { path: \"orders\", loadComponent: () = import(\"./orders/order-list\").then(m = m.OrderList) }, // lazy component { path: \"admin\", canActivate: [authGuard], canMatch: [adminGuard], loadChildren: () = import(\"./admin/admin.routes\").then(m = m.ADMIN ROUTES) }, // lazy route group { path: \"orders/:id\", component: OrderDetail, resolve: { order: orderResolver } }, { path: \" \", component: NotFound }, ]; export const authGuard: CanActivateFn = () = inject(AuthService).isLoggedIn() ? true : inject(Router).createUrlTree([\"/login\"]); export const orderResolver: ResolveFn<Order = route = inject(OrderService).get(Number(route.paramMap.get(\"id\"))); html <a routerLink=\"/orders\" routerLinkActive=\"active\" Orders</a <a [routerLink]=\"['/orders', o.id]\" [queryParams]=\"{ tab: 'lines' }\" Open</a <router-outlet / Guards: canActivate , canActivateChild , canDeactivate (unsaved changes), canMatch (choose route/lazy load), resolve . Read params: ActivatedRoute.paramMap (observable) or component input binding ( withComponentInputBinding() → id = input<string () ). Preloading strategies: withPreloading(PreloadAllModules) ."},{"kind":"lesson","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"template-driven-vs-reactive-forms","title":"Template-driven vs reactive forms","body":"ts // Reactive (typed) form private fb = inject(NonNullableFormBuilder); form = this.fb.group({ customer: [\"\", [Validators.required, Validators.minLength(3)]], email: [\"\", [Validators.required, Validators.email]], lines: this.fb.array([this.newLine()]), }); newLine() { return this.fb.group({ productId: [0, Validators.min(1)], qty: [1, [Validators.min(1), Validators.max(100)]] }); } save() { if (this.form.invalid) { this.form.markAllAsTouched(); return; } this.api.save(this.form.getRawValue()); } html <form [formGroup]=\"form\" (ngSubmit)=\"save()\" <input formControlName=\"customer\" / @if (form.controls.customer.touched && form.controls.customer.hasError('required')) { <small Required</small } <button [disabled]=\"form.invalid\" Save</button </form Template-driven Reactive --- --- --- Model defined in Template ( ngModel ) Component class ( FormGroup / FormControl ) Data flow Async, two-way binding Sync, explicit, immutable updates Validation Directives ( required , custom validator directives) Functions ( Validators , custom/async validators) Testing Harder (needs DOM) Easy (pure TS) Dynamic forms Awkward FormArray , add/remove controls Use Simple forms Complex/dynamic/enterprise forms Custom validator: (control: AbstractControl): ValidationErrors null . Async validator returns Observable<ValidationErrors null (e.g. \"username taken\"). v21 adds experimental Signal Forms ."},{"kind":"lesson","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"testing-angular-apps","title":"Testing Angular apps","body":"ts describe(\"OrderCard\", () = { it(\"emits the id when clicked\", async () = { await TestBed.configureTestingModule({ imports: [OrderCard] }).compileComponents(); const fixture = TestBed.createComponent(OrderCard); fixture.componentRef.setInput(\"order\", { id: 7, customer: \"Asha\", total: 500, status: \"paid\" }); let emitted: number undefined; fixture.componentInstance.select.subscribe(id = (emitted = id)); fixture.detectChanges(); fixture.nativeElement.querySelector(\"button\").click(); expect(emitted).toBe(7); }); }); // Services with HTTP TestBed.configureTestingModule({ providers: [provideHttpClient(), provideHttpClientTesting()] }); const httpMock = TestBed.inject(HttpTestingController); httpMock.expectOne(\"/api/orders\").flush([]); Runners: Vitest (default in new v21 projects), Jest, or Karma + Jasmine (older projects; Karma is deprecated). Component harnesses (CDK) for Material components; Playwright/Cypress for E2E."},{"kind":"lesson","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"performance-optimisation","title":"Performance optimisation","body":"1. OnPush everywhere + immutable data + signals; consider zoneless. 2. Lazy load routes ( loadComponent / loadChildren ) and @defer heavy blocks. 3. track in @for (or trackBy ) to avoid re-rendering lists. 4. Virtual scrolling ( cdk-virtual-scroll-viewport ) for long lists. 5. Avoid function calls in templates (use computed /pure pipes). 6. Unsubscribe (async pipe, takeUntilDestroyed ) to prevent leaks. 7. SSR + hydration ( @angular/ssr , incremental hydration) for first paint and SEO; prerender static routes. 8. NgOptimizedImage ( ngSrc ) for images; budgets in angular.json ; analyse bundles ( ng build --stats-json + esbuild/webpack analyzers). 9. Web Workers for heavy computation; preloading strategies. 10. Production builds (AOT, tree-shaking, minification are default)."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"895","title":"What is Angular and how is it different from AngularJS?","body":"Angular is a TypeScript-based, component-driven framework (2016+, by Google) with a CLI, hierarchical DI, RxJS, signals, a router, forms and HTTP modules, AOT compilation and SSR. AngularJS (1.x) used JavaScript, controllers and $scope , two-way binding with dirty-checking digest cycles, and reached EOL in Dec 2021. Angular is faster, more modular, mobile-friendly, and has semver releases every six months."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"896","title":"What are components and what is a standalone component?","body":"A component is a TypeScript class decorated with @Component that controls a piece of UI through its template and styles, with a selector used in other templates. A standalone component (v14+, default since v19) declares its own dependencies via imports without belonging to an NgModule, making apps simpler, enabling lazy loading per component, and reducing boilerplate."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"897","title":"Explain the types of data binding in Angular.","body":"Interpolation {{ }} and property binding [prop]=\"expr\" (component → view), event binding (event)=\"handler()\" (view → component), and two-way binding [(ngModel)]=\"value\" (banana-in-a-box: property + event). Also attribute [attr.x] , class [class.x] and style [style.x] bindings."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"898","title":"What are directives? Types of directives?","body":"Classes that add behaviour to elements. Components are directives with templates. Attribute directives change appearance/behaviour ( ngClass , ngStyle , custom appHighlight ). Structural directives change DOM layout by adding/removing elements ( ngIf , ngFor , ngSwitch — now largely replaced by built-in control flow @if , @for , @switch )."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"899","title":"What are pipes? Pure vs impure?","body":"Pipes transform values in templates ( date , currency , async , custom). Pure pipes (default) run only when the input value/reference changes — efficient. Impure pipes ( pure: false ) run on every change detection cycle — needed for detecting changes inside mutable objects/arrays, but expensive. async is impure because it tracks emissions."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"900","title":"What is the Angular CLI? Name common commands.","body":"The official command-line tool to scaffold, develop, build, test and update Angular apps: ng new , ng serve , ng generate component service pipe guard directive , ng build , ng test , ng e2e , ng add (add libraries with schematics), ng update (automated migrations between versions), ng lint (with angular-eslint)."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"901","title":"Explain the component lifecycle hooks.","body":"ngOnChanges (input changes, before init), ngOnInit (once, initialise/fetch data), ngDoCheck (each CD cycle), ngAfterContentInit / ngAfterContentChecked (projected content), ngAfterViewInit / ngAfterViewChecked (view and child views, @ViewChild ready), ngOnDestroy (cleanup). The constructor is for DI only. Modern code often uses signal inputs/ computed instead of ngOnChanges , afterNextRender for DOM work and DestroyRef / takeUntilDestroyed for cleanup."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"902","title":"What is dependency injection in Angular? What does `providedIn: 'root'` mean?","body":"DI supplies a class's dependencies from injectors instead of the class creating them. Services are registered with providers; consumers use inject(Service) or constructor parameters. @Injectable({ providedIn: 'root' }) registers a tree-shakable application-wide singleton. Providers can also be scoped to routes or components (new instance per component). Injectors are hierarchical: lookup goes from the element injector up to the root/environment injector."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"903","title":"Observable vs Promise?","body":"A Promise handles a single future value, is eager (starts immediately), and isn't cancellable. An Observable can emit many values over time, is lazy (runs on subscribe), cancellable (unsubscribe), and composable with operators (map, switchMap, debounceTime, retry). Angular uses Observables for HttpClient, router events, forms valueChanges; convert with firstValueFrom / toSignal when convenient."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"904","title":"switchMap vs mergeMap vs concatMap vs exhaustMap?","body":"All map each source value to an inner observable and flatten. switchMap cancels the previous inner observable when a new value arrives (typeahead search, route param changes). mergeMap runs all concurrently (parallel independent requests). concatMap queues them and runs one after another in order (sequential saves). exhaustMap ignores new values while the current inner observable is active (prevent duplicate login submissions)."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"905","title":"What are signals and why were they introduced?","body":"Signals (v16+) are reactive primitives holding a value: signal() (writable), computed() (derived, memoised), effect() (side effects). Angular tracks which templates/computeds read which signals, so it knows exactly what changed and can update only affected components — enabling fine-grained, zoneless change detection, simpler state than RxJS for synchronous state, and better performance. RxJS remains useful for async event streams; toSignal / toObservable bridge them."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"906","title":"Template-driven vs reactive forms — which do you use?","body":"Template-driven forms define the model in the template with ngModel and directive validators — quick for simple forms. Reactive forms define FormGroup / FormControl / FormArray in the component, are synchronous, strongly typed (v14+), easy to unit test, and ideal for complex, dynamic forms with custom/async validators. Most enterprise apps use reactive forms; v21 previews signal-based forms."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"907","title":"How do you implement route guards and lazy loading?","body":"Guards are functions ( CanActivateFn , CanMatchFn , CanDeactivateFn , ResolveFn ) listed on routes; they return boolean, UrlTree (redirect), or an observable/promise of those — e.g. authGuard redirects to /login. Lazy loading uses loadComponent: () = import(...) or loadChildren so feature code is downloaded only when the route is visited, reducing the initial bundle; preloading strategies can fetch them in the background."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"908","title":"How do components communicate?","body":"Parent to child with inputs; child to parent with outputs (events); two-way with model() ; parent to child methods via viewChild ; siblings/unrelated components through a shared injectable service holding signals or a BehaviorSubject; app-wide via a store (NgRx); and through the router (params, query params, state)."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"909","title":"What is an HTTP interceptor?","body":"A function ( HttpInterceptorFn ) or class registered with provideHttpClient(withInterceptors([...])) that sees every outgoing request and incoming response. Uses: attaching auth tokens, adding headers, global error handling (401 redirect, toast), logging, loading spinners, caching, retrying. Requests are immutable — use req.clone() to modify."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"910","title":"Explain change detection. What does OnPush do? What is zoneless?","body":"Change detection syncs component state to the DOM. With zone.js, Angular runs a check over the tree after any async event. OnPush limits checks of a component to when its input references change, an event happens inside it, an async pipe emits, a signal it reads changes, or markForCheck() is called — fewer checks, better performance, but requires immutable updates. Zoneless mode (default for new apps in v21) removes zone.js entirely; change detection is scheduled by signals, events and explicit notifications, which gives smaller bundles and more predictable updates."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"911","title":"How do you prevent memory leaks in Angular?","body":"Unsubscribe from long-lived observables: prefer the async pipe or toSignal , use takeUntilDestroyed() (or takeUntil with a destroy subject), remove manual DOM listeners and timers in ngOnDestroy / DestroyRef.onDestroy , avoid storing component references in singleton services, and be careful with effect() s that create subscriptions. HttpClient requests complete on their own but still should be cancelled if the component is destroyed mid-request (switchMap/takeUntilDestroyed)."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"912","title":"What is SSR and hydration in Angular?","body":"Server-side rendering ( @angular/ssr ) renders pages on the server (or prerenders at build time) so users and search engines get HTML immediately. Hydration then reuses that DOM in the browser instead of re-rendering it (non-destructive hydration v16+), with event replay so early clicks aren't lost and incremental hydration (v19) to hydrate parts lazily with @defer triggers. Watch for browser-only APIs ( window , localStorage ) — guard them with isPlatformBrowser or afterNextRender ."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"913","title":"What is NgRx and when should you use it?","body":"A Redux-style state management library: actions describe events, reducers produce new immutable state, the store holds a single state tree, selectors read memoised slices, effects handle side effects like HTTP. Use it for large apps with complex shared state, many teams, and a need for predictability, debugging (DevTools time travel) and strict patterns. For small/medium apps, signal-based services or NgRx Signal Store are simpler."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"914","title":"A list of 10,000 rows renders slowly and scrolling lags. How do you optimise?","body":"Use CDK virtual scrolling ( cdk-virtual-scroll-viewport ) so only visible rows are in the DOM; track item.id in @for ; OnPush row components with immutable inputs; avoid function calls and impure pipes in row templates (use computed/pure pipes); paginate or load incrementally from the API; move heavy computations to a Web Worker; and measure with Angular DevTools profiler."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"915","title":"Your search box sends a request on every keystroke and results sometimes appear out of order. Fix it.","body":"Use a reactive control and RxJS: valueChanges.pipe(debounceTime(300), distinctUntilChanged(), filter(t = t.length = 2), switchMap(t = this.api.search(t))) . switchMap cancels the previous HTTP request, so stale responses can't overwrite newer ones. Show results with the async pipe or toSignal , and handle errors with catchError returning an empty list."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"916","title":"After login, some API calls still go out without the token, and expired tokens cause random 401s. How do you design auth handling?","body":"Centralise it: an auth service storing the token (in memory/signal; refresh token in an HttpOnly cookie via the backend), a functional interceptor that adds the Authorization header to API requests, and on 401 attempts a single shared refresh (queue concurrent requests while refreshing using a shared observable), then retries; if refresh fails, log out and redirect via a guard. Protect routes with canActivate / canMatch guards; never rely on the frontend for real authorisation — the API must enforce it."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"917","title":"You get \"ExpressionChangedAfterItHasBeenCheckedError\". What does it mean and how do you fix it?","body":"In development mode Angular runs a second check after change detection; the error means a bound value changed between the first and second check — usually state modified in ngAfterViewInit / ngAfterContentInit , in a child that updates the parent during the same cycle, or a getter returning a new value each time. Fix the data flow: initialise values earlier ( ngOnInit ), derive with computed , move updates into an event or the next tick only as a last resort, or restructure so children don't mutate parent state during rendering."},{"kind":"question","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"918","title":"How would you upgrade an Angular 12 app to the latest version?","body":"Upgrade one major version at a time with ng update @angular/core@13 @angular/cli@13 (and so on), following angular.dev/update-guide for each step; update Angular Material and third-party libraries alongside; fix breaking changes and run tests after each hop; along the way migrate to standalone components ( ng generate @angular/core:standalone ), built-in control flow ( ng generate @angular/core:control-flow ), signal inputs, the esbuild application builder, and functional guards/interceptors; check Node and TypeScript version requirements."},{"kind":"cheat","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"1","title":"CLI","body":"ng new · ng serve · ng g c s p d g · ng build · ng test · ng add · ng update ."},{"kind":"cheat","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"2","title":"Bindings","body":"{{ }} · [prop] · (event) · [(ngModel)] · [class.x] · [style.x] · [attr.x] ."},{"kind":"cheat","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"3","title":"Control flow (v17+)","body":"@if / @else · @for (x of xs; track x.id) {} @empty {} · @switch / @case · @defer (on viewport) · @let ."},{"kind":"cheat","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"4","title":"Signals","body":"signal() · computed() · effect() · linkedSignal() · resource() · input() · output() · model() · viewChild() · toSignal() / toObservable() ."},{"kind":"cheat","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"5","title":"Lifecycle","body":"constructor → ngOnChanges → ngOnInit → ngDoCheck → ngAfterContentInit/Checked → ngAfterViewInit/Checked → ngOnDestroy."},{"kind":"cheat","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"6","title":"RxJS","body":"switchMap (cancel) · mergeMap (parallel) · concatMap (sequential) · exhaustMap (ignore while busy) · debounceTime · distinctUntilChanged · catchError · retry · forkJoin · combineLatest · shareReplay · takeUntilDestroyed · BehaviorSubject."},{"kind":"cheat","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"7","title":"Routing","body":"provideRouter(routes) · loadComponent / loadChildren · guards CanActivateFn / CanMatchFn / CanDeactivateFn · ResolveFn · routerLink · <router-outlet / ."},{"kind":"cheat","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"8","title":"Forms","body":"Template-driven ( ngModel ) vs Reactive ( FormGroup , FormControl , FormArray , Validators , typed) · Signal Forms (v21, experimental)."},{"kind":"cheat","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"9","title":"Performance","body":"OnPush · signals · zoneless · lazy routes · @defer · track · virtual scroll · SSR + hydration · NgOptimizedImage · no functions in templates."},{"kind":"cheat","course_slug":"angular","course_title":"Angular (2 → 21)","ref":"10","title":"Versions","body":"2 (2016) · 9 Ivy · 14 standalone · 16 signals · 17 control flow + @defer · 19 standalone default · 20 stable signals · 21 zoneless default + Vitest · major every 6 months, 18-month support."},{"kind":"course","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"","title":"React (with Hooks, React 19 & Next.js basics)","body":"JSX, components and props, state, events, conditional rendering and lists, hooks in depth, effects and data fetching, forms, context, reducers, refs, performance (memo, useMemo, useCallback, React Compiler), routing, state libraries, React 19 actions and Server Components, testing and Next.js. React is a JavaScript library for building user interfaces from components , created at Facebook (Meta) by Jordan Walke and open-sourced in 2013. It is the most widely used frontend library. Core ideas: - Declarative UI — describe what the UI should look like for a given state; React updates the DOM. - Components — functions returning JSX ; compose them like building blocks. - One-way data flow — data flows down via props ; events flow up via callbacks. - State + re-render — when state changes, React re-renders the component and reconciles the result against the previous render, updating only what changed in the DOM. - Hooks (2019) — state and side effects in function components. - \"Learn once, write anywhere\" — React DOM (web), React Native (mobile), React Server Components. React is a library ; for routing, data fetching, SSR and bundling you add tools or use a framework such as Next.js or React Router (framework mode, formerly Remix) — the React docs recommend starting new apps with a framework (or Vite for a pure client app). Create React App was deprecated in February 2025 . Version Date Highlights --- --- --- 0.3 May 2013 Open-sourced at JSConf US 0.14 2015 react / react-dom split, stateless function components 15 Apr 2016 Version jump from 0.14; createElement DOM rendering 16 Sep 2017 Fiber reconciler, fragments, error boundaries, portals; 16.3 new Context API; 16.8 (Feb 2019) Hooks 17 Oct 2020 No new features — gradual upgrades, new JSX transform (no import React needed) 18 Mar 2022 Concurrent rendering , createRoot , automatic batching , useTransition , useDeferredValue , useId , streaming SSR with Suspense 19 Dec 2024 Actions , useActionState , useOptimistic , use() , form action , ref as a prop, Server Components & Server Actions stable, document metadata, resource preloading 19.1 / 19.2 2025 Owner stacks; 19.2 (Oct 2025): <Activity , useEffectEvent , partial pre-rendering, cacheSignal Ecosystem milestones: React Compiler 1.0 (Oct 2025 — automatic memoisation), React Native New Architecture default (0.76, 2024), React and React Native moved to the React Foundation under the Linux Foundation (announced Oct 2025). Next.js: 13 (App Router, 2022), 14, 15 (2024, React 19), 16 (2025, Turbopack default). Component lifecycle (function components): 1. Mount — React calls the component function (render) → commits DOM → runs useLayoutEffect → browser paints → runs useEffect callbacks. 2. Update — triggered by a state change, new props from the parent re-rendering, or a context change → render again → React diffs the new element tree with the old one (reconciliation) → commits minimal DOM changes → runs effect cleanups for changed dependencies, then the new effects. 3. Unmount — effect cleanups run (unsubscribe, clear timers). In development Strict Mode mounts components twice (mount → unmount → mount) to reveal missing cleanups. Class component lifecycle (legacy): constructor → render → componentDidMount updates: shouldComponentUpdate → render → getSnapshotBeforeUpdate → componentDidUpdate componentWillUnmount errors: getDerivedStateFromError , componentDidCatch . Class method Hook equivalent --- --- componentDidMount useEffect(() = {...}, []) componentDidUpdate useEffect(() = {...}, [deps]) componentWillUnmount cleanup returned from useEffect shouldComponentUpdate React.memo this.state / setState useState / useReducer Render phases: render phase (pure — call components, compute the tree; can be paused/interrupted in concurrent mode) → commit phase (apply DOM mutations, run layout effects, then passive effects). Tool Use --- --- Vite ( npm create vite@latest ) Fast client-side React setup Next.js , React Router (framework), Expo (React Native) Frameworks React Developer Tools (browser extension) Component tree, props/state, profiler TypeScript Typed props/state ESLint + eslint-plugin-react-hooks Rules of Hooks, exhaustive deps React Compiler (babel/SWC plugin) Automatic memoisation TanStack Query, SWR, RTK Query Server-state fetching & caching Redux Toolkit, Zustand, Jotai Client state React Hook Form + Zod Forms and validation Tailwind CSS, CSS Modules, shadcn/ui, MUI, Chakra Styling and UI kits Vitest/Jest + React Testing Library , Playwright Testing Storybook Component development in isolation"},{"kind":"lesson","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"jsx-components-and-props","title":"JSX, components and props","body":"jsx // JSX compiles to function calls: <h1 className=\"t\" Hi</h1 → jsx(\"h1\", { className: \"t\", children: \"Hi\" }) function OrderCard({ order, onSelect }) { // props are read-only const isBig = order.total 10000; return ( <div className={ card ${isBig ? \"big\" : \"\"} } onClick={() = onSelect(order.id)} <h3 {order.id} — {order.customer}</h3 <p {order.total.toLocaleString(\"en-IN\", { style: \"currency\", currency: \"INR\" })}</p </div ); } function OrderList({ orders }) { return ( < {/ Fragment: no extra DOM node /} {orders.map(o = ( <OrderCard key={o.id} order={o} onSelect={id = console.log(id)} / ))} </ ); } JSX rules: one root element (or fragment), className not class , htmlFor , camelCase attributes ( onClick , tabIndex ), {} for JavaScript expressions, self-close empty tags, style={{ color: \"red\" }} . JSX escapes values by default (XSS-safe); dangerouslySetInnerHTML bypasses that. children prop for composition: <Card <p Body</p </Card → function Card({ children }) { return <div className=\"card\" {children}</div ; } ."},{"kind":"lesson","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"state-with-usestate-and-event-handling","title":"State with useState and event handling","body":"jsx import { useState } from \"react\"; function Counter() { const [count, setCount] = useState(0); const [form, setForm] = useState({ name: \"\", email: \"\" }); return ( < <button onClick={() = setCount(c = c + 1)} Clicked {count} times</button {/ functional update /} <input value={form.name} onChange={e = setForm(prev = ({ ...prev, name: e.target.value }))} // immutable update / </ ); } - State updates are asynchronous and batched — count doesn't change until the next render. Use the functional form ( c = c + 1 ) when the new value depends on the old one. - Never mutate state ( form.name = \"x\" ); create new objects/arrays ( [...items, newItem] , items.filter(...) , items.map(...) ). - Lazy initial state for expensive computation: useState(() = loadFromStorage()) . - Events are React synthetic events wrapping native ones; e.preventDefault() for forms."},{"kind":"lesson","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"conditional-rendering-and-lists-with-keys","title":"Conditional rendering and lists with keys","body":"jsx {isLoading ? <Spinner / : <OrderTable orders={orders} / } {error && <p className=\"error\" {error.message}</p } {orders.length === 0 && <EmptyState / } {/ careful: {0 && <X/ } renders \"0\" — use length 0 /} <ul {todos.map(todo = <TodoItem key={todo.id} todo={todo} / )} </ul Keys let React match list items between renders. Use a stable, unique ID from data. Using the array index as key breaks state and animations when items are inserted, removed or reordered (inputs keep the wrong value)."},{"kind":"lesson","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"controlled-vs-uncontrolled-forms","title":"Controlled vs uncontrolled forms","body":"jsx // Controlled: React state is the source of truth function LoginForm({ onLogin }) { const [email, setEmail] = useState(\"\"); const [error, setError] = useState(\"\"); function handleSubmit(e) { e.preventDefault(); if (!email.includes(\"@\")) return setError(\"Enter a valid email\"); onLogin(email); } return ( <form onSubmit={handleSubmit} <input type=\"email\" value={email} onChange={e = setEmail(e.target.value)} / {error && <span role=\"alert\" {error}</span } <button Login</button </form ); } // Uncontrolled: the DOM holds the value; read it with a ref or FormData function SearchForm() { const inputRef = useRef(null); return <form onSubmit={e = { e.preventDefault(); search(inputRef.current.value); }} <input ref={inputRef} defaultValue=\"\" / </form ; } For real forms, React Hook Form (uncontrolled, performant) + Zod schema validation is common; React 19 adds form Actions (below)."},{"kind":"lesson","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"react-project-folder-structure-with-sample-files-vite-typescript","title":"React project folder structure — with sample files (Vite + TypeScript)","body":"npm create vite@latest shop-ui -- --template react-ts creates a client-side React app. A real project grows into a feature-based structure: text shop-ui/ ├── index.html the single HTML page; <div id=\"root\" where React mounts ├── public/ static files copied as-is (favicon, robots.txt) ├── src/ │ ├── main.tsx entry point: createRoot(...).render(<App / ) with providers (Router, QueryClient) │ ├── App.tsx root component: layout + routes │ ├── routes.tsx route table (React Router) │ ├── index.css global styles │ ├── assets/ images/fonts imported by components │ ├── components/ shared, reusable UI │ │ ├── ui/Button.tsx, Modal.tsx, Spinner.tsx │ │ └── layout/Header.tsx, Footer.tsx │ ├── features/ one folder per business feature │ │ ├── products/ │ │ │ ├── api.ts calls to the backend API (fetch/axios) │ │ │ ├── types.ts Product, PagedResult<T │ │ │ ├── useProducts.ts custom hook (TanStack Query) │ │ │ ├── ProductList.tsx page/feature component │ │ │ ├── ProductCard.tsx │ │ │ └── ProductList.test.tsx │ │ └── orders/ … │ ├── hooks/ shared custom hooks (useDebounce, useAuth) │ ├── lib/ apiClient.ts (base URL, auth header), utils │ ├── store/ global client state (Zustand / Redux Toolkit) if needed │ └── types/ shared types ├── .env.development / .env.production VITE API URL=... ├── vite.config.ts dev server, proxy to the API, build settings ├── tsconfig.json · eslint.config.js · package.json tsx // src/main.tsx import { StrictMode } from \"react\"; import { createRoot } from \"react-dom/client\"; import { BrowserRouter } from \"react-router-dom\"; import { QueryClient, QueryClientProvider } from \"@tanstack/react-query\"; import App from \"./App\"; import \"./index.css\"; const queryClient = new QueryClient(); createRoot(document.getElementById(\"root\")!).render( <StrictMode <QueryClientProvider client={queryClient} <BrowserRouter <App / </BrowserRouter </QueryClientProvider </StrictMode ); // src/App.tsx import { Routes, Route } from \"react-router-dom\"; import Header from \"./components/layout/Header\"; import ProductList from \"./features/products/ProductList\"; export default function App() { return ( < <Header / <Routes <Route path=\"/\" element={<ProductList / } / <Route path=\" \" element={<p Not found</p } / </Routes </ ); } Next.js projects use the app/ folder conventions instead (see the Next.js course)."},{"kind":"lesson","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"connecting-a-react-app-to-sql-server-through-an-api","title":"Connecting a React app to SQL Server (through an API)","body":"A browser app never connects to SQL Server directly — it would expose the connection string and SQL Server doesn't speak HTTP. The pattern is: React → HTTP API (ASP.NET Core or Node.js) → SQL Server . text React (browser) ──fetch JSON──▶ ASP.NET Core Web API / Node Express ──ADO.NET/EF/Dapper or mssql──▶ SQL Server 1. Backend (ASP.NET Core minimal API + Dapper): csharp // Program.cs builder.Services.AddCors(o = o.AddPolicy(\"spa\", p = p.WithOrigins(\"http://localhost:5173\").AllowAnyHeader().AllowAnyMethod())); var cs = builder.Configuration.GetConnectionString(\"Shop\"); // appsettings.json → \"Server=.;Database=Shop;Trusted Connection=True;TrustServerCertificate=True\" var app = builder.Build(); app.UseCors(\"spa\"); app.MapGet(\"/api/products\", async () = { await using var conn = new SqlConnection(cs); return await conn.QueryAsync<ProductDto (\"SELECT Id, Name, Price FROM dbo.Products ORDER BY Name\"); }); 2. React side: ts // src/lib/apiClient.ts const BASE = import.meta.env.VITE API URL ?? \"\"; // \"\" in dev when using the Vite proxy export async function api<T (path: string, init?: RequestInit): Promise<T { const res = await fetch( ${BASE}${path} , { ...init, headers: { \"Content-Type\": \"application/json\", ...init?.headers } }); if (!res.ok) throw new Error( API ${res.status} ); return res.json() as Promise<T ; } // src/features/products/api.ts import { api } from \"../../lib/apiClient\"; export type Product = { id: number; name: string; price: number }; export const getProducts = () = api<Product[] (\"/api/products\"); // src/features/products/useProducts.ts import { useQuery } from \"@tanstack/react-query\"; import { getProducts } from \"./api\"; export const useProducts = () = useQuery({ queryKey: [\"products\"], queryFn: getProducts }); // src/features/products/ProductList.tsx export default function ProductList() { const { data, isLoading, error } = useProducts(); if (isLoading) return <p Loading…</p ; if (error) return <p Could not load products.</p ; return <ul {data!.map((p) = <li key={p.id} {p.name} — ₹{p.price}</li )}</ul ; } ts // vite.config.ts — dev proxy avoids CORS during development export default defineConfig({ plugins: [react()], server: { proxy: { \"/api\": { target: \"https://localhost:7001\", changeOrigin: true, secure: false } } }, }); Checklist: CORS on the API for the SPA origin, HTTPS, JWT/cookie auth, the connection string only on the server (appsettings/Key Vault), parameterised SQL on the server, and VITE variables contain no secrets (they are public)."},{"kind":"lesson","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"useeffect-side-effects-dependencies-and-cleanup","title":"useEffect: side effects, dependencies and cleanup","body":"jsx function OrderDetails({ orderId }) { const [order, setOrder] = useState(null); const [error, setError] = useState(null); useEffect(() = { const controller = new AbortController(); setOrder(null); fetch( /api/orders/${orderId} , { signal: controller.signal }) .then(r = { if (!r.ok) throw new Error( HTTP ${r.status} ); return r.json(); }) .then(setOrder) .catch(err = { if (err.name !== \"AbortError\") setError(err); }); return () = controller.abort(); // cleanup: runs before the next effect and on unmount }, [orderId]); // re-run when orderId changes if (error) return <p Failed: {error.message}</p ; return order ? <h2 {order.customer}</h2 : <Spinner / ; } Dependency array Runs --- --- none After every render [] Once after mount (cleanup on unmount) [a, b] After mount and whenever a or b changes ( Object.is comparison) Rules: include every reactive value used inside (the ESLint rule enforces it); don't use effects for things computable during render (\"you might not need an effect\"); avoid setting state that triggers the same effect in a loop; prefer a data library (TanStack Query) or framework loaders for data fetching (caching, dedupe, race conditions). useLayoutEffect runs synchronously after DOM mutations before paint — for measuring layout."},{"kind":"lesson","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"useref-usememo-usecallback-and-react-memo","title":"useRef, useMemo, useCallback and React.memo","body":"jsx const inputRef = useRef(null); // DOM reference: inputRef.current.focus() const renders = useRef(0); // mutable value that does NOT trigger re-render renders.current++; const filtered = useMemo( () = orders.filter(o = o.customer.includes(search)), // cache an expensive calculation [orders, search] ); const handleSelect = useCallback(id = setSelected(id), []); // stable function identity const OrderRow = memo(function OrderRow({ order, onSelect }) { // skip re-render if props are shallow-equal return <tr onClick={() = onSelect(order.id)} <td {order.customer}</td </tr ; }); - useMemo caches a value ; useCallback caches a function ( useCallback(fn, deps) = useMemo(() = fn, deps) ). - React.memo caches a component's render for the same props — useful only if props are stable (hence useCallback / useMemo for objects and functions passed down). - Don't memoise everything — it has its own cost. The React Compiler (1.0, Oct 2025) adds memoisation automatically at build time, making most manual useMemo / useCallback / memo unnecessary in new code. - forwardRef is no longer needed in React 19 — ref is a regular prop for function components."},{"kind":"lesson","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"usecontext-and-usereducer","title":"useContext and useReducer","body":"jsx const AuthContext = createContext(null); function AuthProvider({ children }) { const [user, setUser] = useState(null); const value = useMemo(() = ({ user, login: setUser, logout: () = setUser(null) }), [user]); return <AuthContext value={value} {children}</AuthContext ; // React 19: <Context as provider (older: <AuthContext.Provider ) } const useAuth = () = { const ctx = useContext(AuthContext); if (!ctx) throw new Error(\"useAuth must be used inside AuthProvider\"); return ctx; }; // useReducer: complex state transitions in one place function cartReducer(state, action) { switch (action.type) { case \"add\": return { ...state, items: [...state.items, action.item] }; case \"remove\": return { ...state, items: state.items.filter(i = i.id !== action.id) }; case \"clear\": return { ...state, items: [] }; default: throw new Error( Unknown action ${action.type} ); } } const [cart, dispatch] = useReducer(cartReducer, { items: [] }); dispatch({ type: \"add\", item: { id: 7, name: \"Mouse\", price: 900 } }); Context avoids prop drilling for app-wide values (theme, auth, locale). Every consumer re-renders when the context value changes — split contexts, memoise the value, or use a state library for frequently changing global state."},{"kind":"lesson","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"custom-hooks-and-the-rules-of-hooks","title":"Custom hooks and the Rules of Hooks","body":"jsx function useFetch(url) { const [state, setState] = useState({ data: null, error: null, loading: true }); useEffect(() = { const c = new AbortController(); setState(s = ({ ...s, loading: true })); fetch(url, { signal: c.signal }) .then(r = r.json()) .then(data = setState({ data, error: null, loading: false })) .catch(error = { if (error.name !== \"AbortError\") setState({ data: null, error, loading: false }); }); return () = c.abort(); }, [url]); return state; } function useDebounce(value, ms = 300) { const [debounced, setDebounced] = useState(value); useEffect(() = { const t = setTimeout(() = setDebounced(value), ms); return () = clearTimeout(t); }, [value, ms]); return debounced; } Rules of Hooks: 1) call hooks only at the top level of a component or custom hook (not in loops, conditions, nested functions or after early returns) — React relies on call order; 2) call them only from React function components or custom hooks. Custom hook names start with use . Exception: the new use() API can be called conditionally."},{"kind":"lesson","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"actions-useactionstate-useoptimistic-and-use","title":"Actions, useActionState, useOptimistic and use()","body":"jsx // Form Actions (React 19): pass a function to <form action function AddTodo({ addTodo }) { const [error, submitAction, isPending] = useActionState(async (prevState, formData) = { const title = formData.get(\"title\"); if (!title) return \"Title is required\"; await addTodo(title); // async transition: isPending is true meanwhile return null; }, null); return ( <form action={submitAction} <input name=\"title\" / <button disabled={isPending} {isPending ? \"Saving…\" : \"Add\"}</button {error && <p {error}</p } </form ); } // Optimistic UI const [optimisticLikes, addOptimisticLike] = useOptimistic(likes, (current, delta) = current + delta); // use(): read a promise (with Suspense) or context, can be conditional function Comments({ commentsPromise }) { const comments = use(commentsPromise); return comments.map(c = <p key={c.id} {c.text}</p ); } Also: useFormStatus (pending state for a submit button inside a form), useTransition (mark non-urgent updates), useDeferredValue , document metadata ( <title , <meta rendered anywhere), <Activity mode=\"hidden\" (19.2) to keep hidden UI state."},{"kind":"lesson","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"server-components-ssr-and-next-js-basics","title":"Server Components, SSR and Next.js basics","body":"- CSR (client-side rendering): browser downloads JS and renders — slower first paint, weak SEO. - SSR (server-side rendering): server renders HTML per request, client hydrates to make it interactive. - SSG (static generation): HTML at build time; ISR regenerates periodically. - React Server Components (RSC) : components that run only on the server (can read databases/files directly, ship zero JS); Client Components ( \"use client\" ) handle state and events. Server Actions/Functions ( \"use server\" ) are server functions callable from forms/client code. tsx // Next.js App Router — app/orders/page.tsx (Server Component by default) export default async function OrdersPage() { const orders = await db.order.findMany({ orderBy: { createdAt: \"desc\" }, take: 20 }); // runs on the server return <OrderTable orders={orders} / ; } // app/orders/new/actions.ts \"use server\"; export async function createOrder(formData: FormData) { await db.order.create({ data: { customer: String(formData.get(\"customer\")) } }); revalidatePath(\"/orders\"); } Next.js features: file-based routing ( app/ directory, layouts, loading/error files), Server Components by default, streaming with Suspense, Route Handlers (API), middleware/proxy, image/font optimisation, caching. Deployed commonly on Vercel ."},{"kind":"lesson","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"routing-with-react-router","title":"Routing with React Router","body":"jsx import { createBrowserRouter, RouterProvider, Link, NavLink, Outlet, useParams, useNavigate } from \"react-router\"; const router = createBrowserRouter([ { path: \"/\", element: <Layout / , errorElement: <ErrorPage / , children: [ { index: true, element: <Home / }, { path: \"orders\", element: <Orders / }, { path: \"orders/:id\", element: <OrderDetails / , loader: ({ params }) = fetchOrder(params.id) }, { path: \"admin\", element: <RequireAuth <Admin / </RequireAuth }, { path: \" \", element: <NotFound / }, ], }, ]); function Layout() { return < <nav <NavLink to=\"/orders\" Orders</NavLink </nav <Outlet / </ ; } function OrderDetails() { const { id } = useParams(); const navigate = useNavigate(); / ... / } createRoot(document.getElementById(\"root\")).render(<RouterProvider router={router} / ); React Router v7 (2024) merged with Remix and has library mode and framework mode. Alternative: TanStack Router (type-safe)."},{"kind":"lesson","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"state-management-local-server-and-global-state","title":"State management: local, server and global state","body":"Kind Tool --- --- Local UI state useState , useReducer Shared across a subtree Lift state up, Context Server state (API data, caching, refetching) TanStack Query , SWR, RTK Query, framework loaders Global client state Redux Toolkit , Zustand , Jotai, Context + reducer URL state Search params ( useSearchParams ) Form state React Hook Form jsx // TanStack Query const { data: orders, isPending, error } = useQuery({ queryKey: [\"orders\", page], queryFn: () = api.orders(page) }); const mutation = useMutation({ mutationFn: api.createOrder, onSuccess: () = queryClient.invalidateQueries({ queryKey: [\"orders\"] }) }); // Redux Toolkit slice const cartSlice = createSlice({ name: \"cart\", initialState: { items: [] }, reducers: { added(state, action) { state.items.push(action.payload); }, // Immer allows \"mutating\" syntax safely removed(state, action) { state.items = state.items.filter(i = i.id !== action.payload); }, }, }); // Zustand const useCart = create(set = ({ items: [], add: item = set(s = ({ items: [...s.items, item] })) }));"},{"kind":"lesson","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"error-boundaries-portals-suspense-and-lazy-loading","title":"Error boundaries, portals, Suspense and lazy loading","body":"jsx // Error boundary (still a class component, or use the react-error-boundary package) class ErrorBoundary extends React.Component { state = { hasError: false }; static getDerivedStateFromError() { return { hasError: true }; } componentDidCatch(error, info) { logToServer(error, info.componentStack); } render() { return this.state.hasError ? <p Something went wrong.</p : this.props.children; } } // Code splitting const Reports = lazy(() = import(\"./Reports\")); <Suspense fallback={<Spinner / } <Reports / </Suspense // Portal: render outside the parent DOM (modals, tooltips) createPortal(<Modal / , document.getElementById(\"modal-root\")); Error boundaries catch errors during rendering, lifecycle and constructors of children — not in event handlers, async code or the boundary itself."},{"kind":"lesson","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"performance-optimisation","title":"Performance optimisation","body":"1. Measure first: React DevTools Profiler , why-did-you-render, Lighthouse/Core Web Vitals. 2. Avoid unnecessary re-renders: keep state as local as possible, split components, memo + stable props (or React Compiler), split contexts. 3. Correct keys for lists; virtualise long lists (TanStack Virtual, react-window). 4. Code splitting with lazy /dynamic import and route-based splitting. 5. useTransition / useDeferredValue to keep typing responsive during heavy updates. 6. Debounce expensive inputs; avoid creating objects/functions inline for memoised children (or use the compiler). 7. Server Components/SSR to ship less JS; image optimisation; caching server data (TanStack Query). 8. Production build ( vite build ) — dev mode is much slower."},{"kind":"lesson","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"testing-react-components","title":"Testing React components","body":"jsx import { render, screen } from \"@testing-library/react\"; import userEvent from \"@testing-library/user-event\"; test(\"shows an error for an invalid email\", async () = { render(<LoginForm onLogin={vi.fn()} / ); await userEvent.type(screen.getByRole(\"textbox\"), \"not-an-email\"); await userEvent.click(screen.getByRole(\"button\", { name: /login/i })); expect(screen.getByRole(\"alert\")).toHaveTextContent(\"Enter a valid email\"); }); React Testing Library philosophy: test behaviour as a user sees it (roles, labels, text), not implementation details (state, internal methods). Mock network calls with MSW (Mock Service Worker). E2E with Playwright."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"919","title":"What is React and what are its main features?","body":"React is a JavaScript library (by Meta, 2013) for building user interfaces with reusable components. Features: declarative UI, component-based architecture, JSX, one-way data flow via props, state with hooks, efficient updates via reconciliation (virtual DOM diffing), a huge ecosystem, and React Native for mobile. It focuses on the view layer; routing, data fetching and SSR come from libraries or frameworks like Next.js."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"920","title":"What is JSX?","body":"JSX is a syntax extension that looks like HTML inside JavaScript. A compiler (Babel, SWC, esbuild) turns it into function calls ( jsx(\"div\", props) / React.createElement ) that create React elements. It supports embedding expressions in {} , uses className /camelCase attributes, and escapes values by default to prevent XSS. It's optional but universal."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"921","title":"What is the virtual DOM and reconciliation?","body":"The virtual DOM is a lightweight in-memory tree of React elements describing the UI. On each render React creates a new tree, diffs it against the previous one (reconciliation) using heuristics — elements of a different type are replaced, same-type elements are updated, keys identify list items — and applies only the minimal changes to the real DOM in the commit phase. Fiber (React 16+) made this work interruptible and prioritised."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"922","title":"What is the difference between props and state?","body":"Props are inputs passed from parent to child; they're read-only for the child. State is data owned and managed by a component ( useState / useReducer ) that changes over time and triggers re-renders when updated. A parent's state often becomes a child's props. Data flows down via props; children request changes via callback props."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"923","title":"Why are keys important in lists?","body":"Keys give each list item a stable identity so React can match elements between renders and update, move or remove the right DOM nodes and preserve component state. Without good keys (or with array indexes when the list changes order), React may reuse the wrong component instance, causing bugs like inputs showing the wrong values and unnecessary re-renders. Use unique IDs from data; keys need to be unique only among siblings."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"924","title":"Controlled vs uncontrolled components?","body":"In a controlled component, form input values are driven by React state ( value + onChange ), giving React full control — instant validation, conditional disabling, formatting. In an uncontrolled component, the DOM keeps the value and you read it when needed via refs or FormData ( defaultValue ), which means less code and fewer re-renders (React Hook Form uses this approach). File inputs are always uncontrolled."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"925","title":"Explain useEffect and its dependency array. How do you clean up?","body":"useEffect(fn, deps) runs side effects (data fetching, subscriptions, timers, DOM APIs) after the component commits. With no deps it runs after every render; with [] once after mount; with [a, b] when those values change. Return a cleanup function from the effect to unsubscribe, clear timers or abort fetches — React runs it before re-running the effect and on unmount. Missing dependencies cause stale values; the ESLint hooks rule helps."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"926","title":"What are the Rules of Hooks and why do they exist?","body":"Only call hooks at the top level of React function components or custom hooks — never inside loops, conditions, nested functions or after early returns — and only from React functions. React stores hook state in an ordered list per component and relies on the call order being identical on every render to match each useState / useEffect with its stored data."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"927","title":"useMemo vs useCallback vs React.memo?","body":"useMemo(() = compute(a, b), [a, b]) caches the result of an expensive calculation. useCallback(fn, deps) caches a function's identity so it doesn't change every render. React.memo(Component) skips re-rendering a component when its props are shallowly equal. They work together: memoised child + stable callback/object props. Use them where profiling shows a benefit; the React Compiler now automates most of this."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"928","title":"What is the Context API? When would you not use it?","body":"Context passes data through the component tree without prop drilling: createContext , a provider with a value, and useContext in consumers. It suits low-frequency global values (theme, auth user, locale, feature flags). Avoid it for frequently changing, large global state, because every consumer re-renders on any change of the value — use a state library (Zustand, Redux Toolkit) or split contexts and memoise values. It's not a replacement for server-state caching."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"929","title":"useState vs useReducer?","body":"useState is ideal for simple, independent values. useReducer centralises complex state logic where the next state depends on the previous one and on multiple action types (forms with many fields, carts, wizards). Its reducer is pure and easily testable, and dispatch is stable, which helps memoisation. It often pairs with Context for small app-wide stores."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"930","title":"What is lifting state up?","body":"When two components need the same changing data, move the state to their closest common parent and pass it down as props, with callbacks for updates. This keeps a single source of truth. If many layers are involved, consider composition (passing components as children), Context, or a store."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"931","title":"What are custom hooks? Give an example.","body":"Functions starting with use that call other hooks to encapsulate reusable stateful logic — useFetch(url) , useDebounce(value) , useLocalStorage(key) , useOnlineStatus() . Each component that calls a custom hook gets its own independent state. They replace older patterns like HOCs and render props for logic reuse."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"932","title":"What are error boundaries?","body":"Components (currently class components implementing getDerivedStateFromError / componentDidCatch , or the react-error-boundary package) that catch JavaScript errors in their child component tree during rendering, lifecycle methods and constructors, show a fallback UI and log the error, instead of unmounting the whole app. They don't catch errors in event handlers, async code (setTimeout, promises outside rendering), SSR or themselves."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"933","title":"How do you optimise the performance of a React application?","body":"Profile with React DevTools; avoid unnecessary re-renders (state colocation, splitting components, memo with stable props or the React Compiler, splitting contexts); virtualise long lists; correct keys; code-split routes and heavy components with lazy /Suspense; useTransition / useDeferredValue for heavy updates during typing; cache server data with TanStack Query; debounce inputs; use SSR/Server Components to reduce client JS; optimise images; always ship production builds."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"934","title":"What are React Server Components and how do they differ from SSR?","body":"SSR renders the whole component tree to HTML on the server per request, then ships all the component JS to hydrate it in the browser. Server Components are components that run only on the server (or at build time): they can access databases and secrets directly, and their code is never sent to the browser — only their rendered output (RSC payload). Client Components ( \"use client\" ) are still hydrated for interactivity. RSC and SSR are complementary — frameworks like Next.js use both."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"935","title":"What's new in React 18 and 19?","body":"React 18: concurrent rendering (interruptible rendering), createRoot , automatic batching of all state updates, transitions ( useTransition , startTransition ), useDeferredValue , useId , streaming SSR with Suspense. React 19: Actions (async functions in transitions and <form action ), useActionState , useFormStatus , useOptimistic , the use() API, ref as a prop (no forwardRef ), <Context as provider, document metadata tags, stable Server Components and Server Actions, and better hydration error messages. 19.2 added <Activity and useEffectEvent ."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"936","title":"What causes infinite re-render loops and how do you fix them?","body":"Setting state during render unconditionally ( setCount(count + 1) in the body), calling a handler instead of passing it ( onClick={handle()} ), or an effect that sets state which changes its own dependencies (objects/arrays/functions recreated each render in the dependency array). Fix by moving updates into event handlers, passing function references, computing derived values during render instead of in effects, memoising dependency objects or depending on primitive fields, and guarding effect updates with conditions."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"937","title":"A dashboard with many widgets re-renders entirely when the user types in a search box. How do you fix it?","body":"Find what re-renders with the Profiler. Usually the search state lives too high (in the page) so every widget re-renders. Move the search state down into the search component or the part that uses it; wrap expensive widgets in memo and pass stable props (or enable the React Compiler); use useDeferredValue for the filtered results so typing stays responsive; debounce the search before triggering data fetching; split a big context into smaller ones."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"938","title":"Fetching data in useEffect sometimes shows results for the previous user ID after switching quickly. Why and how to fix?","body":"Race condition: an older request resolves after a newer one and overwrites state. Fix by aborting the previous request in the effect cleanup ( AbortController ), or ignoring stale responses with a flag ( let ignore = false; return () = { ignore = true } ). Better: use TanStack Query/SWR or framework loaders, which key requests by parameters and handle caching, deduplication and races automatically."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"939","title":"How would you structure a large React application?","body":"Feature-based folders ( features/orders/{components,hooks,api,types} ) plus shared components/ui , lib , hooks ; a framework (Next.js) or Vite + React Router; TypeScript everywhere; server state in TanStack Query (or framework loaders), minimal global client state in Zustand/Redux Toolkit; a design system (Tailwind/shadcn or MUI); forms with React Hook Form + Zod; route-based code splitting; testing with Vitest + RTL + MSW and Playwright; ESLint (hooks rules) and Prettier; Storybook for shared components; CI with type checks, tests and bundle-size budgets."},{"kind":"question","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"940","title":"A modal rendered inside a card is cut off by `overflow: hidden` on the card. How do you fix it in React?","body":"Render the modal with a portal ( createPortal(<Modal / , document.body) or a dedicated modal-root ) so it's attached outside the card's DOM hierarchy while still part of the React tree (events and context still work). Manage focus trapping, Escape to close and aria-modal for accessibility — or use the native <dialog element or an accessible library (Radix UI)."},{"kind":"cheat","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"1","title":"Core","body":"Components = functions returning JSX · props down, callbacks up · state triggers re-render · keys for lists · immutable updates · fragments < ...</ ."},{"kind":"cheat","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"2","title":"Hooks","body":"useState · useEffect (deps, cleanup) · useLayoutEffect · useRef · useMemo · useCallback · useContext · useReducer · useId · useTransition · useDeferredValue · useSyncExternalStore · React 19: use · useActionState · useFormStatus · useOptimistic · 19.2: useEffectEvent ."},{"kind":"cheat","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"3","title":"Effect dependency rules","body":"none = every render · [] = mount/unmount · [x] = when x changes · cleanup before re-run and on unmount · abort fetches."},{"kind":"cheat","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"4","title":"Rules of Hooks","body":"Top level only · React functions only · names start with use ."},{"kind":"cheat","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"5","title":"Performance","body":"Profile → colocate state → memo + stable props (or React Compiler) → virtualise lists → lazy + Suspense → transitions → TanStack Query caching → SSR/RSC."},{"kind":"cheat","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"6","title":"State choices","body":"Local useState · complex useReducer · subtree Context · server data TanStack Query · global Zustand/Redux Toolkit · URL params · forms React Hook Form."},{"kind":"cheat","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"7","title":"Rendering models","body":"CSR · SSR + hydration · SSG/ISR · Server Components ( \"use server\" actions, \"use client\" components) · Next.js App Router."},{"kind":"cheat","course_slug":"react","course_title":"React (with Hooks, React 19 & Next.js basics)","ref":"8","title":"Versions","body":"16.8 Hooks (2019) · 18 concurrent + batching (2022) · 19 Actions + RSC stable (Dec 2024) · 19.2 Activity (Oct 2025) · React Compiler 1.0 · CRA deprecated (2025)."},{"kind":"course","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"","title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","body":"What Next.js adds to React, the App Router folder structure with sample files for every special file (layout, page, loading, error, not-found, route handlers, middleware/proxy), Server vs Client Components, rendering strategies (static, dynamic, streaming, ISR, partial prerendering), data fetching and caching, Server Actions and forms, metadata and SEO, connecting to SQL Server from server code (mssql, Prisma), authentication, deployment to Vercel/Azure/IIS, the Pages Router for legacy apps, and Next.js interview questions. Next.js (by Vercel) is a React framework for full stack web apps. React is a UI library; Next.js adds everything around it: file-based routing , server rendering , data fetching , API endpoints , image/font optimisation , SEO metadata , bundling and deployment. Feature Plain React (Vite SPA) Next.js --- --- --- Routing Add React Router File-system routing built in Rendering Client-side only Server Components, SSR, static generation, streaming SEO Hard (empty HTML until JS runs) Full HTML from the server, metadata API Backend code Separate API project Route handlers and Server Actions in the same project Data access Always through an API Server Components can query the database directly DevLadder itself is built with Next.js (App Router, Server Components reading SQLite, static generation, sitemap and metadata). Version Year Highlights --- --- --- 1–8 2016–2019 SSR for React, file routing ( pages/ ), dynamic routes, API routes (9) 9.3 – 12 2020–2021 getStaticProps / getServerSideProps , ISR, image component, middleware, Rust compiler (SWC) 13 2022 App Router ( app/ ) beta: layouts, Server Components, streaming; Turbopack alpha 13.4 2023 App Router stable; Server Actions (alpha) 14 2023 Server Actions stable, partial prerendering preview 15 2024 React 19, async request APIs ( await params ), caching defaults changed (fetch no longer cached by default), Turbopack dev stable 16 2025 Cache Components ( \"use cache\" ) and PPR, Turbopack default for builds, middleware renamed to proxy , React Compiler support, next typegen What happens on a request to /products/42 (App Router): 1. Request reaches the Next.js server (Node.js runtime, edge, or Vercel's infrastructure); proxy/middleware runs first (redirects, auth checks, rewrites). 2. The router matches the URL to app/products/[id]/page.tsx and its parent layouts . 3. Server Components render on the server: await params , fetch data (database, APIs) directly; the output is the RSC payload (a serialised component tree) and HTML. 4. Static parts may come from the cache (prerendered at build or revalidated); dynamic parts stream in with Suspense boundaries ( loading.tsx ). 5. The browser receives HTML immediately (fast first paint, SEO-friendly), then downloads JavaScript only for Client Components ( \"use client\" ) and hydrates them to make them interactive. 6. Navigations with <Link fetch only the RSC payload for the new route (no full page reload); prefetching happens for links in view. 7. Mutations go through Server Actions or route handlers; revalidatePath / revalidateTag / updateTag refresh cached data. - npx create-next-app@latest (TypeScript, ESLint, Tailwind, App Router, Turbopack options), next dev , next build , next start . - Vercel (hosting), @vercel/analytics , Next.js DevTools / React DevTools. - Data: Prisma, Drizzle, mssql , pg , @vercel/postgres /Neon, Supabase. - Auth: Auth.js (NextAuth), Clerk, Microsoft Entra ID (MSAL), custom JWT. - UI: Tailwind CSS, shadcn/ui, CSS Modules. - Testing: Vitest/Jest + React Testing Library, Playwright."},{"kind":"lesson","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"next-js-app-router-folder-structure-with-sample-files","title":"Next.js App Router folder structure — with sample files","body":"text my-shop/ ├── app/ ← App Router: folders = URL segments │ ├── layout.tsx root layout (required): <html , <body , shared nav/footer │ ├── page.tsx \"/\" home page │ ├── globals.css global styles │ ├── favicon.ico / icon.svg app icon (file convention) │ ├── not-found.tsx 404 UI │ ├── error.tsx error boundary for the segment (Client Component) │ ├── loading.tsx instant loading UI (Suspense fallback) │ ├── sitemap.ts · robots.ts · opengraph-image.tsx SEO file conventions │ ├── products/ │ │ ├── page.tsx \"/products\" │ │ ├── loading.tsx loading UI just for products │ │ └── [id]/ dynamic segment │ │ ├── page.tsx \"/products/42\" │ │ └── edit/page.tsx \"/products/42/edit\" │ ├── (shop)/ route GROUP — organises files, not part of the URL │ │ ├── layout.tsx layout only for pages in this group │ │ └── cart/page.tsx \"/cart\" │ ├── admin/ │ │ ├── layout.tsx admin layout (sidebar) │ │ └── [[...slug]]/page.tsx optional catch-all: \"/admin\", \"/admin/a/b\" │ ├── api/ │ │ └── products/route.ts route handler: GET/POST \"/api/products\" (REST API) │ └── components/ private folder (underscore) — not a route ├── components/ shared UI components (Button.tsx, ProductCard.tsx) ├── lib/ server/client utilities: db.ts, auth.ts, validation.ts ├── public/ static files served as-is: /logo.png, /robots.txt (if static) ├── proxy.ts (middleware.ts before v16) runs before requests: auth redirects, rewrites, headers ├── next.config.ts Next.js configuration (images, redirects, headers) ├── .env.local secrets for local dev (never commit) — DB connection string ├── tsconfig.json · eslint.config.mjs · package.json Sample files: tsx // app/layout.tsx — root layout import type { Metadata } from \"next\"; import \"./globals.css\"; export const metadata: Metadata = { title: { default: \"My Shop\", template: \"%s · My Shop\" }, description: \"Buy great things\" }; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang=\"en\" <body <header My Shop</header <main {children}</main <footer © 2026</footer </body </html ); } // app/products/[id]/page.tsx — dynamic Server Component page import { notFound } from \"next/navigation\"; import { getProduct } from \"@/lib/products\"; export async function generateMetadata({ params }: { params: Promise<{ id: string } }) { const p = await getProduct(Number((await params).id)); return { title: p?.name ?? \"Product\" }; } export default async function ProductPage({ params }: { params: Promise<{ id: string } }) { const product = await getProduct(Number((await params).id)); // runs on the server — can query the DB if (!product) notFound(); return <h1 {product.name} — ₹{product.price}</h1 ; } // app/products/loading.tsx export default function Loading() { return <p Loading products…</p ; } // app/error.tsx — must be a Client Component \"use client\"; export default function Error({ error, reset }: { error: Error; reset: () = void }) { return <div <p Something went wrong.</p <button onClick={() = reset()} Try again</button </div ; } // app/api/products/route.ts — REST endpoint import { NextResponse } from \"next/server\"; import { listProducts, createProduct } from \"@/lib/products\"; export async function GET() { return NextResponse.json(await listProducts()); } export async function POST(request: Request) { const body = await request.json(); return NextResponse.json(await createProduct(body), { status: 201 }); } // proxy.ts — protect /admin (named middleware.ts with export function middleware before Next 16) import { NextResponse, type NextRequest } from \"next/server\"; export function proxy(request: NextRequest) { if (!request.cookies.get(\"session\")) return NextResponse.redirect(new URL(\"/login\", request.url)); } export const config = { matcher: [\"/admin/:path \"] }; Special files (in order of nesting): layout → template → error → loading → not-found → page . A folder becomes a public route only when it has page.tsx or route.ts ."},{"kind":"lesson","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"server-components-vs-client-components","title":"Server Components vs Client Components","body":"Server Component (default) Client Component ( \"use client\" ) --- --- --- Runs On the server (build time or request) Server-rendered to HTML, then hydrated in the browser Can use async/await , database, file system, secrets useState , useEffect , event handlers, browser APIs JavaScript sent to browser None Yes (bundle) Typical Pages, data loading, layouts, static content Buttons, forms with state, modals, charts tsx // app/products/page.tsx (Server Component) import AddToCart from \"./AddToCart\"; import { listProducts } from \"@/lib/products\"; export default async function Products() { const products = await listProducts(); // direct DB call, no API needed return <ul {products.map((p) = <li key={p.id} {p.name} <AddToCart id={p.id} / </li )}</ul ; } // app/products/AddToCart.tsx (Client Component) \"use client\"; import { useState } from \"react\"; export default function AddToCart({ id }: { id: number }) { const [added, setAdded] = useState(false); return <button onClick={() = setAdded(true)} {added ? \"Added ✓\" : \"Add to cart\"}</button ; } Rules: push \"use client\" as far down the tree as possible; Server Components can render Client Components (props must be serialisable); Client Components can't import Server Components but can receive them as children ; mark server-only modules with import \"server-only\" so secrets never reach the browser."},{"kind":"lesson","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"rendering-strategies-static-dynamic-streaming-isr-and-ppr","title":"Rendering strategies — static, dynamic, streaming, ISR and PPR","body":"Strategy When HTML is produced Use --- --- --- Static (SSG) At build time ( generateStaticParams for dynamic routes) Marketing pages, docs, blogs, product catalogs that change rarely ISR / revalidation Static, regenerated after a time ( export const revalidate = 60 ) or on demand ( revalidatePath ) Catalogs, news Dynamic (SSR) On every request (uses cookies/headers/searchParams or uncached data) Personalised dashboards, carts Streaming Shell first, slow parts stream later via <Suspense / loading.tsx Pages with slow data Partial Prerendering (Cache Components) Static shell prerendered; dynamic holes stream in Best of both on one page (Next 16) Client-side rendering In the browser (Client Components + fetch/SWR/React Query) Highly interactive widgets tsx // Static generation of all product pages at build time export async function generateStaticParams() { return (await listProducts()).map((p) = ({ id: String(p.id) })); } export const revalidate = 3600; // re-generate at most once per hour"},{"kind":"lesson","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"data-fetching-caching-and-server-actions","title":"Data fetching, caching and Server Actions","body":"tsx // Fetch in a Server Component (Next 15+: not cached unless you opt in) const res = await fetch(\"https://api.example.com/rates\", { next: { revalidate: 300, tags: [\"rates\"] } }); // Next 16 Cache Components: cache a function's result async function getCategories() { \"use cache\"; return db.query(\"SELECT Id, Name FROM dbo.Categories\"); } Server Actions — functions that run on the server, callable from forms or client code (no API route needed): tsx // app/products/new/actions.ts \"use server\"; import { revalidatePath } from \"next/cache\"; import { redirect } from \"next/navigation\"; import { z } from \"zod\"; import { createProduct } from \"@/lib/products\"; const Schema = z.object({ name: z.string().min(2), price: z.coerce.number().positive() }); export async function addProduct(formData: FormData) { const parsed = Schema.safeParse(Object.fromEntries(formData)); if (!parsed.success) return { error: \"Invalid input\" }; await createProduct(parsed.data); // auth check here too — actions are public endpoints! revalidatePath(\"/products\"); redirect(\"/products\"); } // app/products/new/page.tsx import { addProduct } from \"./actions\"; export default function NewProduct() { return ( <form action={addProduct} <input name=\"name\" placeholder=\"Name\" required / <input name=\"price\" type=\"number\" step=\"0.01\" required / <button type=\"submit\" Save</button </form ); } Forms work even before JavaScript loads (progressive enhancement); useActionState and useFormStatus give pending/error states in Client Components."},{"kind":"lesson","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"connecting-next-js-to-sql-server","title":"Connecting Next.js to SQL Server","body":"Database code must run only on the server (Server Components, Server Actions, route handlers) — never in Client Components, or credentials would be exposed. ts // lib/db.ts import \"server-only\"; import sql from \"mssql\"; const config: sql.config = { server: process.env.DB SERVER!, database: process.env.DB NAME!, user: process.env.DB USER!, password: process.env.DB PASSWORD!, options: { encrypt: true, trustServerCertificate: process.env.NODE ENV !== \"production\" }, pool: { max: 10 }, }; // Reuse one pool across hot reloads in development and across requests in production const globalForDb = globalThis as unknown as { mssqlPool?: Promise<sql.ConnectionPool }; export const pool = globalForDb.mssqlPool ?? new sql.ConnectionPool(config).connect(); if (process.env.NODE ENV !== \"production\") globalForDb.mssqlPool = pool; // lib/products.ts import \"server-only\"; import { pool } from \"./db\"; import sql from \"mssql\"; export type Product = { id: number; name: string; price: number }; export async function listProducts(): Promise<Product[] { const r = await (await pool).request().query(\"SELECT Id AS id, Name AS name, Price AS price FROM dbo.Products ORDER BY Name\"); return r.recordset; } export async function getProduct(id: number): Promise<Product undefined { const r = await (await pool).request().input(\"id\", sql.Int, id) .query(\"SELECT Id AS id, Name AS name, Price AS price FROM dbo.Products WHERE Id = @id\"); return r.recordset[0]; } export async function createProduct(p: { name: string; price: number }) { const r = await (await pool).request().input(\"name\", sql.NVarChar(200), p.name).input(\"price\", sql.Decimal(18, 2), p.price) .query(\"INSERT INTO dbo.Products (Name, Price) OUTPUT INSERTED.Id AS id VALUES (@name, @price)\"); return { id: r.recordset[0].id as number, ...p }; } bash .env.local (not committed; set the same keys in Vercel/Azure settings) DB SERVER=localhost DB NAME=Shop DB USER=shop app DB PASSWORD=change-me - Route handlers using mssql must run on the Node.js runtime (the default), not the Edge runtime. - With Prisma : provider = \"sqlserver\" in schema.prisma , a single PrismaClient instance kept on globalThis in development. - Serverless platforms (Vercel) open connections per function instance — keep pools small and prefer a database in the same region; Azure SQL serverless works well. - Alternative architecture: Next.js frontend calling an ASP.NET Core Web API that owns SQL Server (common in .NET shops) — then Next.js only does fetch to the API."},{"kind":"lesson","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"metadata-seo-images-fonts-and-performance","title":"Metadata, SEO, images, fonts and performance","body":"tsx export const metadata = { title: \"Products\", description: \"All products\", alternates: { canonical: \"/products\" }, openGraph: { images: [\"/og.png\"] } }; import Image from \"next/image\"; <Image src=\"/hero.jpg\" alt=\"Shop hero\" width={1200} height={600} priority / // resized, lazy, modern formats import { Inter } from \"next/font/google\"; const inter = Inter({ subsets: [\"latin\"] }); // self-hosted font, no layout shift File conventions sitemap.ts , robots.ts , opengraph-image.tsx , icon.tsx generate SEO files. Performance: Server Components (less JS), streaming, next/image , next/link prefetching, dynamic import() for heavy client components, bundle analyzer."},{"kind":"lesson","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"authentication-and-deployment-vercel-azure-iis-docker","title":"Authentication and deployment (Vercel, Azure, IIS, Docker)","body":"Authentication: Auth.js/NextAuth (OAuth providers, credentials, Microsoft Entra ID), Clerk, or your own JWT/cookie session. Check auth in three places : proxy (fast redirects), Server Components/layouts (render), and every Server Action/route handler (security — they're public endpoints). Deployment options: Target How --- --- Vercel Connect the Git repo; every push deploys (preview per branch, production on main); env vars in project settings Azure App Service (Linux, Node) / Azure Static Web Apps (hybrid Next.js) next build with output: \"standalone\" , deploy the .next/standalone folder, start with node server.js Docker Multi-stage build using the standalone output; run on Container Apps, AKS, ECS, Cloud Run IIS (Windows Server) Run node server.js as a service (PM2/NSSM) on a port and put IIS in front as a reverse proxy (URL Rewrite + ARR), or use iisnode Static export output: \"export\" for fully static sites (no server features) ts // next.config.ts const nextConfig = { output: \"standalone\" }; // self-contained server bundle for Docker/Azure/IIS export default nextConfig;"},{"kind":"lesson","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"pages-router-legacy-vs-app-router","title":"Pages Router (legacy) vs App Router","body":"Many existing apps still use the Pages Router ( pages/ folder): text pages/ ├── app.tsx wraps every page (global CSS, providers) ├── document.tsx custom <html /<body ├── index.tsx \"/\" ├── products/[id].tsx \"/products/42\" └── api/products.ts API route: export default function handler(req, res) tsx // Pages Router data fetching export async function getServerSideProps({ params }) { return { props: { product: await getProduct(Number(params.id)) } }; } // per request export async function getStaticProps() { return { props: { products: await listProducts() }, revalidate: 60 }; } // build + ISR export async function getStaticPaths() { return { paths: [], fallback: \"blocking\" }; } Pages Router App Router --- --- getServerSideProps / getStaticProps async Server Components + fetch /DB calls, revalidate , generateStaticParams app.tsx / document.tsx app/layout.tsx API routes pages/api/ .ts Route handlers app/ /route.ts + Server Actions All components are client components Server Components by default next/head Metadata API Both routers can coexist during a gradual migration."},{"kind":"question","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"941","title":"What is Next.js and how is it different from React?","body":"React is a library for building UI components. Next.js is a React framework that adds file-based routing, server-side and static rendering, Server Components, data fetching and caching, API endpoints (route handlers, Server Actions), image/font optimisation, SEO metadata and production build/deployment tooling. It produces full HTML from the server, improving SEO and first load."},{"kind":"question","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"942","title":"Explain the App Router folder structure and special files.","body":"Folders inside app/ map to URL segments; a segment becomes routable with page.tsx (UI) or route.ts (API). layout.tsx wraps child pages and persists across navigation; loading.tsx is the Suspense fallback; error.tsx is the error boundary; not-found.tsx shows 404s. [id] is a dynamic segment, [...slug] catch-all, (group) organises without affecting URLs, folder is private."},{"kind":"question","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"943","title":"What are Server Components and Client Components?","body":"Server Components (default in the App Router) render on the server, can be async and access databases/secrets directly, and send no JavaScript to the browser. Client Components ( \"use client\" ) are hydrated in the browser and can use state, effects and event handlers. Use server by default and client only for interactive parts."},{"kind":"question","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"944","title":"What rendering strategies does Next.js support?","body":"Static generation at build time (with generateStaticParams ), Incremental Static Regeneration (time-based revalidate or on-demand revalidatePath/Tag ), dynamic server rendering per request, streaming with Suspense, Partial Prerendering/Cache Components (static shell + dynamic holes), and client-side rendering inside Client Components. Choose per page/component based on how fresh and personalised the data must be."},{"kind":"question","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"945","title":"What are Server Actions and what must you be careful about?","body":"Async functions marked \"use server\" that run on the server and can be called from forms ( <form action={fn} ) or client code, used for mutations without writing API routes; they integrate with revalidation and redirects and work without JavaScript. Careful: each action is effectively a public HTTP endpoint — always authenticate, authorise and validate input inside it, and don't return sensitive data."},{"kind":"question","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"946","title":"How do you connect Next.js to SQL Server safely?","body":"Only from server code — Server Components, Server Actions and route handlers on the Node.js runtime — using mssql (one shared connection pool kept on globalThis in development) or Prisma with the sqlserver provider; mark modules import \"server-only\" , keep credentials in environment variables, use parameterised queries, and keep the database close to the hosting region. Alternatively call an ASP.NET Core API that owns the database."},{"kind":"question","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"947","title":"What is middleware (proxy in Next 16) used for?","body":"Code that runs before a request is routed — redirects, rewrites, authentication gates, A/B testing, adding headers, localisation — configured with a matcher . It should be fast and must not be the only security check; validate access again in pages, actions and route handlers."},{"kind":"question","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"948","title":"How does Next.js help SEO?","body":"Pages render to full HTML on the server (static or dynamic), so crawlers see content immediately; the Metadata API and generateMetadata set titles, descriptions, canonical URLs and Open Graph tags; file conventions generate sitemap.xml , robots.txt and OG images; next/image and next/font improve Core Web Vitals; clean URLs from file routing."},{"kind":"question","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"949","title":"Pages Router vs App Router?","body":"Pages Router uses pages/ , getServerSideProps/getStaticProps , app/ document and API routes; every component is a client component. App Router uses app/ , nested layouts, React Server Components, streaming, Server Actions, route handlers and the Metadata API, with fetch/caching integrated. New projects use the App Router; both can coexist for incremental migration."},{"kind":"question","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"950","title":"What is hydration and what causes hydration errors?","body":"Hydration attaches React's event handlers and state to server-rendered HTML in the browser. Errors happen when the client's first render differs from the server HTML — using Date.now() /random values, window / localStorage during render, locale-dependent formatting, invalid HTML nesting, or browser extensions modifying the DOM. Fix by rendering client-only values in useEffect , consistent formatting, or suppressHydrationWarning for intentional differences."},{"kind":"question","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"951","title":"A product listing page is slow because it queries SQL Server on every request, but prices change only once a day. What do you do?","body":"Make it static or cached: use generateStaticParams + revalidate = 86400 (ISR) or cache the query function ( \"use cache\" with a cache life / unstable cache in older versions), and call revalidatePath(\"/products\") or revalidateTag from the admin update action so changes appear immediately. Add proper indexes for the query, and keep only truly personalised parts (cart badge) dynamic."},{"kind":"question","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"952","title":"After deployment, a page shows stale data even after the database changed. Why?","body":"The route or fetch is statically generated or cached (build-time rendering, revalidate , \"use cache\" , cached fetch). Trigger on-demand revalidation ( revalidatePath / revalidateTag / updateTag ) after mutations, lower the revalidate interval, or make the route dynamic if it must always be fresh (reading cookies/headers or connection() )."},{"kind":"question","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"953","title":"Your Next.js app works locally but database calls fail on Vercel. What do you check?","body":"Environment variables set in the Vercel project for the right environment; the database firewall allows Vercel's outbound IPs (or use Azure SQL with public access rules / private networking); encrypt: true and valid certificates (no trustServerCertificate against a misconfigured server); the route runs on the Node.js runtime (not Edge); connection limits from many serverless instances (small pools); region latency."},{"kind":"question","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"954","title":"What is the difference between `next/link` and `<a>`?","body":"<Link performs client-side navigation — it fetches only the new route's payload, keeps layouts mounted and prefetches linked routes in the viewport — so navigation is fast without full page reloads. A plain <a causes a full browser navigation. Use <Link for internal links and <a for external ones."},{"kind":"question","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"955","title":"How do you handle environment variables in Next.js?","body":"Server-only variables in .env.local /hosting settings are read via process.env.X on the server. Variables prefixed NEXT PUBLIC are inlined into client bundles at build time — never put secrets there. Different files per environment ( .env.development , .env.production ); validate them at startup (zod)."},{"kind":"cheat","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"1","title":"Folder conventions","body":"app/ routes · page.tsx · layout.tsx · loading.tsx · error.tsx · not-found.tsx · route.ts (API) · [id] dynamic · [...slug] catch-all · (group) · private · proxy.ts (middleware) · public/ static."},{"kind":"cheat","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"2","title":"Components","body":"Server by default (async, DB, secrets, zero JS) · \"use client\" for state/events · keep client components small · import \"server-only\" for DB code."},{"kind":"cheat","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"3","title":"Rendering","body":"Static + generateStaticParams · ISR revalidate · on-demand revalidatePath/Tag · dynamic per request · streaming Suspense · Cache Components \"use cache\" (16)."},{"kind":"cheat","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"4","title":"SQL Server","body":"mssql pool on globalThis · Node runtime · env vars (no NEXT PUBLIC ) · parameterised queries · or Prisma sqlserver · or call an ASP.NET Core API."},{"kind":"cheat","course_slug":"nextjs","course_title":"Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server","ref":"5","title":"Deploy","body":"Vercel (git push) · output: \"standalone\" for Docker/Azure/IIS (reverse proxy) · output: \"export\" for static sites."},{"kind":"course","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"","title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","body":"Vue instance and SFCs, template syntax and directives, reactivity (ref, reactive, computed, watch), Options vs Composition API, components, props, emits, slots, provide/inject, lifecycle hooks, composables, Vue Router, Pinia, forms, performance, testing and Nuxt. Vue.js is a progressive JavaScript framework for building user interfaces, created by Evan You (ex-Google, worked on AngularJS) in 2014. \"Progressive\" means you can use it as a drop-in script to enhance a page, or as a full SPA framework with router, state management and SSR. Key characteristics: - Single-File Components (SFCs) — .vue files with <template , <script and <style together. - Declarative templates with directives ( v-if , v-for , v-model , v-bind , v-on ). - Fine-grained reactivity — Vue tracks which components depend on which state (via JavaScript Proxies in Vue 3) and re-renders only what's needed. - Two API styles: Options API ( data , methods , computed ) and Composition API ( ref , reactive , computed inside <script setup ). - Official ecosystem: Vue Router , Pinia (state), Vite (build tool, also created by Evan You), Vue DevTools , Nuxt (full-stack framework, third-party but closely aligned). Vue sits between AngularJS-style templates and React-style components: approachable for beginners, scalable for large apps (used by Alibaba, Xiaomi, GitLab, Nintendo and many Asian companies). Version Date Highlights --- --- --- 0.x Feb 2014 First public release 1.0 Oct 2015 \"Evangelion\" 2.0 Sep 2016 Virtual DOM, server-side rendering, render functions 2.5 / 2.6 2017 / 2019 Better TypeScript; 2.6 v-slot syntax 2.7 Jul 2022 \"Naruto\" — backports Composition API and <script setup to Vue 2 — 31 Dec 2023 Vue 2 end of life (commercial extended support available, e.g. HeroDevs) 3.0 Sep 2020 \"One Piece\": Composition API , Proxy-based reactivity, Fragments, Teleport, Suspense, better TypeScript, smaller and faster 3.2 Aug 2021 <script setup stable, v-memo , defineCustomElement 3.3 May 2023 Generic components, imported types in defineProps , defineOptions , defineSlots 3.4 Dec 2023 Rewritten template parser (2× faster), defineModel stable, v-bind same-name shorthand 3.5 Sep 2024 Reactivity memory/performance overhaul, reactive props destructure , useTemplateRef , useId , lazy hydration, onWatcherCleanup 3.6 (in development) 2025– Vapor Mode (compile without virtual DOM, opt-in, alpha), alien-signals based reactivity Ecosystem: Vuex (official store for Vue 2) → Pinia became the official recommendation (2022). Vue CLI (webpack) → create-vue + Vite . Nuxt 3 (2022), Nuxt 4 (July 2025). Component lifecycle (Composition API hook → Options API name): Phase Composition API Options API Use --- --- --- --- Setup setup() / <script setup runs beforeCreate , created Initialise state; no DOM yet Before mount onBeforeMount beforeMount Template compiled, about to render Mounted onMounted mounted DOM available — fetch data, third-party libs, focus Before update onBeforeUpdate beforeUpdate State changed, before DOM patch Updated onUpdated updated DOM patched (avoid changing state here) Before unmount onBeforeUnmount beforeUnmount (Vue 2: beforeDestroy ) Cleanup start Unmounted onUnmounted unmounted (Vue 2: destroyed ) Remove listeners, timers Errors onErrorCaptured errorCaptured Error from a descendant KeepAlive onActivated / onDeactivated activated / deactivated Cached components shown/hidden SSR onServerPrefetch serverPrefetch Fetch data during SSR Reactivity update cycle: state change → the reactive Proxy's set trap triggers the effects (components, computeds, watchers) that read that property → component re-render is queued and batched in the next microtask ( nextTick ) → virtual DOM diff (optimised by compiler hints: static hoisting, patch flags, block tree) → DOM patched → onUpdated . App bootstrap: createApp(App) → app.use(router) , app.use(createPinia()) , global components/directives → app.mount(\" app\") . Tool Use --- --- npm create vue@latest (create-vue) Scaffold a Vite-based project (TS, Router, Pinia, Vitest, ESLint options) Vite Dev server and build Vue DevTools (browser extension + Vite plugin) Inspect components, Pinia, router, timeline VS Code + Vue - Official extension (Volar) SFC IntelliSense and type checking ( vue-tsc ) Vue Router, Pinia Routing and state VueUse Collection of composables Vuetify, PrimeVue, Element Plus, Naive UI, Quasar UI libraries VeeValidate, FormKit, Zod/Yup Forms and validation Vitest + Vue Test Utils , Playwright/Cypress Testing Nuxt SSR/SSG/full-stack framework Vite-SSG, Pinia Colada / TanStack Query for Vue Static generation and data fetching"},{"kind":"lesson","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"creating-an-app-and-single-file-components","title":"Creating an app and Single-File Components","body":"bash npm create vue@latest shop choose TypeScript, Router, Pinia, Vitest, ESLint cd shop && npm install && npm run dev vue <!-- src/components/OrderCard.vue -- <script setup lang=\"ts\" import { computed } from \"vue\"; const props = defineProps<{ order: { id: number; customer: string; total: number; status: string } } (); const emit = defineEmits<{ select: [id: number] } (); const isBig = computed(() = props.order.total 10000); </script <template <div class=\"card\" :class=\"{ big: isBig, paid: order.status === 'paid' }\" @click=\"emit('select', order.id)\" <h3 {{ order.id }} — {{ order.customer }}</h3 <p {{ order.total.toLocaleString(\"en-IN\", { style: \"currency\", currency: \"INR\" }) }}</p </div </template <style scoped .card { padding: 1rem; border: 1px solid ddd; } .big { border-color: gold; } </style ts // src/main.ts import { createApp } from \"vue\"; import { createPinia } from \"pinia\"; import App from \"./App.vue\"; import router from \"./router\"; createApp(App).use(createPinia()).use(router).mount(\" app\"); <style scoped adds a data attribute so styles apply only to this component; :deep() reaches into children; CSS modules via <style module ."},{"kind":"lesson","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"template-syntax-and-directives","title":"Template syntax and directives","body":"vue <template <p {{ message.toUpperCase() }}</p <!-- interpolation (escaped) -- <p v-html=\"trustedHtml\" </p <!-- raw HTML: XSS risk with user input -- <img :src=\"product.image\" :alt=\"product.name\" / <!-- v-bind shorthand ':' -- <button @click=\"addToCart(product)\" Add</button <!-- v-on shorthand '@' -- <form @submit.prevent=\"save\" <!-- event modifiers: .prevent .stop .once .self -- <input v-model.trim=\"name\" @keyup.enter=\"save\" / <!-- v-model modifiers: .trim .number .lazy -- </form <p v-if=\"orders.length === 0\" No orders</p <p v-else-if=\"loading\" Loading…</p <ul v-else <li v-for=\"(o, index) in orders\" :key=\"o.id\" {{ index + 1 }}. {{ o.customer }}</li </ul <div v-show=\"isOpen\" Toggled with CSS display</div <span v-once {{ initialValue }}</span <!-- render once -- <component :is=\"currentTab\" / <!-- dynamic component -- </template Directive Purpose --- --- v-bind / : Bind attribute/prop v-on / @ Listen to events v-model Two-way binding on inputs/components v-if / v-else-if / v-else Conditional rendering (creates/destroys) v-show Toggle display (stays in DOM) v-for Lists (always with :key ) v-html , v-text Raw HTML / text v-slot / Named/scoped slots v-once , v-memo , v-pre , v-cloak Render optimisation / skip compilation Avoid v-if and v-for on the same element (in Vue 3 v-if has higher priority) — filter in a computed property or wrap with <template ."},{"kind":"lesson","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"vue-3-project-folder-structure-with-sample-files","title":"Vue 3 project folder structure — with sample files","body":"npm create vue@latest shop-ui (Vite + Vue 3, optional TypeScript, Router, Pinia, Vitest) creates: text shop-ui/ ├── index.html mount point <div id=\"app\" ├── public/ static files (favicon) ├── src/ │ ├── main.ts createApp(App).use(router).use(pinia).mount(' app') │ ├── App.vue root component with <RouterView / │ ├── router/index.ts route definitions │ ├── stores/ Pinia stores (cart.ts, auth.ts) │ ├── views/ page-level components mapped to routes (ProductsView.vue) │ ├── components/ reusable components (ProductCard.vue, BaseButton.vue) │ ├── composables/ reusable composition functions (useProducts.ts, useDebounce.ts) │ ├── services/ API calls (api.ts, productService.ts) │ ├── assets/ css, images │ └── types/ shared TypeScript types ├── .env.development / .env.production VITE API URL=... ├── vite.config.ts · tsconfig.json · package.json ts // src/main.ts import { createApp } from \"vue\"; import { createPinia } from \"pinia\"; import App from \"./App.vue\"; import router from \"./router\"; createApp(App).use(createPinia()).use(router).mount(\" app\"); // src/router/index.ts import { createRouter, createWebHistory } from \"vue-router\"; export default createRouter({ history: createWebHistory(), routes: [ { path: \"/\", component: () = import(\"../views/ProductsView.vue\") }, // lazy-loaded route { path: \"/products/:id\", component: () = import(\"../views/ProductDetailView.vue\"), props: true }, ], }); vue <!-- src/App.vue -- <template <header <RouterLink to=\"/\" Shop</RouterLink </header <main <RouterView / </main </template Nuxt projects (the Vue meta-framework, like Next.js for React) use pages/ , components/ , composables/ , server/api/ (server routes) and nuxt.config.ts ."},{"kind":"lesson","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"connecting-a-vue-app-to-sql-server-through-an-api","title":"Connecting a Vue app to SQL Server (through an API)","body":"Like every browser framework, Vue talks to an HTTP API , and the API talks to SQL Server (ASP.NET Core with EF Core/Dapper, or Node.js with mssql ; with Nuxt the server/api routes can query SQL Server directly on the server). ts // src/services/api.ts const BASE = import.meta.env.VITE API URL ?? \"\"; export async function api<T (path: string, init?: RequestInit): Promise<T { const res = await fetch( ${BASE}${path} , { ...init, headers: { \"Content-Type\": \"application/json\", ...init?.headers } }); if (!res.ok) throw new Error( API ${res.status} ); return res.json(); } // src/composables/useProducts.ts import { ref, onMounted } from \"vue\"; import { api } from \"../services/api\"; export type Product = { id: number; name: string; price: number }; export function useProducts() { const products = ref<Product[] ([]); const loading = ref(true); const error = ref<string null (null); onMounted(async () = { try { products.value = await api<Product[] (\"/api/products\"); } catch { error.value = \"Could not load products\"; } finally { loading.value = false; } }); return { products, loading, error }; } vue <!-- src/views/ProductsView.vue -- <script setup lang=\"ts\" import { useProducts } from \"../composables/useProducts\"; const { products, loading, error } = useProducts(); </script <template <p v-if=\"loading\" Loading…</p <p v-else-if=\"error\" {{ error }}</p <ul v-else <li v-for=\"p in products\" :key=\"p.id\" {{ p.name }} — ₹{{ p.price }}</li </ul </template ts // Nuxt server route — runs on the server, safe to use SQL credentials // server/api/products.get.ts import sql from \"mssql\"; const pool = new sql.ConnectionPool(useRuntimeConfig().db).connect(); export default defineEventHandler(async () = (await (await pool).request().query(\"SELECT Id, Name, Price FROM dbo.Products\")).recordset); Dev proxy in vite.config.ts ( server.proxy['/api'] ) avoids CORS locally; in production enable CORS on the API for the app's origin or serve both from the same domain."},{"kind":"lesson","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"ref-reactive-computed-and-watch","title":"ref, reactive, computed and watch","body":"ts import { ref, reactive, computed, watch, watchEffect } from \"vue\"; const count = ref(0); // any value; access .value in script, auto-unwrapped in templates count.value++; const cart = reactive({ items: [] as Item[], coupon: \"\" }); // objects only; deep reactive Proxy cart.items.push({ id: 1, price: 900, qty: 2 }); const total = computed(() = cart.items.reduce((s, i) = s + i.price i.qty, 0)); // cached until deps change watch(count, (newVal, oldVal) = console.log( count ${oldVal} → ${newVal} )); // specific source, lazy watch(() = cart.coupon, async code = { cart.discount = await validateCoupon(code); }); watch(() = props.userId, id = loadUser(id), { immediate: true }); watchEffect(() = console.log(\"total is\", total.value)); // runs immediately, auto-tracks dependencies ref reactive --- --- --- Holds Any type (primitives too) Objects, arrays, Maps, Sets Access .value in script Direct property access Reassign whole value Yes ( x.value = newObj ) No — replacing the variable breaks reactivity Destructuring Fine Loses reactivity — use toRefs() Recommendation from the Vue docs: prefer ref as the primary API. shallowRef / shallowReactive for large non-deep data; readonly() to expose state safely; toRaw() / markRaw() to opt out. computed vs watch vs methods: computed = derived value, cached; methods = called every time (event handlers or uncached work); watch = side effects in response to changes (API calls, localStorage)."},{"kind":"lesson","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"how-vue-3-reactivity-works","title":"How Vue 3 reactivity works","body":"- reactive() wraps an object in a Proxy : the get trap tracks which running effect (component render, computed, watcher) read the property; the set trap triggers those effects. - ref() is an object with a getter/setter on .value doing the same tracking. - Effects re-run → component re-render is scheduled → batched → DOM patched in the next tick ( await nextTick() to read updated DOM). - Vue 2 used Object.defineProperty , so it couldn't detect added/deleted properties or array index assignment — you needed Vue.set / this.$set . Vue 3's Proxies detect all of these. ts const state = reactive({ user: { name: \"Asha\" } }); state.user.email = \"a@x.com\"; // reactive in Vue 3 (needed Vue.set in Vue 2) const arr = reactive([1, 2, 3]); arr[0] = 99; // reactive in Vue 3"},{"kind":"lesson","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"options-api-vs-composition-api","title":"Options API vs Composition API","body":"vue <!-- Options API -- <script export default { props: { initial: { type: Number, default: 0 } }, data() { return { count: this.initial }; }, computed: { double() { return this.count 2; } }, watch: { count(n) { console.log(n); } }, methods: { increment() { this.count++; } }, mounted() { console.log(\"mounted\"); }, }; </script <!-- Composition API with <script setup -- <script setup import { ref, computed, watch, onMounted } from \"vue\"; const props = defineProps({ initial: { type: Number, default: 0 } }); const count = ref(props.initial); const double = computed(() = count.value 2); watch(count, n = console.log(n)); const increment = () = count.value++; onMounted(() = console.log(\"mounted\")); </script Options API Composition API --- --- --- Organisation By option type (data/methods/computed) By feature/logic Reuse Mixins (name clashes, unclear origin) Composables (plain functions) TypeScript Weaker inference Excellent Learning curve Easier for beginners More flexible, better for large apps this Used everywhere No this Both are fully supported in Vue 3; new projects usually use <script setup + Composition API."},{"kind":"lesson","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"props-emits-and-v-model-on-components","title":"Props, emits and v-model on components","body":"vue <!-- ChildInput.vue -- <script setup lang=\"ts\" const model = defineModel<string ({ required: true }); // Vue 3.4+: two-way binding helper const props = withDefaults(defineProps<{ label: string; max?: number } (), { max: 100 }); const emit = defineEmits<{ (e: \"submit\", value: string): void } (); </script <template <label {{ label }} <input v-model=\"model\" :maxlength=\"max\" @keyup.enter=\"emit('submit', model)\" / </label </template <!-- Parent.vue -- <ChildInput v-model=\"search\" label=\"Search\" @submit=\"runSearch\" / - One-way data flow : props flow down and are read-only in the child (Vue warns if you mutate them). To change data, emit an event or use v-model . - Prop validation ( type , required , default , validator ) or TypeScript types. - v-model on a component = modelValue prop + update:modelValue event (multiple: v-model:title ). - Fallthrough attributes ( class , id , listeners) apply to the root element ( inheritAttrs: false + v-bind=\"$attrs\" to control)."},{"kind":"lesson","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"slots-provide-inject-and-component-communication","title":"Slots, provide/inject and component communication","body":"vue <!-- Card.vue -- <template <div class=\"card\" <header <slot name=\"title\" Default title</slot </header <slot / <!-- default slot -- <footer <slot name=\"footer\" :total=\"total\" / </footer <!-- scoped slot passes data up to the parent's template -- </div </template <!-- usage -- <Card <template title <h3 Orders</h3 </template <p Body content</p <template footer=\"{ total }\" Total: {{ total }}</template </Card ts // provide/inject: pass data deep without prop drilling // Ancestor provide(\"theme\", readonly(theme)); // Any descendant const theme = inject(\"theme\", ref(\"light\")); // default value Communication How --- --- Parent → child Props Child → parent Emits (events), v-model Parent calls child Template ref + defineExpose() in the child Deep descendants provide / inject Siblings / global Pinia store (or a shared composable) Routing Route params/query Avoid the old Vue 2 event bus ( new Vue() as emitter) — use Pinia or a small mitt emitter if truly needed."},{"kind":"lesson","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"composables-reusable-logic","title":"Composables (reusable logic)","body":"ts // composables/useFetch.ts import { ref, watchEffect, toValue, type MaybeRefOrGetter } from \"vue\"; export function useFetch<T (url: MaybeRefOrGetter<string ) { const data = ref<T null (null); const error = ref<Error null (null); const loading = ref(false); watchEffect(async onCleanup = { const controller = new AbortController(); onCleanup(() = controller.abort()); loading.value = true; error.value = null; try { const res = await fetch(toValue(url), { signal: controller.signal }); if (!res.ok) throw new Error( HTTP ${res.status} ); data.value = await res.json(); } catch (e) { if ((e as Error).name !== \"AbortError\") error.value = e as Error; } finally { loading.value = false; } }); return { data, error, loading }; } // In a component const { data: orders, loading } = useFetch<Order[] (() = /api/orders?page=${page.value} ); Composables are functions named useXxx that use Composition API features; each call gets its own state (or share module-level state for a singleton). VueUse offers 200+ ready-made composables ( useLocalStorage , useDebounceFn , useIntersectionObserver )."},{"kind":"lesson","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"built-in-components-transition-keepalive-teleport-suspense","title":"Built-in components: Transition, KeepAlive, Teleport, Suspense","body":"vue <Transition name=\"fade\" <p v-if=\"show\" Hello</p </Transition <!-- CSS classes fade-enter-from, fade-leave-to... -- <TransitionGroup tag=\"ul\" name=\"list\" <li v-for=\"i in items\" :key=\"i.id\" {{ i.name }}</li </TransitionGroup <KeepAlive :include=\"['OrderList']\" :max=\"10\" <!-- cache component instances (keep state) -- <component :is=\"currentView\" / </KeepAlive <Teleport to=\"body\" <Modal v-if=\"open\" @close=\"open = false\" / </Teleport <!-- render elsewhere in the DOM -- <Suspense <!-- async setup / async components (experimental API) -- <AsyncDashboard / <template fallback Loading…</template </Suspense Async components: defineAsyncComponent(() = import(\"./Reports.vue\")) for code splitting."},{"kind":"lesson","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"vue-router","title":"Vue Router","body":"ts // router/index.ts import { createRouter, createWebHistory } from \"vue-router\"; const router = createRouter({ history: createWebHistory(), // or createWebHashHistory() routes: [ { path: \"/\", component: () = import(\"@/views/Home.vue\") }, { path: \"/orders\", name: \"orders\", component: () = import(\"@/views/Orders.vue\") }, { path: \"/orders/:id(\\\\d+)\", name: \"order\", component: () = import(\"@/views/OrderDetail.vue\"), props: true }, { path: \"/admin\", component: () = import(\"@/views/Admin.vue\"), meta: { requiresAuth: true }, children: [{ path: \"users\", component: () = import(\"@/views/AdminUsers.vue\") }] }, { path: \"/:pathMatch(. ) \", component: () = import(\"@/views/NotFound.vue\") }, ], }); router.beforeEach(to = { // global navigation guard const auth = useAuthStore(); if (to.meta.requiresAuth && !auth.isLoggedIn) return { name: \"login\", query: { redirect: to.fullPath } }; }); export default router; vue <RouterLink :to=\"{ name: 'order', params: { id: o.id } }\" Open</RouterLink <RouterView / <script setup import { useRoute, useRouter } from \"vue-router\"; const route = useRoute(); // route.params.id, route.query const router = useRouter(); // router.push({ name: \"orders\" }) </script Guards: global ( beforeEach , beforeResolve , afterEach ), per-route ( beforeEnter ), in-component ( onBeforeRouteLeave , onBeforeRouteUpdate ). History mode needs a server fallback to index.html ."},{"kind":"lesson","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"pinia-state-management","title":"Pinia state management","body":"ts // stores/cart.ts — setup store syntax import { defineStore } from \"pinia\"; import { ref, computed } from \"vue\"; export const useCartStore = defineStore(\"cart\", () = { const items = ref<CartItem[] ([]); const total = computed(() = items.value.reduce((s, i) = s + i.price i.qty, 0)); // getter function add(item: CartItem) { items.value.push(item); } // action async function checkout() { await api.checkout(items.value); items.value = []; } return { items, total, add, checkout }; }); // In a component const cart = useCartStore(); const { items, total } = storeToRefs(cart); // keep reactivity when destructuring state/getters cart.add({ id: 1, name: \"Mouse\", price: 900, qty: 1 }); Pinia vs Vuex: Pinia (official since 2022) has no mutations (actions change state directly), a simpler API, full TypeScript inference, modular stores by default (no nested modules/namespaces), DevTools support and a tiny size. Vuex 4 is maintenance-only. Options-store syntax ( state , getters , actions ) is also supported."},{"kind":"lesson","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"forms-and-validation","title":"Forms and validation","body":"vue <script setup lang=\"ts\" import { reactive, computed } from \"vue\"; const form = reactive({ email: \"\", qty: 1, agree: false, size: \"M\", tags: [] as string[] }); const emailError = computed(() = form.email && !/^\\S+@\\S+\\.\\S+$/.test(form.email) ? \"Invalid email\" : \"\"); const canSubmit = computed(() = !emailError.value && form.email && form.agree); </script <template <form @submit.prevent=\"canSubmit && save(form)\" <input v-model.trim=\"form.email\" type=\"email\" / <small v-if=\"emailError\" {{ emailError }}</small <input v-model.number=\"form.qty\" type=\"number\" min=\"1\" / <input v-model=\"form.agree\" type=\"checkbox\" / <select v-model=\"form.size\" <option S</option <option M</option <option L</option </select <label <input v-model=\"form.tags\" type=\"checkbox\" value=\"gift\" / Gift</label <button :disabled=\"!canSubmit\" Save</button </form </template For larger forms: VeeValidate (+ Zod/Yup schemas) or FormKit ."},{"kind":"lesson","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"performance-optimisation","title":"Performance optimisation","body":"1. Lazy-load routes and heavy components ( () = import() , defineAsyncComponent ). 2. Stable :key s; avoid v-if + v-for together; prefer v-show for frequent toggles. 3. Virtual scrolling for long lists (vue-virtual-scroller, TanStack Virtual). 4. shallowRef / shallowReactive / markRaw for large immutable data or third-party instances. 5. v-once / v-memo for static or rarely changing subtrees. 6. Computed properties instead of methods in templates (cached). 7. Keep props stable so child components don't re-render unnecessarily (Vue already skips children whose props didn't change). 8. KeepAlive for tabs to avoid re-creating components. 9. SSR/SSG with Nuxt for first paint and SEO; lazy hydration (3.5). 10. Analyse bundles ( rollup-plugin-visualizer ), tree-shake imports, production builds."},{"kind":"lesson","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"testing-vue-components","title":"Testing Vue components","body":"ts import { mount } from \"@vue/test-utils\"; import { describe, it, expect } from \"vitest\"; import OrderCard from \"@/components/OrderCard.vue\"; describe(\"OrderCard\", () = { it(\"emits select with the order id\", async () = { const wrapper = mount(OrderCard, { props: { order: { id: 7, customer: \"Asha\", total: 500, status: \"paid\" } } }); await wrapper.trigger(\"click\"); expect(wrapper.emitted(\"select\")?.[0]).toEqual([7]); expect(wrapper.text()).toContain(\"Asha\"); }); }); Use @pinia/testing ( createTestingPinia ) to stub stores, mock HTTP with MSW, and test user-visible behaviour (Testing Library for Vue is also available). E2E with Playwright or Cypress."},{"kind":"lesson","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"nuxt-and-migrating-vue-2-vue-3","title":"Nuxt and migrating Vue 2 → Vue 3","body":"Nuxt (Nuxt 4, 2025): file-based routing ( pages/ ), layouts, auto-imports of components and composables, SSR/SSG/hybrid rendering per route ( routeRules ), server API routes ( server/api on the Nitro engine), useFetch / useAsyncData with SSR-friendly data fetching, modules ecosystem (Pinia, Tailwind, i18n, content). Deploy to Node, serverless or edge. Vue 2 → 3 migration (Vue 2 is EOL since Dec 2023): - Use the migration build ( @vue/compat ) to run Vue 2 code on Vue 3 with deprecation warnings, fix them incrementally, then remove compat. - Breaking changes: new Vue() → createApp() ; global API ( Vue.use , Vue.component ) → app instance; filters removed (use methods/computed); v-model on components uses modelValue / update:modelValue ; $listeners merged into $attrs ; v-if priority over v-for ; beforeDestroy/destroyed → beforeUnmount/unmounted ; $on/$off removed (no event bus); functional components simplified; .sync replaced by v-model:prop . - Upgrade ecosystem: Vue Router 4, Pinia (or Vuex 4), Vuetify 3/other UI library versions, Vite instead of Vue CLI. - Vue 2.7 can be an intermediate step (Composition API available in Vue 2)."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"956","title":"What is Vue.js and why is it called progressive?","body":"Vue is an open-source JavaScript framework for building UIs and SPAs (Evan You, 2014). It's \"progressive\" because you can adopt it incrementally: start by adding it to part of a page via a script tag, then grow into a full SPA with SFCs, Vue Router, Pinia, a build tool and SSR (Nuxt). It offers declarative templates, a reactive data system, components and a small, fast core."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"957","title":"What are the most commonly used Vue directives?","body":"v-bind ( : ) for attributes/props, v-on ( @ ) for events (with modifiers like .prevent ), v-model for two-way form binding, v-if/v-else-if/v-else for conditional rendering, v-show for CSS visibility toggling, v-for for lists with :key , v-html / v-text , v-slot ( ) for slots, plus v-once , v-memo , v-pre , v-cloak . Custom directives are possible for low-level DOM access."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"958","title":"What is the difference between v-if and v-show?","body":"v-if conditionally renders: when false the element and its child components aren't created (or are destroyed), so toggling is expensive but the initial render is cheap. v-show always renders the element and toggles display: none , so toggling is cheap but the initial render always pays the cost. Use v-show for frequent toggles, v-if for rarely changing conditions. v-show doesn't work on <template ."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"959","title":"What are computed properties and how are they different from methods and watchers?","body":"Computed properties derive values from reactive state and are cached until their dependencies change — ideal for filtered lists or totals used in templates. Methods run every time they're called (re-render) — use for event handlers. Watchers run side effects when a specific value changes (API calls, saving to localStorage); watchEffect auto-tracks dependencies."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"960","title":"What is the purpose of the `key` attribute in v-for?","body":"key gives each item a unique, stable identity so Vue's virtual DOM can track, reorder and reuse elements correctly and preserve component state and DOM state (focus, input values). Without keys, Vue uses an in-place patch strategy that can show stale state when items are reordered or removed. Use unique IDs, not array indexes, for dynamic lists."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"961","title":"How do you pass data between parent and child components?","body":"Parent to child with props (read-only in the child). Child to parent by emitting events ( defineEmits , emit('save', data) ), and two-way via v-model on components ( defineModel ). For deeper trees use provide/inject; for global or sibling state use Pinia; parent can call child methods via template refs and defineExpose ."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"962","title":"Explain ref vs reactive.","body":"ref() wraps any value (including primitives) in an object with a reactive .value property; templates unwrap it automatically. reactive() makes an object/array/Map deeply reactive via a Proxy, accessed directly without .value , but you can't reassign the whole object and destructuring loses reactivity (use toRefs ). The Vue docs recommend ref as the default because it works with all types and is explicit."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"963","title":"How does reactivity work in Vue 3? How is it different from Vue 2?","body":"Vue 3 wraps state in JavaScript Proxies: getters track which effect (render, computed, watcher) accessed a property; setters trigger those effects, which re-run in a batched, asynchronous update queue. Vue 2 used Object.defineProperty on existing properties, so it couldn't detect new or deleted properties or direct array index/length changes, requiring Vue.set / Vue.delete . Proxies remove those caveats and improve performance and memory usage."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"964","title":"Options API vs Composition API — which and why?","body":"The Options API organises code by option type (data, methods, computed, lifecycle) and is easy for small components and beginners. The Composition API ( setup / <script setup ) organises code by logical concern, enables clean reuse via composables (replacing mixins and their naming conflicts), and gives far better TypeScript inference. For large or long-lived apps, the Composition API with <script setup is generally preferred; both are supported in Vue 3."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"965","title":"What are the lifecycle hooks in Vue 3?","body":"setup (replacing beforeCreate/created), onBeforeMount , onMounted (DOM ready — fetch data, init libraries), onBeforeUpdate , onUpdated , onBeforeUnmount , onUnmounted (cleanup), plus onErrorCaptured , onActivated / onDeactivated (KeepAlive), onServerPrefetch (SSR), and debug hooks onRenderTracked / onRenderTriggered . Options API equivalents use beforeUnmount / unmounted instead of Vue 2's beforeDestroy / destroyed ."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"966","title":"What are slots and scoped slots?","body":"Slots let a parent pass template content into a child component's placeholders: the default slot, named slots ( <slot name=\"footer\" filled with <template footer ), and fallback content. Scoped slots let the child pass data back to the slot content ( <slot :item=\"item\" used as <template default=\"{ item }\" ) — e.g. a generic table component where the parent customises how each row renders."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"967","title":"What is Pinia and how does it compare to Vuex?","body":"Pinia is Vue's official state management library. Stores are defined with defineStore (state, getters, actions, or setup syntax with refs/computeds/functions). Compared with Vuex: no mutations (actions modify state directly, sync or async), no nested modules — just multiple independent stores, full TypeScript support without boilerplate, smaller size, DevTools integration and SSR support. Vuex is in maintenance mode."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"968","title":"What is provide/inject?","body":"A dependency-injection mechanism: an ancestor provide s a value under a key and any descendant, at any depth, can inject it — avoiding prop drilling for things like theme, configuration or a form context. Provide refs (often readonly ) to keep it reactive. It's not a replacement for global state management (Pinia)."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"969","title":"How do navigation guards work in Vue Router?","body":"Guards run during navigation and can allow, cancel ( return false ) or redirect (return a route location). Global guards: router.beforeEach (auth checks), beforeResolve , afterEach (analytics). Per-route: beforeEnter . In-component: onBeforeRouteLeave (unsaved changes) and onBeforeRouteUpdate (same component, new params). Route meta fields (e.g. requiresAuth ) drive guard logic."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"970","title":"What are composables and how do they differ from mixins?","body":"Composables are functions ( useXxx ) that use Composition API primitives to encapsulate and reuse stateful logic, returning refs and functions. Unlike mixins, they make the source of each property explicit (via destructuring), avoid naming collisions, can accept arguments, can be composed together, and are fully typed. Mixins merged options implicitly, causing unclear origins and conflicts."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"971","title":"What is nextTick and when do you need it?","body":"Vue batches DOM updates asynchronously: after changing state, the DOM isn't updated immediately but in the next \"tick\" (microtask). await nextTick() waits until the DOM reflects the latest state — e.g. to measure an element's size or focus an input that was just rendered with v-if ."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"972","title":"How does Vue's compiler optimise rendering?","body":"The template compiler analyses templates at build time: it hoists static nodes (created once), adds patch flags to dynamic nodes (so diffing only checks what can change, like text or class), and builds a block tree that tracks dynamic descendants, avoiding a full virtual DOM tree walk. Vapor Mode (in development for 3.6) goes further, compiling templates to direct DOM operations without a virtual DOM."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"973","title":"A page with a list of 20,000 items is slow to render and scroll. How do you fix it?","body":"Render only what's visible with virtual scrolling (vue-virtual-scroller/TanStack Virtual); paginate or load incrementally from the API; use stable :key s; store the large list with shallowRef (or markRaw items) so Vue doesn't make every nested property reactive; move filtering/sorting into computed properties; avoid heavy components per row; use v-memo for rows that rarely change."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"974","title":"You destructure props or a reactive store and the UI stops updating. Why?","body":"Destructuring copies the current values out of the reactive Proxy, breaking the connection. Fix: use toRefs(reactiveObj) or storeToRefs(store) for Pinia state/getters (actions can be destructured directly), access via props.x , or rely on Vue 3.5's compiler-supported reactive props destructure inside <script setup , which keeps destructured props reactive in templates and computeds."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"975","title":"Your company has a large Vue 2 app. Vue 2 reached EOL in December 2023. What's your plan?","body":"Assess dependencies (Vuex, Vue Router 3, UI libraries like Vuetify 2/Element UI, plugins) and test coverage. Short term: upgrade to Vue 2.7 (Composition API) and consider extended commercial support for security. Then use the @vue/compat migration build on Vue 3 to fix deprecations incrementally; migrate Vue Router 3 → 4, Vuex → Pinia (store by store), Vue CLI → Vite, and UI libraries to Vue 3 versions (often the biggest effort); remove filters, the event bus and $listeners ; add Playwright tests for critical flows before and during the migration; ship in stages."},{"kind":"question","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"976","title":"A watcher calling an API fires too often while the user types. How do you control it?","body":"Debounce the watcher's work ( useDebounceFn from VueUse or a debounce wrapper), add v-model.lazy if updating on change is enough, ignore short queries, cancel the previous request with AbortController via onWatcherCleanup (Vue 3.5) or the onCleanup argument so stale responses can't overwrite newer ones, and cache results."},{"kind":"cheat","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"1","title":"Template","body":"{{ }} · :prop · @event.prevent · v-model.trim/.number/.lazy · v-if/v-else-if/v-else · v-show · v-for=\"(x, i) in xs\" :key=\"x.id\" · slot · <component :is ."},{"kind":"cheat","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"2","title":"Reactivity","body":"ref ( .value ) · reactive · computed · watch (lazy, specific) · watchEffect (immediate, auto-track) · toRefs / storeToRefs · shallowRef · readonly · nextTick ."},{"kind":"cheat","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"3","title":"script setup macros","body":"defineProps · defineEmits · defineModel (3.4) · defineExpose · defineOptions · defineSlots · withDefaults ."},{"kind":"cheat","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"4","title":"Lifecycle (Composition)","body":"setup → onBeforeMount → onMounted → onBeforeUpdate → onUpdated → onBeforeUnmount → onUnmounted (+ onErrorCaptured, onActivated/onDeactivated)."},{"kind":"cheat","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"5","title":"Communication","body":"props ↓ · emits ↑ · v-model ↕ · provide/inject (deep) · Pinia (global) · template ref + defineExpose."},{"kind":"cheat","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"6","title":"Built-ins","body":"<Transition · <TransitionGroup · <KeepAlive · <Teleport · <Suspense · defineAsyncComponent ."},{"kind":"cheat","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"7","title":"Ecosystem","body":"Vite · Vue Router 4 (guards: beforeEach, beforeEnter, onBeforeRouteLeave) · Pinia · VueUse · Vitest + Vue Test Utils · Nuxt 4."},{"kind":"cheat","course_slug":"vue","course_title":"Vue.js 3 (with Pinia, Vue Router & Nuxt basics)","ref":"8","title":"Versions","body":"2.0 (2016) · 2.7 (2022) · Vue 2 EOL 31 Dec 2023 · 3.0 (2020) · 3.2 script setup · 3.4 defineModel · 3.5 props destructure, useTemplateRef · 3.6 Vapor Mode (in development)."},{"kind":"course","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"","title":"Test Automation — Selenium, Playwright, API and BDD with C#","body":"Testing fundamentals and the test pyramid, NUnit/xUnit, Selenium WebDriver and locators, waits, Page Object Model, Playwright for .NET, API testing with HttpClient/RestSharp/Postman, BDD with Reqnroll (SpecFlow), data-driven tests, CI pipelines, flaky tests and the SDET interview questions. Test automation means writing code that tests software automatically and repeatably — UI tests that drive a browser, API tests that call endpoints, and unit/integration tests that check code directly. An SDET (Software Development Engineer in Test) or automation engineer builds and maintains these frameworks and runs them in CI/CD. The test pyramid (Mike Cohn): text / UI / E2E \\ few — slow, brittle, test real user flows / API / service \\ more — fast, stable, test business rules through the API / Unit tests \\ most — milliseconds, test classes/functions in isolation Level Tools (.NET) Speed --- --- --- Unit xUnit, NUnit, MSTest + Moq/NSubstitute + FluentAssertions ms Integration WebApplicationFactory , Testcontainers, EF Core with real SQL seconds API HttpClient, RestSharp, Postman/Newman, Playwright API seconds UI / E2E Selenium WebDriver, Playwright, Cypress (JS) seconds–minutes BDD Reqnroll (successor of SpecFlow), Cucumber wraps any level Performance k6, JMeter, NBomber, Azure Load Testing minutes Year Milestone --- --- 2004 Selenium created at ThoughtWorks (Jason Huggins) 2011 Selenium 2 merges WebDriver 2016 Selenium 3 (Selenium RC removed) 2018 WebDriver becomes a W3C Recommendation 2020 Playwright released by Microsoft (Node), .NET/Python/Java bindings in 2021 2021 Selenium 4 — W3C protocol, relative locators, CDP access, new Grid 2023 Selenium Manager (automatic driver download) built in from 4.6+ 2024 SpecFlow end-of-life announced; community fork Reqnroll becomes the .NET BDD standard; WebDriver BiDi rolling out 2025 Playwright 1.5x — test agents, MCP integration; Selenium 4.3x with BiDi APIs Automation in the software testing life cycle (STLC): 1. Requirement analysis — which acceptance criteria can be automated; risk-based selection. 2. Test planning — scope, tools, framework design, environments, data strategy. 3. Test design — test cases, data sets, page objects, API contracts. 4. Framework & scripts — build reusable framework, write tests, code review them like product code. 5. Execution — locally and in CI (on every PR: unit + API smoke; nightly: full regression; parallel/grid). 6. Reporting — results, screenshots, videos, traces (Allure, ExtentReports, Azure Test Plans, Playwright HTML report). 7. Maintenance — fix flaky tests, update locators, refactor; delete tests that no longer give value. - Test runners: NUnit, xUnit, MSTest; dotnet test . - UI: Selenium WebDriver (C ), Playwright for .NET ( Microsoft.Playwright ), Appium (mobile), WinAppDriver/FlaUI (Windows desktop). - API: HttpClient, RestSharp, Flurl, Postman + Newman, Playwright APIRequestContext . - BDD: Reqnroll (Gherkin .feature files with C step definitions). - Assertions & mocks: FluentAssertions / Shouldly, Moq, NSubstitute, WireMock.Net (fake HTTP services). - Data & environments: Bogus (fake data), Testcontainers (Docker DBs), Selenium Grid / Selenoid, BrowserStack, Sauce Labs. - CI & reporting: Azure DevOps, GitHub Actions, Jenkins, Allure, ExtentReports."},{"kind":"lesson","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"testing-types-terms-and-what-to-automate","title":"Testing types, terms and what to automate","body":"Term Meaning --- --- Functional vs non-functional What it does vs how well (performance, security, usability) Smoke Few critical checks — is the build alive? Sanity Quick check of one changed area Regression Re-run existing tests to catch side effects of changes — the main candidate for automation Black box / white box Without / with knowledge of the code Verification vs validation Built right (spec) vs built the right thing (user need) Severity vs priority Impact on the system vs urgency to fix Automate: repetitive regression, smoke, data-driven cases, API contracts, cross-browser checks, stable features. Keep manual: exploratory testing, usability/look-and-feel, one-off checks, features still changing daily. Test case design techniques: equivalence partitioning, boundary value analysis (age 17/18/99/100), decision tables, state transition, pairwise."},{"kind":"lesson","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"unit-test-frameworks-nunit-and-xunit","title":"Unit test frameworks — NUnit and xUnit","body":"csharp // NUnit [TestFixture] public class DiscountTests { private DiscountService sut = null!; [SetUp] public void Setup() = sut = new DiscountService(); [TestCase(500, 0)] [TestCase(1000, 50)] [TestCase(5000, 500)] public void Discount depends on order total(decimal total, decimal expected) = Assert.That( sut.For(total), Is.EqualTo(expected)); } // xUnit — a new class instance per test; constructor = setup, IDisposable = teardown public class CartTests { [Theory] [InlineData(0, false)] [InlineData(3, true)] public void HasItems(int count, bool expected) = new Cart(count).HasItems.Should().Be(expected); [Fact] public async Task Checkout calls payment once() { var payment = Substitute.For<IPaymentGateway (); await new CheckoutService(payment).PayAsync(new Order(100)); await payment.Received(1).ChargeAsync(100); } } NUnit xUnit MSTest --- --- --- --- Test [Test] [Fact] [TestMethod] Parameterised [TestCase] , [TestCaseSource] [Theory] + [InlineData] / [MemberData] [DataRow] Setup [SetUp] , [OneTimeSetUp] constructor, IClassFixture<T [TestInitialize] Popular for Selenium frameworks .NET Core apps Microsoft shops Structure every test as Arrange – Act – Assert ; one behaviour per test; name tests by behaviour."},{"kind":"lesson","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"selenium-webdriver-with-csharp-locators-and-actions","title":"Selenium WebDriver with C# — locators and actions","body":"csharp using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Support.UI; var options = new ChromeOptions(); options.AddArgument(\"--headless=new\"); using IWebDriver driver = new ChromeDriver(options); // Selenium Manager downloads the driver automatically (4.6+) driver.Navigate().GoToUrl(\"https://shop.example.com/login\"); driver.FindElement(By.Id(\"email\")).SendKeys(\"qa@example.com\"); driver.FindElement(By.CssSelector(\"input[name='password']\")).SendKeys(\"Secret 123\"); driver.FindElement(By.XPath(\"//button[normalize-space()='Sign in']\")).Click(); var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); var heading = wait.Until(d = d.FindElement(By.CssSelector(\"[data-testid='dashboard-title']\"))); Assert.That(heading.Text, Is.EqualTo(\"Dashboard\")); Locator priority (most to least stable): dedicated test ids ( data-testid ) → id → name → CSS selectors → XPath → link text. Avoid absolute XPath ( /html/body/div[3]/... ) and auto-generated classes. XPath tricks Example --- --- Text //button[text()='Save'] , contains(text(),'Save') Attribute contains //input[contains(@id,'email')] Axes //label[.='Email']/following-sibling::input , //td[.='1001']/parent::tr//button Other APIs: Actions (hover, drag-drop, keyboard), SelectElement (dropdowns), SwitchTo().Frame()/Window()/Alert() , IJavaScriptExecutor (scroll, read values), GetScreenshot() ."},{"kind":"lesson","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"waits-and-synchronisation-killing-flaky-tests","title":"Waits and synchronisation — killing flaky tests","body":"Wait Behaviour Verdict --- --- --- Thread.Sleep(5000) Always waits the full time ❌ Slow and still flaky Implicit wait ( driver.Manage().Timeouts().ImplicitWait ) Polls for every FindElement ⚠️ Global, hides problems; don't mix with explicit Explicit wait ( WebDriverWait + condition) Waits until a specific condition or timeout ✅ Use this Fluent wait Explicit wait with polling interval and ignored exceptions ✅ For special cases csharp var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(15)) { PollingInterval = TimeSpan.FromMilliseconds(250) }; wait.IgnoreExceptionTypes(typeof(NoSuchElementException), typeof(StaleElementReferenceException)); var button = wait.Until(d = { var e = d.FindElement(By.Id(\"save\")); return e.Displayed && e.Enabled ? e : null; }); Common exceptions: NoSuchElementException (wrong locator or not loaded), StaleElementReferenceException (DOM re-rendered — find the element again), ElementClickInterceptedException (overlay/spinner covering it — wait for it to disappear), TimeoutException ."},{"kind":"lesson","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"page-object-model-and-framework-design","title":"Page Object Model and framework design","body":"Page Object Model (POM): one class per page/component holding its locators and actions; tests call meaningful methods instead of raw locators — locator changes are fixed in one place. csharp public class LoginPage(IWebDriver driver) { private IWebElement Email = driver.FindElement(By.Id(\"email\")); private IWebElement Password = driver.FindElement(By.Id(\"password\")); private IWebElement SignIn = driver.FindElement(By.CssSelector(\"[data-testid='sign-in']\")); public DashboardPage LoginAs(string email, string password) { Email.SendKeys(email); Password.SendKeys(password); SignIn.Click(); return new DashboardPage(driver); // fluent navigation } } [Test] public void Valid user reaches dashboard() { var dashboard = new LoginPage(Driver).LoginAs(TestUsers.Standard.Email, TestUsers.Standard.Password); Assert.That(dashboard.Title, Is.EqualTo(\"Dashboard\")); } Typical framework layout: text Tests/ test classes (NUnit/xUnit or Reqnroll features) Pages/ page objects / components Core/ DriverFactory (browser, headless, grid), config (appsettings.json), waits, logging Data/ test data builders (Bogus), JSON/Excel data Api/ API clients for setup/teardown (create data via API, not UI) Reports/ Allure/Extent configuration, screenshots on failure Principles: tests independent and order-free, data created per test (via API/DB), no hard-coded waits or environments, parallel-safe (one driver per test/thread), screenshot + logs on failure."},{"kind":"lesson","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"playwright-for-dotnet","title":"Playwright for .NET","body":"csharp // dotnet add package Microsoft.Playwright.NUnit ; then: pwsh bin/Debug/net10.0/playwright.ps1 install public class CheckoutTests : PageTest { [Test] public async Task User can place order() { await Page.GotoAsync(\"https://shop.example.com\"); await Page.GetByRole(AriaRole.Link, new() { Name = \"Laptops\" }).ClickAsync(); await Page.GetByTestId(\"product-101\").GetByRole(AriaRole.Button, new() { Name = \"Add to cart\" }).ClickAsync(); await Page.GetByRole(AriaRole.Button, new() { Name = \"Checkout\" }).ClickAsync(); await Expect(Page.GetByText(\"Order placed\")).ToBeVisibleAsync(); // auto-retrying assertion } } Selenium Playwright --- --- --- Protocol W3C WebDriver (BiDi coming) Direct browser protocols (CDP / patched engines) Waiting Manual explicit waits Auto-wait before actions + retrying assertions Browsers Chrome, Edge, Firefox, Safari, IE (legacy) Chromium, Firefox, WebKit Isolation New driver per test (slow) Browser contexts (fast, isolated) Extras Huge ecosystem, Grid, Appium for mobile Tracing viewer, codegen, network mocking, API testing, video Languages Java, C , Python, JS, Ruby TS/JS, C , Python, Java Useful features: playwright codegen (record locators), Page.RouteAsync (mock APIs), trace viewer (step-by-step DOM snapshots), StorageState (reuse login), parallel workers."},{"kind":"lesson","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"api-test-automation","title":"API test automation","body":"csharp public class OrdersApiTests { private readonly HttpClient client = new() { BaseAddress = new Uri(\"https://api.example.com\") }; [Test] public async Task Create order returns 201 and location() { client.DefaultRequestHeaders.Authorization = new(\"Bearer\", await TokenHelper.GetAsync()); var response = await client.PostAsJsonAsync(\"/api/orders\", new { customerId = 42, lines = new[] { new { productId = 1, qty = 2 } } }); Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Created)); Assert.That(response.Headers.Location, Is.Not.Null); var order = await response.Content.ReadFromJsonAsync<OrderDto (); Assert.That(order!.Lines, Has.Count.EqualTo(1)); } [Test] public async Task Missing token returns 401() = Assert.That((await new HttpClient().GetAsync(\"https://api.example.com/api/orders\")).StatusCode, Is.EqualTo(HttpStatusCode.Unauthorized)); } What to check: status codes, response body and schema, headers, error messages (ProblemDetails), auth (401/403), validation (400), idempotency, pagination, performance thresholds. For ASP.NET Core apps, WebApplicationFactory<Program runs the API in-memory for fast integration tests; WireMock.Net fakes third-party APIs. Postman: collections, environments, pre-request scripts, pm.test(...) assertions, run in CI with Newman ."},{"kind":"lesson","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"bdd-with-reqnroll-specflow-successor","title":"BDD with Reqnroll (SpecFlow successor)","body":"gherkin Feature: Login Scenario Outline: Login with different users Given I am on the login page When I log in as \"<email \" with password \"<password \" Then I should see \"<result \" Examples: email password result qa@example.com Secret 1 Dashboard qa@example.com wrong Invalid password csharp [Binding] public class LoginSteps(ScenarioContext ctx, IWebDriver driver) { private readonly LoginPage login = new(driver); [Given(\"I am on the login page\")] public void Open() = login.Open(); [When(\"I log in as {string} with password {string}\")] public void Login(string e, string p) = login.Submit(e, p); [Then(\"I should see {string}\")] public void Check(string text) = Assert.That(driver.PageSource, Does.Contain(text)); } BDD value: shared language with business (Three Amigos), living documentation. Cost: an extra layer — use it when business people actually read the feature files. Hooks: [BeforeScenario] , [AfterScenario] (screenshot on failure), tags ( @smoke ) to filter runs."},{"kind":"lesson","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"running-tests-in-ci-cd-parallel-execution-and-reporting","title":"Running tests in CI/CD, parallel execution and reporting","body":"yaml Azure DevOps pipeline (excerpt) - task: DotNetCoreCLI@2 inputs: { command: test, projects: 'tests/ / .csproj', arguments: '--filter TestCategory=Smoke --logger trx' } - task: PublishTestResults@2 inputs: { testResultsFormat: VSTest, testResultsFiles: ' / .trx' } - When to run: unit + API smoke on every PR; full UI regression nightly or before release; smoke after each deployment. - Parallel: NUnit [Parallelizable(ParallelScope.All)] + [FixtureLifeCycle(LifeCycle.InstancePerTestCase)] ; xUnit runs test classes in parallel; Playwright workers; Selenium Grid / cloud grids for many browsers. - Headless browsers in CI; record video/trace only on failure. - Reports: TRX in Azure DevOps, Allure/Extent HTML, Playwright HTML report with traces. - Environment & data: config per environment (appsettings + pipeline variables), secrets from Key Vault/variable groups, fresh data created through APIs, Testcontainers for DBs."},{"kind":"lesson","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"flaky-tests-causes-and-cures","title":"Flaky tests — causes and cures","body":"A flaky test passes and fails on the same code. It destroys trust in the suite. Cause Cure --- --- Timing (element not ready, animations, async loads) Explicit waits on conditions / Playwright auto-wait; wait for network idle or a specific response Shared/test-order-dependent data Each test creates and cleans its own data; unique names (GUIDs) Brittle locators data-testid , role-based locators, POM Environment instability Health check before run, mock external services (WireMock), stable test env Parallel collisions Separate users/data per worker; thread-safe driver handling Hidden bugs (race conditions in the app) Investigate — the flakiness may be real Process: quarantine (tag and exclude from blocking runs), track flake rate, fix or delete — never just add retries everywhere (retries hide real problems; use them as a temporary, visible measure)."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"977","title":"What is the test pyramid and why does it matter?","body":"Many fast unit tests at the bottom, fewer API/integration tests in the middle, and a small number of slow UI/E2E tests at the top. It gives fast feedback and stable suites: most logic is tested cheaply below the UI, while a few E2E tests confirm critical user journeys. The anti-pattern is the \"ice-cream cone\" (mostly UI tests) — slow and flaky."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"978","title":"What should and shouldn't be automated?","body":"Automate stable, repetitive, high-value checks: regression, smoke, data-driven cases, API contracts, cross-browser critical paths. Don't automate exploratory and usability testing, one-off checks, features that change daily, or anything where the maintenance costs more than running it manually."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"979","title":"Which Selenium locators do you use and in what order?","body":"Prefer stable, unique attributes: data-testid / data-qa → id → name → CSS selectors → relative XPath (text, attributes, axes) → link text. Avoid absolute XPath and generated class names. If the app lacks good attributes, ask developers to add test ids — it's the most effective fix for brittle tests."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"980","title":"Implicit vs explicit vs fluent wait?","body":"Implicit: a global timeout applied to every element lookup. Explicit: WebDriverWait waiting for a specific condition (visible, clickable, text present) up to a timeout — recommended. Fluent: an explicit wait with configurable polling and ignored exceptions. Never use Thread.Sleep , and don't mix implicit and explicit waits (timeouts combine unpredictably)."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"981","title":"What is the Page Object Model?","body":"A design pattern where each page or component is a class that owns its locators and exposes user actions ( LoginAs , AddToCart ). Tests read like user steps, locators live in one place (one fix when the UI changes), and code is reused. Variants: Page Factory (Java), component objects, Screenplay pattern."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"982","title":"Selenium vs Playwright — which would you choose?","body":"Playwright for new web projects: auto-waiting and retrying assertions (less flakiness), fast isolated browser contexts, built-in tracing, network mocking, API testing, parallel runs and codegen. Selenium when you need the W3C standard, the widest language/browser support (including real Safari and legacy browsers), Appium for mobile, an existing large Selenium framework, or vendor grids. Both work well with C ."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"983","title":"How do you handle StaleElementReferenceException?","body":"It means the element you hold was removed or re-rendered in the DOM. Re-locate the element right before using it (page-object properties that find each time, not cached fields), wait for the page update to finish (explicit wait on a condition), and include it in ignored exceptions of a fluent wait for dynamic grids."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"984","title":"How do you design an automation framework from scratch?","body":"Language and runner matching the team (C + NUnit/xUnit), Selenium or Playwright for UI and HttpClient/RestSharp for API, layered structure (tests → pages/components → core: driver factory, config, waits, logging → data builders → API helpers), configuration per environment, test data created via API, parallel execution, screenshots/traces and reports on failure, CI integration with categories (smoke/regression), and coding standards with code review. Optionally Reqnroll for BDD."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"985","title":"How do you test REST APIs? What do you validate?","body":"Using HttpClient/RestSharp/Postman: send requests with correct and incorrect data, check status codes (200/201/204/400/401/403/404/409), response body and JSON schema, headers, error format, authentication and authorisation per role, boundary values, pagination and sorting, idempotency of PUT/DELETE, and response time. Chain requests (create → get → update → delete) and clean up data."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"986","title":"What is data-driven testing?","body":"Running the same test logic with multiple data sets: NUnit [TestCase] / [TestCaseSource] , xUnit [Theory] + [InlineData] / [MemberData] , Reqnroll Scenario Outline + Examples , or data from JSON/CSV/Excel/DB. It increases coverage (boundaries, partitions) without duplicating code."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"987","title":"How do you handle iframes, multiple windows, alerts and dropdowns in Selenium?","body":"Frames: driver.SwitchTo().Frame(idOrElement) then SwitchTo().DefaultContent() . Windows/tabs: store CurrentWindowHandle , loop WindowHandles , SwitchTo().Window(handle) . Alerts: SwitchTo().Alert().Accept()/Dismiss()/Text . Dropdowns: new SelectElement(element).SelectByText(\"India\") for <select ; custom dropdowns are clicked like normal elements."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"988","title":"What is BDD and when is it worth it?","body":"Behaviour-Driven Development describes behaviour in Gherkin (Given/When/Then) agreed with business and QA, then automates those scenarios with step definitions (Reqnroll in .NET). Worth it when business stakeholders read and help write scenarios — it becomes living documentation. If only engineers read them, the Gherkin layer is overhead; plain readable tests are enough."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"989","title":"How do you run UI tests in parallel safely?","body":"One driver/browser context per test (thread-local or per-test instance), no static shared state, unique test data per test (GUIDs, separate users), tests independent of order, config for worker count, and infrastructure that can handle the load (Selenium Grid, cloud grid, Playwright workers). NUnit: [Parallelizable] with instance-per-test-case; xUnit: collections control parallelism."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"990","title":"How do you integrate automated tests into CI/CD?","body":"Tests live in the same repo or a sibling repo, run via dotnet test in Azure DevOps/GitHub Actions/Jenkins: unit and API smoke on every PR (quality gate), deployment smoke tests after each environment deploy, full regression nightly. Headless browsers or a grid, results published (TRX/JUnit), artefacts on failure (screenshots, videos, traces), notifications, and failing tests block the pipeline."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"991","title":"What metrics do you track for test automation?","body":"Pass rate and flaky rate, execution time, coverage of critical flows/requirements (not just code coverage), defects found by automation vs escaped defects, time to fix broken tests, and automation ROI (manual hours saved). Use them to decide what to fix, speed up or delete."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"992","title":"Your regression suite of 800 UI tests takes 6 hours and 10% fail randomly. What do you do?","body":"Measure first: list slowest and flakiest tests. Move logic checks down the pyramid (API/unit tests); keep UI tests for critical journeys. Replace sleeps with condition waits or Playwright auto-wait; use stable locators; create test data via API instead of UI steps; reuse login state. Run in parallel on a grid with independent data. Quarantine flaky tests and fix root causes. Target: smoke < 10 min per PR, full regression < 1 hour, flake rate < 1–2%."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"993","title":"A test passes locally but fails in the CI pipeline. How do you investigate?","body":"Compare environments: headless vs headed (viewport/screen size differs), browser/driver versions, timing on slower agents, environment URLs and config, test data present/missing, parallel runs colliding, time zone/culture, network/proxy. Collect evidence: screenshots, video, Playwright trace, browser console and network logs, CI logs. Reproduce with the same settings locally (headless, same browser version, same data)."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"994","title":"The developers change the UI often and your locators break every sprint. How do you fix this?","body":"Agree with developers to add stable data-testid attributes (part of the definition of done), use role/text-based locators (Playwright GetByRole , GetByLabel ) that follow user-visible behaviour, centralise locators in page/component objects, review UI changes with QA early, and add a quick smoke run on every PR so breaks are found immediately — not at the end of the sprint."},{"kind":"question","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"995","title":"How would you test a login page? List the cases.","body":"Valid login; invalid password; unknown user; empty fields; field validation (email format, length); password masked; case sensitivity; account lockout after N attempts; \"remember me\"; forgot password flow; SQL injection/XSS strings; session timeout and logout; back button after logout; HTTPS; multiple browsers/devices; accessibility (labels, keyboard); performance under load; error messages don't reveal whether the user exists."},{"kind":"cheat","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"1","title":"Pyramid & what to automate","body":"Many unit → some API/integration → few UI. Automate regression, smoke, data-driven, API contracts; keep exploratory and usability manual."},{"kind":"cheat","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"2","title":"Selenium essentials","body":"csharp driver.FindElement(By.CssSelector(\"[data-testid='save']\")).Click(); new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(d = d.FindElement(By.Id(\"ok\")).Displayed); new SelectElement(el).SelectByText(\"India\"); driver.SwitchTo().Frame(\"pay\");"},{"kind":"cheat","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"3","title":"Playwright essentials","body":"csharp await Page.GetByRole(AriaRole.Button, new() { Name = \"Save\" }).ClickAsync(); await Expect(Page.GetByText(\"Saved\")).ToBeVisibleAsync(); await Page.RouteAsync(\" /api/orders\", r = r.FulfillAsync(new() { Json = new[] { new { id = 1 } } }));"},{"kind":"cheat","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"4","title":"Framework checklist","body":"POM/components · driver factory · config per env · explicit waits only · data via API · independent tests · parallel-safe · screenshots/traces on failure · reports · CI categories (smoke/regression)."},{"kind":"cheat","course_slug":"test-automation","course_title":"Test Automation — Selenium, Playwright, API and BDD with C#","ref":"5","title":"Flaky test fixes","body":"Condition waits · stable locators · own data per test · mock unstable dependencies · quarantine + fix · retries only as a visible, temporary measure."},{"kind":"course","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"","title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","body":"Automation pyramid and Purdue model, sensors and actuators, signals (digital, 4–20 mA), PLC hardware and scan cycle, IEC 61131-3 ladder logic and structured text, timers and counters, PID control, HMI/SCADA/DCS, historians, fieldbuses and industrial Ethernet, Modbus RTU/TCP, OPC UA, connecting plant data to .NET, safety and OT security (IEC 62443), with interview questions. Industrial automation uses control systems — PLCs, DCS, SCADA, robots — to run machines and processes with little human intervention. It is the OT (Operational Technology) side of a factory, as opposed to IT (ERP, email, business apps). Industry 4.0 is largely about connecting the two. Automation pyramid / Purdue model (ISA-95 levels): Level What lives there Examples --- --- --- 4 — Business ERP, planning, logistics SAP, Oracle, Dynamics 365 3 — Manufacturing operations MES, quality, scheduling, historian MES, AVEVA PI, Ignition MES 2 — Supervisory control SCADA, HMI, engineering stations WinCC, FactoryTalk View, Ignition, AVEVA InTouch 1 — Control PLC, DCS controllers, drives, robot controllers Siemens S7-1500, Allen-Bradley ControlLogix 0 — Field / process Sensors, actuators, motors, valves Proximity sensors, RTDs, VFDs, solenoid valves Typical industries: automotive, pharma, food & beverage, oil & gas, power, water, semiconductors, packaging. Year Milestone --- --- 1968–1969 First PLC (Modicon 084, Dick Morley) built for General Motors to replace relay panels 1979 Modbus protocol published by Modicon 1980s DCS and SCADA spread; Profibus (1989) 1993 IEC 61131-3 standardises PLC languages (3rd edition 2013) 1996 OPC (OLE for Process Control, Windows DCOM-based) — OPC DA 1999 Modbus TCP; Modbus later handed to Modbus Organization (2004) 2003 PROFINET; EtherNet/IP (2001) 2006–2008 OPC UA released (platform-independent, secure; IEC 62541) 2009+ ISA/IEC 62443 series for industrial cybersecurity 2010 Stuxnet attack on Siemens PLCs — OT security becomes mainstream 2018+ OPC UA over TSN, OPC UA PubSub/MQTT; companion specifications 2020s Software-defined/virtual PLCs, IEC 61499 distributed control, IT/OT convergence How a PLC runs (scan cycle), repeated every few milliseconds: 1. Read inputs — copy the state of all input modules into the input image table. 2. Execute the program — evaluate ladder/ST logic from top to bottom using the image. 3. Write outputs — copy the output image to output modules (motors, valves). 4. Housekeeping — communications, diagnostics; then repeat. Scan time is typically 1–50 ms. Automation project lifecycle: requirements & URS → functional design spec (FDS) → I/O list and electrical design → panel build → PLC/HMI programming → FAT (Factory Acceptance Test at the vendor) → installation → SAT (Site Acceptance Test) → commissioning → validation (IQ/OQ/PQ in pharma) → maintenance and change management. - PLC programming: Siemens TIA Portal (S7-1200/1500), Rockwell Studio 5000 (ControlLogix/CompactLogix), CODESYS (many vendors), Mitsubishi GX Works, Schneider EcoStruxure Control Expert, Omron Sysmac Studio, Beckhoff TwinCAT. - HMI/SCADA: Siemens WinCC (Unified), Rockwell FactoryTalk View, Ignition (Inductive Automation), AVEVA (Wonderware) InTouch/System Platform, GE CIMPLICITY. - Historians: AVEVA PI System (formerly OSIsoft PI), Ignition historian, InfluxDB, Canary. - Protocol tools: Modbus Poll/Slave, UaExpert (OPC UA client), Wireshark, Kepware KEPServerEX (driver/OPC server). - .NET libraries: OPC Foundation UA .NET Standard stack, NModbus / FluentModbus, S7.Net / Sharp7 (Siemens), libplctag (Rockwell), MQTTnet. - Simulation: PLCSIM (Siemens), Factory I/O, digital twins."},{"kind":"lesson","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"sensors-actuators-and-signal-types","title":"Sensors, actuators and signal types","body":"Sensors (inputs): Sensor Measures / detects Output --- --- --- Inductive proximity Metal object present Digital (PNP/NPN) Capacitive proximity Any material (level in tank) Digital Photoelectric Object breaks light beam Digital Limit switch Mechanical position Digital RTD (PT100) / thermocouple Temperature Analog Pressure / level / flow transmitter Process values Analog 4–20 mA, HART, fieldbus Encoder Speed / position Pulses (high-speed counter) Actuators (outputs): contactors and motors, VFD (variable frequency drive — controls AC motor speed), solenoid valves, pneumatic cylinders, control valves, servo drives, indicator lamps, buzzers. Signal types: Type Range Notes --- --- --- Digital (discrete) 24 V DC on/off PNP (sourcing) vs NPN (sinking) sensors Analog current 4–20 mA 4 mA = 0 %, 20 mA = 100 %; < ~3.8 mA means broken wire (\"live zero\"); immune to voltage drop on long cables Analog voltage 0–10 V Simple, but affected by cable length/noise Pulse kHz Flow meters, encoders Scaling an analog value: value = (raw − rawMin) / (rawMax − rawMin) × (engMax − engMin) + engMin . Example: a Siemens analog input gives 0–27648 for 4–20 mA; a 0–10 bar transmitter reading 13824 → 5 bar."},{"kind":"lesson","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"plc-hardware-and-how-a-plc-differs-from-a-pc","title":"PLC hardware and how a PLC differs from a PC","body":"A PLC (Programmable Logic Controller) is a rugged industrial computer: CPU, power supply, digital/analog I/O modules, communication modules, often in a rack or as a compact unit. PLC PC --- --- --- Environment Heat, vibration, electrical noise, 24/7 for decades Office conditions Timing Deterministic scan cycle (real-time) Non-deterministic OS scheduling I/O Built for direct sensor/actuator wiring Needs extra hardware Programming IEC 61131-3 languages Any language Reliability Very high, hot-swap modules, redundancy options Lower Related controllers: DCS (Distributed Control System — plant-wide continuous processes such as refineries, tightly integrated with its own HMI, e.g. Emerson DeltaV, ABB 800xA, Honeywell Experion); PAC (programmable automation controller — PLC + PC features); RTU (remote terminal unit for remote sites like pipelines); safety PLC (SIL-rated, e.g. Siemens F-CPU, GuardLogix); soft/virtual PLC running on industrial PCs."},{"kind":"lesson","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"iec-61131-3-languages-and-ladder-logic-basics","title":"IEC 61131-3 languages and ladder logic basics","body":"Language Style Best for --- --- --- LD — Ladder Diagram Graphical relay logic Discrete on/off logic, electricians can read it FBD — Function Block Diagram Graphical blocks Process control, signal flow ST — Structured Text Pascal-like text Calculations, loops, data handling SFC — Sequential Function Chart Steps and transitions Sequences (batch, machine cycles) IL — Instruction List Assembly-like Deprecated in the 3rd edition (2013) Classic start/stop (seal-in) circuit: text Start Stop Overload Motor --- ---+--- / -------- / ---------------( )---- Motor --- ---+ - normally open contact (true when the bit is 1), / normally closed contact (true when the bit is 0), ( ) output coil. - Pressing Start energises Motor ; the parallel Motor contact \"seals in\" so it stays on after Start is released; Stop (wired NC in the field for fail-safety) breaks the rung. Same logic in Structured Text: pascal Motor := (Start OR Motor) AND NOT Stop AND NOT Overload; Other instructions: set/reset (latch/unlatch), rising/falling edge ( R TRIG , F TRIG ), compare, move, math, jump/subroutine calls."},{"kind":"lesson","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"timers-counters-and-sequences","title":"Timers, counters and sequences","body":"pascal // Structured Text (IEC 61131-3) VAR tStartDelay : TON; // on-delay timer ctParts : CTU; // up counter rtSensor : R TRIG; // rising edge detector END VAR tStartDelay(IN := StartRequest, PT := T 5S); ConveyorRun := tStartDelay.Q; // runs 5 s after the request rtSensor(CLK := PartSensor); ctParts(CU := rtSensor.Q, RESET := ResetCount, PV := 100); BoxFull := ctParts.Q; // true after 100 parts Block Behaviour --- --- TON Output turns ON after input has been ON for preset time TOF Output stays ON for preset time after input turns OFF TP Fixed-length pulse CTU / CTD / CTUD Count up / down / both to a preset Sequences — use a state machine (SFC, or a CASE on a step number in ST): Idle → Fill → Heat → Mix → Drain → Idle, each step with entry conditions, timeouts and fault handling. Avoid scattering sequence logic across many unrelated rungs."},{"kind":"lesson","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"pid-control-loops","title":"PID control loops","body":"Closed-loop control: measure the process variable (PV) , compare with the setpoint (SP) , and adjust the output (CV/MV) to reduce the error. text SP ──►(+)──error──► PID ──CV──► valve/heater ──► process ──► PV ▲(−) │ └──────────────────── sensor ◄───────────────────────┘ Term Effect --- --- P — proportional Output proportional to current error; too high → oscillation; alone leaves steady-state offset I — integral Accumulates past error; removes offset; too much → overshoot, windup D — derivative Reacts to rate of change; damps overshoot; sensitive to noise Practicalities: anti-windup, bumpless transfer between manual and auto, output limits, filtering noisy signals, tuning methods (Ziegler–Nichols, step-response, auto-tune in the PLC). Examples: temperature of an oven, tank level, pressure, motor speed."},{"kind":"lesson","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"hmi-scada-alarms-and-historians","title":"HMI, SCADA, alarms and historians","body":"- HMI (Human-Machine Interface) — operator screen for one machine or line: start/stop, setpoints, status, alarms. - SCADA (Supervisory Control and Data Acquisition) — supervises many PLCs/RTUs across a plant or region (pipelines, water networks): data collection, control, alarms, trends, reports, often redundant servers. - Alarm management (ISA-18.2): priorities, acknowledgement, shelving, avoid alarm floods; every alarm must require an operator action. - Historian — time-series database storing tag values (temperatures, states) with compression for years; used for trends, OEE, investigations, batch reports. - High-performance HMI (ISA-101): grey backgrounds, colour only for abnormal states, clear hierarchy of screens. Tag = named data point (e.g. Line1.Filler.Motor.Running , Tank3.Level.PV ) with type, address, scaling, alarms and history settings."},{"kind":"lesson","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"industrial-networks-and-modbus","title":"Industrial networks and Modbus","body":"Network Type Common with --- --- --- Modbus RTU Serial (RS-485), master/slave Meters, drives, simple devices Modbus TCP Ethernet, client/server, port 502 Everywhere — simplest Ethernet protocol PROFIBUS DP Fieldbus (RS-485) Siemens installations PROFINET Industrial Ethernet, real-time Siemens EtherNet/IP (CIP) Industrial Ethernet Rockwell / Allen-Bradley EtherCAT Very fast Ethernet fieldbus Motion control, Beckhoff CAN / CANopen, DeviceNet Fieldbus Machines, vehicles IO-Link Point-to-point smart sensor link Sensor diagnostics and parameters HART Digital signal over 4–20 mA Process instruments Modbus data model: Table Access Function codes --- --- --- Coils (0xxxx) — 1 bit Read/write FC01 read, FC05 write single, FC15 write multiple Discrete inputs (1xxxx) — 1 bit Read-only FC02 Input registers (3xxxx) — 16 bit Read-only FC04 Holding registers (4xxxx) — 16 bit Read/write FC03 read, FC06 write single, FC16 write multiple 32-bit floats use two registers — check the word/byte order (big-endian vs \"word swapped\") in the device manual. Modbus has no authentication or encryption — keep it on isolated networks."},{"kind":"lesson","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"opc-ua-the-standard-for-it-ot-data-exchange","title":"OPC UA — the standard for IT/OT data exchange","body":"OPC UA (Unified Architecture, IEC 62541) is a platform-independent, secure, service-oriented standard for industrial data exchange — the successor of classic OPC DA, which depended on Windows DCOM. Feature Meaning --- --- Information model Address space of nodes (objects, variables, methods) with types and references — data has meaning, not just addresses Services Browse, Read, Write, Subscribe (monitored items notify on change), Call methods, history read, alarms & conditions Security X.509 certificates, signing and encryption, user authentication (username, certificate, token) Transports Binary over TCP ( opc.tcp://host:4840 ), HTTPS; PubSub over UDP/MQTT for one-to-many Companion specifications Standard models per industry/machine type (PackML, Robotics, Machine Tools/umati, Euromap for plastics) Many PLCs (Siemens S7-1500, Beckhoff, B&R, CODESYS) include an OPC UA server; gateways such as Kepware expose older protocols as OPC UA."},{"kind":"lesson","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"connecting-plcs-to-dotnet-applications","title":"Connecting PLCs to .NET applications","body":"Read a Modbus TCP register with NModbus: csharp using System.Net.Sockets; using NModbus; using var tcp = new TcpClient(\"192.168.0.10\", 502); var master = new ModbusFactory().CreateMaster(tcp); ushort[] regs = master.ReadHoldingRegisters(slaveAddress: 1, startAddress: 0, numberOfPoints: 2); float temperature = BitConverter.ToSingle(BitConverter.GetBytes((regs[0] << 16) regs[1]), 0); // word order per device manual master.WriteSingleRegister(1, 10, 750); // write setpoint 75.0 (scaled ×10) Subscribe to OPC UA values with the OPC Foundation .NET stack (simplified): csharp var endpoint = CoreClientUtils.SelectEndpoint(config, \"opc.tcp://plc1:4840\", useSecurity: true); using var session = await Session.Create(config, new ConfiguredEndpoint(null, endpoint), false, \"MES\", 60000, new UserIdentity(), null); var subscription = new Subscription(session.DefaultSubscription) { PublishingInterval = 1000 }; var item = new MonitoredItem(subscription.DefaultItem) { StartNodeId = \"ns=3;s=\\\"Line1\\\".\\\"Temperature\\\"\", SamplingInterval = 500 }; item.Notification += (mi, e) = { foreach (var value in mi.DequeueValues()) Console.WriteLine($\"{mi.StartNodeId} = {value.Value} ({value.StatusCode}) @ {value.SourceTimestamp}\"); }; subscription.AddItem(item); session.AddSubscription(subscription); subscription.Create(); Architecture for a plant-data application: text PLCs (Modbus/S7/EtherNet/IP) ─► Gateway / OPC UA server ─► Edge service (.NET Worker, buffering) ─► MQTT broker or Azure IoT Hub ─► Stream processing ─► SQL Server / time-series DB ─► Dashboards, MES, ML Design rules: read-mostly (writes to PLCs only through controlled, audited paths with interlocks staying in the PLC), buffer data at the edge when the network drops (store-and-forward), use source timestamps and status/quality codes, keep OT networks segmented."},{"kind":"lesson","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"functional-safety-and-ot-cybersecurity","title":"Functional safety and OT cybersecurity","body":"Functional safety — protecting people and equipment when something fails: - Standards: IEC 61508 (general), IEC 61511 (process industry SIS), ISO 13849 / IEC 62061 (machinery). - SIL (Safety Integrity Level 1–4) / PL (Performance Level a–e) express required risk reduction. - Emergency stop circuits are hard-wired or on safety PLCs; standard PLC logic must never be the only protection. - Fail-safe design: stop buttons wired normally-closed, outputs de-energise to a safe state, watchdogs. OT cybersecurity: Principle Practice --- --- Segmentation Zones and conduits (IEC 62443), firewalls between levels, an industrial DMZ between IT and OT Least privilege Role-based access to engineering tools and HMIs; no shared admin passwords Secure protocols OPC UA with security; avoid exposing Modbus/S7 to IT or the internet Patch & asset management Inventory of PLC firmware/versions; patch in maintenance windows Monitoring OT intrusion detection (Nozomi, Claroty, Dragos); log engineering changes Remote access Through secured jump hosts/VPN with MFA, time-limited, recorded Real incidents: Stuxnet (2010, centrifuge PLCs), Ukraine power grid (2015/2016), Triton/Trisis (2017, targeted safety systems), Colonial Pipeline (2021, IT ransomware that forced OT shutdown)."},{"kind":"question","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"996","title":"What is a PLC and how is it different from a microcontroller or PC?","body":"A PLC is a rugged industrial controller that reads inputs, runs a control program in a deterministic scan cycle and drives outputs. Compared to a PC it is built for harsh environments, real-time deterministic timing, direct industrial I/O and decades of 24/7 operation, programmed in IEC 61131-3 languages. A microcontroller is a chip that needs custom boards, protection and certification to do the same job."},{"kind":"question","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"997","title":"Explain the PLC scan cycle.","body":"Read all inputs into the input image table → execute the program top to bottom using that image → write the output image to the physical outputs → do communication and diagnostics → repeat. Scan time is usually milliseconds. Because inputs are sampled once per scan, very short pulses need high-speed inputs or interrupts."},{"kind":"question","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"998","title":"What are the IEC 61131-3 programming languages?","body":"Ladder Diagram (relay-style graphics), Function Block Diagram (blocks connected by signals), Structured Text (high-level text like Pascal), Sequential Function Chart (steps and transitions for sequences), and Instruction List (assembly-like, deprecated since the 2013 edition). Ladder for discrete logic, ST for maths and data, SFC for sequences, FBD for process control."},{"kind":"question","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"999","title":"What is the difference between SCADA, HMI and DCS?","body":"HMI is the operator interface for a machine or line. SCADA supervises many controllers over a plant or wide area — data acquisition, control, alarms, trends and reporting. A DCS is an integrated control system (controllers + HMI + engineering) for continuous processes like refineries and power plants, where control is distributed across controllers on a common platform."},{"kind":"question","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"1000","title":"Why is 4–20 mA used instead of 0–20 mA or 0–10 V?","body":"Current signals are not affected by voltage drop over long cables and are less sensitive to electrical noise. The \"live zero\" at 4 mA lets you detect a broken wire (current near 0 mA) as a fault rather than reading it as 0 %, and the 4 mA can power two-wire loop-powered transmitters."},{"kind":"question","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"1001","title":"What is the difference between NO and NC contacts, and why is a stop button wired NC?","body":"Normally open contacts close when actuated; normally closed contacts open when actuated. Stop and emergency-stop buttons are wired NC so a broken wire or loose terminal has the same effect as pressing Stop — the machine fails safe instead of becoming impossible to stop."},{"kind":"question","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"1002","title":"Explain the start/stop seal-in (latching) circuit.","body":"Start (NO) in parallel with a contact of the motor output, in series with Stop (NC in the field) and overload. Pressing Start energises the motor coil; the motor's own contact keeps the rung true after Start is released (seal-in); pressing Stop or an overload breaks the rung. In ST: Motor := (Start OR Motor) AND NOT Stop AND NOT Overload; ."},{"kind":"question","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"1003","title":"Explain TON, TOF and counters with an example.","body":"TON (on-delay): output becomes true when the input has stayed true for the preset — e.g. start a conveyor 5 s after a horn. TOF (off-delay): output stays true for the preset after the input turns false — e.g. keep a cooling fan running 2 minutes after the motor stops. CTU counts rising edges to a preset — e.g. 100 parts fill a box, then reset."},{"kind":"question","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"1004","title":"What is Modbus? Explain its data model and function codes.","body":"A simple open request/response protocol (RTU over RS-485 serial, TCP over Ethernet on port 502). Data tables: coils (read/write bits — FC01/05/15), discrete inputs (read-only bits — FC02), input registers (read-only 16-bit — FC04) and holding registers (read/write 16-bit — FC03/06/16). 32-bit values span two registers with device-specific word order. It has no security, so it belongs on segmented networks."},{"kind":"question","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"1005","title":"What is OPC UA and why is it important for Industry 4.0?","body":"A vendor- and platform-independent standard (IEC 62541) for secure industrial data exchange. It provides a rich information model (typed objects, not just addresses), services for read/write/subscribe/methods/history/alarms, built-in security with certificates and encryption, and transports from client/server to PubSub over MQTT. It lets MES, cloud and analytics systems read machine data the same way from any vendor."},{"kind":"question","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"1006","title":"What is PID control? What do P, I and D do?","body":"A feedback algorithm that adjusts an output to keep a process variable at its setpoint. P reacts to the current error (bigger error → bigger correction), I accumulates past error to remove steady-state offset, D reacts to how fast the error changes to reduce overshoot. Tuning balances speed, overshoot and stability; add anti-windup and output limits."},{"kind":"question","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"1007","title":"What is the difference between FAT and SAT?","body":"Factory Acceptance Test: the system (panels, PLC/HMI programs) is tested at the integrator's site, often with simulated I/O, before shipping. Site Acceptance Test: after installation at the plant, with real field devices and process, before handover to production. Both are witnessed and documented against the functional specification."},{"kind":"question","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"1008","title":"How would you collect data from 50 PLCs of different brands into a .NET application?","body":"Use a gateway/OPC UA layer to normalise protocols (built-in OPC UA servers, or Kepware/Ignition for S7, EtherNet/IP, Modbus), then a .NET edge service (Worker Service) that subscribes to OPC UA monitored items or polls Modbus, adds source timestamps and quality, buffers locally (store-and-forward) and publishes to MQTT/Azure IoT Hub or writes to a time-series/SQL database. Use a tag configuration table, a consistent naming model (ISA-95 hierarchy), and keep OT and IT networks separated by a DMZ."},{"kind":"question","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"1009","title":"How do you secure an OT network?","body":"Defence in depth per IEC 62443: asset inventory, segmentation into zones and conduits with firewalls and an industrial DMZ, no direct internet access to controllers, secure protocols (OPC UA with signing/encryption), strict remote access (jump host, MFA, recording), least-privilege accounts, change control and backups of PLC programs, patching in maintenance windows, OT-aware monitoring, and incident response plans that consider safety."},{"kind":"question","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"1010","title":"What is the difference between a standard PLC and a safety PLC?","body":"A safety PLC is certified for functional safety (e.g. SIL 3 / PL e): redundant processors and I/O, self-diagnostics, safe communication (PROFIsafe, CIP Safety), and a protected safety program that goes to a safe state on any detected fault. Safety functions (e-stop, light curtains, guard doors, burner management) belong in the safety PLC or hard-wired circuits, never only in standard logic."},{"kind":"question","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"1011","title":"A motor sometimes doesn't start when the operator presses Start on the HMI. How do you troubleshoot?","body":"Check the PLC online: is the HMI command bit reaching the PLC (HMI write and tag address), is the command a momentary pulse shorter than the scan or overwritten elsewhere (duplicate coil, another rung/routine), are permissives/interlocks true (stop, overload, guard, upstream conditions), any faults on the drive/VFD, the output module and contactor (output LED, fuse, wiring). Use cross-references and a trend of the involved bits; check the alarm log for the time of failure."},{"kind":"question","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"1012","title":"The MES shows wrong temperature values from a Modbus device. What could be wrong?","body":"Wrong register address (0- vs 1-based offset: 40001 is register 0), wrong function code (holding vs input registers), wrong data type or word/byte order for 32-bit floats, missing scaling factor (value ×10), wrong slave/unit id, or reading stale data after a communication error without checking quality. Compare with a tool like Modbus Poll and the device manual."},{"kind":"question","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"1013","title":"Management wants to let a cloud dashboard write setpoints directly to PLCs. What do you advise?","body":"Treat it as a safety and security risk. Keep control and interlocks in the PLC; allow only bounded, validated setpoint changes through a controlled path (MES/SCADA with role-based access, approval, audit trail, limits enforced again in the PLC); no inbound connections from the internet into OT — use outbound-only edge connections through the DMZ; follow change-management and safety review (MOC). Often a read-only cloud dashboard is the right first step."},{"kind":"cheat","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"1","title":"Levels (ISA-95 / Purdue)","body":"0 field devices · 1 PLC/DCS control · 2 SCADA/HMI · 3 MES/historian · 4 ERP. DMZ between 3 and 4."},{"kind":"cheat","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"2","title":"PLC basics","body":"Scan: inputs → program → outputs → housekeeping. Languages: LD, FBD, ST, SFC (IL deprecated). Timers TON/TOF/TP; counters CTU/CTD; edges R TRIG/F TRIG."},{"kind":"cheat","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"3","title":"Signals","body":"Digital 24 V (PNP/NPN) · 4–20 mA (live zero, broken-wire detection) · 0–10 V · scaling (raw−rMin)/(rMax−rMin)×(eMax−eMin)+eMin ."},{"kind":"cheat","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"4","title":"Modbus","body":"Coils FC01/05/15 · discrete inputs FC02 · input registers FC04 · holding registers FC03/06/16 · TCP port 502 · two registers per float — check word order · no security."},{"kind":"cheat","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"5","title":"OPC UA","body":"Nodes + information model · read/write/subscribe/methods/history/alarms · certificates + encryption · opc.tcp://host:4840 · PubSub over MQTT · companion specs."},{"kind":"cheat","course_slug":"industrial-automation","course_title":"Industrial Automation — PLC, SCADA, Modbus and OPC UA","ref":"6","title":"Safety & security","body":"E-stop NC and on safety PLC/hard-wired · SIL/PL · IEC 62443 zones & conduits · no internet to PLCs · audited writes only."},{"kind":"course","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"","title":"Industry 4.0 & IIoT — Smart Manufacturing Software","body":"The four industrial revolutions and Industry 4.0 pillars, IIoT architecture (edge, gateway, cloud), MQTT and Sparkplug B, the unified namespace, ISA-95 and MES functions, OEE and downtime analytics, traceability and genealogy, time-series data, digital twins, predictive maintenance and AI, Azure/AWS IoT platforms, building it with .NET, and the Industry 4.0 interview questions. Industry 4.0 (the fourth industrial revolution) is the digital transformation of manufacturing: machines, products, people and systems connected and exchanging data so factories can monitor, analyse and optimise themselves. Revolution Around Driver --- --- --- 1.0 1780s Mechanisation — water and steam power 2.0 1870s Mass production — electricity, assembly lines 3.0 1970s Automation — electronics, PLCs, IT 4.0 2010s → Cyber-physical systems — IIoT, cloud, data analytics, AI 5.0 (EU concept, 2021) Now Human-centric, resilient, sustainable industry Pillars / technologies: Industrial IoT (IIoT), cloud and edge computing, big data and analytics, AI/ML, digital twins and simulation, horizontal and vertical system integration (ERP ↔ MES ↔ machines), additive manufacturing, augmented reality, autonomous robots/AMRs, cybersecurity. Why companies invest: higher OEE , less unplanned downtime, better quality (fewer defects and scrap), traceability for regulations and recalls, energy savings, faster changeovers, data-driven decisions instead of paper and Excel. Year Milestone --- --- 1999 MQTT created (Andy Stanford-Clark, IBM and Arlen Nipper) for oil pipeline telemetry 2000 ISA-95 first published (later IEC 62264) — enterprise–control integration 2011 \"Industrie 4.0\" presented at Hannover Messe; German government strategy 2014 MQTT 3.1.1 becomes an OASIS standard; Industrial Internet Consortium founded 2015 RAMI 4.0 reference architecture; Asset Administration Shell concept 2016–2018 Azure IoT Hub / IoT Edge, AWS IoT Greengrass; Eclipse Sparkplug for MQTT 2019 MQTT 5.0 2021 European Commission publishes \"Industry 5.0\" vision 2022–2023 Sparkplug 3.0 (Eclipse); \"Unified Namespace\" architecture popular; Azure Digital Twins mature 2024–2025 Azure IoT Operations (edge, Kubernetes-based, MQTT broker + OPC UA connector) GA; generative AI copilots for operators and maintenance Data journey in a smart factory: 1. Sense — PLCs, sensors, machines produce signals (temperature, counts, states, alarms). 2. Connect — protocols (OPC UA, Modbus, MQTT) via gateways and edge devices. 3. Contextualise — attach meaning: which site/area/line/machine, which order, product, shift (ISA-95 model). 4. Store — time-series database/historian for signals, relational database for orders, quality and genealogy. 5. Analyse — OEE, downtime Pareto, SPC, energy per unit, ML for anomalies and predictions. 6. Act — dashboards and alerts to operators, work orders to maintenance, adjustments via MES/SCADA — closing the loop. 7. Improve — continuous improvement (Kaizen, Lean, Six Sigma) using the data. Implementation roadmap: pick one line and one KPI (pilot) → connect machines → OEE/downtime dashboard → prove value → standardise data model and architecture → scale to lines/plants → advanced use cases (predictive maintenance, AI, digital twin). - Edge & connectivity: Kepware, Ignition Edge, Node-RED, Azure IoT Edge / Azure IoT Operations, AWS IoT Greengrass, Siemens Industrial Edge, HiveMQ / EMQX / Mosquitto (MQTT brokers). - Platforms: Azure IoT Hub, Azure Event Hubs, Azure Digital Twins, Microsoft Fabric Real-Time Intelligence / Azure Data Explorer, AWS IoT Core & SiteWise, Siemens Insights Hub (MindSphere), PTC ThingWorx. - MES / MOM: Siemens Opcenter, Rockwell FactoryTalk ProductionCentre / Plex, AVEVA MES, Critical Manufacturing, Ignition MES modules, custom .NET MES. - Data: InfluxDB, TimescaleDB, AVEVA PI, SQL Server, Azure Data Explorer (KQL), Grafana, Power BI. - .NET building blocks: MQTTnet, OPC UA .NET Standard, Azure IoT SDK ( Microsoft.Azure.Devices.Client ), Worker Services, SignalR (live dashboards), ML.NET."},{"kind":"lesson","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"industry-4-0-concepts-and-the-smart-factory","title":"Industry 4.0 concepts and the smart factory","body":"Key terms: Term Meaning --- --- Cyber-physical system (CPS) Physical machine + software that monitors and controls it via data IIoT Internet of Things applied to industrial equipment IT/OT convergence Connecting business IT systems with plant operational technology Vertical integration Data flows up and down the levels: sensor → PLC → SCADA → MES → ERP Horizontal integration Data flows along the value chain: suppliers → plants → logistics → customers Edge computing Processing data near the machines (low latency, works offline, reduces bandwidth) Digital thread Connected data across the product lifecycle — design, production, service Lights-out manufacturing Highly automated production that runs with minimal human presence Smart factory example: a CNC line streams spindle load, temperature and state to an edge gateway; MES knows which order and part is running; OEE dashboards show losses in real time; a vibration model predicts bearing failure two weeks ahead and creates a maintenance work order; every part's serial number is linked to its machine parameters for traceability."},{"kind":"lesson","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"isa-95-mes-and-what-mes-does","title":"ISA-95, MES and what MES does","body":"ISA-95 (IEC 62264) defines the interface between enterprise systems (Level 4, ERP) and manufacturing operations (Level 3, MES) and a standard equipment hierarchy: text Enterprise → Site → Area → Work centre / Production line → Work unit / Machine MES (Manufacturing Execution System) — the system that runs production on the shop floor between ERP and machines. Typical functions (MESA model): Function What it does --- --- Production order management Receive orders from ERP, dispatch to lines, track progress Work instructions Digital SOPs per step and product Data collection Counts, scrap, downtime reasons, process parameters Quality management Inspections, SPC, non-conformances, CAPA Traceability & genealogy Which materials, lots and machines made each product Performance analysis OEE, downtime, cycle times Labour management Operators, skills, shifts Maintenance integration Machine states → CMMS work orders Material/inventory on the floor WIP, consumption, kanban ERP plans what and when (days/weeks); MES executes how (minutes/seconds); PLCs control the machine (milliseconds)."},{"kind":"lesson","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"iiot-reference-architecture-device-edge-cloud","title":"IIoT reference architecture — device, edge, cloud","body":"text Machines/PLCs ──OPC UA/Modbus──► Edge gateway (filter, buffer, compute) ──MQTT/AMQP/HTTPS──► Cloud ingestion (IoT Hub / Event Hubs / MQTT broker) ──► Stream processing (rules, aggregates) ├─► Hot path: real-time dashboards & alerts (SignalR, Grafana) ├─► Warm path: time-series store (ADX, InfluxDB, PI) for trends & OEE └─► Cold path: data lake / warehouse for ML and reporting MES / ERP / CMMS integrations ◄──► APIs and events Edge vs cloud: Edge Cloud --- --- Millisecond-second decisions, works offline Fleet-wide analytics, long-term storage, ML training Protocol translation, filtering, compression Integration across plants and with business systems Store-and-forward when the link fails Elastic scale, managed services Design rules: outbound-only connections from OT to cloud, device identity with certificates, buffering at the edge, source timestamps in UTC, data quality flags, a consistent naming model, and data contracts versioned like APIs."},{"kind":"lesson","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"mqtt-sparkplug-b-and-the-unified-namespace","title":"MQTT, Sparkplug B and the Unified Namespace","body":"MQTT — lightweight publish/subscribe protocol over TCP (1883, TLS 8883). Clients publish to topics ; the broker delivers to subscribers. Feature Meaning --- --- Topics Hierarchical strings: acme/pune/assembly/line1/robot2/temperature Wildcards + one level ( acme/+/assembly/ ), all remaining levels QoS 0 / 1 / 2 At most once / at least once / exactly once Retained message Broker keeps the last value for new subscribers Last Will & Testament Broker publishes it if a client disconnects unexpectedly (device offline) Persistent session Broker queues messages for a client while it is offline MQTT 5 Reason codes, user properties, shared subscriptions, message expiry Sparkplug B (Eclipse) adds an industrial standard on top of MQTT: fixed topic namespace ( spBv1.0/group/NDATA/edge-node/device ), Protobuf payloads with metrics, birth/death certificates ( NBIRTH / NDEATH ) so subscribers know state, and report-by-exception. Unified Namespace (UNS) — a single, event-driven hub (usually an MQTT broker) where every system publishes its current state under an ISA-95-structured topic tree, and every consumer subscribes to what it needs — replacing point-to-point integrations. csharp // Publish a machine state with MQTTnet (v4/v5 style) var client = new MqttClientFactory().CreateMqttClient(); await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer(\"broker.plant.local\", 8883).WithTlsOptions(o = o.UseTls()) .WithClientId(\"line1-edge\").WithWillTopic(\"acme/pune/assembly/line1/edge/status\").WithWillPayload(\"offline\").WithWillRetain().Build()); var json = JsonSerializer.Serialize(new { state = \"Running\", speed = 42.5, ts = DateTime.UtcNow }); await client.PublishAsync(new MqttApplicationMessageBuilder() .WithTopic(\"acme/pune/assembly/line1/filler/state\").WithPayload(json) .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce).WithRetainFlag().Build()); MQTT vs OPC UA: OPC UA = rich information model and client/server access to machines (great at Level 1–2); MQTT = lightweight pub/sub for moving data to many consumers and the cloud. They are complementary (and OPC UA PubSub can run over MQTT)."},{"kind":"lesson","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"oee-calculation-six-big-losses-and-downtime-analysis","title":"OEE — calculation, six big losses and downtime analysis","body":"OEE (Overall Equipment Effectiveness) = Availability × Performance × Quality Factor Formula Loss it captures --- --- --- Availability Run time ÷ Planned production time Breakdowns, changeovers, waiting Performance (Ideal cycle time × Total count) ÷ Run time Slow cycles, minor stops Quality Good count ÷ Total count Scrap, rework, start-up rejects Worked example (one shift): planned time 480 min; downtime 60 min → run time 420 min → Availability = 87.5 % . Ideal cycle time 1.0 min/part; 380 parts produced → Performance = 380 ÷ 420 = 90.5 % . 361 good parts → Quality = 95 % . OEE = 0.875 × 0.905 × 0.95 ≈ 75.2 % . (World-class benchmark often quoted ≈ 85 %; many plants start at 40–60 %.) Six big losses (TPM): breakdowns, setup/adjustments (→ availability); small stops, reduced speed (→ performance); start-up rejects, production rejects (→ quality). sql -- OEE per line per shift from MES tables (simplified) SELECT s.LineId, s.ShiftDate, s.Shift, Availability = CAST(s.RunMinutes AS float) / NULLIF(s.PlannedMinutes, 0), Performance = (s.IdealCycleMin s.TotalCount) / NULLIF(s.RunMinutes, 0), Quality = CAST(s.GoodCount AS float) / NULLIF(s.TotalCount, 0), OEE = (CAST(s.RunMinutes AS float) / NULLIF(s.PlannedMinutes, 0)) ((s.IdealCycleMin s.TotalCount) / NULLIF(s.RunMinutes, 0)) (CAST(s.GoodCount AS float) / NULLIF(s.TotalCount, 0)) FROM mes.ShiftSummary s; Other KPIs: MTBF (mean time between failures), MTTR (mean time to repair), throughput, first pass yield (FPY), scrap rate, cycle time, takt time (available time ÷ customer demand), energy per unit, schedule adherence."},{"kind":"lesson","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"traceability-genealogy-and-quality-spc","title":"Traceability, genealogy and quality (SPC)","body":"Traceability answers: for this finished serial/lot, which raw-material lots, machines, operators, parameters and test results were involved (backward), and where did a suspect material lot end up (forward)? Essential in automotive (IATF 16949), pharma (GMP, 21 CFR Part 11 electronic records), food and aerospace — and for targeted recalls. sql -- Genealogy: which finished serials used a suspect component lot? WITH Tree AS ( SELECT ChildLot, ParentSerial FROM mes.Consumption WHERE ChildLot = 'LOT-2026-0412' UNION ALL SELECT c.ChildLot, c.ParentSerial FROM mes.Consumption c JOIN Tree t ON c.ChildLot = t.ParentSerial ) SELECT DISTINCT ParentSerial FROM Tree; SPC (Statistical Process Control): control charts (X̄–R, I-MR) with control limits at ±3σ; rules (Western Electric/Nelson) flag out-of-control trends before parts go out of tolerance. Cp/Cpk measure process capability against specification limits (Cpk ≥ 1.33 a common target)."},{"kind":"lesson","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"time-series-data-at-scale","title":"Time-series data at scale","body":"Machine data is time-series : (timestamp, tag, value, quality), arriving continuously — thousands of tags × 1 Hz = hundreds of millions of rows per month. Technique Why --- --- Time-series databases (ADX/KQL, InfluxDB, TimescaleDB, PI) Fast ingest, compression, time-bucket queries Report by exception / deadband Store only changes beyond a threshold — reduces volume 10–100× Downsampling & retention tiers Raw for weeks, 1-min aggregates for years Partitioning by time (SQL Server partitioning, columnstore) Efficient ranges and archiving UTC timestamps + source time vs ingest time Correct ordering across time zones and late data sql -- SQL Server 2022+: one-minute average per tag with DATE BUCKET SELECT TagId, DATE BUCKET(MINUTE, 1, Ts) AS Minute, AVG(Value) AS AvgValue, MAX(Value) AS MaxValue FROM iot.Telemetry WHERE Ts = DATEADD(HOUR, -8, SYSUTCDATETIME()) GROUP BY TagId, DATE BUCKET(MINUTE, 1, Ts);"},{"kind":"lesson","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"predictive-maintenance-and-ai-in-manufacturing","title":"Predictive maintenance and AI in manufacturing","body":"Strategy Trigger Downside --- --- --- Reactive Fix after failure Unplanned downtime, secondary damage Preventive Fixed schedule (hours, cycles) Replaces healthy parts, still misses random failures Condition-based Threshold on a measurement (vibration limit) Late warning Predictive Model predicts failure/remaining useful life from trends Needs data, labels and domain knowledge Data used: vibration (accelerometers, FFT spectra), temperature, current/power, pressure, acoustic, oil analysis, cycle counts, alarm history, maintenance records (labels). Approach: collect and label history → feature engineering (RMS, kurtosis, spectral peaks, trends) → anomaly detection (isolation forest, autoencoders) when few failures exist, or classification/regression for remaining useful life → deploy at edge or cloud → alert + create CMMS work order → measure avoided downtime and false alarms. Other AI use cases: visual inspection with computer vision (defect detection), process parameter optimisation, demand-driven scheduling, energy optimisation, generative-AI assistants that answer operators from manuals and work history."},{"kind":"lesson","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"digital-twins-and-simulation","title":"Digital twins and simulation","body":"A digital twin is a live digital representation of a physical asset, process or plant, kept in sync with real data, used to monitor, simulate and optimise. Level Example --- --- Component/asset twin A pump with its live state, health score and maintenance history Process/line twin A production line model to test a new schedule or layout virtually Plant/system twin Whole factory — energy, flow, capacity planning Product twin Each serial's as-built data for service and warranty Technologies: Azure Digital Twins (DTDL models + twin graph), Asset Administration Shell (Industry 4.0 standard for asset information), NVIDIA Omniverse/Siemens tools for 3D simulation, discrete-event simulation (AnyLogic, Plant Simulation), virtual commissioning (test PLC code against a simulated machine before it exists)."},{"kind":"lesson","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"building-an-industry-4-0-platform-with-dotnet","title":"Building an Industry 4.0 platform with .NET","body":"Typical .NET solution for a smart-factory MES/IIoT platform: text Edge: .NET Worker Service (OPC UA / Modbus / MQTT clients) → local buffer (SQLite) → MQTT / IoT Hub Cloud/on-prem: Ingestion : MQTT broker or Azure IoT Hub/Event Hubs → .NET consumer (BackgroundService) or Azure Functions Storage : SQL Server (orders, quality, genealogy — RLS per plant/tenant) + time-series store (ADX/InfluxDB) APIs : ASP.NET Core Web API (REST), SignalR hub for live machine states UI : Angular/React/Next.js dashboards — OEE, downtime Pareto, andon boards, work instructions Jobs : Shift summaries, OEE aggregation, ERP sync (SAP/Dynamics via APIs/IDocs) Ops : Docker/Kubernetes or Azure Container Apps, OpenTelemetry, Grafana csharp // Edge worker: read OPC UA/Modbus, publish to MQTT, buffer when offline (sketch) public class TelemetryWorker(ITagReader reader, IMqttPublisher mqtt, ILocalBuffer buffer, ILogger<TelemetryWorker log) : BackgroundService { protected override async Task ExecuteAsync(CancellationToken ct) { using var timer = new PeriodicTimer(TimeSpan.FromSeconds(1)); while (await timer.WaitForNextTickAsync(ct)) { var samples = await reader.ReadChangedAsync(ct); // report by exception try { await buffer.FlushAsync(mqtt, ct); await mqtt.PublishAsync(samples, ct); } catch (Exception ex) { log.LogWarning(ex, \"Broker unreachable, buffering {Count}\", samples.Count); await buffer.StoreAsync(samples, ct); } } } } Non-functional concerns interviewers ask about: multi-plant/multi-tenant isolation (Row-Level Security), time zones and shift calendars, offline tolerance, audit trails and e-signatures (pharma 21 CFR Part 11), validation, OT security, and scaling ingestion (partitioning, batching, back-pressure)."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1014","title":"What is Industry 4.0?","body":"The fourth industrial revolution: connecting machines, products, people and IT systems through IIoT, cloud/edge computing, data analytics and AI so factories become transparent, flexible and self-optimising. It builds on the automation of Industry 3.0 (PLCs, IT) by adding connectivity and data-driven decisions — e.g. real-time OEE, predictive maintenance, full traceability and digital twins."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1015","title":"What is IIoT and how is it different from consumer IoT?","body":"Industrial IoT connects industrial equipment — sensors, PLCs, machines — to collect and use data. Compared with consumer IoT it demands higher reliability, determinism and safety, works with industrial protocols (OPC UA, Modbus, PROFINET), runs in harsh environments with long equipment lifetimes (20+ years, brownfield machines), and has stricter security and uptime requirements."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1016","title":"What is OEE and how is it calculated?","body":"Overall Equipment Effectiveness = Availability × Performance × Quality. Availability = run time ÷ planned time; Performance = (ideal cycle time × total count) ÷ run time; Quality = good count ÷ total count. Example: 87.5 % × 90.5 % × 95 % ≈ 75 %. It shows how much of planned time is truly productive and which loss to attack first."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1017","title":"What is an MES and how does it differ from ERP?","body":"MES executes and tracks production on the shop floor in real time — orders dispatched to lines, data collection, quality, traceability, OEE, work instructions. ERP manages the business — finance, purchasing, inventory, sales, planning over days/weeks. ISA-95 defines the integration: ERP sends orders and receives production confirmations and consumption from MES."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1018","title":"What is ISA-95?","body":"An international standard (IEC 62264) for integrating enterprise and control systems. It defines the levels (0–4), the functions of manufacturing operations management (production, quality, maintenance, inventory) and object models for data exchanged between ERP and MES, plus the equipment hierarchy enterprise → site → area → line → unit — used to structure data models and topic namespaces."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1019","title":"What is MQTT and why is it popular in IIoT?","body":"A lightweight publish/subscribe protocol over TCP with a broker. Small overhead, works on unreliable networks, decouples producers from consumers, supports QoS levels, retained messages, last will (detect offline devices) and persistent sessions; easy to secure with TLS and certificates; all clouds support it. Sparkplug B adds a standard namespace, payload format and state management for industrial use."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1020","title":"Explain MQTT QoS levels.","body":"QoS 0 — at most once, fire-and-forget, may be lost. QoS 1 — at least once, acknowledged, may be duplicated (consumers must be idempotent). QoS 2 — exactly once via a four-step handshake, slower. Telemetry usually uses 0 or 1; commands and important events use 1 with idempotency or 2."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1021","title":"What is the difference between OPC UA and MQTT? When do you use which?","body":"OPC UA is a full industrial interoperability standard — rich information models, browse/read/write/subscribe/methods, built-in security — ideal for connecting to machines and controllers. MQTT is a lightweight transport for pub/sub distribution of data to many consumers and to the cloud. Common pattern: OPC UA at the machine/edge, MQTT (or OPC UA PubSub over MQTT) from the edge to the enterprise/cloud."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1022","title":"What is edge computing and why is it needed in factories?","body":"Processing data close to the machines on gateways or industrial PCs. Needed for low-latency decisions, operation when the network or cloud is down (store-and-forward), reducing bandwidth by filtering/aggregating high-frequency data, protocol translation, and keeping sensitive OT networks closed while sending only outbound data."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1023","title":"What is the Unified Namespace?","body":"An architecture where an event broker (typically MQTT) holds the current state of the whole business in one ISA-95-structured topic hierarchy. Machines, MES, ERP and analytics publish and subscribe there instead of building point-to-point integrations, making data discoverable and new consumers easy to add. It needs governance of topic structure and payload contracts."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1024","title":"What are MTBF and MTTR?","body":"MTBF (mean time between failures) = operating time ÷ number of failures — reliability. MTTR (mean time to repair) = total repair time ÷ number of repairs — maintainability. Availability ≈ MTBF ÷ (MTBF + MTTR). Improving maintenance, spare-part availability and diagnostics reduces MTTR; root-cause analysis and predictive maintenance increase MTBF."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1025","title":"How does predictive maintenance work? What data do you need?","body":"Collect condition data (vibration, temperature, current, pressure, cycles) plus maintenance and failure history, engineer features (RMS, spectral peaks, trends), train anomaly-detection or remaining-useful-life models, deploy them at the edge or cloud, and turn predictions into alerts and CMMS work orders. Success needs domain experts, enough failure examples (or anomaly detection when rare), and a feedback loop measuring avoided downtime and false alarms."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1026","title":"Design a real-time OEE dashboard for 20 production lines.","body":"Edge per line reads machine state, counts and reject signals via OPC UA/Modbus, timestamps in UTC and publishes state changes to MQTT/IoT Hub. A stream processor or .NET consumer maintains current state per line, accumulates run/down time by reason and counts, stores events in a time-series/SQL store and shift summaries in SQL. An ASP.NET Core API + SignalR pushes live updates to an Angular/React dashboard (andon view, OEE gauges, downtime Pareto). Operators enter downtime reasons on a tablet. Handle shift calendars, planned stops, ideal cycle times per product, and offline buffering."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1027","title":"What is a digital twin? Give a practical example.","body":"A live virtual model of a physical asset or process, synchronised with real data and used to monitor, predict and simulate. Example: a twin of a packaging line combining live machine states, a throughput model and maintenance data, used to test a new product changeover sequence virtually and to predict the effect of a slower filler on output. Tools: Azure Digital Twins (DTDL), Asset Administration Shell, simulation software, virtual commissioning."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1028","title":"How do you handle millions of telemetry rows per day in SQL Server?","body":"Batch inserts (SqlBulkCopy, table-valued parameters), narrow tables with tag ids, clustered columnstore indexes for history, partitioning by date with sliding-window archiving, report-by-exception/deadband to cut volume, aggregates (1-min/1-h) for dashboards, DATE BUCKET and window functions for queries, separate hot recent data from cold history — or use a dedicated time-series store (ADX/InfluxDB) and keep SQL for transactional MES data."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1029","title":"A plant has 30-year-old machines without network connectivity. How do you bring them into an Industry 4.0 project?","body":"Retrofit: add sensors (current clamps for run/stop, vibration sensors, photo-eyes or counters for parts), read existing PLC I/O through gateways or protocol converters (serial Modbus → TCP), or use IO-Link and small edge devices. Start with simple, high-value signals (running/stopped, count, reject) to get OEE and downtime, then add condition monitoring. Keep the machine's safety and control untouched; document and secure the new connections."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1030","title":"OEE dashboards show 110 % performance on some lines. What is wrong?","body":"Performance above 100 % means the ideal cycle time is wrong (too slow) or counts are inflated — wrong ideal cycle time for the running product, product not switched in the system at changeover, double counting from sensor bounce (needs debounce/edge detection), counting rejects twice, or run time understated (downtime recorded incorrectly). Validate the master data per product and the signal logic at the edge."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1031","title":"Telemetry arrives late and out of order after network outages. How do you keep reports correct?","body":"Use the device's source timestamp (UTC) rather than ingestion time, buffer and replay at the edge with sequence numbers, make ingestion idempotent (dedupe by device + sequence/timestamp), let aggregations handle late data (recompute affected windows, or watermarks in stream processing), and show data-quality flags on dashboards when data is incomplete."},{"kind":"question","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1032","title":"Management asks: \"How do we start Industry 4.0 with a small budget?\"","body":"Start with a clear business problem and one KPI — usually OEE/downtime on a bottleneck line. Connect a few signals with low-cost edge hardware, build a simple dashboard and digital downtime-reason entry, run daily review meetings on the data, and quantify savings (more output, less scrap, less overtime). Use the result to fund scaling with a standard architecture (ISA-95 naming, MQTT/OPC UA, central data store), then move to predictive maintenance and quality analytics."},{"kind":"cheat","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"1","title":"Concepts","body":"Industry 4.0 = CPS + IIoT + cloud/edge + analytics/AI · IT/OT convergence · vertical (sensor→ERP) and horizontal (supply chain) integration · Industry 5.0 = human-centric, resilient, sustainable."},{"kind":"cheat","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"2","title":"Levels & systems","body":"ISA-95: 0 field · 1 PLC · 2 SCADA/HMI · 3 MES/historian · 4 ERP. ERP plans (days), MES executes (minutes), PLC controls (ms)."},{"kind":"cheat","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"3","title":"OEE","body":"OEE = Availability × Performance × Quality · A = run/planned · P = ideal cycle × count / run · Q = good/total · six big losses · world class ≈ 85 %."},{"kind":"cheat","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"4","title":"Protocols","body":"OPC UA (machine access, information model, security) · MQTT (pub/sub, QoS 0/1/2, retained, LWT) · Sparkplug B (namespace + birth/death) · Unified Namespace on an MQTT broker."},{"kind":"cheat","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"5","title":"Use cases","body":"Real-time OEE & downtime · traceability/genealogy · SPC & quality · predictive maintenance · energy monitoring · digital twin & virtual commissioning · computer-vision inspection · AI assistants."},{"kind":"cheat","course_slug":"industry-40","course_title":"Industry 4.0 & IIoT — Smart Manufacturing Software","ref":"6","title":".NET stack","body":"Worker Service edge (OPC UA .NET, NModbus, MQTTnet) · IoT Hub/Event Hubs · ASP.NET Core API + SignalR · SQL Server (RLS, columnstore, partitions) + time-series DB · Angular/React dashboards · Docker/K8s · OpenTelemetry."},{"kind":"course","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"","title":"Blockchain & Web3 Fundamentals","body":"Web1/Web2/Web3, blockchain data structures, hashing and cryptography, consensus (PoW, PoS), Bitcoin and Ethereum, accounts, transactions and gas, wallets and keys, tokens (ERC-20, ERC-721, ERC-1155), DeFi, NFTs, DAOs, layer 2s, oracles, dApp architecture with .NET and JavaScript, and security. Blockchain is a distributed, append-only ledger replicated across many computers (nodes). Records are grouped into blocks , each linked to the previous one by a cryptographic hash , so altering history is practically impossible without redoing the work/stake of the whole network. Nodes agree on the state with a consensus mechanism — no central authority. Web3 is the idea of an internet where users own their data, identity and assets via blockchains, wallets and smart contracts: Web1 (1990s–2004) Web2 (2004–) Web3 --- --- --- --- Model Read Read + write Read + write + own Content Static pages User-generated, platforms User-owned assets & data Identity None Platform accounts (email/password, OAuth) Wallet (public key) Money — Payment gateways Native crypto, tokens Control Site owners Big platforms Protocols, smart contracts, DAOs Main uses: cryptocurrencies and payments, stablecoins, decentralised finance (DeFi), NFTs and digital ownership, tokenisation of real-world assets (RWA), supply-chain traceability, decentralised identity, DAOs, gaming. Honest perspective for interviews: blockchains trade performance and simplicity for decentralisation and trustlessness. Good answers mention when a normal database is the better choice, regulation (e.g. India's 30% tax on virtual digital asset gains and 1% TDS; Taiwan's VASP registration regime) and security risks (scams, hacks, key loss). Year Milestone --- --- 1991 Haber & Stornetta — cryptographically secured chain of timestamped documents 2008 Bitcoin whitepaper by the pseudonymous Satoshi Nakamoto Jan 2009 Bitcoin genesis block mined; network launched 2013 Vitalik Buterin publishes the Ethereum whitepaper Jul 2015 Ethereum mainnet (Frontier) — programmable smart contracts, EVM 2015 Hyperledger (Linux Foundation) for enterprise/permissioned chains 2017 ICO boom; ERC-20 standardised; CryptoKitties (early NFTs, ERC-721 finalised 2018) 2020 \"DeFi summer\" (Uniswap, Aave, Compound); Ethereum Beacon Chain launched (PoS) 2021 NFT boom; EIP-1559 fee market (London upgrade); El Salvador makes BTC legal tender Sep 2022 The Merge — Ethereum switches from Proof of Work to Proof of Stake (~99.95% less energy) 2023 Shanghai/Capella (staking withdrawals); ERC-4337 account abstraction deployed 2024 Dencun (EIP-4844 \"blobs\" → much cheaper layer-2 fees); US spot Bitcoin ETFs (Jan) and Ether ETFs (Jul); Bitcoin's 4th halving (Apr) 2025 Pectra upgrade (May — EIP-7702 smart accounts for regular wallets, higher validator stake limit); Fusaka (Dec 2025 — PeerDAS for more blob capacity) Programming-language and tooling versions: Solidity 0.4 (2016) → 0.8 (2020, checked arithmetic) → 0.8.x current; ethers.js v6 (2023); viem 2 (2024); Nethereum 4.x/5.x for .NET. Transaction lifecycle on Ethereum: 1. User builds a transaction in a wallet (to, value, data, gas limit, max fee, nonce). 2. The wallet signs it with the private key (ECDSA secp256k1). 3. Broadcast to a node via JSON-RPC ( eth sendRawTransaction ) → enters the mempool . 4. A block proposer (validator in PoS) selects transactions (usually by fee/priority tip) and builds a block (about every 12 seconds — one slot). 5. Transactions execute in the EVM ; state changes (balances, contract storage); gas is charged; events/logs emitted; a receipt records status. 6. The block is attested by validators → added to the chain → confirmations accumulate. 7. Finality — under Ethereum PoS a block is finalised after two epochs (~12.8 minutes); then reverting it would require destroying at least 1/3 of staked ETH. Smart contract lifecycle: design → write (Solidity) → test (unit + fuzz) → audit → deploy (a transaction creating the contract; code is immutable unless an upgrade pattern is used) → verify source on a block explorer → interact → upgrade via proxy (if designed) or migrate → pause/deprecate. Block lifecycle (Bitcoin PoW): transactions in mempool → miners assemble a block → find a nonce so the block hash is below the difficulty target (~10 minutes average) → broadcast → nodes validate → longest valid (most-work) chain wins; 6 confirmations is the common safety threshold. Area Tools --- --- Wallets MetaMask, Coinbase Wallet, Rabby, Trust Wallet; hardware: Ledger, Trezor; Safe (multisig) Node access (RPC) Infura, Alchemy, QuickNode, own node (Geth, Nethermind (written in .NET/C ), Reth, Erigon + consensus client) Development frameworks Hardhat , Foundry (forge/cast/anvil), Remix IDE (browser) Libraries (JS/TS) ethers.js , viem , wagmi (React hooks), web3.js (legacy, sunset 2025) Libraries (.NET) Nethereum Contract libraries OpenZeppelin Contracts (ERC-20/721/1155, access control, upgradeable proxies) Explorers Etherscan, Blockscout, Polygonscan, BscScan Test networks Sepolia, Holesky/Hoodi (Ethereum testnets), local Anvil/Hardhat Network Indexing & data The Graph, Dune, Etherscan APIs Oracles Chainlink, Pyth Storage IPFS, Filecoin, Arweave Security Slither, Mythril, Echidna, Foundry fuzzing, audits (OpenZeppelin, Trail of Bits, Certora)"},{"kind":"lesson","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"what-a-blockchain-is-and-how-blocks-link","title":"What a blockchain is and how blocks link","body":"Each block contains a header (previous block hash, timestamp, Merkle root of transactions, plus consensus data like nonce/difficulty or proposer info) and a list of transactions . Block 100 Block 101 Block 102 ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ prevHash: 0xab12 │◄────────│ prevHash: H(100) │◄────────│ prevHash: H(101) │ │ merkleRoot │ │ merkleRoot │ │ merkleRoot │ │ txs: [...] │ │ txs: [...] │ │ txs: [...] │ └──────────────────┘ └──────────────────┘ └──────────────────┘ Changing any transaction in block 100 changes its hash, which breaks the link in block 101 and every later block — so tampering is obvious, and rewriting requires re-doing consensus for all following blocks faster than the honest network. Properties: decentralised , immutable/append-only , transparent (public chains), pseudonymous (addresses, not names), trustless (verify instead of trust), fault-tolerant . Types: public permissionless (Bitcoin, Ethereum — anyone can join), private/permissioned (Hyperledger Fabric, R3 Corda, Quorum — known participants), consortium (several organisations), hybrid ."},{"kind":"lesson","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"cryptography-hashing-keys-signatures-and-merkle-trees","title":"Cryptography: hashing, keys, signatures and Merkle trees","body":"- Hash function (SHA-256 in Bitcoin, Keccak-256 in Ethereum): deterministic, fixed-size output, one-way, tiny input change → completely different output (avalanche), collision-resistant. - Public-key cryptography (elliptic curve secp256k1 ): a random private key (256-bit) → public key → address (Ethereum: last 20 bytes of Keccak-256 of the public key, shown as 0x... ). - Digital signature (ECDSA): proves the transaction was authorised by the private-key holder without revealing it; anyone can verify with the public key. - Merkle tree : transactions hashed pairwise up to a single Merkle root in the header — lets light clients prove a transaction is in a block with a small proof (O(log n)). - Seed phrase (BIP-39 mnemonic, 12/24 words) derives many keys (BIP-32/44 hierarchical deterministic wallets). Whoever has the seed phrase owns the funds — no password reset. js // Hashing and signing with ethers.js v6 import { keccak256, toUtf8Bytes, Wallet, verifyMessage } from \"ethers\"; keccak256(toUtf8Bytes(\"hello\")); // 0x1c8aff95... const wallet = Wallet.createRandom(); // never log real keys const sig = await wallet.signMessage(\"Login nonce 4821\"); verifyMessage(\"Login nonce 4821\", sig) === wallet.address; // true → \"Sign-In with Ethereum\" idea"},{"kind":"lesson","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"consensus-mechanisms","title":"Consensus mechanisms","body":"Mechanism How blocks are produced Examples Trade-offs --- --- --- --- Proof of Work Miners compete to solve a hash puzzle; most cumulative work wins Bitcoin, Litecoin Very secure and simple; high energy use; slow Proof of Stake Validators lock stake; chosen to propose/attest; misbehaviour is slashed Ethereum (since 2022), Cardano, Solana (PoS + Proof of History) Energy-efficient, faster finality; complexity, stake concentration Delegated PoS Token holders vote for a few block producers EOS, TRON Fast; more centralised PBFT / BFT variants Known validators vote in rounds Hyperledger Fabric (ordering), Tendermint/CometBFT (Cosmos) Instant finality; limited validator count Proof of Authority Approved identities sign blocks Private networks, some testnets Fast; centralised trust Ethereum PoS numbers: validators stake 32 ETH (Pectra raised the max effective balance to 2,048 ETH); a slot is 12 seconds, an epoch is 32 slots (6.4 minutes); finality after ~2 epochs. 51% attack — controlling the majority of hash power (PoW) or stake (PoS) allows reorganising recent blocks/double spending (not stealing arbitrary funds). Double spending is prevented by consensus on transaction order. Blockchain trilemma (Vitalik Buterin): hard to maximise decentralisation, security and scalability at the same time — hence layer-2 solutions."},{"kind":"lesson","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"bitcoin-vs-ethereum","title":"Bitcoin vs Ethereum","body":"Bitcoin Ethereum --- --- --- Launched 2009 2015 Purpose Digital money / store of value Programmable platform (world computer) Consensus Proof of Work Proof of Stake (since Sep 2022) Block time ~10 minutes 12 seconds Supply Capped at 21 million BTC; halving every 210,000 blocks (~4 years) No hard cap; issuance to validators, part of fees burned (EIP-1559) Model UTXO (unspent transaction outputs) Account-based (balances + contract storage) Smart contracts Limited (Bitcoin Script) Turing-complete (EVM, Solidity) Units 1 BTC = 100,000,000 satoshis 1 ETH = 10^18 wei; 1 gwei = 10^9 wei"},{"kind":"lesson","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"accounts-transactions-gas-and-fees","title":"Accounts, transactions, gas and fees","body":"Accounts: - EOA (Externally Owned Account) — controlled by a private key; has balance and nonce; initiates transactions. - Contract account — has code and storage; runs only when called; no private key. - Smart accounts (account abstraction, ERC-4337; EIP-7702 since Pectra) — programmable wallets: social recovery, batched calls, paying gas in tokens (paymasters), session keys. Gas: every EVM operation costs gas (a unit of computation). A transaction specifies a gas limit . Since EIP-1559 (2021): fee = gasUsed × (baseFee + priorityTip) — the base fee is set by the protocol per block (rises when blocks are full) and is burned ; the priority fee (tip) goes to the validator. Users set maxFeePerGas and maxPriorityFeePerGas . Unused gas is refunded; if gas runs out, the transaction reverts but the fee is still paid. A simple ETH transfer costs 21,000 gas. Nonce — per-account counter preventing replay and ordering transactions."},{"kind":"lesson","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"smart-contracts-and-the-evm","title":"Smart contracts and the EVM","body":"A smart contract is a program deployed on the blockchain that runs exactly as written: it holds state (storage), exposes functions, emits events , and can hold and move funds. The EVM (Ethereum Virtual Machine) is the deterministic, sandboxed, stack-based VM that executes contract bytecode on every node. - Languages: Solidity (most common), Vyper (Pythonic), Yul (low-level). - Compiled to bytecode + an ABI (Application Binary Interface — JSON describing functions/events, used by clients to encode calls). - Read calls ( view / pure via eth call ) are free and don't create transactions; writes require a signed transaction and gas. - Immutability : code can't be changed after deployment — upgrades use proxy patterns (Transparent, UUPS) with an admin, which reintroduces trust. - Contracts can't fetch off-chain data themselves → oracles . - EVM-compatible chains: Polygon PoS, BNB Chain, Avalanche C-Chain, and layer 2s (Arbitrum, Optimism, Base, zkSync, Scroll, Linea). The full Solidity course is next in this track."},{"kind":"lesson","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"token-standards-erc-20-erc-721-erc-1155","title":"Token standards: ERC-20, ERC-721, ERC-1155","body":"Standard Type Key functions Examples --- --- --- --- ERC-20 Fungible tokens (each unit identical) totalSupply , balanceOf , transfer , approve , allowance , transferFrom ; events Transfer , Approval USDC, USDT, DAI, LINK, UNI ERC-721 Non-fungible tokens (unique IDs) ownerOf , safeTransferFrom , approve , setApprovalForAll , tokenURI (metadata) NFT art, tickets, domain names (ENS) ERC-1155 Multi-token (fungible + non-fungible in one contract) balanceOf(account, id) , safeBatchTransferFrom Game items ERC-4626 Tokenised vaults deposit , withdraw , convertToShares Yield vaults ERC-2612 permit (gasless approvals via signatures) permit Many ERC-20s ERC-4337 Account abstraction (smart accounts) UserOperations, bundlers, paymasters Smart wallets Approve + transferFrom pattern: a user approves a DEX contract to spend N tokens, then the DEX pulls them. Unlimited approvals are a common risk — wallets that approved malicious contracts can be drained. Stablecoins : tokens pegged to fiat (USDC, USDT — backed by reserves; DAI — crypto-collateralised)."},{"kind":"lesson","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"defi-nfts-and-daos","title":"DeFi, NFTs and DAOs","body":"- DeFi (decentralised finance): financial services as smart contracts — DEXs using Automated Market Makers (Uniswap: constant product x × y = k , liquidity pools, LP tokens, impermanent loss ), lending/borrowing (Aave, Compound: over-collateralised loans, liquidation), stablecoins, derivatives, yield aggregators, liquid staking (Lido). Key risks: smart-contract bugs, oracle manipulation, flash-loan attacks, liquidation cascades. - NFTs : ERC-721/1155 tokens representing unique items; metadata (name, image) usually stored off-chain on IPFS/Arweave with a tokenURI ; marketplaces (OpenSea, Blur); royalties (ERC-2981, not enforced on-chain universally). Uses beyond art: tickets, memberships, certificates, gaming items, real-world asset titles. - DAOs (decentralised autonomous organisations): governance by token holders voting on proposals (Governor contracts, Snapshot off-chain voting), treasury in a multisig (Safe). Risks: low participation, whale dominance, governance attacks."},{"kind":"lesson","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"scaling-layer-1-layer-2-rollups-and-sidechains","title":"Scaling: layer 1, layer 2, rollups and sidechains","body":"- Layer 1 — the base chain (Ethereum, Bitcoin, Solana). - Layer 2 — executes transactions off the main chain and posts data/proofs to L1, inheriting its security: - Optimistic rollups (Arbitrum, Optimism, Base): assume transactions are valid; anyone can submit a fraud proof during a challenge window (~7 days for withdrawals to L1). - ZK rollups (zkSync Era, Starknet, Scroll, Linea, Polygon zkEVM): post validity proofs (zero-knowledge proofs); faster finality, more complex. - EIP-4844 blobs (Dencun, 2024) made L2 data much cheaper → L2 fees often cents or less. - Sidechains (Polygon PoS, Gnosis Chain): separate chains with their own consensus and bridges (not L1 security). - State channels (Bitcoin Lightning Network): off-chain payments between parties, settle on-chain. - Bridges move assets between chains — historically the biggest hack targets (Ronin $625M in 2022, Wormhole $325M in 2022)."},{"kind":"lesson","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"oracles-storage-and-indexing","title":"Oracles, storage and indexing","body":"- Oracles feed off-chain data (prices, weather, randomness) to contracts — Chainlink Data Feeds, Chainlink VRF (verifiable randomness), Pyth. Using a single DEX spot price as an oracle is a classic exploit vector (flash-loan price manipulation) — use time-weighted or decentralised feeds. - Storage : on-chain storage is very expensive → store files on IPFS (content-addressed by hash — CID), pin with services (Pinata, web3.storage), or permanently on Arweave ; store only the hash/URI on-chain. - Indexing : reading historical events directly from nodes is slow → The Graph subgraphs, custom indexers listening to events into a SQL database, or APIs (Alchemy, Moralis, Etherscan)."},{"kind":"lesson","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"dapp-architecture","title":"dApp architecture","body":"Browser (React/Next.js + wagmi/viem or ethers.js) │ connect wallet (EIP-1193 provider: MetaMask, WalletConnect) │ read: eth call via RPC provider write: user signs tx in wallet ▼ RPC node (Alchemy/Infura/own node) ─────► Ethereum / L2 (smart contracts) ▲ │ events │ ▼ Backend (ASP.NET Core + Nethereum, optional) ◄── indexer / The Graph → SQL DB for fast queries │ off-chain data, auth (Sign-In with Ethereum), notifications ▼ IPFS / Arweave (NFT metadata, files) Principles: the frontend never holds users' private keys — the wallet signs ; keep business-critical logic on-chain only when trustlessness is needed; use a backend for indexing, search, notifications and anything private; handle chain IDs, network switching, pending/failed transactions and re-orgs (wait for confirmations)."},{"kind":"lesson","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"javascript-reading-and-writing-with-ethers-js-v6","title":"JavaScript: reading and writing with ethers.js v6","body":"js import { BrowserProvider, Contract, formatUnits, parseUnits } from \"ethers\"; const ERC20 ABI = [ \"function balanceOf(address) view returns (uint256)\", \"function decimals() view returns (uint8)\", \"function transfer(address to, uint256 amount) returns (bool)\", \"event Transfer(address indexed from, address indexed to, uint256 value)\", ]; const provider = new BrowserProvider(window.ethereum); // MetaMask (EIP-1193) await provider.send(\"eth requestAccounts\", []); const signer = await provider.getSigner(); const token = new Contract(\"0xTokenAddress\", ERC20 ABI, signer); const decimals = await token.decimals(); const balance = await token.balanceOf(await signer.getAddress()); console.log(formatUnits(balance, decimals)); // e.g. \"125.5\" const tx = await token.transfer(\"0xRecipient\", parseUnits(\"10\", decimals)); // wallet pops up to sign const receipt = await tx.wait(1); // wait for 1 confirmation console.log(receipt.status === 1 ? \"success\" : \"reverted\"); token.on(\"Transfer\", (from, to, value) = console.log(from, to, formatUnits(value, decimals))); Token amounts are integers in the smallest unit ( uint256 ) — always use parseUnits / formatUnits (BigInt), never floating point. In React apps, wagmi + viem + a connector UI (RainbowKit, ConnectKit, Reown AppKit) is the common stack."},{"kind":"lesson","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"dotnet-nethereum","title":".NET: Nethereum","body":"csharp // dotnet add package Nethereum.Web3 using Nethereum.Web3; using Nethereum.Web3.Accounts; using Nethereum.Contracts.Standards.ERC20.ContractDefinition; var web3 = new Web3(\"https://sepolia.infura.io/v3/<project-id \"); // read-only var balanceWei = await web3.Eth.GetBalance.SendRequestAsync(\"0xAddress\"); var eth = Web3.Convert.FromWei(balanceWei.Value); var erc20 = web3.Eth.ERC20.GetContractService(\"0xTokenAddress\"); var decimals = await erc20.DecimalsQueryAsync(); var tokens = await erc20.BalanceOfQueryAsync(\"0xAddress\"); // Writing requires an account (private key from Key Vault / HSM — NEVER hard-coded) var account = new Account(privateKeyFromVault, chainId: 11155111); // Sepolia var signerWeb3 = new Web3(account, \"https://sepolia.infura.io/v3/<project-id \"); var receipt = await signerWeb3.Eth.ERC20.GetContractService(\"0xTokenAddress\") .TransferRequestAndWaitForReceiptAsync(new TransferFunction { To = \"0xRecipient\", Value = Web3.Convert.ToWei(10, decimals) }); // Typed contract services can be generated from ABIs with the Nethereum code generator (VS Code extension / CLI) Typical .NET roles in Web3 projects: backend APIs that index events into SQL Server, custodial/treasury services signing with keys in Azure Key Vault Managed HSM , payment confirmation services (watch for transfers to deposit addresses and wait for N confirmations), reporting, and admin tools."},{"kind":"lesson","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"wallets-custody-and-web3-authentication","title":"Wallets, custody and Web3 authentication","body":"- Custodial wallets (exchange holds keys — e.g. centralised exchanges) vs non-custodial (user holds keys — MetaMask, hardware wallets). \"Not your keys, not your coins.\" - Hot (online) vs cold (offline, hardware/air-gapped) storage; multisig (Safe: M-of-N signatures) for treasuries; MPC wallets split keys across parties. - Sign-In with Ethereum (SIWE, ERC-4361) : backend issues a nonce → user signs a structured message → backend verifies the signature recovers the address → issues a session/JWT. No passwords; protects against replay with nonce, domain and expiry. - EIP-712 typed structured data signing — human-readable signatures for permits/orders."},{"kind":"lesson","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"security-risks-and-compliance","title":"Security, risks and compliance","body":"Common attacks and failures: - Private key / seed phrase theft (phishing, malware, fake support) — the 1 cause of individual losses. - Malicious approvals and drainer sites; address-poisoning scams. - Smart contract bugs : reentrancy (The DAO, 2016 — led to the Ethereum/Ethereum Classic split), access control mistakes, integer issues (pre-0.8), oracle manipulation, flash-loan exploits, front-running/MEV, signature replay, upgradeable proxy misconfiguration. - Bridge hacks and compromised validator/multisig keys. - Rug pulls and pump-and-dump schemes. Mitigations: audits, OpenZeppelin libraries, tests + fuzzing + formal verification, bug bounties (Immunefi), timelocks and multisig admins, monitoring (Forta, OpenZeppelin Defender), limiting approvals, hardware wallets. Compliance: KYC/AML for exchanges and on/off-ramps, the FATF \"travel rule\", tax reporting. India: virtual digital assets taxed at 30% on gains plus 1% TDS on transfers (since 2022), and exchanges must register with the Financial Intelligence Unit (FIU-IND). Taiwan: crypto service providers must register for AML with the Financial Supervisory Commission (FSC), with a dedicated VASP law being developed. Rules change — check current regulations."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1033","title":"What is blockchain? Explain it simply.","body":"A blockchain is a shared digital ledger copied across many computers. Transactions are grouped into blocks; each block stores the hash of the previous block, forming a chain, so changing an old record would break every later link. A consensus mechanism lets the computers agree on the next block without a central authority. Result: a tamper-evident, transparent, append-only record that participants don't have to trust a single party to maintain."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1034","title":"What is Web3 and how is it different from Web2?","body":"Web2 is today's platform-centric internet: users create content but companies own the data, accounts and payment rails. Web3 adds native ownership via blockchains: users hold assets and identity in wallets (private keys), applications are built on open smart contracts, and value can move peer to peer without intermediaries. Trade-offs: user responsibility for keys, scalability limits, UX friction and regulatory uncertainty."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1035","title":"What is a hash and why is it important in blockchain?","body":"A hash function maps any input to a fixed-size output (SHA-256 → 256 bits) that is deterministic, one-way, collision-resistant and changes completely with any tiny input change. Blockchains use hashes to link blocks (each header contains the previous block's hash), summarise transactions (Merkle root), derive addresses, and in Proof of Work mining (finding a hash below a target)."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1036","title":"What is the difference between a public and a private blockchain?","body":"A public (permissionless) blockchain lets anyone read, transact and participate in consensus (Bitcoin, Ethereum) — maximally decentralised and censorship-resistant, but slower and fully transparent. A private/permissioned blockchain restricts participants to known organisations (Hyperledger Fabric, Corda) — faster, private data channels, governance by a consortium, but less decentralised; often used for supply chains and inter-bank settlement."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1037","title":"What is a smart contract?","body":"A program stored on a blockchain that runs automatically and deterministically when called by a transaction, enforcing rules without intermediaries — e.g. an escrow releasing funds when conditions are met, a token contract tracking balances, a DEX swapping tokens. On Ethereum, contracts are written in Solidity, compiled to EVM bytecode, are immutable once deployed (unless proxies are used), and every execution costs gas."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1038","title":"What is a wallet? What happens if you lose your seed phrase?","body":"A wallet manages private keys and signs transactions; the blockchain holds the balances. A seed phrase (12–24 words, BIP-39) is a human-readable backup from which all the wallet's keys are derived. If you lose it and the device, the funds are permanently inaccessible — there's no reset. If someone else gets it, they can take everything. Store it offline; never share it or type it into websites."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1039","title":"Proof of Work vs Proof of Stake?","body":"In PoW, miners spend computing power to find a valid block hash; the chain with the most cumulative work is canonical — very secure and battle-tested (Bitcoin) but energy-intensive. In PoS, validators lock up (stake) coins to earn the right to propose and attest blocks; dishonest behaviour is punished by slashing — far more energy-efficient (Ethereum cut energy use by ~99.95% after The Merge in Sep 2022) and gives economic finality, but is more complex and can concentrate stake."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1040","title":"Explain gas and EIP-1559.","body":"Gas measures the computational work of an EVM operation; every transaction sets a gas limit and pays gasUsed × gas price . EIP-1559 (London, 2021) introduced a protocol-set base fee per block (adjusts with congestion and is burned) plus an optional priority tip to the validator; users specify maxFeePerGas and maxPriorityFeePerGas . Failed transactions still consume gas. Gas prevents infinite loops and spam and pays for network resources."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1041","title":"What are ERC-20 and ERC-721?","body":"Ethereum token standards (interfaces). ERC-20 defines fungible tokens with balanceOf , transfer , approve , allowance , transferFrom and Transfer/Approval events — every unit is identical (stablecoins, governance tokens). ERC-721 defines non-fungible tokens where each tokenId is unique with an ownerOf and tokenURI for metadata (NFTs). ERC-1155 supports many fungible and non-fungible token types in one contract with batch transfers."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1042","title":"What are layer 2 solutions? Optimistic vs ZK rollups?","body":"Layer 2s execute transactions off the main chain and post compressed data and proofs to layer 1, inheriting its security while increasing throughput and cutting fees. Optimistic rollups (Arbitrum, Optimism, Base) assume batches are valid and allow fraud proofs during a challenge period (~7 days for L1 withdrawals). ZK rollups (zkSync, Starknet, Scroll, Linea) post validity proofs, giving faster finality without a challenge window but with more complex proving. EIP-4844 blobs (2024) made L2 data much cheaper."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1043","title":"What is the difference between the UTXO model and the account model?","body":"UTXO (Bitcoin): a transaction consumes previous unspent outputs and creates new ones; a balance is the sum of UTXOs you can unlock. It's parallelisable and privacy-friendlier (new addresses), but less convenient for complex logic. Account model (Ethereum): global state stores balances and contract storage per address, and transactions update them directly — simpler for smart contracts, needs nonces for replay protection."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1044","title":"What is an oracle and why is it needed?","body":"Smart contracts can only see on-chain data; they can't call web APIs, because every node must produce the same result. An oracle is a service that brings external data (prices, sports results, randomness) on-chain, ideally decentralised and tamper-resistant (Chainlink aggregates many data providers). Poor oracle design — e.g. using a single DEX pool's spot price — enables price manipulation and flash-loan exploits."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1045","title":"What is the blockchain trilemma?","body":"The observation that a blockchain finds it hard to be simultaneously decentralised, secure and scalable — optimising two tends to sacrifice the third. Bitcoin and Ethereum L1 prioritise decentralisation and security; high-throughput chains often use fewer, more powerful validators. Layer 2 rollups, sharding of data (danksharding/blobs) and better clients try to improve scalability without giving up the other two."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1046","title":"How would you build a backend in .NET that confirms crypto payments?","body":"Generate a unique deposit address or payment reference per order (HD wallet derivation, or a payment contract with order IDs), subscribe to new blocks/Transfer events via an RPC provider (Nethereum with WebSockets or a provider's webhooks), match incoming transfers to orders (exact token contract, amount, decimals), wait for N confirmations or finality before marking paid (re-org safety), make processing idempotent (by tx hash + log index), persist state in SQL Server, handle under/over-payments and expirations, keep signing keys in an HSM (Azure Key Vault Managed HSM) if you send refunds, and monitor RPC failures with fallbacks. Also account for KYC/AML and tax rules."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1047","title":"What are MEV and front-running?","body":"Maximal Extractable Value is profit that block builders/searchers make by including, excluding or reordering transactions in a block — e.g. front-running a large DEX swap (buy before it, sell after: a \"sandwich attack\"), arbitrage and liquidations. Users are protected by slippage limits, private transaction relays (Flashbots Protect, MEV-blocker RPCs), batch auctions (CoW Swap) and commit-reveal schemes in contract design."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1048","title":"When should you NOT use a blockchain?","body":"When a single trusted party (or a small set that already trusts each other) controls the data; when you need high throughput, low latency and cheap writes; when data must be deleted or kept private (GDPR right to erasure conflicts with immutability); when there's no need for censorship resistance or a shared ledger among mistrusting parties. A regular database with audit logs, digital signatures or a ledger database (SQL Server ledger tables, Azure Confidential Ledger) is usually simpler, cheaper and faster."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1049","title":"A user says their tokens were stolen even though they never shared their seed phrase. What likely happened, and how could the dApp have protected them?","body":"Likely causes: they signed a malicious approval or permit (gasless signature) giving a drainer contract the right to spend their tokens, signed a phishing transaction disguised as a mint/claim, interacted with a compromised frontend, or had malware. Protections: show clear human-readable signing (EIP-712), request exact (not unlimited) approvals, warn on known-malicious addresses, use transaction simulation (wallets like Rabby/Blockaid), domain verification, and encourage revoking old approvals (revoke.cash) and using hardware wallets."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1050","title":"Your company wants to \"put the supply chain on the blockchain\". How do you evaluate it?","body":"Ask: who are the participants and do they distrust each other? Who writes data, and who verifies it? Blockchain only guarantees that recorded data hasn't been altered — not that it was true when entered (garbage in, garbage out), so you need trusted inputs (IoT sensors, signed attestations). Evaluate a permissioned ledger (Hyperledger Fabric) vs a public chain with hashes/anchoring vs a shared database with signed audit logs; consider privacy of commercial data, throughput, cost, governance, integration with ERP, and regulation. Often the best design anchors document hashes on-chain and keeps data off-chain."},{"kind":"question","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1051","title":"Transactions from your backend keep failing with \"nonce too low\" or get stuck pending. How do you fix it?","body":"Nonces must be sequential per sending account. Concurrent workers sending from the same account race for nonces, and a stuck low-fee transaction blocks later ones. Fixes: one nonce manager per account (serialise sends, track the pending nonce in DB/Redis), set EIP-1559 fees from current base fee + a reasonable tip, replace stuck transactions by resending the same nonce with a higher fee (speed-up/cancel), use multiple sender accounts for throughput, and monitor the mempool and receipts with retries."},{"kind":"cheat","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"1","title":"Core terms","body":"Block · hash · Merkle root · node · consensus · mempool · confirmation · finality · fork · wallet · private/public key · address · seed phrase · gas · nonce · smart contract · EVM · ABI · token · dApp · oracle · bridge · L1/L2."},{"kind":"cheat","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"2","title":"Consensus","body":"PoW (Bitcoin, mining) · PoS (Ethereum since Sep 2022, staking, slashing, 32 ETH validator, 12 s slots, ~12.8 min finality) · DPoS · BFT · PoA."},{"kind":"cheat","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"3","title":"Bitcoin vs Ethereum","body":"BTC: 2009, PoW, 10-min blocks, 21M cap, UTXO, halving every ~4 years. ETH: 2015, PoS, 12-s blocks, account model, smart contracts, 1 ETH = 10^18 wei, EIP-1559 fee burn."},{"kind":"cheat","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"4","title":"Token standards","body":"ERC-20 fungible · ERC-721 NFT · ERC-1155 multi-token · ERC-4626 vaults · ERC-2612 permit · ERC-4337 account abstraction · EIP-712 typed signing · ERC-4361 Sign-In with Ethereum."},{"kind":"cheat","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"5","title":"Scaling","body":"Optimistic rollups (Arbitrum, Optimism, Base — 7-day challenge) · ZK rollups (zkSync, Starknet, Scroll, Linea) · sidechains (Polygon PoS) · Lightning (BTC) · EIP-4844 blobs (2024)."},{"kind":"cheat","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"6","title":"Upgrades to remember","body":"The DAO hack 2016 · EIP-1559 2021 · The Merge 2022 · Shanghai 2023 · Dencun 2024 · Pectra May 2025 · Fusaka Dec 2025."},{"kind":"cheat","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"7","title":"Dev stack","body":"Solidity · Hardhat / Foundry / Remix · OpenZeppelin · ethers.js v6 / viem / wagmi · Nethereum (.NET) · MetaMask · Infura/Alchemy · Etherscan · Sepolia testnet · IPFS · The Graph · Chainlink."},{"kind":"cheat","course_slug":"blockchain-web3","course_title":"Blockchain & Web3 Fundamentals","ref":"8","title":"Security","body":"Seed phrase = ownership · limit approvals · audits · reentrancy · oracle manipulation · flash loans · bridge risk · MEV · multisig + timelock admins."},{"kind":"course","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"","title":"Solidity & Smart Contract Development","body":"Solidity syntax, data types and data locations, functions, visibility and modifiers, events, errors, inheritance and interfaces, ERC-20/721 with OpenZeppelin, payable and Ether transfers, upgradeable contracts, gas optimisation, testing with Hardhat/Foundry, deployment and security vulnerabilities. Solidity is a statically typed, curly-brace, contract-oriented language for writing smart contracts on the EVM (Ethereum and EVM-compatible chains: Arbitrum, Optimism, Base, Polygon, BNB Chain, Avalanche...). Syntax is influenced by C++, Python and JavaScript. Created by Gavin Wood and others; developed by the Ethereum Foundation's Solidity team (first released 2015). A contract is like a class: state variables (stored permanently on-chain), functions , modifiers , events , errors , and can inherit from other contracts. Code is compiled with solc into EVM bytecode plus an ABI . Smart contract development is high-stakes: deployed code is public, usually immutable, and often holds money — bugs are exploited quickly. Interviews focus heavily on security , gas costs and testing . Version Year Notable changes --- --- --- 0.1–0.3 2015–2016 Early releases 0.4.x 2016–2018 Widely used in the ICO era; constant functions; many legacy contracts 0.5.0 2018 Explicit data locations, address payable , explicit visibility required 0.6.0 2019 virtual / override required, receive() / fallback() split, try/catch for external calls 0.7.0 2020 now removed (use block.timestamp ), constructor visibility removed 0.8.0 Dec 2020 Checked arithmetic (overflow/underflow reverts by default; unchecked {} to opt out), ABI coder v2 default 0.8.4 2021 Custom errors ( error InsufficientBalance(...) — cheaper than revert strings) 0.8.18–0.8.30 2023–2025 User-defined operators, named mapping parameters, transient storage ( transient keyword, 0.8.28, after Dencun's EIP-1153), new EVM version defaults (Cancun, Prague) 0.9 (planned) — Further breaking cleanups Always pin the compiler: pragma solidity 0.8.28; (or ^0.8.24 ) and use a recent 0.8.x release. Library versions: OpenZeppelin Contracts 4.x (2021–2023) → 5.x (2023+, custom errors, Ownable(initialOwner) , namespaced storage). Development lifecycle: 1. Specify — requirements, roles, invariants (\"total supply equals sum of balances\"), threat model. 2. Write — Solidity using audited building blocks (OpenZeppelin). 3. Compile — forge build / npx hardhat compile → bytecode + ABI. 4. Test — unit tests, fuzz tests, invariant tests, fork tests against mainnet state; coverage. 5. Static analysis — Slither, compiler warnings, linters (solhint). 6. Audit — internal review + external audit; bug bounty. 7. Deploy — testnet (Sepolia) → mainnet with a script; record addresses; deploy through a multisig where possible. 8. Verify — publish source on Etherscan/Blockscout. 9. Operate — monitoring (events, Defender/Forta), admin actions via multisig + timelock, incident response (pause). 10. Upgrade or migrate — through a proxy (if designed) or by deploying a new contract and migrating state. Contract execution lifecycle (per call): transaction/call reaches the contract → EVM loads bytecode → function selector (first 4 bytes of calldata = keccak256(\"transfer(address,uint256)\")[0:4] ) dispatches to the function → modifiers run → body executes reading/writing storage , using memory / stack , possibly calling other contracts → emits events → returns data, or reverts (all state changes undone, remaining gas returned except for what was used). Contract lifecycle on-chain: creation transaction runs the constructor (init code) → runtime bytecode stored at the new address → used via calls → (legacy selfdestruct is effectively disabled since Dencun/EIP-6780 except within the same transaction as creation). Tool Use --- --- Remix IDE (remix.ethereum.org) Browser IDE — learning, quick tests Foundry (forge, cast, anvil, chisel) Rust-based toolkit; tests in Solidity; fast fuzzing Hardhat (v3) JS/TS toolkit; plugins; Hardhat Network; Ignition deployments OpenZeppelin Contracts / Wizard / Upgrades plugin / Defender Audited contracts, generator, proxy tooling, ops solc, solc-select Compiler versions Slither , Mythril, Aderyn Static analysis Echidna, Medusa, Foundry invariant tests Fuzzing Certora, Halmos, SMTChecker Formal verification / symbolic execution Tenderly Debugging, simulation, monitoring Etherscan / Blockscout Verification, reading contracts VS Code + Solidity extension (Nomic Foundation/Juan Blanco) Editing"},{"kind":"lesson","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"contract-structure-state-variables-and-types","title":"Contract structure, state variables and types","body":"solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; contract SimpleBank { // ---- state variables (stored on-chain) ---- address public immutable owner; // set once in constructor, stored in bytecode (cheap to read) uint256 public constant MIN DEPOSIT = 0.01 ether; // compile-time constant uint256 public totalDeposits; mapping(address = uint256) public balances; // public → auto-generated getter bool private paused; // ---- events & errors ---- event Deposited(address indexed account, uint256 amount); event Withdrawn(address indexed account, uint256 amount); error InsufficientBalance(uint256 requested, uint256 available); error NotOwner(); constructor() { owner = msg.sender; // deployer } modifier onlyOwner() { if (msg.sender != owner) revert NotOwner(); ; // continue with the function body } function deposit() external payable { require(msg.value = MIN DEPOSIT, \"Deposit too small\"); balances[msg.sender] += msg.value; totalDeposits += msg.value; emit Deposited(msg.sender, msg.value); } function withdraw(uint256 amount) external { uint256 bal = balances[msg.sender]; if (amount bal) revert InsufficientBalance(amount, bal); balances[msg.sender] = bal - amount; // update state BEFORE the external call (checks-effects-interactions) totalDeposits -= amount; (bool ok, ) = payable(msg.sender).call{value: amount}(\"\"); require(ok, \"Transfer failed\"); emit Withdrawn(msg.sender, amount); } function setPaused(bool p) external onlyOwner { paused = p; } } Value types: bool , uint8…uint256 ( uint = uint256 ), int8…int256 , address (20 bytes) / address payable , bytes1…bytes32 , enum . Reference types: arrays ( uint[] , uint[10] ), bytes , string , struct , mapping(K = V) (no iteration, no length; every key exists with a default zero value). Units: 1 ether = 1e18 wei , gwei ; time units seconds , minutes , hours , days , weeks . No floating point — use integers with fixed decimals. Global variables: msg.sender (immediate caller), msg.value (wei sent), msg.data , block.timestamp , block.number , block.chainid , tx.origin (original EOA — never use for auth), gasleft() , address(this).balance ."},{"kind":"lesson","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"functions-visibility-state-mutability-and-modifiers","title":"Functions: visibility, state mutability and modifiers","body":"Visibility Callable from --- --- public Anywhere (internally and externally); public state vars get getters external Only from outside (other contracts/EOAs), or this.f() internal This contract and derived contracts (default for state variables) private Only this contract (still visible on-chain — not secret!) Mutability Meaning --- --- (none) Can read and modify state view Reads state, doesn't modify pure Neither reads nor modifies state payable Can receive Ether solidity function quote(uint256 qty) public view returns (uint256 price) { price = qty unitPrice; } function add(uint256 a, uint256 b) external pure returns (uint256) { return a + b; } receive() external payable { } // plain Ether transfers (empty calldata) fallback() external payable { } // unknown function selector (or Ether with data) Modifiers wrap function logic (access control, state checks, reentrancy guard). Function overloading is allowed. Calls to view / pure functions from off-chain ( eth call ) are free; when called inside a transaction they still cost gas."},{"kind":"lesson","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"data-locations-storage-memory-calldata-stack-and-transient","title":"Data locations: storage, memory, calldata, stack and transient","body":"Location Lifetime Cost Notes --- --- --- --- storage Permanent (contract state) Most expensive (SSTORE ~20,000 gas for a new non-zero slot, 2,900–5,000 for updates; reads ~2,100 cold / 100 warm) State variables; storage pointers memory During the function call Cheap, grows quadratically Temporary arrays/structs, function params of public functions calldata Read-only input of external calls Cheapest for inputs Use for external function array/string params stack Local value-type variables Cheapest 1024 slots max depth; \"stack too deep\" with too many locals transient (EIP-1153, Solidity 0.8.28+) Until end of the transaction Cheap Reentrancy locks, temporary approvals solidity struct Order { address buyer; uint96 amount; bool paid; } Order[] public orders; function markPaid(uint256 id) external { Order storage o = orders[id]; // reference to storage → modifies state o.paid = true; } function preview(uint256 id) external view returns (Order memory) { Order memory o = orders[id]; // copy into memory → changes would NOT persist return o; } function sum(uint256[] calldata xs) external pure returns (uint256 t) { for (uint256 i; i < xs.length; ++i) t += xs[i]; }"},{"kind":"lesson","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"errors-require-revert-assert-and-events","title":"Errors, require, revert, assert and events","body":"solidity error Unauthorized(address caller); error InsufficientFunds(uint256 needed, uint256 available); function pay(uint256 amount) external { require(amount 0, \"Zero amount\"); // input validation (string costs more gas) if (balance[msg.sender] < amount) revert InsufficientFunds(amount, balance[msg.sender]); // custom error (0.8.4+), cheapest assert(totalSupply = balance[msg.sender]); // invariants that should NEVER fail (Panic error) } // try/catch for external calls try oracle.latestPrice() returns (uint256 p) { price = p; } catch Error(string memory reason) { emit OracleFailed(reason); } catch (bytes memory) { emit OracleFailed(\"unknown\"); } On revert, all state changes in the call are undone ; gas used so far is consumed. Events ( emit Transfer(from, to, amount) ) write to transaction logs — cheap, not readable by contracts, but indexed by off-chain apps; up to 3 indexed parameters become searchable topics."},{"kind":"lesson","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"inheritance-interfaces-abstract-contracts-and-libraries","title":"Inheritance, interfaces, abstract contracts and libraries","body":"solidity interface IPriceFeed { // no implementation, all functions external function latestPrice() external view returns (uint256); } abstract contract Pausable { // can't be deployed; may have unimplemented functions bool public paused; modifier whenNotPaused() { require(!paused, \"Paused\"); ; } function pause() internal virtual { paused = true; } } contract Shop is Pausable, Ownable { // multiple inheritance, C3 linearization (right-most is most derived) constructor() Ownable(msg.sender) {} function pause() external onlyOwner { pause(); } function pause() internal override { super. pause(); emit ShopPaused(); } // virtual/override, super event ShopPaused(); } library MathLib { // reusable code; internal functions are inlined function percent(uint256 x, uint256 bps) internal pure returns (uint256) { return x bps / 10 000; } } using MathLib for uint256; // attach: amount.percent(250) Functions must be marked virtual to be overridable and override when overriding. Interfaces enable calling other contracts: IERC20(token).transfer(to, amt) ."},{"kind":"lesson","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"erc-20-and-erc-721-with-openzeppelin","title":"ERC-20 and ERC-721 with OpenZeppelin","body":"solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\"; import {ERC20Permit} from \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol\"; import {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\"; contract DivakarToken is ERC20, ERC20Permit, Ownable { constructor(address initialOwner) ERC20(\"Divakar Token\", \"DVK\") ERC20Permit(\"Divakar Token\") Ownable(initialOwner) { mint(initialOwner, 1 000 000 10 decimals()); // 18 decimals by default } function mint(address to, uint256 amount) external onlyOwner { mint(to, amount); } } solidity import {ERC721} from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\"; import {AccessControl} from \"@openzeppelin/contracts/access/AccessControl.sol\"; contract CourseCertificate is ERC721, AccessControl { bytes32 public constant ISSUER ROLE = keccak256(\"ISSUER ROLE\"); uint256 private nextId = 1; string private base; constructor(string memory baseUri) ERC721(\"Course Certificate\", \"CERT\") { grantRole(DEFAULT ADMIN ROLE, msg.sender); grantRole(ISSUER ROLE, msg.sender); base = baseUri; // e.g. ipfs://<CID / } function issue(address student) external onlyRole(ISSUER ROLE) returns (uint256 id) { id = nextId++; safeMint(student, id); } function baseURI() internal view override returns (string memory) { return base; } function supportsInterface(bytes4 id) public view override(ERC721, AccessControl) returns (bool) { return super.supportsInterface(id); } } Use OpenZeppelin instead of writing token logic yourself — audited, standard-compliant. Ownable (single owner) vs AccessControl (roles) vs AccessManager (centralised permissions, OZ 5)."},{"kind":"lesson","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"sending-and-receiving-ether-safely","title":"Sending and receiving Ether safely","body":"solidity // Recommended: call with checks-effects-interactions + reentrancy guard (bool ok, ) = payable(to).call{value: amount}(\"\"); require(ok, \"ETH transfer failed\"); // transfer/send forward only 2,300 gas — can break with smart-contract wallets; generally avoid payable(to).transfer(amount); // reverts on failure bool sent = payable(to).send(amount); // returns false on failure Pull over push: instead of sending Ether to many users in a loop (one failing recipient blocks everyone; gas limits), record balances and let each user withdraw() ."},{"kind":"lesson","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"security-vulnerabilities-and-defences","title":"Security vulnerabilities and defences","body":"Vulnerability What happens Defence --- --- --- Reentrancy External call re-enters your function before state is updated (The DAO, 2016) Checks-Effects-Interactions , ReentrancyGuard ( nonReentrant ), pull payments Access control bugs Missing onlyOwner /role checks, unprotected initialize Explicit modifiers, tests for every privileged function, OZ AccessControl tx.origin auth Phishing contract calls yours on behalf of the user Use msg.sender Integer overflow Pre-0.8 wrap-around (BEC token 2018) Solidity ≥ 0.8 (checked), careful unchecked Oracle manipulation Spot price from one pool manipulated (often with flash loans) Chainlink/TWAP, multiple sources, sanity bounds Front-running / MEV Attackers see pending txs and reorder Commit-reveal, slippage limits, batch auctions Denial of service Unbounded loops, failing recipient blocks payouts Pagination, pull payments, avoid loops over user arrays Signature replay Same signature reused (other chain/contract/after use) Nonces, chainid , EIP-712 domain separator, deadlines Unchecked return values Ignoring call result or non-standard ERC-20s (USDT returns nothing) Check ok ; use SafeERC20 delegatecall / proxy storage collisions Logic contract overwrites proxy storage OZ upgradeable patterns, storage gaps / ERC-7201 namespaced storage, disableInitializers() Randomness block.timestamp / prevrandao predictable/influenceable Chainlink VRF Precision loss Divide before multiply Multiply first, use fixed-point libraries Private data private vars readable from storage Never store secrets on-chain; commit hashes solidity import {ReentrancyGuard} from \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\"; import {SafeERC20, IERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\"; contract Vault is ReentrancyGuard { using SafeERC20 for IERC20; IERC20 public immutable token; mapping(address = uint256) public shares; constructor(IERC20 t) { token = t; } function withdraw(uint256 amount) external nonReentrant { require(shares[msg.sender] = amount, \"Too much\"); // checks shares[msg.sender] -= amount; // effects token.safeTransfer(msg.sender, amount); // interactions } }"},{"kind":"lesson","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"upgradeable-contracts-proxy-patterns","title":"Upgradeable contracts (proxy patterns)","body":"Contracts are immutable, so upgradeability uses a proxy that holds storage and delegatecalls into a replaceable implementation (logic) contract. Pattern Upgrade logic lives in Notes --- --- --- Transparent proxy Proxy (admin via ProxyAdmin) Admin can't call logic functions; slightly more gas UUPS (ERC-1822) Implementation ( upgradeTo + authorizeUpgrade ) Cheaper; risk of bricking if an upgrade removes upgrade logic Beacon proxy Beacon contract shared by many proxies Upgrade many instances at once Diamond (ERC-2535) Multiple facets Very large/modular systems; complex Rules: use initializers instead of constructors ( initialize() with initializer modifier; call disableInitializers() in the implementation's constructor), never change the order/types of existing storage variables (append only, or use ERC-7201 namespaced storage), protect upgrades with a multisig + timelock , and validate with the OpenZeppelin Upgrades plugin. Upgradeability trades trustlessness for fixability — be transparent with users."},{"kind":"lesson","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"gas-optimisation","title":"Gas optimisation","body":"1. Minimise storage writes ; cache storage reads in local variables ( uint256 bal = balances[a]; ). 2. Pack variables into 32-byte slots ( uint128 a; uint128 b; share one slot; order struct fields by size). 3. constant and immutable for fixed values (no storage reads). 4. calldata instead of memory for external read-only params. 5. Custom errors instead of revert strings. 6. Use mapping over arrays for lookups; avoid unbounded loops. 7. unchecked { ++i; } in loops where overflow is impossible; ++i vs i++ (minor). 8. Emit events instead of storing data that only off-chain apps need. 9. Short-circuit conditions (cheap checks first); external over public for functions not called internally (minor in modern compilers). 10. Batch operations; use transient storage for in-transaction flags. 11. Enable the optimizer ( runs tuned: low for deploy cost, high for call cost); compare with forge snapshot / gas reports. Readability and security beat micro-optimisation — measure first."},{"kind":"lesson","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"testing-with-foundry-and-hardhat-deployment","title":"Testing with Foundry and Hardhat, deployment","body":"solidity // test/SimpleBank.t.sol (Foundry) import {Test} from \"forge-std/Test.sol\"; import {SimpleBank} from \"../src/SimpleBank.sol\"; contract SimpleBankTest is Test { SimpleBank bank; address alice = makeAddr(\"alice\"); function setUp() public { bank = new SimpleBank(); vm.deal(alice, 10 ether); } function test DepositAndWithdraw() public { vm.startPrank(alice); bank.deposit{value: 1 ether}(); bank.withdraw(0.4 ether); vm.stopPrank(); assertEq(bank.balances(alice), 0.6 ether); } function test RevertWhen WithdrawTooMuch() public { vm.prank(alice); vm.expectRevert(abi.encodeWithSelector(SimpleBank.InsufficientBalance.selector, 1 ether, 0)); bank.withdraw(1 ether); } function testFuzz Deposit(uint96 amount) public { // fuzzing: random inputs vm.assume(amount = 0.01 ether && amount <= 10 ether); vm.prank(alice); bank.deposit{value: amount}(); assertEq(bank.totalDeposits(), amount); } } bash forge init bank && forge build && forge test -vvv forge test --gas-report && forge coverage anvil local node forge script script/Deploy.s.sol --rpc-url $SEPOLIA RPC --account deployer --broadcast --verify cast call <address \"balances(address)(uint256)\" <alice --rpc-url $SEPOLIA RPC Hardhat alternative npx hardhat test npx hardhat ignition deploy ./ignition/modules/Bank.ts --network sepolia --verify Test types: unit, fuzz , invariant (properties that must always hold across random call sequences), fork tests (against real mainnet state), integration with frontends. Keep deployer keys in an encrypted keystore or hardware wallet — never in .env committed to Git."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1052","title":"What is Solidity and what is the EVM?","body":"Solidity is a statically typed, contract-oriented programming language for writing smart contracts that run on the Ethereum Virtual Machine. The EVM is the sandboxed, deterministic, stack-based virtual machine that every Ethereum node runs to execute contract bytecode identically, metering each operation in gas. Solidity compiles to EVM bytecode plus an ABI used by clients to call contract functions."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1053","title":"Explain function visibility in Solidity.","body":"public — callable internally and externally (state variables get automatic getters). external — callable only from outside the contract (or via this. ). internal — this contract and contracts that inherit from it (default for state variables). private — only this contract. Note: private doesn't hide data — all on-chain storage is publicly readable."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1054","title":"What is the difference between view and pure functions?","body":"view functions can read state but not modify it; pure functions neither read nor modify state (only use their inputs and local variables). Both are free when called off-chain via eth call , but cost gas when called from within a transaction. The compiler enforces these restrictions."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1055","title":"What are storage, memory and calldata?","body":"They're data locations. storage is persistent contract state on the blockchain (expensive to write). memory is temporary, modifiable data that exists for the duration of a function call. calldata is a read-only, non-persistent area holding the arguments of external calls — the cheapest choice for external function array/string/struct parameters. Assigning storage to a local storage variable creates a reference; to memory creates a copy."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1056","title":"What is msg.sender vs tx.origin?","body":"msg.sender is the immediate caller of the current function — an EOA or another contract. tx.origin is always the EOA that originally signed the transaction. Using tx.origin for authorisation is a vulnerability: a malicious contract the user interacts with can call your contract and pass a tx.origin == owner check. Always use msg.sender ."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1057","title":"What are events and why use them?","body":"Events ( event Transfer(address indexed from, address indexed to, uint256 value) ) emitted with emit are stored in transaction logs, not contract storage — much cheaper. Off-chain apps (frontends, indexers, The Graph, .NET backends) subscribe to and filter them (up to 3 indexed topics). Contracts can't read logs. Use them for activity history, notifications and indexing."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1058","title":"What is a reentrancy attack and how do you prevent it?","body":"When a contract makes an external call (e.g. sending Ether) before updating its own state, the recipient's code (fallback/receive or a token hook) can call back into the contract and repeat the action — for example withdrawing again before the balance is reduced (The DAO hack, 2016, ~3.6M ETH). Prevent it with the Checks-Effects-Interactions pattern (validate, update state, then call out), OpenZeppelin ReentrancyGuard ( nonReentrant ), pull-payment designs, and care with token callbacks (ERC-777/721/1155 hooks)."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1059","title":"require vs revert vs assert vs custom errors?","body":"require(cond, \"msg\") validates inputs/conditions and reverts with an Error(string). revert CustomError(args) (or revert(\"msg\") ) aborts explicitly, often after an if . Custom errors (0.8.4+) are cheaper (4-byte selector + args instead of strings) and carry structured data. assert(cond) checks internal invariants that should never be false; failure raises a Panic error and indicates a bug. All revert all state changes in the call."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1060","title":"How do you send Ether from a contract? transfer vs send vs call?","body":"transfer forwards 2,300 gas and reverts on failure; send forwards 2,300 gas and returns false on failure; call{value: x}(\"\") forwards all available gas (configurable) and returns (success, data). Since gas costs changed (EIP-1884) and smart-contract wallets need more gas, call with a checked return value is recommended — combined with reentrancy protection and the pull-payment pattern."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1061","title":"What changed in Solidity 0.8?","body":"Arithmetic is checked by default: overflow/underflow reverts (Panic 0x11) instead of silently wrapping, making SafeMath unnecessary; unchecked { } blocks opt out for gas savings where safe. ABI coder v2 became the default. Later 0.8.x versions added custom errors (0.8.4), user-defined value types, bytes.concat / string.concat , named mapping parameters, user-defined operators and transient storage (0.8.28)."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1062","title":"What is the difference between an interface, an abstract contract and a library?","body":"An interface declares only external function signatures (no state, no implementation, no constructor) — used to interact with other contracts and define standards (IERC20). An abstract contract can contain state and implemented functions but has at least one unimplemented function or is marked abstract — it can't be deployed, only inherited. A library holds reusable functions without state (internal functions are inlined; public ones are deployed and called via delegatecall), attached to types with using X for Y ."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1063","title":"What are modifiers? Give an example.","body":"Reusable code that runs before and/or after a function body, where marks where the body executes. Typical uses: access control ( onlyOwner , onlyRole ), state checks ( whenNotPaused ), reentrancy guards, input validation. Example: modifier onlyOwner() { if (msg.sender != owner) revert NotOwner(); ; } ."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1064","title":"How do upgradeable contracts work? What are the risks?","body":"A proxy contract holds the state and forwards calls using delegatecall to an implementation contract, which runs in the proxy's storage context; upgrading means pointing the proxy to a new implementation (Transparent, UUPS, Beacon patterns). Risks: storage layout collisions if variables are reordered, uninitialised implementations being taken over (use disableInitializers ), forgetting to protect the upgrade function, a malicious or compromised admin (mitigate with multisig + timelock), and loss of the \"code is law\" guarantee for users."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1065","title":"How do you reduce gas costs in a contract?","body":"Reduce storage writes and reads (cache in memory/stack), pack variables into 32-byte slots, use constant / immutable , calldata for external inputs, custom errors, mappings instead of array searches, avoid unbounded loops, use unchecked where overflow can't happen, emit events instead of storing off-chain-only data, batch operations, transient storage for per-transaction flags, and tune the optimizer. Measure with gas reports/snapshots and never trade away safety."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1066","title":"Why is on-chain randomness hard, and how do you get it?","body":"Everything on-chain is deterministic and visible: block.timestamp , blockhash and block.prevrandao can be predicted or influenced by validators/attackers, and users can revert transactions with unfavourable outcomes. Use a verifiable random function oracle (Chainlink VRF) that provides randomness with a cryptographic proof, or commit-reveal schemes among multiple parties."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1067","title":"What is the difference between call, delegatecall and staticcall?","body":"call executes code in the target contract's context (its storage; msg.sender becomes the caller contract) and can send Ether. delegatecall executes the target's code in the caller's context (caller's storage, msg.sender and msg.value preserved) — used by proxies and libraries; dangerous with untrusted targets. staticcall is like call but reverts on any state modification — used for view calls."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1068","title":"You must build a token sale contract that accepts USDC and gives buyers your token. What would you check for security?","body":"Use OpenZeppelin ERC-20 and SafeERC20 ( safeTransferFrom for USDC); handle decimals correctly (USDC has 6, your token 18); checks-effects-interactions plus nonReentrant ; caps per wallet and a total cap; start/end times; pausable by a multisig; no reliance on spot prices; no unbounded loops (let users claim — pull, not push); withdrawal of raised funds only by the treasury multisig; events for every purchase; comprehensive unit/fuzz tests including edge cases (zero amounts, rounding); an external audit; and legal/compliance review (securities rules, KYC)."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1069","title":"A deployed contract has a bug that can drain funds, and it's not upgradeable. What do you do?","body":"Act immediately: if it has a pause or emergency-withdraw function controlled by a multisig, use it; otherwise consider a white-hat rescue (exploit it yourself first to move funds to safety, coordinated with security firms such as SEAL 911), notify users and integrators to stop interacting, revoke approvals guidance, coordinate with exchanges/bridges to freeze stolen funds where possible, then deploy a fixed contract, migrate state from a snapshot, compensate users if possible, and publish a post-mortem. Prevention: audits, bug bounties, pausability, rate limits and monitoring."},{"kind":"question","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1070","title":"Your NFT mint is expensive and fails for some buyers because of gas. How do you improve it?","body":"Optimise the mint: avoid storing per-token data that can be computed or kept off-chain (use a base URI + token ID), use ERC721A or similar batch-mint-optimised implementations for multi-mints, pack storage, use custom errors, and remove loops over all holders; use a Merkle-proof allowlist instead of storing whitelists on-chain; deploy on a layer 2 (Base, Arbitrum) for much lower fees; and test gas usage with Foundry gas reports before launch."},{"kind":"cheat","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"1","title":"Skeleton","body":"solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; contract C is Parent { uint256 public x; address public immutable owner; uint256 constant MAX = 100; mapping(address = uint256) public bal; event Did(address indexed who, uint256 v); error Nope(uint256 code); modifier onlyOwner() { if (msg.sender != owner) revert Nope(1); ; } constructor() { owner = msg.sender; } function f(uint256 a) external payable onlyOwner returns (uint256) { emit Did(msg.sender, a); return a; } receive() external payable {} }"},{"kind":"cheat","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"2","title":"Visibility & mutability","body":"public · external · internal · private (still readable on-chain) · view · pure · payable."},{"kind":"cheat","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"3","title":"Data locations","body":"storage (persistent, costly) · memory (temporary) · calldata (read-only inputs, cheapest) · stack · transient (per-tx, 0.8.28)."},{"kind":"cheat","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"4","title":"Errors","body":"require · revert CustomError() · assert (Panic) · try/catch for external calls · all state rolled back."},{"kind":"cheat","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"5","title":"Security checklist","body":"CEI + nonReentrant · msg.sender not tx.origin · access control on every admin function · SafeERC20 · no spot-price oracles · no unbounded loops · pull payments · nonces + chainid in signatures · Chainlink VRF for randomness · initializers + disableInitializers for proxies · multisig + timelock · audits + fuzzing."},{"kind":"cheat","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"6","title":"Gas tips","body":"Fewer SSTOREs · cache reads · pack slots · constant/immutable · calldata · custom errors · unchecked loops · events over storage · optimizer."},{"kind":"cheat","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"7","title":"Tooling","body":"Remix · Foundry (forge/cast/anvil) · Hardhat · OpenZeppelin · Slither · Echidna · Tenderly · Etherscan verify · Sepolia."},{"kind":"cheat","course_slug":"solidity","course_title":"Solidity & Smart Contract Development","ref":"8","title":"Versions","body":"0.5 explicit locations · 0.6 virtual/override, receive/fallback · 0.8 checked math · 0.8.4 custom errors · 0.8.28 transient storage · OpenZeppelin 5.x."},{"kind":"course","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"","title":".NET Full Stack Developer Interview — End to End","body":"How .NET full stack interviews run, the end-to-end request flow (Angular/React → ASP.NET Core → EF Core → SQL Server), authentication, a feature built across every layer, performance, deployment, architecture and system design — with the questions interviewers ask most. A .NET full stack developer builds a feature through every layer: the UI (Angular or React with TypeScript), the API (ASP.NET Core Web API in C ), data access (EF Core or Dapper), the database (SQL Server), and usually the delivery path (Git, CI/CD, Docker, Azure). Interviewers for this role do not want five separate specialists. They test whether you can connect the layers : Layer Typical stack What they check --- --- --- UI Angular / React, TypeScript, HTML, CSS Components, state, forms, calling APIs, routing, auth guards API ASP.NET Core Web API, C REST design, DI, middleware, validation, error handling, auth Data access EF Core, Dapper, ADO.NET LINQ, tracking, migrations, N+1, transactions Database SQL Server Joins, indexes, stored procedures, execution plans, deadlocks Delivery Git, Azure DevOps / GitHub Actions, Docker, Azure Branching, pipelines, config, secrets, monitoring Design SOLID, patterns, clean architecture Layering, testability, trade-offs This course is the glue : each lesson follows one concern across the whole stack. The deep dives live in the individual courses (C , Web API, EF Core, SQL Server, Angular, React …). Use the .NET Full Stack Developer question bank (Interview Questions menu) to drill every question from all of those courses in one place. The stack most job descriptions ask for in 2026: Part Current version Notes --- --- --- .NET .NET 10 (LTS, Nov 2025) .NET 8 (LTS) still very common in production; .NET 9 is STS C C 14 (with .NET 10) Extension members, field keyword, null-conditional assignment ASP.NET Core 10 Minimal APIs and controllers; built-in OpenAPI document generation EF Core 10 LeftJoin/RightJoin LINQ operators, named query filters, complex types SQL Server 2022 / 2025 2025 adds vector data type, JSON type and regex functions Angular 20 / 21 Standalone components, signals, new control flow ( @if , @for ), zoneless React 19.x Actions, use , Server Components (via frameworks such as Next.js) TypeScript 5.x TypeScript 7 (native Go compiler) in preview Node.js (tooling) 22 / 24 LTS Needed for Angular CLI, Vite, npm Interview tip: say which version you used in your last project and one feature from it you actually used (\"we moved to .NET 8 and used IExceptionHandler for global errors\"). How a full stack feature moves from ticket to production: 1. Requirement — user story with acceptance criteria (Jira / Azure Boards). 2. Design — API contract (endpoint, request/response DTOs, status codes), DB change (table, index, migration), UI screens. 3. Database — migration script or EF Core migration; seed data; indexes for the new queries. 4. API — DTOs, validation, service/business logic, repository or DbContext query, controller/endpoint, unit tests. 5. UI — service that calls the API, component, form with validation, routing, error and loading states. 6. Integration — CORS, auth token flow, end-to-end test (Playwright/Cypress). 7. Review & CI — pull request, code review, pipeline runs build + tests + static analysis. 8. Deploy — CD pipeline to dev → QA → UAT → production; config per environment; feature flags if needed. 9. Operate — logs (Serilog / Application Insights), metrics, alerts; fix and iterate. - IDE: Visual Studio 2022/2026, VS Code, JetBrains Rider. - API testing: Swagger UI / Scalar, Postman, .http files in Visual Studio, curl. - Database: SQL Server Management Studio (SSMS), Azure Data Studio (retired 2026 — use VS Code MSSQL extension), SQL Profiler / Extended Events. - Frontend: Angular CLI, Vite, Chrome DevTools, Redux DevTools, Angular DevTools, React DevTools. - Testing: xUnit / NUnit, Moq / NSubstitute, FluentAssertions, Jasmine/Karma or Jest/Vitest, Playwright. - Delivery: Git, GitHub / Azure Repos, Azure DevOps Pipelines / GitHub Actions, Docker Desktop, Azure Portal, Azure CLI. - Monitoring: Application Insights, Serilog + Seq, Grafana."},{"kind":"lesson","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"the-interview-rounds-and-what-each-one-tests","title":"The interview rounds and what each one tests","body":"Most companies (product companies, service companies and startups) use some mix of these rounds: Round Duration What happens How to prepare --- --- --- --- Screening / online test 30–90 min MCQs on C , SQL, JS + 1–2 coding problems Coding Round course, C basics, SQL joins Technical round 1 45–60 min C , OOP, .NET Core, Web API, EF Core, SQL \"★ Must know\" questions in the .NET role bank Technical round 2 45–60 min Angular/React, JavaScript, end-to-end flow, a small live task This course + frontend courses Design / architecture 45–60 min Design a feature or a system; layering, scaling, trade-offs Microservices & System Design course Managerial 30–45 min Project, ownership, conflict, estimates, Agile Team Lead & Agile course HR 20–30 min Notice period, salary, relocation, gaps HR and Career Gaps courses What separates a strong full stack candidate: - Explains one real feature end to end : UI → API → DB → back, including errors and security. - Knows why (trade-offs), not only what (definitions). - Writes working code live: a LINQ query, a SQL query, a component, an endpoint. - Talks about production: logging, performance, deployment, incidents. Interview tip: When asked any definition question, finish with \"In my last project we used it for …\". It turns a textbook answer into evidence."},{"kind":"lesson","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"explain-your-project-architecture-the-end-to-end-answer","title":"\"Explain your project architecture\" — the end-to-end answer","body":"This is asked in almost every round. Prepare a 2-minute answer using this skeleton: 1. Business — \"An order-management portal for distributors; ~300 internal users, ~20k orders/day.\" 2. Frontend — \"Angular 17 SPA with standalone components, reactive forms, an HTTP interceptor that adds the JWT and handles 401.\" 3. API — \"ASP.NET Core 8 Web API, layered: Controllers → Services → Repositories (EF Core). FluentValidation for input, global exception middleware returning ProblemDetails, Serilog to Application Insights.\" 4. Database — \"SQL Server 2019; ~60 tables; stored procedures for heavy reports; indexes tuned using execution plans.\" 5. Security — \"Azure AD (Entra ID) login; API validates JWT bearer tokens; role-based policies.\" 6. Delivery — \"Git with feature branches and PRs; Azure DevOps pipelines build, test and deploy to Azure App Service; separate dev/QA/prod.\" 7. Your part — \"I owned the orders module end to end: API, EF queries, the Angular screens, and I cut the order search from 6 s to 300 ms by adding a covering index and paging.\" Draw it as you talk: text [Angular SPA] --HTTPS + JWT-- [ASP.NET Core API] --EF Core-- [SQL Server] Entra ID login Serilog - App Insights Nightly SSIS/ETL Interview tip: Always end with your contribution and one measurable result . Interviewers remember numbers."},{"kind":"lesson","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"from-a-button-click-to-sql-server-and-back","title":"From a button click to SQL Server and back","body":"Follow one request — \"Load page 1 of orders for customer 42\": 1. UI (Angular) — the component asks a service; the service calls the API: typescript // order.service.ts @Injectable({ providedIn: 'root' }) export class OrderService { private http = inject(HttpClient); getOrders(customerId: number, page = 1, size = 20) { return this.http.get<PagedResult<OrderDto ( /api/customers/${customerId}/orders , { params: { page, size } }); } } 2. Browser → server — HTTPS request; an interceptor adds Authorization: Bearer <token ; for another origin the browser first sends a CORS preflight ( OPTIONS ). 3. ASP.NET Core pipeline — Kestrel receives it → middleware in order: exception handler → HTTPS redirection → routing → CORS → authentication → authorization → endpoint. 4. Controller / endpoint — model binding, validation, call the service: csharp [ApiController] [Route(\"api/customers/{customerId:int}/orders\")] public class OrdersController(IOrderService orders) : ControllerBase { [HttpGet] public async Task<ActionResult<PagedResult<OrderDto Get(int customerId, [FromQuery] int page = 1, [FromQuery] int size = 20, CancellationToken ct = default) = Ok(await orders.GetPageAsync(customerId, page, Math.Clamp(size, 1, 100), ct)); } 5. Service + EF Core — LINQ is translated to one SQL query; AsNoTracking for read-only; project to a DTO so only needed columns travel: csharp public async Task<PagedResult<OrderDto GetPageAsync(int customerId, int page, int size, CancellationToken ct) { var query = db.Orders.AsNoTracking().Where(o = o.CustomerId == customerId); var total = await query.CountAsync(ct); var items = await query.OrderByDescending(o = o.OrderDate) .Skip((page - 1) size).Take(size) .Select(o = new OrderDto(o.Id, o.OrderDate, o.Status, o.Lines.Sum(l = l.Qty l.Price))) .ToListAsync(ct); return new PagedResult<OrderDto (items, total, page, size); } 6. SQL Server — runs the generated query ( ORDER BY ... OFFSET ... FETCH ), ideally an index seek on (CustomerId, OrderDate DESC) . 7. Back up the stack — DTOs serialised to JSON by System.Text.Json → 200 OK → Angular deserialises → the template renders with @for . Interview tip: Mention async all the way (frees threads while waiting for SQL), CancellationToken (stops work when the user navigates away), AsNoTracking and projection . These four show production experience."},{"kind":"lesson","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"authentication-end-to-end-jwt-refresh-tokens-cors","title":"Authentication end to end — JWT, refresh tokens, CORS","body":"Typical flow (token-based, SPA + API): 1. User logs in (own endpoint, or an identity provider such as Microsoft Entra ID / Auth0 / Duende IdentityServer using OAuth 2.0 + OpenID Connect with PKCE). 2. The SPA receives an access token (short-lived JWT, e.g. 15–60 min) and often a refresh token (long-lived, rotated). 3. An HTTP interceptor adds Authorization: Bearer <access token to API calls. 4. The API validates signature, issuer, audience and expiry; builds ClaimsPrincipal ; [Authorize] and policies check roles/claims. 5. On 401 , the SPA uses the refresh token to get a new access token, or redirects to login. csharp builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(o = { o.Authority = builder.Configuration[\"Auth:Authority\"]; // identity provider o.Audience = builder.Configuration[\"Auth:Audience\"]; }); builder.Services.AddAuthorization(o = o.AddPolicy(\"CanApprove\", p = p.RequireRole(\"Manager\"))); app.UseCors(\"spa\"); app.UseAuthentication(); app.UseAuthorization(); typescript // Angular functional interceptor export const authInterceptor: HttpInterceptorFn = (req, next) = { const token = inject(AuthService).accessToken(); return next(token ? req.clone({ setHeaders: { Authorization: Bearer ${token} } }) : req); }; Question Short answer --- --- Where to store tokens in the browser? Best: keep tokens out of JS (BFF pattern + HttpOnly, Secure, SameSite cookie). If in JS, keep the access token in memory, not localStorage (XSS can read it). Authentication vs authorization Authentication = who you are (401 if missing/invalid). Authorization = what you may do (403 if not allowed). What is CORS? A browser rule: a page from origin A may call origin B only if B returns Access-Control-Allow-Origin for A. It is not a server security feature — Postman ignores it. JWT contents Header (alg), payload (claims: sub , exp , aud , iss , roles), signature. Base64Url-encoded, not encrypted — never put secrets in it."},{"kind":"lesson","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"validation-error-handling-and-logging-across-the-layers","title":"Validation, error handling and logging across the layers","body":"Validate at every boundary — for different reasons: Layer Validation Why --- --- --- UI Reactive form validators / schema (Zod) Fast feedback for the user API DataAnnotations or FluentValidation; [ApiController] returns 400 automatically Never trust the client Domain/service Business rules (credit limit, status transitions) Rules that need data Database NOT NULL, FK, UNIQUE, CHECK constraints Last line of defence for integrity Consistent errors with ProblemDetails (RFC 9457): csharp builder.Services.AddProblemDetails(); builder.Services.AddExceptionHandler<GlobalExceptionHandler (); app.UseExceptionHandler(); public sealed class GlobalExceptionHandler(ILogger<GlobalExceptionHandler log) : IExceptionHandler { public async ValueTask<bool TryHandleAsync(HttpContext ctx, Exception ex, CancellationToken ct) { var (status, title) = ex switch { NotFoundException = (404, \"Not found\"), ValidationException = (400, \"Validation failed\"), = (500, \"Unexpected error\") }; if (status == 500) log.LogError(ex, \"Unhandled error for {Path}\", ctx.Request.Path); ctx.Response.StatusCode = status; await ctx.Response.WriteAsJsonAsync(new ProblemDetails { Status = status, Title = title }, ct); return true; } } UI side: one HTTP interceptor maps 400 → show field errors, 401 → refresh/login, 403 → \"not allowed\", 500 → toast + correlation id. Logging: structured logs ( {OrderId} placeholders, not string concatenation), a correlation id per request passed from UI to API to downstream services, log levels used properly, no passwords/tokens/PII in logs."},{"kind":"lesson","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"worked-example-products-crud-with-search-and-paging","title":"Worked example — \"Products\" CRUD with search and paging","body":"The classic live-coding / take-home task. Build it layer by layer. 1. Database (SQL Server) sql CREATE TABLE dbo.Products ( Id INT IDENTITY PRIMARY KEY, Name NVARCHAR(200) NOT NULL, Category NVARCHAR(100) NOT NULL, Price DECIMAL(18,2) NOT NULL CHECK (Price = 0), IsActive BIT NOT NULL DEFAULT 1, RowVersion ROWVERSION ); CREATE INDEX IX Products Category Name ON dbo.Products(Category, Name) INCLUDE (Price) WHERE IsActive = 1; 2. Entity, DTOs and validation csharp public class Product { public int Id { get; set; } public string Name { get; set; } = \"\"; public string Category { get; set; } = \"\"; public decimal Price { get; set; } public bool IsActive { get; set; } = true; public byte[] RowVersion { get; set; } = []; } public record ProductDto(int Id, string Name, string Category, decimal Price); public record SaveProductRequest( [property: Required, MaxLength(200)] string Name, [property: Required, MaxLength(100)] string Category, [property: Range(0, 1 000 000)] decimal Price); 3. Endpoints (minimal API style) csharp var products = app.MapGroup(\"/api/products\").RequireAuthorization(); products.MapGet(\"/\", async (AppDb db, string? q, int page = 1, int size = 20) = { var query = db.Products.AsNoTracking().Where(p = p.IsActive); if (!string.IsNullOrWhiteSpace(q)) query = query.Where(p = p.Name.Contains(q)); var total = await query.CountAsync(); var items = await query.OrderBy(p = p.Name).Skip((page - 1) size).Take(size) .Select(p = new ProductDto(p.Id, p.Name, p.Category, p.Price)).ToListAsync(); return Results.Ok(new { items, total }); }); products.MapPost(\"/\", async (AppDb db, SaveProductRequest r) = { var p = new Product { Name = r.Name, Category = r.Category, Price = r.Price }; db.Products.Add(p); await db.SaveChangesAsync(); return Results.Created($\"/api/products/{p.Id}\", new ProductDto(p.Id, p.Name, p.Category, p.Price)); }); products.MapDelete(\"/{id:int}\", async (AppDb db, int id) = await db.Products.Where(p = p.Id == id).ExecuteUpdateAsync(s = s.SetProperty(p = p.IsActive, false)) == 1 ? Results.NoContent() : Results.NotFound()); // soft delete 4. UI (React + TypeScript) tsx function Products() { const [q, setQ] = useState(\"\"); const [page, setPage] = useState(1); const [data, setData] = useState<{ items: ProductDto[]; total: number } ({ items: [], total: 0 }); useEffect(() = { const ctrl = new AbortController(); const t = setTimeout(() = fetch( /api/products?q=${encodeURIComponent(q)}&page=${page} , { signal: ctrl.signal }) .then(r = r.json()).then(setData).catch(() = {}), 300); // debounce typing return () = { clearTimeout(t); ctrl.abort(); }; }, [q, page]); return (< <input value={q} onChange={e = { setQ(e.target.value); setPage(1); }} placeholder=\"Search\" / <table <tbody {data.items.map(p = <tr key={p.id} <td {p.name}</td <td {p.category}</td <td {p.price}</td </tr )}</tbody </table <button disabled={page === 1} onClick={() = setPage(page - 1)} Prev</button <button disabled={page 20 = data.total} onClick={() = setPage(page + 1)} Next</button </ ); } Points interviewers look for: DTOs instead of entities over the wire, server-side paging with a max page size, 201 Created with a location, soft delete, debounced search with request cancellation, a concurrency token ( ROWVERSION ) for edits, and an index that matches the query."},{"kind":"lesson","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"performance-across-the-stack","title":"Performance across the stack","body":"Find the slow layer first — measure, don't guess (browser Network tab → API timings/Application Insights → SQL execution plan). Layer Common problem Fix --- --- --- UI Huge bundles, re-rendering lists, many API calls Lazy-load routes, OnPush /signals (Angular), memo /virtualised lists (React), batch/combine calls Network Large JSON, no compression Paging, projection, response compression, HTTP caching ( ETag , Cache-Control ) API Blocking calls ( .Result ), sync I/O, chatty services Async all the way, IHttpClientFactory , output caching, parallel independent calls with Task.WhenAll Data access N+1 queries, tracking big read sets, ToList() too early Include /projection, AsNoTracking , AsSplitQuery for big graphs, compiled queries Database Missing index, scans, parameter sniffing, blocking Execution plan, covering index, update statistics, OPTION (RECOMPILE) where justified, RCSI Caching Same data loaded every request IMemoryCache / HybridCache (.NET 9+) / Redis with expiry and invalidation csharp // N+1 (one query for orders + one per order for lines) … foreach (var o in await db.Orders.ToListAsync()) total += o.Lines.Sum(l = l.Qty); // lazy loading → N extra queries // … fixed: one query, only the numbers needed var totals = await db.Orders.Select(o = new { o.Id, Qty = o.Lines.Sum(l = l.Qty) }).ToListAsync(); Interview tip: Tell a real story: \"Search took 6 s; the plan showed a clustered index scan on 4M rows; I added a covering index on (CustomerId, OrderDate) INCLUDE (Status, Total) and server-side paging — 300 ms.\""},{"kind":"lesson","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"deployment-config-secrets-docker-ci-cd-azure","title":"Deployment — config, secrets, Docker, CI/CD, Azure","body":"Configuration per environment: appsettings.json → appsettings.{Environment}.json → environment variables → Azure App Configuration / Key Vault. Bind to options classes ( IOptions<T ). Never commit secrets; use User Secrets locally and Key Vault + Managed Identity in Azure. Container image for the API: dockerfile FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build WORKDIR /src COPY . . RUN dotnet publish Api/Api.csproj -c Release -o /app FROM mcr.microsoft.com/dotnet/aspnet:10.0 WORKDIR /app COPY --from=build /app . USER app ENTRYPOINT [\"dotnet\", \"Api.dll\"] Pipeline (Azure DevOps or GitHub Actions): restore → build → unit tests → publish artefact (or build/push image) → deploy to dev → automated tests → approval → staging slot → swap to production. Hosting options: Azure App Service (simplest for a web API + SPA), Azure Container Apps (containers without managing Kubernetes), AKS (full Kubernetes), Azure Static Web Apps for the SPA. Database: Azure SQL Database. Migrations: run EF Core migration bundles or SQL scripts as a pipeline step, not on app start in production."},{"kind":"lesson","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"layered-and-clean-architecture-in-a-dotnet-solution","title":"Layered and clean architecture in a .NET solution","body":"A common, interview-friendly solution layout: text src/ Shop.Domain/ entities, value objects, domain rules (no dependencies) Shop.Application/ use cases/services, DTOs, interfaces (IOrderRepository), validation Shop.Infrastructure/ EF Core DbContext, repositories, email, file storage, external APIs Shop.Api/ controllers/endpoints, DI wiring, middleware, auth tests/ Shop.UnitTests/ Shop.IntegrationTests/ web/ shop-ui/ Angular or React app Dependency rule: dependencies point inwards — Api → Application → Domain; Infrastructure implements interfaces defined in Application. That is the Dependency Inversion Principle in practice, and it is what makes services unit-testable (mock IOrderRepository ). Question Answer --- --- Do I need a repository over EF Core? DbContext already is a unit of work and DbSet a repository. Add your own repository when you want to hide EF from the application layer, share query logic or ease testing; avoid generic repositories that just wrap DbSet . Where does validation go? Input shape in the API (FluentValidation), business rules in Application/Domain, integrity in the database. Monolith or microservices? Start with a modular monolith ; split a module into a service only when it needs independent scaling, deployment or ownership. CQRS? Separate read models (fast queries, often Dapper/SQL views) from write models (rich domain + EF). Useful when reads and writes have very different needs; MediatR is optional."},{"kind":"lesson","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"system-design-for-a-full-stack-dotnet-developer","title":"System design for a full stack .NET developer","body":"You are not expected to design Netflix. Expect: \"Design an e-commerce order system / a URL shortener / a notification service.\" Use this structure: 1. Clarify requirements — functional (place order, track status) and non-functional (users, requests/sec, latency, availability, consistency). 2. Estimate — e.g. 10k orders/day ≈ 0.1/sec average, peaks ×20; data ~5 GB/year → one SQL database is fine. 3. API design — POST /orders , GET /orders/{id} , idempotency key on create. 4. Data model — Orders, OrderLines, Products, Customers; indexes for the main queries. 5. High-level design — SPA → CDN; API behind a load balancer (stateless, scale out); SQL primary + read replica; Redis cache; Service Bus queue for emails/invoices. 6. Deep dive — one hard part: payment + stock consistency (outbox pattern, idempotency), or caching strategy. 7. Reliability & ops — retries with backoff (Polly / Microsoft.Extensions.Http.Resilience ), health checks, logging, monitoring, alerts. 8. Trade-offs — say what you would do differently at 100× scale. text Browser ─ CDN (SPA files) │ └─ HTTPS ─ Load balancer ─ API (N instances) ─┬─ SQL Server (primary + read replica) ├─ Redis cache └─ Service Bus ─ Worker (emails, invoices)"},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1071","title":"Explain the architecture of your current project end to end.","body":"Use the skeleton: business context → frontend (framework, state, auth) → API (layers, validation, errors, logging) → data (EF/Dapper, SQL Server, stored procedures) → security (identity provider, JWT, roles) → delivery (Git, CI/CD, hosting) → your part and one measurable result. Draw the boxes while you speak and keep it to about two minutes; the interviewer will drill into what interests them."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1072","title":"What happens when a user clicks \"Save\" in your Angular/React app until the data is in SQL Server?","body":"Form validation → service calls POST /api/... with JSON → interceptor adds the JWT → browser sends CORS preflight if cross-origin → Kestrel → middleware (exception handling, routing, CORS, authentication, authorization) → controller/endpoint → model binding and validation (400 if invalid) → service applies business rules → EF Core tracks the new entity → SaveChangesAsync opens a transaction and runs INSERT → SQL Server checks constraints and commits → API returns 201 Created with the new resource → UI updates the list and shows a message. Errors flow back as ProblemDetails and are shown by the interceptor."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1073","title":"What is the difference between authentication and authorization? Which status codes do they return?","body":"Authentication proves who the caller is (token, cookie); failure → 401 Unauthorized . Authorization decides what an authenticated caller may do (roles, policies, claims); failure → 403 Forbidden . In ASP.NET Core: UseAuthentication() then UseAuthorization() , [Authorize(Roles = \"Admin\")] or policies."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1074","title":"What is CORS and why do you get a CORS error only in the browser?","body":"CORS (Cross-Origin Resource Sharing) is a browser protection: JavaScript from origin A (e.g. http://localhost:4200 ) may read a response from origin B ( https://api.example.com ) only if B sends Access-Control-Allow-Origin allowing A. Non-simple requests trigger an OPTIONS preflight. Postman and server-to-server calls don't enforce it. Fix: builder.Services.AddCors(...) with the exact SPA origins and app.UseCors(...) before auth — never AllowAnyOrigin together with credentials."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1075","title":"Why do you return DTOs instead of EF entities from an API?","body":"Entities expose internal fields (passwords, audit columns), create circular references for JSON, couple the API contract to the database schema, and with lazy loading can trigger extra queries during serialisation. DTOs give a stable contract, only the needed fields, and let you project in SQL ( Select(o = new OrderDto(...)) ) so less data is read."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1076","title":"How do you implement paging, sorting and searching in a full stack app?","body":"Server-side: the API takes page , size (clamped to a maximum, e.g. 100), sort and q ; EF Core builds Where → OrderBy → Skip/Take , returns { items, total } (or a continuation token for keyset paging on very large tables). SQL needs an index that supports the filter + order. UI: debounce the search box (300 ms), cancel the previous request ( switchMap in RxJS / AbortController ), keep page/sort in the URL query string so links and Back work."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1077","title":"Where do you store the JWT in an SPA, and how do you refresh it?","body":"Safest: don't expose tokens to JavaScript — use a Backend-for-Frontend that keeps tokens server-side and gives the browser an HttpOnly, Secure, SameSite cookie. If the SPA holds tokens, keep the short-lived access token in memory (not localStorage , which XSS can read) and use refresh-token rotation via the identity provider (MSAL / oidc-client handle this). On a 401 the interceptor refreshes once and retries; if refresh fails, redirect to login."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1078","title":"How do you handle errors globally in both the API and the UI?","body":"API: AddProblemDetails() + an IExceptionHandler (or exception middleware) maps known exceptions to 400/404/409 and logs unknown ones as 500 with a correlation id; [ApiController] returns validation errors automatically. UI: one HTTP interceptor (Angular) or fetch wrapper (React) maps status codes to field errors, a login redirect, a \"no permission\" page, or a toast showing the correlation id; React error boundaries / Angular ErrorHandler catch rendering errors."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1079","title":"Explain the N+1 problem and how you detect and fix it.","body":"One query loads N parents, then one more query runs per parent to load children (often through lazy loading or a query inside a loop) — 1 + N round trips. Detect it with EF Core logging / Application Insights dependency telemetry / SQL Profiler showing many identical queries. Fix: eager load with Include , or better project only what you need in one query ( Select ), use AsSplitQuery for large graphs, and never query inside a loop."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1080","title":"How do you make an API call from Angular and show loading and error states?","body":"Inject HttpClient into a service that returns an Observable<T ; in the component either subscribe with takeUntilDestroyed() or use the async pipe / toSignal . Keep loading , error and data state (signals or a store), set loading before the call, clear it in finalize , catch errors with catchError . For search, use debounceTime + distinctUntilChanged + switchMap so older requests are cancelled."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1081","title":"How do you secure an ASP.NET Core Web API?","body":"HTTPS only (HSTS); authentication with JWT bearer from a trusted identity provider; authorization with policies and resource checks (user may only see their own orders — prevents IDOR); input validation; parameterised queries (EF/Dapper do this — never concatenate SQL); rate limiting ( AddRateLimiter ); CORS restricted to known origins; secrets in Key Vault; security headers; no stack traces to clients; dependency scanning in CI; logging without sensitive data."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1082","title":"How do you handle two users editing the same record at the same time?","body":"Optimistic concurrency: a ROWVERSION column mapped as a concurrency token ( [Timestamp] ). The UI sends back the version it loaded; EF Core adds WHERE Id = @id AND RowVersion = @v to the UPDATE. If no row is updated, EF throws DbUpdateConcurrencyException ; the API returns 409 Conflict and the UI shows \"this record changed — reload\". Pessimistic locking (holding locks) is rarely right for web apps."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1083","title":"How do you manage configuration and secrets across dev, QA and production?","body":"appsettings.json + appsettings.{Environment}.json + environment variables, bound to strongly typed options ( IOptions<T , validated on start). Secrets: User Secrets locally, Azure Key Vault in the cloud, accessed with Managed Identity (no passwords in config). The SPA gets environment settings at build time (Angular environment.ts / Vite env) or from a /config.json loaded at startup so the same build can go to every environment."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1084","title":"What does your CI/CD pipeline do for a full stack app?","body":"On PR: restore, build API and UI, run unit tests, lint, code analysis, maybe SonarQube and dependency scanning. On merge to main: build artefacts or Docker images with a version tag, deploy to dev, run DB migration scripts, smoke/integration tests, deploy to QA/UAT with approvals, then production via deployment slots or rolling update; rollback = redeploy the previous artefact. Pipelines are YAML in the repo."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1085","title":"How would you structure a new .NET full stack solution from scratch?","body":"Domain, Application, Infrastructure and Api projects (clean architecture), tests projects alongside, and the SPA in its own folder. Dependency rule inwards; DI registers Infrastructure implementations of Application interfaces. Cross-cutting: global error handling with ProblemDetails, validation (FluentValidation), structured logging with correlation ids, health checks, OpenAPI. Start as a modular monolith, one database with schemas per module. Add CI from day one."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1086","title":"Your list page takes 8 seconds to load. How do you find and fix the problem?","body":"Measure layer by layer: browser DevTools Network (is it the API call or rendering?), API timing / Application Insights (controller vs SQL time), EF Core logs or SQL Profiler for the generated SQL, actual execution plan in SSMS. Typical fixes: server-side paging and projection, a covering index for the filter/sort columns, removing N+1 queries, AsNoTracking , caching reference data, removing .Result blocking, virtualising long lists and lazy-loading the route in the UI. Re-measure after each change and report the before/after numbers."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1087","title":"Monolith or microservices for a new product? Justify.","body":"Usually a modular monolith first: one deployable, clear module boundaries, one database with separate schemas, in-process calls — simpler to build, test, deploy and debug. Move a module to a microservice when it needs independent scaling, release cadence, technology or team ownership. Microservices add network failures, distributed data and transactions (sagas/outbox), observability and DevOps cost — accept that only for a concrete benefit."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1088","title":"How do you keep the API and the frontend contract in sync?","body":"Generate the contract from the API: ASP.NET Core produces an OpenAPI document (built-in AddOpenApi in .NET 9+, or Swashbuckle/NSwag); generate TypeScript clients/types with NSwag, openapi-typescript or Orval in the build. Version breaking changes ( /api/v2 or header versioning with Asp.Versioning), keep changes additive, and run contract or end-to-end tests in CI."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1089","title":"How do you run long work (reports, emails, imports) without blocking the user?","body":"Don't do it inside the HTTP request. Return 202 Accepted with a job id, push a message to a queue (Azure Service Bus / RabbitMQ / Hangfire / a Channel<T + BackgroundService for simple cases), process it in a worker, store status, and let the UI poll or receive a push via SignalR. Make the job idempotent and retryable."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1090","title":"The UI shows \"CORS error\" after you deployed the API to Azure, but it worked locally. What do you check?","body":"The CORS policy must include the production SPA origin exactly (scheme + host + port, no trailing slash); UseCors must run before UseAuthentication / UseAuthorization and before the endpoints; Azure App Service's own CORS setting can override the app — use one or the other; the \"CORS error\" can also hide a 500 or 404 (a failed preflight or an error page without CORS headers) — check the API logs and the Network tab for the actual status."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1091","title":"A user can see another customer's orders by changing the id in the URL. What is wrong and how do you fix it?","body":"That is an IDOR (Insecure Direct Object Reference) — broken object-level authorization, the 1 item in the OWASP API Security Top 10. Authentication alone is not enough: the API must check ownership on every request, e.g. filter by the current user's customer id from the token ( Where(o = o.CustomerId == currentUser.CustomerId) ) or use resource-based authorization ( IAuthorizationService.AuthorizeAsync(User, order, \"OwnsOrder\") ). Return 404 (not 403) to avoid revealing that the id exists, and add tests for it."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1092","title":"After a release the API is slow and SQL CPU is at 100%. What do you do?","body":"Stabilise first: roll back or scale up if users are blocked. Then find the top queries by CPU (Query Store / sys.dm exec query stats ), compare plans before and after the release — usually a new query without an index, a changed LINQ query producing a bad plan, an N+1 loop, or parameter sniffing. Fix with an index, a rewritten query, forcing the last good plan in Query Store as a stop-gap, and add a performance test or alert so it is caught earlier next time."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1093","title":"You are asked to add a \"bulk upload products from Excel\" feature. Walk through your design.","body":"UI: upload control with file type/size checks, shows progress, then a result summary. API: POST multipart, validate size, store the file (Blob Storage), return 202 with an import id. Worker: read with a streaming library (e.g. ClosedXML/ExcelDataReader), validate every row and collect errors, insert in batches ( SqlBulkCopy or EF Core bulk/ ExecuteUpdate ) inside a transaction or into a staging table then MERGE . Status endpoint/SignalR for progress; downloadable error report; idempotent so a retry doesn't duplicate rows; audit who uploaded what."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1094","title":"Two services need the same customer data. One team proposes sharing one database table. What do you advise?","body":"Sharing tables couples deployments and schema changes between teams. Prefer one owner of the data: other services call its API or keep a read-only copy updated through events (CustomerUpdated on a message bus). If they truly must share, use a view or a stable read schema as the contract. Inside a modular monolith, keep separate schemas and access other modules only through their public interfaces."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1095","title":"Your Angular/React app works locally but shows a blank page after deployment. How do you debug it?","body":"Open DevTools console and Network: typical causes are a wrong base href / base path, 404s for JS bundles, the server not rewriting deep links to index.html (SPA fallback), missing environment config (API URL points to localhost), mixed content (HTTPS page calling HTTP API) or a runtime error in production mode only. Fix the hosting rewrite rule, base path and environment config, and add a smoke test to the pipeline."},{"kind":"question","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1096","title":"An order must be saved, stock reduced and an email sent. How do you keep these consistent?","body":"Order and stock in the same database transaction ( SaveChangesAsync on one DbContext, or an explicit transaction). The email is a side effect outside the database, so use the outbox pattern : in the same transaction insert an \"OrderPlaced\" row into an Outbox table; a background worker reads it, publishes/sends the email and marks it done. If the app crashes after commit, the worker still sends it; consumers are idempotent so a retry doesn't send twice."},{"kind":"cheat","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"1","title":"End-to-end request path","body":"UI service → interceptor (JWT) → CORS preflight → Kestrel → exception handler → routing → CORS → authN → authZ → endpoint → validation → service → EF Core / Dapper → SQL Server → DTO → JSON → UI state → render ."},{"kind":"cheat","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"2","title":"Status codes to quote","body":"Code Use --- --- 200 / 201 / 204 OK / Created (+ Location) / No content (delete, update) 202 Accepted — background job started 400 Validation failed (ProblemDetails with errors) 401 / 403 Not authenticated / authenticated but not allowed 404 / 409 Not found / conflict (concurrency, duplicate) 429 Rate limited 500 Unhandled error — log with correlation id"},{"kind":"cheat","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"3","title":"Performance checklist","body":"- Server-side paging, projection to DTOs, AsNoTracking for reads - Index for every important WHERE + ORDER BY ; read the execution plan - No N+1, no query inside a loop, no .Result / .Wait() - Cache reference data ( IMemoryCache / HybridCache /Redis) - UI: lazy routes, debounce + cancel, virtual scrolling, OnPush /signals or memo"},{"kind":"cheat","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"4","title":"Security checklist","body":"- HTTPS + HSTS; JWT from a trusted IdP; policies, not only roles - Ownership checks on every resource (no IDOR) - Parameterised SQL only; validate all input - CORS limited to known origins; rate limiting - Secrets in Key Vault with Managed Identity; nothing sensitive in logs or JWT payload"},{"kind":"cheat","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"5","title":"Project answer skeleton","body":"Business → Frontend → API layers → Data → Security → CI/CD & hosting → My contribution + one number ."},{"kind":"cheat","course_slug":"dotnet-fullstack-interview","course_title":".NET Full Stack Developer Interview — End to End","ref":"6","title":"Words that show seniority","body":"Idempotency key · outbox pattern · correlation id · ProblemDetails · optimistic concurrency (ROWVERSION) · covering index · keyset paging · modular monolith · Managed Identity · deployment slots · feature flags · health checks."},{"kind":"course","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"","title":"HR & Behavioural Interview","body":"How HR and behavioural rounds work, the STAR method, \"tell me about yourself\", strengths and weaknesses, why this company, why leaving, conflict, failure, pressure, teamwork, culture fit, questions to ask, body language, online interview etiquette and model answers. The HR round checks whether you are a good fit for the company and role beyond technical skills: communication, attitude, motivation, stability, culture fit, salary expectations and notice period. Behavioural interviews (asked by HR, managers and even technical panels) use questions like \"Tell me about a time when...\" on the principle that past behaviour predicts future behaviour . What interviewers evaluate: Area What they look for --- --- Communication Clear, structured, concise answers; listening Motivation Why this company/role; genuine interest Attitude Ownership, positivity, learning mindset, no blaming Teamwork Collaboration, handling conflict, helping others Integrity Honest answers, consistency with your CV Stability Reasons for job changes, long-term fit Logistics Notice period, location/relocation, salary, visa/work permit The golden rule: be honest, specific and positive — and prepare stories in advance. Interview practices have evolved: Era Practice --- --- Traditional Unstructured chats, \"What are your strengths?\" 1970s–80s Behavioural interviewing popularised (Tom Janz and others) — \"Tell me about a time…\" 1990s–2000s Competency frameworks; STAR method widely adopted 2010s Structured interviews with scoring rubrics; values-based interviews (e.g. Amazon Leadership Principles) 2020 onwards Remote/video interviews become standard; asynchronous video screening (HireVue-style) and AI-assisted screening; skills-based hiring Typical hiring process (varies by company): 1. Application / referral → resume screening (often an ATS — applicant tracking system — keyword match). 2. Recruiter / HR screening call (15–30 min): background, notice period, current/expected CTC, location, interest. 3. Online assessment (aptitude, coding, MCQs) — common in service companies and for freshers. 4. Technical round(s) — 1 to 3 rounds (concepts, coding, system design, project discussion). 5. Managerial / techno-managerial round — ownership, team fit, scenarios. 6. HR round — behavioural questions, culture fit, salary discussion. 7. Offer — verbal offer → written offer letter → negotiation → acceptance. 8. Background verification (employment, education, address, criminal check) → onboarding . Answer lifecycle (how to handle any HR question): listen fully → pause briefly → structure (STAR or point-reason-example) → answer in 60–120 seconds → connect back to the role → stop and let them ask follow-ups. - Your resume (one or two pages, tailored to the job description, achievements with numbers). - STAR story bank — 8–10 stories (spreadsheet/notes) covering conflict, failure, success, leadership, deadline, learning, mistake, disagreement, customer focus, innovation. - Company research : company website, annual report/investor pages, news, LinkedIn, Glassdoor, AmbitionBox (India), job description. - Mock interviews : this site's Practice panel, a friend, recording yourself on video. - Online setup : quiet room, good light, headphones with mic, stable internet, Zoom/Teams/Meet tested. - Demo kit → My pitch on this site to keep your introduction and stories handy."},{"kind":"lesson","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"the-star-method","title":"The STAR method","body":"Structure every behavioural answer as: Step What to say Share of the answer --- --- --- S — Situation Context: where, when, what was going on ~15% T — Task Your responsibility or goal ~10% A — Action What you did — specific steps, decisions, why ~60% R — Result Outcome with numbers + what you learned ~15% Tips: use \"I\" for your actions (not only \"we\"); quantify results (time saved, % improvement, money, users); keep it to about 2 minutes; prepare stories that can be adapted to several questions; end with the learning. Example (tight deadline): S: In my last project, the client moved a regulatory reporting release forward by two weeks. T: I owned the SSIS and SQL Server part — 14 reports had to be validated. A: I listed the reports by risk, automated the reconciliation checks with T-SQL scripts instead of manual Excel comparisons, split work with two colleagues, and gave the client daily status with risks. R: We delivered 3 days early with zero defects in UAT, and the reconciliation scripts became part of the standard release checklist."},{"kind":"lesson","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"tell-me-about-yourself-the-60-90-second-pitch","title":"\"Tell me about yourself\" — the 60–90 second pitch","body":"Formula: Present → Past → Future (or Who you are → What you've done → What you want and why here). \"I'm a .NET developer with 5 years of experience building web APIs and data platforms with C , ASP.NET Core, SQL Server and Azure. Currently at ABC Technologies, I work on a payments platform where I designed the reconciliation service that processes about 2 lakh transactions a day and cut the nightly batch from 3 hours to 25 minutes. Before that , at XYZ, I built SSIS/SSRS reporting for a banking client and moved their deployments to Azure DevOps pipelines. I'm now looking for a role where I can work on cloud-native, high-scale systems, which is why this position on your Azure platform team interests me.\" Do: tailor it to the job description, include 1–2 measurable achievements, finish with why this role. Don't: recite your CV line by line, talk about family/personal life at length (unless asked), or go over 2 minutes."},{"kind":"lesson","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"strengths-weaknesses-and-self-awareness","title":"Strengths, weaknesses and self-awareness","body":"Strengths — pick 2–3 relevant to the role, each with proof : \"My strength is debugging production issues systematically. Last quarter I traced a recurring timeout to parameter sniffing in a stored procedure using Query Store, fixed it, and added monitoring — incidents for that service dropped to zero.\" Weakness — real, not disqualifying for the role, and show what you are doing about it : \"I used to take on too much myself instead of delegating, because I wanted things done perfectly. It slowed the team down in one release. Since then I break work into tasks in Jira early, pair with juniors, and review instead of rewriting — our last sprint finished all committed stories.\" Avoid clichés (\"I'm a perfectionist\", \"I work too hard\") and fatal weaknesses (\"I miss deadlines\", \"I don't like teamwork\")."},{"kind":"lesson","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"researching-the-company-and-why-do-you-want-to-join-us","title":"Researching the company and \"Why do you want to join us?\"","body":"Research: products/services, customers, industry, recent news (funding, launches, acquisitions), tech stack (job posts, engineering blog), values/culture, office location, interview process (Glassdoor/AmbitionBox). Answer formula: Company → Role → You . \"Your company builds payment infrastructure used by thousands of merchants — I've worked on reconciliation and settlement for 3 years, so the domain is familiar and I want to go deeper. The role focuses on .NET services on Azure with high transaction volumes, which matches my experience and is where I want to grow. And from your engineering blog, the focus on observability and automated testing is how I like to work.\""},{"kind":"lesson","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"why-are-you-leaving-your-current-job","title":"Why are you leaving your current job?","body":"Be honest but positive and forward-looking ; never criticise your current employer or manager. Good reasons: growth/learning, bigger scope or responsibility, new technology/domain, relocation, project ended, company restructuring, stability after a contract role. \"I've learned a lot at my current company and delivered two major releases. The product is now in maintenance mode, and I want to work on building new cloud-native systems at a larger scale — which this role offers.\" If you were laid off: \"My role was part of a company-wide restructuring affecting 15% of staff. It wasn't performance-related — I have a reference from my manager. I used the time to complete AZ-204 and build a project with .NET 10 and Azure Container Apps.\""},{"kind":"lesson","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"where-do-you-see-yourself-in-five-years","title":"Where do you see yourself in five years?","body":"Show ambition aligned with the company, not a plan to leave: \"In five years I'd like to be a senior engineer or tech lead who owns the architecture of a product area, mentors developers and works closely with the business. I'm also aiming to deepen my Azure architecture skills. I'd like to grow into that here, because this role gives exposure to design decisions early.\""},{"kind":"lesson","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"logistics-notice-period-relocation-shifts-joining-date","title":"Logistics: notice period, relocation, shifts, joining date","body":"- Notice period : state it exactly (e.g. 60 days) and whether buyout or early release is possible. Don't promise what you can't deliver. - Relocation : be clear about willingness and timing; ask about relocation support. - Shifts / on-call / travel : answer honestly; ask how often. - Bond / service agreement : read the terms before accepting. - Documents : relieving letters, payslips, Form 16 (India), degree certificates — keep them ready for background verification. - Work permits : e.g. for Taiwan, foreign professionals need a work permit (or a Taiwan Employment Gold Card) — know your status and timeline."},{"kind":"lesson","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"body-language-voice-and-online-interview-etiquette","title":"Body language, voice and online interview etiquette","body":"- Be on time (5 minutes early online; 10–15 in person). - Camera at eye level, face well lit, plain background, look at the camera when speaking. - Mute notifications; close other apps; keep water, a pen and your resume nearby. - Sit upright, nod, smile naturally; avoid interrupting; pause before answering. - Speak clearly and at a moderate pace; if the connection drops, rejoin and briefly summarise where you were. - Dress one level above the company's daily dress code. - Close politely: thank them, ask about next steps, send a short thank-you email within 24 hours."},{"kind":"lesson","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"questions-to-ask-the-interviewer","title":"Questions to ask the interviewer","body":"Always ask 2–3. Good ones: - \"What does success look like in this role in the first 90 days?\" - \"What are the biggest challenges the team is facing right now?\" - \"How is the team structured, and who would I work with most?\" - \"How do you handle code reviews, testing and deployments?\" - \"What do you like most about working here?\" - \"How are performance reviews and promotions handled?\" - \"What are the next steps in the process?\" Avoid asking first about leave, perks or \"How soon can I get promoted?\" — and never say \"No questions\"."},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1097","title":"Tell me about yourself.","body":"Use Present → Past → Future in 60–90 seconds. Example: \"I'm a .NET developer with 5 years' experience in C , ASP.NET Core, SQL Server and Azure. Currently I build payment reconciliation APIs at ABC, where I cut the nightly batch from 3 hours to 25 minutes by moving row-by-row processing to set-based T-SQL and parallel jobs. Earlier at XYZ I built SSIS/SSRS reporting for a banking client and set up Azure DevOps CI/CD. I'm looking for a role building cloud-native, high-scale services — which is why this Azure platform role interests me.\" Tailor the achievements to the job description."},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1098","title":"Why should we hire you?","body":"Connect three things: the role's needs, your proof, and your attitude. \"You need someone who can build and run .NET services on Azure and improve performance. I've done exactly that — for example, I reduced API p95 latency by 60% with caching and query tuning, and I set up the CI/CD pipeline my team uses today. I also communicate well with business users, and I'm keen to keep learning, as my recent AZ-204 certification shows. I can contribute from the first month.\""},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1099","title":"What are your strengths?","body":"Pick two or three that matter for the role and prove each with a short example. \"First, problem-solving under pressure — I led the fix for a production payment outage within 40 minutes by isolating a failing dependency and switching to a fallback. Second, ownership — I don't stop at 'code complete'; I add monitoring and documentation. Third, learning quickly — I picked up Angular in a month to help our frontend team meet a release.\""},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1100","title":"What is your greatest weakness?","body":"Choose a real but manageable weakness and show improvement. \"I used to find it hard to say no to extra requests, which once put a sprint commitment at risk. I've learned to make trade-offs visible: when a new request comes in, I ask my lead or product owner what should move out, and I track everything in Jira. Over the last three sprints we met all our commitments.\""},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1101","title":"Why do you want to work here?","body":"Show research and fit: company → role → you. Mention the product/domain, something specific (tech stack, engineering culture, growth, customers), and how your experience matches. Avoid answers about salary only or \"it's a big brand\". Example: \"Your platform serves banks across Asia, and I've spent three years on banking data systems. This role combines .NET microservices with Azure, which is where I want to grow, and your focus on automated testing matches how I work.\""},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1102","title":"Why are you leaving your current company?","body":"Stay positive and future-focused: \"I've had a great learning experience and delivered X and Y, but the project has moved into maintenance, and I'm looking for larger-scale, cloud-native work and more ownership, which this role offers.\" Never criticise your employer, manager or colleagues, and keep it consistent with what's on LinkedIn and your resume."},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1103","title":"Where do you see yourself in five years?","body":"Show realistic ambition aligned with the company's path: \"I see myself as a senior engineer or tech lead owning a product area's architecture, mentoring developers and working closely with business stakeholders, with deeper Azure architecture expertise. I'd like to grow into that here.\" Avoid \"running my own startup\" or \"in your job\"."},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1104","title":"What do you know about our company?","body":"Summarise in four points: what they do (products/services and customers), scale or market position (from public sources), recent news (launch, expansion, acquisition, results), and the tech/culture aspects relevant to you. Then connect: \"That's why this role appeals to me…\". Only use facts you've verified — don't guess numbers."},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1105","title":"Are you willing to relocate or work in shifts?","body":"Answer honestly with any conditions: \"Yes, I'm open to relocating to Hyderabad; I'd need about a month after my notice period to move. Could you tell me if relocation support is provided?\" For shifts: \"I'm fine with occasional on-call rotations and overlap with US hours a few days a week. Could you share how often night shifts are needed?\""},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1106","title":"What is your notice period? Can you join earlier?","body":"State it exactly and what flexibility exists: \"My notice period is 60 days. My company allows buyout of part of it, so I could join in about 30–45 days if needed, and I'm finishing my handover documentation early to make that possible.\" Don't claim an immediate joining you can't deliver — background checks will confirm dates."},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1107","title":"Tell me about a time you had a conflict with a colleague.","body":"STAR, showing empathy and resolution — not blame. \"S: A senior QA and I disagreed on releasing a hotfix — he wanted a full regression; I worried about the client's outage. T: We needed a decision within the hour. A: I spoke with him privately, understood his concern about a past incident, and proposed a targeted regression of affected modules plus a rollback plan, then we presented both options to the lead together. R: We released in 90 minutes with no new defects; since then we keep a 'hotfix test checklist' we built together, and we work well.\""},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1108","title":"Tell me about a failure or mistake you made.","body":"Choose a genuine mistake with low-to-moderate impact, own it, and show learning. \"I once deployed a database migration that locked a large table during business hours, causing 10 minutes of slow responses. I rolled back immediately, informed my manager and the client, and redid it off-hours in batches. I then added a pre-deployment checklist for migrations — size checks, off-peak scheduling and a tested rollback script — and we haven't had a repeat.\""},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1109","title":"Describe a situation where you worked under pressure or a tight deadline.","body":"Use STAR with planning and communication. \"When a client moved a release forward by two weeks, I prioritised by risk, automated repetitive validation with scripts, split tasks with two teammates, and gave daily status updates highlighting risks early. We delivered three days early with zero UAT defects.\" Emphasise calm prioritisation, not heroic overtime."},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1110","title":"Tell me about your biggest achievement.","body":"Pick a professional achievement relevant to the role, with a measurable result and your personal contribution. \"Re-architecting our report generation: reports took up to 20 minutes and often timed out. I profiled the queries, introduced pre-aggregated tables refreshed by SSIS, moved generation to a background queue with email delivery, and added caching. Average time dropped to under 30 seconds, and support tickets on reports fell by 80%.\""},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1111","title":"How do you handle criticism or negative feedback?","body":"\"I treat feedback as information to improve. I listen without being defensive, ask for specific examples, and agree on what to change. For example, my lead said my PRs were too large to review; I started splitting work into smaller PRs with clear descriptions. Review time dropped from days to hours, and I now give feedback to others the same way.\""},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1112","title":"How do you prioritise when you have multiple tasks?","body":"\"I first clarify impact and deadlines with stakeholders, then sort by urgency and importance (production issues and blockers first, then committed sprint work, then improvements). I break tasks into smaller pieces, track them in Jira, communicate early if something will slip, and ask my lead to arbitrate real conflicts rather than silently missing a deadline.\""},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1113","title":"What motivates you?","body":"Be specific and genuine: \"Solving real problems for users and seeing measurable impact — like a report that used to take 20 minutes running in 30 seconds. I'm also motivated by learning new things, such as moving our services to containers, and by working with a team where people help each other.\""},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1114","title":"Do you prefer working alone or in a team?","body":"\"Both have their place. I enjoy deep focused work on complex problems, but I deliver best in a team: design discussions, code reviews and pairing improve quality. In my current team I own the reporting module end to end and also review two colleagues' PRs daily.\""},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1115","title":"Have you ever disagreed with your manager? What happened?","body":"Show respectful disagreement backed by data, then commitment. \"My manager wanted to add a feature directly into the monolith to meet a date; I was concerned about coupling. I wrote a one-page comparison of effort and risks and suggested a small separate module behind an interface. He agreed to a middle path: we shipped on time inside the monolith but behind the interface, and we extracted it later in two days. Once a decision is made, I fully support it.\""},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1116","title":"How do you keep your skills up to date?","body":"Give concrete, recent examples: \"I follow the .NET and Azure blogs and release notes, did the AZ-204 certification last year, build small side projects to try new features — recently Minimal APIs with .NET 10 and Azure Container Apps — and share learnings in our team's monthly tech talk.\""},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1117","title":"Tell me about a time you went beyond your job description.","body":"\"Our team kept losing time on manual deployments. Although DevOps wasn't my role, I wrote a YAML pipeline in Azure DevOps for build, test and deployment to dev and QA, documented it and ran a session for the team. Deployment time went from 2 hours to 15 minutes and failed deployments dropped sharply. It was later adopted by two other teams.\""},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1118","title":"You are offered a role, but another company is also likely to make an offer next week. What do you do?","body":"Be honest and professional: thank the first company, express genuine interest, and ask for a reasonable timeline to decide (\"Could I confirm by next Friday?\"). Inform the second company that you have an offer and a deadline to see if they can speed up. Compare on role, learning, team, stability, compensation and location — not just salary. Once you accept, honour it; reneging after accepting damages your reputation (and in India some companies share data on offer drop-outs)."},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1119","title":"Your manager asks you to finish a task that you believe will cause a production problem. What do you do?","body":"Raise the concern immediately with facts: explain the risk, likely impact and evidence, and propose alternatives (a safer approach, a feature flag, a staged rollout, more testing). Put it in writing (email/ticket) so the decision is documented. If the manager still decides to proceed and it isn't unethical or illegal, execute it as safely as possible with monitoring and a rollback plan. If it's unethical or illegal (e.g. data privacy violation), escalate through proper channels."},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1120","title":"A teammate isn't contributing and you're doing their work. How do you handle it?","body":"First talk to them privately and without blame — there may be a reason (overload, personal issues, unclear tasks). Offer help and agree on clear ownership and deadlines. Make work visible on the board. If nothing changes and delivery is at risk, raise it factually with the lead, focusing on the impact on the work rather than on the person."},{"kind":"question","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1121","title":"What would you do in your first 30–60–90 days here?","body":"\"First 30 days: learn the product, architecture, codebase, deployment process and people; fix small bugs to learn the workflow. 60 days: own a feature end to end, contribute to code reviews and on-call. 90 days: deliver a meaningful improvement — for example in performance, testing or tooling — and agree on goals with my manager.\" Adjust to the role and ask what they expect."},{"kind":"cheat","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"1","title":"Answer frameworks","body":"- STAR : Situation · Task · Action (60%, \"I\") · Result (numbers + learning). - Tell me about yourself : Present → Past → Future → why this role (60–90 s). - Why us : Company → Role → You. - Weakness : real + not fatal + what you're doing about it + proof of progress."},{"kind":"cheat","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"2","title":"Story bank (prepare 8–10)","body":"Biggest achievement · conflict · failure/mistake · tight deadline · disagreement with manager · leadership/mentoring · learning something fast · customer/stakeholder issue · going beyond your role · process improvement."},{"kind":"cheat","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"3","title":"Never","body":"Badmouth employers · lie (background checks verify) · say \"no questions\" · give a salary number before researching · ramble beyond 2 minutes · use only \"we\"."},{"kind":"cheat","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"4","title":"Always","body":"Research the company · tailor examples to the JD · quantify results · ask 2–3 questions · send a thank-you email · keep your story consistent with your resume and LinkedIn."},{"kind":"cheat","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"5","title":"Online checklist","body":"Camera at eye level · light in front · headphones · notifications off · resume + JD + pitch notes open · join 5 minutes early · water nearby."},{"kind":"cheat","course_slug":"hr-behavioral","course_title":"HR & Behavioural Interview","ref":"6","title":"Questions to ask","body":"90-day success · team challenges · team structure · engineering practices · growth/reviews · next steps."},{"kind":"course","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"","title":"Team Lead, Managerial & Agile Interview","body":"The tech lead vs engineering manager role, SDLC and Agile/Scrum/Kanban, estimation and planning, delegation, mentoring, performance management, conflict resolution, stakeholder management, risk and incident management, hiring, technical decision-making and model answers for managerial rounds. Managerial / techno-managerial rounds (often with a delivery manager, engineering manager, director or client) test whether you can deliver through a team — not just code. For senior developer, tech lead, team lead, project lead and engineering manager roles, expect questions on: - Delivery : planning, estimation, sprint management, risk, deadlines, scope changes. - People : delegation, mentoring, motivation, feedback, underperformers, conflict, hiring. - Stakeholders : clients, product owners, escalations, saying no, status reporting. - Technical leadership : architecture decisions, code quality, technical debt, production incidents. - Process : Agile/Scrum/Kanban, SDLC, DevOps metrics, documentation. Role Main focus --- --- Senior developer Complex features, quality, reviews, guiding juniors Tech lead Technical direction, design, code quality, unblocking the team; still codes a lot Team lead (common in Indian IT services) Tech + people + delivery for a small team; client interaction; task allocation Engineering manager People (hiring, growth, performance), process, delivery, cross-team collaboration; less coding Project / delivery manager Scope, schedule, budget, risks, client relationship, reporting Architect System-wide design, standards, technology choices, non-functional requirements Management and delivery methods have evolved: Year Milestone --- --- 1970 Winston Royce's paper (commonly cited as the origin of the \"Waterfall\" model, though it argued for iteration) 1986 Takeuchi & Nonaka's \"The New New Product Development Game\" — inspiration for Scrum 1995 Scrum presented by Ken Schwaber and Jeff Sutherland 1996–1999 Extreme Programming (Kent Beck) 2001 Agile Manifesto (4 values, 12 principles) 2004–2010 Kanban for software (David J. Anderson); first Scrum Guide (2010) 2009 \"DevOps\" term (Patrick Debois' DevOpsDays) 2011 SAFe (Scaled Agile Framework) 1.0 2014–2018 DORA research; Accelerate book (2018) 2020 Current Scrum Guide revision (Product Goal, one Scrum Team, \"Developers\") 2020s Remote/hybrid teams, platform engineering, SPACE framework for developer productivity, AI-assisted development SDLC (Software Development Life Cycle) phases: Requirements → Analysis → Design → Implementation → Testing → Deployment → Maintenance. Models: Waterfall (sequential), V-Model (testing paired with each phase), Iterative/Incremental , Spiral (risk-driven), Agile (Scrum, Kanban, XP), DevOps (continuous delivery and operations). Scrum lifecycle (per sprint, 1–4 weeks, commonly 2): 1. Product Backlog (owned by the Product Owner, ordered by value) with refinement sessions. 2. Sprint Planning — why (Sprint Goal), what (selected backlog items), how (plan/tasks) → Sprint Backlog . 3. Daily Scrum — 15 minutes for Developers to inspect progress toward the Sprint Goal and adapt. 4. Development work; Definition of Done applied to every increment. 5. Sprint Review — demo the increment to stakeholders, adapt the backlog. 6. Sprint Retrospective — improve how the team works. 7. Repeat. Scrum roles (accountabilities): Product Owner , Scrum Master , Developers . Artifacts: Product Backlog (commitment: Product Goal), Sprint Backlog (Sprint Goal), Increment (Definition of Done). Team development lifecycle (Tuckman): Forming → Storming → Norming → Performing (→ Adjourning). A lead adapts style: directive early, coaching during storming, supportive/delegating when performing. Incident lifecycle: detect → triage/assess severity → communicate → mitigate/restore → resolve root cause → blameless post-mortem → follow-up actions. Area Tools --- --- Work tracking Jira, Azure Boards, Linear, GitHub Projects, Trello Documentation Confluence, Notion, SharePoint, Azure DevOps Wiki, architecture decision records (ADRs) Communication Microsoft Teams, Slack, Zoom, Outlook Planning & estimation Planning poker (story points), roadmaps, Gantt (MS Project) for fixed-scope work Metrics DORA metrics, velocity, cycle time, burndown/burnup, cumulative flow diagrams Quality SonarQube, code review policies, test coverage, defect tracking Incident management PagerDuty, Opsgenie, Azure Monitor alerts, status pages People 1:1 notes, OKRs/goals tools, performance review systems (Workday, SuccessFactors) Diagrams draw.io, Lucidchart, Excalidraw, C4 model"},{"kind":"lesson","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"from-developer-to-tech-lead-what-changes","title":"From developer to tech lead: what changes","body":"Developer Lead --- --- Measured by own output Measured by team output and outcomes Solves assigned problems Defines problems, breaks them down, assigns Deep in code Code + design reviews + unblocking + communication Reports status Owns status, risks and expectations with stakeholders Responds to decisions Makes and explains decisions, accepts accountability Typical lead time split: ~30–60% hands-on technical work, the rest planning, reviews, mentoring, meetings and stakeholder communication. A common trap: being the \"hero\" who does the hardest work alone — it doesn't scale and blocks the team's growth."},{"kind":"lesson","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"agile-scrum-and-kanban-essentials","title":"Agile, Scrum and Kanban essentials","body":"Agile Manifesto values: individuals and interactions over processes and tools; working software over comprehensive documentation; customer collaboration over contract negotiation; responding to change over following a plan. Scrum Kanban --- --- --- Cadence Fixed sprints Continuous flow Roles PO, Scrum Master, Developers No prescribed roles Commitment Sprint backlog / goal WIP limits per column Change Usually between sprints Any time Metrics Velocity, burndown Cycle time, lead time, throughput, CFD Best for Product development with planning cycles Support/maintenance, ops, unpredictable work Terms: user story (\"As a … I want … so that …\") with acceptance criteria (Given/When/Then), story points (relative effort/complexity, Fibonacci), velocity , Definition of Ready / Done , epic → feature → story → task , spike (time-boxed research), MVP , INVEST (Independent, Negotiable, Valuable, Estimable, Small, Testable)."},{"kind":"lesson","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"estimation-and-planning","title":"Estimation and planning","body":"- Break work down until pieces are ≤ 1–3 days; unknowns become spikes. - Relative estimation (story points + planning poker) builds shared understanding; use historical velocity for sprint capacity. - For fixed-date/fixed-scope client projects: bottom-up estimates in hours/days + three-point estimates (optimistic, most likely, pessimistic → PERT: (O + 4M + P) / 6) + contingency (often 15–25%) + explicit assumptions. - Include non-coding work: code review, testing, deployment, documentation, meetings, holidays, support load. - Re-estimate when you learn more; communicate changes early. - Make trade-offs explicit: scope, time, cost, quality (the iron triangle — quality shouldn't be the variable)."},{"kind":"lesson","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"delegation-and-task-allocation","title":"Delegation and task allocation","body":"- Delegate outcomes , not just tasks: context (why), expected result, constraints, deadline, how and when to check in. - Match tasks to skill and growth : stretch tasks for growth with support; critical-path work to experienced members; pair juniors with seniors. - Use situational leadership: directing (new/low skill) → coaching → supporting → delegating (expert, motivated). - Avoid single points of failure — rotate knowledge (pairing, documentation, code reviews). - Track on the board, not via constant status chasing; be available to unblock."},{"kind":"lesson","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"mentoring-feedback-and-1-1s","title":"Mentoring, feedback and 1:1s","body":"- 1:1s (weekly/biweekly, 30 min): their agenda first — blockers, growth, wellbeing, feedback both ways. - Feedback models: SBI (Situation – Behaviour – Impact), timely, specific, private for criticism, public for praise. \"In yesterday's client call (situation), you jumped in to correct the client mid-sentence twice (behaviour). The client seemed annoyed and the call ran long (impact). Next time, can you note your point and raise it when they finish? Happy to role-play before the next call.\" - Growth: individual development plans, stretch assignments, certifications, tech talks, gradual ownership. - Psychological safety: people can admit mistakes and ask questions without fear — the strongest predictor of team effectiveness in Google's Project Aristotle research."},{"kind":"lesson","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"handling-underperformance","title":"Handling underperformance","body":"1. Observe and gather facts (missed deliverables, quality issues) — not impressions. 2. Talk privately and early : share specific examples, listen — find the cause (unclear expectations, skill gap, personal issue, motivation, wrong role). 3. Agree a plan : clear expectations, support (training, pairing, smaller tasks), timeline, check-ins. 4. Follow up regularly; recognise improvement. 5. If no improvement: involve your manager/HR for a formal performance improvement plan (PIP) , document everything, be fair and consistent. 6. Throughout: respect, confidentiality, no public criticism."},{"kind":"lesson","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"conflict-resolution","title":"Conflict resolution","body":"Types: task conflict (what to do), process conflict (how), relationship conflict (personal). Healthy task conflict improves decisions; relationship conflict must be addressed quickly. Approach: 1. Talk to each person privately; understand interests behind positions. 2. Bring them together; set ground rules; focus on facts and shared goals (customer, quality, deadline). 3. Generate options; decide using agreed criteria (data, spike/prototype, architecture principles) — or the lead decides if needed (\"disagree and commit\"). 4. Document the decision (ADR) and follow up. Thomas-Kilmann modes: competing, collaborating, compromising, avoiding, accommodating — collaborating is ideal for important issues; compromising when time is short."},{"kind":"lesson","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"stakeholder-management-and-communication","title":"Stakeholder management and communication","body":"- Identify stakeholders (client, PO, users, other teams, management) and what each cares about. - Regular status reporting : progress vs plan, RAG (red/amber/green) status, risks, decisions needed, next steps — short and factual. - No surprises : share bad news early with a plan (\"We're 1 week behind on the payment module because the gateway sandbox was down for 3 days; options: A) cut feature X from this release, B) add one developer for 2 weeks, C) move the date to the 20th. I recommend A.\"). - Say no (or \"not now\") with reasons and alternatives; protect the team from constant scope changes — route them through the backlog/change request process. - Manage expectations in writing: scope, assumptions, acceptance criteria."},{"kind":"lesson","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"risk-management-and-scope-changes","title":"Risk management and scope changes","body":"- Maintain a risk register : risk, probability, impact, owner, mitigation, contingency. - Common risks: unclear requirements, dependencies on other teams/vendors, key-person dependency, new technology, environments, data migration, performance, security/compliance. - Strategies: avoid , mitigate , transfer , accept . - Scope creep : every change goes through impact analysis (effort, timeline, risk) → agreement with the PO/client → change request or backlog reprioritisation. In fixed-price projects, formal change requests matter."},{"kind":"lesson","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"production-incidents-and-post-mortems","title":"Production incidents and post-mortems","body":"- Define severity levels (Sev1: full outage/revenue impact; Sev2: major feature down; Sev3: minor). - During an incident: an incident commander coordinates; separate roles for investigation and communication; focus on restoring service first (rollback, failover, feature flag off), root cause later; regular updates to stakeholders/status page. - Blameless post-mortem : timeline, impact, root cause(s) (5 Whys), what went well, what didn't, action items with owners and dates. - Track MTTR (mean time to restore) and change failure rate ; invest in monitoring, alerting, runbooks and safe deployments."},{"kind":"lesson","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"technical-decision-making-debt-and-quality","title":"Technical decision-making, debt and quality","body":"- Decide with criteria : requirements (functional + non-functional — performance, scalability, security, availability, cost), team skills, time to market, maintainability, vendor lock-in. - Use spikes/proofs of concept for uncertain choices; document with Architecture Decision Records (context, decision, alternatives, consequences). - Technical debt : make it visible (backlog items with impact), allocate capacity (e.g. 15–20% per sprint), pay down debt in areas that change often, avoid \"big rewrite\" unless justified. - Quality gates: code review standards, automated tests, CI checks, static analysis, Definition of Done. - Build vs buy: core differentiators → build; commodity → buy/open source."},{"kind":"lesson","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"hiring-and-building-teams","title":"Hiring and building teams","body":"- Define the role (must-have vs nice-to-have skills), structured interview with consistent questions and scoring rubric, realistic coding/design tasks, panel diversity, and fast feedback to candidates. - Hire for skills + learning ability + collaboration ; avoid \"culture fit\" as an excuse for bias — look for \"culture add\". - Onboarding plan: documentation, buddy, first-week small task in production, 30-60-90 goals. - Retention: growth opportunities, recognition, fair workload, good tooling, meaningful work, career conversations."},{"kind":"lesson","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"metrics-that-matter","title":"Metrics that matter","body":"- DORA : deployment frequency, lead time for changes, change failure rate, time to restore (failed deployment recovery time). - Flow : cycle time, throughput, WIP, blocked time. - Quality : escaped defects, incident count/severity, test coverage trend. - Team health : engagement surveys, attrition, on-call load. - Avoid misuse: never compare individuals by velocity, lines of code or commits — it destroys trust and encourages gaming (Goodhart's law: when a measure becomes a target, it ceases to be a good measure)."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1122","title":"What is the difference between a tech lead and an engineering manager?","body":"A tech lead owns technical direction for a team: architecture and design decisions, code quality, breaking down work, unblocking developers and mentoring — and still writes significant code. An engineering manager owns people and delivery: hiring, career growth, performance reviews, team health, process and cross-team coordination, with less hands-on coding. In smaller teams (and in many Indian IT services companies' \"team lead\" roles) one person does parts of both."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1123","title":"Explain Scrum roles, events and artifacts.","body":"Accountabilities: Product Owner (maximises value, owns and orders the Product Backlog), Scrum Master (coaches the team and organisation in Scrum, removes impediments), Developers (create the increment, own the Sprint Backlog). Events: the Sprint (container), Sprint Planning, Daily Scrum (15 min), Sprint Review, Sprint Retrospective. Artifacts with commitments: Product Backlog → Product Goal, Sprint Backlog → Sprint Goal, Increment → Definition of Done (2020 Scrum Guide)."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1124","title":"What is the difference between Agile and Waterfall?","body":"Waterfall is sequential — requirements, design, build, test, deploy — each phase completed before the next, with change being costly; it suits fixed, well-understood requirements and regulated contexts. Agile delivers in short iterations with working software each cycle, continuous feedback, and embraces change; it suits evolving requirements. Many enterprises use hybrids (fixed milestones with agile execution)."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1125","title":"What are story points and velocity?","body":"Story points are relative estimates of effort, complexity and uncertainty (often Fibonacci: 1, 2, 3, 5, 8, 13), agreed by the team with planning poker — not hours. Velocity is the average number of points a team completes per sprint, used to forecast how much to plan. Velocity is team-specific: don't compare teams or use it as a performance target."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1126","title":"Scrum vs Kanban — when would you use each?","body":"Scrum works well for product development where you can plan in fixed sprints with a stable team and regular reviews. Kanban suits continuous, unpredictable inflow like support, maintenance and operations: work is pulled through columns with WIP limits, measured by cycle time. Teams often combine them (\"Scrumban\") — e.g. sprints for features with a Kanban lane for production support."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1127","title":"How do you estimate a project or a large feature?","body":"Clarify scope and acceptance criteria; break it into small tasks (≤ 2–3 days) including testing, reviews, deployment and documentation; estimate with the people doing the work (planning poker or three-point estimates); add buffers for risks and unknowns (spikes for unclear areas); account for real capacity (meetings, support, leaves); state assumptions and dependencies explicitly; give a range rather than a single date; re-forecast as you learn and communicate changes early."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1128","title":"How do you delegate work in your team?","body":"I delegate outcomes with context: why it matters, what done looks like, constraints, deadline and check-in points. I match tasks to skills and growth goals — a stretch task for a junior with a senior pairing, critical-path work for experienced people — and adjust my involvement to their experience (directing for new members, delegating to experts). Work is tracked on the board, I stay available to unblock, and I avoid taking the hardest tasks myself all the time so the team grows and I don't become a bottleneck."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1129","title":"How do you mentor junior developers?","body":"Regular 1:1s and pairing sessions; clear coding standards and examples; code reviews that explain the why rather than just fixing things; gradually larger tasks with support (first a bug fix, then a small feature, then owning a module); encouraging questions and making it safe to make mistakes; sharing resources and certification paths; and celebrating progress publicly. I measure success by how independently they can deliver after a few months."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1130","title":"How do you handle a team member who is underperforming?","body":"Gather facts first, then talk privately and early with specific examples, and listen to understand the cause (unclear expectations, skill gap, personal issues, motivation, wrong role). Agree on a concrete improvement plan with support — training, pairing, smaller scoped tasks — and regular check-ins. Recognise improvements. If there's no progress after a fair period, involve my manager and HR for a formal plan, documenting everything and treating the person with respect throughout."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1131","title":"How do you resolve a conflict between two team members?","body":"Speak with each privately to understand their perspective and underlying concerns, then bring them together focused on facts and the shared goal. For technical disagreements, agree criteria and use data or a quick spike to decide; if still split, I make the call, explain the reasoning, record it (ADR) and ask both to commit. For personal friction, set expectations for respectful behaviour and follow up. I address conflict early, before it affects the team."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1132","title":"How do you handle scope changes requested in the middle of a sprint?","body":"Protect the Sprint Goal. I acknowledge the request, assess urgency and impact with the Product Owner: if it's truly critical (production issue, regulatory), we swap out work of similar size and make the trade-off visible; otherwise it goes into the backlog for the next sprint planning. For client projects, significant changes go through impact analysis and a change request covering effort, timeline and cost."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1133","title":"How do you report project status to stakeholders?","body":"Regular, concise updates: progress vs plan (with a RAG status), key achievements, risks and issues with mitigation plans, decisions needed from them, and next steps. I share bad news early with options and a recommendation, back statements with data (burnup charts, defect counts), tailor the detail to the audience (executives vs product owners), and keep a written record."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1134","title":"What do you do in a sprint retrospective that has become boring and repetitive?","body":"Change the format (Start/Stop/Continue, 4Ls, sailboat, timeline), focus on one or two impactful improvements rather than long lists, review whether previous action items were done (and why not), use data (cycle time, escaped defects, interruptions), rotate the facilitator, and make it safe to raise uncomfortable topics. If the same issues keep coming back, escalate the systemic blockers outside the team."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1135","title":"How do you handle technical debt?","body":"Make it visible as backlog items describing the business impact (slower delivery, incidents, security risk); prioritise debt in areas that change often or cause incidents; reserve regular capacity (e.g. 15–20% per sprint) or attach refactoring to related feature work (Boy Scout rule); prevent new debt with Definition of Done, reviews and automated quality gates; and avoid big-bang rewrites unless the case is very strong — prefer incremental Strangler Fig approaches."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1136","title":"How do you make architecture or technology decisions in a team?","body":"Start from requirements (including non-functional ones and constraints like budget, skills and timelines), list options, evaluate them against agreed criteria, run a spike or proof of concept for risky unknowns, involve the team and relevant experts, decide (and own the decision), and document it in an Architecture Decision Record with context, alternatives and consequences. Revisit decisions when context changes. I prefer reversible decisions made quickly and irreversible ones made carefully."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1137","title":"How do you measure your team's performance?","body":"At team level, never individuals by raw output: DORA metrics (deployment frequency, lead time, change failure rate, time to restore), flow metrics (cycle time, throughput, WIP), quality (escaped defects, incident trends), predictability (planned vs delivered), and team health (engagement, attrition, on-call load). Business outcomes — features adopted, customer issues resolved — matter most. I use metrics to find improvement opportunities, not to rank people."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1138","title":"How would you build and scale a new team from 3 to 10 developers?","body":"Define the team's mission and the roles needed (mix of seniorities and skills); set up a structured hiring process with a scorecard; create strong onboarding (docs, buddy, dev environment scripts, first-week deliverable); establish working agreements, coding standards, CI/CD and review practices before scaling; split into sub-teams or feature pods around 5–7 people with clear ownership as you grow; grow leaders internally (tech leads per pod); and keep communication channels clear (team rituals, ADRs, documentation)."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1139","title":"Your project is two weeks from the deadline and you realise it will be late by one week. What do you do?","body":"Verify the estimate with the team and find the cause. Inform stakeholders immediately — no surprises — with options: reduce scope (ship must-haves first, defer nice-to-haves), add focused help where it actually speeds things up (not late-stage new joiners on complex code — Brooks's law), remove distractions from the team, parallelise testing, or move the date. Give a recommendation, get a decision in writing, update the plan, and run a retrospective later on why the risk wasn't spotted earlier."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1140","title":"A critical production issue occurs on Friday evening. Walk me through how you handle it.","body":"Acknowledge and assess severity; assemble the right people (on-call, owners) and appoint an incident lead; open a communication channel and inform stakeholders with regular updates. Prioritise restoring service — roll back the last deployment, toggle a feature flag, fail over, scale up — before deep root-cause analysis. Once stable, monitor, then do a blameless post-mortem the next week with a timeline, root causes (5 Whys), and owned action items (tests, alerts, runbooks, safer deployments). Make sure people who worked late get time off."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1141","title":"The client keeps adding requirements without changing the deadline. How do you manage it?","body":"Make the impact visible: maintain a prioritised backlog with estimates, show the client what each new request displaces, and agree priorities together (MoSCoW: Must/Should/Could/Won't). Use a change-request process for contractual scope, protect the current sprint, and propose phased delivery — an MVP by the date, the rest in later releases. Document decisions and keep the relationship collaborative rather than confrontational."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1142","title":"Your best developer resigns in the middle of a critical release. What do you do?","body":"Have an honest conversation to understand the reasons — if it's fixable (role, growth, compensation) and appropriate, explore a counter-offer with my manager, but don't rely on it. Immediately plan the knowledge transfer: document their modules, pair them with others during the notice period, record walkthroughs, and review critical code together. Re-plan the release with stakeholders based on reduced capacity. Longer term, reduce single points of failure by rotating ownership, and look at retention across the team."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1143","title":"Two senior developers disagree strongly on using microservices versus a modular monolith for a new product. How do you decide?","body":"Bring the discussion back to requirements: team size, expected scale, deployment independence needs, domain boundaries, operational maturity, timeline and cost. Have each present trade-offs against those criteria; if uncertain, run a short spike. For most new products with one team, a well-structured modular monolith is simpler and can be split later along module boundaries. Decide, document the reasoning and the triggers that would make us revisit it in an ADR, and ask both to commit."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1144","title":"A team member is consistently working late and seems burned out. What do you do?","body":"Talk privately and with care: ask how they're doing and what's driving the extra hours (workload, unclear priorities, perfectionism, personal stress, fear of failing). Reduce or redistribute their load, clarify priorities, remove blockers, encourage time off and normal hours, and check the team's overall planning so this isn't systemic. Point them to company support (EAP) if appropriate, and follow up regularly."},{"kind":"question","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1145","title":"You are asked to lead a team working on a technology you don't know well. How do you approach it?","body":"Be honest about the gap and learn fast: study the architecture and fundamentals, pair with the team's experts and rely on them for detailed technical decisions, while I contribute leadership strengths — planning, unblocking, stakeholder management, quality practices. I'd get hands-on with small tasks to build credibility, use external help (docs, vendor support, other teams) and set myself a learning plan with milestones."},{"kind":"cheat","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"1","title":"Leadership answer pattern","body":"Context → my approach (principles) → concrete example (STAR) → result/metric → what I learned."},{"kind":"cheat","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"2","title":"Scrum quick facts","body":"Roles: PO · Scrum Master · Developers. Events: Sprint · Planning · Daily (15 min) · Review · Retro. Artifacts: Product Backlog (Product Goal) · Sprint Backlog (Sprint Goal) · Increment (DoD). Scrum Guide 2020."},{"kind":"cheat","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"3","title":"Planning tools","body":"INVEST stories · acceptance criteria · story points + planning poker · velocity · three-point/PERT (O + 4M + P)/6 · MoSCoW · risk register · RAG status."},{"kind":"cheat","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"4","title":"People tools","body":"1:1s · SBI feedback · situational leadership (direct → coach → support → delegate) · Tuckman (form, storm, norm, perform) · psychological safety · PIP as last resort."},{"kind":"cheat","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"5","title":"Delivery tools","body":"Definition of Done · WIP limits · change requests · ADRs · blameless post-mortems (5 Whys) · DORA metrics · tech-debt budget 15–20%."},{"kind":"cheat","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"6","title":"Phrases that work","body":"\"Here are three options and my recommendation.\" · \"What will we drop to add this?\" · \"Disagree and commit.\" · \"Let's restore service first, then find root cause.\" · \"What does success look like for you?\""},{"kind":"cheat","course_slug":"leadership","course_title":"Team Lead, Managerial & Agile Interview","ref":"7","title":"Avoid","body":"Blaming the team · hero culture · comparing individuals by velocity · hiding bad news · promising dates without the team's estimate."},{"kind":"course","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"","title":"Career Gaps, Job Changes & Salary Negotiation","body":"Explaining career gaps, layoffs, frequent job changes, domain/tech switches and freelancing; understanding CTC and offers (India and Taiwan), researching market pay, answering expected-salary questions, negotiating, counter-offers, offer comparison and resignation etiquette. Two topics make many candidates nervous: gaps or unusual career moves , and talking about money . Both are normal parts of hiring, and both go well when you prepare honest, short, confident answers. Principles: - Honesty — background verification checks employment dates, designations and sometimes salary. Never fake experience, payslips or relieving letters (it's grounds for offer withdrawal or termination, and fake documents can be a criminal offence). - Brevity + forward focus — explain a gap in 2–3 sentences, then move to what you learned and why you're ready now. - Data-driven negotiation — research the market, know your numbers, negotiate the whole package, stay polite. How expectations have changed: Period Shift --- --- Before 2020 Gaps often viewed with suspicion; long tenures valued 2020–2021 COVID-19 layoffs and caregiving made gaps common and more accepted; remote work expanded 2021–2022 \"Great Resignation\"/talent shortage — big hikes and counter-offers in tech 2022–2024 Large tech layoffs worldwide; LinkedIn added a \"Career break\" option (2022) to profiles 2023–2025 Pay-transparency laws spread (several US states; EU Pay Transparency Directive adopted 2023, to apply from 2026); skills-based hiring; more scrutiny of moonlighting in India 2025–2026 AI-related restructuring; more contract/freelance work; hiring focused on proven skills and recent hands-on projects Job change lifecycle: 1. Decide why you're moving and what you want (role, tech, pay, location). 2. Update resume/LinkedIn (consistent dates; career break entry if relevant). 3. Research market pay for your role, level, location and company type. 4. Apply / get referrals → interviews. 5. Salary discussion (recruiter screen and/or HR round). 6. Offer (verbal → written) → review CTC breakup and terms. 7. Negotiate (once, with justification) → final offer. 8. Accept in writing → resign professionally → serve notice / buyout → handle counter-offer → handover. 9. Collect relieving/experience letters, final settlement (and PF transfer in India) → join → background verification. Gap explanation lifecycle: acknowledge → reason (brief) → what you did during the gap (learning, projects, certifications, freelancing, caregiving) → proof → readiness and commitment. - Salary data : AmbitionBox, Glassdoor, Levels.fyi (product companies), LinkedIn Salary, Naukri/Instahyre insights (India); 104 / 1111 / Yourator / CakeResume salary info and government statistics (Taiwan); recruiter conversations; peers. - CTC calculators (in-hand salary calculators for India; Taiwan net-pay calculators for labour/health insurance). - Offer comparison spreadsheet (see lesson). - Portfolio proof for gaps : GitHub, deployed projects, certifications (AZ-204, AZ-900, etc.), courses, blog posts. - LinkedIn \"Career break\" entry type."},{"kind":"lesson","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"explaining-a-career-gap","title":"Explaining a career gap","body":"Formula: Reason (1 sentence) → What I did (proof) → Why I'm ready now. Common honest reasons: layoff/restructuring, health (no details needed), family/caregiving, relocation (e.g. moving countries), higher studies or exam preparation, starting a business/freelancing, visa or work-permit waiting period, deliberate upskilling, burnout recovery. Layoff: \"My position was eliminated in a company-wide restructuring in March. Since then I completed the AZ-204 certification and built an order-management API with .NET 10, EF Core and Azure Container Apps — it's on my GitHub. I'm now looking for a stable, long-term role.\" Family: \"I took 10 months off to care for a family member. That's fully resolved now. During the last three months I refreshed my skills — I built a React + ASP.NET Core project and revised SQL Server performance tuning — and I'm ready to commit full-time.\" Relocation: \"I relocated to Taiwan and waited for my work authorisation. I used the time to study cloud architecture and contribute to an open-source project, and I'm fully eligible to work now.\" Don'ts: don't lie or invent a company; don't over-share medical or personal details; don't sound apologetic or bitter; don't leave the gap unexplained on your resume if it's longer than ~6 months — a one-line \"Career break: upskilling in Azure and React (projects on GitHub)\" helps."},{"kind":"lesson","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"frequent-job-changes-short-stints-and-layoffs","title":"Frequent job changes, short stints and layoffs","body":"- Short stints : give the reason briefly and show a pattern of growth, not escape. \"My first company was acquired and the project shut down after 8 months; at my second job I've been 3 years and led two releases.\" - Contract roles : label them clearly (\"Contract — 6 months\") so they don't look like quitting. - Many changes : emphasise what each move added (skills, scope) and why you now want stability — and mean it. - Layoffs : say it plainly — it's common and not a performance judgement. Offer references. - Terminated for performance : be honest if asked directly, take responsibility without excessive detail, show what you learned and changed."},{"kind":"lesson","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"switching-technology-domain-or-role","title":"Switching technology, domain or role","body":"- Tech switch (e.g. .NET → React, support → development, manual testing → automation, data → cloud): show evidence of the new skill — projects, certifications, internal contributions — and connect transferable skills. - Domain switch (banking → healthcare): highlight domain-agnostic strengths (data handling, compliance awareness, client communication) and a learning plan. - Service company → product company : product companies focus more on DSA/coding rounds and system design; prepare those explicitly (see Coding Practice). - Developer → lead/manager : show examples of informal leadership (mentoring, reviews, running stand-ups). - Freelancing → full-time : present freelancing as professional work (clients, deliverables, outcomes); explain why you want a team environment now; confirm no conflict of interest going forward."},{"kind":"lesson","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"resume-and-background-verification-honesty","title":"Resume and background verification honesty","body":"- Keep dates, titles and companies consistent across resume, LinkedIn and application forms. - In India, background verification commonly checks previous employment (HR confirmation, relieving letters), education, address, criminal records and sometimes the UAN/EPFO service history, which shows actual employment periods. Overlapping employment (moonlighting) becomes visible. - Don't inflate CTC: some companies ask for payslips or Form 16 / bank statements; a mismatch can cancel the offer. - If something is complicated (company closed, no relieving letter), tell HR upfront and offer alternatives (offer letter + payslips + bank statements + manager reference)."},{"kind":"lesson","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"understanding-an-offer-india-ctc-fixed-variable-in-hand","title":"Understanding an offer (India: CTC, fixed, variable, in-hand)","body":"CTC (Cost to Company) is the total annual cost to the employer — not what you receive monthly. Component Notes --- --- Basic salary Often 40–50% of fixed pay; drives PF and gratuity HRA House rent allowance (tax-exempt portion under the old tax regime if you pay rent) Special/other allowances Taxable balancing component Variable pay / performance bonus Paid based on company and individual performance — not guaranteed Employer PF contribution 12% of basic (often capped on ₹15,000 basic) — part of CTC but goes to your PF account Gratuity Typically 4.81% of basic, payable after 5 years of continuous service (Payment of Gratuity Act) Insurance (health, term) Group policies; sometimes included in CTC Joining bonus One-time; often clawed back if you leave within 12 months ESOPs / RSUs Equity with a vesting schedule (e.g. 4 years with a 1-year cliff) Retention bonus, relocation, notice buyout Negotiable extras In-hand (take-home) = fixed monthly gross − employee PF (12% of basic) − professional tax (state-dependent, e.g. ₹200/month in several states) − income tax (TDS). Ask HR for the CTC breakup and calculate in-hand under the new vs old tax regime . Typical hike expectations when switching in Indian IT vary widely with skills, demand and company type — research rather than assume a fixed percentage."},{"kind":"lesson","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"understanding-an-offer-in-taiwan","title":"Understanding an offer in Taiwan","body":"- Salaries are quoted monthly (月薪) — annual pay is usually 12 months + bonuses . Many companies pay a year-end bonus (年終獎金) and some pay festival bonuses or profit sharing (員工分紅); these vary widely and aren't guaranteed by law — ask how many months were actually paid in recent years. - Mandatory labour insurance and national health insurance — employee contributes a portion, employer the rest. - Labour pension (new system): employer contributes at least 6% of monthly wage to your individual pension account; you may voluntarily add up to 6% (tax-deductible). - Statutory minimum wage for 2026: NT$29,500/month (adjusted yearly; verify current figures). - Foreign professionals: employer-sponsored work permits usually require a minimum monthly salary for white-collar roles (commonly cited as NT$47,971, but check the Ministry of Labor's current rules); the Taiwan Employment Gold Card is an alternative open work permit for qualified professionals. - Ask about: base salary, guaranteed months, year-end bonus history, annual leave (statutory minimums based on seniority), overtime policy, remote work, probation (試用期), and relocation/visa support."},{"kind":"lesson","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"researching-your-market-value","title":"Researching your market value","body":"1. Define your profile: role, years of relevant experience, key skills (e.g. .NET + Azure + SQL), location, company type (service vs product vs startup vs MNC/GCC). 2. Collect data from several sources (salary sites, recent offers of peers, recruiters, job ads with salary ranges — common in Taiwan on 104). 3. Build a range : market low / median / high for your profile. 4. Decide your numbers: - Walk-away (minimum you'd accept, considering current pay, cost of living, risk). - Target (realistic for market and your strengths). - Anchor (what you'll state — at or slightly above target, justified). 5. Consider total compensation, not only base: bonus, equity, benefits, learning, commute/remote, stability."},{"kind":"lesson","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"answering-what-is-your-current-expected-salary","title":"Answering \"What is your current/expected salary?\"","body":"- Current salary : answer truthfully if asked (it can be verified); you may add context (\"My current fixed is ₹14 LPA plus variable; my expectation is based on the role and market, not just my current pay\"). In some regions, asking about salary history is restricted by law — know your local rules. - Expected salary : give a researched range or a number with justification, ideally after you understand the role. \"Based on the scope of this role, my experience with .NET microservices on Azure and current market data for similar roles in Bengaluru, I'm looking for a fixed component in the range of ₹24–27 lakhs. I'm flexible depending on the overall package, including variable pay and growth opportunities.\" - Early in the process you can defer politely: \"I'd like to learn more about the role and responsibilities first, but I can share that my expectation is in line with market rates for a senior .NET engineer.\" - Don't give a number far below market out of fear, and don't anchor unrealistically high without justification."},{"kind":"lesson","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"negotiating-the-offer","title":"Negotiating the offer","body":"Steps: 1. Thank and show enthusiasm — they should know you want to join. 2. Ask for time to review the written offer and CTC breakup (24–72 hours is reasonable). 3. Identify gaps vs your target and the market. 4. Make one clear, justified request — by phone/video if possible, followed up in email. \"Thank you — I'm excited about the role and the team. Having reviewed the offer, the fixed component is about 12% below what I'm seeing for similar senior roles, and below another offer I'm considering. Given my Azure and payments experience that you highlighted in the interviews, would it be possible to bring the fixed pay to ₹26 lakhs? If that's difficult on base, a joining bonus or an earlier performance review would also help.\" 5. Negotiate the package , not just base: joining bonus, notice-period buyout, relocation, designation/level, ESOPs, remote days, review timing (e.g. revision after 6 months), learning budget, start date. 6. Get the final offer in writing before resigning. 7. Know when to stop — after one or two rounds, decide. Don't bluff with fake offers."},{"kind":"lesson","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"comparing-offers-and-counter-offers","title":"Comparing offers and counter-offers","body":"Offer comparison factors: fixed pay, variable (and its realistic payout), equity, benefits, role/level, tech stack and learning, team and manager, company stability/funding, work-life balance, commute/remote, location and cost of living, visa/relocation support, notice and bond terms. Counter-offers from your current employer: consider why you wanted to leave — money rarely fixes growth, culture or manager issues. Common risks: being seen as a flight risk, the raise coming from future increments, reasons for leaving remaining. If you accept a counter-offer, inform the new company promptly and politely. If you decline, thank your employer."},{"kind":"lesson","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"resignation-and-notice-period-etiquette","title":"Resignation and notice period etiquette","body":"- Resign only after you have a written offer (and ideally after background verification begins). - Tell your manager in person/video first , then send a short, positive resignation email with your last working day. - Offer a handover plan : documentation, knowledge-transfer sessions, finishing or reassigning tasks. - Serve the notice professionally; buyout or early release must be agreed in writing. - Collect: relieving letter, experience letter, final settlement, Form 16 (India), PF transfer via the UAN portal, and return company assets. - Never burn bridges — industries are small, and references matter."},{"kind":"question","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"1146","title":"I see a gap of a year in your resume. Can you explain it?","body":"Answer in three parts: reason, activity, readiness. Example: \"My role was affected by a restructuring in early 2025. I used the time to deepen my skills — I completed the AZ-204 certification and built a full-stack project with ASP.NET Core, React and Azure that's on my GitHub — and I also did a three-month freelance contract building APIs for a logistics client. I'm now fully ready and looking for a long-term role where I can contribute from day one.\" Keep it calm, factual and short, then move on."},{"kind":"question","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"1147","title":"What is your expected salary?","body":"Give a researched range tied to the role: \"For a senior .NET developer role with Azure responsibilities in Pune, market data and my experience put my expectation at ₹22–25 lakhs fixed. I'm open to discussing the full package, including variable pay and growth.\" If it's very early, you can ask to learn more about the role first, but don't avoid answering entirely if they insist."},{"kind":"question","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"1148","title":"What is your current CTC and why do you expect a big hike?","body":"State your current CTC honestly with its breakup (fixed vs variable). Justify the expectation with market value, expanded responsibilities in the new role, skills you bring (e.g. cloud, leadership), and competing offers if real. Example: \"My current CTC is ₹12 LPA, of which ₹10.5 is fixed. My current salary is below the market median because I've been with the company since joining as a fresher, while my responsibilities have grown to leading a module and owning CI/CD. The market range for this role is ₹18–22 LPA, which is the basis for my expectation.\""},{"kind":"question","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"1149","title":"Why did you change jobs so frequently?","body":"Explain briefly and show a positive pattern: \"My first role was a 10-month contract; the second company shut down its India development centre; since then I've been at my current company for three years and grown from developer to module lead. Now I'm looking for a long-term role where I can grow into a technical lead.\" Emphasise what you learned and your intention to stay."},{"kind":"question","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"1150","title":"Are you open to negotiation on the salary you mentioned?","body":"\"Yes, I'm flexible within reason. The role and growth matter to me as much as the number. If the fixed component needs to be lower, components like a joining bonus, a performance review after six months, or equity could balance it.\" This shows flexibility without abandoning your target."},{"kind":"question","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"1151","title":"You were laid off. Was it because of performance?","body":"\"No — it was part of a company-wide restructuring that affected about 20% of the engineering team after a client contract ended. My last review rated me 'exceeds expectations', and my manager is happy to give a reference. I've stayed active since — I completed a certification and built a project with the latest .NET.\" Only say this if it's true; offer references."},{"kind":"question","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"1152","title":"How do you justify switching from support/testing to development?","body":"Show evidence, not just interest: \"In my support role I wrote C tools and SQL scripts that automated incident triage, saving about 10 hours a week. Over the last year I built two applications with ASP.NET Core and React (on GitHub), completed a .NET certification, and contributed bug fixes to our internal product with my lead's approval. My production-support background helps me write more reliable, debuggable code.\""},{"kind":"question","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"1153","title":"We can offer only 15% above your current salary. Will you accept?","body":"Respond politely and with data: \"Thank you. I'm keen on this role. However, a 15% increase puts the offer below the market range for this position, and below another offer I'm considering. Would there be flexibility to reach ₹X fixed, or to add a joining bonus and a salary review after six months?\" If they can't move and you still want the job, decide based on the whole picture; if not, decline gracefully."},{"kind":"question","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"1154","title":"Do you have other offers?","body":"Be honest. If yes: \"Yes, I have one offer from a product company and I'm in final rounds with another. This role is my preferred option because of the team and the Azure work, so I'd like to see if we can align on the package.\" Don't invent offers — companies sometimes ask for proof, and it damages trust. If no: \"I'm in process with a couple of companies, but this role is a strong fit for me.\""},{"kind":"question","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"1155","title":"What is your notice period, and will you be able to join early?","body":"\"My notice period is 90 days. My company allows a buyout of up to 45 days, so I could join in about 45–60 days. If the buyout amount is a concern, would you be able to support it?\" Be accurate — commitments you can't keep damage trust."},{"kind":"question","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"1156","title":"How would you respond to a counter-offer from your current employer?","body":"Thank them, and evaluate against the reasons you wanted to leave — growth, technology, team, location — not only the money. If those reasons remain, decline respectfully: \"I appreciate the offer and everything I've learned here, but I've decided to take this new role for the learning opportunity. I'll make sure the handover is smooth.\" If you accept a counter-offer, inform the new employer immediately and courteously."},{"kind":"question","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"1157","title":"You receive a written offer below your expectation, but you really want the job. What do you do?","body":"Express enthusiasm and ask for time to review. Calculate the in-hand amount and compare with market data and your walk-away number. Then make one well-justified request covering the specific gap, and offer alternatives (joining bonus, earlier appraisal, a higher designation, a relocation allowance, remote days). If they can't move, decide consciously: accept if the role's learning, brand or stability is worth it, or politely decline. Either way, get the final terms in writing."},{"kind":"question","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"1158","title":"Background verification shows a mismatch in your previous employment dates. What should you do?","body":"Contact HR immediately and explain transparently — for example, the resume used the project start date while the official joining date was a month later, or a notice period was shortened. Provide documents (offer and relieving letters, payslips, PF/UAN service history). Small honest discrepancies can usually be resolved; deliberate misrepresentation usually leads to offer withdrawal. Prevent it by using official dates on your resume."},{"kind":"question","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"1159","title":"You were freelancing for two years. The interviewer worries you won't fit into a team. How do you answer?","body":"\"Freelancing taught me to own outcomes end to end — requirements, delivery, deployment and support — and to communicate directly with clients. I also worked in teams on most projects: for example, with a client's in-house developers using Git and pull requests, and with designers and QA. I'm moving to full-time because I want deeper long-term product ownership and to grow with a team. I've closed my freelance engagements, so there's no conflict of interest.\""},{"kind":"question","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"1160","title":"An HR person asks for your expected salary before the technical rounds, and the posting has no range. What do you say?","body":"Try to learn the band first: \"Could you share the budgeted range for this role? That will help me give a meaningful answer.\" If they insist, give a researched range with a qualifier: \"Based on what I understand about the role and the market for senior .NET engineers in this city, I'm looking at ₹24–28 lakhs fixed, depending on the responsibilities and total package.\" Avoid a single low number that anchors the whole negotiation."},{"kind":"cheat","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"1","title":"Gap answer formula","body":"Reason (1 line) → what I did (projects, certifications, freelancing, caregiving) → proof (GitHub, certificate) → ready and committed now. Never lie; keep it under 30 seconds."},{"kind":"cheat","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"2","title":"Salary research","body":"Profile (role, YOE, skills, city, company type) → 3+ data sources → range (low/median/high) → walk-away, target, anchor numbers."},{"kind":"cheat","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"3","title":"India offer terms","body":"CTC · fixed · variable · basic · HRA · special allowance · employer PF (12% of basic) · gratuity (after 5 years) · joining bonus (clawback) · ESOP/RSU vesting · in-hand = gross − PF − professional tax − TDS · old vs new tax regime."},{"kind":"cheat","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"4","title":"Taiwan offer terms","body":"Monthly salary × 12 + year-end bonus (not guaranteed) · labour + health insurance · employer pension ≥ 6% · probation · work permit / Gold Card · minimum wage 2026 NT$29,500/month (verify)."},{"kind":"cheat","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"5","title":"Negotiation steps","body":"Thank → ask time → compare with data → one clear justified ask → negotiate the package (bonus, buyout, review, level, remote) → get it in writing → decide."},{"kind":"cheat","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"6","title":"Phrases","body":"\"Based on market data for this role…\" · \"I'm flexible on the structure of the package…\" · \"Is there flexibility on the fixed component?\" · \"Could a joining bonus or an earlier review bridge the gap?\""},{"kind":"cheat","course_slug":"career-gaps-salary","course_title":"Career Gaps, Job Changes & Salary Negotiation","ref":"7","title":"Resignation checklist","body":"Written offer first · tell manager personally · short positive email · handover plan · relieving/experience letters · final settlement · PF transfer (UAN) · return assets · no burned bridges."},{"kind":"course","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"","title":"Company-wise Interview Preparation","body":"How interviews typically run at Indian IT services companies (TCS, Infosys, Wipro, HCLTech, Cognizant, Accenture, Capgemini, Tech Mahindra, LTIMindtree), global product companies (Microsoft, Amazon, Google, Oracle), consulting firms, GCCs, startups and Taiwan employers — with the most important questions and model answers. Every company type tests the same core skills — fundamentals, problem solving, project knowledge, communication — but with different emphasis and formats . Knowing the pattern helps you prepare the right material. Company type Typical emphasis --- --- Indian IT services (TCS, Infosys, Wipro, HCLTech, Cognizant, Accenture, Capgemini, Tech Mahindra, LTIMindtree) Fundamentals (OOP, C , SQL, .NET), project explanation, client communication, flexibility (shifts, relocation, technologies); aptitude tests for freshers Global product companies (Microsoft, Amazon, Google, Oracle, Adobe, Salesforce) Data structures and algorithms, system design (senior), behavioural/values interviews, high hiring bar Global Capability Centres (GCCs) (banks, retailers, manufacturers with Indian/Taiwan tech centres) Mix: strong fundamentals + domain + design + stakeholder skills Consulting / Big Four (Deloitte, EY, KPMG, PwC, Accenture consulting) Technical breadth, client-facing communication, case/scenario questions Startups Practical coding/take-home tasks, ownership, speed, full-stack breadth, culture Taiwan employers Hardware/semiconductor/electronics giants, software companies and foreign firms in Taipei; language requirements vary; work permit eligibility matters for foreigners Important: interview processes change frequently and differ by role, level and team. The patterns below are general and based on publicly shared information (company career pages and candidate reports). Always check recent candidate experiences (Glassdoor, AmbitionBox, LeetCode Discuss, Blind, PTT Tech Job for Taiwan) and ask the recruiter about the exact rounds. How company hiring has changed: Period Change --- --- 2000s Mass campus hiring by Indian IT services with written aptitude tests 2010s Online assessments (AMCAT, CoCubes, HackerRank, Codility); product companies standardise DSA + system design loops 2018–2020 National qualifier tests (e.g. TCS NQT launched 2018–2019); tiered fresher roles (e.g. TCS Ninja/Digital, Infosys Specialist Programmer, Wipro Elite, Cognizant GenC tiers) 2020–2022 Fully virtual interviews; hiring boom and high attrition; online proctored tests 2023–2024 Hiring slowdown, layoffs at many tech companies, longer processes; growth of GCCs in India 2025–2026 AI-assisted screening, stricter anti-cheating measures in online assessments, more emphasis on practical skills and AI tooling familiarity General end-to-end process (experienced hires): 1. Application / referral / recruiter outreach (LinkedIn, Naukri, Instahyre, 104 in Taiwan). 2. Recruiter screen: experience, skills, notice period, CTC, location. 3. Online assessment or technical screen (coding/MCQ) — more common for freshers and product companies. 4. 1–3 technical rounds (concepts, coding, project deep-dive, design). 5. Managerial / techno-managerial round. 6. HR round (behavioural, salary, joining date). 7. Offer → background verification → onboarding. Fresher campus/off-campus process (Indian IT services, typical): registration → online test (aptitude: quantitative, logical, verbal; programming MCQs; coding; sometimes communication/game-based) → technical interview → managerial/HR interview → offer → training (e.g. initial training programmes before project allocation). - Company career portals — official process and role names (TCS iBegin/NextStep, Infosys careers, Wipro careers, Cognizant careers, Accenture careers, Amazon.jobs, Microsoft careers, Google Careers). - Candidate reports : Glassdoor, AmbitionBox, LeetCode Discuss (company tags), GeeksforGeeks interview experiences, Blind, Reddit (r/developersIndia, r/cscareerquestions), PTT Tech Job and Dcard (Taiwan). - Practice : LeetCode (company-tagged lists require Premium), HackerRank, PrepInsta / IndiaBix (aptitude), this site's Coding Practice, SQL Server and Practice panels. - Values documents : Amazon Leadership Principles, Microsoft's culture (growth mindset), Google's hiring guidance — read them before interviews."},{"kind":"lesson","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"what-it-services-interviews-focus-on","title":"What IT services interviews focus on","body":"For experienced .NET developers (2–10 years), expect: 1. Self-introduction and current project — architecture, your role, technologies, team size, client, challenges. Prepare a whiteboard-level diagram. 2. C and OOP — four pillars, abstract class vs interface, overloading vs overriding, ref / out , string vs StringBuilder , value vs reference types, IEnumerable vs IQueryable , async/await, exception handling, collections, delegates/events. 3. ASP.NET Core / MVC / Web API — middleware, DI lifetimes, filters, routing, authentication (JWT), model binding/validation, IActionResult vs ActionResult<T , REST verbs and status codes. 4. Entity Framework / ADO.NET — code-first vs DB-first, migrations, loading strategies, AsNoTracking , N+1, transactions; ADO.NET objects. 5. SQL Server — joins, second-highest salary, duplicates, CTE, window functions, stored procedure vs function, indexes, DELETE vs TRUNCATE , normalisation, performance. 6. Frontend basics if full-stack — JavaScript, Angular/React fundamentals. 7. Azure/DevOps basics — App Service, Functions, Key Vault, CI/CD pipelines, Git. 8. Coding — simple programs (string reverse, palindrome, duplicates, Fibonacci, LINQ queries), sometimes on a shared editor or notepad. 9. Client-facing/scenario questions — handling production issues, changing requirements, working in shifts, communicating delays. 10. HR — notice period, relocation, salary, bond (for some fresher roles)."},{"kind":"lesson","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"fresher-hiring-patterns-typical-verify-current-details","title":"Fresher hiring patterns (typical, verify current details)","body":"- TCS — the TCS NQT (National Qualifier Test) is used for fresher hiring, with role tiers commonly known as Ninja and Digital (and Prime for the highest tier in recent drives). Interviews typically combine technical, managerial and HR discussions. - Infosys — fresher roles include Systems Engineer and higher tiers such as Digital Specialist Engineer and Specialist Programmer ; coding competitions such as HackWithInfy have been used as a hiring channel. - Wipro — Elite NLTH (National Level Talent Hunt) for freshers; online assessment + interviews. - Cognizant — fresher tracks named GenC , GenC Next , GenC Pro/Elevate (names change between years). - Accenture — online assessments covering cognitive abilities, technical MCQs, coding and a communication assessment, followed by an interview. - Capgemini — has used game-based aptitude tests alongside pseudo-code, English and technical assessments. - HCLTech, Tech Mahindra, LTIMindtree — online assessment + technical + HR, with role-specific variants. Common fresher topics: aptitude, any one programming language, OOP, DBMS/SQL, OS basics, computer networks basics, final-year project, and communication."},{"kind":"lesson","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"project-explanation-that-impresses","title":"Project explanation that impresses","body":"Structure (3–5 minutes): 1. Business context — client/domain, users, problem solved. 2. Architecture — frontend → API → services → database → integrations; hosting (Azure/on-prem); draw it. 3. Your role — modules you owned, decisions you made. 4. Tech stack — and why (e.g. \"Dapper for reporting queries because EF generated inefficient SQL\"). 5. A challenge — problem → investigation → solution → measurable result. 6. Process — Agile/Scrum, CI/CD, code reviews, testing. 7. What you'd improve. Expect drill-down questions on anything you mention — only mention what you can explain deeply."},{"kind":"lesson","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"amazon-leadership-principles-and-the-loop","title":"Amazon: Leadership Principles and the loop","body":"- Amazon evaluates candidates against its 16 Leadership Principles (Customer Obsession, Ownership, Invent and Simplify, Are Right A Lot, Learn and Be Curious, Hire and Develop the Best, Insist on the Highest Standards, Think Big, Bias for Action, Frugality, Earn Trust, Dive Deep, Have Backbone; Disagree and Commit, Deliver Results, Strive to be Earth's Best Employer, Success and Scale Bring Broad Responsibility). - Typical SDE process: online assessment (coding + work-style questions) → interview loop (commonly 4–5 interviews) mixing coding/DSA, system design (for SDE II and above) and behavioural questions mapped to LPs. One interviewer is often a Bar Raiser — an experienced interviewer from outside the hiring team who helps maintain the hiring bar. - Prepare 2 STAR stories per principle with metrics; expect deep follow-ups (\"What exactly did you do? What data did you use?\")."},{"kind":"lesson","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"microsoft-and-google-what-to-expect","title":"Microsoft and Google: what to expect","body":"Microsoft (typical, varies by team): recruiter screen → one or more technical screens → a loop of around 4–5 interviews covering coding (DSA), design (system/object-oriented design for experienced roles), and behavioural/collaboration questions. Culture emphasis: growth mindset , collaboration, customer focus. Knowledge of Azure/.NET helps for many teams but isn't always required. Google (typical): recruiter screen → technical phone/video screen → several interviews (often 4–5) covering coding/algorithms, system design (for experienced roles) and a Googleyness & Leadership behavioural interview. Interview feedback is reviewed by a hiring committee , followed by team matching. Coding is usually in a shared doc/editor without IDE autocomplete — practise writing clean code by hand. Common across these companies: arrays/strings, hash maps, two pointers, sliding window, trees/graphs (BFS/DFS), heaps, dynamic programming (more at Google), and design topics (URL shortener, rate limiter, chat system, news feed, distributed cache)."},{"kind":"lesson","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"system-design-basics-for-product-company-rounds","title":"System design basics for product-company rounds","body":"Framework (45 minutes): 1. Requirements — functional (features) and non-functional (scale, latency, availability, consistency). Ask questions. 2. Estimates — users, requests/second, storage growth. 3. API design — main endpoints. 4. High-level design — clients → load balancer → API services → cache → database → queues → workers → CDN. 5. Data model — SQL vs NoSQL, keys, indexes, partitioning/sharding. 6. Deep dive — the hardest part (e.g. generating unique short IDs, fan-out for feeds, rate limiting algorithm). 7. Bottlenecks and trade-offs — caching strategy, replication, consistency, failure handling, monitoring. Classic problems: URL shortener, rate limiter, notification system, chat (WebSockets), news feed, file storage (Dropbox), ride-hailing matching, payment system (idempotency), search autocomplete."},{"kind":"lesson","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"consulting-firms-and-gccs","title":"Consulting firms and GCCs","body":"- Big Four / consulting (Deloitte, EY, KPMG, PwC, Accenture consulting): technical breadth plus client communication; scenario questions (\"The client is unhappy with delivery — what do you do?\"), estimation, presenting solutions; sometimes case-style discussions. Domain knowledge (banking, insurance, tax, audit, ERP) is valued. - GCCs (Global Capability Centres of banks, retailers, insurers, manufacturers in Bengaluru, Hyderabad, Pune, Chennai and elsewhere): rounds similar to product companies but often more practical — strong C /.NET/SQL, design, cloud, code quality and stakeholder management with global teams; behavioural rounds focused on ownership and collaboration across time zones."},{"kind":"lesson","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"startups","title":"Startups","body":"- Practical: take-home assignments (build a small API/UI in a few hours), live coding on real-world problems, code review exercises, product thinking. - They look for ownership, speed, breadth (frontend + backend + DevOps), learning ability and comfort with ambiguity. - Ask about: funding/runway, business model, team size, on-call expectations, equity (vesting, cliff, valuation), and work hours. - Show you can ship: GitHub projects, deployed demos, measurable impact."},{"kind":"lesson","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"interviewing-with-taiwan-employers","title":"Interviewing with Taiwan employers","body":"- Major employers include semiconductor and electronics companies (TSMC, MediaTek, Foxconn/Hon Hai, ASUS, Acer, Quanta, Delta Electronics), software and internet companies (Trend Micro, Appier, Gogoro, LINE Taiwan/LY Corporation, Shopee Taiwan, KKCompany), and foreign multinationals' Taipei offices (Microsoft, Google Taiwan hardware teams, Amazon Web Services, NVIDIA and others). - Language : many local companies interview and work in Mandarin; English-only roles exist mainly in multinationals, startups with international teams and some R&D centres — filter job posts (e.g. \"English\" on 104/Yourator/CakeResume/LinkedIn). - Process : online application → HR phone screen → technical test or take-home → 1–3 interviews (team lead, manager, sometimes department head) → offer with monthly salary + bonus discussion. - Work authorisation : foreign professionals need an employer-sponsored work permit or a Taiwan Employment Gold Card ; be ready to state your status clearly. - Culture tips : punctuality, politeness and humility; prepare a short self-introduction; bring/attach transcripts or certificates if asked; follow up through the recruiter."},{"kind":"question","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"1161","title":"(IT services) Explain your current project and your role in it.","body":"Structure: business context → architecture → your role → tech stack → one challenge with a measurable result → process. Example: \"I work on a loan-origination system for a European bank. It's an Angular frontend calling ASP.NET Core Web APIs, with SQL Server and Azure Service Bus for integration with the credit-scoring service, hosted on Azure App Service. I own the document-verification module and the reporting APIs. A key challenge was slow PDF generation timing out under load; I moved it to a background worker with Service Bus and blob storage, cutting API response time from 25 seconds to under 1 second. We work in two-week sprints with Azure DevOps pipelines and mandatory code reviews.\""},{"kind":"question","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"1162","title":"(IT services) Why do you want to join a services company like ours?","body":"Mention exposure to multiple clients, domains and technologies; structured training and certifications; global delivery experience; career paths (technical or managerial); and the company's specific strengths (a major client in your domain, a cloud or AI practice, a location). Example: \"Working with global clients across banking and retail would broaden my domain knowledge. Your Microsoft cloud practice is strong, and your certification programmes would help me move towards solution architecture.\""},{"kind":"question","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"1163","title":"(IT services) Are you comfortable working in different shifts, technologies or locations?","body":"Answer honestly with any constraints: \"Yes, I'm comfortable with overlap with UK or US hours and occasional on-call support. I'm primarily a .NET developer but I've also worked on Angular and SSIS, and I'm open to learning what the project needs. I'd prefer Pune or Bengaluru, but I'm open to discussing other locations.\" Ask how often shifts rotate."},{"kind":"question","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"1164","title":"(Freshers) What happens in online assessments like TCS NQT or similar tests, and how do you prepare?","body":"These tests typically cover quantitative aptitude, logical reasoning, verbal ability, programming fundamentals and one or two coding problems, all under time pressure, with proctoring. Prepare with timed practice (aptitude books/sites, previous-year style questions), master one language for coding (input/output handling, strings, arrays), revise OOP, DBMS/SQL and OS basics, and read the official registration page for the current pattern, since sections change between years."},{"kind":"question","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"1165","title":"(Amazon) Tell me about a time you disagreed with your manager or team. (Have Backbone; Disagree and Commit)","body":"\"S: My manager wanted to ship a reporting feature by computing aggregates on every request. T: I believed it would overload the database at month-end. A: I gathered data — query costs and expected month-end traffic — and proposed pre-aggregating nightly with a fallback for today's data. He disagreed because of the timeline, so we agreed on a quick load test; the on-request version exceeded our latency target by 4×. R: We implemented my approach in 2 extra days; month-end reports stayed under 2 seconds. Had the test gone the other way, I'd have committed fully to his design.\" Show data, respect and commitment."},{"kind":"question","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"1166","title":"(Amazon) Tell me about a time you obsessed over a customer. (Customer Obsession)","body":"Pick a story where you went beyond the ticket to understand the user's real problem: \"Customers kept calling support about failed payments. Instead of just fixing the error message, I analysed 3 months of logs and found 40% of failures came from one bank's timeout. I added retries with idempotency keys and a clear status page for pending payments. Support calls on payments dropped by 60%.\" Quantify customer impact."},{"kind":"question","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"1167","title":"(Amazon) Tell me about a time you had to dive deep to solve a problem. (Dive Deep)","body":"\"Our API had random 5-second spikes. Dashboards showed nothing obvious, so I collected traces and found the spikes coincided with Gen 2 garbage collections caused by large JSON payloads (over 85 KB) landing on the Large Object Heap. I switched to streaming serialisation and paginated the responses. P99 latency dropped from 5.2 s to 300 ms.\" Show detailed investigation and data."},{"kind":"question","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"1168","title":"(Microsoft/Google) How do you approach a coding interview problem?","body":"Clarify requirements and constraints (input size, edge cases), talk through examples, state a brute-force solution with its complexity, optimise (hash map, two pointers, sorting, BFS/DFS, DP), write clean code while explaining, test with examples and edge cases, and state time and space complexity. Communicate throughout — interviewers evaluate problem solving and communication, not just the final answer."},{"kind":"question","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"1169","title":"(Product companies) Design a URL shortener.","body":"Requirements: shorten URLs, redirect fast, custom aliases, expiry, analytics; read-heavy (say 100:1). API: POST /urls → short code; GET /{code} → 301/302 redirect. ID generation: base62 encoding of a unique ID (from a distributed ID generator or a pre-allocated range per server) to avoid collisions, or random codes with collision checks. Storage: key-value or SQL table (code PK → long URL, created, expiry, owner); cache hot codes in Redis; CDN/edge for redirects. Scale: stateless app servers behind a load balancer, DB replication/sharding by code, async analytics via a queue. Discuss 301 vs 302 (caching vs analytics), abuse/malware checks and rate limiting."},{"kind":"question","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"1170","title":"(Consulting) The client says your team's delivery quality is poor. How do you respond?","body":"Listen first and gather specifics (which defects, which releases, impact). Acknowledge and share a data-backed analysis (defect trends, root causes — requirements gaps, rushed testing, environment issues). Propose a concrete improvement plan: stronger acceptance criteria, automated tests and code-quality gates, a UAT checklist, release readiness reviews, and weekly quality reporting. Agree on measurable targets and follow up. Keep it professional and collaborative, never defensive."},{"kind":"question","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"1171","title":"(Startups) You get a 4-hour take-home: build a small task-management API. What do you prioritise?","body":"Read the requirements carefully and clarify assumptions in a README. Deliver a working, clean core first: a well-structured ASP.NET Core API with validation, error handling (ProblemDetails), persistence (EF Core with SQLite for easy setup), and a few meaningful tests. Then add polish: Docker/compose to run it, OpenAPI docs, seed data, and notes on trade-offs and what you'd do with more time (auth, pagination, CI). Commit in small, clear steps. Quality and clarity beat feature count."},{"kind":"question","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"1172","title":"(Taiwan) Why do you want to work in Taiwan, and how do you handle the language?","body":"Give genuine reasons: Taiwan's strong technology and semiconductor ecosystem, the specific company's products, career growth, and quality of life. Be honest about language: \"I work professionally in English and my team communication would be in English; I'm learning Mandarin (currently basic) and I'm comfortable working with bilingual colleagues and tools.\" State your work-permit or Gold Card status clearly. Only apply for roles whose language requirements you can meet."},{"kind":"question","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"1173","title":"(GCC) How would you work effectively with a team spread across India, Europe and the US?","body":"Agree overlap hours for synchronous meetings and rotate inconvenient slots fairly; use asynchronous communication well (clear written updates, design docs, recorded demos, well-written tickets); document decisions (ADRs, wiki); use follow-the-sun handovers with checklists for support; be explicit about time zones in deadlines; build relationships with video calls and occasional visits; and respect cultural differences in communication styles."},{"kind":"question","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"1174","title":"You have interviews with a services company and a product company in the same week. How do you prepare differently?","body":"Common base: strong project explanation, C /.NET/SQL fundamentals, behavioural stories. Services company: emphasise breadth (C , ASP.NET Core, EF, SQL, Azure basics), client communication, flexibility, and classic coding programs. Product company: practise DSA problems by pattern (timed), system design for your level, and values-based behavioural stories (e.g. Amazon LPs), and write code without IDE help. Schedule the harder one later if possible, and use one as practice for the other."},{"kind":"question","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"1175","title":"You failed a round at a company you really wanted. What do you do next?","body":"Ask the recruiter politely for feedback (not always shared). Write down every question you were asked the same day and identify gaps. Create a focused plan (e.g. 4 weeks of DSA patterns or system design) and practise with mock interviews. Many companies allow re-applying after a cooling-off period (commonly around 6–12 months, depending on the company) — check the policy and re-apply stronger. Meanwhile, keep interviewing elsewhere for practice."},{"kind":"question","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"1176","title":"A recruiter from a big brand offers a role with a lower title and similar pay. Should you accept?","body":"Compare beyond the title: the actual responsibilities and level mapping (titles differ between companies — a \"Senior Engineer\" in one may equal \"Engineer II\" in another), learning opportunities, brand value for your career, team and manager, tech stack, stability, and growth path to the next level. Ask how levels map and what promotion timelines look like. Negotiate the level if your experience justifies it, with examples of scope you've handled."},{"kind":"cheat","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"1","title":"Prepare by company type","body":"Type Must prepare --- --- IT services Project explanation, C /OOP, ASP.NET Core, EF, SQL queries, basic programs, Azure/DevOps basics, flexibility answers Product (Amazon/Microsoft/Google) DSA by pattern, system design, behavioural stories (Amazon: 16 LPs), clean code without IDE Consulting / Big Four Breadth, client scenarios, communication, estimation, domain knowledge GCC Fundamentals + design + cloud + stakeholder skills across time zones Startup Take-home quality, full-stack breadth, ownership, shipping speed Taiwan Language requirements, work permit/Gold Card status, company research, polite and concise communication"},{"kind":"cheat","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"2","title":"Fresher tests (typical, verify yearly)","body":"TCS NQT (Ninja/Digital/Prime) · Infosys (Systems Engineer / Specialist Programmer / Digital Specialist Engineer, HackWithInfy) · Wipro Elite NLTH · Cognizant GenC tiers · Accenture cognitive + technical + coding + communication · Capgemini game-based + pseudo-code."},{"kind":"cheat","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"3","title":"Amazon LPs (16)","body":"Customer Obsession · Ownership · Invent and Simplify · Are Right, A Lot · Learn and Be Curious · Hire and Develop the Best · Insist on the Highest Standards · Think Big · Bias for Action · Frugality · Earn Trust · Dive Deep · Have Backbone; Disagree and Commit · Deliver Results · Strive to be Earth's Best Employer · Success and Scale Bring Broad Responsibility."},{"kind":"cheat","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"4","title":"Research sources","body":"Official careers pages · Glassdoor · AmbitionBox · LeetCode Discuss · GeeksforGeeks experiences · Blind · Reddit · PTT Tech Job (Taiwan) · recruiter."},{"kind":"cheat","course_slug":"company-wise","course_title":"Company-wise Interview Preparation","ref":"5","title":"Universal must-haves","body":"60–90 s introduction · project deep-dive with a diagram · 8–10 STAR stories · core fundamentals · coding patterns · 2–3 smart questions · researched salary range."}]