面试集锦(五)

1.宏任务和微任务

js是一门单线程语言,所以同一时间只能执行一个任务。为了防止主线程不阻塞,开发者提出了事件循环(Event Loop)

1.1任务执行的原则:

  • js将任务分为了同步任务和异步任务。
  • 同步任务都在主线程上执行,形成一个执行栈。
  • 异步任务会进入到一任务列表注册他们,一旦异步任务有了执行结果,则将其放到一个任务队列中。
  • 当同步任务执行完成后,此时主线程空闲,则将异步任务队列放入执行栈中,依次执行。

在这里插入图片描述

1.2 宏任务

每次执行栈执行的的代码都可以看做一个宏任务。

浏览器为了能够是js内部的宏任务和DOM任务有序执行。每次宏任务结束下次宏任务开始前都会进行一次页面重绘。

宏任务->页面重绘->宏任务

常见的宏任务包含:

script(整体代码)
setTimeout
setInterval
I/O
UI交互事件
postMessage
MessageChannel
setImmediate(Node.js 环境)

1.3 微任务

当前任务执行结束后立即执行的任务。当前任务结束后,下一个任务执行前(渲染之前)

常见的微任务包含:

Promise.then
Object.observe
MutaionObserver
process.nextTick(Node.js 环境)

在这里插入图片描述

宏任务和微任务被放在了不同的队列中。
当前宏任务执行完成后会检查微任务队列中是否存在任务,有则执行。
宏任务的优先级高于微任务

console.log("script start")

setTimeout(()=>{
        console.log("异步宏任务")
},0)

new Promise((resolve)=>{
        console.log("同步宏任务")
        resolve()
}).then(()=>{
        console.log("微任务1")
})

console.log("script end")

script start
同步宏任务
script end
微任务1
异步宏任务

解析:

  1. script startPromisescript end放入主线程执行栈、setTimeout放入异步宏任务队列。

Promise是立即执行函数,在其创建的时候就被执行了,只有在then()执行时才会被推入微任务队列

  1. script start执行完成后,立即执行new Promise任务。
  2. resolve执行成功后,将then放入微任务队列,同时,继续下一个宏任务。
  3. 因为script end本身就在主线程上,在同步执行栈中,优先执行同步任务。
  4. 完成后发现微任务中有then任务,立即执行。
  5. 最后继续查找是否还有同步任务,没有了,所以开始执行异步宏任务setTimeOut

1.4 事件循环(Event Loop)

事件循环是解决js单线程运行阻塞的一种机制。

在这里插入图片描述

2.new操作

new操作主要完成了以下4个步骤:

  1. 创建一个新的对象{}。
  2. 将构造函数的作用域赋给新的对象,即this指向新对象。
  3. 执行构造函数的代码,为新的对象添加属性。
  4. 返回这个新的对象。

3.XSS和CSRF攻击

3.1 XSS

XSS:(跨域脚本攻击)

攻击原理:
不需要做登陆验证,通过合法的操作(例如在输入框输入脚本,url添加脚本参数),向你的页面注入可执行脚本,从而破坏页面正常结构,或插入广告等恶意内容。

攻击方式:

  1. 反射性攻击(Reflected XSS):是指xss代码在请求的url中,而后提交到服务器,服务器解析后,XSS代码随着响应内容一起传给客户端进行解析执行。
  2. 存储型攻击(Stored XSS):Stored XSS和 Reflected XSS的差别就在于,具有攻击性的脚本被保存到了服务器端(数据库,内存,文件系统)并且可以被普通用户完整的从服务的取得并执行,从而获得了在网络上传播的能力。
  3. 基于DOM或本地的 XSS 攻击:DOM型 XSS其实是一种特殊类型的反射型 XSS,它是基于 DOM文档对象模型的一种漏洞。可以通过 DOM来动态修改页面内容,从客户端获取 DOM中的数据并在本地执行。基于这个特性,就可以利用 JS脚本来实现 XSS漏洞的利用。

防御措施:

  1. 输入过滤:前后端对传入数据进行校验和过滤。
  2. 实体转义:当需要往 HTML 标签之间插入不可信数据的时候,首先要做的就是对不可信数据进行 HTML Entity 编码。
  3. javaScript编码转义:对不可信的数据进行javaScript编码。
  4. Http Only cookie:将重要的cookie设置为 http only。

3.2 CSRF

CSRF:跨站请求伪造

攻击原理:

  1. 用户登录了授信网站A,并且在本地生成了cookie信息。
  2. 在不退出A网站的前提下,访问了危险网站B。
  3. 网站B接收到接收到用户请求后,返回一些攻击性的代码,然后在用户不知情的情况下,携带cookie向A网站发出请求,从而达到攻击的目的。

防御措施:

  1. 验证 HTTP Referer 字段
  2. 在请求地址中添加 token 并验证
  3. 在 HTTP 头中自定义属性并验证

4.作用域

作用域是存储和访问变量的一套规则,定义了变量的可访问性。常分为局部作用域、全局作用域、块级作用域。

编译过程一般分为三个步骤:词法分析、解析词法、代码生成。

4.1词法分析

通常会将代码解析成有意义的代码块,这些代码块叫做词法单元
例如:
var a=2
解析后为:
var、a、=、2

4.2解析词法

将词法单元组成一个抽象语法树(AST)

4.3 代码生成

将抽象语法树转化成可执行的代码,并将变量存储到内存中。

作用域就是负责维护所有声明的变量和查询操作而存在的。

4.5编译过程

var a = 2 为例

  1. 编译器询问当前作用域中是否存在变量 a,若果存在忽略声明,否则在当前作用域中新建一个变量a。
  2. 编译器生成可执行的代码,js引擎询问当前作用域是否存在变量a,存在则直接使用,否则继续向上级作用域查找。
  3. 如果js引擎找到了变量a则将2赋值给它,否则抛出异常。

5.强缓存和协商缓存

5.1强缓存

当浏览器请求某个文件时,会根据response header中的缓存字段,并且判断其是否缓存超时,如果未超时,则不发起请求,直接利用浏览器缓存的资源,状态码:200。

强缓存的header字段有2个:
expires:它是http1.0时的提出的。它的值为一个绝对时间的GMT格式的时间字符串,如Mon, 10 Jun 2015 21:31:12 GMT,如果发送请求的时间在expires之前,那么本地缓存始终有效,否则就会发送请求到服务器来获取资源。

cache-control:max-age=number:它是http1.1时提出的。主要利用max-age的值来判断是否超时,其值是一个相对值。资源第一次的请求时间和Cache-Control设定的有效期,计算出一个资源过期时间,再拿这个过期时间跟当前的请求时间比较,如果请求时间在过期时间之前,就能命中缓存,否则未命中。

cache-control有以下几个常用值:

  • no-cache:不使用本地缓存,需要使用协商缓存,先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务器进行验证,未过期则不更新。
  • no-store:禁用浏览器缓存,用户的每次请求都将重新从服务器下载全新的资源。
  • public:可以被所有用户缓存,包含终端用户和CDN等中间代理服务器。
  • private:只能被终端用户的浏览器缓存,不允许代理服务器对其缓存。
  • max-age:缓存相对时间,与上一次资源变更时间相加,用于计算资源过期时间。

cache-control的优先级高于expires

5.2协商缓存

当强缓存未命中的时候,向服务端发送请求,根据响应头的信息,判端浏览器的缓存资源是否和服务器资源一致,如果一致,则仅返回一个请求头状态码304,如果不一致,则重新返回浏览器资源,同时修改请求头信息,状态码为200.

协商缓存是客户端与服务端公共约定的一套通讯标识,用于让服务端能清晰的判断请求资源是否可以缓存访问。协商缓存的字段是成对出现的,如果请求头不包含缓存字段,那么响应头也不会有。

常用的协商缓存字段有以下2对:

  • Last-Modified/If-Modified-Since:这2者都是一个GMT格式的时间字符串。具体使用流程如下:
    1. 浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在respone header加上Last-Modified字段,其表示资源在服务器上的最后修改时间。
    2. 浏览器再次跟服务器请求这个资源时,在request header上加上If-Modified-Since字段,其表示上一次请求资源时返回的Last-Modified的值。
    3. 服务器根据浏览器传入的If-Modified-Since和服务器资源的最后更新时间进行比较,如果未变化,则返回304 Not Modified,浏览器直接利用缓存,如果缓存未命中,则重新加载服务端的资源,且修改respone header中的Last-Modified

*Etag/If-None-Match:这两个值都是服务器生成的资源唯一标识,当资源变化时唯一标识也会变化。
判断流程与Last-Modified/If-Modified-Since类似。

Etag相较于Last-Modified的优点:

  1. 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
  2. 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒);
  3. 某些服务器不能精确的得到文件的最后修改时间。

Last-ModifiedETag可以一起使用,但必须遵循缓存优先级。
cache-control>expries>etag>last-modified

在这里插入图片描述

需注意:

  • F5刷新并不会修改expires/cache-control,但是会对last-modified/etag进行验证。
  • ctrl+F5强制刷新,对expires/cache-controllast-modified/etag都没有影响,会完全利用浏览器缓存。
  • 其他刷新操作均会进行缓存校验
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值