天下无难试之 HTTP 协议面试刁难大全(上)

2018-03-22 11:50:36 +08:00
 codehole

小编是一个非典型面试官,对于 HTTP 协议的第一个问题,一般人会问常用的状态码有哪些。小编不这么问,小编的问题是 HTTP 的全称是什么,把英语给我说出来!

HTTP 的全称是什么?

超文本传输协议,HyperText Transfer Protocol,这几个单词可别发走音了。所谓的超文本就是带标记的文本,刚开始的时候是指 HTML。现在 HTTP 协议传输的东西可不只是 HTML 了,什么表单啊 JSON 啊 XML 啊文件啊都可以传输。

HTTP 常用的状态码有哪些?

大部分同学都知道 200、404、500、302 状态码。如果连 404 都不知道,是要被小编鄙视的。500 错误为什么这么常见呢,因为在开发的时候老是出 bug,一个大异常抛出来,浏览器就 500 了。500 表示 InternalServerError,也就是内部服务器错误,如果不是 bug,一般就是数据库挂了。

再多问几个状态码很多人就不知道了,因为大多数公司的软件服务没有走标准的 HTTP 状态码,很多状态码从来就不会出现,同学们自然也不会知道。

400 Bad Request 用于参数验证,少了一个参数或者参数类型错误之类的。

502 Bad Gateway 后端服务挂掉或者压力过大的时候,Nginx 接到的请求无法及时传递给后端的服务进行处理,这个时候就会出现 502 错误。这个也非常常见,知乎豆瓣网站经常开小差的时候发生的错误就是这个。

304 Not Modified 极少人知道这个状态码,因为大部分后端开发者的前端 Javascript 开发经验都严重不足。当你用 Chrome 打开一个经常访问的网站,看看 Network 传输的静态资源就可以看到很多 304 状态码。它表示该资源被浏览器缓存了不需要重新请求服务器。

401 Unauthorized 权限不足,这个很好理解,就是资源存在但是不让你访问。

403 Forbidden 资源禁止访问,如果你的 IP 列为黑名单了,就会发生这种错误。

其实还有很多状态码,小编也没去好好研究了,因为实在不会在工作中用到。感兴趣的请继续阅读维基百科

HTTP 有哪些 Method ?

GET 不解释,如果读者不知道,建议别在 IT 圈混了。

POST 一般用于创建或者修改资源,在 RESTFUL 规范里面 POST 只用来创建资源,并返回 201 Created 状态码表示创建成功。不过大多数网站都不遵循严格的 RESTFUL 规范,POST 拿来做修改资源的事也是非常常见的。

PUT 用于修改资源,比如修改资源的某个具体属性。

DELETE 用于删除资源。

HEAD 不常用,跟 GET 差不多,区别就是不返回 Body 内容,只返回 HTTP 头信息。一般用于获取资源的元信息,比如长度,修改时间等

OPTIONS 跨域相关,后面再讲。

TRACE 小编没用过。

CONNECT 小编没用过。

后面三个感兴趣的去阅读一下 RPC 规范。小编大概看了一下,表示没怎么看懂,你行你上去挑战一下。

HTTP 协议格式是怎样的?

HTTP 的请求和响应的消息协议是一样的,分为三个部分,起始行、消息头和消息体。这三个部分以 CRLF 作为分隔符。最后一个消息头有两个 CRLF,用来表示消息头部的结束。

HTTP 请求的起始行称为请求行,形如 GET /index.html HTTP/1.1

HTTP 响应的起始行称为状态行,形如 200 ok

消息头部有很多键值对组成,多个键值对之间使用 CRLF 作为分隔符,也可以完全没有键值对。形如 Content-Encoding: gzip

消息体是一个字符串,字符串的长度是由消息头部的 Content-Length 键指定的。如果没有 Content-Length 字段说明没有消息体,譬如 GET 请求就是没有消息体的,POST 请求的消息体一般用来放置表单数据。GET 请求的响应返回的页面内容也是放在消息体里面的。我们平时调用 API 返回的 JSON 内容都是放在消息体里面的。

什么是分块传送?

当浏览器向服务器请求一个资源时,这个资源是一个动态资源,服务器无法提前预知资源的大小,这个时候就可以使用分块传输。

服务器先生成一个 thunk,发送这个 chunk,再生成一个 chunk,再发送一个 chunk,直到全部资源传送完成。

分块传送需要在请求头增加一个特殊的键值对 transfer-encoding: thunked,那么消息体的内容便是分块传送的。

chunked 传输格式如图所示,由一段一段的分块组合而成,每个块由一个长度行和一个分块体组成,最后一个分块长度为 0 表示结束。

持久连接的机制是怎样的?

HTTP 早期版本中每个请求都会发起一个连接,一个网页除了页面的 HTML 之外还会有很多静态资源以及诸多的 API 调用,如果每个请求都一个连接,势必网页的一次加载就会和服务器创建多次连接,这是非常浪费服务器资源的,同时也让客户端的访问速度慢了不少。HTTP1.0 之后引入了 Keep-Alive 持久连接,在 HTTP1.1 版本中成为默认选项。它使得 HTTP 的一个连接可以连续服务多个请求,有效节省了资源,增加了客户端页面的加载速度。

持久连接也不宜一直保持,毕竟每个连接都会占用服务器资源,如果打开网页的人太多,那服务器资源也会紧张,所以一般服务器都会配置一个 KeepAlive Timeout 参数和 KeepAlive Requests 参数限制单个连接持续时长和最多服务的请求次数。

如果服务器设置的 timeout 时长为 0,就退化到非持久连接。非持久连接会在响应头部增加一个头信息 Connection: Close 通知客户端在接受完当前响应后连接需要立即关闭。

同样浏览器也不会因为服务器将 KeepAlive Timeout 配置了无限长就不管不问一直持续保持连接。每个浏览器都有它自己的内置限制,具体限制浏览器厂商各有不同。

什么叫 Pipeline 管线化?

HTTP1.0 不支持管线化,同一个连接处理请求的顺序是逐个应答模式,处理一个请求就需要耗费一个 TTL,也就是客户端到服务器的往返时间,处理 N 个请求就是 N 个 TTL 时长。当页面的请求非常多时,页面加载速度就会非常缓慢。

从 HTTP1.1 开始要求服务器支持管线化,可以同时将多个请求发送到服务器,然后逐个读取响应。这个管线化和 Redis 的管线化原理是一样的,响应的顺序必须和请求的顺序保持一致。

如何理解 HTTP 协议的无状态性?

所谓 HTTP 协议的无状态性是指服务器的协议层无需为不同的请求之间建立任何相关关系,它特指的是协议层的无状态性。但是这并不代表建立在 HTTP 协议之上的应用程序就无法维持状态。应用层可以通过会话 Session 来跟踪用户请求之间的相关性,服务器会为每个会话对象绑定一个唯一的会话 ID,浏览器可以将会话 ID 记录在本地缓存 LocalStorage 或者 Cookie,在后续的请求都带上这个会话 ID,服务器就可以为每个请求找到相应的会话状态。

阅读相关文章,关注公众号 [码洞]

6559 次点击
所在节点    程序员
44 条回复
Kilerd
2018-03-22 14:44:40 +08:00
> PUT 用于修改资源,比如修改资源的某个具体属性。
看到这个不想吐槽。
在 RESTFUL 里面,PUT 用于全部修改数据,PATCH 用于部分修改。

PATCH 都能漏了,我还是不关注好了,拉低智商。
chq3272991
2018-03-22 14:45:28 +08:00
不错不错
mentalkiller
2018-03-22 15:05:29 +08:00
@codehole #19

> wsstest:作为一个安全从业人员表示上面的基本都会,第一天入行师傅就叫我去自学 http 协议了……
> codehole:"下辈子也去做安全"

这个回复可以说是相当不友善了。

tips: codehole[加入于 2018-03-21]
g1165297373
2018-03-22 15:14:30 +08:00
算是比较常规的问题了。主要是题主标题太拉仇恨了。V 站大牛还是很多的,谦卑之心还是要有的
codehole
2018-03-22 15:30:57 +08:00
@mentalkiller 哎哟,一不小心就说错话了啊,不该不该
codehole
2018-03-22 15:31:34 +08:00
@g1165297373 老师教训的是
g1165297373
2018-03-22 15:38:19 +08:00
@codehole 哈哈,我也是菜鸡。从题主的文章学到了很多,感谢
hisuiibmpower4
2018-03-22 15:39:48 +08:00
101 和 451,好像大家忘了,哈哈哈
codehole
2018-03-22 15:54:17 +08:00
@hisuiibmpower4 451 太敏感不敢提,101 属于高级代码,后面再讲
codehole
2018-03-22 15:55:13 +08:00
@g1165297373 只有菜鸡们才会让小编觉得的文字写的有价值
mengyaoss77
2018-03-22 16:11:49 +08:00
帆帆可以
codehole
2018-03-22 16:13:37 +08:00
@mengyaoss77 抱抱佛脚还是管点用的
scukmh
2018-03-22 16:19:41 +08:00
418 都没有🙂
codehole
2018-03-22 16:27:07 +08:00
@scukmh 418 不好解释
silencefent
2018-03-22 16:32:54 +08:00
抛开文字不看的话,里番妹子还是可以
qsnow6
2018-03-22 16:36:49 +08:00
一本《图解 HTTP 》的事,扯这么多
7654
2018-03-22 16:43:48 +08:00
@bestkayle #9
@codehole #13
哪里有图哪里有妹子,没看到
codehole
2018-03-22 16:52:23 +08:00
@qsnow6 人家一本,我是一页
codehole
2018-03-22 16:53:16 +08:00
@7654 这位朋友道法很高啊
mario85
2018-03-22 20:25:30 +08:00
CONNECT 居然看不懂
https 默秒全

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/440366

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX