.NET Runtime & CLR quiz and interview questions
Every .NET interview has a few questions about what happens under the hood: how the CLR runs your code, how the garbage collector frees memory, and how threads, tasks and async/await really work. This quiz covers them with short, practical examples.
.NET Runtime & CLR: key concepts
- CLR and JIT
- The Common Language Runtime loads your assemblies, JIT-compiles their IL into native code, manages memory with the garbage collector and enforces type safety.
- Assemblies
- A compiled .dll or .exe containing IL code plus metadata (types, references, version). It's the unit of deployment and versioning.
- Garbage collection
- The GC frees objects nothing references any more. New objects start in generation 0; survivors move to 1 and 2, which are collected less often.
- Dispose vs Finalize
- Dispose releases resources now, when your code (or using) calls it. A finalizer runs later, whenever the GC gets to it — don't rely on it.
- Threads and tasks
- A thread is an OS-level worker. A Task is a higher-level promise of work that runs on the thread pool, returns results and composes with async/await.
- Thread safety
- When several threads change shared data, use lock, Interlocked or concurrent collections — otherwise updates are lost in race conditions.
All 36 .NET Runtime & CLR questions with answers
Try each one first, then open the answer. Making a class test? Use the test maker.
What does the CLR do?
- A. Compiles C# to JavaScript
- B. Runs .NET code: JIT compilation, memory management (GC) and type safety
- C. Hosts websites only
- D. Manages SQL databases
Show answer
B. Runs .NET code: JIT compilation, memory management (GC) and type safety — The Common Language Runtime is the engine that executes every .NET app, whatever language it was written in.
What is JIT compilation?
- A. Compiling C# while typing
- B. Converting IL into native machine code at run time
- C. A way to minify code
- D. Compiling SQL queries
Show answer
B. Converting IL into native machine code at run time — C# compiles to Intermediate Language (IL). The Just-In-Time compiler turns IL into CPU instructions the first time a method runs.
What is an assembly in .NET?
- A. A machine-code file
- B. A compiled .dll or .exe with IL code and metadata
- C. A folder of source files
- D. A NuGet feed
Show answer
B. A compiled .dll or .exe with IL code and metadata — Assemblies are the deployable units of .NET. Their manifest lists the version, culture and the other assemblies they depend on.
In .NET Framework, what is the GAC?
- A. A garbage collector setting
- B. The Global Assembly Cache — a machine-wide store for shared, strong-named assemblies
- C. A web cache
- D. A build tool
Show answer
B. The Global Assembly Cache — a machine-wide store for shared, strong-named assemblies — The GAC let several apps share one installed copy of a library. Modern .NET ships dependencies with each app instead.
How are CTS and CLS related?
- A. They're the same
- B. CTS defines all .NET types; CLS is the subset every .NET language must support so libraries work across languages
- C. CLS is for C++ only
- D. CTS is a compiler
Show answer
B. CTS defines all .NET types; CLS is the subset every .NET language must support so libraries work across languages — Stick to CLS-compliant public APIs (e.g. avoid unsigned types in public signatures) if your library must work from any .NET language.
What is reflection?
- A. Mirroring a UI
- B. Inspecting types and their members at run time, and creating or calling them dynamically
- C. Copying objects
- D. A debugging window
Show answer
B. Inspecting types and their members at run time, and creating or calling them dynamically — typeof(User).GetProperties() lists properties at run time. Serializers, ORMs and DI containers rely on reflection.
What is serialization?
- A. Running code in order
- B. Converting an object into a format such as JSON or XML so it can be stored or sent — and back again
- C. Numbering database rows
- D. Encrypting data
Show answer
B. Converting an object into a format such as JSON or XML so it can be stored or sent — and back again — JsonSerializer.Serialize(order) produces JSON for an API response; Deserialize turns JSON back into an Order object.
What does the garbage collector do?
- A. Deletes temp files
- B. Automatically frees memory used by objects that are no longer reachable
- C. Closes database connections
- D. Removes unused code
Show answer
B. Automatically frees memory used by objects that are no longer reachable — You don't call delete in C#. When no variable references an object any more, the GC reclaims its memory.
Which GC generation is collected most often?
- A. Generation 2
- B. Generation 1
- C. Generation 0
- D. All equally
Show answer
C. Generation 0 — Most objects die young, so gen 0 (new objects) is collected frequently and cheaply. Long-lived objects end up in gen 2.
What is the key difference between Dispose and a finalizer?
- A. None
- B. Dispose runs when your code calls it (deterministic); a finalizer runs whenever the GC decides
- C. Finalizers are faster
- D. Dispose frees managed memory
Show answer
B. Dispose runs when your code calls it (deterministic); a finalizer runs whenever the GC decides — Release files and connections in Dispose (via using). Finalizers are only a safety net for unmanaged resources.
Can you force a garbage collection?
- A. No
- B. Yes, with GC.Collect(), but it's rarely a good idea
- C. Only in debug builds
- D. Only for strings
Show answer
B. Yes, with GC.Collect(), but it's rarely a good idea — GC.Collect() exists, but the GC usually knows better; forcing it in production often hurts performance.
What is the difference between a process and a thread?
- A. They're the same
- B. A process has its own memory; threads run inside a process and share its memory
- C. Threads have their own memory
- D. A thread can contain processes
Show answer
B. A process has its own memory; threads run inside a process and share its memory — Each app runs as a process. It can have many threads working in parallel over the same memory.
Why prefer Task over creating a Thread yourself?
- A. Tasks are always faster
- B. Tasks use the thread pool, can return results and work with async/await
- C. Threads can't run in parallel
- D. Tasks never throw exceptions
Show answer
B. Tasks use the thread pool, can return results and work with async/await — new Thread() creates a dedicated OS thread. Task.Run reuses pool threads and gives you a Task<T> to await.
What is the main benefit of asynchronous I/O in a web API?
- A. Code runs on more CPUs
- B. Threads are freed while waiting for the database or network, so the server handles more requests
- C. Responses are smaller
- D. No exceptions
Show answer
B. Threads are freed while waiting for the database or network, so the server handles more requests — await on I/O returns the thread to the pool until the result arrives — great for throughput, not for CPU-bound work.
What does this print?
async Task<int> GetAsync() { await Task.Delay(10); return 5; } var t = GetAsync(); Console.Write("A"); Console.Write(await t);- A. 5A
- B. A5
- C. A
- D. Deadlock
Show answer
B. A5 — GetAsync starts and returns a pending task at the first await. "A" prints immediately, then await t waits and prints 5.
What does this print?
var tasks = new[] { Task.FromResult(1), Task.FromResult(2), Task.FromResult(3), }; int[] results = await Task.WhenAll(tasks); Console.WriteLine(results.Sum());- A. 1
- B. 3
- C. 6
- D. 123
Show answer
C. 6 — Task.WhenAll waits for all tasks and returns their results in order: 1 + 2 + 3 = 6.
What's wrong with this code?
int count = 0; Parallel.For(0, 1000, i => count++); Console.WriteLine(count);- A. Nothing — it prints 1000
- B. Race condition: threads overwrite each other, so it often prints less than 1000
- C. Parallel.For doesn't exist
- D. Infinite loop
Show answer
B. Race condition: threads overwrite each other, so it often prints less than 1000 — count++ is read-modify-write, not atomic. Use Interlocked.Increment(ref count) or a lock.
What does the lock statement guarantee?
- A. Code runs faster
- B. Only one thread at a time runs the locked block for the same lock object
- C. The object can't be modified
- D. No exceptions inside
Show answer
B. Only one thread at a time runs the locked block for the same lock object — lock (_sync) { ... } protects shared state. Keep the block short and never lock on this or a public object.
What is managed code?
- A. Code reviewed by a manager
- B. Code run by the CLR, with automatic memory management
- C. Code written in C++
- D. Code that only runs on servers
Show answer
B. Code run by the CLR, with automatic memory management — C# and F# are managed. Unmanaged code (native C/C++, Win32 handles) needs you to free resources yourself.
In library code, why use ConfigureAwait(false)?
- A. To run code synchronously
- B. So the continuation doesn't need the caller's synchronization context — avoiding overhead and some deadlocks
- C. To disable exceptions
- D. To make the task cancelable
Show answer
B. So the continuation doesn't need the caller's synchronization context — avoiding overhead and some deadlocks — Libraries don't need to resume on a UI thread. ASP.NET Core has no sync context, but shared libraries may be used from UI apps.
How does modern .NET (5+) differ from .NET Framework?
- A. It's Windows-only
- B. It's cross-platform and open source; .NET Framework runs only on Windows
- C. It can't build web apps
- D. It has no garbage collector
Show answer
B. It's cross-platform and open source; .NET Framework runs only on Windows — .NET Framework 4.8 is in maintenance. New projects use .NET 8/9+, which runs on Windows, Linux and macOS.
Where are objects created with new SomeClass() stored?
- A. On the stack
- B. On the managed heap
- C. In the GAC
- D. In the CPU cache only
Show answer
B. On the managed heap — Class instances live on the heap and are freed by the GC. Local value-type variables usually live on the stack.
What is IL (MSIL/CIL)?
- A. Machine code for x64
- B. The CPU-independent instruction set C# compiles to, later JIT-compiled to native code
- C. A database language
- D. A configuration format
Show answer
B. The CPU-independent instruction set C# compiles to, later JIT-compiled to native code — Every .NET language compiles to IL, which is why they can all run on the same runtime.
What replaced AppDomains for loading and unloading assemblies in modern .NET?
- A. Nothing
- B. AssemblyLoadContext
- C. The GAC
- D. Docker
Show answer
B. AssemblyLoadContext — .NET Core doesn't support creating extra AppDomains; plugins use AssemblyLoadContext (or separate processes).
What is a strong-named assembly?
- A. An assembly with a long name
- B. An assembly signed with a key pair, giving it a unique identity (name, version, culture, public key)
- C. An encrypted assembly
- D. A NuGet package
Show answer
B. An assembly signed with a key pair, giving it a unique identity (name, version, culture, public key) — Strong names were required for the .NET Framework GAC; they matter much less in modern .NET.
What is a NuGet package?
- A. A Windows installer
- B. A packaged .NET library (with its dependencies) you add to projects
- C. A database backup
- D. A Docker image
Show answer
B. A packaged .NET library (with its dependencies) you add to projects — dotnet add package Serilog downloads it from nuget.org and records it in the .csproj.
What is the difference between globalization and localization?
- A. None
- B. Globalization makes the app handle many cultures (dates, numbers); localization translates text into specific languages
- C. Localization is for servers
- D. Globalization means translation only
Show answer
B. Globalization makes the app handle many cultures (dates, numbers); localization translates text into specific languages — Formatting 1,234.50 vs 1.234,50 is globalization; resource files with Urdu text are localization.
What does this print?
var price = 1234.5m; Console.WriteLine(price.ToString("N2", new CultureInfo("en-US")));- A. 1234.5
- B. 1,234.50
- C. 1.234,50
- D. 1234.50
Show answer
B. 1,234.50 — N2 means number format with group separators and 2 decimals; en-US uses , for thousands and . for decimals.
How do you build a long-running background service in modern .NET?
- A. A console app with an infinite loop and no hosting
- B. The Worker Service template (BackgroundService), which can run as a Windows Service or Linux systemd service
- C. An ASP.NET page
- D. A Windows Forms app
Show answer
B. The Worker Service template (BackgroundService), which can run as a Windows Service or Linux systemd service — dotnet new worker gives you hosting, DI, logging and graceful shutdown.
Which objects go on the Large Object Heap?
- A. All classes
- B. Objects of about 85,000 bytes or more, like big arrays
- C. Only strings
- D. Static fields
Show answer
B. Objects of about 85,000 bytes or more, like big arrays — The LOH is collected with gen 2 and isn't compacted by default, so many large allocations can fragment memory — reuse buffers (ArrayPool).
Why call GC.SuppressFinalize(this) inside Dispose()?
- A. To run the finalizer sooner
- B. The object is already cleaned up, so the GC can skip the (costly) finalizer
- C. To force a collection
- D. It's required for all classes
Show answer
B. The object is already cleaned up, so the GC can skip the (costly) finalizer — Objects with finalizers survive an extra GC cycle; suppressing it after Dispose avoids that.
What is the thread pool?
- A. A database of threads
- B. A set of reusable worker threads that run tasks and callbacks without creating new threads each time
- C. A thread limit setting
- D. A UI thread
Show answer
B. A set of reusable worker threads that run tasks and callbacks without creating new threads each time — Task.Run, async continuations and ASP.NET Core requests all use pool threads.
What does this print?
var sw = Stopwatch.StartNew(); await Task.WhenAll(Task.Delay(1000), Task.Delay(1000)); Console.WriteLine(sw.Elapsed.TotalSeconds < 1.5);- A. True
- B. False
- C. 2
- D. Exception
Show answer
A. True — Both delays run at the same time, so WhenAll finishes after about 1 second, not 2.
What does Interlocked.Increment(ref count) guarantee?
- A. Nothing
- B. The read-add-write happens atomically, so concurrent threads don't lose updates
- C. It locks the whole object
- D. It makes count readonly
Show answer
B. The read-add-write happens atomically, so concurrent threads don't lose updates — It's faster than lock for simple counters.
What does this print (default compiler settings)?
int max = int.MaxValue; Console.WriteLine(max + 1);- A. 2147483648
- B. -2147483648
- C. OverflowException
- D. 0
Show answer
B. -2147483648 — Integer arithmetic is unchecked by default, so it wraps around to int.MinValue.
What does the checked keyword do?
- A. Validates input
- B. Makes integer overflow throw an OverflowException instead of wrapping
- C. Checks for null
- D. Locks a variable
Show answer
B. Makes integer overflow throw an OverflowException instead of wrapping — checked(max + 1) throws — useful for money and counters where silent wrap-around would be a bug.
More subjects
Need software for your business instead? I'm an AI automation & full-stack developer — see what I build.