中兴通讯 C++开发一面总结

1. 自我介绍,说说你的项目经历和技术栈

回答框架:

  • 教育背景和工作经验
  • 熟悉的编程语言和技术栈
  • 做过的项目类型和业务场景
  • 项目中的角色和主要贡献

2. 你的项目中用到了哪些设计模式?举例说明应用场景

答案:

常用设计模式

  1. 单例模式:场景:配置管理类、日志类、数据库连接池保证全局唯一实例
  2. 工厂模式:场景:创建不同类型的网络协议解析器解耦对象创建和使用
  3. 观察者模式:场景:Qt的信号槽机制事件通知、消息订阅
  4. 策略模式:场景:不同的数据压缩算法(gzip、lz4、snappy)运行时切换算法
  5. 装饰器模式:场景:给网络数据包添加加密、压缩等功能动态扩展功能
  6. 适配器模式:场景:适配不同版本的协议接口接口转换

实际案例:"我们的网管系统需要支持多种设备协议(SNMP、Telnet、SSH),用工厂模式创建不同的协议处理器。每种协议处理器实现统一的接口,业务层不需要关心具体协议类型。"

3. 如果软件界面有多个相同类型的控件需要同时响应,你会如何设计

答案:

方案一:信号槽统一处理

// 所有按钮连接到同一个槽
for (int i = 0; i < 10; ++i) {
    QPushButton* btn = new QPushButton(QString::number(i));
    connect(btn, &QPushButton::clicked, this, &MainWindow::onButtonClicked);
}

void MainWindow::onButtonClicked() {
    QPushButton* btn = qobject_cast<QPushButton*>(sender());
    if (btn) {
        qDebug() << "Button" << btn->text() << "clicked";
    }
}

方案二:Lambda捕获索引

for (int i = 0; i < 10; ++i) {
    QPushButton* btn = new QPushButton(QString::number(i));
    connect(btn, &QPushButton::clicked, [this, i]() {
        handleButton(i);
    });
}

方案三:QSignalMapper(Qt5之前)

QSignalMapper* mapper = new QSignalMapper(this);
for (int i = 0; i < 10; ++i) {
    QPushButton* btn = new QPushButton(QString::number(i));
    connect(btn, SIGNAL(clicked()), mapper, SLOT(map()));
    mapper->setMapping(btn, i);
}
connect(mapper, SIGNAL(mapped(int)), this, SLOT(handleButton(int)));

方案四:事件过滤器

for (int i = 0; i < 10; ++i) {
    QPushButton* btn = new QPushButton(QString::number(i));
    btn->installEventFilter(this);
}

bool MainWindow::eventFilter(QObject* obj, QEvent* event) {
    if (event->type() == QEvent::MouseButtonPress) {
        QPushButton* btn = qobject_cast<QPushButton*>(obj);
        if (btn) {
            // 统一处理
        }
    }
    return QObject::eventFilter(obj, event);
}

4. 说说C++的红黑树,STL中哪些容器用了红黑树

答案:

红黑树特点

  • 自平衡二叉搜索树
  • 每个节点有颜色(红或黑)
  • 根节点是黑色
  • 红色节点的子节点必须是黑色
  • 从根到叶子的所有路径,黑色节点数量相同

性能

  • 查找、插入、删除:O(log n)
  • 比AVL树平衡性差一点,但插入删除更快

STL容器

  • map:键值对,有序,底层红黑树
  • set:集合,有序,去重,底层红黑树
  • multimap:允许重复键的map
  • multiset:允许重复元素的set

与unordered_map的区别

  • map:有序,O(log n),红黑树
  • unordered_map:无序,O(1)平均,哈希表

使用场景

  • 需要有序:用map/set
  • 需要范围查询:用map/set
  • 只需要快速查找:用unordered_map/set

5. map和unordered_map的底层实现,哈希冲突如何解决

答案:

map

  • 底层:红黑树
  • 有序:按key排序
  • 时间复杂度:O(log n)
  • 内存:每个节点有额外指针和颜色

unordered_map

  • 底层:哈希表
  • 无序
  • 时间复杂度:O(1)平均,O(n)最坏
  • 内存:需要额外的桶数组

哈希冲突解决

  1. 链地址法(C++ STL采用):每个桶是一个链表冲突的元素放到同一个链表查找时遍历链表
  2. 开放寻址法:线性探测:顺序查找下一个空位二次探测:按平方数探测双重哈希:用第二个哈希函数

负载因子

  • 元素数量 / 桶数量
  • STL默认负载因子1.0
  • 超过阈值会rehash(扩容)

性能优化

  • 预留空间:reserve()避免频繁rehash
  • 自定义哈希函数:提高分布均匀性
  • 选择合适的初始桶数量

6. 图的遍历方法有哪些?如何解决迷宫问题

答案:

图的遍历

  1. 深度优先搜索(DFS):递归或栈实现一条路走到底,再回溯适合:路径搜索、连通性判断
  2. 广度优先搜索(BFS):队列实现逐层遍历适合:最短路径、层次遍历

迷宫问题(最短路径)

struct Point {
    int x, y, dist;
};

int solveMaze(vector<vector<int>>& maze, Point start, Point end) {
    int dx[] = {0, 0, 1, -1};
    int dy[] = {1, -1, 0, 0};
    
    queue<Point> q;
    vector<vector<bool>> visited(maze.size(), 
                                 vector<bool>(maze[0].size(), false));
    
    q.push({start.x, start.y, 0});
    visited[start.x][start.y] = true;
    
    while (!q.empty()) {
        Point cur = q.front();
        q.pop();
        
        if (cur.x == end.x && cur.y == end.y) {
            return cur.dist;
        }
        
        for (int i = 0; i < 4; ++i) {
            int nx = cur.x + dx[i];
            int ny = cur.y + dy[i];
            
            if (nx >= 0 && nx < maze.size() && 
                ny >= 0 && ny < maze[0].size() &&
                maze[nx][ny] == 0 && !visited[nx][ny]) {
                q.push({nx, ny, cur.dist + 1});
                visited[nx][ny] = true;
            }
        }
    }
    
    return -1; // 无解
}

其他图算法

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

C++八股文全集 文章被收录于专栏

本专栏系统梳理C++技术面试核心考点,涵盖语言基础、面向对象、内存管理、STL容器、模板编程及经典算法。从引用指针、虚函数表、智能指针等底层原理,到继承多态、运算符重载等OOP特性从const、static、inline等关键字辨析,到动态规划、KMP算法、并查集等手写实现。每个知识点以面试答题形式呈现,注重原理阐述而非冗长代码,帮助你快速构建完整知识体系,从容应对面试官提问,顺利拿下offer。

全部评论

相关推荐

不会做题的小熊:我感觉我就算是找不到工作,我也不会作弊进去,作弊进去感觉一方面是自己不踏实,其次就是都靠作弊了,那后面肯定工作的心态是不一样的,没有一种内驱力。
点赞 评论 收藏
分享
1.8&nbsp;腾讯官网直投,凌晨把综合测评答完了(2h)。1.13&nbsp;网易互娱官网直投。1.15&nbsp;腾讯一面面邀。1.20&nbsp;早上腾讯一面技术面,感觉良好,下午两位面试官加了微信,邀请二面。1.22&nbsp;腾讯二面总监面(难度直线飙升),压力测试加摸底式技术追问,对线了很久,应对得最不从容的一次。结束后脑袋嗡嗡作响,对自己的表现感到不满意,心情比较难过。1.23&nbsp;早上网易&nbsp;HR&nbsp;加好友并发了&nbsp;JD&nbsp;,看了一下是人工智能+TA方向,感觉不错。HR&nbsp;表示主管刷到我的作品集视频,希望走提前一点的流程,但偏日常实习,婉拒,表示想先走官网看看。1.23&nbsp;下午腾讯一面面试官邀请语音通话并发了两道测试题(意思是二面已过),让我二选一,面试官开玩笑说都做完也可以。悬着的心终于放下了。当晚网易官网测试题直发(但与腾讯测试题时间冲突)。1.24&nbsp;疯狂熬夜,基本完成腾讯第一道测试题,同时找到了第二道题的思路,决定两道题都做,继续攻坚克难(平均每天4h睡眠)。1.26&nbsp;腾讯测试题工程文件、技术文档、视频演示提交,处于身心俱疲状态。当晚收到第二题的迭代要求,ddl27号晚上,强撑继续熬夜肝。1.27&nbsp;早上腾讯测试题迭代版提交。1.29&nbsp;腾讯两道测试题都顺利通过。收到网易测试题邮件催促,然而几乎零进度。比较疲惫。1.30&nbsp;早上腾讯&nbsp;HR&nbsp;面,当天云证。不太满意自己网易测试题的效果,截止日已到,遗憾放弃提交笔试。2.3&nbsp;网易又一位&nbsp;HR&nbsp;电话联系,希望另外给我发测试题,表示可以让我先去腾讯实习,网易的&nbsp;Offer&nbsp;入职时间灵活,可以暑期再入职,并可提供转正机会。反复博弈,本身欣赏网易氛围且有认识网易的小伙伴,欣然接受。晚上&nbsp;HR&nbsp;和业务沟通后表示给我免笔试(受宠若惊)。2.4&nbsp;网易一面面邀。2.6&nbsp;网易一面,虽然有些算法没答上来,但是作品集相关的问题答得没问题,当天过了。感觉面试官像主管,而且真的是把我的B站视频大概看了一下,连我以前喜欢玩什么游戏都知道,气氛一下变得融洽了起来。晚上邮件二面面邀。2.9&nbsp;腾讯官网流程卡在录用评估一个多星期了,比较焦虑。由于行程安排需要,并且临近春节,在群里友好催了一下腾讯二位面试官,结果秒发邮件,无&nbsp;OC&nbsp;直接&nbsp;Offer&nbsp;!戴上红围脖啦~2.10&nbsp;网易二面。因为没做笔试题,所以几乎还是和一面一样追问作品集,但只追问了一两个技术比较复杂的demo,相比一面,问题深度多上了几个level,而且比较发散,会考虑到实际开发的可能遇到的难题。两位面试官,几乎只是一位面试官在问,另一位面试官只在反问环节进行了解答。2.12&nbsp;网易方面最早联系我的那位&nbsp;HR&nbsp;邀请微信语音通话,表示网易方面想要给我发&nbsp;Offer&nbsp;,但是考虑到我这边已经有腾讯&nbsp;Offer&nbsp;了,需要我取舍一下,并反复强调网易的福利,继续博弈,婉拒了网易,希望暑期能够有机会再次合作。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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