A 伟大的c++开发者 is primarily a 优秀的软件开发人员具有很强的解决问题能力和抽象思维能力的人, 找到合适的工具和框架的能力, 以及对计算机科学的热情.
There are plenty of interview questions that are language independent and designed to check the engineering prowess of the candidate; on a more basic level, the FizzBuzz问题 在过滤一般编码能力方面是出了名的有效. 但我们目前的重点将非常具体地针对c++.
如果候选人也熟悉应用程序开发 其他语言,你就有机会让面试过程更有成效. In that case, 这前三个问题将开启一场关于不同语言哲学的有趣讨论, 它们的基本结构, 以及由此产生的优点和缺点.
The fact that GetBaseSalary and MonthlyPerformance are const 成员函数告诉我们 employee 在这些调用之后不会改变它的状态. GetDebt takes a const Employee&也就是说,它没有被修改过. The PaySalary 然而,函数需要一个 Employee&这就是我们要深入研究的地方.
c++ 11引入了新的智能指针: unique_ptr, shared_ptr, and weak_ptr. unique_ptr 有效地使 auto_ptr obsolete.
对线程的内置支持
无需纠结于os原生和c风格的库.
问:你觉得c++ 17的哪个特性最有用?为什么?
结构化的绑定
这个特性增加了可读性.
// c++之前
For (const auto .& Name_and_id: name_to_id) {
const auto& Name = name_and_id.first;
const auto& Id = name_and_id.second;
// after C++17
For (const auto .& [name, id]: name_to_id) {
Compile-time if
With if constexpr,我们可以根据编译时条件启用代码的不同部分. 这使得模板元编程(TMP) enable_if 魔术更容易和更好地实现.
内置文件系统库
就像c++ 11中的线程支持一样, 这个内置库继续减少c++开发人员编写特定于操作系统的代码的需要. 它提供了一个接口来处理文件本身(而不是其内容)和目录, 让开发者复制它们, remove them, 递归地迭代它们, and so on.
Parallel STL
c++ 17包含了大量使用的STL算法的并行替代方案,这是一个重要的特性,因为多核处理器甚至在桌面上也变得很常见.
vector 使用大小标记将元素存储在基础数组中. When it’s full, a new, 分配更大的存储空间, 元素是从旧存储中复制的, 然后被释放. 它的迭代器是 random access category. ()的渐近复杂度push_back) is 平摊常数时间,索引访问是 constant time, remove is linear.
list 实现一个双重链表,存储指向头节点和尾节点的指针. 它的迭代器是 bidirectional. insert()的复杂度push_back and push_front) and remove (pop_back and pop_front) are constant time,而索引访问是 linear.
set and map 是否在平衡二叉搜索树上实现, 更具体地说,是红黑树, 这样就保持了元素的排序. 它们的迭代器是 bidirectional as well. 插入、查找(查找)和删除的复杂性是 logarithmic. 使用迭代器删除元素(erase 成员函数)有 平摊常数时间 complexity.
unordered_set and unordered_map 哈希表的实现是数据结构吗. 通常,它是一个所谓桶的数组,桶就是简单的链表. 为一个元素选择一个桶(在插入或查找期间)取决于它的哈希值和桶的总数. 当容器中的元素太多,平均桶大小大于实现定义的阈值(通常为1.0),则桶的数量增加,并将元素移动到正确的桶中. 这个过程叫做 rehashing,这使得插入变得复杂 平摊常数时间. 查找并删除 constant time complexities.
这些是最基本的容器—必须了解上述细节, 但是否每一个细节都经过测试取决于面试官的直觉.
问:给定算法的渐近复杂度是多少??
一些著名的STL算法的渐近复杂性是:
Algorithm
Complexity
std::sort
O(N log(N))
std:: nth_element
O(N)
std::advance
O(1) for 随机存取迭代器,否则为0 (N)
std:: binary_search
O(log(N)) for 随机存取迭代器,否则为0 (N)
std:: set_intersection
O(N)
或者,用一个简单的问题来解决所有问题:
问:哪些集装箱可以使用 insertion 操作使迭代器失效?
这个问题的巧妙之处在于它很难被记住, 正确的答案需要对容器的底层数据结构和一些逻辑有广泛的了解.
The insertion 操作可能使上的迭代器失效 vector, string, deque, and unordered_set /地图 (在扩展/重新散列的情况下). For list, set, and map但是,由于它们基于节点的数据结构,情况并非如此.