中兴通讯 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。

全部评论

相关推荐

02-12 20:22
重庆大学 Java
字节暑期刚入职四天,因为是年前,所以很多正职都放假走了,也就没有给我分配mt,然后有一个老哥在我来的时候给我发了一个landing手册,然后还有关于部门业务的白皮书,还有一些业务代码。然后本人是java面的,进来第一次接触go语言&nbsp;前面几天熟悉了一下go的语法和go的框架,可以读但是还不太会写,然后业务白皮书也看的很头疼,包括landing手册里要了解的很多东西说实话我看文档真的快看死了,一个嵌套一个,问题是我还完全不知道咋用这个我了解的东西,还有就是那个项目代码,那个老哥喊我去写写单测,熟悉一下go的语法,但也进行的很困难(这是我第一段实习,之前都是springboot那一套,真不太熟悉这个)想问问大家的建议,就是我从现在开始到在开年回来之前应该做些什么,我目前就一个想法&nbsp;就是复现一个landing手册上的go框架小项目&nbsp;就是相当于帮自己锻炼锻炼怎么写go&nbsp;或者各位大佬有没有更好的锻炼go语法的建议还有就是大家都在说vibe&nbsp;coding,那我应该怎么锻炼自己使用ai的能力,感觉我除了给一些需求然后它给我生成代码,好像就没别的用法了,那些什么工作流、拆解、skill啥的都不知道从哪一个地方开始,包括我现在正在实习,不知道精力该怎么分配,去网上想找找关于agent开发的一些学习流程,说实话,众说纷纭,有的是从python开始打基础然后系统学那些rag&nbsp;prompt&nbsp;langchain&nbsp;mcp等等,有的是说直接找一个github上的ai项目然后反复问ai,我确实有点迷茫,恳求各位大佬能留下你们宝贵的建议,我一定认真反复深刻学习有一说一&nbsp;我觉得字节饭挺好吃的!
双非后端失败第N人:1. go语言我建议你让ai带着你先把基本语法速通了,然后再去用go重新刷你以前刷过的leetcode,这样熟悉起来很快 2. 直接看你们组go项目,里面用***比较复杂,然后把每一个语法现象都喂给ai,一点点看
字节跳动公司福利 1371人发布
点赞 评论 收藏
分享
owwhy:难,技术栈在嵌入式这块显得非常浅,并且简历有大问题。教育经历浓缩成两行就行了,写什么主修课程,说的不好听这块没人在意,自我评价删了,项目写详细点,最终简历缩成一页。相关技能怎么说呢,有点差了,还写成这么多行
投了多少份简历才上岸
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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