Mis à jour le

🟣
Intermediaire 20 questions • C#

Questions C# et .NET

20 questions C#/.NET pour les entretiens. LINQ, async/await, dependency injection, Entity Framework et ASP.NET Core.

1. Quelle est la différence entre une classe et une struct en C# ?

Une classe est un type référence alloue sur le tas (heap), supporte l'héritage et peut être null. Une struct est un type valeur alloue sur la pile (stack), ne supporte pas l'héritage (mais implemente des interfaces) et ne peut pas être null (sauf Nullable). Les structs sont copiees par valeur lors de l'affectation. Utilisez une struct pour des petits objets immuables (Point, Color, DateTime). Utilisez une classe pour des objets complexes avec un comportement riche. Les structs evitent la pression sur le garbage collector car elles ne nécessitent pas d'allocation heap.

2. Expliquez le fonctionnement du garbage collector en .NET.

Le GC .NET gere automatiquement la mémoire avec un système generationnel a trois niveaux. Génération 0 : objets récemment alloues, collectes fréquemment. Génération 1 : objets ayant survecu une collection Gen 0, zone tampon. Génération 2 : objets a longue durée de vie, collectes rarement. Le GC utilise un algorithme mark-and-sweep : il identifie les objets accessibles depuis les racines (variables statiques, pile, handles), marque les objets vivants, et libère la mémoire des objets non marques. Le LOH (Large Object Heap) gere les objets de plus de 85 000 octets séparément.

3. Qu'est-ce que l'injection de dépendances et comment fonctionne-t-elle dans ASP.NET Core ?

L'injection de dépendances (DI) est un patron de conception ou les dépendances sont fournies à une classe plutôt que creees par celle-ci. ASP.NET Core integre un conteneur DI natif. On enregistre les services dans Program.cs avec trois durées de vie : Transient (nouvelle instance à chaque demande), Scoped (une instance par requête HTTP), Singleton (une seule instance pour toute l'application). Les dépendances sont injectees via le constructeur. Cela facilité les tests unitaires (mocking), le decouplage et la maintenabilité du code.

4. Expliquez async/await en C# et les pièges courants.

async/await permet d'écrire du code asynchrone de manière lisible. Une méthode async retourne Task ou Task. Le mot-cle await suspend l'exécution jusqu'à la complétion de la tâche sans bloquer le thread. Pièges courants : async void (à éviter sauf pour les event handlers car les exceptions ne sont pas capturees), deadlock en appelant .Result ou .Wait() dans un contexte de synchronisation, oublier await (la tâche s'execute mais les erreurs sont perdues), et le ConfigureAwait(false) nécessaire dans les bibliothèques pour éviter la capture du contexte de synchronisation.

5. Quelle est la différence entre IEnumerable et IQueryable ?

IEnumerable travaille en mémoire (LINQ to Objects). Le filtrage s'execute cote client après avoir charge toutes les données. IQueryable traduit les expressions LINQ en requêtes (ex: SQL via Entity Framework). Le filtrage s'execute cote serveur, ne ramenant que les données nécessaires. Utilisez IQueryable quand vous travaillez avec une source de données externe (base de données) pour optimiser les performances. Utilisez IEnumerable pour les collections en mémoire. Attention : materialiser un IQueryable trop tot avec ToList() annule l'avantage du filtrage cote serveur.

6. Comment fonctionne le pattern CQRS et quand l'utiliser ?

CQRS (Command Query Responsibility Segregation) separe les opérations de lecture (Queries) et d'écriture (Commands) en modèles distincts. Les Commands modifient l'état et ne retournent rien. Les Queries retournent des données sans modifier l'état. Avantages : optimisation indépendante des lectures et écritures, scalabilité (bases de données séparées possibles), modèles de lecture denormalises pour la performance. En .NET, souvent implemente avec MediatR. A utiliser pour les systèmes complexes avec des besoins différents en lecture et écriture. Éviter pour les CRUD simples ou cela ajoute de la complexité inutile.

7. Expliquez les middleware dans ASP.NET Core.

Les middleware sont des composants qui forment le pipeline de traitement des requêtes HTTP. Chaque middleware peut traiter la requête, la passer au suivant, ou court-circuiter le pipeline. L'ordre d'enregistrement est crucial. Pipeline typique : gestion des exceptions, HSTS, redirection HTTPS, fichiers statiques, routage, CORS, authentification, autorisation, endpoints. On cree un middleware personnalise via une classe avec une méthode InvokeAsync ou via app.Use() inline. Les middleware sont exécutés dans l'ordre pour la requête et en ordre inverse pour la réponse.

8. Qu'est-ce que Entity Framework Core et comment optimiser ses performances ?

EF Core est l'ORM officiel de Microsoft pour .NET. Il mappe les classes C# aux tables de base de données et traduit LINQ en SQL. Optimisations : utiliser AsNoTracking() pour les lectures seules, éviter le N+1 avec Include() et ThenInclude(), utiliser les projections (Select) pour ne charger que les colonnes nécessaires, activer le split queries pour les grandes jointures, utiliser raw SQL ou des stored procédures pour les requêtes complexes, configurer les index correctement, et utiliser le batching pour les insertions massives. Monitorer avec le logging SQL pour détecter les requêtes lentes.

9. Quelle est la différence entre les types valeur et les types référence en C# ?

Les types valeur (int, float, bool, struct, enum) sont stockes sur la pile et contiennent directement la donnée. La copie duplique la valeur. Les types référence (class, string, array, delegate) sont stockes sur le tas avec une référence sur la pile. La copie duplique la référence, pas l'objet. Le boxing convertit un type valeur en référence (allocation heap), l'unboxing fait l'inverse. Les types valeur nullables (int?) ajoutent la capacité d'être null. Comprendre cette distinction est essentiel pour la performance et éviter les bugs subtils.

10. Comment implémenter la gestion des erreurs et le logging dans une application ASP.NET Core ?

Stratégie en couches : middleware d'exception global pour capturer toutes les exceptions non gérées et retourner des réponses standardisees (ProblemDetails RFC 7807). Validation avec FluentValidation ou Data Annotations au niveau des contrôleurs. Try-catch cible uniquement pour les opérations pouvant echouer de manière prévisible (appels externes, I/O). Pour le logging, utiliser ILogger natif avec des fournisseurs comme Serilog ou NLog. Configurer le logging structure (JSON) avec des niveaux (Debug, Info, Warning, Error, Critical). Centraliser les logs avec ELK Stack, Seq, ou Application Insights pour le monitoring en production.

Besoin d'aide pour préparer vos entretiens ?

Decrivez votre profil pour des conseils de preparation personnalises.

Recevoir des conseils

Questions fréquentes

C# est-il demande en France ?
Oui, surtout dans l'industrie, la finance et le jeu video (Unity). .NET est tres utilise en entreprise.

Pages liées

Chaque semaine, le meilleur de la tech française

Tendances, salaires, outils et opportunités — directement dans votre boîte mail.

Gratuit. Desabonnement en un clic. Pas de spam.