Curated interview practice questions with answers. These are practice scenarios, not a verified list of past interview questions.
About Bloomberg hiring for C++ roles
Bloomberg is a financial data, software and media company best known for the Bloomberg Terminal used by finance professionals. It provides market data, analytics, news and trading tools. Its India presence includes Mumbai-based teams, and its interviews for engineering and data roles focus on problem solving and an interest in financial markets.
For C++ roles, this Bloomberg practice set focuses most on Performance, Debugging and Build Tools (5), Object-Oriented Programming in C++ (4), Templates and Generic Programming (4), Standard Template Library (STL) (4). It has 2 easy, 23 medium, 5 hard questions, so you can start easy and work up to the harder ones.
Company type
Fintech
Headquarters
New York, USA
Main India offices
Mumbai
Bloomberg C++ interview process
Recruiter screening
Technical phone interview (coding)
Onsite technical rounds
Manager round
HR round
Typical pattern based on public candidate experiences. Rounds vary by role, team and year.
Solved for BloombergStart 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.
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
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.
03
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.
04
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.
05
Why should you prefer make_unique and make_shared over calling new directly?
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.
Slicing happens when a derived object is copied into a base object by value. Only the base part is copied, the derived data is lost and virtual calls use the base version. Example: void draw(Shape s) called with a Circle loses Circle's radius and behaviour. Avoid it by passing polymorphic objects by reference or pointer, and consider deleting copy operations in polymorphic base classes.
07
The linker reports undefined reference to a function that is declared in a header. What could be wrong?
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.
08
What are std::optional, std::variant and std::any?
std::optional<T> holds either a T or nothing, ideal for functions that may not return a value, without using magic values or pointers. std::variant<A, B> is a type-safe union that holds exactly one of the listed types, inspected with std::visit or std::get_if. std::any holds a value of any copyable type and needs any_cast to read it. Prefer optional and variant because they are checked at compile time.
09
An asynchronous callback crashes intermittently. It is a lambda that captures local variables by reference. Explain the problem and fix.
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.
10
How does std::condition_variable work and what are spurious wakeups?
A condition variable lets a thread sleep until another thread signals that some state changed. The waiter holds a unique_lock and calls cv.wait(lock, predicate), which releases the mutex while sleeping and reacquires it on wake. The notifier changes the state under the mutex and calls notify_one or notify_all. Threads can wake without notification, called spurious wakeups, so always wait with a predicate that rechecks the condition.
11
Build times have become very slow because heavy templates are included everywhere. How do you speed them up?
I would measure first with -ftime-trace or build analyzers to find the costly headers. Then reduce includes with forward declarations, move template-heavy implementation details behind non-template interfaces, use extern template with explicit instantiation for common types, enable precompiled headers and a compiler cache such as ccache, and evaluate C++20 modules where the toolchain supports them well.
12
What is the diamond problem and how does virtual inheritance solve it?
When B and C both inherit from A and D inherits from B and C, D contains two copies of A, so accessing A's members is ambiguous. Declaring class B : virtual public A and class C : virtual public A makes D share a single A subobject. The most-derived class then initialises A directly. Virtual inheritance adds pointer overhead, so it is used sparingly, usually for interface-like bases.
13
Tell me about a time you convinced your team to adopt a new C++ feature or practice.
Situation: our team avoided smart pointers, and leaks kept reaching QA. Task: get agreement to adopt unique_ptr in new code. Action: I prepared a short benchmark showing no measurable overhead, converted one leaky module as a pilot, and presented before and after defect counts at our tech sync. I also wrote clang-tidy rules to help. Result: the team agreed to make it a coding standard and leak bugs dropped sharply in the next quarter.
14
Write a deadlock-free money transfer between two bank accounts.
Make sure core dumps are enabled with ulimit -c unlimited or systemd-coredump, and keep debug symbols for release builds. Load the core with gdb binary core, run bt to see the stack trace, then inspect frames and variables. If the stack looks corrupted, reproduce in staging with AddressSanitizer. I would also check logs around the crash time and recent deployments, then add a regression test with the fix.
18
What is template argument deduction and class template argument deduction?
For function templates the compiler deduces T from the call, so maxOf(3, 7) deduces int; mixing int and double fails because T would be ambiguous. Class template argument deduction, added in C++17, lets you write std::vector v{1, 2, 3}; or std::pair p(1, 2.5); without spelling the template arguments. Deduction guides can be written to tell the compiler how to deduce types from constructors.
19
Tell me about a time you worked with QA to fix a flaky test.
Situation: a multithreaded integration test failed about once in twenty runs and QA kept reopening the ticket. Task: make it reliable without hiding a real bug. Action: I sat with the QA engineer, ran the test in a loop with logging, and saw it used sleep to wait for a worker. I replaced the sleep with a condition variable signal and fixed a small real race we found. Result: 1000 consecutive passes and better trust between dev and QA.
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.
22
What is cache locality and why does it matter for performance?
CPUs load memory in cache lines, usually 64 bytes, and access to L1 cache takes a few cycles while main memory takes hundreds. Code that walks memory sequentially, like iterating a std::vector, uses every byte loaded and lets the prefetcher help. Pointer-heavy structures like linked lists jump around memory and cause cache misses. That is why a vector often beats a list even for insert-heavy workloads.
23
Explain move semantics and what std::move actually does.
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.
24
You need a container that holds ints, strings and doubles together. Which approach would you choose?
If the set of types is fixed and known, std::vector<std::variant<int, std::string, double>> is type-safe and needs no heap per element; std::visit handles each type. If types are open-ended, std::any works but needs any_cast and loses compile-time checks. If the items share behaviour, a base class interface with unique_ptr is cleanest. I usually prefer variant for closed sets.
25
What is the erase-remove idiom and what replaced it in C++20?
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.
26
A service occasionally freezes and thread dumps show two threads each waiting on a mutex held by the other. How do you fix it?
This is a lock-order deadlock. I would find the two code paths, for example transfer locking account A then B while another locks B then A. The fix is to lock both together with std::scoped_lock(a.m, b.m), or to define a global ordering such as by account ID and always lock lower first. I would also shrink critical sections and add a stress test, and consider TSan or lock hierarchy checks.
27
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.
28
Your program crashes with the message double free or corruption. What could cause it?
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.
29
List the gdb commands you would use to debug a crash.
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
30
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.
Tips to crack the Bloomberg C++ interview
Practise DSA problems with a focus on clear communication, as Bloomberg interviewers often discuss your approach in detail.
Learn basic market concepts like stock prices, bonds and indices, since Bloomberg products serve financial users.
Read about the Bloomberg Terminal and its features so you can explain why financial data products interest you.
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; Bloomberg interviewers usually ask follow-ups on your first answer.
Frequently asked questions
How many rounds are there in the Bloomberg C++ interview?
Candidates usually go through 5 stages: Recruiter screening; Technical phone interview (coding); Onsite technical rounds; Manager 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 Bloomberg C++ interview?
This practice set leans on Performance, Debugging and Build Tools (5), Object-Oriented Programming in C++ (4), Templates and Generic Programming (4), Standard Template Library (STL) (4). Revise those first, then practise explaining one or two of your own projects end to end, because most Bloomberg interviewers ask you to walk through real work.
Are these the exact questions asked at Bloomberg?
No. These are curated practice questions that match the skills and difficulty usually tested in fintech interviews like Bloomberg's. They are not a leaked or verified list of past questions.
Where does Bloomberg hire C++ professionals in India?
Bloomberg has large teams in Mumbai. Openings and locations change often, so check the Bloomberg careers page and filter by city and experience.