In the 40 years since its introduction, C++ has carved out its place in the infrastructure of many of our favorite software, systems, and games. Its unique blend of high-level and low-level language features, object-oriented paradigm, and raw power gives it a level of flexibility and performance that’s hard to match. As a result, C++ continues to be one of the most sought-after programming languages, with tech professionals globally striving to master it.
In light of its significance, excelling in C++ technical interviews becomes paramount for aspiring and seasoned programmers alike. These interviews act as gateways to coveted roles in the tech industry, and a deep understanding of C++ concepts, coupled with a knack for problem solving, can be your ticket to success.
In this blog post, we’ll delve into some essential C++ interview questions that test both your foundational knowledge and your understanding of advanced C++ concepts. These handpicked questions aim to mirror the kind of challenges you might face in a real C++ technical interview, whether you’re seeking a role in systems programming, game development, or any tech domain that calls for C++ expertise. By the end of this guide, you should be better equipped to impress in your next C++ coding interview.
Understanding the C++ Interview
Roles that call for C++ proficiency span a wide range, from system-level roles to game development and even financial technology roles. These roles can include software engineers, back-end developers, quality analysts, game programmers, embedded engineers, and programming architects. As part of the interview process for these positions, candidates will likely face C++ interview questions designed to gauge their depth of understanding and practical expertise as it pertains to the role.
Now, let’s delve into some of these critical C++ interview questions, ranging from intermediate to advanced levels. Each question will also come with a sample answer to provide practical insight into how you could tackle such problems in a live interview setting.
1. Attribute Parser
This challenge works with a custom-designed markup language HRML. In HRML, each element consists of a starting and ending tag, and there are attributes associated with each tag. Only starting tags can have attributes. We can call an attribute by referencing the tag, followed by a tilde, ‘~’, and the name of the attribute. The tags may also be nested.
The opening tags follow the format:
<tag-name attribute1-name = "value1" attribute2-name = "value2" ...>
The closing tags follow the format:
</tag-name>
The attributes are referenced as:
tag1~value
tag1.tag2~name
Given the source code in HRML format consisting of N lines, answer Q queries. For each query, print the value of the attribute specified. Print “Not Found!” if the attribute does not exist.
Example
HRML listing
<tag1 value = "value">
<tag2 name = "name">
<tag3 another="another" final="final">
</tag3>
</tag2>
</tag1>
Queries
tag1~value
tag1.tag2.tag3~name
tag1.tag2~value
Here, tag2 is nested within tag1, so attributes of tag2 are accessed as tag1.tag2~<attribute>. The results of the queries are:
Query Value
tag1~value "value"
tag1.tag2.tag3~name "Not Found!"
tag1.tag2.tag3~final "final"
Input Format
The first line consists of two space-separated integers, N and Q. N specifies the number of lines in the HRML source program. Q specifies the number of queries.
The following N lines consist of either an opening tag with zero or more attributes or a closing tag. There is a space after the tag-name, attribute-name, ‘=’, and value. There is no space after the last value. If there are no attributes there is no space after the tag name.
Q queries follow. Each query consists of a string that references an attribute in the source program. More formally, each query is of the form tagᵢ1 . tagᵢ2 . tagᵢ3 …. tagᵢm ~attr – name where m>=1 and tagᵢ₁ . tagᵢ₂ …. tagᵢm are valid tags in the input.
Constraints
1 ≤ N ≤ 20
1 ≤ Q ≤ 20
- Each line in the source program contains, at most, 200 characters.
- Every reference to the attributes in the Q queries contains at most 200 characters.
- All tag names are unique and the HRML source program is logically correct, i.e. valid nesting.
- A tag may have no attributes.
Output Format
Print the value of the attribute for each query. Print “Not Found!” without quotes if the attribute does not exist.
Sample Input
4 3
<tag1 value = “HelloWorld”>
<tag2 name = “Name1”>
</tag2>
</tag1>
tag1.tag2~name
tag1~name
tag1~value
Sample Output
Name1
Not Found!
HelloWorld
2. Inherited Code
You inherited a piece of code that performs username validation for your company’s website. The existing function works reasonably well, but it throws an exception when the username is too short. Upon review, you realize that nobody ever defined the exception.
The inherited code is provided for you in the locked section of your editor. Complete the code so that, when an exception is thrown, it prints Too short: n (where n is the length of the given username).
Input Format
The first line contains an integer, t, the number of test cases.
Each of the t subsequent lines describes a test case as a single username string, u.
Constraints
- 1 ≤ t ≤ 1000
- 1 ≤ │u│≤ 100
- The username consists only of uppercase and lowercase letters.
Output Format
You are not responsible for directly printing anything to stdout. If your code is correct, the locked stub code in your editor will print either Valid (if the username is valid), Invalid (if the username is invalid), or Too short: n (where n is the length of the too-short username) on a new line for each test case.
Sample Input
3
Peter
Me
Arxwwz
Sample Output
Valid
Too short: 2
Invalid
Explanation
Username Me is too short because it only contains 2 characters, so your exception prints Too short: 2.
All other validation is handled by the locked code in your editor.
3. Virtual Functions
This problem is to get you familiar with virtual functions. Create three classes: Person, Professor, and Student. The class Person should have data members name and age. The classes Professor and Student should inherit from the class Person.
The class Professor should have two integer members: publications and cur_id. There will be two member functions: getdata and putdata. The function getdata should get the input from the user: the name, age and publications of the professor. The function putdata should print the name, age, publications, and the cur_id of the professor.
The class Student should have two data members: marks, which is an array of size 6 and cur_id. It has two member functions: getdata and putdata. The function getdata should get the input from the user: the name, age, and the marks of the student in 6 subjects. The function putdata should print the name, age, sum of the marks, and the cur_id of the student.
For each object being created of the Professor or the Student class, sequential ID’s should be assigned to them starting from 1.
Solve this problem using virtual functions, constructors, and static variables. You can create more data members if you want.
Note: Expand the main function to look at how the input is being handled.
Input Format
The first line of input contains the number of objects that are being created. If the first line of input for each object is 1, it means that the object being created is of the Professor class. You will have to input the name, age, and publications of the professor.
If the first line of input for each object is 2, it means that the object is of the Student class. You will have to input the name, age, and the marks of the student in 6 subjects.
Constraints
1 ≤ lenname ≤ 100, where lenname is the length of the name.
1 ≤ age ≤ 80
1 ≤ publications ≤ 100
0 ≤ marks ≤ ≤ 100, where marks is the marks of the student in each subject.
Output Format
There are two types of output depending on the object.
If the object is of type Professor, print the space-separated name, age, publications, and id on a new line.
If the object is of the Student class, print the space-separated name, age, the sum of the marks in 6 subjects, and id on a new line.
Sample Input
4
1
Walter 56 99
2
Jesse 18 50 48 97 76 34 98
2
Pinkman 22 10 12 0 18 45 50
1
White 58 87
Sample Output
Walter 56 99 1
Jesse 18 403 1
Pinkman 22 135 2
White 58 87 2
4. Operator Overloading
Classes define new types in C++. Types in C++ not only interact by means of constructions and assignments but also via operators. For example:
int a=2, b=1, c;
c = b + a;
The result of variable c will be 3.
Similarly, classes can also perform operations using operator overloading. Operators are overloaded by means of operator functions, which are regular functions with special names. Their name begins with the operator keyword followed by the operator sign that is overloaded. The syntax is: type operator sign (parameters) { /*… body …*/ }
You are given a main() function which takes a set of inputs to create two matrices and prints the result of their addition. You need to write the class Matrix, which has a member a of type vector<vector<int> >. You also need to write a member function to overload the operator +. The function’s job will be to add two objects of Matrix type and return the resultant Matrix.
Input Format
The first line will contain the number of test cases T. For each test case, there are three lines of input.
The first line of each test case will contain two integers N and M, which denote the number of rows and columns respectively of the two matrices that will follow on the next two lines. These next two lines will each contain N * M elements describing the two matrices in row-wise format, i.e. first M elements belong to the first row, next M elements belong to the second row, and so on.
Constraints
1<= T <= 1000
1 <= N <= 100
1 <= M <= 100
1 <= Ai,j <= 10, where Ai,j is the element in the ith row and jth column of the matrix.
Output Format
The code provided in the editor will use your class Matrix and overloaded operator function to add the two matrices and give the output.
Sample Input
1
2 2
2 2 2 2
1 2 3 4
Sample Output
3 4
5 6
Explanation
The sum of the first matrix and the second matrix is the matrix given in the output.
5. Abstract Classes – Polymorphism
Abstract base classes in C++ can only be used as base classes. Thus, they are allowed to have virtual member functions without definitions.
A cache is a component that stores data so future requests for that data can be served faster. The data stored in a cache might be the results of an earlier computation or the duplicates of data stored elsewhere. A cache hit occurs when the requested data can be found in a cache, while a cache miss occurs when it cannot. Cache hits are served by reading data from the cache, which is faster than recomputing a result or reading from a slower data store. Thus, the more requests that can be served from the cache, the faster the system performs.
One of the popular cache replacement policies is “least recently used” (LRU). It discards the least recently used items first.
For example, if a cache with a capacity to store 5 keys has the following state (arranged from most recently used key to least recently used key): 5 3 2 1 4
Now, if the next key comes as 1 (which is a cache hit), then the cache state in the same order will be: 1 5 3 2 4
Now, if the next key comes as 6 (which is a cache miss), then the cache state in the same order will be: 6 1 5 3 2
You can observe that 4 has been discarded because it was the least recently used key, and since the capacity of cache is 5, it could not be retained in the cache any longer.
Given an abstract base class Cache with member variables and functions:
- mp – Map the key to the node in the linked list
- cp – Capacity
- tail – Double linked list tail pointer
- head – Double linked list head pointer
- set() – Set/insert the value of the key, if present, otherwise add the key as the most recently used key. If the cache has reached its capacity, it should replace the least recently used key with a new key.
- get() – Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
You have to write a class LRUCache, which extends the class Cache and uses the member functions and variables to implement an LRU cache.
Input Format
The first line of input will contain the N number of lines containing get or set commands followed by the capacity M of the cache.
The following N lines can either contain get or set commands.
An input line starting with get will be followed by a key to be found in the cache. An input line starting with set will be followed by the key and value respectively to be inserted/replaced in the cache.
Constraints
1<= N <= 500000
1 <= M <= 1000
1 <= key <= 20
1 <= value <= 2000
Output Format
The code provided in the editor will use your derived class LRUCache to output the value whenever a get command is encountered.
Sample Input
3 1
set 1 2
get 1
get 2
Sample Output
2
-1
Explanation
Since the capacity of the cache is 1, the first set results in setting up the key 1 with its value 2. The first get results in a cache hit of key 1, so 2 is printed as the value for the first get. The second get is a cache miss, so -1 is printed.
6. C++ Variadics
A template parameter pack is a template parameter that accepts zero or more template arguments (non-types, types, or templates). To read more about parameter packs, click here.
Create a template function named reversed_binary_value. It must take an arbitrary number of bool values as template parameters. These booleans represent binary digits in reverse order. Your function must return an integer corresponding to the binary value of the digits represented by the booleans. For example, reversed_binary_value<0,0,1>() should return 4.
Input Format
The first line contains an integer, t, the number of test cases. Each of the t subsequent lines contains a test case. A test case is described as 2 space-separated integers, x and y, respectively.
- x is the value to compare against.
- y represents the range to compare: 64 × y to 64 × y + 63.
Constraints
- 0 ≤ x ≤ 65535
- 0 ≤ y ≤ 1023
- The number of template parameters passed to reversed_binary_value will be ≤ 16.
Output Format
Each line of output contains 64 binary characters (i.e., 0’s and 1’s). Each character represents one value in the range. The first character corresponds to the first value in the range. The last character corresponds to the last value in the range. The character is 1 if the value in the range matches x; otherwise, the character is 0.
Sample Input
2
65 1
10 0
Sample Output
0100000000000000000000000000000000000000000000000000000000000000
0000000000100000000000000000000000000000000000000000000000000000
Explanation
The second character on the first line is a 1, because the second value in the range 64..127 is 65 and x is 65.
The eleventh character on the second line is a 1, because the eleventh value in the range 0..63 is 10 and x is 10.
All other characters are zero because the corresponding values in the range do not match x.
7. Bit Array
You are given four integers: N, S, P, Q. You will use them in order to create the sequence a with the following pseudo-code:
a[0] = S (modulo 2^31)
for i = 1 to N-1
a[i] = a[i-1]*P+Q (modulo 2^31)
Your task is to calculate the number of distinct integers in the sequence a.
Input Format
Four space-separated integers on a single line, N, S, P, and Q respectively.
Output Format
A single integer that denotes the number of distinct integers in the sequence a.
Constraints
1 ≤ N ≤ 108
0 ≤ S, P, Q < 231
Sample Input
3 1 1 1
Sample Output
3
Explanation
a = [1,2,3]
Hence, there are 3 different integers in the sequence.
Resources to Improve C++ Knowledge
HackerRank C++ Practice Questions
This article was written with the help of AI. Can you tell which parts?