40 questions with answers for candidates with Freshers — 20 easy, 19 medium, 1 hard.
What interviewers expect: freshers
Fresher interviews start with an online coding test, usually two or three DSA problems, followed by technical rounds on C++ basics, pointers, OOP, virtual functions and STL. Interviewers check that you can write correct code without an IDE, explain time complexity and talk clearly about your college projects. An HR round covers relocation, learning attitude and teamwork.
This set is weighted towards Templates and Generic Programming (8), C++ Basics and Syntax (6), Pointers and Memory Management (6), Object-Oriented Programming in C++ (5).
Pointers and references OOP and virtual functions STL containers and complexity Arrays, strings and linked list problems
Solved at this levelStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
✓ 3 questions free • Unlock the rest in seconds
01
Why should a base class have a virtual destructor?
If you delete a derived object through a base pointer and the base destructor is not virtual, only the base destructor runs, which is undefined behaviour and typically leaks the derived part's resources. Making the destructor virtual ensures the derived destructor runs first, then the base one. Rule: any class meant to be used polymorphically needs a public virtual destructor, or a protected non-virtual one.
02
What are the main components of the Standard Template Library?
The STL has four parts. Containers store data, such as vector, deque, list, map, set and unordered_map. Iterators give a uniform way to traverse containers. Algorithms such as sort, find, accumulate and lower_bound work on iterator ranges. Function objects and lambdas customise algorithms, for example a comparator for sort. Adapters such as stack, queue and priority_queue wrap other containers.
03
Four threads each increment a shared int one million times, but the final total is less than four million. Why?
counter++ is a read-modify-write of three steps, so threads interleave and overwrite each other's updates, which is a data race and undefined behaviour. Fix it with std::atomic<int> and fetch_add, which is fast for a simple counter, or protect the variable with a mutex. Even better for performance, let each thread count in a local variable and add it to the total once at the end.
Ranges let algorithms take whole containers, as in std::ranges::sort(v), instead of begin and end pairs. Views such as filter, transform, take and reverse are lazy and compose with the pipe operator, for example v | std::views::filter(isEven) | std::views::transform(square). Nothing is computed until you iterate. Ranges also use concepts, so errors are clearer, and projections let you sort by a member easily.
05
Write a minimal modern CMakeLists.txt for an app with a library and tests.
A template is only a pattern; code is generated when it is instantiated with concrete types, and the compiler must see the full definition at that point. If the body lives in a .cpp file, other translation units cannot instantiate it and you get linker errors. The usual fix is defining templates in headers, or using explicit instantiation in the .cpp for a known, fixed set of types.
A deadlock happens when threads wait forever for each other's locks, for example thread A holds m1 and waits for m2 while thread B holds m2 and waits for m1. It needs mutual exclusion, hold and wait, no preemption and circular wait. Prevent it by always locking in a fixed global order, locking several mutexes together with std::scoped_lock, keeping critical sections small and never calling unknown code while holding a lock.
08
What is the difference between an inline function and a macro?
A macro is text substitution done by the preprocessor with no type checking, so #define SQ(x) x*x gives a wrong result for SQ(a+1) and may evaluate arguments twice. An inline function is a real function with type checking, scope and debugger support, and the compiler may expand it at the call site. In modern C++ inline mainly allows a function to be defined in a header without breaking the One Definition Rule.
09
Describe how you handled an urgent production issue while on call.
Situation: at 2 AM our order service started timing out. Task: restore service quickly and find the cause. Action: I followed the runbook, checked dashboards, saw thread pool saturation after a new release, rolled back within 15 minutes and posted updates in the incident channel. Next day I found a blocking database call inside a worker thread. Result: service was restored fast, and I added a timeout and an alert on queue depth.
10
What does the static keyword mean in different contexts?
Inside a function, a static local variable is initialised once and keeps its value between calls. At namespace scope, static gives internal linkage, so the name is visible only in that translation unit. Inside a class, a static data member belongs to the class rather than each object, and a static member function has no this pointer. Since C++17 inline static members can be defined directly in the header.
11
A teammate complains that a template function produces hundreds of lines of compiler errors when misused. How do you improve this?
Constrain the template so misuse fails early with a clear message. With C++20 I would add a concept or requires clause, for example template <std::totally_ordered T>, so the error names the unmet requirement at the call site. On older standards, a static_assert with a readable message at the top of the function body helps. Good naming and a comment on expected type properties also help.
12
Show how std::format and std::print format output in modern C++.
A shallow copy copies pointer members, so two objects share one heap buffer; destroying one leaves the other dangling and causes a double free. A deep copy allocates new memory and copies the contents. The compiler-generated copy constructor copies member by member, so a class owning a raw pointer needs a custom copy constructor and copy assignment, or better, should hold a std::vector or unique_ptr instead.
14
What is std::string_view and what are its pitfalls?
string_view is a non-owning pointer and length pair that refers to existing characters, so passing it avoids copies and accepts both std::string and literals. The main pitfall is lifetime: it must not outlive the data it views, so returning a string_view to a local string or a temporary dangles. It is also not guaranteed to be null-terminated, so do not pass data() to C functions expecting C strings.
A default constructor takes no arguments. A parameterised constructor takes arguments to initialise members. A copy constructor, T(const T&), creates an object from another of the same type. A move constructor, T(T&&), steals resources from a temporary. There are also delegating constructors that call another constructor and converting constructors that take one argument; mark those explicit to avoid unwanted implicit conversions.
Template parameters can be values, not just types, as long as they are compile-time constants, such as integers, enums, pointers and, since C++20, some class types. std::array<int, 5> uses a size parameter. Example: template <int N> int power(int x) can be unrolled by the compiler. Each different value creates a separate instantiation, so they suit small fixed sets of values.
An lvalue has identity and a persistent address, such as a named variable x. An rvalue is a temporary without lasting identity, such as 5 or the result of a + b. C++11 splits these further into lvalue, xvalue and prvalue. The distinction matters because rvalue references, written T&&, bind to temporaries and enable move semantics, letting the program steal resources instead of making expensive copies.
18
Write a swap function using references and explain why a pass-by-value version fails.
void swapByValue(int a, int b) { // works on copies, caller sees no change
int t = a; a = b; b = t;
}
void swapByRef(int& a, int& b) { // a and b alias the caller's variables
int t = a;
a = b;
b = t;
}
int x = 1, y = 2;
swapByRef(x, y); // now x == 2, y == 1
19
What is the difference between const int*, int* const and const int* const?
Read the declaration from right to left. const int* p is a pointer to a const int: you cannot modify the value through p, but p can point elsewhere. int* const p is a const pointer to int: the address is fixed but the value can change. const int* const p fixes both the address and the value. These forms are frequent interview traps and appear in function signatures.
20
Use lambdas with standard algorithms to sort strings by length and count those longer than a limit.
bool isPrime(long long n) {
if (n < 2) return false;
if (n % 2 == 0) return n == 2;
for (long long i = 3; i * i <= n; i += 2) {
if (n % i == 0) return false;
}
return true;
}
// Only odd divisors up to sqrt(n) are checked: O(sqrt n) time.
22
Describe a time you had to learn a new library or API quickly.
Situation: during my internship I was asked to fix a bug in code using Boost.Asio, which I had never used. Task: understand enough to fix it within the sprint. Action: I read the official examples, wrote a tiny echo server to learn the async model, then traced the bug to a missing handler for connection timeouts. Result: I fixed it in four days and wrote a short internal note for the next new joiner.
23
What is the difference between delete and delete[]?
delete destroys a single object created with new. delete[] destroys an array created with new[] and calls the destructor of every element, using an element count the runtime stores with the allocation. Using delete on an array or delete[] on a single object is undefined behaviour and can leak or corrupt the heap. In modern code std::vector or std::unique_ptr<T[]> removes the need for either.
24
What is a pure virtual function and an abstract class?
A pure virtual function is declared with = 0, such as virtual double area() const = 0;, and has no required implementation in the base. A class with at least one pure virtual function is abstract and cannot be instantiated; it only defines an interface. Derived classes must override every pure virtual function to become concrete. This is how C++ expresses interfaces like Shape or PaymentGateway.
25
A generic maxOf template gives wrong results when called with two C-style string literals. Why, and how do you fix it?
T is deduced as const char*, so the template compares pointer addresses instead of the characters. The result depends on where the literals are stored. Fix it by adding an overload for const char* that uses std::strcmp, or better, call it with std::string or std::string_view, where operator< compares contents. This shows why generic code must consider what operations mean for each type.
26
Implement a generic Stack class template backed by std::vector.
In C++20 I would constrain it: template <typename T> requires std::is_arithmetic_v<T> double average(const std::vector<T>& v). Passing a vector of strings then fails with a clear constraint error. On C++17 the same check can go in a static_assert or std::enable_if. I would also decide whether bool and char should be allowed, since they are technically arithmetic types.
29
What is the difference between overloading and overriding, and what do override and final do?
Overloading means same name, different parameters, resolved at compile time within one scope. Overriding means a derived class replaces a base virtual function with the same signature, resolved at run time. The override keyword makes the compiler check that a matching base virtual exists, catching typos and const mismatches. final stops further overriding of a function or further inheritance from a class.
30
Tell me about a time you found a difficult bug in your C++ code.
Situation: a service crashed randomly about once a day in production. Task: find the root cause without blocking releases. Action: I enabled core dumps, analysed them in gdb and saw a corrupted vector inside a callback. A staging run with AddressSanitizer showed a use-after-free because a lambda captured a raw pointer to a destroyed object. I changed it to capture a weak_ptr. Result: no crashes for months, and sanitizer runs were added to CI.
31
A function returns a reference to a local variable and the code sometimes works. Explain what is happening.
The local is destroyed when the function returns, so the reference dangles and using it is undefined behaviour. It may seem to work because the old bytes remain on the stack until another call overwrites them. Compilers warn with -Wreturn-local-addr or -Wreturn-stack-address. The fix is to return by value; copy elision and move semantics make returning objects cheap.
32
What are type traits and how does if constexpr use them?
Type traits in <type_traits> answer questions about types at compile time, such as std::is_integral_v<T>, std::is_pointer_v<T> or std::is_same_v<T, U>, and transform types, such as std::remove_reference_t. if constexpr picks a branch at compile time and discards the other, so code like if constexpr (std::is_integral_v<T>) can call integer-only operations safely inside a generic function.
33
Sort a vector of pairs by the second value in descending order, breaking ties by the first value.
size is the number of stored elements; capacity is how many fit before reallocation. When push_back exceeds capacity, vector allocates a larger buffer, typically 1.5 or 2 times larger, moves or copies elements and frees the old one, giving amortised O(1) appends. reserve(n) pre-allocates capacity to avoid repeated reallocations when the final size is known; shrink_to_fit requests releasing unused capacity.
CPUs access data fastest at addresses that are multiples of its size, so the compiler aligns members and inserts padding bytes. A struct of char, int, char is usually 12 bytes, while ordering it as int, char, char gives 8. alignof reports alignment and alignas raises it, for example to 64 bytes to keep data used by different threads on separate cache lines. Packed structs save space but may be slower.
36
What are the four pillars of object-oriented programming in C++?
Encapsulation hides data behind a class interface using private members and public methods. Abstraction exposes only what users need, often through abstract base classes. Inheritance lets a derived class reuse and extend a base class. Polymorphism lets one interface behave differently: compile-time through overloading and templates, run-time through virtual functions. Together they help model systems such as bank accounts, shapes or payment methods cleanly.
Any insertion that causes reallocation, when size exceeds capacity, invalidates all iterators, pointers and references. Insertion without reallocation invalidates those at or after the insertion point. erase invalidates iterators at and after the erased element. clear and resize to a larger size beyond capacity invalidate everything. Holding a pointer to an element and then calling push_back is a classic bug.
Including the same header twice in a translation unit would redefine classes and cause errors. Header guards wrap the file in #ifndef MY_HEADER_H, #define MY_HEADER_H and #endif, so the second inclusion is skipped. #pragma once does the same in one line and is supported by all major compilers, though it is not in the standard. Most modern projects use #pragma once for simplicity.
39
What are templates in C++? Explain function and class templates.
Templates let you write code once for many types; the compiler generates a concrete version for each type used. A function template such as template <typename T> T maxOf(T a, T b) works for int, double or std::string. A class template such as template <typename T> class Stack builds containers for any element type. The whole STL, including vector, map and algorithms, is built on templates.
A void* can hold the address of any object type but cannot be dereferenced or used in arithmetic until it is cast back to a real type. It appears in C APIs such as malloc, memcpy and callback user-data parameters. In C++ code, templates, std::any or std::variant are better because void* removes type safety and mistakes appear only at run time.
Frequently asked questions
What is asked in C++ interviews for Freshers?
Fresher interviews start with an online coding test, usually two or three DSA problems, followed by technical rounds on C++ basics, pointers, OOP, virtual functions and STL. Interviewers check that you can write correct code without an IDE, explain time complexity and talk clearly about your college projects. An HR round covers relocation, learning attitude and teamwork.
How many questions should I practise before a C++ interview?
Work through all 40 questions here, then the company-wise sets for the employers you are targeting. Quality matters more than count: be able to explain why each answer is right.
Which topics matter most for Freshers?
Focus first on Pointers and references, OOP and virtual functions, STL containers and complexity, Arrays, strings and linked list problems.