AI 点评
cover

项目难点和面试技巧

香蕉牛奶 Lv.6 2026-10-08 19:59 1818 字 浏览 157 点赞 评论 1 C++

项目如何描述

按照 HR 搜索简历的方式,基本都是采用关键字搜索,所以要在简历中暴露项目中的技术亮点。

为了让面试官通过简历快速了解项目和采用的技术,需在项目介绍时融入技术细节,让项目描述更饱满一点。

可增加个人业绩或者个人成长,让面试官了解项目的意义等。

综上所述,一个项目的描述需包含如下几点:

  • 项目描述
  • 技术亮点
  • 项目价值

项目描述

这是一个全栈的即时通讯项目。

前端基于 QT 实现气泡聊天对话框,通过 QListWidget 实现好友列表,利用 GridLayout 和 QPainter 封装气泡聊天框组件,基于 QT network 模块封装 http 和 tcp 服务。支持添加好友、好友通信、聊天记录展示等功能,仿微信布局并使用 qss 优化界面。

后端采用分布式设计,分为 GateServer 网关服务、多个 ChatServer 聊天服务、StatusServer 状态服务以及 VerifyServer 验证服务。

各服务通过 grpc 通信,支持断线重连。GateServer 网关对外采用 http 服务,负责处理用户登录和注册功能。登录时 GateServer 从 StatusServer 查询聊天服务达到负载均衡,ChatServer 聊天服务采用 asio 实现 tcp 可靠长链接异步通信和转发,采用多线程模式封装 iocontext 池提升并发性能。数据存储采用 mysql 服务,并基于 mysqlconnector 库封装连接池,同时封装 redis 连接池处理缓存数据,以及 grpc 连接池保证多服务并发访问。

经测试单服务器支持 8000 连接,多服务器分布部署可支持 1W~2W 活跃用户。

技术点

asio 网络库,grpc,Node.js,多线程,Redis,MySql,Qt 信号槽,网络编程,设计模式

项目意义

关于项目意义可结合自身讨论,比如项目解决了高并发场景下单个服务连接数吃紧的情况,提升了自己对并发和异步的认知和处理能力等。


考察点

如何利用 asio 实现 tcp 服务

利用 asio 的多线程模式,根据 CPU 核数封装 iocontext 连接池,每个连接池跑在独立线程,采用异步 async_read 和 async_write 方式读写,通过消息回调完成数据收发。

整个项目采用的网络模式是 Proactor 模式,每个连接通过 Session 类管理,通过智能指针管理 Session,保证回调之前 Session 可用,底层绑定用户 id 和 session 关联,回调函数可根据 session 反向查找用户进行消息推送。

客户端和服务器通信采用 json,通过 tlv 方式(消息头:消息id + 消息长度 + 消息内容)封装消息包防止粘包。通过心跳机制检测连接可用性。

如何保证服务高可用

  1. 故障检测与自动恢复:

    • 实施监控系统,实时检测服务的健康状况。
    • 配置自动重启或故障转移机制,确保在故障发生时能够迅速恢复服务。
  2. 分布式架构:

    • 采用微服务架构,将应用拆分为多个独立的服务,降低单个服务故障对整体系统的影响。
  3. 数据备份与恢复:

    • 定期备份数据,并进行恢复演练,确保在数据丢失或损坏时能够快速恢复。
  4. 多活部署:

    • 在不同地理位置部署多个活跃的数据中心,确保在某个数据中心发生故障时,其他数据中心可以继续提供服务。

为何封装 Mysql 连接池

首先多个线程使用同一个 mysql 连接是不安全的,所以要为每个线程分配独立连接,而连接数不能随着线程数无限增加,所以考虑连接池,每个线程想要操作 mysql 的时候从连接池取出连接进行数据访问。

Mysql 连接池封装包括 Mgr 管理层和 Dao 数据访问层,Mgr 管理层是单例模式,Dao 层包含了一个连接池,采用生产者消费者模式管理可用连接,并且通过心跳定时访问 mysql 保活连接。

如何测试性能

测试性能分为三个方面:

  • 压力测试,测试服务器连接上限
  • 测试一定连接数下,收发效率稳定性
  • 采用 pingpong 协议,收发效率稳定在 10ms 下,连接数上限

压力测试,看服务器性能,客户端初始多个线程定时间隔连接,单服务节点连接上限 2w 以上稳定连接,并未出现掉线情况。

测试稳定性,单服务节点连接数 1W 情况下,收发稳定未出现丢包和断线,并且延迟稳定在 10ms。

保证 10ms 延迟情况下,增加连接数,测下连接数上限,这个看机器性能,8000~2W 连接不等。

用到哪些设计模式和思想

  • Actor 模式,逻辑解耦
  • 生产者消费者模式(涉及线程池)
  • 单例模式(网络管理和数据库管理类)
  • RAII 思想(defer 回收连接)
  • 代理模式(数据库、redis 等通过代理对接应用层调用,底层线程池隐藏技术细节)
  • MVC 控制思想,客户端通过 MVC 三层结构设计
  • 线程分离,网络线程、数据处理线程以及 UI 渲染线程分离
  • 心跳服务
  • 数据序列化压缩发送(Protobuf,Json)
  • 队列解耦合,服务器采用发送队列保证异步顺序,通过接受队列缓存收到数据,通过逻辑队列处理数据
  • 分布式设计,多服务通过 grpc 通信,支持断线重连
  • C++11 现代化技术,智能指针、伪闭包、模板类型推导、线程池、future、promise 等

描述线程池封装

线程池采用 C++11 风格编写,整体来说线程池通过单例封装,内部初始化 N 个线程,采用生产者消费者方式管理线程,包含任务队列,任务队列采用 package_task 打包存储,提供对外接口 commit 提交任务,采用 bind 语法实现任务提交在 commit 内部自行绑定,通过智能指针伪闭包方式保证任务生命周期。同时使用 C++11 future 特性,允许外部等待任务执行完成。

为什么要设计心跳

在网络情况下,会出现各种各样的中断,有些是网络不稳定或者客户端主动断开连接,这种服务器是可以检测到的。

PC 拔掉网线,还有一种情况客户端突然崩溃,有时候服务器会检测不到断开连接,那么你这个用户就相当于僵尸连接。

当服务器有太多僵尸连接就会造成服务器性能的损耗。

另外心跳还有一个作用,保证连接持续可用,比如 mysql、redis 这种连接池,如果不设计心跳,时间过长没有访问的时候连接会自动断开。


最后更新时间:2026-10-14 19:42

微信扫码分享

评论(1) 最新 热门

登录 后才能评论。

  • Fool Lv.6 网站管理员 2026-10-10 10:29
    💚