Skip to content

C++ Interview Questions for Freshers

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?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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.
04

What does the C++20 ranges library add?

Save to ▾
Show answer
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.

Save to ▾
Show answer
cmake_minimum_required(VERSION 3.20) project(Inventory LANGUAGES CXX) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_library(core src/stock.cpp src/order.cpp) target_include_directories(core PUBLIC include) target_compile_options(core PRIVATE -Wall -Wextra -Wpedantic) add_executable(app src/main.cpp) target_link_libraries(app PRIVATE core) enable_testing() find_package(GTest REQUIRED) add_executable(core_tests tests/stock_test.cpp) target_link_libraries(core_tests PRIVATE core GTest::gtest_main) add_test(NAME core_tests COMMAND core_tests)
06

Why are templates usually defined in header files?

Save to ▾
Show answer
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.
07

What is a deadlock and how do you prevent it?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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.

Save to ▾
Show answer
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?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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++.

Save to ▾
Show answer
#include <format> #include <print> // C++23 #include <string> std::string name = "Kiran"; double score = 92.456; std::string line = std::format("{} scored {:.1f}%", name, score); // C++20 std::print("{:<10}|{:>8.2f}\n", name, score); // C++23 std::string hex = std::format("{:#x}", 255); // 0xff // Type-safe like iostreams, readable like printf, and checked at compile time.
13

What is the difference between a shallow copy and a deep copy?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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.
15

What kinds of constructors does C++ have?

Save to ▾
Show answer
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.
16

What are non-type template parameters?

Save to ▾
Show answer
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.
17

What are lvalues and rvalues?

Save to ▾
Show answer
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.

Save to ▾
Show answer
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?

Save to ▾
Show answer
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.

Save to ▾
Show answer
#include <algorithm> #include <string> #include <vector> std::vector<std::string> names = {"Ravi", "Anjali", "Om", "Priyanka"}; std::size_t limit = 4; std::sort(names.begin(), names.end(), [](const std::string& a, const std::string& b) { return a.size() < b.size(); }); auto longCount = std::count_if(names.begin(), names.end(), [limit](const std::string& s) { return s.size() > limit; }); // names: Om, Ravi, Anjali, Priyanka; longCount == 2
21

Write an efficient function to check whether a number is prime.

Save to ▾
Show answer
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.

Save to ▾
Show answer
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[]?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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.

Save to ▾
Show answer
#include <stdexcept> #include <vector> template <typename T> class Stack { std::vector<T> items_; public: void push(const T& x) { items_.push_back(x); } void push(T&& x) { items_.push_back(std::move(x)); } void pop() { if (items_.empty()) throw std::out_of_range("empty stack"); items_.pop_back(); } const T& top() const { return items_.back(); } bool empty() const { return items_.empty(); } std::size_t size() const { return items_.size(); } };
27

Write a GoogleTest unit test for a function, including an edge case.

Save to ▾
Show answer
#include <gtest/gtest.h> #include <stdexcept> #include <vector> double average(const std::vector<int>& v) { if (v.empty()) throw std::invalid_argument("empty"); long long s = 0; for (int x : v) s += x; return static_cast<double>(s) / v.size(); } TEST(AverageTest, ComputesMean) { EXPECT_DOUBLE_EQ(average({2, 4, 6}), 4.0); } TEST(AverageTest, ThrowsOnEmpty) { EXPECT_THROW(average({}), std::invalid_argument); }
28

A generic average function must accept only numeric types. How would you enforce that?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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.

Save to ▾
Show answer
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.

Save to ▾
Show answer
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?

Save to ▾
Show answer
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.

Save to ▾
Show answer
#include <algorithm> #include <vector> std::vector<std::pair<int, int>> v = {{1, 5}, {2, 3}, {3, 5}}; std::sort(v.begin(), v.end(), [](const auto& a, const auto& b) { if (a.second != b.second) return a.second > b.second; return a.first < b.first; }); // Result: {1,5} {3,5} {2,3}. The comparator must be a strict weak ordering.
34

How does std::vector grow, and what is the difference between size, capacity and reserve?

Save to ▾
Show answer
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.
35

What are memory alignment and padding?

Save to ▾
Show answer
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++?

Save to ▾
Show answer
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.
37

When are std::vector iterators invalidated?

Save to ▾
Show answer
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.
38

What are header guards and #pragma once?

Save to ▾
Show answer
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.

Save to ▾
Show answer
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.
40

What is a void pointer and when would you use it?

Save to ▾
Show answer
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.