本文已收录于Github:https://github.com/imcoderlemon/CodeClass
内含原创干货文章,千本计算机电子书,3本LeetCode题解,各类编程资源
大家好,我是柠檬。
柠檬哥作为一个普通大学、非计算机专业,自学后端技术进入腾讯做后端开发工作,我自己也是非科班自学计算机成功转行软件开发(有想听柠檬哥转行之路经历的吗,可以留言告诉我,人多就写写),体会过当初想学又不知从何学起的迷茫,还好最后摸索出了一条正确学习的路线。
思来想去,学习方向和路线很重要。比起具体的技术细节,可复制的经验、清晰的学习路线,是大部分人更加需要的东西。
朝着正确的方向努力否则只会离目标越来越远,不是吗?
只顾着写各种技术,不告诉大家这个知识点在后端技术图谱的什么位置,有点盲人摸象不知全貌的感觉,很多在我看来大家都懂的内容,其实只是我以为,信息差是客观存在的,抹平信息差是分享的价值所在。
所以这一期文章柠檬哥足足花了半个月时间,整理了一张后端技术学习路线思维导图,来和你聊聊:
要成为一个符合 BAT、TMD 大厂要求的后端技术工程师,到底需要学哪些技术?后端技术学习路线是怎样的?
话不多说,直接上刚画完的后端技术学习路线思维导图框架:
图中的每一个节点都可以点开,我都做了细分,在后面章节逐个展开介绍。
后端技术学堂开课半年以来,写了 30+ 篇原创文章,内容有Linux、数据库、算法、架构、微服务、甚至中间还写了一个系列的Golang基础教程,真算得上是天马行空,这就是才华横溢吧(狗头)。
历史文章都在后端知识体系范畴内,你甚至可以对照下我历史文章分享的内容,都可以在我今天整理的这张学习路线图中找到相应的位置,后续更新的文章我也会归类到其中,方便大家归纳复习。
不管是后端开发还是前端开发,说到底我们所有的软件开发都是在计算上编写程序,虽然对于大部分人来说,真正开始写代码的时候很少会让你去解决计算机底层的问题,不接触不代表不重要,计算机基础是最重要的。
后端开发工作中经常用到 Java、C++、Python、Golang 这些语言称为高级编程语言,称为高级是它们接近我们日常交流的自然语言,离计算机底层远,但所有的高级语言最终都会转化成汇编->计算机指令->控制流操控计算机硬件,所以学习计算机构成和工作原理、操作系统这些基础知识,能够加深我们队高级语言的理解。
那我们一直说的计算机基础到时是什么?计算机科学技术 CS(Computer Science)作为一门专业课程,就和其他工科课程一样有自己的理论体系,如果你是计算机专业的同学不用我来教该学什么,计算机专业大学四年学校教的那些就是基础,别小看你在学校学的那些看起来没啥用的课程。我这有一份中中科大的计算机技术本科主要课程结构安排。
一流大学的计算机专业要学什么可以对照着看下,从学科数学理论基础、计算机体系结构、软件工程方法等等维度展开。
那如果你不是计算机相关专业的想转行,也不要被吓到了,毕竟这是人家四年时间的学习内容,本科的培养目标不仅仅是培养出一个软件工程师,本科学习还是面向硕士博士的基础培养,注意是计算机科学专业,名字里有个词叫「科学」,我这篇文章要说的 BAT 公司后台软件开发,可以认为是「工学」方向,更多的是服务于工程开发。
如果只是面向后台开发和工作面试,或者你是非计算机专业想转行,社畜没有太多时间去学习大学那些理论课程,那帮我把计算机基础的范围缩小到下面这 4 门专业课:计算机组成原理、计算机网路、操作系统、数据结构。
这门课程让你了解计算机的组成和工作原理,要学习的内容包括:
世界上第一台通用计算机「ENIAC」于 1946 被发明出来,如其名字一样仅仅是用于计算,在后来计算机越来越多,如果没有网络每台计算机都将成为一个孤岛,也不会有现在互联网的繁荣,「计算机网络」这门课程的学习路线非常清晰,就是围绕着如何让地理位置上不同的计算机连接起来,并高效可靠的交换数据信息,实现人在家中做,天下事尽知。
计算机网络有分层次,根据各层属性和特点,分为:
这个层次划分从上到下就是一个网络数据包的接收路径,反之就是发送路径。既然要交换信息肯定得商量一套通用的协议,就像我们和老外交流,要么他们学中文要么我们学英文,反正得统一出一个标准语言出来,这在计算机网络中称之为「通信协议」。如上述的网络分层,每层都有各自适配的协议,所以计算机网络的学习基本就是围绕着分层协议的学习。
操作系统也是一种软件。你熟悉的微软Windos操作系统,后台开发熟悉的各种发行版的 Linux 系统,都是通过软件的形式安装在计算机上。
只不过这个软件和我们平常接触的应用程序软件不同,它比较特殊,因为它向下和计算机硬件(就是我们在计算机组成原理中学习的那些硬件)打交道,向上给其他应用程序和用户提供通用的交互的接口,说白了操作系统就是个中介和管家的角色。它帮我们做了下面这些事情:
数据结构大家最熟悉,即使毫无计算机基础或是想转行计算机,第一个遇到的就是数据结构,因为面试刷的算法题本质上就是对各种数据结构的运用。所以单纯对面试功利的角度来说,数据结构也是必须要掌握的计算机基础,数据结构要学到:
好了,计算机基础四大专业课已经大概过了一遍,当然这是我给没有计算机基础同学的实用主义建议,等你学完这四门课程也只能够说入门计算机了,不过这已经比很多人厉害了。如果想真正的了解计算机这门学科,可以等学完了这 4 门基础课程之后,再花写时间挑一些上面培养方案中的课程去学习,做一个知识体系完备的计算机软件后端开发工程师。
在后台开发领域,你所能接触到的后端服务不敢说 100%,至少也有 90% 以上是运行在 Linux 系统之上,因为它开源、便利、功能强大,需要学习以下技术点:
所以如果你想走后端开发这条路线,我建议你趁早使用 Linux ,越早越好。可以是在个人 PC 上装 Linux 虚拟机,或者装个双系统,我在大学就是这么玩的,那时候云服务器还没现在这么普及,现在我觉得买个 Linux 云服务器最方便,如果是学生还有教育优惠也不贵。
有了Linux系统之后干嘛呢?把它作为你的常用系统,经常登录进去对照着「鸟哥的 Linux 私房菜」从头到尾操作一遍,ok,Linux的基础操作你就掌握了。
Linux「高级编程」的意思是比上面的 Linux 基础操作更深入一个层次。
学会了 Linux 的使用还不算是一个真正的开发人员,使用系统是成为开发者最基本要求,会操作Linux 就像使用 Windows 系统一样,只不过是学习成本的问题,如果这个世界没有 Window 系统,你女朋友花点时间也能掌握 Linux 系统基本操作。
要想进阶成为后端开发人员,就要懂得如何使用 Linux 系统提供的各种系统API(系统调用接口)进行编程开发,程序员用你写的代码来控制系统,普通用户只会用鼠标操纵。这个阶段需要学习:
Unix 系统实现 Linux、基本系统数据类型
文件操作函数: open
、read
close
write
dup
fcntl
ioctl
stat
chmod
access
chdir
…
系统编程接口的基本特性和高级特性
Linux进程环境、如何创建进程、线程,程序的存储空间分配、环境变量
进程组、会话以及任务控制、进程优先级和调度
动态库和静态库
进程间通信:管道和FIFO、消息队列、信号量、共享内存、内存映射
套接字和网络编程
总之,这一阶段需要学习的是在 Linux 环境下的高级编程技巧,通过对这些内容的学习也能让你更深入的理解 Linux 系统是如何工作和运行的,并且真正的踏入 Linux 系统编程大门。
网络编程是通过网络套接字 socket 方式实现的通信,所以也属于进程间通信 IPC(Inter-Process Communication)。
由于现在的后台服务基于服务端/客户端模型,两者之间基于网络通信,你在家用手机点个外卖的服务请求,也是通过网络通信发给某团的后台服务器,所以后台服务开发,说到底还是网络编程,以及建立在网络编程数据之上的应用层开发。
网络编程学什么:
学完以上内容你大概可以写一个类似QQ一样的网络聊天小工具。
不在在工作中,都有成熟的网络框架或网络通信库,大公司比如鹅厂大部分是自研网络通信框架,小公司用开源项目,这让很多后台开发人员不必关心底层的网络通信细节,除了部分基础架构的开发同学,大部分后台开发同学工作都是在做业务系统的开发。
但了解底层网络编程原理,是后台开发人员的核心能力,这点对于 C/C++ 后台开发程序员尤为重要。它能拔高你看问题的高度,不了解底层原理,就像是在黑盒编程一样,出了问题无从下手排查。
学完了以上内容,基本是具备了从事后台开发的基础能力,也能开发出一个简单的后台服务器了。
除非是单纯的转发路由类后台服务,一般来说后台开发的web服务器后台程序,后台服务程序说白了就是个死循环:
接收客户端数据包 -> 处理数据包 -> 业务逻辑处理 -> 保存必要的数据 -> 回复响应数据给客户端
这其中会伴随对各种数据的处理,比如电商系统会处理订单数据、用户数据,游戏后台会处理角色数据和装备数据等等,有数据就会涉及到存储系统,数据一般都存储到数据库。
主要学习 2 大类数据库:
关系型数据库是指采用了关系模型来组织数据的数据库,简单理解就是二维表格模型。
非关系型数据库一般指的是 key-value
形式存储数据的 NoSQL 数据库,数据和键值是简单的映射关系。
后台开发服务还需要学会解决三高问题:高并发、高可用、高性能。
利用到目前为止学习的内容,我们的开发的后台服务器应付一些小并发场景绰绰有余,但是随着互联网应用业务量的上涨,对后台服务端的请求数剧增,高并发需求随之而来,高并发指的就是高 TPS 和高 QPS
对于高并发服务必须改变传统的单进程模型,才能处理的过来如此海量的请求。
对于高并发的服务请求,由于后台服务一般都是 IO 密集型应用,IO 密集型应用就是大部分 CPU 时间用在网络 IO 上,相对的是 CPU 密集型应用大部分时间花在数据计算上。
大多数的后台服务程序都是 IO 密集型的应用,网络 IO 的时候 CPU 等待白白浪费时间, 这就告诉我们 CPU 的潜力还没有完全发挥,所以当一个进程的处理能力达到上限,我们可以多创建几个进程,这就是多进程模型。
多线程与多进程类似,实际在Linux系统中线程是由轻量级的进程 LWP(Light-weight process)实现,多线程方式实现的后台服务相对于多进程更加轻量,因为多线程是在同一个进程内部实现。
不过多线程也会带来新的问题,比如全局数据竞争和同步问题,引入线程锁还要防止死锁的发生。
那什么是协程呢?协程 Coroutines
是一种比线程更加轻量级的微线程。类比一个进程可以拥有多个线程,一个线程也可以拥有多个协程,因此协程又称微线程和纤程。可以粗略的把协程理解成子程序调用,每个子程序都可以在一个单独的协程内执行。
所谓异步回调就是,服务端发起 IO 请求的线程不等网络 IO 线程操作完成,就继续执行随后的代码,一般请求线程需要先注册一个回调函数,当IO 完成之后网络IO线程通过调用之前注册的回调函数来通知发起 IO 请求的线程,这样发起请求的线程就不会阻塞住等待结果,提高了服务处理性能。
关于这一小节内容可参考柠檬哥之前的文章 图解:高并发服务框架-进程线程协程
按以上服务模型可以提高服务本身处理能力,高性能后台服务往往还会利用多种技术、从多个维度优化提高性能。比如采用CDN(Content Delivery Network)内容分发网络,存储和分发使用户就近获取内容,缩短响应时间;采用池化技术,避免频繁的资源分配与回收;采用服务集群,横向扩展服务能力;采用缓存技术,热点数据加入缓存,减少数据库访问。
高可用即保证服务的稳定性,不出现重大问题或宕机,常见的解决高可用思路是冗余和负载均衡。冗余的意思就是多部署几台服务器,当其中一台挂掉另外一台能顶上。通过负载均衡技术实现对流量的动态调配,不至于出现大量流量冲击某台机器出现请求不均匀,软件负载均衡技术可以通过DNS、Nginx、LVS等技术实现。这里主要学习的技术有:
设计模式代表着软件开发的一种最佳实践。已经经历了很长一段时间的发展,它们提供了软件开发过程中面临的一般问题的最佳解决方案。学习这些模式有助于经验不足的开发人员通过一种简单快捷的方式来学习软件设计,当设计大规模软件时遵循必要的设计模式能让写出的代码更加健壮和可扩展。
设计模式 6 大原则:
常见设计模式分类
为什么会出现分布式?随着业务的体量不断增长,单个节点的处理能力无法满足日益增长的计算、存储任务的时候,且硬件的提升(加内存、加磁盘、使用更好的CPU)高昂到得不偿失的时候,应用程序也不能进一步优化的时候,我们才需要考虑分布式系统。
分布式系统是由一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统。分布式系统的出现是为了用廉价的、普通的机器完成单个计算机无法完成的计算、存储任务。其目的是利用更多的机器,处理更多的数据。
分布式系统要解决的问题本身就是和单机系统一样的,而由于分布式系统多节点、通过网络通信的拓扑结构,会引入很多单机系统没有的问题,为了解决这些问题又会引入更多的机制、协议。这里需要学习的内容包括:
本质上后台服务在网络上运行,需要和各种网络环境交互,在正常情况下能够工作,但互联网中有很多针对后台服务的恶意攻击,因此网络安全也是后台开发工程师需要学习的内容。这里主要包括:
后台服务运行我们如何了解其运行状态和健康度?如果只是开发小玩具监控和统计大可不必,只需记录本地日志即可,对于成熟的大型后台服务系统,监控、统计、追踪必不可少,无监控,不运营。
开源的监控软件有:Prometheus、Zabbix、Open-Falcon。
追踪系统也非常重要,特别是目前微服务化,一次服务请求需要经历多个不同的微服务处理,给分布式追踪带来新的挑战,主要包含以下三个方面:
业界也有一些成熟的开源软件用于监控与追踪:SkyWalking、Pinpoint、Zipkin、CAT大众点评开源。不过大公司一般都有自研的一套监控与追踪系统,比如腾讯内部就有多套自研监控与调用链追踪系统。
我们讨论的是全文搜索引擎,什么是全文搜索引擎?
全文搜索引擎是目前广泛应用的主流搜索引擎。它的工作原理是计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。
数据分为结构化数据与非结构化数据
像数据库表这种的数据是结构化数据;而对于像HTML、XML、文档这样不定长度且无固定格式的数据我们称之为非结构化数据。非结构化数据也称为全文数据,对非结构化数据的搜索可以用全文检索的方式,
目前两大主流的全文搜索引擎「Solr」和「Elasticsearch」都是基于 Lucene 建立。搜索引擎需要学习的内容:
搜索引擎原理,搜索引擎利用倒排索引技术来实现对全文数据的高效检索。
Lucene,Apache Lucene 是一个开源的全文搜索引擎工具包。
Elasticsearch 原理与使用
Solr 原理与使用
大数据,又称为巨量资料,指的是在传统数据处理应用软件不足以处理的大或复杂的数据集的术语。随着后台服务用户数增加和数据的积累,产生海量有待挖掘价值的数据,分析利用这些数据可以反馈线上决策,优化运营策略,产生数据价值。
海量数据也可以定义为来自各种来源的大量非结构化或结构化数据。
在软件开发领域的大数据概念自 20 世纪 90 年代的数据仓库开始,对于大数据的处理也导致各种海量数据的统计和处理技术发展。
主要包含以下的技术点需要学习:数据存储、离线分析、流式计算。
虚拟化,是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机。
常见的虚拟化技术:KVM、Xen、OpenVZ、Docker
虽然对于大多数后台服务程序来说, 很多服务都是部署在 Docker 容器里,但 Docker 共用了底层系统的 kernel,所有容器共用一部分的运行库,因此隔离性相比 KVM 之类的虚拟化技术差一点,KVM 与 Docker 有各自的使用场景,未来很长一段时间是共存状态。
OpenStack 管理 VM(Virtual Machine)虚拟机的工具;Kubernetes 简称 K8s ,是管理 container 容器的工具。
在后端开发中你可能经常听说到「中间件」这个词,那什么是中间件?看下Wiki上的定义:
中间件技术创建在对应用软件部分常用功能的抽象上,将常用且重要的过程调用、分布式组件、消息队列、事务、安全、链接器、商业流程、网络并发、HTTP 服务器、Web Service 等功能集于一身或者分别在不同品牌的不同产品中分别完成。
中国科学院软件所研究员仲萃豪把中间件定义为「平台+通信」。这个定义限定了只有用于分布式系统中的此类软件才能被称为中间件,同时此定义也把中间件与实际应用的应用软件区分开来。
大白话来说,中间件就是把分布式系统中一些通用功能的抽象出来提供服务的一类软件统称。它屏蔽掉了底层操作系统的复杂性,向上提供一个统一的开发环境,降低了软件系统开发的复杂度,由于中间件是介于操作系统和应用软件之间,为应用软件提供服务功能的软件,由于介于两种软件之间,所以称为中间件。
常见的的开源中间件有下面几种,组合起来就能搭建一个完整的分布式后台服务系统:
大型软件项目的代码量巨大,如何有效组织和管理源码和版本,于是产生了版本控制系统。版本控制系统就是我们常说的SVN 或 Git,用来追踪、维护源码、文件以及配置文件等等的改动,并且提供控制这些改动控制权的程序。
常见的版本控制系统分为两大类:集中式版本控制和分布式版本控制。作为后端开发工程师,版本控制系统的使用也是必须掌握的基础技能,不过这些系统一般都是边使用边熟悉,刚开始熟悉一些常用操作就好。
一些和后端开发或者说软件开发相关的工具推荐,主要是编辑器和 IDE。
在 Linux 下开发肯定离不开 Vim 或者 Emacs,这两个都是常用的编辑器,已经形成了两大爱好者阵营。特别是 Vim 编辑器,学习成本有点高,配合上各种插件和配置,有些 Vim 爱好者已经把它当成 IDE 来用了,一旦掌握可以大幅提升工作效率,值得你去学习。
当然除了 Vim 如果是文字编辑工作,比如写 README 文档或者写技术博客,那么强烈推荐学习下 Markdown 语法,这是一种种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,注重内容本身不用过多的调整排版。Markdown 编辑器推荐 Typora 、有道云笔记 Markdown 编辑器、VSCode Markdown插件。
编辑器作为小工程还可以胜任,不过后端开发工作中,一般都是大型的软件工程项目,所以不大可能用编辑器来管理,这时候就需要学习使用专业的集成开发工具。
集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面等工具。
磨刀不误砍柴工,挑一把趁手的兵器再去编程世界遨游。各语言 IDE 五花八门,推荐 JetBrains 系列和 VS Code ,JetBrains 产品包括各语言开发的一系列的 IDE,特别是Java 的Intellij IDEA 口碑非常不错,部分对应的产品系列如下。
Visual Studio Code(简称VS Code)是一个由微软开发,同时支持Windows 、 Linux和macOS等操作系统的免费代码编辑器,它支持测试,并内置了Git 版本控制功能,同时也具有开发环境功能,例如代码补全(类似于 IntelliSense)、代码片段和代码重构等。该编辑器支持用户个性化配置,例如改变主题颜色、键盘快捷方式等各种属性和参数,同时还在编辑器中内置了扩展程序管理的功能。
在2019年的 Stack Overflow 组织的开发者调研中,VS Code被认为是最受开发者欢迎的开发环境。
软件工程师不仅要写代码,还要做测试,软件测试和软件开发是相伴相生,测试能让保证我们写出代码更加健壮和可维护。
TDD是测试驱动开发(Test-Driven Development)的英文简称,是敏捷开发中的一项核心实践和技术,也是一种设计方法论。TDD的原理是在开发功能代码之前,先编写单元测试用例代码,根据测试代码确定需要编写什么产品代码。需要掌握和了解以下测试技术和方法。
总结下,后端技术学习的内容还是很多的,不可能一蹴而就。
这篇文章能看到这里的同学,如果是初学者,可能就想问直接问我从哪里开始学习?那我就不卖关子,如果你不知道从哪开始学,对于学习路线各个节点,我就按个人的学习经验并结合认识的大厂高 P 给的建议,给你把以上技术路线学习优先级做个排序,你照着学就行,排序规则:
星级越高,排名越靠前,重要程度越高,优先安排时间学习。
计算机基础 5星
Linux 5 星
数据库 5 星
设计模式 5 星
工具 5 星
中间件 4 星
分布式 4 星
高并发、高可用、高性能 4 星
搜索引擎 4 星
测试 3 星
监控与统计 3 星
虚拟化 3 星
安全 3 星
大数据 3 星
细心的读者应该发现了,到目前为止本文讨论的后端技术学习路线内容,并没有提及特定编程语言,不提及并不是说不重要,语言是很多技术的前置知识。打个比方来说,编程语言是砖瓦,高大上的项目都是一砖一瓦堆砌而成。
其实你在学习上述技术点的过程中,会自然而然的接触到各种编程语言的中间件或是开源项目,不管用什么语言做后端服务开发,都是没有问题的,并且都不有很多优秀的开源框架可以借鉴学习,关键是要有清晰的学习路线,主流的后端开发语言包括 Java、C++、PHP、Python、Go ,那学哪个呢?
如果你是在校的学生,时间充足,我建议可以都可以尝试下,不试过怎么知道不合适?然后结合自己偏爱和未来打算从事的岗位方向选择一门语言深入学习;
如果你是职场社畜,那就要适应团队,产品业务需要用什么语言开发那就学哪个。万变不离其宗,后端技术的知识都是相通的,不要被特定语言所束缚,这些通用的后端技术掌握后,剩下的就只是编程语言学习,很快啊,很快的。
这篇文章我从月初开始整理内容、绘制思维导图,真真是肝了半个月之久。创作过程中,我把自己从初级开发人员到现在高级工程师,这些年学习的技术都在脑子里过了一遍。
说来惭愧有些我画在导图上的技术我也只是懂点皮毛,但整个后端技术栈的学习路线和方向是没问题的,我都画出来了,大家参考着学习和查漏补缺,在技术上我也需要继续精进学习,咱们共勉。
学习路线和高清路线大图我会放在我的 Github 项目上,这篇文章只是个开始,也不是最终版,我会持续在 Github 更新和完善本文内容,我这个项目的地址是:
https://github.com/imcoderlemon/CodeClass
点击文末「阅读原文」链接直达 Github 项目主页,记得点个 star 这样我更新了内容你就能收到通知。
公众号后台回复「路线图」获取后端技术学习路线高清思维导图!
这篇文章没写之前我就预感会很长,写到这里已经 1 万多字了。
对于每个技术点还可以展开聊聊我是如何学习的,那样就太长了,柠檬哥作为一个普通大学、非计算机科班人员,通过自学后端技术,进入鹅厂做软件开发,我的后端技术学习经验或许能给你一点借鉴。
我可以给大家分享下细分技术领域的学习路线,比如计算机基础学习路线、数据库学习路线、分布式技术学习路线、高并发技术学习路线…如果大家想看的话就点 「在看」给我点动力,攒够 50 个在看,就再写写具体的学习路线。顺便做个调查你最想看柠檬哥分享哪方面的学习路线。
本文已收录于Github:https://github.com/imcoderlemon/CodeClass
内含原创干货文章,千本计算机电子书,3本LeetCode题解,各类编程资源
文章每周持续更新,我们下期见!