Domande colloquio C#/.NET backend con risposte

Milad Bonakdar
Autore
Preparati ai colloqui backend C#/.NET con domande pratiche su ASP.NET Core, EF Core, async, DI, API REST, test e architettura.
Introduzione
Per un colloquio backend C#/.NET devi saper spiegare come costruisci API con ASP.NET Core, mantieni efficiente l'accesso ai dati con EF Core, usi codice async senza bloccare thread e organizzi i servizi con la dependency injection. Le risposte solide collegano il concetto a un vero trade-off backend: performance, affidabilità, testabilità o manutenibilità.
Usa questa guida come checklist pratica. Rivedi le risposte brevi, poi allenati a trasformare ciascuna in un esempio concreto da un progetto, stage, esercizio tecnico o bug di produzione.
Fondamenti del linguaggio C#
1. Qual è la differenza tra struct e class in C#?
Risposta:
- Class: Un tipo di riferimento (allocato nell'heap). Quando si passa un oggetto class a un metodo, si passa un riferimento alla posizione di memoria. Le modifiche all'interno del metodo influenzano l'oggetto originale. Supporta l'ereditarietà.
- Struct: Un tipo di valore (allocato nello stack). Quando si passa uno struct, viene passata una copia dei dati. Le modifiche all'interno del metodo non influenzano lo struct originale. Non supporta l'ereditarietà (ma può implementare interfacce).
- Utilizzo: Utilizzare
structper strutture dati piccole e immutabili che rappresentano un singolo valore (comePoint,Color). Utilizzareclassper la maggior parte degli altri oggetti.
Rarità: Comune Difficoltà: Facile
2. Spiega async e await. Come aiutano con la scalabilità?
Risposta:
async e await permettono a un metodo di sospendersi mentre un'operazione di I/O è in corso e riprendere quando il Task termina.
- Meccanismo:
awaitnon crea un nuovo thread. Per chiamate a database, file o rete libera il thread della richiesta. - Scalabilità: Migliora il throughput degli endpoint ASP.NET Core legati a I/O, ma non rende più veloce il lavoro CPU-bound.
- Suggerimento: Cita
CancellationTokene metodi EF Core comeToListAsyncoSaveChangesAsyncquando parli di I/O verso il database.
Rarità: Molto Comune Difficoltà: Media
3. Cos'è l'Dependency Injection (DI) e come viene implementata in .NET?
Risposta: Dependency Injection è un modello di progettazione in cui le dipendenze di una classe vengono fornite dall'esterno anziché create internamente.
- In .NET: ASP.NET Core ha un contenitore DI integrato. Si registrano i servizi in
Program.cs(oStartup.csnelle versioni precedenti) e li si inietta tramite l'iniezione del costruttore. - Durate:
- Transient: Creati ogni volta che vengono richiesti.
- Scoped: Creati una volta per richiesta client (richiesta HTTP).
- Singleton: Creati la prima volta che vengono richiesti e condivisi da tutte le richieste successive.
Rarità: Molto Comune Difficoltà: Media
4. Qual è la differenza tra IEnumerable<T> e IQueryable<T>?
Risposta:
IEnumerable<T>: Esegue la query in memoria. Se utilizzato con un database (EF Core), recupera tutti i dati dal server alla memoria del client e poi li filtra. Ottimo per LINQ to Objects.IQueryable<T>: Esegue la query in remoto (ad esempio, sul server SQL). Costruisce un albero delle espressioni che viene tradotto in una query SQL. Il filtraggio avviene lato database, il che è molto più efficiente per grandi set di dati.
Rarità: Comune Difficoltà: Media
5. Cosa sono i Metodi di Estensione?
Risposta: I metodi di estensione consentono di "aggiungere" metodi ai tipi esistenti senza creare un nuovo tipo derivato, ricompilare o modificare in altro modo il tipo originale.
- Sintassi: Definiti come metodi statici in una classe statica. Il primo parametro specifica su quale tipo opera il metodo, preceduto dalla parola chiave
this. - Esempio: Aggiunta di un metodo
WordCount()alla classestring.
Rarità: Comune Difficoltà: Facile
ASP.NET Core e Architettura
6. Cos'è Middleware in ASP.NET Core?
Risposta: I middleware sono componenti software che vengono assemblati in una pipeline applicativa per gestire richieste e risposte.
- Pipeline: Ogni componente sceglie se passare la richiesta al componente successivo nella pipeline e può eseguire operazioni prima e dopo che il componente successivo viene invocato.
- Esempi: Autenticazione, Autorizzazione, Logging, Gestione delle eccezioni, Servizio di file statici.
- L'ordine è importante: L'ordine in cui il middleware viene aggiunto in
Program.csdefinisce l'ordine di esecuzione.
Rarità: Molto Comune Difficoltà: Media
7. Spiega la differenza tra .NET Core e .NET Framework.
Risposta:
- .NET Framework: L'implementazione originale, solo Windows. Matura, ma legata a Windows.
- .NET Core / .NET moderno: La linea successiva multipiattaforma e open source. Da .NET 5 la piattaforma si chiama di solito semplicemente
.NET; le versioni attuali includono .NET 10 LTS con C# 14. - Differenze chiave: .NET moderno è la scelta predefinita per nuove API backend perché supporta container Linux, versioni affiancate, funzionalità ASP.NET Core attuali e continui miglioramenti del runtime.
Rarità: Comune Difficoltà: Facile
8. Cos'è Kestrel?
Risposta: Kestrel è un web server multipiattaforma, open-source, event-driven che è incluso di default nei template ASP.NET Core.
- Ruolo: Ascolta le richieste HTTP e le passa all'applicazione.
- Utilizzo: Può essere eseguito standalone (edge server) o dietro un reverse proxy come IIS, Nginx o Apache. L'utilizzo di un reverse proxy è raccomandato per la produzione per gestire la sicurezza, il bilanciamento del carico e la terminazione SSL.
Rarità: Media Difficoltà: Media
9. Come gestisci la Gestione Globale delle Eccezioni in ASP.NET Core?
Risposta: Invece di blocchi try-catch in ogni controller, dovresti utilizzare middleware per la gestione globale delle eccezioni.
UseExceptionHandler: Middleware integrato che cattura le eccezioni, le registra e riesegue la richiesta in una pipeline alternativa (di solito puntando a una pagina di errore o a una risposta API).- Middleware personalizzato: Puoi scrivere middleware personalizzati per catturare le eccezioni e restituire una risposta di errore JSON standardizzata (ad esempio,
ProblemDetails).
Rarità: Comune Difficoltà: Media
Database ed Entity Framework
10. Cos'è Entity Framework Core (EF Core)? Code-First vs. Database-First?
Risposta: EF Core è un Object-Relational Mapper (ORM) per .NET. Consente agli sviluppatori di lavorare con un database utilizzando oggetti .NET.
- Code-First: Definisci prima le tue classi di dominio (entità) e EF Core crea/aggiorna lo schema del database in base a esse utilizzando le Migrazioni. Preferito per nuovi progetti.
- Database-First: Hai un database esistente ed EF Core genera le classi .NET (scaffolding) in base allo schema.
Rarità: Comune Difficoltà: Facile
11. Qual è il problema N+1 in EF Core e come lo risolvi?
Risposta: Il problema N+1 nasce quando recuperi una lista di entità e poi, dentro un ciclo, carichi una relazione per ogni elemento, generando molte query aggiuntive.
- Soluzione: Carica i dati correlati in modo intenzionale con
Include, include filtrati, proiezioni o caricamento esplicito. Evita lazy loading nei percorsi critici. - Esempio:
await context.Orders.Include(o => o.Customer).ToListAsync(); - Trade-off: Con più collection navigation valuta split query o proiezioni per evitare cartesian explosion e colonne inutili.
Rarità: Molto Comune Difficoltà: Media
12. Spiega il Repository Pattern. Perché usarlo con EF Core?
Risposta: Il Repository Pattern media tra i livelli di dominio e di mapping dei dati utilizzando un'interfaccia simile a una collection per accedere agli oggetti di dominio.
- Pro: Disaccoppia l'applicazione dalla specifica tecnologia di accesso ai dati (EF Core), semplifica l'unit testing (può mockare il repository) e centralizza la logica di accesso ai dati.
- Contro/Dibattito:
DbContextdi EF Core è già un'implementazione del Repository/Unit of Work pattern. L'aggiunta di un altro livello a volte può essere ridondante ("astrazione sull'astrazione").
Rarità: Comune Difficoltà: Difficile
API REST e Servizi Web
13. Quali sono i Verbi HTTP e il loro tipico utilizzo?
Risposta:
- GET: Recupera una risorsa. Sicuro e Idempotente.
- POST: Crea una nuova risorsa. Non Idempotente.
- PUT: Aggiorna/Sostituisce una risorsa esistente. Idempotente.
- PATCH: Aggiorna parzialmente una risorsa. Non necessariamente Idempotente (ma di solito lo è).
- DELETE: Rimuove una risorsa. Idempotente.
Rarità: Comune Difficoltà: Facile
14. Qual è la differenza tra 401 Unauthorized e 403 Forbidden?
Risposta:
- 401 Unauthorized: L'utente non è autenticato. Il client deve effettuare il login e riprovare. "Non so chi sei."
- 403 Forbidden: L'utente è autenticato ma non ha il permesso di accedere alla risorsa. "So chi sei, ma non puoi farlo."
Rarità: Comune Difficoltà: Facile
Testing e Best Practice
15. Qual è la differenza tra Unit Test e Integration Test?
Risposta:
- Unit Test: Testa una piccola unità di codice (di solito un metodo) in isolamento. Le dipendenze vengono mockate (utilizzando strumenti come Moq). Veloci e affidabili.
- Integration Test: Testa come diverse parti dell'applicazione lavorano insieme (ad esempio, endpoint API + Database). Più lenti ma verificano il comportamento effettivo del sistema.
Rarità: Comune Difficoltà: Facile
16. Come mocki le dipendenze negli Unit Test?
Risposta: Framework di mocking come Moq o NSubstitute vengono utilizzati per creare implementazioni fake di interfacce.
- Scopo: Isolare la classe in fase di test. Ad esempio, se si testa un
UserService, si mockaIUserRepositoryin modo da non colpire il database reale. - Esempio (Moq):
Rarità: Comune Difficoltà: Media
17. Cosa sono i principi SOLID? Fai un esempio di uno.
Risposta: SOLID è un acronimo per 5 principi di progettazione per rendere il software più comprensibile, flessibile e manutenibile.
- Single Responsibility Principle (SRP)
- Open/Closed Principle (OCP)
- Liskov Substitution Principle (LSP)
- Interface Segregation Principle (ISP)
- Dependency Inversion Principle (DIP)
- Esempio (DIP): I moduli di alto livello non dovrebbero dipendere dai moduli di basso livello. Entrambi dovrebbero dipendere da astrazioni. Questa è la base per la Dependency Injection.
Rarità: Comune Difficoltà: Difficile
18. Cosa sono Boxing e Unboxing? Perché evitarli?
Risposta:
- Boxing: Conversione di un tipo di valore (come
int) in un tipo di riferimento (object). Alloca memoria nell'heap. - Unboxing: Conversione del tipo di riferimento di nuovo nel tipo di valore.
- Prestazioni: Entrambe sono operazioni costose (allocazione di memoria, controllo del tipo). I generics (
List<T>) aiutano a evitare il boxing/unboxing rispetto alle collection più vecchie (ArrayList).
Rarità: Comune Difficoltà: Media
19. Cos'è l'istruzione using in C#?
Risposta:
L'istruzione using fornisce una sintassi conveniente che garantisce l'uso corretto degli oggetti IDisposable.
- Meccanismo: Chiama automaticamente il metodo
Dispose()sull'oggetto quando si esce dal blocco (anche se si verifica un'eccezione). - Sintassi moderna:
using var file = File.OpenRead("path");(non sono necessarie parentesi graffe, eliminato alla fine dello scope).
Rarità: Comune Difficoltà: Facile
20. Spiega il concetto di Middleware nel contesto del pattern "Chain of Responsibility".
Risposta: ASP.NET Core Middleware è un'implementazione classica del pattern Chain of Responsibility.
- Pattern: Una richiesta viene passata lungo una catena di gestori. Ogni gestore decide se elaborare la richiesta o passarla al gestore successivo nella catena.
- Applicazione: In .NET, il
RequestDelegaterappresenta il gestore successivo. I componenti middleware sono concatenati per formare la pipeline di richiesta.
Rarità: Non comune Difficoltà: Difficile


