Standard Template Library (STL) Interview Questions for C++
25 Standard Template Library (STL) questions with answers for c++ roles — 7 easy, 13 medium, 5 hard.
About Standard Template Library (STL)
Master containers such as vector, deque, list, map, set, unordered_map and priority_queue, along with iterators and algorithms. Learn complexity guarantees, iterator invalidation, custom comparators and hashes, and how to pick the right container. These skills are tested heavily in coding rounds and daily development work.
Sheet progressStart 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
What are the main components of the Standard Template Library?
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.
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.
03
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.
04
Sort a vector of pairs by the second value in descending order, breaking ties by the first value.
#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.
07
Describe a time you had to learn a new library or API quickly.
Situation: during my internship I was asked to fix a bug in code using Boost.Asio, which I had never used. Task: understand enough to fix it within the sprint. Action: I read the official examples, wrote a tiny echo server to learn the async model, then traced the bug to a missing handler for connection timeouts. Result: I fixed it in four days and wrote a short internal note for the next new joiner.
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.
09
How does std::vector grow, and what is the difference between size, capacity and reserve?
size is the number of stored elements; capacity is how many fit before reallocation. When push_back exceeds capacity, vector allocates a larger buffer, typically 1.5 or 2 times larger, moves or copies elements and frees the old one, giving amortised O(1) appends. reserve(n) pre-allocates capacity to avoid repeated reallocations when the final size is known; shrink_to_fit requests releasing unused capacity.
10
What is the difference between push_back and emplace_back?
push_back takes an existing object, copying or moving it into the container. emplace_back forwards constructor arguments and builds the element directly in place, which can avoid a temporary. For example v.emplace_back(name, age) constructs a Person inside the vector. The gain is small when you already have an object, and emplace_back can call explicit constructors unexpectedly, so use it deliberately.
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.
12
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.
13
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.
14
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.
15
Using a custom struct as the key of an unordered_map gives a compile error. Why, and how do you fix it?
unordered_map needs a hash function and equality comparison for the key type, and std::hash is not defined for user structs. Fix it by defining operator== (or defaulting it in C++20) and providing a hash functor that combines member hashes, passed as the third template argument, or by specialising std::hash for the type. std::map instead needs operator< or a comparator.
16
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.
17
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.
18
Write a custom hash so a struct can be used as a key in std::unordered_map.
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.
21
You need to build an LRU cache with O(1) get and put. Which containers would you use?
Combine a doubly linked list with a hash map. std::list stores key-value pairs in usage order, with the most recent at the front. std::unordered_map maps each key to its list iterator. On get, splice the node to the front in O(1). On put, update or insert at the front and, if over capacity, remove the back node and its map entry. list iterators stay valid after splice, which makes this work.
22
You must find the top 100 most frequent items in a stream of 10 million events. How would you do it?
Count frequencies with an unordered_map reserved to the expected key count. Then keep a min-heap, a priority_queue with greater comparator, of size 100: push each entry and pop when size exceeds 100, which costs O(n log k). Alternatively copy counts into a vector and use std::nth_element for O(n) average. If memory is limited and approximate results are fine, a Count-Min sketch helps.
23
Code that takes bool& from a std::vector<bool> fails to compile. Why?
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.
Situation: a colleague's change stored pointers to vector elements in a map and then appended to the vector. Task: flag the risk without discouraging them. Action: I commented with a short example showing reallocation invalidating the pointers, suggested storing indices or using std::deque, and offered to pair on the fix. Result: the bug was fixed before release, and we added a checklist item on iterator invalidation for reviews.
Frequently asked questions
How important is Standard Template Library (STL) in C++ interviews?
Master containers such as vector, deque, list, map, set, unordered_map and priority_queue, along with iterators and algorithms. Learn complexity guarantees, iterator invalidation, custom comparators and hashes, and how to pick the right container. These skills are tested heavily in coding rounds and daily development work.
How should I use the Standard Template Library (STL) sheet?
Go top to bottom — easy to hard. Answer before opening each answer, tick what you solved and save misses to Last-Minute Revision.