这篇博客是写给团队后端方向的同学看的。主要是介绍我在工作一年之后对于后端工作方向的一些新的认知(虽然职位是前端,但在这个大环境下面,对后端的工作内容还是有一些了解的)。让大家在学校里可以对外面工业界的需求有一个大致的认识,在自己的兴趣和就业的导向之间找到一个平衡。

互联网公司的技术部门组织架构

从单体到分布式:后端工程师的分工

要理解一个(大型)互联网公司的组织架构,首先要理解一个产品的后端服务从 0 到 1 的发展过程。《大型网站技术架构》这本书对于这个过程有详细的解释。具体的看这篇博客

大致来说就是这样的过程:

单机系统:Java/PHP/Node/Python + Linux + MySql + Nginx。 ==>

流量增大,数据库读写出现瓶颈,数据库分库分表  ==>

流量继续增大,单机部署无法应对高并发,于是集群部署,横向拓展 ==>

为了提高性能,抽出单独的缓存服务 ==>
 
分布式数据库/分布式存储 ==>

微服务架构 ==>

最终进化为适应于特定业务场景的复杂分布式架构

在小型的公司,一般就只有一个后端开发团队,里面没有非常明确的角色分配。服务,数据库,缓存,部署,都要自己来搞。当公司变大的时候,就会出现一些分工。

开发工程师主要负责开发服务,运维和 DBA 负责服务的部署,数据库的安全和效率。架构师负责设计整个应用的架构。

中间件/数据库:后端服务的基石

上一节说到互联网公司的后端架构最终演化为一个分布式的系统。那一个分布式的系统运行,需要许多中间件的支持。比如消息队列,分布式缓存,分布式数据库,微服务框架,容器编排调度等等。这些被其他服务调用的,负责通信/存储的服务,就是所谓的中间件。中间件可以说是连接两个服务的一个中介。

公司越来越大,就需要有人专门去维护这些公共组件,让开发工程师可以专注于业务逻辑的开发。比如维护自己的消息队列,数据库,缓存,RPC框架等等。在大公司中,开源的方案并不能满足业务需求,所以需要对开源的方案进行改进和创新。

上一节中的分工里没有提到的,就是中间件研发的工程师。这些工程师在一个大型的互联网公司中是非常重要的。

数据平台:公司决策的引擎

科技公司在运行中会产生各种各样的数据,比如用户行为数据,订单数据,访问记录数据。还有服务器的运行状态等等数据。这些数据都是一种资产,是公司来了解业务情况的一个窗口。

大数据这个方向其实已经非常成熟了,它主要包括数据的搜集,清洗,加工,存储,计算,分析。在这个链路上,需要很多工程师的努力。我们需要工程师来进行数据的清洗和加工,需要工程师来搭建数据仓库,数据加工平台,数据分析平台。需要工程师来优化数据实时和离线计算的引擎。需要工程师来写各个终端的数据上报服务。

所以大型的互联网公司都会有一个数据部门,让数据产生价值。

运维/安全:保证服务的高可用和安全性

传统意义上的运维负责公司服务器的管理,生产环境的稳定性,公司机房的设计和日常维护。大型公司中,还会涉及异地多活等等高可用方案。

运维这个角色现在也叫运维开发(DevOps)或者 SRE(网站稳定性工程师)。通过脚本和工具进行自动化的运维。比如开发要使用数据库,运维就搭建一个多副本的数据库集群,并且让数据库可以自动备份,还写了一个平台来访问和管理数据库。又或者有一个基础软件,需要安装在 500 台机器上。运维就开发了一个软件,可以让大家一键部署。

安全则是一个很大的领域,主要负责产品的信息安全。公司里一般都会有安全部。

一个大型科技公司的技术部门组织架构:从技术部到中台

小型公司一般只有一个技术部,里面分前端后台等角色。大公司一般是按业务来划分部门。比如电商业务,金融业务,零售业务等等。所谓的业务最终会落地到一个实际的产品中,比如淘宝。一个业务部门可能会同时运营多款产品。

这里需要引入一个概念,叫中台。和中台相对的就是前台。前台部门就是业务部门,直接开发面向消费者的产品的。中台部门就是负责给前台部门输送弹药的。负责支持前台部门。这里的支持不是帮前台部门写业务代码,而是提供一些基础的服务。比如前文里说到的中间件和数据库,还有数据平台。

我们在写产品的时候,会有一个抽象公共代码的过程。把多个模块中公共的部分抽出来。那在公司的运营中,我们也可以把公共的职能抽出来,变为中台。

每个业务部门自己去维护自己的中间件或者数据库,或者搭建数据平台,会造成很大的资源浪费。对部门之前的合作也不利。一个科技公司,统一自己内部的技术栈和基础设施,有几点好处:

  • 方便内部的技术交流和合作
  • 营造统一的技术氛围,利于公司内部的认同感
  • 方便对外输出技术
  • 降低各部门开发的成本

其实中台战略的好处是显而易见的,让专业的人做专业的事,前台负责业务上攻城略地,中台部门负责中台能力的搭建,支持前台业务。

按上述的模式设计的一个虚构的公司 foobar 的技术部门组织架构是这样的:

需要留意的是,本文里介绍的组织架构只是一个高度理想化的模型。现实中的大型科技公司的组织架构有很多种类。有的公司没有统一的中台部门,中台部门的职能被分散到各个业务部门中。只不过小前台+大中台是本文所推崇的一种组织架构。

职位概览

研发(Java/C++)

支持各种系统(面向消费者的,或者内部系统)的研发。基础平台,人工智能,数据平台也需要有平台来展现,所以也需要研发工程师。

简单的说就是写接口的。

数据研发

企业的数据中台,从数据的采集,加工,计算,存储,分析,都需要熟悉大数据相关技术(数据仓库/实时计算/离线计算/数据清洗)的工程师来参与。

基础平台研发(Java/C++/Go)

数据库开发,网络(CDN,机房网络),分布式存储,云计算(虚拟化,操作系统),云计算网络(SDN),中间件(消息队列,缓存,分布式服务框架)

运维(DevOps, DBA)

运维开发,负责产品,数据库,中间件的运维,开发相应的软件来做运维自动化。也会做一些监控系统来监控服务的运行情况。

算法

算法其实不属于后端,是单独的一个类别,里面有视觉/语音/推荐等等各种小方向的职位。

应用 vs 底层

这么多后端方向的职位,我们可以大致分为应用底层两个部分。

应用就是指业务代码,也就是所谓的写 API。

底层就是指中台下面的几个方向,比如中间件/数据平台等等的研发。当然底层里面也有数据库开发/Linux 内核开发等等偏系统级软件的开发。也有平台软件/中间件的研发,比如 K8s 这样的容器调度系统,或者是一个消息队列。这样的软件更靠近应用层,对底层操作系统的依赖没那么大。

今后去工作的时候也会遇到应用 vs 底层的选择。能直接投相关的职位当然是最好,大公司一般都会分清楚招的职位具体是做什么。有的公司可能是先以应用研发的名义统一招人,后面才会有具体的方向。先进入这个行业工作,然后选择自己的方向,也是一个不错的道路。

计算机基础要学到什么样的程度?

国内的教学比较水。我们对一门课的要求是按国外 CS 强校的标准来定的。国外课程的特点是这样的:

  • 教学内容紧凑,只讲核心内容,并且最后会涉及目前时代的新技术,作为拓展
  • 鼓励阅读 Paper 了解技术的原始发表文件,培养学术习惯
  • 作业和 Lab 相辅相成,课后需要花很多时间
  • 作业和 Lab 有老师的 Office Hour(答疑时间)和助教指导,还有课程论坛。有的会由助教开专门的 Lab 复盘课
  • 日常出勤占比例很低,普遍会提供课程录像供后面查阅
  • Lab 设计合理,一般都是环环相扣,系统类的课,一般最终会要求写一个完整的系统,这个系统是这门课的内容的精髓和总结

后端比较关键的课程是这些(除了数据结构和算法,以及编程思想和设计模式一类的课程):

  • 计算机网络
  • 数据库系统
  • 分布式系统
  • 操作系统

这样的课,我们的要求就是,针对每一门课,找到一门国外的课,跟着学完内容(PPT 和要求读的课本相关章节看过,理解,如果有课程视频要看视频),做完 Lab。作业可以根据自己兴趣来做。重点还是在 Lab。

这些 Lab 一般都是要你实现一些底层的东西,比如数据库系统,会让你实现 Buffer Pool 和 B+ Tree。计算机网络让你实现一个完整的 Web Server,还有 TCP 协议等等。分布式系统一般要求实现简单的分布式 KV 存储,还有 Raft 等分布式一致性协议。这些东西都是一门学科最精髓的,而你手动实现过了,那你对这个东西的理解自然远远超过普通的刷题看书的学习方式。

国外 CS 强校招人要求很高,比如 CMU,会要求你在高中就有专业方面的经验和极大的兴趣。所以大家如果做 Lab 做的不爽是很正常的。但在我们整个团队的努力下,我们可以把这些 Lab 一个个做出来。留下攻略给后人。这样我们团队就掌握了这些技术。(国外 CS 名校毕业生比较抢手也是因为他们受到的教育的确不一般)

什么样的技术栈比较好找工作?

应用研发的需求自然要大于底层研发,也只有比较大的企业才会有专职的底层研发。所以说如果技术栈和当前公司流行的技术栈匹配的话,就比较好找工作。现在比较流行的后端开发语言就是 Java 和 C++ 了。电商公司一般都是 Java。腾讯和百度是用的 C++ 比较多。微博用的是 Java 和 PHP。用 PHP 的大公司也有,但在公司里不是主流,所以 PHP 就可以排除了。同样 Python 在大公司里主要还是做一些辅助的工作,比如要开发一个运维系统,就可以用 Python 来写,这样比较快。

一些创业公司也喜欢用 Python 来快速搭建产品原型。比如豆瓣/知乎/字节跳动。但后期如果业务复杂了,一般会用 Java 重构。

Go 语言在大公司用的也挺多,主要是做云计算方向。但很少有大公司直接招 Go 工程师,所以首先精通 Java/C++ 的一种,然后还懂 Go,是比较好的一种选择。

底层研发用的语言就比较受限制了。中间件一般是 Java/C++,系统软件一般是 C/C++。云计算相关的底层系统,Go 用的会比较多。其他语言在底层开发里是很少见到的。

团队后端的几个方向

应用研发由整个后端组的同学来承担(客户端那边也会参与一些中间层服务的编写,简单的全栈工程)

深入的专业方向大概有以下几个:

  • Data 组:数据库/缓存中间件/大数据存储/大数据计算/日志存储和分析/分布式存储原理
  • Cloud 组: 云计算/容器编排/分布式系统/消息队列中间件/微服务框架/RPC框架
  • DevOps 组: 自动化运维/高可用/DBA(规划)

产出:

  • 团队相关方向业务的支持(比如日志系统,比如容器调度)
  • 相关方向课程的 Lab 题解和指南
  • 相关方向开源项目的原理
  • 产出一个我们团队在这方向的小项目(简化版),可以用来学习原理,就像大学都有自己为了教操作系统课程而开发的玩具操作系统一样
  • 相关方向新技术的调研和应用