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
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
5. Quelle est la différence entre IEnumerable et IQueryable ?
IEnumerable
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