华为 C++ 一面

1. 屏幕共享简历并介绍

根据自己的具体情况回答

2. 哈希冲突是什么?如何解决?

哈希冲突指不同的key经过哈希函数计算后,得到相同的哈希地址,是哈希表设计中必然出现的问题。解决方法主要有四种:

  1. 链地址法:哈希表数组的每个位置挂载一个链表,冲突的key直接加入对应位置的链表,实现简单,适合高冲突场景,是工业界主流用法;
  2. 开放定址法:冲突后按固定规则(线性探测、二次探测等)寻找下一个空的哈希地址,无需额外空间,但易产生数据聚集,删除操作复杂;
  3. 再哈希法:准备多个哈希函数,一个函数产生冲突时,用下一个函数计算新地址,减少数据聚集但增加了哈希计算的开销;
  4. 公共溢出区法:将哈希表分为基本表和溢出表,所有冲突的元素统一放入溢出表,处理逻辑简单但溢出表满后性能会大幅下降。

3. 为什么析构函数往往是虚函数?

核心原因是为了避免基类指针/引用指向子类对象时,销毁对象发生内存泄漏;若析构函数非虚函数,编译器会进行静态绑定,通过基类指针删除子类对象时,仅会调用基类的析构函数,子类独有的资源无法被释放;将基类析构函数设为虚函数后,会触发动态绑定,删除对象时会先调用子类的析构函数,再调用基类的析构函数,保证父子类的资源都能被完整释放;仅当类作为基类且会被继承时,才需要将析构函数设为虚函数,普通类无需额外设置。

4. 如何用C语言模拟实现面向对象的特性,包括继承和多态?

C语言无原生面向对象特性,核心通过「结构体模拟类的封装」「函数指针模拟类的成员方法」「结构体嵌套实现继承」「函数指针重写实现多态」完成,具体逻辑:

  1. 封装:用结构体封装类的成员变量和函数指针(对应成员方法),对外只暴露结构体和构造函数,隐藏内部实现细节;
  2. 继承:子类结构体中嵌套基类结构体,直接复用基类的所有成员变量和方法,子类可按需扩展专属的成员变量和方法;
  3. 多态:子类重写基类的函数指针(方法),通过基类指针调用该方法时,会自动执行子类的重写实现,达成一个接口多种表现的效果;同时可通过自定义函数实现类的构造/析构逻辑,完成资源的创建和释放,整体通过结构体+函数指针的组合,实现面向对象的核心特性。

5. 拥塞控制的流程是什么?

TCP拥塞控制的核心是通过调整拥塞窗口(cwnd)控制数据发送速率,避免网络因数据量过大产生拥塞,经典流程分为四个阶段:

  1. 慢启动:初始将cwnd设为1个MSS,每收到一个ACK确认,cwnd翻倍呈指数级增长,直到cwnd达到慢启动阈值(ssthresh),进入下一阶段;
  2. 拥塞避免:此阶段cwnd不再指数增长,每经过一个RTT(往返时间)cwnd加1呈线性增长,持续探测网络的最大承载能力;
  3. 拥塞检测:当出现超时重传或收到3个重复ACK时,判定网络发生拥塞;若超时重传,将ssthresh设为cwnd/2,cwnd重置为1,重新进入慢启动;若收到3个重复ACK,将ssthresh设为cwnd/2,cwnd等于新的ssthresh,进入快速恢复阶段;
  4. 快速恢复:每收到一个重复ACK,cwnd加1,当收到新的有效ACK后,将cwnd设为ssthresh,重新进入拥塞避免阶段。

6. 共享屏幕解决算法题:滑动窗口

滑动窗口是双指针的经典应用,通过左、右指针维护一个动态窗口,在O(n)时间复杂度内解决子数组/子串类问题,分定长窗口和不定长窗口两类,核心实现和解题思路如下:

定长窗口(例:长度为k的子数组最大和)

解题思路:右指针扩展窗口,窗口长度达到k后,左指针随右指针同步右移,保持窗口长度不变,遍历过程中统计窗口内结果并更新最优答案。核心代码:

#include <vector>
#include <climits>
using namespace std;
int maxSubarraySum(vector<int>& nums, int k) {
    int n = nums.size();
    if (n < k) return 0;
    int window_sum = 0, max_sum = INT_MIN, left = 0;
    for (int right = 0; right < n; right++) {
        window_sum += nums[right];
        if (right - left + 1 == k) {
            max_sum = max(max_sum, window_sum);
            window_sum -= nums[left++];
        }
    }
    return max_sum;
}

不定长窗口(例:无重复字符的最长子串)

解题思路:右指针扩展窗口,当窗口内满足题目条件被破坏时,左指针收缩窗口,直到条件重新满足,遍历过程中持续更新最优结果。核心代码:

#include <string>
#include <unordered_set>
using namespace std;
int lengthOfLongestSubstring(string s) {
    unordered_set<char> window;
    int left = 0, max_len = 0;
    for (int right = 0; right < s.size(); right++) {
        while (window.count(s[right])) {
            window.erase(s[left++]);
        }
        window.insert(s[right]);
        max_len = max(max_len, right - left + 1);
    }
    return max_len;
}

通用解题步骤

  1. 初始化左指针、结果变量、窗口统计变量(和/哈希表/集合等);
  2. 右指针遍历数组/字符串,扩展窗口并更新统计变量;
  3. 根据题目条件调整左指针,维护窗口的有效性;
  4. 遍历过程中持续更新最优答案。

7. 反问

  1. 这个岗位日常主要负责哪些开发工作,入职后会先接手什么类型的任务?
  2. 团队目前在做的核心项目,技术上的难点和重点突破方向是什么?
  3. 对于实习生,团队会有怎样的带教方式,有代码评审或者技术交流的常规安排吗?
  4. 从实际工作角度,这个岗位需要实习生重点具备哪些能力,我还有哪些地方需要加强?
C++面试总结 文章被收录于专栏

本专栏系统梳理C++面试高频考点,从基础语法、内存管理、STL与设计模式,到操作系统与项目实战,结合真实面试题深度解析,帮助开发者高效查漏补缺,提升技术理解与面试通过率,打造扎实的C++工程能力。

全部评论

相关推荐

不会做题的小熊:我感觉我就算是找不到工作,我也不会作弊进去,作弊进去感觉一方面是自己不踏实,其次就是都靠作弊了,那后面肯定工作的心态是不一样的,没有一种内驱力。
点赞 评论 收藏
分享
评论
1
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务