Junior C++ Developer Interview Questions & Answers
40 questions for Junior C++ Developer interviews — 24 easy, 16 medium.
About the Junior C++ Developer role
A junior C++ developer writes and maintains features in an existing codebase under the guidance of senior engineers. Daily work includes fixing bugs, writing unit tests, using STL containers correctly and following team coding standards. Interviews focus on language basics, pointers, OOP, STL and data structure problems. Freshers from B.Tech, BCA or MCA backgrounds with solid C++ fundamentals and a couple of projects can target this role at product, services and embedded companies.
Core C++ syntax OOP design STL containers Unit testing Debugging with gdb
Solved for this roleStart 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
Write an efficient function to check whether a number is prime.
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.
02
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.
03
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.
04
A program that prints a million lines with std::endl is very slow. Why, and how do you fix it?
std::endl writes a newline and also flushes the stream buffer every time, forcing a system call per line. Replace it with the newline character so output is buffered and written in large chunks. For competitive programming or bulk output, also call std::ios::sync_with_stdio(false) and std::cin.tie(nullptr). Flush explicitly only when output must appear immediately, such as before a risky operation.
05
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.
06
Tell me about a time when choosing a better data structure improved performance.
Situation: a pricing job took 40 minutes because it searched a vector of 2 lakh products linearly for every order line. Task: bring it under 5 minutes without changing output. Action: I profiled with perf, confirmed the hot loop, replaced the search with an unordered_map keyed by product ID built once with reserve, and added a regression test. Result: the job finished in about 3 minutes and the team adopted profiling before optimising.
07
What is the difference between stack and heap memory?
Stack memory holds local variables and call frames; allocation is very fast and automatic, and memory is freed when the scope ends, but the size is limited to a few megabytes. Heap memory is allocated at run time with new or by containers, is much larger and lives until it is freed, but allocation is slower and can fragment. Large, variable-size or long-lived objects belong on the heap.
vector stores elements contiguously, gives O(1) random access and fast iteration, with amortised O(1) push_back but O(n) insertion in the middle. list is a doubly linked list with O(1) insert and erase anywhere given an iterator, but no random access and poor cache use. deque supports fast insertion at both ends and random access, stored in chunks. Default to vector unless profiling says otherwise.
09
What is the difference between a declaration and a definition?
A declaration tells the compiler that a name of a certain type exists, for example extern int count; or void f(int);. A definition actually allocates storage or provides the function body. You may declare a name many times but define it only once across the whole program, which is the One Definition Rule. Headers normally hold declarations and .cpp files hold definitions.
10
Write a C++20 concept and use it to constrain a function.
const means a value cannot be modified after initialisation, but it may still be computed at run time. constexpr means the variable or function can be evaluated at compile time when its inputs are constant. With constexpr int sq(int x) { return x * x; } you can write int arr[sq(4)];. Use constexpr for array sizes, template arguments and lookup tables, and consteval when evaluation must happen at compile time.
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.
13
Write a minimal modern CMakeLists.txt for an app with a library and tests.
#include <string>
#include <utility>
void reverseInPlace(std::string& s) {
if (s.empty()) return;
std::size_t i = 0, j = s.size() - 1;
while (i < j) {
std::swap(s[i], s[j]);
++i;
--j;
}
}
// Two pointers meet in the middle: O(n) time, O(1) extra space.
15
Overload operator+ and operator<< for a Complex number class.
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.
17
Tell me about a time you designed the class structure for a module and how you handled review feedback.
Situation: I had to build a report export module supporting PDF, CSV and Excel. Task: design it so new formats were easy to add. Action: I proposed an abstract Exporter interface and a factory, shared a short design note and asked seniors to review before coding. They pointed out duplicated formatting logic, so I extracted a Formatter helper. Result: a fourth format was later added in one day with no changes to existing classes.
#include <algorithm>
#include <vector>
void dedupSorted(std::vector<int>& v) {
std::sort(v.begin(), v.end());
v.erase(std::unique(v.begin(), v.end()), v.end());
}
// O(n log n). std::unique only removes adjacent duplicates, so sort first.
// To keep the original order, track seen values in an unordered_set instead.
19
What is function overloading and how does the compiler choose an overload?
Overloading means several functions share a name but differ in the number or types of parameters; return type alone is not enough. The compiler runs overload resolution: exact matches win, then promotions such as char to int, then standard conversions, then user-defined conversions. If two candidates are equally good the call is ambiguous and compilation fails. Name mangling gives every overload a unique linker symbol.
20
Solve two sum: return indices of two numbers that add up to a target.
A pointer is a variable that stores a memory address; it can be null, can be reassigned and supports arithmetic. A reference is an alias for an existing object; it must be initialised, cannot be reseated to another object and cannot be null in valid code. Pointers suit optional values, arrays and dynamic memory, while references give clean syntax for parameters and operator overloading.
A data race occurs when two threads access the same memory at the same time, at least one writes, and there is no synchronisation; in C++ this is undefined behaviour. A race condition is a broader logic bug where the result depends on timing, such as check-then-act on a file or a balance, even if each access is atomic. Mutexes, atomics and careful design of shared state prevent both.
23
What are the fundamental data types in C++ and their typical sizes?
The main types are bool, char, short, int, long, long long, float, double and long double. On a typical 64-bit Linux system char is 1 byte, short 2, int 4, long 8, long long 8, float 4 and double 8. The standard only guarantees minimum ranges, so check with sizeof, and use fixed-width types such as int32_t or uint64_t from <cstdint> when the exact size matters.
24
What are default arguments and what rules apply to them?
Default arguments supply values when a caller leaves out trailing arguments, for example void log(const std::string& msg, int level = 1);. Defaults must appear at the end of the parameter list and be given only once, usually in the header declaration. They are bound at compile time, so for a virtual function the default value comes from the static type of the pointer, not the dynamic type, which is a common trap.
25
Sorting a vector of large objects is slow. What can you do?
Sorting moves elements many times, so large objects that copy instead of move are expensive. First ensure the type has a noexcept move constructor. If moves are still heavy, sort a vector of indices or pointers with a comparator on the key, then reorder once if needed. Precomputing the sort key avoids repeated expensive comparisons. Use std::stable_sort only when equal-element order matters.
26
When would you use std::set versus std::priority_queue?
priority_queue is a binary heap that gives O(1) access to the largest element and O(log n) push and pop, but you cannot search or erase arbitrary elements. std::set keeps all elements sorted with O(log n) insert, erase and find, and gives both minimum and maximum. Use priority_queue for schedulers and Dijkstra, and set or multiset when you must update or remove arbitrary items.
27
Sort a vector of pairs by the second value in descending order, breaking ties by the first value.
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.
29
Compare pass by value, pass by pointer and pass by reference.
Pass by value copies the argument, so changes inside the function do not affect the caller. Pass by pointer passes an address, can be null and needs dereferencing. Pass by reference creates an alias that cannot be null and uses normal syntax. A good rule: pass small types such as int by value, large read-only objects by const reference, and use a non-const reference or pointer for output parameters.
30
What is the difference between struct and class in C++?
The only language difference is default access. Members and base classes of a struct are public by default, while in a class they are private by default. Both can have constructors, member functions, inheritance and templates. By convention a struct is used for simple data aggregates such as a Point, and a class is used for types that protect invariants with private state.
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.
32
Memory leaks appear when derived objects stored as Base* are deleted. What is wrong and how do you fix it?
The base class almost certainly has a non-virtual destructor, so delete through a Base* runs only the base destructor and the derived members, such as buffers or file handles, are never released. Add virtual ~Base() = default; to the base. Better still, store the objects as std::unique_ptr<Base> so deletion is automatic, and enable -Wdelete-non-virtual-dtor to catch this at compile time.
C++ is a compiled, statically typed, multi-paradigm language built on top of C. It adds classes, inheritance, templates, exceptions, namespaces, references, function overloading and a large Standard Library, while C is purely procedural. C++ keeps the low-level control and speed of C, which is why it is used in game engines, trading systems, browsers, databases, compilers and embedded firmware where performance and hardware access matter.
34
Explain the stages of compiling and running a C++ program.
There are four stages. The preprocessor expands #include directives and macros into a translation unit. The compiler turns each translation unit into assembly and then an object file. The linker combines object files and libraries and resolves symbols into an executable. At run time the loader maps it into memory. A missing function body therefore shows up as a linker error, not a compiler error.
35
Write a Shape hierarchy with a virtual area function and use it polymorphically.
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.
37
A program does millions of lookups in a std::map with string keys and is slow. How would you speed it up?
If ordering is not needed, switch to std::unordered_map and call reserve with the expected size to avoid rehashing. For string keys, use heterogeneous lookup with string_view to avoid building temporary strings. If keys are fixed after loading, a sorted vector with binary search is very cache friendly. I would profile before and after, because hashing long strings has its own cost.
38
Why did you choose C++ for your career instead of a language like Python or Java?
Situation: in college I built a small game and a file compressor in Python and hit performance limits. Task: I wanted to understand what happens closer to the hardware. Action: I learned C++ properly, including memory management, STL and multithreading, and rewrote the compressor. Result: it ran about ten times faster and I understood systems much better. I enjoy work where that control matters, while I still use Python for scripting.
39
What is the difference between std::map and std::unordered_map?
std::map is usually a red-black tree: keys are kept sorted and lookup, insert and erase are O(log n). std::unordered_map is a hash table with average O(1) operations but no ordering, and worst case O(n) with many collisions. Use map when you need ordered iteration or range queries like lower_bound, and unordered_map for fast key lookups where order does not matter.
40
Code that erases elements from a vector inside a range-based for loop crashes. Why, and what is the correct way?
erase invalidates the iterator being used by the loop, so the next increment is undefined behaviour. Range-based for loops cannot handle this safely. Use the iterator returned by erase: for (auto it = v.begin(); it != v.end();) { if (bad(*it)) it = v.erase(it); else ++it; }. Better still, use std::erase_if, which is O(n) overall instead of O(n squared) for repeated erases.
Frequently asked questions
What does a Junior C++ Developer do?
A junior C++ developer writes and maintains features in an existing codebase under the guidance of senior engineers. Daily work includes fixing bugs, writing unit tests, using STL containers correctly and following team coding standards. Interviews focus on language basics, pointers, OOP, STL and data structure problems. Freshers from B.Tech, BCA or MCA backgrounds with solid C++ fundamentals and a couple of projects can target this role at product, services and embedded companies.
Which skills are tested in a Junior C++ Developer interview?
Expect questions on Core C++ syntax, OOP design, STL containers, Unit testing, Debugging with gdb. Most rounds also ask you to explain a project and solve one practical problem live.
How do I prepare for a Junior C++ Developer interview?
Revise C++ Basics and Syntax, Object-Oriented Programming in C++, Standard Template Library (STL) first using the topic sheets, practise the questions on this page aloud, then do one full mock interview to practise timing.