C and C++ interview questions show up together in embedded firmware, operating systems, game engines, trading infrastructure, and performance-critical backend teams. Interviewers rarely test only one language in isolation—they want you to explain C memory and pointers, then defend C++ ownership with RAII, choose the right STL container, and survive a live coding round without leaking or invoking undefined behavior.
Below are 45 C and cpp interview questions with elaborate answers for developers preparing in 2026. Each section builds from C foundations through modern C++ and coding scenarios, with strong answer samples on technical questions you can say aloud in the room. Pair this guide with operating system interview questions for processes, virtual memory, and Linux kernel context, OOP interview questions for cross-language object-oriented design, Java interview questions part 1 for managed-memory contrast, shell scripting interviews for gdb and sanitizer workflows on Linux, and Git interviews for review and CI habits.
malloc discipline first, then C++ Rule of Zero, smart pointers, and STL complexities. Coding rounds often mix both—a C string utility plus a C++ RAII wrapper is a common pattern.
Tested on: Ubuntu 25.04 (Plucky Puffin); kernel 6.14.0-37-generic; GCC 14.2.0 / G++ 14.2.0.
Interview context and how to prepare
What do combined C and C++ interviews test?
Hiring loops that list C and C++ usually need engineers who can work on legacy C APIs, modern C++ services, or bare-metal plus host tooling.
| Skill band | C side | C++ side |
|---|---|---|
| Memory | malloc/free, pointers, layout |
RAII, smart pointers, move |
| Abstraction | Structs, function pointers | Classes, templates, STL |
| Correctness | UB, bounds, const/volatile |
Exceptions, noexcept, casts |
| Performance | Cache, no hidden alloc | vector, algorithms, profiling |
| Coding | String/array utilities | STL + ownership in one problem |
| Role type | Typical split |
|---|---|
| Embedded | 70% C, 30% C++ wrappers |
| Systems / infra | 40% C APIs, 60% C++17/20 |
| Games / HFT | Heavy C++ with C hot paths |
C vs C++ — key differences interviewers expect you to list?
| Feature | C | C++ |
|---|---|---|
| Paradigm | Procedural | Multi-paradigm (OOP, generic, procedural) |
| Memory | Manual malloc/free |
Constructors, destructors, smart pointers |
| Abstraction | Structs + function pointers | Classes, templates, namespaces |
| Polymorphism | Function pointers | Virtual functions, templates |
| Standard library | C standard library | STL + C library |
| Compatibility | — | Mostly backward compatible with C (extern "C") |
C++ adds type safety, RAII, and zero-cost abstractions when used well—not automatic safety if you still use raw owning pointers everywhere.
What is a typical C and C++ interview loop?
| Round | Duration | Focus |
|---|---|---|
| Phone screen | 30 min | Projects, domains, safety-critical experience |
| Language fundamentals | 45–60 min | Pointers, OOP, STL, UB |
| Coding | 60–90 min | C string ops, C++ container problem, debug snippet |
| Systems / design | 45 min | Module boundaries, threading, API design |
| Debugging story | 30 min | Segfault, leak, race you fixed |
Follow-up questions often go deep on pointer arithmetic, virtual destructors, smart pointer choice, and iterator invalidation—plan to explain each with a small code example.
What is a realistic prep plan for C and C++ interviews?
| Week | Focus | Deliverable |
|---|---|---|
| 1–2 | C pointers, arrays, malloc, strings |
Linked list + valgrind/ASan clean |
| 3 | C structs, padding, function pointers | Draw struct layout; qsort comparator |
| 4 | C++ classes, RAII, Rule of Zero | Wrap FILE* or socket handle |
| 5 | Smart pointers, move, four casts | Refactor raw owner to unique_ptr |
| 6 | STL containers + complexities | Explain when vector beats list |
| 7 | Threads, mutexes, atomics | Fix a race; run TSan |
| 8 | Mock coding + STAR incidents | Three timed problems out loud |
Compile with -Wall -Wextra -Wpedantic and run AddressSanitizer and UndefinedBehaviorSanitizer on practice code.
C fundamentals: memory, pointers, and types
Explain stack vs heap storage in C and C++.
| Storage | Lifetime | Allocation |
|---|---|---|
| Stack (automatic) | Function scope | Compiler-managed |
| Heap | Until freed/delete |
malloc/free or new/delete |
| Static | Program lifetime | BSS/data segments |
void demo(void) {
int x = 10; /* stack */
static int counter; /* static */
int *p = malloc(sizeof *p); /* heap */
free(p);
}Returning address of local x is undefined behavior. C++ adds RAII so stack objects run destructors automatically.
A strong answer is:
Stack is automatic and fast; heap outlives the function but needs explicit or RAII cleanup—I never return pointers to expired stack frames.
How do pointers, dereferencing, and pointer arithmetic work in C?
int arr[] = {10, 20, 30};
int *p = arr;
printf("%d %d\n", *p, *(p + 2));| Rule | Detail |
|---|---|
* |
Dereference — read/write through address |
& |
Address-of |
p + n |
Advances by n * sizeof(type) |
p[i] |
Same as *(p + i) |
Valid arithmetic only within same array object (or one past end for comparison, not dereference).
A strong answer is:
Pointers are typed addresses—I use arithmetic only inside known bounds and treat one-past-end as compare-only, not dereference.
What are common malloc and free mistakes?
| Mistake | Result |
|---|---|
| Memory leak | No free |
| Double free | Heap corruption |
| Use-after-free | UB / crash |
| Wrong size | malloc(n * sizeof *p) not sizeof(p) |
free non-heap pointer |
UB |
Always check malloc for NULL. Set pointer to NULL after free if reused.
A strong answer is:
One allocation pairs with exactly one free on every path—I use sizeof on the pointed-to type, check NULL, and verify with AddressSanitizer.
What do const and volatile mean in C?
const — cannot modify object through that lvalue (unless cast away illegally).
volatile — accesses must not be optimized away; for MMIO, signal handlers, special hardware—not for thread synchronization.
const int limit = 100;
volatile uint32_t *reg = (volatile uint32_t *)0x40001000;C++ adds constexpr for compile-time constants; C has const but not full constexpr.
A strong answer is:
const documents immutability; volatile is for special memory that hardware changes—I do not use volatile as a mutex substitute.
What is undefined behavior and why does it matter in C/C++?
UB means the standard imposes no requirements—anything may happen. Compilers assume UB never occurs and optimize accordingly.
Common sources:
- Signed integer overflow
- Out-of-bounds access
- Uninitialized reads
- Invalid pointer arithmetic / dereference
- Data races (C++ memory model)
Code that "works in debug" may break in -O2 release after UB-based optimizations.
A strong answer is:
UB is not implementation-defined—it is license for the compiler to break my program; I avoid it with bounds checks, sanitizers, and defined types like
uint32_t.
C strings, structs, and procedural patterns
How are C strings stored and copied safely?
Null-terminated char sequences. Length is O(n) via strlen.
#include <stdio.h>
#include <string.h>
int main(void) {
char dest[16];
snprintf(dest, sizeof dest, "%s", "hello");
printf("%zu %s\n", strlen(dest), dest);
return 0;
}Compiled and run, this prints 5 hello on one line.
Prefer snprintf, strncpy with explicit bounds, or C++ std::string at boundaries. Never gets; avoid unbounded strcpy.
A strong answer is:
C strings end at the first null—I always pass buffer sizes to bounded APIs and treat string length as explicit in APIs I design.
What is structure padding and alignment?
CPU alignment rules insert padding between struct members.
struct S { char c; double d; }; /* often 16 bytes total */Use offsetof to inspect layout. Reorder fields (large alignment first) to reduce waste. #pragma pack affects ABI—use only when wire format demands it.
A strong answer is:
Padding aligns members for hardware access—I calculate layout with offsetof and document packed structs for network binary protocols carefully.
What are function pointers used for in C?
Callbacks, dispatch tables, qsort/bsearch comparators, driver interfaces.
#include <stdlib.h>
int cmp_int(const void *a, const void *b) {
int x = *(const int *)a, y = *(const int *)b;
return (x > y) - (x < y);
}C++ often replaces C-style function pointers with std::function, lambdas, or templates—but C APIs and embedded code still use raw function pointers daily.
A strong answer is:
Function pointers decouple call sites from implementations—I use them for comparators and plugin tables with clear, documented signatures.
How do C and C++ interoperate with extern "C"?
C++ name mangling encodes overloads into linker symbols. C expects unmangled names.
#ifdef __cplusplus
extern "C" {
#endif
void c_api_init(void);
#ifdef __cplusplus
}
#endifExpose stable C ABI from C++ libraries for other languages and older C callers. Headers shared between .c and .cpp files need extern "C" guards.
A strong answer is:
extern "C" gives C linkage for shared APIs—I wrap C++ implementations behind C headers when the ABI must stay stable.
What is array-to-pointer decay?
In most expressions, an array name decays to pointer to first element.
| Context | sizeof(arr) |
|---|---|
| In scope of declared array | Total array size |
Function parameter int arr[] |
Pointer size (decayed) |
Always pass explicit length with array parameters in C.
A strong answer is:
Arrays decay to pointers in function calls—I never infer array length from a bare pointer parameter.
C++ object model and OOP
What is RAII and why is it central to C++?
Resource Acquisition Is Initialization — acquire in constructor, release in destructor.
Destructors run when scope ends, including during exception unwind, so cleanup is tied to object lifetime—not scattered free calls.
class Guard {
std::lock_guard<std::mutex> lock_;
public:
Guard(std::mutex& m) : lock_(m) {}
}; // unlocks automatically
RAII applies to memory, files, locks, sockets, and GPU handles.
A strong answer is:
RAII makes cleanup automatic and exception-safe—I wrap every resource in a type whose destructor releases it.
Static vs dynamic polymorphism in C++?
| Kind | Mechanism | When resolved |
|---|---|---|
| Static | Templates, overload resolution | Compile time |
| Dynamic | virtual functions, vtable |
Runtime |
template<typename T>
T max_t(T a, T b) { return (a < b) ? b : a; } // static
struct Base { virtual void f(); };
struct Derived : Base { void f() override; };Templates enable zero-cost generics; virtual enables runtime substitution with vtable cost.
A strong answer is:
Templates give compile-time polymorphism without vtable cost; virtual gives runtime substitution when types are not known until run time.
Why must polymorphic base classes have virtual destructors?
Deleting through base pointer without virtual destructor calls only base destructor—derived subobject leaks or corrupts.
struct Base {
virtual ~Base() = default;
};
struct Derived : Base {
std::vector<int> data;
};
std::unique_ptr<Base> p = std::make_unique<Derived>();unique_ptr with virtual destructor is the modern default pattern.
A strong answer is:
If I delete derived objects through a base pointer, the base destructor must be virtual—or I use unique_ptr with a custom deleter and no public polymorphic delete.
Explain Rule of Zero, Three, and Five.
| Rule | Guidance |
|---|---|
| Rule of Zero | Use RAII members (string, vector, smart ptr)—define no special members |
| Rule of Three | Custom destructor ⇒ need copy ctor + copy assign |
| Rule of Five | Add move ctor + move assign (C++11+) |
If you manage a raw char* manually, you own the full five or delete copying.
A strong answer is:
Rule of Zero is my default; if I hold raw resources I implement or delete the full copy/move/destructor set explicitly.
Shallow copy vs deep copy?
| Shallow | Deep | |
|---|---|---|
| Pointers | Copy pointer value | Duplicate pointed-to data |
| Risk | Double free, aliasing | Extra cost, correct ownership |
C++ default copy is memberwise shallow. std::string and vector deep-copy internally. Raw owning pointers need explicit deep copy or deleted copy.
A strong answer is:
Shallow copy shares pointer addresses; deep copy duplicates data—I rely on value types and Rule of Zero instead of manual deep copies.
Smart pointers, new/delete, and move semantics
unique_ptr vs shared_ptr vs weak_ptr?
| Type | Ownership | Overhead |
|---|---|---|
unique_ptr |
Exclusive | None vs raw |
shared_ptr |
Shared refcount | Control block + atomics |
weak_ptr |
Non-owning | Breaks cycles |
auto u = std::make_unique<int>(42);
auto s = std::make_shared<Resource>();
std::weak_ptr<Resource> w = s;Prefer make_unique / make_shared for exception safety and single allocation (shared).
A strong answer is:
unique_ptr by default; shared_ptr when lifetime is genuinely shared; weak_ptr to observe without keeping objects alive or creating cycles.
new/delete vs malloc/free — when use each?
malloc/free |
new/delete |
|
|---|---|---|
| Language | C (+ C++ compatible) | C++ only |
| Construction | No constructors | Calls ctor/dtor |
| Type | Returns void* |
Typed pointer |
| Failure | Returns NULL | Throws bad_alloc (default) |
In modern C++, new is rare—use containers and smart pointers. malloc remains for C interop, custom allocators, and embedded pools.
A strong answer is:
malloc is for C-style untyped bytes; new runs constructors—I avoid both for owning code and use make_unique and vectors instead.
What are move semantics and why mark moves noexcept?
Move transfers resources from expiring objects instead of copying.
std::vector<int> build() {
std::vector<int> v{1, 2, 3};
return v; // NRVO or move
}std::move casts to rvalue. Move ctor should leave source valid but unspecified, often empty.
noexcept on move lets vector reallocate with moves instead of copies.
A strong answer is:
Move pilfers resources from dying objects—I implement noexcept moves so containers pick them during growth.
Explain static_cast, dynamic_cast, const_cast, and reinterpret_cast.
| Cast | Safe use |
|---|---|
static_cast |
Numeric conversions, up/down casts with programmer guarantee |
dynamic_cast |
Polymorphic downcast; returns null or throws |
const_cast |
Add/remove const only (not immutability hack on truly read-only memory) |
reinterpret_cast |
Low-level bit reinterpretation—implementation-defined, dangerous |
Prefer C++-style casts over C (T)x—they are searchable and categorized.
A strong answer is:
I use static_cast for compile-time conversions, dynamic_cast for safe runtime downcasts, and treat reinterpret_cast as last-resort low-level code.
What is operator overloading in C++?
Define operator+, operator[], operator<<, etc. on user types for natural syntax.
struct Vec2 {
double x, y;
Vec2 operator+(const Vec2& o) const { return {x + o.x, y + o.y}; }
};Rules:
- Cannot overload
::,.*,?:,sizeof - At least one user-defined type in overload
- Maintain intuitive semantics—don't surprise readers
A strong answer is:
Operator overloading is syntactic sugar for functions—I overload only when it reads clearly and matches mathematical or domain expectations.
STL, templates, and algorithms
Compare vector, list, deque, map, and unordered_map.
| Container | Random access | Insert middle | Lookup by key |
|---|---|---|---|
vector |
O(1) | O(n) | — |
list |
O(n) | O(1) | — |
deque |
O(1) ends | O(n) middle | — |
map |
— | O(log n) | O(log n) ordered |
unordered_map |
— | O(1) avg | O(1) avg |
Default: vector until profiling proves otherwise—cache locality dominates many workloads.
A strong answer is:
vector for contiguous data; unordered_map for average O(1) hash lookup; map when I need sorted iteration.
When do vector iterators invalidate?
| Operation | Iterator validity |
|---|---|
push_back / resize beyond capacity |
Invalidate all (reallocation) |
push_back without reallocation |
Only to end |
erase |
Invalidate at/after erase point |
insert |
Invalidate if reallocation |
Classic bug: for (auto it = v.begin(); it != v.end(); ++it) { if (*it == x) v.erase(it); } — use erase-remove idiom or careful loop.
A strong answer is:
vector reallocation invalidates all iterators—I use indices, reserve capacity, or erase-remove instead of erasing while iterating with raw iterators.
What are C++ templates at interview level?
Templates generate type-safe generic code at compile time.
template<typename T>
const T& min_ref(const T& a, const T& b) {
return (a < b) ? a : b;
}C++20 concepts constrain templates: template<std::integral T>.
Definitions usually live in headers—each translation unit instantiates used specializations.
A strong answer is:
Templates are compile-time generics—I constrain them with concepts in C++20 and keep definitions visible to the compiler.
Name important STL algorithms and complexities.
| Algorithm | Typical use | Complexity |
|---|---|---|
std::sort |
General sort | O(n log n) |
std::lower_bound |
Binary search on sorted range | O(log n) |
std::find |
Linear search | O(n) |
std::accumulate |
Sum / fold | O(n) |
std::transform |
Map | O(n) |
Prefer algorithms over hand-rolled loops—they document intent and enable optimizer patterns.
A strong answer is:
I reach for sort, lower_bound, and find before writing custom loops—knowing complexities matches interviewer expectations.
Concurrency, exceptions, and modern C++
How do std::thread and std::mutex prevent data races?
std::mutex m;
int counter = 0;
void inc() {
std::lock_guard<std::mutex> lock(m);
++counter;
}| Primitive | Role |
|---|---|
lock_guard |
RAII lock |
unique_lock |
Deferred, try_lock, condition_variable |
scoped_lock |
Multiple mutexes without deadlock |
Run ThreadSanitizer (-fsanitize=thread) on concurrent tests.
A strong answer is:
I protect shared mutable state with mutexes or atomics and verify with thread sanitizer—not ad hoc volatile flags.
What are std::atomic and memory orders?
Atomics give defined concurrent read/write without mutex for simple counters/flags.
| Order | Use |
|---|---|
memory_order_relaxed |
Statistics where ordering irrelevant |
acquire / release |
Publish-consume |
seq_cst |
Default; strongest |
C11 _Atomic mirrors for C-only subsystems.
A strong answer is:
atomics define legal concurrent access—I start with seq_cst and relax only with measurement and a written memory-order rationale.
How do C++ exceptions interact with RAII?
When an exception throws, stack unwinds and destructors run for automatic objects—RAII releases locks and memory.
| Guarantee | Meaning |
|---|---|
| Basic | No leaks on throw |
| Strong | All-or-nothing state change |
noexcept |
Move operations containers rely on |
Embedded projects may compile with -fno-exceptions—know team policy.
A strong answer is:
Exceptions unwind through destructors—RAII gives basic safety; I mark moves noexcept so vectors reallocate efficiently.
What are C++ lambdas and captures?
int factor = 10;
auto f = [factor](int x) { return factor * x; }; // by value
auto g = [&factor](int x) { return factor * x; }; // by reference
mutable allows modifying value-captured copies. Generic lambdas (auto params) act like templates.
Used with std::sort, std::thread, and STL algorithms.
A strong answer is:
Lambdas are local function objects—I capture by value unless I need to mutate external state safely with explicit reference discipline.
Coding interview problems (C and C++)
Coding: Reverse a C string in place.
#include <stdio.h>
void reverse(char *s) {
if (!s) return;
char *a = s, *b = s;
while (*b) ++b;
if (b > s) --b;
while (a < b) {
char t = *a;
*a++ = *b;
*b-- = t;
}
}
int main(void) {
char s[] = "hello";
reverse(s);
printf("%s\n", s);
return 0;
}Running prints olleh. Must use writable array—not a string literal.
A strong answer is:
Two pointers from both ends swap until they meet—I only mutate buffers I own.
Coding: Two-sum with a hash map (C++ STL).
Find two indices whose values sum to target—classic STL + complexity question.
#include <iostream>
#include <unordered_map>
#include <vector>
std::pair<int, int> two_sum(const std::vector<int>& nums, int target) {
std::unordered_map<int, int> seen;
for (int i = 0; i < (int)nums.size(); ++i) {
int need = target - nums[i];
auto it = seen.find(need);
if (it != seen.end()) return {it->second, i};
seen[nums[i]] = i;
}
return {-1, -1};
}
int main() {
std::vector<int> v{2, 7, 11, 15};
auto [a, b] = two_sum(v, 9);
std::cout << a << " " << b << "\n";
}Compile with g++ -std=c++17 -Wall -Wextra — prints 0 1.
A strong answer is:
I trade O(n) space for O(n) time with unordered_map—state complexity aloud in coding rounds.
Coding: Detect a cycle in a linked list (C).
Floyd's tortoise-and-hare — O(n) time, O(1) space.
#include <stdbool.h>
#include <stddef.h>
struct Node { int val; struct Node *next; };
bool has_cycle(struct Node *head) {
struct Node *slow = head, *fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) return true;
}
return false;
}Check fast and fast->next before advancing to avoid null dereference.
A strong answer is:
Floyd's algorithm detects cycles without extra memory—I validate pointers before each step.
Coding: Wrap a C FILE* in minimal RAII (C++).
class File {
FILE* f_{nullptr};
public:
explicit File(const char* path, const char* mode) : f_(fopen(path, mode)) {}
~File() { if (f_) fclose(f_); }
File(const File&) = delete;
File& operator=(const File&) = delete;
FILE* get() const { return f_; }
};Interview checks destructor cleanup, deleted copy, and explicit constructor.
A strong answer is:
I wrap C handles in RAII classes with deleted copy and explicit acquisition—production code uses similar patterns behind unique_ptr custom deleters.
Debugging, design, and senior scenarios
How do you debug segfaults and memory corruption on Linux?
| Step | Tool |
|---|---|
| Reproduce minimally | — |
| gdb backtrace | bt, core files |
| AddressSanitizer | -fsanitize=address |
| UBSan | -fsanitize=undefined |
| Valgrind | Heap errors (C-heavy code) |
See shell scripting interviews for automating core dump collection.
A strong answer is:
I reproduce, gdb the backtrace, then fix under sanitizers—root cause is usually bounds, use-after-free, or race, not random hardware.
What is the PIMPL idiom?
Pointer to implementation — hide details behind unique_ptr<Impl> in header, define Impl in .cpp.
Benefits: faster compiles, stable ABI, encapsulation.
Trade-off: extra indirection and allocation.
A strong answer is:
PIMPL hides implementation details and reduces compile coupling—I use it for stable library APIs, not every small class.
Embedded C vs application C++ — interview focus shift?
| Embedded C | Server C++ | |
|---|---|---|
| Heap | Often banned / pools | STL allocators |
| RTTI / exceptions | Often disabled | Enabled |
| Libraries | Minimal | Full STL |
| Tools | JTAG, scope | profilers, sanitizers |
Many engineers face both in one product—RTOS in C, configuration UI in C++.
A strong answer is:
Embedded loops stress deterministic C and hardware; application loops stress RAII, STL, and concurrency with sanitizers.
Scenario: Hot loop in C++ — what do you optimize first?
- Algorithm — better Big-O (hash vs nested loops)
- Allocations — remove per-iteration
new/push_backwithoutreserve - Cache — data layout, SoA vs AoS
- Branches — predictable patterns
- Micro-opts — only after
perf record
A strong answer is:
I fix complexity and allocation churn before SIMD or micro-benchmark trivia—always profiled, never guessed.
Final preparation
Coding: Implement strcmp-style logic (C).
#include <stdio.h>
int my_cmp(const char *a, const char *b) {
while (*a && (*a == *b)) { ++a; ++b; }
return (unsigned char)*a - (unsigned char)*b;
}
int main(void) {
printf("%d %d\n", my_cmp("abc", "abd"), my_cmp("abc", "abc"));
return 0;
}Prints negative integer and 0. Cast to unsigned char for correct signed char platforms.
A strong answer is:
I compare unsigned char values so comparison matches ASCII order on all platforms—classic low-level C detail interviewers love.
What is enum class in C++ vs C enum?
C enum — names leak into enclosing scope; underlying type implementation-defined.
enum class (C++11) — scoped enumerators, optional fixed underlying type, no implicit conversion to int.
enum class Color : uint8_t { Red, Green, Blue };Safer for new C++ code than unscoped enums.
A strong answer is:
enum class prevents implicit int conversions and name pollution—I use it for type-safe constants in modern C++.
What is copy elision / RVO?
Compiler may omit copy/move when returning locals or constructing temporaries—mandatory in some C++17 cases (prvalue materialization).
std::vector<int> make() {
return std::vector<int>{1, 2, 3}; // often no copy
}Do not pessimize by std::move on returned local—can block RVO.
A strong answer is:
RVO and copy elision eliminate extra copies on returns—I return by value and let the compiler elide, not std::move locals blindly.
What are friend functions and friend classes?
Friends grant private access to non-members—use sparingly for operators and tightly coupled collaborators.
class Matrix {
friend std::ostream& operator<<(std::ostream& os, const Matrix& m);
};Breaks encapsulation boundary deliberately—prefer public interface when possible.
A strong answer is:
Friends expose private access for operators or paired classes—I use them narrowly, not to bypass design.
What should you rehearse before a C and C++ interview?
Checklist:
- Draw stack vs heap; explain pointer size on 64-bit
-
malloc/freerules + sanitizer workflow - virtual destructor and vtable sketch
- Rule of Zero and smart pointer defaults
- Four casts and when each is valid
- vector invalidation and
reserve - unordered_map vs
mapcomplexity - Code: reverse string, two-sum, cycle detect
- extern "C" for ABI boundaries
- One debugging STAR story (ASan, gdb, race)
- Java OOP contrast if full-stack loop
A strong answer is:
I rehearse C pointer fluency and C++ ownership weekly with timed coding until complexity, memory, and strong answers are automatic under pressure.
Pattern cheat sheet (quick reference)
| Need | C / C++ approach |
|---|---|
| Dynamic buffer (C) | malloc + free, size param |
| Dynamic buffer (C++) | std::vector |
| Exclusive ownership | std::unique_ptr |
| Shared ownership | std::shared_ptr + weak_ptr |
| Polymorphic delete | virtual ~Base() |
| C API from C++ | extern "C" |
| Fast lookup | unordered_map |
| Sorted keys | map |
| Sort custom type | std::sort + comparator |
| Thread-safe increment | mutex or atomic |
| Find bugs | ASan, UBSan, gdb, Valgrind |
References
Official language references
On-site prep
- Java interview questions — part 1
- Java interview questions — part 2
- Shell scripting interview questions
- Git interview questions
- Spring Boot interview questions
- Senior Android developer interviews (NDK/native)
- Interview Questions category
Summary
C and C++ interviews connect pointer discipline, modern ownership, STL complexity, and clean coding under time pressure. Compile the examples locally and compare your answers to each section. Pair with shell scripting and Java interviews when interviewers compare memory models.

