Curated interview practice questions with answers. These are practice scenarios, not a verified list of past interview questions.
About Amazon hiring for C++ roles
Amazon is a global technology company spanning e-commerce, cloud computing through AWS, devices, advertising and streaming. In India it runs large engineering, operations and analytics teams supporting both Amazon.in and global businesses. It hires for software development engineers, SDETs, quality assurance engineers, business intelligence engineers, data engineers and data scientists.
For C++ roles, this Amazon practice set focuses most on Multithreading and Concurrency (6), Performance, Debugging and Build Tools (5), Standard Template Library (STL) (4), Templates and Generic Programming (4). It has 1 easy, 17 medium, 12 hard questions, so you can start easy and work up to the harder ones.
Company type
Product
Headquarters
Seattle, USA
Main India offices
Bengaluru, Hyderabad, Chennai, Pune, Gurugram
Amazon C++ interview process
Online assessment (coding + work style survey)
Technical round 1 (DSA)
Technical round 2 (DSA or system design)
Bar raiser round
Hiring manager round
Typical pattern based on public candidate experiences. Rounds vary by role, team and year.
Solved for AmazonStart 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
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.
02
Two third-party libraries both define a global function called init and your build fails with duplicate symbols. How do you fix it?
The clean fix is to place each library's code in its own namespace so calls become liba::init and libb::init. If the source cannot change, I would check whether one function is only used internally and give it internal linkage, or wrap one library behind a shared library that hides its symbols using visibility settings. I avoid macro renaming hacks because they break silently on upgrades.
03
Write a deadlock-free money transfer between two bank accounts.
Templates give static polymorphism: resolved at compile time, inlinable and fast, but types must be known at compile time and code size grows. Virtual functions give dynamic polymorphism: one compiled body, types can be chosen at run time, plugins are possible, at the cost of an indirect call. I use templates for performance-critical generic algorithms and virtual interfaces for runtime-configurable components.
05
A production service's memory usage grows steadily over several days. How do you find the cause?
First confirm it is a real leak and not a cache or allocator fragmentation by tracking RSS and allocator statistics. Then reproduce in staging with a heap profiler such as heaptrack or jemalloc profiling and compare snapshots to see which call stacks keep growing. LeakSanitizer catches lost blocks. Common culprits are unbounded maps, shared_ptr cycles and listeners never removed. After the fix, add a long soak test.
06
You call a virtual function from a base class constructor but the derived override never runs. Why?
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.
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.
If each update loop touches only a few fields, such as position and velocity, a struct of arrays keeps those fields contiguous, so every cache line is fully used and the compiler can vectorise with SIMD. An array of structs is simpler and better when most fields of one particle are used together. I would benchmark both, and often a hybrid that groups hot fields together works best.
11
Implement a simple String class that follows the rule of five.
I would measure with Clang -ftime-trace or build tooling to find the slowest files and headers. Then reduce header dependencies using forward declarations and the pimpl idiom, use Ninja for parallel builds, enable ccache or sccache, add precompiled headers for stable heavy headers, and split huge translation units. Unity builds and distributed compilation also help, and CI can cache build outputs.
13
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.
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.
16
A function returns a string_view and callers sometimes print garbage. What is the likely bug?
The function probably builds or receives a temporary std::string and returns a string_view into it. When the function returns, the string is destroyed and the view dangles. Examples are returning std::string_view(a + b) or a view of a local string. Fix it by returning std::string, or make sure the view refers to data with a longer lifetime, such as a member or static storage.
17
A generic maxOf template gives wrong results when called with two C-style string literals. Why, and how do you fix it?
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.
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.
19
Show the compiler commands to build with strict warnings and sanitizers enabled.
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.
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.
24
Tell me about a concurrency bug you investigated and how you solved it.
Situation: a market data service dropped a few updates per day only under heavy load. Task: find the cause without disrupting trading hours. Action: I wrote a stress harness replaying recorded traffic, ran it under ThreadSanitizer and found two threads updating a shared index without synchronisation. I redesigned it to a single-writer model with an SPSC queue. Result: zero dropped updates over a month and latency improved slightly because locks were removed.
25
A function taking a Money object is silently called with an int and gives wrong results. What is happening?
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.
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.
std::vector<bool> is a special case that packs bits, so elements are not real bool objects and operator[] returns a proxy object, not bool&. You cannot take a reference or pointer to a single element, and it is not thread-safe to write neighbouring elements from different threads. If you need real bools use std::vector<char>, std::deque<bool>, or std::bitset when the size is fixed.
29
Write a custom hash so a struct can be used as a key in std::unordered_map.
Situation: our risk calculation batch took 90 minutes and blocked morning reports. Task: bring it under 30 minutes. Action: I profiled with perf and found most time in allocating small objects and a map lookup inside the inner loop. I preallocated buffers, replaced the map with a flat sorted vector and parallelised independent portfolios with a thread pool, validating outputs against the old version. Result: 22 minutes, with identical numbers.
Tips to crack the Amazon C++ interview
Prepare STAR-format stories for each Amazon Leadership Principle, such as Customer Obsession, Ownership and Dive Deep.
Practise medium-level DSA problems on arrays, trees, graphs and dynamic programming, explaining time and space complexity aloud.
For BIE or data roles, practise SQL window functions and metric-driven case questions on e-commerce funnels and delivery operations.
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; Amazon interviewers usually ask follow-ups on your first answer.
Frequently asked questions
How many rounds are there in the Amazon C++ interview?
Candidates usually go through 5 stages: Online assessment (coding + work style survey); Technical round 1 (DSA); Technical round 2 (DSA or system design); Bar raiser round; Hiring manager 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 Amazon C++ interview?
This practice set leans on Multithreading and Concurrency (6), Performance, Debugging and Build Tools (5), Standard Template Library (STL) (4), Templates and Generic Programming (4). Revise those first, then practise explaining one or two of your own projects end to end, because most Amazon interviewers ask you to walk through real work.
Are these the exact questions asked at Amazon?
No. These are curated practice questions that match the skills and difficulty usually tested in product interviews like Amazon's. They are not a leaked or verified list of past questions.
Where does Amazon hire C++ professionals in India?
Amazon has large teams in Bengaluru, Hyderabad, Chennai, Pune, Gurugram. Openings and locations change often, so check the Amazon careers page and filter by city and experience.