377 questions for senior .NET engineer interviews, each with a 30-second answer, the full answer, a deep dive, the follow-ups interviewers ask next, and real-world production problems.
Debugging Release-only bugs: the usual causes (removed debug-only code, JIT optimisations exposing races and non-volatile reads, shortened object lifetimes, timing), a systematic investigation with Release builds, logs, dumps and symbols, and preventing recurrence.
Build items for files: Compile, None, Content and EmbeddedResource, CopyToOutputDirectory and CopyToPublishDirectory, embedded resource naming and LogicalName, reading with GetManifestResourceStream, .resx localisation, and when to embed versus copy.
The .NET analyser ecosystem: built-in CA code quality analysers and IDE code style analysers, AnalysisLevel and AnalysisMode, EnforceCodeStyleInBuild, .editorconfig severities, third-party analyser packages, suppressions, and rolling stricter rules out to a team.
Adopting nullable reference types at scale: what <Nullable> does, annotations and warnings, flow analysis and attributes, a project-by-project or file-by-file migration plan, handling public APIs and EF Core, and making nullable warnings errors.
A code review of warning policy: TreatWarningsAsErrors versus WarningsAsErrors and WarningsNotAsErrors, NoWarn versus severities in .editorconfig, CI-only versus local enforcement, AnalysisLevel pinning, and ratcheting a legacy codebase to zero warnings.
Diagnosing slow and non-incremental builds: capturing binary logs with -bl, reading them in the MSBuild Structured Log Viewer, finding slow targets, tasks and analysers, spotting broken incrementality, and fixes such as Inputs/Outputs, caching and build server settings.
The full journey of .NET code: Roslyn compiles C# to IL, the runtime loads the assembly, the JIT (with tiered compilation and Dynamic PGO) or an AOT compiler turns IL into machine code, and the CPU runs those instructions.
Positional number systems (base 2, 10 and 16), converting between them by hand and in C#, and why hex is the natural way to read bytes, memory addresses, colours, hashes and GUIDs.
Bits, bytes and two's complement; the sizes and ranges of C# numeric types; unchecked versus checked overflow; and bitwise operations and flags enums.
Why text needs an encoding, what ASCII covers and where it stops, how Unicode assigns code points, and how code points, code units, bytes and user-perceived characters (grapheme clusters) differ.
How UTF-8 and UTF-16 encode code points, surrogate pairs, why .NET strings are UTF-16 internally, when UTF-8 is used, and how to count, slice and limit text correctly with Rune and StringInfo.
A practical debugging walkthrough for mojibake and replacement characters: reading the bytes in hex, identifying UTF-8 versus Windows-1252 and double encoding, the BOM and Excel, and fixing both export and import paths in .NET.
Big-endian versus little-endian byte order, which platforms and protocols use which, network byte order, and the .NET APIs (BinaryPrimitives, BinaryReader, BitConverter, Guid) that handle byte order explicitly or implicitly.
A code review that combines encoding and endianness: ASCII data loss, truncating by chars instead of bytes, splitting surrogate pairs, BitConverter's machine byte order, missing validation, and an allocation-free rewrite with BinaryPrimitives and UTF-8.
A tour of CPU architecture for software engineers: cores and hardware threads, the register file, the ALU and other execution units, the control unit, the cache hierarchy and the clock, and why each matters for .NET performance.
The instruction cycle (fetch, decode, execute, memory access, write-back), the instruction pointer, how jumps, calls and returns change the flow, and how to read a few lines of JIT-generated x64 or Arm64 assembly.
Instruction pipelining, superscalar issue, out-of-order execution with register renaming and the reorder buffer, the hazards that stall pipelines (data dependencies, branches, cache misses), and how dependency chains show up in .NET code.
How CPUs predict conditional and indirect branches, what a misprediction costs, the classic sorted-versus-unsorted example, branchless techniques, how the .NET JIT uses conditional moves and Dynamic PGO, and how to measure mispredictions.
Spatial and temporal locality, cache lines and hardware prefetching, row-major layout of C# multidimensional arrays, arrays of structs versus arrays of references, struct-of-arrays layouts, and benchmarking the effects.
Cache coherence and why two threads writing different variables on the same cache line slow each other down, how to recognise and measure false sharing, and fixes: thread-local accumulation, padding, and avoiding shared writes.