So meistern Sie das C#-Vorstellungsgespräch: Top-Fragen von A bis Z

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung

Ein Vorstellungsgespräch für eine Stelle als C#-Entwickler ist nicht nur eine Überprüfung der Syntax. Arbeitgeber möchten ein Verständnis der .NET-Plattform, der Funktionsweise der CLR, die Fähigkeit, leistungsfähigen Code zu schreiben, und Kenntnisse moderner Ansätze (async, LINQ, DI) sehen.

In diesem Artikel behandeln wir die Top-Fragen zu C# von A bis Z – von grundlegenden Datentypen bis zu komplexen Themen wie Garbage Collection und asynchroner Programmierung. Jede Frage wird von einer kurzen Antwort und einem Codebeispiel begleitet, damit Sie sich im Interview sicher fühlen.



1. Grundlegende Fragen: Typen, Klassen und Speicher



1.1. Was ist der Unterschied zwischen Value Type und Reference Type?

Value Type (int, struct, enum) werden auf dem Stack gespeichert und per Wert kopiert. Reference Type (class, string, array) werden auf dem Heap gespeichert, die Variable enthält einen Verweis auf das Objekt.

int a = 10;int b = a; // b ist eine Kopie, a und b sind unabhängig

class MyClass { public int X; }MyClass obj1 = new MyClass { X = 5 };MyClass obj2 = obj1; // obj2 verweist auf dasselbe Objektobj2.X = 10; // obj1.X wird ebenfalls 10


1.2. Was sind Boxing und Unboxing?

Boxing ist das Verpacken eines Werttyps in ein Objekt (auf den Heap). Unboxing ist der umgekehrte Vorgang. Häufige Verwendung beeinträchtigt die Leistung.

int number = 42;object boxed = number;    // Boxingint unboxed = (int)boxed; // Unboxing


1.3. Erzählen Sie mir etwas über den Garbage Collector.

Der GC in .NET gibt automatisch Speicher von Objekten frei, auf die keine Verweise mehr existieren. Er arbeitet mit Generationen (Gen 0, 1, 2). Große Objekte (>85 KB) landen im Large Object Heap (LOH).

Tipp: Rufen Sie GC.Collect() nicht manuell auf – dies stört die Optimierungen des GC.



2. OOP und Entwurfsprinzipien



2.1. Erklären Sie die SOLID-Prinzipien.

  • S – Single Responsibility: Eine Klasse sollte nur einen Grund für eine Änderung haben.
  • O – Open/Closed: Offen für Erweiterung, geschlossen für Modifikation.
  • L – Liskov Substitution: Unterklassen sollten die Basisklasse korrekt ersetzen können.
  • I – Interface Segregation: Viele kleine Schnittstellen sind besser als eine große.
  • D – Dependency Inversion: Abhängigkeiten sollten von Abstraktionen und nicht von konkreten Klassen ausgehen.


2.2. Was ist Dependency Injection (DI)?

DI ist ein Entwurfsmuster, bei dem Abhängigkeiten von außen an eine Klasse übergeben werden (über Konstruktor, Methode oder Eigenschaft). In .NET Core gibt es einen integrierten DI-Container.

public interface ILogger{    void Log(string message);}

public class ConsoleLogger : ILogger{ public void Log(string message) => Console.WriteLine(message);}

public class OrderService{ private readonly ILogger _logger; public OrderService(ILogger logger) // DI über Konstruktor { _logger = logger; }}


3. LINQ, Ausnahmen und Zeichenketten



3.1. Wie funktioniert LINQ? Was ist verzögerte Ausführung?

LINQ (Language Integrated Query) ermöglicht das Schreiben von Abfragen für Sammlungen, Datenbanken (EF Core) und XML. Verzögerte Ausführung bedeutet, dass die Abfrage erst beim Durchlaufen des Ergebnisses ausgeführt wird (z. B. mit foreach oder .ToList()).

var numbers = new List<int> { 1, 2, 3, 4, 5 };var query = numbers.Where(n => n > 2); // Abfrage wird nicht ausgeführtnumbers.Add(6); // Hinzufügen nach Erstellung der Abfrageforeach (var n in query) // Ausführung hier    Console.WriteLine(n); // 3, 4, 5, 6


3.2. Was ist der Unterschied zwischen String und StringBuilder?

String ist ein unveränderlicher Typ. Jede Verkettungsoperation erzeugt ein neues Objekt. StringBuilder verwendet einen veränderbaren Puffer und ist effizient für mehrfache Änderungen an einer Zeichenkette.

// Schlecht (viele Allokationen)string s = "";for (int i = 0; i < 1000; i++)    s += i.ToString(); // Erzeugt 1000 neue String-Objekte

// GutStringBuilder sb = new StringBuilder();for (int i = 0; i < 1000; i++) sb.Append(i.ToString());string result = sb.ToString();


3.3. Was ist der Unterschied zwischen throw und throw ex?

throw wirft die aktuelle Ausnahme erneut und bewahrt den ursprünglichen Stack-Trace. throw ex setzt den Stack-Trace zurück, was das Debugging erschwert.

try{    // Code}catch (Exception ex){    // Falsch: throw ex;    throw; // Richtig: bewahrt den Stack-Trace}


4. Async/Await und Multithreading



4.1. Wie funktioniert async/await?

Die Schlüsselwörter async und await ermöglichen asynchrone Programmierung, ohne Threads zu blockieren. await gibt den Thread an den Thread-Pool zurück, während auf den Abschluss einer Operation gewartet wird.

public async Task<string> GetDataAsync(){    using (HttpClient client = new HttpClient())    {        string result = await client.GetStringAsync("https://api.example.com");        return result;    }}


4.2. Was ist der Unterschied zwischen Task und Thread?

Thread ist ein systemnahes Konzept, das einen Betriebssystem-Thread darstellt. Task ist eine abstraktere Einheit asynchroner Arbeit, die vom Task Parallel Library (TPL) verwaltet wird. Tasks können Threads aus dem Thread-Pool verwenden und unterstützen Continuations.



4.3. Was ist Deadlock und wie vermeidet man ihn?

Ein Deadlock tritt auf, wenn zwei oder mehr Threads gegenseitig auf Ressourcen warten, die der jeweils andere hält. Vermeidungsstrategien: Verwenden Sie Monitor.TryEnter mit Timeout, verwenden Sie SemaphoreSlim oder ReaderWriterLockSlim, und vermeiden Sie verschachtelte Sperren.



5. Erweiterte Themen: GC, Pattern Matching und Performance



5.1. Wie funktioniert die Garbage Collection in .NET?

Der GC arbeitet in Generationen: Gen 0 (kurzlebig), Gen 1 (Puffer), Gen 2 (langlebig). Der GC durchläuft drei Phasen: Markieren (lebende Objekte finden), Komprimieren (Fragmentierung beseitigen) und Aktualisieren von Verweisen. Der Large Object Heap (LOH) wird nicht komprimiert.



5.2. Was ist Pattern Matching in C#?

Pattern Matching ermöglicht es, den Typ und die Struktur von Objekten zu überprüfen und Daten daraus zu extrahieren. Beispiele: is-Ausdrücke, switch-Ausdrücke, Positionsmuster.

public string GetShapeInfo(object shape) => shape switch{    Circle c => $"Kreis mit Radius {c.Radius}",    Rectangle r => $"Rechteck {r.Width}x{r.Height}",    _ => "Unbekannte Form"};


5.3. Wie optimiert man die Leistung von C#-Code?

  • Verwenden Sie Span<T> und Memory<T> zur Vermeidung von Heap-Allokationen.
  • Vermeiden Sie Boxing durch Verwendung generischer Typen.
  • Verwenden Sie ArrayPool für temporäre Arrays.
  • Verwenden Sie ValueTask für leistungskritische asynchrone Methoden.
  • Vermeiden Sie unnötige LINQ-Abfragen in Schleifen.


Fazit

Ein erfolgreiches C#-Vorstellungsgespräch erfordert nicht nur Wissen über die Sprache, sondern auch ein tiefes Verständnis der .NET-Plattform, Speicherverwaltung und moderner Entwurfsmuster. Üben Sie das Schreiben von Code auf einem Whiteboard oder in einem Texteditor, erklären Sie Ihre Gedanken laut und haben Sie keine Angst zu sagen: "Ich weiß es nicht, aber ich würde es so herausfinden."

Viel Erfolg bei Ihrem Vorstellungsgespräch!

Blogs

Buchempfehlungen