淘天 客户端开发-C++ 一面

1. 自我介绍

2. 你为什么做这个项目

3. 你在项目中有遇到什么困难吗?

4. 这个项目是买的博主的还是学校让做的

5. 项目中有用到线程池吗?线程池的核心结构是什么?

项目中使用了线程池处理服务端异步业务逻辑,避免阻塞IO线程。核心结构包括:任务队列、工作线程组、互斥锁(保证队列安全)、条件变量(线程等待与唤醒)、任务提交与调度接口。

#include <iostream>
#include <vector>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
using namespace std;

class ThreadPool {
public:
    ThreadPool(int num = 4) : stop(false) {
        for (int i = 0; i < num; ++i)
            threads.emplace_back([this] { run(); });
    }

    template<class F>
    void addTask(F&& f) {
        unique_lock<mutex> lock(mtx);
        tasks.emplace(forward<F>(f));
        cv.notify_one();
    }

    ~ThreadPool() {
        stop = true;
        cv.notify_all();
        for (auto& t : threads) t.join();
    }

private:
    void run() {
        while (true) {
            unique_lock<mutex> lock(mtx);
            cv.wait(lock, [this] { return stop || !tasks.empty(); });
            if (stop && tasks.empty()) return;
            auto task = move(tasks.front());
            tasks.pop();
            lock.unlock();
            task();
        }
    }

    vector<thread> threads;
    queue<function<void()>> tasks;
    mutex mtx;
    condition_variable cv;
    bool stop;
};

6. RPC 服务端收到消息时会有异步处理,这部分你是怎么设计的?

服务端采用IO线程与工作线程分离的设计:

  1. IO线程仅负责接收数据、拆包、协议解析;
  2. 将解析完成的请求封装为任务对象;
  3. 提交至线程池异步执行业务逻辑;
  4. 处理完成后,将响应结果交还给IO线程发送回客户端。该设计保证IO线程不被耗时逻辑阻塞,提升系统并发能力。

7. 项目底层使用什么协议通信?为什么选用 TCP?

底层采用TCP协议通信。RPC调用要求消息可靠、有序、不丢失、不重复,TCP原生支持连接管理、确认应答、超时重传、流量控制和拥塞控制,能保证远程调用的稳定性和正确性,非常适合RPC这种强可靠性要求的场景。

8. 如果换成 UDP 可以吗?上层需要做哪些设计来保证可靠性?

UDP可以使用,但UDP本身不可靠,必须在应用层实现可靠性机制:

  1. 消息编号与序列号;
  2. ACK确认应答机制;
  3. 超时重传策略;
  4. 乱序数据包重排;
  5. 重复数据包过滤;
  6. 基础拥塞控制。相当于在应用层实现一套轻量级TCP可靠性协议。

9. 你了解 muduo 库的底层实现模型吗?

muduo采用one loop per thread + 线程池的经典高并发模型:

  1. 基于epoll事件驱动,非阻塞IO;
  2. 每个线程拥有独立的事件循环loop;
  3. IO线程只处理网络事件,不执行业务逻辑;
  4. 耗时业务交由线程池异步处理;整体无锁设计、低延迟、高并发,是客户端/服务端网络层的优秀实现方案。

10. 你的项目主体只有 RPC 客

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

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

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

全部评论

相关推荐

02-25 22:31
东北大学 Java
Part1:字符串/数组(注重StringBuilder的使用):1.合并两个数组:倒序插入排序2.删除有序数组重复项&nbsp;I&nbsp;/&nbsp;II&nbsp;:&nbsp;指针计数3.股票利润II&nbsp;:&nbsp;局部贪心累加所有上升坡段4.H指数:计数排序(桶排序),倒着遍历5.O(1)&nbsp;时间插入、删除和获取随机元素:HashMap&nbsp;+&nbsp;ArrayList,删除就用尾节点与被删节点交换再删尾节点6.加油站:贪心&nbsp;总油量不能亏损&nbsp;找局部亏损最低点7.分糖果:两次贪心&nbsp;&nbsp;进阶:常数空间解法:上升段&nbsp;平坡&nbsp;下降段8.罗马数字转整数:比较相邻两罗马数字,左&nbsp;&gt;&nbsp;右&nbsp;+当前罗马数字数值&nbsp;否则&nbsp;减&nbsp;当前罗马数字数值9.整数转罗马数字:排列所有可能罗马数字从大到小,遍历数值,减去罗马数字数值去拼接10.最长公共前缀:以第一个字符为基准,去纵向扫描其他字符串的列开始比较11.反转字符串的单词:去除字符串首位和单词间多余空格(仅保留一个)-&gt;&nbsp;反转字符串&nbsp;-&gt;&nbsp;反转每个单词12.Z字型变换:用StringBuilder对象作为桶来存储该存储的字符,用一个标志变量flag判断向下/向上走(第一行/最后一行)13.找出字符串中第一个匹配项的下标(haystack,&nbsp;needle):needle&nbsp;是一个固定长度的窗口,在&nbsp;haystack&nbsp;上从左向右滑动,设&nbsp;haystack&nbsp;长度为&nbsp;n,needle&nbsp;长度为&nbsp;m。我们只需要在&nbsp;haystack&nbsp;中遍历到索引&nbsp;n&nbsp;-&nbsp;m,去匹配。&nbsp;&nbsp;&nbsp;&nbsp;进阶:KMP算法(next数组)14.文本左右对齐!!!(难度巅峰):核心是空格的分配:情况&nbsp;1:当前行只有一个单词-单词左对齐,末尾补齐空格情况&nbsp;2:当前行是最后一行-所有单词左对齐,单词间只留&nbsp;1&nbsp;个空格,行末补齐空格情况&nbsp;3:普通行-计算总空格数:maxWidth&nbsp;-&nbsp;当前行单词总字符数。均匀分配:空格数&nbsp;/&nbsp;(单词数&nbsp;-&nbsp;1)&nbsp;是基础空格数。左侧多分配:空格数&nbsp;%&nbsp;(单词数&nbsp;-&nbsp;1)&nbsp;是需要额外多加&nbsp;1&nbsp;个空格的间隔数。
查看14道真题和解析
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

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