Skip to content

Cisco C++ Interview Questions & Answers

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

About Cisco hiring for C++ roles

Cisco is a networking and security company making routers, switches, security products, collaboration tools such as Webex, and observability software including Splunk. Its Bengaluru campus is one of its largest R&D centres outside the US. It hires in India for software engineers, test and validation engineers, network engineers and data analysts.

For C++ roles, this Cisco practice set focuses most on Templates and Generic Programming (6), Performance, Debugging and Build Tools (5), Modern C++ (C++11 to C++23) (4), Multithreading and Concurrency (4). It has 3 easy, 20 medium, 7 hard questions, so you can start easy and work up to the harder ones.

Company type
Hardware & semiconductors
Headquarters
San Jose, California, USA
Main India offices
Bengaluru, Pune, Chennai

Cisco C++ interview process

  1. Online assessment (aptitude + networking + 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 CiscoStart 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

Write a function to reverse a string in place without using std::reverse.

Save to ▾
Show answer
#include <string> #include <utility> void reverseInPlace(std::string& s) { if (s.empty()) return; std::size_t i = 0, j = s.size() - 1; while (i < j) { std::swap(s[i], s[j]); ++i; --j; } } // Two pointers meet in the middle: O(n) time, O(1) extra space.
02

After calling std::move on a string, a teammate prints it and sees an empty value. Is this a bug?

Save to ▾
Show answer
It is a misunderstanding. A moved-from standard library object is in a valid but unspecified state; for std::string it is often empty, but you cannot rely on that. The safe operations are destroying it or assigning a new value. Reading it is not undefined behaviour, but the content is meaningless. Clang-tidy's bugprone-use-after-move check catches this pattern in code review.
03

A binary runs on your laptop but fails on the server with error while loading shared libraries. What is wrong?

Save to ▾
Show answer
The program depends on a shared library that is missing or in a different version on the server, or the loader cannot find it. I would run ldd on the binary to see unresolved libraries, then install the right package, set the rpath at link time, or ship the library alongside. A newer glibc or libstdc++ on the build machine is a common cause; build inside a container matching production, or link statically where allowed.
04

Implement a basic Observer pattern for an event publisher.

Save to ▾
Show answer
#include <functional> #include <string> #include <vector> class EventBus { public: using Handler = std::function<void(const std::string&)>; int subscribe(Handler h) { handlers_.push_back({nextId_, std::move(h)}); return nextId_++; } void unsubscribe(int id) { std::erase_if(handlers_, [id](const auto& p) { return p.first == id; }); } void publish(const std::string& msg) const { for (const auto& [id, h] : handlers_) h(msg); } private: std::vector<std::pair<int, Handler>> handlers_; int nextId_ = 0; };
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 the difference between const int*, int* const and const int* const?

Save to ▾
Show answer
Read the declaration from right to left. const int* p is a pointer to a const int: you cannot modify the value through p, but p can point elsewhere. int* const p is a const pointer to int: the address is fixed but the value can change. const int* const p fixes both the address and the value. These forms are frequent interview traps and appear in function signatures.
07

What is template argument deduction and class template argument deduction?

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

Group a list of words into anagram groups.

Save to ▾
Show answer
#include <algorithm> #include <string> #include <unordered_map> #include <vector> std::vector<std::vector<std::string>> groupAnagrams(const std::vector<std::string>& words) { std::unordered_map<std::string, std::vector<std::string>> groups; for (const auto& w : words) { std::string key = w; std::sort(key.begin(), key.end()); groups[key].push_back(w); } std::vector<std::vector<std::string>> out; for (auto& [k, g] : groups) out.push_back(std::move(g)); return out; } // O(n * k log k) where k is the word length.
09

A generic maxOf template gives wrong results when called with two C-style string literals. Why, and how do you fix it?

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

How do you keep your C++ knowledge up to date with new standards?

Save to ▾
Show answer
Situation: I noticed many tutorials still teach C++98 style. Task: learn modern practices properly. Action: I follow cppreference for each new standard, watch selected conference talks, read the C++ Core Guidelines and try features such as concepts, ranges and std::format in small practice projects compiled with recent GCC and Clang. Result: I can explain when a modern feature helps and when older code is fine.
11

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

What is the difference between an inline function and a macro?

Save to ▾
Show answer
A macro is text substitution done by the preprocessor with no type checking, so #define SQ(x) x*x gives a wrong result for SQ(a+1) and may evaluate arguments twice. An inline function is a real function with type checking, scope and debugger support, and the compiler may expand it at the call site. In modern C++ inline mainly allows a function to be defined in a header without breaking the One Definition Rule.
13

A function returns a string_view and callers sometimes print garbage. What is the likely bug?

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

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
15

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

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

Implement a simple String class that follows the rule of five.

Save to ▾
Show answer
#include <cstring> #include <utility> class String { char* data_ = nullptr; std::size_t len_ = 0; public: String(const char* s = "") : len_(std::strlen(s)) { data_ = new char[len_ + 1]; std::memcpy(data_, s, len_ + 1); } ~String() { delete[] data_; } String(const String& o) : String(o.data_) {} String(String&& o) noexcept : data_(std::exchange(o.data_, nullptr)), len_(std::exchange(o.len_, 0)) {} String& operator=(String o) noexcept { // copy-and-swap handles both std::swap(data_, o.data_); std::swap(len_, o.len_); return *this; } const char* c_str() const { return data_ ? data_ : ""; } };
18

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

Implement an LRU cache with get and put in O(1).

Save to ▾
Show answer
#include <list> #include <unordered_map> class LRUCache { int cap_; std::list<std::pair<int, int>> items_; // front = most recent std::unordered_map<int, std::list<std::pair<int, int>>::iterator> pos_; public: explicit LRUCache(int capacity) : cap_(capacity) {} int get(int key) { auto it = pos_.find(key); if (it == pos_.end()) return -1; items_.splice(items_.begin(), items_, it->second); return it->second->second; } void put(int key, int value) { if (auto it = pos_.find(key); it != pos_.end()) { it->second->second = value; items_.splice(items_.begin(), items_, it->second); return; } if (static_cast<int>(items_.size()) == cap_) { pos_.erase(items_.back().first); items_.pop_back(); } items_.emplace_front(key, value); pos_[key] = items_.begin(); } };
20

You are building a particle simulation with millions of particles. Would you store them as an array of structs or a struct of arrays?

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

Compute the sum of a large vector in parallel using std::async.

Save to ▾
Show answer
#include <future> #include <numeric> #include <vector> long long parallelSum(const std::vector<int>& v, int parts = 4) { std::vector<std::future<long long>> futs; std::size_t chunk = v.size() / parts; for (int i = 0; i < parts; ++i) { auto b = v.begin() + i * chunk; auto e = (i == parts - 1) ? v.end() : b + chunk; futs.push_back(std::async(std::launch::async, [b, e] { return std::accumulate(b, e, 0LL); })); } long long total = 0; for (auto& f : futs) total += f.get(); return total; } // C++17 alternative: std::reduce(std::execution::par, v.begin(), v.end(), 0LL)
22

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

How do you decide between templates and virtual functions for polymorphism?

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

Design a producer-consumer pipeline where one thread reads log lines and several workers parse them.

Save to ▾
Show answer
I would use a bounded thread-safe queue built with a mutex and two condition variables, one for not empty and one for not full, so a fast reader cannot exhaust memory. The reader pushes lines and workers pop and parse them. For shutdown, the reader pushes a sentinel per worker or sets a closed flag and notifies all. Batching lines per push reduces locking overhead, and results go to a second queue.
25

A program does millions of lookups in a std::map with string keys and is slow. How would you speed it up?

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

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

A program crashes with terminate called without an active exception when a function returns. What is the cause?

Save to ▾
Show answer
A std::thread object that is still joinable was destroyed, often because the function returned early or threw before reaching join. The std::thread destructor calls std::terminate in that case. Fix it by making sure every thread is joined on all paths, using an RAII guard, or switching to std::jthread, which joins automatically. Be careful with detach, since detached threads may access destroyed data.
28

Write a move constructor and move assignment operator for a class that owns a buffer.

Save to ▾
Show answer
#include <utility> class Buffer { std::size_t size_ = 0; int* data_ = nullptr; public: explicit Buffer(std::size_t n) : size_(n), data_(new int[n]{}) {} ~Buffer() { delete[] data_; } Buffer(Buffer&& other) noexcept : size_(std::exchange(other.size_, 0)), data_(std::exchange(other.data_, nullptr)) {} Buffer& operator=(Buffer&& other) noexcept { if (this != &other) { delete[] data_; size_ = std::exchange(other.size_, 0); data_ = std::exchange(other.data_, nullptr); } return *this; } };
29

What are lvalues and rvalues?

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

Write a minimal modern CMakeLists.txt for an app with a library and tests.

Save to ▾
Show answer
cmake_minimum_required(VERSION 3.20) project(Inventory LANGUAGES CXX) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_library(core src/stock.cpp src/order.cpp) target_include_directories(core PUBLIC include) target_compile_options(core PRIVATE -Wall -Wextra -Wpedantic) add_executable(app src/main.cpp) target_link_libraries(app PRIVATE core) enable_testing() find_package(GTest REQUIRED) add_executable(core_tests tests/stock_test.cpp) target_link_libraries(core_tests PRIVATE core GTest::gtest_main) add_test(NAME core_tests COMMAND core_tests)

Tips to crack the Cisco C++ interview

  • Revise computer networking deeply, including OSI layers, TCP/IP, subnetting, routing protocols and VLANs.
  • For test roles, be ready to explain how you would test a network feature, including traffic tools and automation with Python.
  • Read about Cisco's security and Splunk observability products, which have become a growing focus area.
  • 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; Cisco interviewers usually ask follow-ups on your first answer.

Frequently asked questions

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

Candidates usually go through 5 stages: Online assessment (aptitude + networking + 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 Cisco C++ interview?

This practice set leans on Templates and Generic Programming (6), Performance, Debugging and Build Tools (5), Modern C++ (C++11 to C++23) (4), Multithreading and Concurrency (4). Revise those first, then practise explaining one or two of your own projects end to end, because most Cisco interviewers ask you to walk through real work.

Are these the exact questions asked at Cisco?

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

Where does Cisco hire C++ professionals in India?

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

C++ questions for similar companies