Skip to content

Qualcomm C++ Interview Questions & Answers

Curated interview practice questions with answers. These are practice scenarios, not a verified list of past interview questions.

About Qualcomm hiring for C++ roles

Qualcomm designs semiconductors and wireless technologies, including Snapdragon processors, modems and connectivity chips for smartphones, PCs, automotive and IoT. Its India centres in Hyderabad and Bengaluru are major engineering sites for software, hardware and testing. It hires for embedded software engineers, test engineers, hardware engineers and data roles.

For C++ roles, this Qualcomm practice set focuses most on Object-Oriented Programming in C++ (7), Pointers and Memory Management (6), Multithreading and Concurrency (5), Performance, Debugging and Build Tools (4). It has 2 easy, 20 medium, 8 hard questions, so you can start easy and work up to the harder ones.

Company type
Hardware & semiconductors
Headquarters
San Diego, California, USA
Main India offices
Hyderabad, Bengaluru, Chennai

Qualcomm C++ interview process

  1. Online assessment (aptitude + technical + coding)
  2. Technical round 1
  3. Technical round 2
  4. Managerial round
  5. HR round

Typical pattern based on public candidate experiences. Rounds vary by role, team and year.

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

Should a Car class inherit from Engine or contain an Engine? Explain your choice.

Save to ▾
Show answer
A car is not an engine, it has an engine, so composition is correct: class Car holds an Engine member or a unique_ptr<Engine>. Inheritance models an is-a relationship and exposes the base interface, which would let callers treat a Car as an Engine. Composition also allows swapping engine types at run time through an interface such as PetrolEngine or ElectricMotor and keeps coupling low.
02

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

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

A program that prints a million lines with std::endl is very slow. Why, and how do you fix it?

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

A function taking a Money object is silently called with an int and gives wrong results. What is happening?

Save to ▾
Show answer
Money probably has a single-argument constructor such as Money(int paise) that is not marked explicit, so the compiler performs an implicit conversion from int. A call like pay(500) compiles even though the unit is unclear. Mark single-argument constructors explicit, so callers must write pay(Money(500)). Also consider strong types or named factory functions like Money::fromRupees to make units obvious.
06

How do you prioritise when a critical bug and a feature deadline arrive at the same time?

Save to ▾
Show answer
Situation: a customer-facing crash was reported two days before a feature demo. Task: handle both without dropping quality. Action: I informed my lead immediately, estimated both tasks, and we agreed the crash came first because it affected users. I fixed and released it in half a day, then cut one optional part of the feature after agreeing with the product owner. Result: the crash was resolved and the demo went ahead on time.
07

You call a virtual function from a base class constructor but the derived override never runs. Why?

Save to ▾
Show answer
During base construction the derived part does not exist yet, so the object's dynamic type is the base and the vptr points to the base vtable. Virtual calls in constructors and destructors therefore go to the version of the class currently being built. Calling a pure virtual this way is undefined. Fix it with a two-phase init method called after construction or a factory function that constructs and then configures.
08

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

Write a deadlock-free money transfer between two bank accounts.

Save to ▾
Show answer
#include <mutex> #include <stdexcept> struct Account { std::mutex m; long long balance = 0; }; void transfer(Account& from, Account& to, long long amount) { if (&from == &to) return; std::scoped_lock lock(from.m, to.m); // locks both without deadlock if (from.balance < amount) throw std::runtime_error("insufficient funds"); from.balance -= amount; to.balance += amount; }
10

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

What is the difference between new/delete and malloc/free?

Save to ▾
Show answer
new allocates memory and calls the constructor, returns a typed pointer and throws std::bad_alloc on failure. malloc only allocates raw bytes, returns void* and gives a null pointer on failure without calling any constructor. delete runs the destructor and then frees memory, while free does not run destructors. Never mix them, and always pair new[] with delete[].
12

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

Describe a situation where you disagreed with a senior engineer about a design decision.

Save to ▾
Show answer
Situation: a senior wanted a deep inheritance hierarchy for device drivers. Task: I believed composition would be simpler to test. Action: instead of arguing in the meeting, I built a small prototype of both designs, measured test setup effort and shared the results calmly, while accepting that the final call was theirs. Result: we chose a hybrid with a thin interface plus composition, and the senior later asked me to document it for the team.
14

Write a micro-benchmark with Google Benchmark comparing two approaches.

Save to ▾
Show answer
#include <benchmark/benchmark.h> #include <list> #include <numeric> #include <vector> static void BM_VectorSum(benchmark::State& state) { std::vector<int> v(state.range(0), 1); for (auto _ : state) benchmark::DoNotOptimize(std::accumulate(v.begin(), v.end(), 0)); } BENCHMARK(BM_VectorSum)->Range(1 << 10, 1 << 20); static void BM_ListSum(benchmark::State& state) { std::list<int> l(state.range(0), 1); for (auto _ : state) benchmark::DoNotOptimize(std::accumulate(l.begin(), l.end(), 0)); } BENCHMARK(BM_ListSum)->Range(1 << 10, 1 << 20); BENCHMARK_MAIN();
15

Compare std::mutex, lock_guard, unique_lock and scoped_lock.

Save to ▾
Show answer
std::mutex provides lock and unlock, but calling them manually is error-prone. lock_guard is a simple RAII wrapper that locks in the constructor and unlocks in the destructor. unique_lock is more flexible: it can defer locking, unlock early, be moved and is required by condition_variable. scoped_lock, from C++17, locks one or more mutexes at once using a deadlock-avoidance algorithm.
16

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

How would you explain polymorphism to a junior developer who has just joined your team?

Save to ▾
Show answer
Situation: a new joiner was confused by virtual functions in our codebase. Task: help them become productive quickly. Action: I used a real example from our code, a Notifier base class with Email and Sms versions, drew how the vtable decides the call at run time, and gave them a small task to add a WhatsApp notifier. Result: they finished it in a day and later explained the idea to the next intern.
18

Many threads read a shared configuration object constantly, but it changes only once an hour. How do you synchronise it efficiently?

Save to ▾
Show answer
A plain mutex would serialise all readers. Option one is std::shared_mutex: readers take shared_lock and run in parallel, the updater takes unique_lock. Option two, often faster, is to keep the config in a std::shared_ptr<const Config> and swap in a new immutable object atomically with std::atomic<std::shared_ptr> in C++20; readers grab a copy of the pointer and never block the writer.
19

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

Explain the rule of three, rule of five and rule of zero.

Save to ▾
Show answer
Rule of three: if a class needs a custom destructor, copy constructor or copy assignment, it usually needs all three because it manages a resource. Rule of five adds the move constructor and move assignment from C++11. Rule of zero says the best design avoids writing any of them by holding resources in members such as std::vector, std::string and unique_ptr, which already manage themselves.
21

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;
22

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); }
23

Overload operator+ and operator<< for a Complex number class.

Save to ▾
Show answer
#include <ostream> class Complex { double re_, im_; public: Complex(double re = 0, double im = 0) : re_(re), im_(im) {} Complex operator+(const Complex& o) const { return Complex(re_ + o.re_, im_ + o.im_); } friend std::ostream& operator<<(std::ostream& os, const Complex& c) { return os << c.re_ << (c.im_ < 0 ? '-' : '+') << (c.im_ < 0 ? -c.im_ : c.im_) << 'i'; } }; // operator<< is a friend non-member so the stream stays on the left side.
24

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

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
26

What is the erase-remove idiom and what replaced it in C++20?

Save to ▾
Show answer
std::remove does not delete elements; it shifts the kept elements forward and returns an iterator to the new logical end. You then call erase to shrink the container: v.erase(std::remove(v.begin(), v.end(), 0), v.end());. remove_if works the same with a predicate. C++20 adds std::erase(v, value) and std::erase_if(v, pred), which do both steps in one call.
27

You parallelised a loop across eight threads but it became slower than the single-threaded version. What could be wrong?

Save to ▾
Show answer
Likely causes are lock contention when all threads share one mutex, false sharing when per-thread counters sit on the same 64-byte cache line, too little work per task so thread creation dominates, or memory bandwidth limits. I would profile with perf, pad per-thread data with alignas(64) or std::hardware_destructive_interference_size, use thread-local accumulation and a thread pool, and make chunks larger.
28

An asynchronous callback crashes intermittently. It is a lambda that captures local variables by reference. Explain the problem and fix.

Save to ▾
Show answer
The lambda runs later on another thread or event loop, after the function that created it has returned, so the captured references point to destroyed stack variables. Fix it by capturing by value, moving owned data into the lambda with init captures, or capturing a shared_ptr or weak_ptr for objects whose lifetime must be extended or checked. Avoid default [&] for any callback that can outlive the scope.
29

Your program gives correct output in a debug build but wrong output in a release build. How do you investigate?

Save to ▾
Show answer
This usually means undefined behaviour or an uninitialised variable that the optimiser exploits. I would compile with -Wall -Wextra and fix every warning, then run tests with -fsanitize=address,undefined to catch out-of-bounds access, overflow and use-after-free. ThreadSanitizer checks for data races. Building with -O2 -g lets me debug the optimised code, and bisecting functions or adding assertions narrows down the faulty spot.
30

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.

Tips to crack the Qualcomm C++ interview

  • Revise C programming, pointers, operating systems and computer architecture for embedded software roles.
  • Learn basics of wireless communication like 4G and 5G, and what a system-on-chip does.
  • Read about Snapdragon platforms and Qualcomm's work in automotive and AI PCs.
  • Keep a one-minute story ready for every project on your CV: problem, your part, tools, result.
  • Practise the hard questions on this page aloud; Qualcomm interviewers usually ask follow-ups on your first answer.

Frequently asked questions

How many rounds are there in the Qualcomm C++ interview?

Candidates usually go through 5 stages: Online assessment (aptitude + technical + coding); Technical round 1; Technical round 2; Managerial round; HR round. The exact rounds change with the role, team, location and your experience, so confirm the process with the recruiter.

Which topics should I prepare for the Qualcomm C++ interview?

This practice set leans on Object-Oriented Programming in C++ (7), Pointers and Memory Management (6), Multithreading and Concurrency (5), Performance, Debugging and Build Tools (4). Revise those first, then practise explaining one or two of your own projects end to end, because most Qualcomm interviewers ask you to walk through real work.

Are these the exact questions asked at Qualcomm?

No. These are curated practice questions that match the skills and difficulty usually tested in hardware & semiconductors interviews like Qualcomm's. They are not a leaked or verified list of past questions.

Where does Qualcomm hire C++ professionals in India?

Qualcomm has large teams in Hyderabad, Bengaluru, Chennai. Openings and locations change often, so check the Qualcomm careers page and filter by city and experience.

C++ questions for similar companies