C++-Vorstellungsgespräch: 7 Fallstricke, die 90 % der Kandidaten scheitern lassen

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

Warum C++ selbst Senioren immer noch Angst macht?

\n

C++ ist eine Sprache, die Ihnen die volle Kontrolle über den Speicher gibt – aber nur so lange, bis Sie vergessen, ein Semikolon zu setzen, oder versehentlich eine virtuelle Funktion aus einem Konstruktor aufrufen. C++-Vorstellungsgespräche sind berüchtigt für ihre Härte: Sie können sowohl nach Bitfeldern als auch nach dem Aufbau der virtuellen Tabelle und den Feinheiten von std::move gefragt werden. Wenn Sie sich auf ein technisches Interview vorbereiten, ist dieser Artikel Ihre Checkliste. Wir analysieren die tückischsten Themen, die in einem Vorstellungsgespräch fast garantiert auftauchen, und zeigen Ihnen, wie Sie antworten, um nicht durchzufallen.

\n\n

Auf dem Bildungsportal PythonLib diskutieren wir oft, wie man von Python zu C++ wechselt und umgekehrt. Aber heute geht es um reines C++. Keine Kompromisse.

\n\n

1. Virtuelle Funktionen und VTable-Tabellen: Wie man der Falle entgeht

\n

Frage: "Was passiert, wenn man eine virtuelle Funktion aus dem Konstruktor der Basisklasse aufruft?" – ein Klassiker. 70 % der Kandidaten antworten falsch. Lassen Sie uns das klären.

\n\n

Warum ist das gefährlich?

\n

Wenn Sie eine virtuelle Funktion im Konstruktor der Basisklasse aufrufen, ist das Objekt der abgeleiteten Klasse noch nicht erstellt. Die virtuelle Tabelle (VTable) zeigt zu diesem Zeitpunkt auf die Methoden der Basisklasse, nicht auf die der abgeleiteten Klasse. Infolgedessen funktioniert der Polymorphismus nicht.

\n\n
#include <iostream>\n\nclass Base {\npublic:\n    Base() { callFoo(); }  // Aufruf im Konstruktor\n    virtual void foo() { std::cout << "Base::foo\\n"; }\n    void callFoo() { foo(); }\n};\n\nclass Derived : public Base {\npublic:\n    Derived() {}\n    virtual void foo() override { std::cout << "Derived::foo\\n"; }\n};\n\nint main() {\n    Derived d;  // Gibt aus: Base::foo, nicht Derived::foo\n    return 0;\n}
\n\n

Fazit: Rufen Sie niemals virtuelle Funktionen in Konstruktoren und Destruktoren auf. Wenn der Interviewer fragt, erklären Sie ruhig den Mechanismus der VTable.

\n\n

2. Intelligente Zeiger: RAII und Speicherverwaltung

\n

Ohne dieses Thema kommt kein ernsthaftes C++-Vorstellungsgespräch aus. Fragen zu std::unique_ptr, std::shared_ptr und std::weak_ptr sind die Grundlage. Aber oft wird auch nach zyklischen Referenzen und std::enable_shared_from_this gefragt.

\n\n

Wie vermeidet man ein Speicherleck mit shared_ptr?

\n

Stellen Sie sich vor, Sie haben zwei Objekte, die über shared_ptr aufeinander verweisen. Der Referenzzähler wird nie auf Null sinken – der Speicher leckt. Lösung: Einer der Zeiger sollte ein weak_ptr sein.

\n\n
#include <memory>\n#include <iostream>\n\nstruct Node {\n    std::shared_ptr<Node> next;\n    std::weak_ptr<Node> prev;  // Schwache Referenz, um einen Zyklus zu vermeiden\n    ~Node() { std::cout << "Node destroyed\\n"; }\n};\n\nint main() {\n    auto a = std::make_shared<Node>();\n    auto b = std::make_shared<Node>();\n    a->next = b;\n    b->prev = a;  // weak_ptr erhöht den Zähler nicht\n    // Beim Verlassen des Gültigkeitsbereichs werden beide Knoten korrekt gelöscht\n    return 0;\n}
\n\n

Erwähnen Sie im Vorstellungsgespräch unbedingt das Konzept RAII (Resource Acquisition Is Initialization) – die Philosophie von C++, die die Lebensdauer einer Ressource an die Lebensdauer eines Objekts bindet.

\n\n

3. Move-Semantik und std::move: Magie oder Trick?

\n

Eine typische Frage: "Was macht std::move?" Die Antwort "es verschiebt das Objekt" ist falsch. std::move wandelt den Typ lediglich in eine Rvalue-Referenz um. Die eigentliche Verschiebung erfolgt im Move-Konstruktor oder Move-Zuweisungsoperator.

\n\n

Beispiel für das Vorstellungsgespräch

\n
#include <string>\n#include <vector>\n#include <iostream>\n\nclass MyString {\n    std::string data;\npublic:\n    MyString(const std::string& s) : data(s) {}\n    // Move-Konstruktor\n    MyString(MyString&& other) noexcept : data(std::move(other.data)) {\n        std::cout << "Move constructor c                

Blogs

Buchempfehlungen