互联网行业因为广为人知的高薪以及相对于传统工科行业更多的发展机会,最近几年涌入了越来越多的非计算机专业毕业的从业人员,校招/社招面试的时候,候选人往往也会被分为两种:科班和非科班,互联网科班一般特指大学就读计算机科学与技术或者软件专业,非科班则包含其他各大传统工科甚至是文科专业。
所以了解计算机底层如何运作是非常有必要的,我们这里谈到的计算机底层知识,包括但不限于:
计算机组成:CPU运行的原理,内存、硬盘等各种硬件如何协调合作;
操作系统:支撑后端框架的系统,具体做了哪些操作;
编译原理:对于Java、C++这类高级语言,如何经过编译,转换为汇编语言以及二进制文件;
计算机网络:计算机与计算机之间如何进行通信。
面试官提问:你了解计算机网络的分层模型吗?其中每一层有哪些常见的协议?
题目解析:这个题目需要拆分为两个关键点分析:
(1)计算机网络是如何分层的?阐述OSI七层协议和通用五层协议的区别。(2)分层后的每一层支持哪些协议?主要会涉及到后端开发过程中常用的协议。
首先,我们都知道最基础的分层协议是计算机网络OSI(OpenSystemInterconnection)体系。OSI模型如上图(a)所示,网络结构被拆分为7层,自顶向下分别是应用层、表示层、会话层、传输层、网络层、数据链路层以及物理层。但是OSI模型是一种概念模型,虽然理论比较完整,并不实用。
作为OSI七层协议和TCP/IP四层协议的折中,还有一种是五层协议的体系,往往是面试中考察的重点。
五层协议,如上图中(b)所示,自顶向下分为应用层、传输层、网络层、数据链路层以及物理层,下面我们将详细阐述每层的作用以及代表协议。
在画出了计算机网络的分层模型之后,我们还需要向面试官解释每一层的定义以及介绍常见的协议。
应用层(ApplicationLayer)是5层协议的顶层,顾名思义,应用层的作用是通过操作系统中应用进程(例如电子邮件、浏览器文件传输)提供网络交互。
传输层(TransportLayer)主要是为了实现端口到端口(porttoport)的通信,计算机的不同进程都会被分配不同的端口,例如域名默认的80端口。从接收和发送信息的角度可以分为两大功能:
复用:把操作系统的多个进程利用一个传输层接口发送信息;
分用:把收到的信息利用传输层接口分发到操作系统的不同进程。
传输层涉及到两个常见的协议,几乎是面试必考协议:
传输控制协议(TCP,TransmissionControlProtocol):特点是面向连接,基于报文段传输,能够保证消息可靠交付的协议;
用户数据包协议(UDP,UserDatagramProtocol):特点是无连接,基于用户数据报传输,不保证消息可靠交付,只尽"最大努力交付"。
计算机之间的通信可以分为位于同一个子网络(也就是局域网,LocalAreaNetwork)和位于不同的子网络(广域网,WideAreaNetwork),网络层协议解决的问题就是如何判断两台计算机是否属于同一个子网络中。
网络层最常涉及的协议是IP协议,就是TCP/IP协议族中的IP网络协议,可见其重要性。
数据链路层将网络层交付的IP数据包封装成帧(Frame),其中每一帧包括了数据以及必要的控制信息(比如同步信息、寻址信息、差错控制信息),这种设计方案非常类似TCP协议中的控制位(由此也能看出计算机网络设计的互通性)。如果通过差错控制信息校验出了错误,那么就会在本层丢弃这个帧,纠正错误是通过网络层的TCP协议完成。
PPP协议(PointtoPointProtocol):在两个点之间传输数据包的协议,因为本层涉及的协议在面试中考察甚少,基本可以只做简单了解。
因为伴随着2010年之后移动互联网在全世界的高速发展,各种各样的浏览器(Chrome、FireFox、Safari等)层出不穷,也诞生了诸多服务端开发的语言(例如Golang语言),浏览器和服务端之间的交互是不可避免的,我们对于不同的浏览器和不同的服务端,总不能每次都创建一种新的交互协议,所以需要确定统一的协议规范,也就是本文的HTTP协议。
面试官提问:什么是HTTP报文?什么是HTTP报文?
题目解析:首先,我们给出HTTP的定义:HTTP(HyperTextTransferProtocol,超文本传输协议)是一个请求-响应(RequesttoResponse)协议,位于网络模型的应用层,基于传输层的TCP协议。
(HTTP请求-响应模型)
其次,HTTP报文是在客户端和服务器端传输的数据报文,由起始行(StartLine)、请求头部(RequestHeader)和请求主体(RequestBody)构成,从类型上分为请求报文(RequestMessage)和响应报文(ResponseMessage)。
面试官提问:HTTP协议的请求方法有哪些,有啥区别?
题目解析:
面试官常常会将POST和GET方法进行对比,我们需要注意以下几个不同:
(1)GET请求主要是为了从服务器获取资源,POST请求主要是为了向服务器发送资源。
(3)GET请求传输的信息量少,POST请求能够传输的信息量多。
(4)GET请求参数在URL明文,容易被爬虫直接获取,POST请求参数不直接可见,安全性更高,例如在表单提交密码时,必须使用POST请求。
面试官提问:请枚举一些常见的HTTP状态码,并且说明作用。
首先我们从性质上分类,HTTP的响应状态码总共有1XX到5XX五种类型,关于每种状态码的定义:
对于5XX开头的错误码,都是因为服务器处理过程中遇到异常产生,例如后端开发程序员在处理HTTP请求的过程触发了Exception,导致响应失败。
在定性之后,面试官大概率还要抽出几个常见的状态码,考察其具体的含义,我们对常见的状态码也需要进行总结:
这里需要分区开301和302错误码(也是常见考点),从字面意思上看,301和302都代表某个URL被转移了,区别在于:
(1)301表示资源被永久转移了,搜索引擎(例如百度的爬虫)在爬取网站的时候会抓取新网站的内容并且保留新网站的URL。
(2)302表示资源被临时转移了,也就是临时重定向,搜索引擎在爬取网站的时候会抓取新的内容,但是保留旧网站作为URL。
TCP和UDP协议是计算机网络的重要组成协议,两者经常被拿来比较,其中TCP协议往往会被面试官深入考察。
本节课程将和大家一起学习传输层的TCP和UDP协议。通过本节课程,你会了解到TCP和UDP协议的区别,重点是要掌握TCP协议的三次握手过程以及三次握手的必要性。
面试官提问:TCP协议和UDP协议有什么区别?有什么共同点?
相同点:两个协议最大的共同点是都位于TCP/IP网络模型的传输层。
不同点:我们通过表格的形式对比不同。
根据表格中的特点对比我们可以总结得到:
面试官提问:上述你提到了UDP和TCP报文,它们的具体结构是怎样的?
在上个题目中我们总结了TCP协议和UDP协议的不同点,其中谈到了TCP和UDP协议首部格式不同,接下来分别画图分析。
如上图可见,UDP首部只有8个字节的数据,包括源端口号、目标端口号、长度以及校验和。
源端口号:发送计算机的应用端口;
目标端口号:接收端计算机的接收端口,也是占用16位Bit;
长度:表示UDP报文首部以及携带数据的长度;
校验和:校验数据在传输过程中是否损坏。
在画完了示意图之后,关于TCP报文首部,我们需要解释的字段:
序号:对字节流编号,例如本次传输的序号是100,携带的数据长度是100字节,那么下次传输的序号就是200;
确认号:客户端A往服务器端B发送了一个报文,序号是100,携带的数据长度是100字节,那么B往A发送的报文中确认号就是200,表示期望收到的下一个报文的序号。
标志位CWR(CongestionWindowReduce):拥塞窗口减少标志;
标志位ECE(ECNEcho):ECE标志等于1时,通知接收方,表示接收方到这边的网络存在拥塞;
标志位URG(Urgent):本报文是否包含紧急数据,只有当URG=1时,"校验和"后面的"紧急指针"字段才有效;
标志位ACK(Acknowledgement):ACK=1则表示前面发送的确认号是否有效,TCP连接建立之后,ACK必须设置为1;
标志位PSH(Push):PSH设置为1则表示需要将收到的数据立即传输给上层应用,否则先放缓存;
标志位RST(Reset):RST设置为1则表示TCP连接出现异常,需要强制断开;
标志位SYN(Synchronize):SYN设置为1则表示希望建立连接;
标志位FIN(Finsish):FIN设置为1则表示数据已经发送完成,可以断开TCP连接。
面试官提问:TCP是如何建立连接的?分析下每个步骤传输了什么样的数据?
(TCP三次握手过程)
首先从行为上分析,TCP建立连接需要发送三次报文,也就是"三次握手"的过程。
我们定义发送报文的一方是客户端,接收报文的一方是服务器端。
首先服务器端处于监听(LISTEN)的状态,否则不会收到客户端发来的请求。
(1)第一次握手:客户端往服务器端发送一个请求建立连接报文,报文首部SYN标志位=1,给定一个初始的Seq序号x。之后客户端进入SYN_SEN(同步发送)状态;
(2)第二次握手:服务器端收到请求报文,如果同意建立连接,则向客户端发送确认报文。确认报文中SYN标志位=1,ACK标志位=1,同时给定一个Seq序号y,Ack确认号x+1,之后服务器端进入SYN_RCVD(同步已发送)状态;
(3)第三次握手:客户端收到来自服务器端的确认报文之后,还需要向服务器端发送确认报文,报文首部ACK标志位=1,Ack确认号为y+1,发送之后客户端进入ESTABLISHED(已建立连接)的状态。服务器端收到确认报文后,也会进入ESTABLISHED状态,在此之后,客户端和服务器端可以开始TCP通信了。
面试官提问:TCP建立连接为什么需要三次握手?可以只有两次握手吗?第三次握手有什么意义?
紧接上面一个问题,如果我们能够成功画出TCP三次握手的过程,以及分析每个过程传输报文的首部内容,那么面试官大概率会抛出这样一个问题,考察我们对TCP三次握手的理解。
首先从定性角度来看,分析三次握手每个步骤的意义:
(1)第一次握手:客户端发送报文,服务器端接收报文,如果成功接收,说明客户端的发送能力、服务器端的接收能力符合预期;
(2)第二次握手:服务器端发送报文,客户端接收报文,如果成功接收。从客户端的角度来看:客户端的发送和接收能力符合预期,服务器端的发送和接收能力符合预期,可以建立连接。但是从服务器端的角度来看:客户端的发送能力符合预期(第一次握手),服务器端的接收能力符合预期(第二次握手),但是因为收不到客户端的反馈(无法获知第二次握手的报文是否成功抵达客户端),那么只能得出服务器端的发送能力和客户端的接收能力不一定符合预期的结论;
(3)第三次握手:客户端发送报文,服务器端接收报文,如果接收成功,从服务器端的角度来看:客户端的报文接收能力以及服务器端的报文发送能力都符合预期。
经过三次握手的过程,客户端和服务器端都明确对方以及自己能成功接收和发送信息,所以就可以开始正常通信。
《计算机网络》一书中对此进行了解释,三次握手的目的是"为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误"。
本章节给大家介绍了TCP和UDP协议的报文格式以及区别,分析了TCP建立连接的握手过程,需要大家能够准确画出TCP握手每个过程的标志位以及序号、确认号,并且从原理上理解三次握手的必要性,下一章节会继续给大家分析TCP四次挥手过程。
上一章节分析了TCP建立连接的过程,既然有建立连接,对应的也有断开连接。数据传输完成之后,客户端和服务器端保持通信状态会占用资源开销,所以需要断开连接,TCP协议中断开连接也被称为TCP四次挥手。
面试官提问:说明一下TCP断开连接的过程,涉及到了几个步骤?
(TCP四次挥手过程)
首先从行为上分析,TCP断开连接总共需要发送四次报文,也就是"四次挥手"的过程。
上一章节中已经对三次握手过程做出了分析,在建立连接后到传输数据的整个过程,客户端和服务器端均处于ESTABLISHED(监听)状态,之后四次挥手的过程如下:(1)第一次挥手:客户端发送一个请求结束报文,其中FIN标志位设置为1,报文中给定一个序列号u,报文内容是FINbit=1seq=u,发送之后主动进入FIN_WAIT状态,等待服务器端的确认报文;
(2)第二次挥手:服务器端收到FIN报文,会发送ACK确认报文,并且把客户端发送的序列号加一作为确认报文的确认号,表示已经收到了客户端的报文,所以报文内容是ACKbit=1seq=vack=u+1,之后进入CLOSE_WAIT(关闭等待)状态。此时会通知应用层的进程,客户端已经不会再发送数据了。此时连接处于半关闭状态,如果服务器端发送数据,客户端还是需要接收。
客户端收到第二次挥手的报文后,会进入FIN_WAIT_2(等待结束)状态,等待服务器发送最后的终止连接报文;
(3)第三次挥手:服务器端把最后的数据发送之后,就开始向客户端发送请求结束报文,FIN标志位设置为1,确认号设置为u+1,比较特殊的一点是报文中ACK标志位也是1,报文内容是FINbit=1ACKbit=1seq=wack=u+1,发送之后服务器端进入LAST_ACK(最终确认)状态,等待客户端的确认报文。
服务器端在收到客户端的第四次挥手报文后,立即进入CLOSED(关闭)状态,表示结束本次TCP连接。
在向面试官分析整个流程的时候,我们可以将四次报文中的第一次和第二次看作一个整体,即是客户端发送请求结束报文以及收到对应响应。第三次和第四次又是一个整体,即服务器端发送请求结束报文并且收到客户端的响应。
面试官提问:为什么TCP建立连接只需要三次握手,而TCP断开连接需要四次握手?
关于TCP建立连接三次握手的必要性,我们已经在上一章节进行了分析,这里不再赘述,这里分析下四次握手的必要性。
前置说明:TCP是双向通信的协议,客户端可以发送和接收数据,服务器端也可以发送和接收数据,也就是全双工通信模式。
第一次挥手时,服务器端收到了客户端的FIN请求结束报文,但是因为应用层的进程可能还需要传输一些数据,不能立即关闭SOCKET,所以只能先给客户端发送一个ACK确认报文,让客户端有"心理准备"。之后服务器端进入CLOSE_WAIT状态,这个状态是为了处理最后的一些数据,等待这些数据也传输完毕之后,服务器端再发送FIN请求结束报文,到这里就已经有三次挥手的步骤了。最后,因为服务器端也需要感知第三次挥手的报文是否成功传输到客户端,所以客户端还需要第四次挥手的报文,来作为确认。
面试官提问:第四次挥手之后,客户端进入的TIME_WAIT状态是什么含义?有什么限制?
在候选人成功向面试官阐述了四次挥手的过程细节以及四次的必要性之后,面试官大概率会针对TIME_WAIT这个状态发出提问。
我们将这个问题拆解开来,分步分析:
①防止丢失报文导致异常:客户端发送的最后一个ACK报文可能丢失,服务器端收不到响应则会发送第三次挥手的超时重传报文,我们假设客户端没有TIME_WAIT状态,而是直接进入CLOSED状态,则会收到非法的报文段,返回一个RST(拒绝连接)的报文,产生异常。
**面试官提问:**为什么有了HTTP协议后还出现了HTTPS协议?HTTPS协议解决了什么问题?
在研究HTTPS协议之前,我们先总结下HTTP协议的优点和缺点:
如上表所示,HTTP协议牺牲了安全性,换来了效率,但是在某些安全性要求高的场景,使用HTTP协议是不合适的。
HTTP协议的全称是HypertextTransferProtocol,HTTPS协议的全程是HypertextTransferProtocolSecure,多了一个Secure(安全)的限制词。从协议上看,HTTPS协议基于HTTP协议,使用SSL/TLS协议对传输内容进行加密,从公式上定义:HTTP+SSL(TLS)=HTTPS。
HTTPS协议将HTTP协议的通信部分由SSL或者TLS协议替代,网络模型划分如下:
除了SSL协议以外,HTTPS协议还涉及几个重要的概念:CA证书、混淆加密方式,以及HTTPS协议具体的工作流程,下面我们拆分解释。
**面试官提问:**既然HTTPS协议对通信内容进行了加密,那么涉及到了什么加密算法?
HTTPS协议的核心是加密流程,首先我们需要区分三种加密方式:对称加密、非对称加密以及混淆加密。
(1)对称加密:加密方和解密方都使用了相同的密钥,只要保证密钥不会泄露给第三方,整个通信过程就是安全的。
因为对称加密算法整个过程共享同一个密钥,所以使用特点也比较明显。
优点:算法简单,加密速度快;
缺点:安全性低,如果密钥泄露,密文也被中间人拦截,那么信息很容易就会被破解。
在企业生产环境下,常用的对称加密算法有AES算法。
(2)非对称加密:在安全性要求更高的场景下,我们需要使用非对称加密,关于非对称加密算法的流程如下:
首先定义两种密钥:一种是公钥(PublicKey),给任何需要和接收方通信的客户端保存;另一种是私钥(PrivateKey),只给接收方自己保存。
对于要发送的原文文本,发送方通过接收方的公钥对内容加密,加密后的内容只有接收方的私钥可以解密。在整个传输过程中,如果发送方的公钥泄露,加密内容也被窃取,也不会导致传输内容被破解(只要接收方的私钥没有泄露)。
常见的非对称加密算法有RSA算法(即一种支持变长密钥的公共密钥算法)。
另外,面试官可能会提出MD5算法的划分,MD5是非常常见的加密算法,例如在保存用户密码时经常被使用。但是要区分的是,MD5算法不是对称和非对称算法,MD5算法不可逆,主要目的是为了文件校验(例如判断文件是否在传输过程中损坏),或者数字签名等途径。
本小节主要给大家简单说明了HTTPS协议和传统HTTP协议的区别,另外给出了对称加密和非对称加密算法的流程,我们需要掌握不同加密算法的特点,在下一章节中会给大家介绍HTTPS协议的具体流程。
面试官提问:HTTPS的请求流程和HTTP协议的请求流程有什么区别?
参考HTTPS的官方文档,我们将整个请求的流程简单抽象为以下几个步骤,抓住其中的核心步骤:
题目解析:输入URL之后,浏览器做的第一件事情就是DNS域名解析。
所以第一个步骤,我们需要获取域名对应的IP地址,会经过以下几个步骤:
(1)访问Hosts文件浏览器会首先查看本机的Hosts文件,是否已经存在映射关系。Hosts文件是用来存储常用的域名和对应IP地址关系的关联文件,例如在Hosts文件中存储了"www.imooc.com"->"204.1.17.89",那么我们不需要访问DNS服务器即可获取百度域名对应的IP地址。
(2)访问本地缓存如果Hosts文件中不存在映射关系,浏览器(例如Chrome)会再查看浏览器本地的缓存,是否存在映射关系。
(3)访问DNS服务器
DNS解析的过程简单来看,是从"我的电脑"传输域名"www."到DNS服务器,解析生成IP后返回给"我的电脑"。但是面试官一般会接着询问DNS解析的详细过程,依次考察候选人的知识深度。
步骤(1):浏览器会向本地DNS服务器发送域名报文。
步骤(2):本地DNS接收报文之后,会将请求转发到根DNS服务器。
步骤(3):根DNS服务器通过".com"后缀返回com顶级域名服务器的IP地址205.0.1.2。
步骤(4):本地DNS服务器带着域名访问IP:205.0.1.2顶级域名服务器。
步骤(5):com顶级域名服务器根据后缀"imooc.com",返回IP地址206.0.1.3。
步骤(6):本地DNS服务器带着域名访问IP206.0.1.3二级域名服务器。
步骤(7):二级域名服务器通过www.imooc.com查询到了域名对应的实际IP地址210.1.17.89,返回给本地DNS服务器。
步骤(8):本地DNS服务器透传IP210.1.17.89返回给"我的电脑"。
在经过DNS解析之后,浏览器已经获取了对应网站的IP地址,通过三次握手连接到网站服务器,这个步骤中,我们可以给面试官画出简化后的三次握手过程:
TCP三次握手
(1)客户端发送一个带有SYN标记位的数据包(syn=J)到服务器,然后进入SYN_SENT状态;
(2)服务器收到SYN包,需要确认客户端的SYN(赋值ack=J+1),然后自己也发送一个SYN包(syn=K),服务器进入SYN_RCVD状态;
(3)客户端收到服务器的SYN+ACK包,向服务器端发送确认包,即ack=K+1,发送完成之后,两边都进入ESTABLISHED建立连接状态。
TCP三次握手之后,客户端和服务器端成功建立了连接,之后浏览器会向服务器特定端口发送HTTP请求。
以Chrome浏览器为例,按下F12即可进入开发者模式,Network一栏查看HTTP请求的具体报文。
一个HTTP报文由请求行(RequestLine)、请求头部(RequestHeaders)、空行(BlankLine)以及请求体(RequestBody)构成,请求行中规定了请求方法、URI以及HTTP的版本,关于每个字段的详细解释,之前的小节已经进行了阐述。
当一个HTTP请求打进服务器之后,一般的流程是:网关层(例如Ngnix)最先获取请求,然后路由转发到具体的Web服务,经过一段业务逻辑之后,可能还会查询数据库,最后将处理的结果返回给浏览器客户端。
对于后端开发程序员来说,日常的工作就集中在服务器端,特别是流程图中的"Web业务服务"这块,例如基于Spring框架、Django框架或者ThinkPHP框架进行业务逻辑开发和上线。
(HTTP请求进入服务器端后的解析流程图)
服务器端处理业务结果之后,也要返回HTTP响应,HTTP响应由状态行(StatusLine)、响应头部(ResponseHeaders)、空行(BlankLine)以及响应体(ResponseBody)构成,关于每个部分的细节也不再赘述。需要特别注意的是,响应体中的各种错误码定义:
当浏览器获取了域名对应的页面信息,为了避免服务器和客户端双方的资源损耗,客户端会请求断开TCP连接,和三次握手的过程相似,TCP四次挥手的过程可以总结为:
(1)第一次请求:客户端请求断开FIN,携带信息seq=u;
(2)第二次请求:服务器确认客户端的断开请求ACK,携带信息ack=u+1,seq=v;
(3)第三次请求:服务器请求断开FIN,携带信息seq=w,ACK,ack=u+1;
(4)第四次请求:客户端确认服务器的断开ACK,携带信息ack=w+1,seq=u+1。
服务器返回给客户端的是HTML以及CSS、Javascript代码,要展示为静态页面,还需要经过浏览器的解析行为。
浏览器内核引擎解析HTML文档并且将标签转换为DOM(DocumentObjectModel,文档对象模型)树的DOM节点,不同浏览器的渲染解析流程大同小异。
同时,浏览器内核引擎还会解析CSS生成CSS规则树,按照从右到左的顺序读取选择器。
另外,在浏览器中还有个"JS脚本解析器",解析HTML和CSS是多线程同时执行的,CSS解析失败不会影响HTML内容的解析,但是如果JS脚本解析过程中触发了异常,会直接终止HTML内容的解析。关于更详细的解析动作,作为后端开发,我们不需要了解太多,这块也不会作为面试考察的内容。
本节中和大家讲解了"我们在浏览器中输入一个URL,具体发生了什么",整个过程中分析了应用层(HTTP、DNS)、传输层(TCP)、网络层(IP)等网络分层的各个协议的作用,也对服务器解析HTTP的基本流程进行了阐述,本小节需要大家掌握访问URL时每个步骤的基本功能,能够通过对调用链路的分析,向面试官展示自己的计算机网络功底。