优必选 C++开发工程师 二面

1. 常见 STL 容器有哪些?vector/list、map/unordered_map 的区别与使用场景

常见容器:vector、deque、list、set、map、unordered_map、unordered_set、queue、stack。

vector vs list:

  • vector 连续内存,随机访问 O(1),尾插高效,cache 友好;
  • list 链表结构,任意位置插删 O(1)(已知迭代器),但随机访问差、cache 不友好。

map vs unordered_map:

  • map 红黑树,O(logN),有序,可范围查询;
  • unordered_map 哈希表,均摊 O(1),无序,最坏可退化。

使用场景:

  • 需要顺序、范围查询、稳定复杂度:map;
  • 追求高频点查性能:unordered_map;
  • 内存局部性和遍历性能优先通常先选 vector。

2. 智能指针:shared_ptr 是线程安全的吗?为什么?

结论分两层:

  1. 控制块引用计数的增减是线程安全的(通常是原子操作);
  2. 指向对象本身的读写不是天然线程安全,仍需锁或无锁同步。

另外,同一个 shared_ptr 实例被多线程同时读写(如 reset)也需要外部同步。 所以“shared_ptr 线程安全”只成立在“计数管理”层面,不等于“对象访问安全”。

3. 除了基础单例,如何实现“线程安全 + 防止反序列化破坏”的工程化单例?

推荐“函数内静态对象”(Meyers Singleton),C++11 起初始化线程安全。 如果系统涉及序列化/反射/插件热加载,还要约束拷贝、移动、构造入口。

代码:

class ConfigCenter {
public:
    static ConfigCenter& instance() {
        static ConfigCenter inst;
        return inst;
    }

    ConfigCenter(const ConfigCenter&) = delete;
    ConfigCenter& operator=(const ConfigCenter&) = delete;
    ConfigCenter(ConfigCenter&&) = delete;
    ConfigCenter& operator=(ConfigCenter&&) = delete;

private:
    ConfigCenter() = default;
    ~ConfigCenter() = default;
};

4. 在“工业 IoT 实时控制网关”项目中你用了哪些容器?为什么这么选?

我在该项目里主要用了:

  • vector:存设备连接快照(遍历密集,cache 友好);
  • unordered_map:device_id -> session 快速路由;
  • deque:收发缓冲队列(头尾操作频繁);
  • priority_queue:定时任务超时管理。 选型原则是“访问模式优先”,而不是“容器功能越多越好”。

5. JsonRpc 分层设计如何做,才能支持高并发与可观测?

答案: 可拆为 5 层:

  1. Transport 层:TCP/WebSocket 收发;
  2. Codec 层:JSON 编解码与协议校验;
  3. Dispatcher 层:方法路由、参数绑定;
  4. Service 层:业务实现与资源访问;
  5. 治理层:超时、重试、限流、熔断、Tracing。

关键点:

  • request_id 全链路透传;
  • 错误码分层(协议错误/业务错误/系统错误);
  • 与线程模型解耦,避免业务阻塞 IO 线程。

6. muduo 的线程模型和架构是什么?主从 Reactor 相比纯线程池优势在哪?

muduo 典型是 one loop per thread:

  • 主 Reactor(acceptor)负责接入;
  • 子 Reacto

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

C++ 常考面试题总结 文章被收录于专栏

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

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

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