阅读 253

HTTP面试题整理(附答案,持续更新)

这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

计算机网络的面试题已在程序员面试中屡见不鲜,这里面的概念纷繁复杂,而且平时工作中很少用到,看了后很容易忘。

于是,我针对计算机网络面试题做了一系列的整理,我参考了大量网络上的资源以及经典参考书,争取能把具体的面试题目给讲明白讲透彻,强调理解记忆,拒绝八股文!!。这一篇内容,既是自我的学习总结,也希望能帮助到正在复习面试的朋友。

本系列文章一共分为两篇,TCP篇HTTP篇

HTTP篇

在浏览器中输入url地址到显示页面的过程(重点)

总体来说分为以下几个过程:

  • DNS解析
  • TCP连接
  • 发送HTTP请求
  • 服务器处理请求并返回HTTP报文
  • 浏览器解析渲染页面
  • 连接结束

文章可以参考:segmentfault.com/a/119000000…

如果是Django应用可以回答:

DNS查询——TCP握手——HTTP请求——反向代理Nginx——uwsgi/gunicorn——web app响应——TCP挥手

HTTPS和HTTP有什么区别(重点)

  • 端口 :HTTP的URL由http://起始且默认使用端口80,而HTTPS的URL由https://起始且默认使用端口443。
  • 安全性和资源消耗: HTTP协议运行在TCP之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。HTTPS是运行在SSL/TLS之上的HTTP协议,SSL/TLS 运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。所以说,HTTP 安全性没有 HTTPS高,但是 HTTPS 比HTTP耗费更多服务器资源。
    • 对称加密:密钥只有一个,加密解密为同一个密码,且加解密速度快,典型的对称加密算法有DES、AES等;
    • 非对称加密:密钥成对出现(且根据公钥无法推知私钥,根据私钥也无法推知公钥),加密解密使用不同密钥(公钥加密需要私钥解密,私钥加密需要公钥解密),相对对称加密速度较慢,典型的非对称加密算法有RSA、DSA等。

HTTPS怎么建立连接的(重点)

  • 浏览器将支持的加密算法信息发送给服务器
  • 服务器选择一套浏览器支持的加密算法,以证书的形式回发浏览器
  • 浏览器验证证书合法性,并结合证书公钥加密信息发送给服务器
  • 服务器使用私钥解密信息,验证哈希,加密响应消息回发浏览器
  • 浏览器解密响应消息,并对消息进行验真,之后进行加密交互数据

更详细的步骤如下:

HTTPS 在 HTTP 与 TCP 层之间加⼊了 TLS 协议。

HTTPS 是应⽤层协议,需要先完成 TCP 连接建⽴,然后⾛ TLS 握⼿过程后,才能建⽴通信安全的连接。

事实上,不同的密钥交换算法,TLS 的握⼿过程可能会有⼀些区别。

这⾥先简单介绍下密钥交换算法,因为考虑到性能的问题,所以双⽅在加密应⽤信息时使⽤的是对称加密密钥,⽽对称加密密钥是不能被泄漏的,为了保证对称加密密钥的安全性,所以使⽤⾮对称加密的⽅式来保护对称加密密钥的协商,这个⼯作就是密钥交换算法负责的。

TLS第一次握手

  • 客户端⾸先会发⼀个「Client Hello」消息。
  • 消息⾥⾯有客户端使⽤的 TLS 版本号、⽀持的密码套件列表,以及⽣成的随机数(Client Random),这个随机数会被服务端保留,它是⽣成对称加密密钥的材料之⼀。

TLS第二次握手

  • 当服务端收到客户端的「Client Hello」消息后,会确认 TLS 版本号是否⽀持,和从密码套件列表中选择⼀个密码套件,以及⽣成随机数(Server Random)。
  • 接着,返回「Server Hello」消息,消息⾥⾯有服务器确认的 TLS 版本号,也给出了随机数(Server Random),然后从客户端的密码套件列表选择了⼀个合适的密码套件。其实这两个随机数是后续作为⽣成「会话密钥」的条件,所谓的会话密钥就是数据传输时,所使⽤的对称加密密钥。
  • 然后,服务端为了证明⾃⼰的身份,会发送「Server Certificate」给客户端,这个消息⾥含有数字证书。
  • 随后,服务端发了「Server Hello Done」消息,⽬的是告诉客户端,我已经把该给你的东⻄都给你了,本次打招呼完毕。

TLS 第三次握⼿

  • 客户端验证完证书后,认为可信则继续往下⾛。接着,客户端就会⽣成⼀个新的随机数 (pre-master),⽤服务器的 RSA 公钥加密该随机数,通过「Change Cipher Key Exchange」消息传给服务端。
  • 服务端收到后,⽤ RSA 私钥解密,得到客户端发来的随机数 (pre-master)。
  • ⾄此,客户端和服务端双⽅都共享了三个随机数,分别是 Client Random、Server Random、pre-master。
  • 于是,双⽅根据已经得到的三个随机数,⽣成会话密钥(Master Secret),它是对称密钥,⽤于对后续的 HTTP请求/响应的数据加解密。
  • ⽣成完会话密钥后,然后客户端发⼀个「Change Cipher Spec」,告诉服务端开始使⽤加密⽅式发送消息。
  • 然后,客户端再发⼀个「Encrypted Handshake Message(Finishd)」消息,把之前所有发送的数据做个摘要,再⽤会话密钥(master secret)加密⼀下,让服务器做个验证,验证加密通信是否可⽤和之前握⼿信息是否有被中途篡改过。
  • 可以发现,「Change Cipher Spec」之前传输的 TLS 握⼿数据都是明⽂,之后都是对称密钥加密的密⽂

TLS 第四次握⼿

  • 服务器也是同样的操作,发「Change Cipher Spec」和「Encrypted Handshake Message」消息,如果双⽅都验证加密和解密没问题,那么握⼿正式完成。
  • 最后,就⽤「会话密钥」加解密 HTTP 请求和响应了。

常见状态码(重点)

HTTP 状态码共有 5 种类型:

分类分类描述
1XX指示信息--表示请求正在处理
2XX成功--表示请求已被成功处理完毕
3XX重定向--要完成的请求需要进行附加操作
4XX客户端错误--请求有语法错误或者请求无法实现,服务器无法处理请求
5XX服务器端错误--服务器处理请求出现错误

相应的 HTTP 状态码列表:

  • 100:Continue 继续。客户端继续处理请求
  • 101:Switching Protocol 切换协议。服务器根据客户端的请求切换到更高级的协议
  • 200 OK 请求成功。请求所希望的响应头或数据体将随此响应返回
  • 201 Created 请求以实现。并且有一个新的资源已经依据需求而建立
  • 202 Accepted 请求已接受。已经接受请求,但还未处理完成
  • 300 Multiple Choices 多种选择。被请求的资源有一系列可供选择的回馈信息,用户或浏览器能够自行选择一个首选地址进行重定向
  • 301 Moved Permanently 永久移动。请求的资源已被永久地移动到新 URI,返回信息会包含新的 URI,浏览器会自动定向到新 URI
  • 302 Found 临时移动。与 301 类似。但资源只是临时被移动,客户端应继续使用原有URI
  • 303 See Other 查看其它地址。与301类似。使用GET和POST请求查看
  • 304 Not Modified 未修改。如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码
  • 400 Bad Request 客户端请求的语法错误,服务器无法理解;请求的参数有误
  • 401 Unauthorized 当前请求需要用户验证
  • 402 Payment Required 该状态码是为了将来可能的需求而预留的
  • 403 Forbidden 服务器已经理解请求,但是拒绝执行它
  • 404 Not Found 请求失败,请求所希望得到的资源未被在服务器上发现
  • 405 Method Not Allowed 客户端请求中的方法被禁止
  • 406 Not Acceptable 请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体
  • 500 Internal Server 服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理
  • 501 Not Implemented 服务器不支持当前请求所需要的某个功能
  • 502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到无效的响应
  • 503 Service Unavailable 由于临时的服务器维护或者过载,服务器当前无法处理请求,一段时间后可能恢复正常
  • 504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
  • 505 HTTP Version not supported 服务器不支持,或者拒绝支持在请求中使用的 HTTP 版本

状态码301和302的区别?

  • 301:永久移动。请求的资源已被永久的移动到新的URI,旧的地址已经被永久的删除了。返回信息会包括新的URI,浏览器会自动定向到新的URI。今后新的请求都应使用新的URI代替。
  • 302:临时移动。与301类似,客户端拿到服务端的响应消息后会跳转到一个新的 URL 地址。但资源只是临时被移动,旧的地址还在,客户端应继续使用原有URI。

HTTP2.0是什么

  • 二进制传输(增加传输效率,减少带宽占用)
  • 多路复用内容数据,(包1-4 HTML 包5-8 CSS html数据 css数据)
  • 服务端推送(访问html,服务端push css js)

HTTP长连接和短连接,应用场景

在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。

而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:

Connection:keep-alive

在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。

HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。

如何区分不同的HTTP请求呢?Content-Length | Transfer-Encoding:chunked

文章参考:

HTTP/1.1 和 HTTP/1.0 的区别

  • 缓存处理:在 HTTP/1.0 中主要使用 header 里的 if-modified-Since, Expries 来做缓存判断的标准。而 HTTP/1.1 请求头中添加了更多与缓存相关的字段,从而支持更为灵活的缓存策略,例如 Entity-tag, If-Unmodified-Since, If-Match, If-None-Match 等可供选择的缓存头来控制缓存策略。
  • 节约带宽: 当客户端请求某个资源时,HTTP/1.0 默认将该资源相关的整个对象传送给请求方,但很多时候可能客户端并不需要对象的所有信息。而在 HTTP/1.1 的请求头中引入了 range 头域,它允许只请求部分资源,其使得开发者可以多线程请求某一资源,从而充分的利用带宽资源,实现高效并发。
  • 错误通知的管理:HTTP/1.1 在 1.0 的基础上新增了 24 个错误状态响应码,例如 414 表示客户端请求中所包含的 URL 地址太长,以至于服务器无法处理;410 表示所请求的资源已经被永久删除。
  • Host 请求头:早期 HTTP/1.0 中认为每台服务器都绑定一个唯一的 IP 地址并提供单一的服务,请求消息中的 URL 并没有传递主机名。而随着虚拟主机的出现,一台物理服务器上可以存在多个虚拟主机,并且它们共享同一个 IP 地址。为了支持虚拟主机,HTTP/1.1 中添加了 host 请求头,请求消息和响应消息中应声明这个字段,若请求消息中缺少该字段时服务端会响应一个 404 错误状态码。
  • 长连接:HTTP/1.0 默认浏览器和服务器之间保持短暂连接,浏览器的每次请求都需要与服务器建立一个 TCP 连接,服务器完成后立即断开 TCP 连接。HTTP/1.1 默认使用的是持久连接,其支持在同一个 TCP 请求中传送多个 HTTP 请求和响应。此之前的 HTTP 版本的默认连接都是使用非持久连接,如果想要在旧版本的 HTTP 协议上维持持久连接,则需要指定 Connection 的首部字段的值为 Keep-Alive。

HTTP/1.X 和 HTTP/2.0 的区别

  • 相比于 HTTP/1.X 的文本(字符串)传送, HTTP/2.0 采用二进制传送。客户端和服务器传输数据时把数据分成帧,帧组成了数据流,流具有流 ID 标识和优先级,通过优先级以及流依赖能够一定程度上解决关键请求被阻塞的问题。
  • HTTP/2.0 支持多路复用。因为流 ID 的存在, 通过同一个 HTTP 请求可以实现多个 HTTP 请求传输,客户端和服务器可以通过流 ID 来标识究竟是哪个流从而定位到是哪个 HTTP 请求。
  • HTTP/2.0 头部压缩。HTTP/2.0 通过 gzip 和 compress 压缩头部然后再发送,同时通信双方会维护一张头信息表,所有字段都记录在这张表中,在每次 HTTP 传输时只需要传头字段在表中的索引即可,大大减小了重传次数和数据量。
  • HTTP/2.0 支持服务器推送。 服务器在客户端未经请求许可的情况下,可预先向客户端推送需要的内容,客户端在退出服务时可通过发送复位相关的请求来取消服务端的推送。

cookie和session的区别

  • Cookie
    • 是由服务器发给客户端的特殊信息,以文本的形式存放在客户端
    • 客户端再次请求的时候,会把cookie回发
    • 服务器接收到后,会解析Cookie生成与客户端相对应的内容
  • Session的简介
    • 服务器端的机制,在服务器上保存的信息
    • 解析客户端请求并操作session id,按需保存状态信息
  • Session的实现方式
    • 使用Cookie来实现(JSESSIONID)
    • 使用URL回写来实现
  • Cookie和Session的区别
    • Cookie数据存放在客户的浏览器上,Session数据放在服务器上
    • Session相对于Cookie更安全
    • 若考虑减轻服务器负担,应当使用Cookie

GET请求和POST请求的区别

  • HTTP报文层面:GET将请求信息放在URL(有长度限制),POST放在报文体中
  • 数据库层面:GET符合幂等性和安全性,POST不符合
  • 其他层面:GET可以被缓存、被存储,而POST不行

参考资料

文章分类
后端
文章标签