1. Quelle est la différence entre String
et StringBuilder
en C# ?
✅ Réponse :
-
String
est immuable (chaque modification crée une nouvelle instance en mémoire). -
StringBuilder
est mutable (il modifie la même instance, évitant ainsi les allocations mémoire inutiles). -
StringBuilder
est plus performant pour des opérations répétées de concaténation.
string s = "Hello";
s += " World"; // Nouvelle instance créée
StringBuilder sb = new StringBuilder("Hello");
sb.Append(" World"); // Modifie l’instance existante
2. Quels sont les principes SOLID en programmation orientée objet ?
✅ Réponse :
Les principes SOLID sont 5 bonnes pratiques pour un code modulaire et maintenable :
-
Single Responsibility Principle (SRP) : Une classe doit avoir une seule raison de changer.
-
Open/Closed Principle (OCP) : Une classe doit être ouverte à l’extension mais fermée à la modification.
-
Liskov Substitution Principle (LSP) : Une classe dérivée doit pouvoir remplacer sa classe mère sans altérer le comportement.
-
Interface Segregation Principle (ISP) : Une interface ne doit pas imposer l’implémentation de méthodes inutiles.
-
Dependency Inversion Principle (DIP) : Une classe doit dépendre d’abstractions, pas d’implémentations concrètes.
3. Quelle est la différence entre Task
et Thread
en C# ?
✅ Réponse :
-
Thread
représente un thread physique du système d’exploitation. -
Task
appartient à la TPL (Task Parallel Library) et est plus optimisé pour le multitâche. -
Task
permet la gestion plus fine des tâches asynchrones avecasync/await
.
// Thread classique
Thread t = new Thread(() => Console.WriteLine("Hello Thread"));
t.Start();
// Task asynchrone
Task.Run(() => Console.WriteLine("Hello Task"));
4. Quelle est la différence entre ref
, out
et in
en C# ?
✅ Réponse :
-
ref
: Passe un paramètre par référence, il doit être initialisé avant l’appel. -
out
: Passe un paramètre par référence, mais n’a pas besoin d’être initialisé avant l’appel. -
in
: Passe un paramètre par référence en lecture seule (ne peut pas être modifié).
void Test(ref int x) { x += 10; } // x doit être initialisé avant
void Test(out int y) { y = 10; } // y n'a pas besoin d’être initialisé
void Test(in int z) { Console.WriteLine(z); } // z ne peut pas être modifié
5. Explique la différence entre IEnumerable
, IQueryable
, List<T>
et Array
en C# ?
✅ Réponse :
Type | Description | Exécution | Mémoire |
---|---|---|---|
IEnumerable<T> |
Collection en mémoire | Exécution immédiate | Faible |
IQueryable<T> |
Exécute des requêtes SQL sur la DB | Exécution différée | Optimisé |
List<T> |
Liste dynamique en mémoire | Exécution immédiate | Moyen |
Array |
Tableau fixe en mémoire | Exécution immédiate | Élevé |
6. Que fait le mot-clé lock
en C# ?
✅ Réponse :
lock
empêche plusieurs threads d’accéder à une ressource partagée en même temps, évitant ainsi les conditions de course.
private static object verrou = new object();
void AccèsCritique()
{
lock (verrou)
{
Console.WriteLine("Section critique");
}
}
⚠️ À éviter sur des objets globaux (ex : this
) pour éviter les deadlocks.
7. Qu’est-ce que le GC
(Garbage Collector) et comment fonctionne-t-il en .NET ?
✅ Réponse :
Le Garbage Collector (GC) libère automatiquement la mémoire des objets non référencés. Il fonctionne en trois générations :
-
Gen 0 : Objets récents (collectés souvent).
-
Gen 1 : Objets intermédiaires.
-
Gen 2 : Objets longue durée (collectés rarement).
Déclenchement :
-
Lorsque la mémoire est insuffisante.
-
Périodiquement en arrière-plan.
-
Manuel via
GC.Collect()
(⚠️ à éviter).
8. Comment implémenter le pattern Dispose
en C# ?
✅ Réponse :
Une classe qui utilise des ressources non managées (ex: fichiers, connexions) doit implémenter IDisposable
et la méthode Dispose()
.
class FichierHandler : IDisposable
{
private FileStream _file;
public FichierHandler(string path)
{
_file = new FileStream(path, FileMode.Open);
}
public void Dispose()
{
_file?.Dispose();
GC.SuppressFinalize(this);
}
}
Utilisation avec using
:
using (var fichier = new FichierHandler("test.txt"))
{
// Utilisation du fichier
} // Dispose() est appelé automatiquement ici
9. Quelle est la différence entre abstract class
et interface
en C# ?
✅ Réponse :
Type | Héritage | Implémentation | Champs et Constructeurs |
---|---|---|---|
Abstract Class | Une seule classe par héritage | Peut contenir des méthodes implémentées | ✅ Oui |
Interface | Plusieurs implémentations | Ne contient que des méthodes abstraites (jusqu'à C# 8) | ❌ Non |
// Classe Abstraite
abstract class Animal
{
public abstract void FaireSon();
}
// Interface
interface IVolant
{
void Voler();
}
10. Comment fonctionne le async/await
en C# ?
✅ Réponse :
async/await
permet d’exécuter des opérations asynchrones sans bloquer le thread principal.
async Task<int> ChargerDonnéesAsync()
{
await Task.Delay(2000); // Simule une attente
return 42;
}
async void Afficher()
{
int result = await ChargerDonnéesAsync();
Console.WriteLine(result);
}
-
await
attend la fin d’une tâche sans bloquer le thread. -
async
doit être utilisé avecTask
ouTask<T>
. -
⚠️
async void
est déconseillé sauf pour les événements, car il ne permet pas la gestion des exceptions.
Aucun commentaire:
Enregistrer un commentaire