C# Interview Questions and Answers

C# interviews usually start with language fundamentals (types, memory, OOP) and then move into LINQ, asynchronous programming and ASP.NET Core. Mid-level and senior candidates are expected to explain how the runtime behaves: garbage collection, dependency lifetimes and what really happens inside an await.

Usually asked in backend and full stack interviews, from intern / fresher to senior (5+ years).

Intern / Fresher

  1. Q1Intern / Fresher
    What is the difference between a value type and a reference type in C#?

    A value type variable holds its data directly and is copied on assignment, while a reference type variable holds a reference to an object, so assignment copies the reference and both variables see the same object.

  2. Q2Intern / Fresher
    What is the difference between string and StringBuilder in C#?

    A string is immutable, so every change creates a new string object, while StringBuilder is a mutable buffer that modifies its contents in place, making it much faster for repeated concatenation.

Junior (0-2 years)

  1. Q1Junior (0-2 years)
    What is the difference between const and readonly in C#?

    A const is a compile-time constant that must be assigned where it is declared, while a readonly field can be assigned at declaration or in the constructor, so its value can be decided at runtime.

  2. Q2Junior (0-2 years)
    What is the difference between ref and out parameters in C#?

    Both pass an argument by reference, but ref requires the variable to be initialised before the call, while out requires the method to assign a value before it returns.

  3. Q3Junior (0-2 years)
    What is the difference between an abstract class and an interface in C#?

    An abstract class can hold state, constructors and partial implementation but a class can inherit only one, while an interface defines a contract that a class can implement many of.

  4. Q4Junior (0-2 years)
    What is boxing and unboxing in C# and why does it affect performance?

    Boxing converts a value type to object by allocating it on the heap, and unboxing converts it back; both add allocations and casts, so avoid them in hot code paths.

  5. Q5Junior (0-2 years)
    What is LINQ in C# and what is deferred execution?

    LINQ (Language Integrated Query) lets you query collections, databases and XML with a consistent syntax, and deferred execution means a query does not run when you define it but when you enumerate the results.

Mid-level (2-5 years)

  1. Q1Mid-level (2-5 years)
    What is the difference between IEnumerable and IQueryable in C#?

    IEnumerable runs the query in memory using delegates, while IQueryable builds an expression tree that a provider such as Entity Framework translates into SQL, so filtering happens in the database.

  2. Q2Mid-level (2-5 years)
    What are transient, scoped and singleton service lifetimes in ASP.NET Core dependency injection?

    Transient services are created every time they are requested, scoped services are created once per HTTP request, and singleton services are created once and shared for the life of the application.

  3. Q3Mid-level (2-5 years)
    What is the difference between Task and Thread, and how does async/await work in C#?

    A Thread is an operating-system execution unit, while a Task represents an asynchronous operation scheduled on the thread pool; await releases the current thread while the operation is pending and resumes the method when it completes.

  4. Q4Mid-level (2-5 years)
    How does garbage collection work in C# and when should you use IDisposable?

    The .NET garbage collector automatically frees managed objects that are no longer reachable, organising them into generations 0, 1 and 2 so short-lived objects are collected cheaply, and IDisposable is used to release unmanaged resources such as files and connections promptly.

Senior (5+ years)

  1. Q1Senior (5+ years)
    How do you avoid deadlocks with async/await in C#?

    Use async all the way down instead of blocking on tasks with .Result or .Wait(), and in library code use ConfigureAwait(false) so continuations do not need to return to a captured context.