V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
codehole
V2EX  ›  程序员

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

  •  
  •   codehole ·
    pyloque · 2018-03-22 11:50:36 +08:00 · 6594 次点击
    这是一个创建于 2443 天前的主题,其中的信息可能已经有所发展或是发生改变。

    小编是一个非典型面试官,对于 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,服务器就可以为每个请求找到相应的会话状态。

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

    第 1 条附言  ·  2018-03-22 12:30:42 +08:00
    第 2 条附言  ·  2018-03-23 09:51:37 +08:00

    朋友们,别忘了看一看下面这篇文章啊,精华中的精华

    Shell文本处理编写单行指令的诀窍

    44 条回复    2018-03-23 10:09:59 +08:00
    ChristopherWu
        1
    ChristopherWu  
       2018-03-22 12:05:05 +08:00
    漏了 302 跳转
    codehole
        2
    codehole  
    OP
       2018-03-22 12:05:56 +08:00
    @ChristopherWu 200 不也漏了么
    ccc008
        3
    ccc008  
       2018-03-22 12:07:50 +08:00   ❤️ 2
    看了开头我就直接拉到结尾。果然没猜错
    congeec
        4
    congeec  
       2018-03-22 12:10:48 +08:00   ❤️ 1
    这叫刁难?原来是公众号拉关注的
    jadec0der
        5
    jadec0der  
       2018-03-22 12:37:46 +08:00 via Android
    文章写的不错,不过这不算刁难
    codehole
        6
    codehole  
    OP
       2018-03-22 12:38:48 +08:00
    @jadec0der 请允许我标题党一下下
    fuxkcsdn
        7
    fuxkcsdn  
       2018-03-22 12:50:35 +08:00 via iPhone
    在简历里写熟悉 http 协议的话,那这些不算刁难
    jasonyang9
        8
    jasonyang9  
       2018-03-22 13:09:05 +08:00
    TLDR; 无状态性是这个意思吗?如果英文是 statelessness 的话??
    KgM4gLtF0shViDH3
        9
    KgM4gLtF0shViDH3  
       2018-03-22 13:33:17 +08:00
    图上的妹子是谁
    codehole
        10
    codehole  
    OP
       2018-03-22 13:36:48 +08:00
    @jasonyang9 你英文不错
    RorschachZZZ
        11
    RorschachZZZ  
       2018-03-22 13:36:54 +08:00
    不刁难
    leonidas
        12
    leonidas  
       2018-03-22 13:37:08 +08:00
    看着好好的 突然蹦出个这么丑的妹子 把老子吓得一条
    codehole
        13
    codehole  
    OP
       2018-03-22 13:37:52 +08:00
    @bestkayle 吉冈里帆
    codehole
        14
    codehole  
    OP
       2018-03-22 13:38:53 +08:00
    @leonidas 开来你的阈值有点高啊
    nikolai
        15
    nikolai  
       2018-03-22 13:38:59 +08:00
    @bestkayle 吉冈里帆
    codehole
        16
    codehole  
    OP
       2018-03-22 13:39:26 +08:00
    @RorschachZZZ 做人要低调啊
    Corbusier
        17
    Corbusier  
       2018-03-22 14:14:02 +08:00 via iPhone
    还行,不怎么刁难
    wsstest
        18
    wsstest  
       2018-03-22 14:20:43 +08:00
    作为一个安全从业人员表示上面的基本都会,第一天入行师傅就叫我去自学 http 协议了……
    codehole
        19
    codehole  
    OP
       2018-03-22 14:27:32 +08:00 via Android
    @wsstest 下辈子也去做安全
    pheyer
        20
    pheyer  
       2018-03-22 14:43:43 +08:00
    眼瞎看到 HTML 的全称是什么,我这脑子。。。
    Kilerd
        21
    Kilerd  
       2018-03-22 14:44:40 +08:00
    > PUT 用于修改资源,比如修改资源的某个具体属性。
    看到这个不想吐槽。
    在 RESTFUL 里面,PUT 用于全部修改数据,PATCH 用于部分修改。

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

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

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

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

    我随便补一条,PUT 是用来更新的,那是全量更新还是部分更新?你回答完一个,我再问另外一种更新用啥?
    iyaozhen
        43
    iyaozhen  
       2018-03-23 00:13:41 +08:00
    不不不,我一般从 TCP 三次握手问起,然后问为什么需要第三次 (逃)
    codehole
        44
    codehole  
    OP
       2018-03-23 10:09:59 +08:00
    @Paddington 感谢纠正啊,可惜 V2EX 不开放编辑了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1126 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 22:45 · PVG 06:45 · LAX 14:45 · JFK 17:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.