浏览器原理面试题 前端「前端面试进阶之浏览器原理」( 七 )


产生死锁的必要条件:
互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用 。
请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放 。
不剥夺条件:进程已获得的资源在未使用完之前,不能剥夺 , 只能在使用完时由自己释放 。
环路等待条件:在发生死锁时,必然存在一个进程——资源的环形链 。
预防死锁的方法:
资源一次性分配:一次性分配所有资源,这样就不会再有请求了(破坏请求条件)
只要有一个资源得不到分配,也不给这个进程分配其他的资源(破坏请保持条件)
可剥夺资源:即当某进程获得了部分资源,但得不到其它资源,则释放已占有的资源(破坏不可剥夺条件)
资源有序分配法:系统给每类资源赋予一个编号 , 每一个进程按编号递增的顺序请求资源,释放则相反(破坏环路等待条件)
7. 如何实现浏览器内多个标签页之间的通信?
实现多个标签页之间的通信 , 本质上都是通过中介者模式来实现的 。因为标签页之间没有办法直接通信,因此我们可以找一个中介者,让标签页和中介者进行通信,然后让这个中介者来进行消息的转发 。通信方法如下:
使用 websocket 协议,因为 websocket 协议可以实现服务器推送,所以服务器就可以用来当做这个中介者 。标签页通过向服务器发送数据,然后由服务器向其他标签页推送转发 。
使用 ShareWorker 的方式,shareWorker 会在页面存在的生命周期内创建一个唯一的线程,并且开启多个页面也只会使用同一个线程 。这个时候共享线程就可以充当中介者的角色 。标签页间通过共享一个线程,然后通过这个共享的线程来实现数据的交换 。
使****用 localStorage 的方式,我们可以在一个标签页对 localStorage 的变化事件进行监听,然后当另一个标签页修改数据的时候,我们就可以通过这个监听事件来获取到数据 。这个时候 localStorage 对象就是充当的中介者的角色 。
使用 postMessage 方法,如果我们能够获得对应标签页的引用,就可以使用postMessage 方法 , 进行通信 。
8. 对Service Worker的理解
Service Worker 是运行在浏览器背后的独立线程 , 一般可以用来实现缓存功能 。使用 Service Worker的话,传输协议必须为 HTTPS 。因为 Service Worker 中涉及到请求拦截,所以必须使用 HTTPS 协议来保障安全 。
Service Worker 实现缓存功能一般分为三个步骤:首先需要先注册 Service Worker,然后监听到 install 事件以后就可以缓存需要的文件,那么在下次用户访问的时候就可以通过拦截请求的方式查询是否存在缓存,存在缓存的话就可以直接读取缓存文件 , 否则就去请求数据 。以下是这个步骤的实现:
// index.js
if (navigator.serviceWorker) {
navigator.serviceWorker
.register('sw.js')
.then(function(registration) {
console.log('service worker 注册成功')
})
.catch(function(err) {
console.log('servcie worker 注册失败')
})
}
// sw.js
// 监听 `install` 事件,回调中缓存所需文件
self.addEventListener('install', e => {
e.waitUntil(
caches.open('my-cache').then(function(cache) {
return cache.addAll(['./index.html', './index.js'])
})
)
})
// 拦截所有请求事件
// 如果缓存中已经有请求的数据就直接用缓存,否则去请求数据
self.addEventListener('fetch', e => {
e.respondWith(
caches.match(e.request).then(function(response) {
if (response) {