Skip to content

C++ Interview Questions in Gurgaon

36 practice questions with answers for C++ interviews in Gurgaon.

C++ jobs in Gurgaon

Gurgaon (Gurugram) is home to many multinational, consulting, fintech and consumer-internet offices. Interviews often expect strong business understanding along with technical skills, especially for analytics and product-facing roles.

Below are 36 questions that match the mix of service, product and domain employers hiring junior c++ developers in Gurgaon.

Solved for GurgaonStart 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

Use std::variant and std::visit to handle different message types.

Save to ▾
Show answer
#include <iostream> #include <string> #include <variant> struct Login { std::string user; }; struct Logout { int sessionId; }; using Message = std::variant<Login, Logout>; template <class... Ts> struct Overloaded : Ts... { using Ts::operator()...; }; void handle(const Message& m) { std::visit(Overloaded{ [](const Login& l) { std::cout << "login " << l.user << '\n'; }, [](const Logout& o) { std::cout << "logout " << o.sessionId << '\n'; }}, m); } // Adding a new type without a handler becomes a compile error.
02

What are AddressSanitizer, UndefinedBehaviorSanitizer and ThreadSanitizer?

Save to ▾
Show answer
They are compiler instrumentation tools in GCC and Clang. ASan, -fsanitize=address, detects out-of-bounds access, use-after-free, double free and leaks with about 2x slowdown. UBSan, -fsanitize=undefined, catches signed overflow, invalid shifts and null dereferences. TSan, -fsanitize=thread, detects data races but cannot be combined with ASan. Running tests under sanitizers in CI catches bugs long before production.
03

Use a C++20 ranges pipeline to get squares of the first three even numbers.

Save to ▾
Show answer
#include <iostream> #include <ranges> #include <vector> int main() { std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8}; auto result = v | std::views::filter([](int x) { return x % 2 == 0; }) | std::views::transform([](int x) { return x * x; }) | std::views::take(3); for (int x : result) std::cout << x << ' '; // 4 16 36 } // Views are lazy: elements are processed only while iterating.
04

What does noexcept mean and why should move constructors be noexcept?

Save to ▾
Show answer
noexcept promises a function will not throw; if it does, std::terminate is called. Containers rely on this: when std::vector reallocates, it moves elements only if the move constructor is noexcept, otherwise it copies them to keep the strong exception guarantee. So a missing noexcept on a move constructor can silently make vector growth much slower. Destructors are noexcept by default.
05

Two objects hold shared_ptr references to each other and their memory is never released. Why, and how do you fix it?

Save to ▾
Show answer
This is a reference cycle. Each object keeps the other's reference count above zero, so neither destructor runs even after all outside pointers are gone. Fix it by making one direction non-owning, usually the back pointer, with weak_ptr. For example, a parent holds shared_ptr to its children, while each child holds a weak_ptr to the parent and calls lock() when it needs access.
06

What is C++ and how is it different from C?

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

How do you create a thread in C++ and what is the difference between join and detach?

Save to ▾
Show answer
std::thread t(func, args); starts a new thread running func. join() blocks until the thread finishes, so the caller can safely use its results. detach() lets the thread run independently; you lose the handle and it must not touch objects that may be destroyed. If a joinable std::thread is destroyed without join or detach, std::terminate is called. C++20 std::jthread joins automatically in its destructor.
08

Find the middle node of a linked list in a single pass.

Save to ▾
Show answer
Node* middle(Node* head) { Node* slow = head; Node* fast = head; while (fast && fast->next) { slow = slow->next; fast = fast->next->next; } return slow; } // fast moves two steps and slow one step, so slow stops at the middle.
09

Write a custom hash so a struct can be used as a key in std::unordered_map.

Save to ▾
Show answer
#include <functional> #include <string> #include <unordered_map> struct Point { int x, y; bool operator==(const Point&) const = default; }; struct PointHash { std::size_t operator()(const Point& p) const noexcept { std::size_t h1 = std::hash<int>{}(p.x); std::size_t h2 = std::hash<int>{}(p.y); return h1 ^ (h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2)); } }; std::unordered_map<Point, std::string, PointHash> grid;
10

A hot loop calls a virtual function millions of times and profiling shows the indirect call cost. What can you do?

Save to ▾
Show answer
Options include static polymorphism with CRTP or templates so calls can be inlined, marking classes or functions final so the compiler can devirtualise, and batching work by type so each loop handles one concrete class. Another option is replacing the hierarchy with std::variant and std::visit. I would confirm with a benchmark first, because often memory layout matters more than the virtual call itself.
11

List the gdb commands you would use to debug a crash.

Save to ▾
Show answer
g++ -g -O0 main.cpp -o app # build with debug symbols gdb ./app # or: gdb ./app core (gdb) run arg1 arg2 # start the program (gdb) bt # backtrace after the crash (gdb) frame 2 # select a stack frame (gdb) info locals # show local variables (gdb) print ptr->size # inspect an expression (gdb) break order.cpp:42 # set a breakpoint (gdb) watch total # stop when a variable changes (gdb) next / step / continue # step over, step into, resume
12

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.
13

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.
14

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.
15

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.
16

Explain move semantics and what std::move actually does.

Save to ▾
Show answer
Move semantics let an object transfer its resources, such as a heap buffer, to another object instead of copying them. A move constructor takes T&& and usually steals the pointer and leaves the source empty but valid. std::move does not move anything; it is just a cast to an rvalue reference that allows a move overload to be chosen. After moving, only assign to or destroy the source.
17

Why should we hire you for this C++ developer role?

Save to ▾
Show answer
Situation: I have prepared specifically for systems-level roles. Task: show I can contribute quickly. Action: I have built projects such as a multithreaded log analyser and a small key-value store in modern C++, used CMake, GoogleTest and sanitizers, and practised data structures and debugging with gdb. Result: I can write safe, measurable, well-tested code from the first sprint, and I learn fast from code reviews and feedback.
18

What are the iterator categories in C++?

Save to ▾
Show answer
Input and output iterators support a single pass, such as stream iterators. Forward iterators allow multiple passes, as in forward_list. Bidirectional iterators also move backwards, as in list, map and set. Random access iterators support jumps and arithmetic, as in vector and deque, and C++20 adds contiguous iterators. Algorithms require a minimum category, so std::sort needs random access and cannot sort a std::list.
19

The linker reports undefined reference to a function that is declared in a header. What could be wrong?

Save to ▾
Show answer
The declaration exists but the linker finds no definition. Common causes: the .cpp file with the body is not compiled or not linked, the signature differs slightly such as const, namespace or parameter type, a template is defined in a .cpp file instead of the header, a C function is called without extern C linkage, or a library is missing from the link command or listed in the wrong order.
20

Explain the stages of compiling and running a C++ program.

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

Your program crashes with the message double free or corruption. What could cause it?

Save to ▾
Show answer
The same block was freed twice or heap metadata was overwritten. Typical causes are a class with a raw owning pointer and the default copy constructor, deleting the same pointer in two places, mixing delete and delete[], or a buffer overflow writing past an allocation. AddressSanitizer shows the first invalid free and where the memory was allocated. The lasting fix is clear ownership with smart pointers or containers.
22

What is undefined behaviour in C++? Give examples.

Save to ▾
Show answer
Undefined behaviour means the standard places no requirement on the result, so the program may crash, print garbage or appear to work. Examples are signed integer overflow, reading an uninitialised variable, out-of-bounds array access, dereferencing a null or dangling pointer and data races. Optimisers assume UB never happens and remove checks based on that, so such bugs often appear only in optimised release builds.
23

What is a pointer and how is it different from a reference?

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

What are C++20 concepts?

Save to ▾
Show answer
Concepts are named compile-time predicates on template parameters. You can write template <std::integral T> T gcd(T a, T b) or define your own with a requires expression. If a type does not satisfy the concept, the compiler reports a short, readable error at the call site instead of pages of instantiation errors. Concepts also allow overloading by constraint and document the template's expectations.
25

When would you use std::set versus std::priority_queue?

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

Implement a thread-safe singleton in modern C++.

Save to ▾
Show answer
class Config { public: static Config& instance() { static Config inst; // initialised once, thread-safe since C++11 return inst; } Config(const Config&) = delete; Config& operator=(const Config&) = delete; private: Config() = default; }; // The Meyers singleton relies on magic statics; no mutex or double-checked locking needed.
27

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.
28

When do you need the typename keyword inside a template?

Save to ▾
Show answer
Inside a template, a name that depends on a template parameter, such as T::value_type, could be a type or a static member, so the compiler assumes it is a value. You must write typename T::value_type x; to say it is a type. Similarly, a dependent member template needs the template keyword, as in obj.template get<0>(). C++20 relaxes this in some contexts, but the rule still matters.
29

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.
30

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.
31

Implement a simple fixed-size thread pool.

Save to ▾
Show answer
#include <condition_variable> #include <functional> #include <mutex> #include <queue> #include <thread> #include <vector> class ThreadPool { std::vector<std::thread> workers_; std::queue<std::function<void()>> tasks_; std::mutex m_; std::condition_variable cv_; bool stop_ = false; public: explicit ThreadPool(std::size_t n) { for (std::size_t i = 0; i < n; ++i) workers_.emplace_back([this] { while (true) { std::function<void()> task; { std::unique_lock<std::mutex> lk(m_); cv_.wait(lk, [this] { return stop_ || !tasks_.empty(); }); if (stop_ && tasks_.empty()) return; task = std::move(tasks_.front()); tasks_.pop(); } task(); } }); } void submit(std::function<void()> f) { { std::lock_guard<std::mutex> lk(m_); tasks_.push(std::move(f)); } cv_.notify_one(); } ~ThreadPool() { { std::lock_guard<std::mutex> lk(m_); stop_ = true; } cv_.notify_all(); for (auto& w : workers_) w.join(); } };
32

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.
33

Describe a time you improved code quality by changing how memory was managed.

Save to ▾
Show answer
Situation: our module used raw new and delete everywhere and QA reported frequent leaks. Task: make it safe without a full rewrite. Action: I proposed a step-by-step migration to unique_ptr and std::vector, wrote a one-page ownership guideline and enabled LeakSanitizer in CI so new leaks failed the build. Result: leak reports dropped to zero within two sprints and reviews became faster because ownership was obvious.
34

Reverse a singly linked list using pointers.

Save to ▾
Show answer
struct Node { int val; Node* next; }; Node* reverse(Node* head) { Node* prev = nullptr; while (head) { Node* nxt = head->next; head->next = prev; prev = head; head = nxt; } return prev; } // O(n) time, O(1) extra space.
35

Write a variadic function that sums any number of arguments and one that prints them.

Save to ▾
Show answer
#include <iostream> template <typename... Args> auto sum(Args... args) { return (args + ...); // unary right fold } template <typename... Args> void printAll(const Args&... args) { ((std::cout << args << ' '), ...); // comma fold std::cout << '\n'; } // sum(1, 2, 3.5) returns 6.5; printAll(1, 'x', 2.5) prints 1 x 2.5
36

Why should you prefer make_unique and make_shared over calling new directly?

Save to ▾
Show answer
They avoid writing raw new, so no allocated object can leak if another expression in the same call throws. make_shared also allocates the object and the control block together in one allocation, which is faster and more cache friendly. One trade-off: with make_shared the memory block stays allocated until every weak_ptr is gone, which matters for very large objects.

Companies with offices in Gurgaon (6)

Frequently asked questions

Which companies hire C++ professionals in Gurgaon?

Companies with large offices in Gurgaon include Microsoft, Google, Amazon, Adobe, DE Shaw, Tower Research Capital. Use their company pages below to practise employer-specific sets.

Are C++ interviews in Gurgaon different from other cities?

The questions depend more on the company than the city. Gurgaon's mix of employers decides the style: Interviews often expect strong business understanding along with technical skills, especially for analytics and product-facing roles

How do I find C++ jobs in Gurgaon?

Shortlist companies with Gurgaon offices, keep your CV focused on C++ projects, apply on company career pages and job portals with the Gurgaon filter, and practise the questions on this page before each interview.