๐Ÿ”ท
Backend Platform

.NET / ASP.NET Core

10 questions across 2 experience levels

Answer

.NET Framework is Windows-only, ships with the OS, and supports WinForms, WPF, and ASP.NET Web Forms. Modern .NET (.NET Core, then .NET 5/6/7/8+) is cross-platform (Windows, Linux, macOS), open-source, high-performance, and ships independently. For new projects, always use modern .NET. ASP.NET Core replaced ASP.NET MVC/Web API and runs on all platforms.

Code Example
// Modern .NET minimal API (Program.cs โ€” no Startup class needed)
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();
app.UseSwagger();
app.UseSwaggerUI();

// Minimal API endpoint โ€” no controller needed
app.MapGet("/users/{id}", (int id, UserService svc) =>
    svc.GetById(id) is { } user
        ? Results.Ok(user)
        : Results.NotFound());

app.Run();
๐Ÿ’ก Simple Analogy

.NET Framework is like an old Windows-only car โ€” powerful but can't leave Windows territory. Modern .NET is like a Tesla โ€” cross-platform, faster, regularly updated, and open-source. For any new project today, use modern .NET. Think .NET 8 or .NET 9 as your starting point.

Answer

async/await is C#'s syntax for writing asynchronous code that reads like synchronous code. When a method is marked async, it can use await to pause execution at an I/O-bound operation (HTTP call, DB query, file read) without blocking the thread. The thread is freed to do other work while waiting, then resumes when the awaited operation completes. This is critical for building scalable web APIs.

Code Example
// Controller using async/await for DB call
[ApiController, Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private readonly AppDbContext _db;
    public ProductsController(AppDbContext db) => _db = db;

    [HttpGet]
    public async Task<ActionResult<List<Product>>> GetAll()
    {
        // Await frees the thread while DB executes the query
        var products = await _db.Products
            .Where(p => p.IsActive)
            .OrderBy(p => p.Name)
            .ToListAsync();   // Entity Framework async method
        return Ok(products);
    }

    [HttpPost]
    public async Task<ActionResult<Product>> Create(Product product)
    {
        _db.Products.Add(product);
        await _db.SaveChangesAsync();
        return CreatedAtAction(nameof(GetAll), product);
    }
}
๐Ÿ’ก Simple Analogy

Without async/await: a waiter takes your order, goes to the kitchen, and STANDS THERE staring at the cook until the food is ready โ€” blocking every other customer. With async/await: the waiter takes your order, goes to the kitchen, then serves OTHER tables while your food cooks. When it's ready, they come back and serve you. Way more efficient.

Answer

LINQ (Language Integrated Query) is a set of extension methods on IEnumerable<T> and IQueryable<T> that lets you query, filter, transform, and aggregate data using a SQL-like syntax directly in C#. It works on any collection (arrays, lists, DB results via Entity Framework). Key methods: Where, Select, OrderBy, GroupBy, First/FirstOrDefault, Any, All, Count, Sum, Aggregate, ToList, ToDictionary.

Code Example
var employees = new List<Employee> { /* ... */ };

// Method syntax (more common in C#)
var seniorDevs = employees
    .Where(e => e.Role == "Developer" && e.YearsExp >= 5)
    .OrderByDescending(e => e.Salary)
    .Select(e => new { e.Name, e.Salary, e.Department })
    .Take(10)
    .ToList();

// Grouping with aggregate
var byDept = employees
    .GroupBy(e => e.Department)
    .Select(g => new {
        Department = g.Key,
        Count = g.Count(),
        AvgSalary = g.Average(e => e.Salary)
    })
    .OrderByDescending(x => x.AvgSalary);

// Query syntax (SQL-like โ€” less common)
var result = from e in employees
             where e.Role == "Manager"
             orderby e.Name
             select e;
๐Ÿ’ก Simple Analogy

Without LINQ, filtering a list means writing a foreach loop with if statements every single time. LINQ gives you reusable 'SQL for collections' โ€” filter with Where, transform with Select, sort with OrderBy, take the first match with First. Write less code, read it like English: 'get all active employees, sort by salary, take the top 5.'

Answer

Entity Framework Core (EF Core) is .NET's official ORM (Object-Relational Mapper). It maps C# classes (entities) to database tables, lets you write C# LINQ queries instead of SQL, and handles migrations (schema changes). The DbContext is the main class you work with โ€” it represents the database session. EF Core supports SQL Server, PostgreSQL, SQLite, MySQL, and others.

Code Example
// 1. Define entity
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public decimal Price { get; set; }
    public bool IsActive { get; set; } = true;
}

// 2. DbContext
public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> opts) : base(opts) {}
    public DbSet<Product> Products => Set<Product>();
}

// 3. CRUD in a service
public class ProductService(AppDbContext db)
{
    public async Task<List<Product>> GetAllAsync() =>
        await db.Products.Where(p => p.IsActive).ToListAsync();

    public async Task<Product?> GetByIdAsync(int id) =>
        await db.Products.FindAsync(id);

    public async Task CreateAsync(Product p)
    {
        db.Products.Add(p);
        await db.SaveChangesAsync();
    }

    public async Task DeleteAsync(int id)
    {
        var p = await db.Products.FindAsync(id);
        if (p != null) { db.Products.Remove(p); await db.SaveChangesAsync(); }
    }
}
๐Ÿ’ก Simple Analogy

Writing raw SQL in your C# code is like speaking a foreign language every time you need data. EF Core is your translator โ€” you write C# and it generates the SQL for you. You define 'Product' as a class, EF creates the 'Products' table. You write LINQ, EF writes the SQL query. Migrations track your schema changes like Git tracks code changes.

Answer

Value types (struct, int, double, bool, DateTime, enum) store their data directly on the stack. Assigning a value type creates a COPY. Reference types (class, string, arrays, interfaces) store a reference (pointer) on the stack to the actual data on the heap. Assigning a reference type copies the reference โ€” both variables point to the same object. This distinction matters for performance and for understanding mutation behavior.

Code Example
// Value type โ€” copy on assignment
int a = 10;
int b = a;   // b is a copy
b = 20;      // a is still 10 โœ“

// Struct is also a value type
Point p1 = new Point(1, 2);
Point p2 = p1;  // full copy
p2.X = 99;      // p1.X is still 1 โœ“

// Reference type โ€” reference copied, same object
var list1 = new List<int> { 1, 2, 3 };
var list2 = list1;  // both point to same list!
list2.Add(4);
Console.WriteLine(list1.Count);  // 4 โ€” list1 was also changed!

// String is a special reference type โ€” immutable
string s1 = "hello";
string s2 = s1;
s2 += " world";  // creates a NEW string โ€” s1 unchanged โœ“
๐Ÿ’ก Simple Analogy

Value types are like writing a phone number on paper โ€” if you photocopy the paper, you get a completely independent copy. Reference types are like a shared Google Doc โ€” you can give multiple people the link, but everyone's editing the SAME document. Change it through one link and everyone sees it. Strings are special: they look like shared docs but are actually immutable โ€” every edit creates a new document.