网络原理面试题

1.如何理解 URI?

URI, 全称为(Uniform Resource Identifier), 也就是统一资源标识符,它的作用很简单,就是区分互联网上不同的资源。但是,它并不是我们常说的网址, 网址指的是URL, 实际上URI包含了URN和URL两个部分,由于 URL 过于普及,就默认将 URI 视为 URL 了。

URI 的结构

URI 真正最完整的结构是这样的

4c2a5e192368

好像跟平时见到的不太一样!先别急,来一一拆解。scheme 表示协议名,比如http, https, file等等。后面必须和://连在一起。user:passwd@ 表示登录主机时的用户信息,不过很不安全,不推荐使用,也不常用。host:port** 表示主机名和端口。path 表示请求路径,标记资源所在位置。query 表示查询参数,为key=val这种形式,多个键值对之间用&隔开。fragment 表示 URI 所定位的资源内的一个锚点**,浏览器可以根据这个锚点跳转到对应的位置。

https://www.baidu.com/s?tn=54093922_6_hao_pg&ie=utf-8&wd=%E7%99%BE%E5%BA%A6

这个 URI 中

  • https 即scheme部分
  • www.baidu.com 为host:port部分(注意,http 和 https 的默认端口分别为80、443)
  • kenguba/upkpls/gisxr2 为path部分
  • word=1&name=kenguba 表示query部分
  • #UrkH4 就是锚点

    0b6adec55d09

URI 编码

URI 只能使用 ASCII , ASCII 之外的字符是不支持显示的,而且还有一部分符号是界定符,如果不加以处理就会导致解析出错。因此,URI 引入了编码机制,将所有非 ASCII 码字符和界定符转为十六进制字节值,然后在前面加个%。

encodeURI("https://www.yuque.com/kenguba/upkpls/gisxr2?name=一缕清风")
"https://www.yuque.com/kenguba/upkpls/gisxr2?name=%E4%B8%80%E7%BC%95%E6%B8%85%E9%A3%8E"
decodeURI("https://www.yuque.com/kenguba/upkpls/gisxr2?name=%E4%B8%80%E7%BC%95%E6%B8%85%E9%A3%8E")

encodeURIComponent("https://www.yuque.com/kenguba/upkpls/gisxr2?name=一缕清风")
"https://www.yuque.com/kenguba/upkpls/gisxr2?name=%E4%B8%80%E7%BC%95%E6%B8%85%E9%A3%8E"
decodeURIComponent("https://www.yuque.com/kenguba/upkpls/gisxr2?name=%E4%B8%80%E7%BC%95%E6%B8%85%E9%A3%8E")

2.解释一下HTTP的超文本传输协议

HTTP 是超文本传输协议,也就是HyperText Transfer Protocol。它可以拆成三个部分:

  • 超文本
  • 传输
  • 协议

f1d5d611ab7f

协议

84841859f15a

生活中的协议,本质上与计算机中的协议是相同的,协议的特点:

  • 协 字,代表的意思是必须有两个以上的参与者。例如三方协议里的参与者有三个:你、公司、学校三个;租房协议里的参与者有两个:你和房东。
  • 议 字,代表的意思是对参与者的一种行为约定和规范。例如三方协议里规定试用期期限、毁约金等;租房协议里规定租期期限、每月租金金额、违约如何处理等。
    针对 HTTP 协议,我们可以这么理解。HTTP 是一个用在计算机世界里的协议。它使用计算机能够理解的语言确立了一种计算机之间交流通信的规范(两个以上的参与者),以及相关的各种控制和错误处理方式(行为约定和规范)

传输

所谓的「传输」,很好理解,就是把一堆东西从 A 点搬到 B 点,或者从 B 点 搬到 A 点。别轻视了这个简单的动作,它至少包含两项重要的信息。HTTP 协议是一个双向协议。我们在上网冲浪时,浏览器是请求方 A ,百度网站就是应答方 B。双方约定用 HTTP 协议来通信,于是浏览器把请求数据发送给网站,网站再把一些数据返回给浏览器,最后由浏览器渲染在屏幕,就可以看到图片、视频了。

b63c9b8403ba

数据虽然是在 A 和 B 之间传输,但允许中间有中转或接力。就好像第一排的同学想穿递纸条给最后一排的同学,那么传递的过程中就需要经过好多个同学(中间人),这样的传输方式就从「A < - > B」,变成了「A <-> N <-> M <-> B」。而在 HTTP 里,需要中间人遵从 HTTP 协议,只要不打扰基本的数据传输,就可以添加任意额外的东西。针对传输,我们可以进一步理解了 HTTP。HTTP 是一个在计算机世界里专门用来在两点之间传输数据的约定和规范。

超文本

HTTP 传输的内容是「超文本」 我们先来理解「文本」,在互联网早期的时候只是简单的字符文字,但现在「文本」的涵义已经可以扩展为图片、视频、压缩包等,在 HTTP 眼里这些都算做「文本」。再来理解「超文本」,它就是超越了普通文本的文本,它是文字、图片、视频等的混合体最关键有超链接,能从一个超文本跳转到另外一个超文本。HTML 就是最常见的超文本了,它本身只是纯文字文件,但内部用很多标签定义了图片、视频等的链接,在经过浏览器的解释,呈现给我们的就是一个文字、有画面的网页了。OK,经过了对 HTTP 里这三个名词的详细解释,就可以给出比「超文本传输协议」这七个字更准确更有技术含量的答案:HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」

⚠️注意: HTTP 不是用于从互联网服务器传输超文本到本地浏览器的协议,也可以是服务器到服务器,所以采用两点之间的描述会更准确

3.HTTP 的特点?HTTP 有哪些缺点?

HTTP 的特点概括

灵活可扩展 主要体现在两个方面。

一个是语义上的自由,只规定了基本格式,比如空格分隔单词,换行分隔字段,其他的各个部分都没有严格的语法限制

另一个是传输形式的多样性,不仅仅可以传输文本,还能传输图片、视频等任意数据,非常方便。

可靠传输 HTTP 基于 TCP/IP,因此把这一特性继承了下来。这属于 TCP 的特性,不具体介绍了。

请求-应答 也就是一发一收、有来有回, 当然这个请求方和应答方不单单指客户端和服务器之间,如果某台服务器作为代理来连接后端的服务端,那么这台服务器也会扮演请求方的角色。

无状态 这里的状态是指通信过程的上下文信息,而每次 http 请求都是独立、无关的,默认不需要保留状态信息

HTTP 缺点

无状态 所谓的优点和缺点还是要分场景来看的,对于 HTTP 而言,最具争议的地方在于它的无状态。

在需要长连接的场景中,需要保存大量的上下文信息,以免传输大量重复的信息,那么这时候无状态就是 http 的缺点了。

但与此同时,另外一些应用仅仅只是为了获取一些数据,不需要保存连接上下文信息,无状态反而减少了网络开销,成为了 http 的优点。

明文传输 即协议里的报文(主要指的是头部)不使用二进制数据,而是文本形式。这当然对于调试提供了便利,但同时也让 HTTP 的报文信息暴露给了外界,给攻击者也提供了便利。WIFI陷阱就是利用 HTTP 明文传输的缺点,诱导你连上热点,然后疯狂抓你所有的流量,从而拿到你的敏感信息。

队头阻塞问题 当 http 开启长连接时,共用一个 TCP 连接,同一时刻只能处理一个请求,那么当前请求耗时过长的情况下,其它的请求只能处于阻塞状态,也就是著名的队头阻塞问题。接下来会有一小节讨论这个问题。

4.HTTP 报文结构是怎样的?

对于 TCP 而言,在传输的时候分为两个部分: **TCP头 **和 数据部分。而 HTTP 类似,也是 header + body 的结构,具体而言:

起始行 + 头部 + 空行 + 实体

由于 http 请求报文和响应报文是有一定区别,因此分开介绍

2Fresize

起始行

对于请求报文来说,起始行类似下面这样:

GET /home HTTP/1.1

也就是方法 + 路径 + http版本。对于响应报文来说,起始行一般张这个样:

HTTP/1.1 200 OK

响应报文的起始行也叫做状态行。由 http版本、状态码和原因 三部分组成。⚠️注意:在起始行中,每两个部分之间用空格隔开,最后一个部分后面应该接一个换行,严格遵循 ABNF 语法规范

头部

展示一下请求头和响应头在报文中的位置:

9b63b1346da8

不管是请求头还是响应头,其中的字段是相当多的,而且牵扯到http非常多的特性,这里就不一一列举的,重点看看这些头部字段的格式:

  • 字段名不区分大小写
  • 字段名不允许出现空格,不可以出现下划线_
  • 字段名后面必须**紧接着 **:

空行

很重要,用来区分开头部和实体。问: 如果说在头部中间故意加一个空行会怎么样?那么空行后的内容全部被视为实体。

实体

就是具体的数据了,也就是 body 部分。请求报文对应请求体, 响应报文对应响应体。

5.如何理解 HTTP 的请求方法?

http/1.1 规定了以下请求方法(注意,都是大写):

  • GET 通常用来获取资源
  • HEAD 获取资源的元信息
  • POST 提交数据,即上传数据
  • PUT 修改数据
  • DELETE 删除资源(几乎用不到)
  • CONNECT 建立连接隧道,用于代理服务器
  • OPTIONS 列出可对资源实行的请求方法,预检请求,用来跨域请求
  • TRACE 追踪请求-响应的传输路径

6.http 常见字段有哪些?

  • Host
  • Content-Length
  • Connection
  • Content-Encoding
  • Content-Type

7.对于定长和不定长的数据,HTTP 是怎么传输的?

定长包体

对于定长包体而言,发送端在传输的时候一般会带上 Content-Length, 来指明包体的长度。我们用一个nodejs服务器来模拟一下:

const http = require('http');

const server = http.createServer();

server.on('request', (req, res) => {
  if(req.url === '/') {
    res.setHeader('Content-Type', 'text/plain');
    res.setHeader('Content-Length', 10);
    res.write("helloworld");
  }
})

server.listen(8081, () => {
  console.log("成功启动");
})

启动后访问: localhost:8081。浏览器中显示如下:

helloworld

这是长度正确的情况,那不正确的情况是如何处理的呢?我们试着把这个长度设置的小一些:

res.setHeader('Content-Length', 8);

重启服务,再次访问,现在浏览器中内容如下:

hellowor

那后面的ld哪里去了呢?实际上在 http 的响应体中直接被截去了。然后试着将这个长度设置得大一些:

res.setHeader('Content-Length', 12);

此时浏览器显示如下:

60cc8ee927ba

直接无法显示了。可以看到 Content-Length 对于 http 传输过程起到了十分关键的作用,如果设置不当可以直接导致传输失败。

不定长包体

上述是针对于定长包体,那么对于不定长包体而言是如何传输的呢?这里就必须介绍另外一个 http 头部字段了:

Transfer-Encoding: chunked

// Transfer-Encoding: chunked
// Transfer-Encoding: compress
// Transfer-Encoding: deflate
// Transfer-Encoding: gzip
// Transfer-Encoding: identity
// Several values can be listed, separated by a comma
// Transfer-Encoding: gzip, chunked

表示分块传输数据,设置这个字段后会自动产生两个效果:

  • Content-Length 字段会被忽略
  • 基于长连接持续推送动态内容
    我们依然以一个实际的例子来模拟分块传输,nodejs 程序如下:
const http = require('http');

const server = http.createServer();

server.on('request', (req, res) => {
  if(req.url === '/') {
    res.setHeader('Content-Type', 'text/html; charset=utf8');
    res.setHeader('Content-Length', 10);
    res.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值