结束语
前言
大兵老师的 《浏览器的工作原理与实践》一文就到此结束了,非常感谢老师的分享。
由于此文并非完全复制老师原文,其中有针对个人做了一些修改。
而且,此处的文章并不全,里面的结束篇个人 并没有更了,后期在复习的时候,个人还是会进行新一版的更新。
所以还是再次建议大家去看看全文。
此文 老师 编写完成的时间是 2019 年下半年,个人更完全文的时间是 2022年 5月份为止。
结果测试
查看答案1、(单选) 关于 await/async ,以下哪个说法不正确?
A、await 等待一个 Promise 对象,如果 Promise 的状态变成了resolve 或者 reject,那么 async 函数会恢复执行
B、V8 通过协程来实现 async 函数暂停和恢复执行
C、如果 await 等待的是一个非 Promise 对象,那么 V8 会隐式地将该对象包装厂一个已经 resolve 的 Promise 对象
D、async 函数不支持 try/catch 来捕获异常
查看答案2、(多选) 使用 Promise 时,微任务是什么时候生成和触发的?
A、创建 Promise 时就生成了微任务
B、调用 resolve 或者 reject 时生成微任务
C、在当前宏任务即将退出之前执行
D、在当前宏任务退出之后立即执行
查看答案3、(单选) 通常,当页面执行动画时,刷新的频率为 60hz,页面才会显得比较流畅,浏览器要保存页面的流畅,处理一帧最多的时长是多少?
A、60 毫秒
B、10 毫秒
C、16.6 毫秒
D、100 毫秒
查看答案4、(单选) 观察下面 HTML 片段:
css: h1 {font-size: 16px} div p {font-weight: 12px} html: <div> <h1> 效率测试题 </h1> <p> 哪个 css 规则效率更高? </p> </div>下面哪个选择器执行效率更高:
A、h1 {font-size: 16px}
B、div p {font-weight: 12px}
C、没有区别
查看答案5、(单选) 执行下面代码,打印出来的内容是什么?
let myname = '极客时间' { console.log(myname) let myname = '极客邦' }A、极客时间
B、极客邦
C、抛出异常
查看答案6、(单选) 执行下面代码,打印出来的内容是什么?
showName() var showName = function() { console.log(2) } function showName() { console.log(1) }A、1
B、2
C、抛出异常
查看答案7、(单选) 关于渲染流程:
a: 构建 DOM 树
b: 样式计算(Recalculate Style)
c: 布局(Layout)
d: 绘制(Paint)
e: 合成(Raster)
f: 显示(Display)
顺序正确的是?
A、abcdef
B、bacdef
C、abcedf
D、abcdfe
查看答案8、(多选) 从输入 URL 到页面展示,这中间发生了什么?
A、当用户输入关键字并键入回车之后,浏览器会给打开的页面一次执行 beforeunload 事件的机会
B、执行 DNS 解析,建立 TCP 连接,发送请求数据给服务器
C、当浏览器接收到服务器返回的数据之后,便会更新浏览器界面状态(包括了安全状态、地址栏的URL、前进后退的历史状态,并更新 Web 页面)
D、渲染进程将渲染的结果同步到 Web 页面上
查看答案9、(单选) 关于 HTTP,以下说法错误的是?
A、HTTP 报文由起始行(start line)、头部(header)和主体(body)三部分组成,起始行是对报文进行的描述,头部包含报文的一些属性,主体包含报文的数据,在发出一个 HTTP 请求之前,这三部分是必须配置好的
B、HTTP 报文可以分为:请求报文(request message)和响应报文(response message)。当客户端向服务端发送请求时,就是发送请求报文;当服务端向客户端返回数据时,就是返回响应报文
C、常用的 HTTP 请求方法有 POST 和 GET
D、HTTP 协议本身是无状态的,通常我们使用 Cookie 来保持客户端和服务端的状态信息
查看答案10、(单选) 关于TCP 和 UDP,以下说法错误的是?
A、TCP 协议提供可靠的连接服务,采用三次握手建立一个连接
B、UDP是无连接的,UDP 发送数据报之前也不需要经过握手创建连接的过程
C、UDP 支持多播和广播,而 TCP 则不行
D、HTTP、HTTP2、HTTP3 都是基于 TCP 协议的
查看答案11、(单选) HTTP 是明文传输数据的,在传输过程中的每一个环节,数据都有可能被窃取或篡改,这也意味着你和服务器之间还可能有个中间人,你们在通信过程中的一切内容都在中间人的掌握中,于是引入了 HTTPS,关于 HTTPS,以下说法错误的是?
A、HTTPS 为了兼容 HTTP,我们在 HTTP 和 TCP 之间引入了一个 SSL/TLS 层来实现 HTTPS
B、HTTPS 协议采用了非对称加密密钥,使用对称加密正文
C、HTTPS 需要使用数字证书来证明服务器身份的可靠性,可以向 CA 机构申请数字证书
D、HTTPS 是绝对安全的
查看答案12、(单选) 由于网络资源是不可靠的,这些网络资源可能会对操作系统造成破坏,因此浏览器默认不信任网络资源,于是浏览器设计者就将安全沙箱引用在渲染进程中,关于安全沙箱,以下说法错误的是?
A、由于渲染进程采取了安全沙箱,所以在渲染进程中是无法直接读写系统文件的
B、由于渲染进程采取了安全沙箱,所以在渲染进程中是无法访问网络资源的。
C、由于渲染进程采取了安全沙箱,所以在渲染进程中是无法直接访问窗口句柄的。
D、采用了安全沙箱,使得浏览器的架构设计变得更加简单
查看答案13、(多选) 同源策略是浏览器中的一项基本的安全策略,那么同源策略中的同源是指?
A、协议相同(protocol)
B、路径相同(pathname)
C、域名相同(hostname)
D、端口相同(port)
查看答案14、(单选) 关于 HTTP3,下面说法错误的是?
A、HTTP3 为了解决 HTTP2 的对头阻塞问题,使用了 QUIC 协议替代了 TCP 协议
B、HTTP3 所使用的 QUIC 协议是基于 UDP 的,所以 HTTP3 是不可靠的协议
C、QUIC 协议集成了 TLS 加密功能
D、HTTP3 目前还不成熟,存在部署难度大,中间设备僵化等问题
查看答案15、(多选) 为什么说 HTTP2 效率比 HTTP1 高?
A、支持多路复用
B、支持头部压缩
C、支持请求的优先级
D、支持服务器推送
E、HTTP2 基于 QUIC 协议,解决了 TCP 队头阻塞的问题
查看答案16、(多选) 关于 HTTP1.0 和 HTTP 1.1 ,以下说法正确的是?
A、HTTP1.0 默认使用短连接,每次请求都需要建立新的 TCP 连接,连接不能复用
B、HTTP 1.1 支持持久连接和请求的流水线处理,在一个 TCP 连接上可以传送多个 HTTP 请求和响应,减少建立和关闭 TCP 连接的消耗和延迟,提高效率。HTTP 1.1 默认开启 “Connection:Keep-Alive”,使用长连接,加入“Connection:close”才关闭
C、HTTP1.0 和 HTTP1.1 都是基于 TCP 协议来实现数据传输的
D、在 HTTP1.0 中主要使用 header 里的 If-Modified-Since,Expires 来作为缓存判断的标准,HTTP1.1 则引入了更多的缓存控制策略,例如引入 Entity tag、If-Unmodified-Since、If-Match、If-None-Match 等更多可供选择的缓存头来控制缓存策略
查看答案17、(单选) 下面哪个元素不在渲染树中?
A、style1{display:none}
B、style2{height:0}
C、style3{visible:hidden}
D、style4{display:block}
查看答案18、(单选) 运行下面这段 HTML 脚本,以下说法正确的是?
<html> <body> <script> let div1 = document.getElementByTagName('div')[0] div1.innerText = 'time.geekbang' </script> <div>test</div> </body> </html>A、页面显示出来的是 time.geekbang
B、页面显示出来的是 test
C、执行脚本出错,导致后面的 div 无法被渲染,故页面是空白的
D、页面显崩溃状态
查看答案19、(多选) 以下哪些方式可以缩短页面的首次白屏时长?
A、通过内联 JS、内联 CSS 来移除这两种类型的文件下载,这样获取到 HTML 文件之后就可以直接开始渲染流程了。
B、尽量减少文件大小,比如通过 webpack 等工具移除一些不必要的注释,并压缩 JS 文件
C、将一些不需要的解析 HTML 阶段使用的 JS 标记上 async 或者 defer
D、对于大的 CSS 文件,可以通过媒体查询属性,将其拆分为多个不同用途的 CSS 文件,这样只有在特定的场景下才会加载特定的 CSS 文件
查看答案20、(单选) 关于微任务和宏任务,以下哪个说法不正确?
A、V8的宿主维护了消息队列,主线程不断从消息队列中取出任务,并依次执行,我们把消息队列中的任务称为宏任务
B、微任务是一个需要异步执行的函数,可以通过 Promise.reject 或者 Promise.resolve 来触发,执行时机是在当前调用 reject 或者 resolve 函数执行结束之后、当前宏任务结束之前
C、V8 在每个宏任务中维护了一个微任务队列
D、在微任务中循环触发新的微任务不会造成线程的卡死
答案
1、D
2、BC
解析:创建 Promise 时,并不会生成微任务,而是需要等到 Promise 对象调用 resolve 或 reject 函数时才会产生微任务,产生的微任务并不会立即执行,而是等待当前宏任务快要执行结束时再执行。
3、C
解析:1000/60 = 16.66
4、A
解析:浏览器是从右向左匹配 CSS 选择器的,当遍历到 p 时,还要额外判断父节点是不是 div,这就做了额外的工作,所以效率会差一点。
5、C
解析:let 存在块级作用域,它没有变量提升,并且具备暂时性死区特性。
6、A
解析:在编译阶段,showName 是第二个函数,进入执行阶段,首先执行的就是该函数。
7、A
8、ABCD
9、A
解析:HTTP 请求体 并不是必须要配置好的。
10、D
解析:HTTP3 是基于 QUIC 协议的。
11、D
解析:可以通过在用户机器上安装假的 HTTPS 根证书来欺骗浏览器
12、D
解析:引入了安全沙箱,浏览器的设计变得更加复杂了,比如不能在安全沙箱保护的进程中执行系统文件读写、网络资源访问、操作窗口句柄等,这样我们不得不将这些功能移到安全沙箱之外的进程中去完成,这就直接加大了浏览器架构设计的难度。
13、ACD
解析:同源策略是指同时具备相同的协议、相同的域名、相同的端口
14、B
解析:虽然 QUIC 是基于 UDP 的,但是在 QUIC 层,已经保证了协议数据传输的可靠性。
15、ABCD
解析:HTTP3 是基于 QUIC 协议的,HTTP2 和 HTTP1 都是基于 TCP 协议的。
16、ABCD
17、A
解析:如果浏览器了检测到 display:none,那么该元素将不会在渲染树中出现
18、B
解析:因为在解析 JS 的时候,div元素还没有被创建出来,所以 getElementsByTagName 返回的数据是空的。报错信息如下:
Uncaught TypeError: Cannot set properties of undefined (setting 'innerHTML')
但是页面中还是 展示 test
19、ABCD
20、D
解析:在微任务中循环触发新的微任务,会导致消息队列中的其他宏任务永远无法被执行,那么就会造成线程的卡死。