P
prepair.app
Start interview →
EnglishУкраїнськаРусский
🔷

C++ interview questions

C++ interviews test three things: whether you understand the object model, whether you can be trusted with memory, and whether you know what the standard library costs. Below are the questions asked most often, each with a model answer.

Junior · no experience / under 1 yearMiddle · 2–4 years of experienceSenior · 5+ years of experience

What they ask about

Memory, pointers and RAII
OOP, virtual functions and vtable
Move semantics and the rule of five
Templates and metaprogramming
STL containers and complexity
Concurrency and data races

10 real questions with answers

Every question comes with a model answer you can compare yours against.

1

What is the difference between a pointer and a reference?

Answer

A reference must be bound when it is created and can never be rebound; a pointer can be null, reassigned, and has its own address and arithmetic. In practice you take a reference when the thing must exist and a pointer when absence is a legal state. A reference is not a separate object, which is why there are no references to references and no arrays of them.

2

What is RAII?

Answer

Resource acquisition is initialisation: a resource is owned by an object, acquired in its constructor and released in its destructor. Because destructors run on every exit path — including an exception unwinding the stack — the resource cannot be leaked by an early return someone added later. Every smart pointer, lock guard and file stream in the standard library is this idea.

3

`unique_ptr`, `shared_ptr`, `weak_ptr` — when does each apply?

Answer

unique_ptr is sole ownership, moves but does not copy, and costs nothing over a raw pointer — it should be the default. shared_ptr is shared ownership with an atomic reference count, which is not free and is often reached for when ownership simply was not decided. weak_ptr observes a shared_ptr without owning it, and its main job is breaking reference cycles that would otherwise never be freed.

4

Why does a base class need a virtual destructor?

Answer

Because deleting a derived object through a base pointer without one is undefined behaviour — in practice the derived destructor never runs and its members leak. The rule is: if a class is meant to be inherited from and deleted polymorphically, its destructor is virtual. If it is not meant to be a base, it does not need one, and giving it one adds a vtable it did not have.

5

What are `vptr` and `vtable`?

Answer

A class with virtual functions gets a table of function pointers — the vtable — one per class, and every object of it stores a hidden pointer to that table, the vptr. A virtual call reads the vptr, indexes the table, and jumps. That is what makes the object bigger by a pointer and the call indirect, and it is why the compiler can devirtualize only when it can prove the dynamic type.

6

What is the difference between the stack and the heap?

Answer

The stack is allocated and freed by moving a pointer as scopes enter and exit, so it is fast, contiguous and cache-friendly, but limited and tied to lifetime. The heap is allocated on request, has no lifetime rules of its own, and costs a real allocator call plus the risk of fragmentation. Prefer the stack; go to the heap when the size is unknown or the object must outlive the scope.

7

What is move semantics and what does `std::move` do?

Answer

Move semantics let a resource be transferred rather than copied — a vector's move constructor steals the buffer pointer instead of allocating and copying elements. std::move itself moves nothing: it is a cast to an rvalue reference that makes the object eligible for a move. Whether anything moves depends on the type having a move constructor, and the moved-from object is left valid but unspecified.

8

What is undefined behaviour and why is it dangerous?

Answer

Behaviour the standard imposes no requirements on — reading past the end of an array, dereferencing null, signed overflow, using a moved-from object incorrectly, a data race. It is dangerous precisely because it often appears to work: the compiler is allowed to assume it never happens and optimises on that assumption, so the same code breaks after an unrelated change or a different optimisation level. Sanitizers are how you find it.

9

When would you choose `std::vector` over `std::list`?

Answer

Almost always. vector is contiguous, so iteration is cache-friendly and prefetchable, while list chases a pointer per element and pays an allocation per node. list only wins when you splice or insert in the middle constantly and hold iterators that must stay valid — and even then it is worth measuring, because on modern hardware locality usually beats the better complexity class.

10

What is a data race and how do you avoid one?

Answer

Two threads accessing the same memory location, at least one of them writing, with no synchronisation between them — that is undefined behaviour, not merely a wrong result. You avoid it by not sharing mutable state, or by protecting it with a mutex, or by making the access atomic. ThreadSanitizer finds most of them, which is more reliable than reasoning about a schedule you cannot reproduce.

🦎

Reading answers is not enough

In a real interview you speak under pressure. Cam asks these same questions, scores every answer, and shows exactly what to fix.

Practice a C++ interview →
Free · 3 interviews per month

Worth reading

All articles →

Other specializations

🔍Manual QA🤖QA AutomationJava Backend🐍Python Backend🐘PHP Backend🦫Go Backend🟢Node.js Backend💎Ruby on Rails🟨JavaScript⚛️React Frontend💚Vue Frontend🅰️Angular FrontendNext.js🍏iOS (Swift)🟩Android (Kotlin)⚙️DevOps / SRE🗄️Data Engineer📈Business Analyst🎯Product Manager📋Project Manager🎨UI/UX Designer📣Marketing