C++ 后台方向项目推荐(持续更新)
发现现在很多 C++ 后台方向的同学简历高度同质化,基本上 50% 以上的同学都有一个项目:WebServer
但是大家不用太担心!
其实面试官都是知道的,知道学生阶段 C++ 本身没有太成熟的生态和框架,不像 Java,学完 Java Web 就有很多项目可做。
C++ 这块的确差一些,基本上每个用 C++ 的公司都是自己搞一套轮子,百度、腾讯、360、搜狗这些基本每家都不一样,像腾讯内部还有好几套 RPC 框架。
所以大家都做这个服务器项目也还好,但是呢!
前提是代码一定是你自己写的,并且你搞懂了这个项目中的一些重点知识,比如IO线程和工作线程、线程池之间通信、并发的处理、epoll 等等。
在这分享一下我学习过程中整理的书籍、面经、博客等,不是在网上那种打包下载的,而是自己需要学到某个方向知识的时候,去挨个找的,最后汇总而成。
有需自取: 计算机必看经典书单(含下载方式)
除了 WebServer 还能做啥?
其实除了 HTTP 服务器,还有很多可以做的,比如文件服务器、FTP服务器、代理服务器(模仿nginx代理功能)、聊天软件、RPC 框架、网络库等等,这一块都是和网络编程相关的。
除了网络编程呢,也可以写一些单机的小软件,比如 KV 存储引擎,这块可以去学习开源的 LevelDb,其代码总量在一万五左右,是谷歌两位大神级别的工程师发起的开源项目,LevelDb 是能够处理十亿级别规模Key-Value型数据持久性存储的C++ 程序库。
学完之后可以掌握 LSM-Tree 这种现在很流行的存储结构,自己也可以模仿简单实现,核心的就是几个打开文件、落盘文件、Put、Delete、Get 接口:

还有类似 文件压缩、加解密的工具,甚至是模仿实现 STL 里面的容器,这些对于在校的同学都是可以作为项目的。
网络编程
另外,很多同学问我网络编程如何学习?
在这分享一点个人经验吧,我们知道有本网络编程圣经:《Unix网络编程》
但是我建议不要直接上来就去看《Unix网络编程》,这本书里面很大的篇幅都在讲解 API 和 Unix Socket API 细节,很容易看不下去。
我建议先去随便找菜鸟教程或者 man 手册熟悉常用的 socket api,先写几个网络聊天室这种小程序来,然后再去考虑进阶。
C++ 后台开发基本是离不开网络编程的,其实甚至整个后台开发也可以看做是在做网络编程。
只不过别人的框架帮我们做了协议解析、网络数据传输、解封包这些底层操作。
比如 SpringBoot 这种保姆级框架,基本上属于将一个框架能干的事都干完了,以至于我们开发业务只需要定义接收和返回包的数据格式,然后做逻辑处理就完了。
像序列化、解封包、IO 处理这种网络编程必备的脏活业务开发根本不会接触到。
但是网络编程技能还是很重要的,特别是对于 Linux C++ 开发来说。
Linux 下网络编程核心的包括系统编程和网络 IO 两个部分:
- 进程间通信方式: 信号量、管道、共享内存、socket 等
- 多线程编程:互斥锁、条件变量、读写锁、线程池等
- 五大 IO 模型:同步、异步、阻塞、非阻塞、信号驱动
- 高性能 IO 两种模式:Reactor 和 Proactor( 但是 Linux 下由于缺少异步 IO 支持,基本没有 Proactor
- IO 复用机制:epoll、select、poll(破解 C10K 问题的利器)
推荐的书:
- 《Unix网络编程》
- 《Unix环境高级编程》
这两本是砖头书,虽然是网络编程和 Unix 系统编程方面的无出其右的圣经,但主要用途还是垫显示器(逃, 个人觉得这种书不是面向读者的,具体原因和如何阅读这种书在后文介绍。
- 《Linux高性能服务器编程》
我强烈推荐,这本书前半部分基本是在重复计网基础知识,但是后面几章关于高性能服务器程序框架、高性能IO、IO复用、定时器、多线程编程、线程池和进程池还是讲得非常全面到位的,值得一看,看完基本上对于整个网络编程就有了框架。
- 《Linux多线程服务器端编程》
这本书同样强烈推荐,这是陈硕大佬写的书,说实话第一部分:C++ 多线程系统编程都直接把我看蒙了,没有想到 C++ 里要做到线程安全这么难,第一章我看了两三遍才看懂吧。。。 这是难得的讲解 C++ 多线程编程的书。
并且在书中,陈硕大佬用了一章讲解了 Muduo 网络库设计与实现,Muduo 比较适合学完基础的网络编程后继续进阶学习如何设计和写一个网络库,是一个高质量的 Reactor 网络库,采用 one loop per thread + thread pool 实现,代码比较简洁,书和源码搭配着看作为学习网络编程方面来说是非常不错。
推荐的阅读顺序:
《Linux高性能服务器编程》—> 《Unix网络编程》(注意,不是全看,而是学习高性能服务器编程这本书的时候需要某个Socket API 或者 IO 模型时再去查阅 UNP) -> 《Linux 多线程服务端编程》
学完网络编程就可以写点小项目练手了,这里列举几个项目:
HTTP 服务器,正如前文所有,这个似乎成了 Linux C/C++ 人手一个的项目了?
这里推荐两个做为参考:
https://github.com/imarvinle/WebServer
、https://github.com/linyacool/WebServer
,HTTP 服务器看着挺简单的,但是可以扩展写的地方还是挺多的,比如可以加入代理功能,这部分我在留学生 lab 中写过,但是没有集成到这个里面来,可以加入日志库,可以添加 CGI 支持等等。网络库 这个也算是造轮子了, 可以就采用 one loop per thread + thread pool 这种模式,先去看懂 Muduo 源码,然后自己再写一个类似的,这个过程就算是抄,你也可以学到不少东西的,学编程不就是这样先看,再模仿、修改,然后创新吗?
RPC 写一个 PRC 你需要考虑到序列化、网络传输、服务发现等,比较有名的有 grpc、brpc,这两个网上文档都比较完善,可以学习一下实现原理。 完整的可以参考 PhxRPC,代码量不算大。
类似 QQ的 网络聊天室 简单版的就可以直接在局域网内实现群聊、单聊等。 更进一步可以考虑一下如何不通过服务器中转消息实现 P2P 聊天,类似 QQ,这里会涉及到 UDP 打洞、NAT 转换等知识,还是很有意思的,我大二用 Java 搞过。 Java的话,这些基础的网络编程概念都是共通的,大家可以再去看看 Netty。
RPC 推荐
在这里在单独提一下 RPC,相比 HTTP 服务器更推荐大家现在有时间的情况下,去自学 RPC 并实现一个简易版的。
因为目前公司内微服务基本都是基于 RPC构建的,做这个更加贴合业界。
推荐两个:
SRPC
一个是搜狗开源的RPC:
https://github.com/sogou/srpc
特点如下:

并且会有教程,教大家如何使用:

phxrpc
另外一个就是微信开源的 rpc:
https://github.com/Tencent/phxrpc
(PS: 以下信息皆来自网上公开内容,不涉及泄露~
众所周知,微信后台主要使用C++。后台服务使用Svrkit框架搭建,服务之间通过同步RPC进行通讯。

使用 Svrkit 构建了数以千计的服务模块,提供数万个服务接口,每天 RPC 调用次数达几十万亿次。
PhxRPC 就是微信后台团队推出的一个非常简洁小巧的 RPC 框架,编译生成的库只有450K:
Github 地址:
https://github.com/Tencent/phxrpc
但是这个开源的框架不是微信内部实际使用的,因为实际使用的版本有太多的内部依赖,已经不太好整理开源出来,所以这个是开源简化版。
PhxRPC 使用“协程” 来解决常规“异步 + 回调”方式存在的 IO 阻塞的问题,大大提高了整体性能。
它主要有以下几个特点:
- 使用 Protobuf 作为IDL用于描述 RPC 接口以及通信数据结构。
- 基于 Protobuf 文件自动生成 Client 以及 Server 接口,用于Client 的构建,以及 Server 的实现。
- 半同步半异步模式,采用独立多IO线程,通过 Epoll 管理请求的接入以及读写,工作线程采用固定线程池。IO 线程与工作线程通过内存队列进行交互。
- 支持协程 Worker,可配置多个线程,每个线程多个协程。
- 提供完善的过载保护,无需配置阈值,支持动态自适应拒绝请求。
- 提供简易的 Client/Server 配置读入方式。
- 基于 Lambda 函数实现并发访问 Server,可以非常方便地实现 Google 提出的 Backup Requests 模式。
用 PhxRPC 写一个服务非常简单,用 Protobuf 定义好接口协议后,直接就可以生成服务代码,你只需要关注业务逻辑实现即可,其它网络收发包、协议解析都由框架完成了:

实现自己的 mini rpc
如果要实现一个简单版本的 RPC 框架,拆解以下,大概需要以下步骤:
- 自定义传输协议,大概就是头部一些字段,然后加上数据包体,可以使用某种语言作为 IDL(Interface Description Language)来定义服务接口,比较常用的 Protobuf。
- 客户端代码生成器:使用 IDL(Interface Description Language)定义服务接口,根据定义生/成客户端代码。
- 服务端代码生成器:使用 IDL 定义服务接口,根据定义生成服务端代码,这里是指生产调用 RPC 框架基础能力的代码。
- 数据传输模块:选择一种合适的终端协议,如 TCP 或者 UDP。
- 序列化和反序列化:将请求和返回值的数据转换为二进制格式进行传输,选择一种序列化协议,如 JSON,Thrift 或 Protobuf,并且要考虑如何将序列化数据反序列化回原始数据。
- 服务注册和发现:实现服务的注册和发现机制,这样客户端与服务端之间才能进行寻址通信。可以使用 ZooKeeper、etcd、Consul 等分布式服务注册中心。当然最简单版本的可以是用配置文件记录各个服务的 IP、Port 信息。
- 并发处理:实现并发处理机制,服务器能同时处理多个请求。
- 异常处理:为服务中可能出现的异常定义错误码、异常信息等,并实现异常处理机制,比如服务端超时重传、快速拒绝等等(这些都是进阶功能)
- 安全验证:添加安全验证机制,如用户认证、IP 白名单、密钥等机制,确保请求来自合法的客户端。
- 性能优化:进行性能调优,如缓存、负载均衡、异步调用等,提高整个 RPC 系统的性能和吞吐量。
- API 文档和测试:提供 API 文档和测试用例。
好了,今天就到这里啦,还在找工作的同学加油!
算法和八股文都要重视起来!