拼多多笔试、面试
1、我想想考察了啥,好像是排序算法的时间复杂度和稳定性
排序算法 | 平均时间复杂度 | 最坏时间复杂度 | 空间复杂度 | 是否稳定 |
---|---|---|---|---|
冒泡排序 | O(n2) | O(n2) | O(1) | 是 |
选择排序 | O(n2) | O(n2) | O(1) | 不是 |
直接插入排序 | O(n2) | O(n2) | O(1) | 是 |
归并排序 | O(nlogn) | O(nlogn) | O(n) | 是 |
快速排序 | O(nlogn) | O(n2) | O(logn) | 不是 |
堆排序 | O(nlogn) | O(nlogn) | O(1) | 不是 |
希尔排序 | O(nlogn) | O(ns) | O(1) | 不是 |
计数排序 | O(n+k) | O(n+k) | O(n+k) | 是 |
基数排序 | O(N∗M) | O(N∗M) | O(M) | 是 |
2、还考察了手写promise.all()
首先promise.all()会异promise数组的形式传入一组promise,把Promise实例包装成一个新的Promise,同时,成功和失败的返回值是不一样的,成功的时候返回的是一个结果数组,而失败的时候返回最先被reject的失败状态的值。
1 |
|
3、判断程序输出
1 |
|
4、依然是程序判断题
1 |
|
5、让你写一个dumpEsception,来处理未被处理的promise和throw的异常
1 |
|
我查了查应该是这个事件是可以的吧,但是devtool不给我面子,跑不通。剩下的我记不得了。
6、读代码写结果,模仿babel将ES6的代码降级成ES5
1 |
|
7、url编码的处理
1 |
|
8、为什么要划分宏任务和微任务
回到问题本身,其实就是如何处理回调的问题。总结起来有三种方式:
- 使用同步回调,直到异步任务进行完,再进行后面的任务。
- 使用异步回调,将回调函数放在进行
宏任务队列
的队尾。 - 使用异步回调,将回调函数放到
当前宏任务中
的最后面。
因为同步的问题非常明显,会让整个脚本阻塞住,当前任务等待,后面的任务都无法得到执行,而这部分等待的时间是可以拿来完成其他事情的,导致CPU的利用率非常低,而且还有另一个致命的问题,就是无法实现延迟绑定的效果。
如果执行的回调的世纪应该是在前面所有的宏任务之前,倘若现在的任务队列非常长,那么回调迟迟得不到执行,造成应用卡顿。
为了解决上述方案的问题,另外也考虑到延迟绑定的需求,Promise采用第三种方式,即引入微任务,即把resolve(reject)回调的执行放在当前宏任务的末尾
。
这样,利用微任务解决了两大痛点:
- 采用异步回调替代同步回调解决了浪费CPU性能的问题
- 放到当前宏任务最后执行,解决了回调执行的实时性问题。
9、事件捕获和事件冒泡
事件冒泡:IE的事件流叫做事件冒泡,即事件开始时由具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点。(element(div)->element(body)->element(html)->document
事件捕获:Netscape Communicatior团队提出另一种事件流叫做事件捕获。事件捕获的思想是不太具体的节点应该更早的接收到事件,那么如果单机click,那么先触发的顺序会是(document->html->body-element)
DOM事件流:DOM2级事件流包含三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。首先发生的是事件捕获(document->element),为截获事件提供机会。然后是实际的目标接收到事件。最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应。
在DOM事件流中,实际的目标(<div>
元素)在捕获阶段
不会接收到事件。这意味着在捕获阶段,事件从document到<html>
再到<body>
后就停止了。下一阶段是处于目标
阶段,于是事件在<div>
上发生,并在事件处理(后面将会讨论这个概念)中被看成冒泡阶段的一部分。
多数支持DOM事件流的浏览器都实现了一种特定的行为;即使“DOM2级事件”规范种明确要求捕获阶段不会涉及事件目标,但IE9、Safari、Chrome、Firefox、Opera9.5及更高版本都会在捕获阶段触发事件对象上的事件。结果,就是有两个机会在目标对象上面操作事件。
1 |
|
10、回流和重绘
队列化修改并批量执行来优化重排过程。浏览器会将修改操作放入到队列里,直到过了一段时间或者操作达到了一个阈值,才清空队列。但是!当你获取布局信息的操作的时候,会强制队列刷新,比如当你访问以下属性或者使用以下方法:
- offsetTop、offsetLeft、offsetWidth、offsetHeight
- scrollTop、scrollLeft、scrollWidth、scrollHeight
- clientTop、clientLeft、clientWidth、clientHeight
- getComputedStyle()
- getBoundingClientRect
- 具体可以访问这个网站:gist.github.com/paulirish/5…
以上属性和方法都需要返回最新的布局信息,因此浏览器不得不清空队列,触发回流重绘来返回正确的值。因此,我们在修改样式的时候,最好避免使用上面列出的属性,他们都会刷新渲染队列。如果要使用它们,最好将值缓存起来。
原文链接:https://juejin.cn/post/6844903734951018504
11、强缓存和协商缓存
相关的header字段
expires:一个未来时间,代表请求有效期,没有过期之前都使用当前请求。
Pragma:Pragma是旧产物,已经逐渐抛弃,有些网站为了向下兼容,还保留了这两个字段。如果报文中同时出现Pragma和Cache-Control时,以Pragma为准。同时出现Cache-Control和Expires时,以Cache-Control为准。(优先级:Pragma->Cache-Control->Expires)
cache-control:
- 请求时候的Cache-Control时
字段名称 说明 no-cache 告知(代理)服务器不直接使用缓存,要求向原服务器发起请求 no-store 所有内容都不会被保存到缓存或者Internet临时文件中 max-age=delta-seconds 告知服务器客户端希望接收一个缓存时间(Age)不大于delta-seconds秒的资源,若没有则为任意超出的时间。 max-stale [=delta-seconds] 告知代理服务器客户端愿意接收一个超过缓存时间的资源,若有定义delta-seconds则为delta-seconds秒,若没有则为任意超出的时间。 no-transform 告知(代理服务器客户端希望获取实体数据没有被转换(比如压缩)过的资源) only-if-cached 告知(代理)服务器客户端希望获取缓存的内容(若有),而不用向原服务器去发请求 min-fresh=delta-seconds 告知(代理)服务器客户端希望接收一个在小于delta-seconds内被更新过的资源 cache-extension 自定义扩展值,若服务器不识别该值将被忽略掉 - 响应时候的Cache-Control时
字段名称 说明 public 表明任何情况下都得缓存该资源(即使是需要HTTP认证的资源) private [=”field-name”] 表明返回报文中全部或部分(若指定了field-name则为field-name的字段数据)仅开放给某些用户(服务器指定的share-user,如代理服务器)做缓存使用,其他用户则不能缓存这些数据 no-cache 不直接使用缓存,要求向服务器发起(新鲜度校验)请求 no-store 所有内容都不会被保存到缓存或Internet临时文件中 no-transform 告知客户端缓存文件时不得对实体数据做任何改变 only-if-cached 告知(代理)服务器客户端希望获取缓存的内容(若有),则不用向原服务器发去请求 must-revalidate 当前资源一定是向原服务器发去验证请求的,若请求失败会返回504(而非代理服务器上的缓存) proxy-revalidate 与must-revalidate类似,但仅能应用于共享缓存(如代理) max-age=delta-seconds 告知客户端资源在delta-secondsm秒内是新鲜的,无需向服务器发送请求 s-maxage=delta-seconds 同max-age,但仅应用于共享缓存(如代理) cache-extension 自定义扩展值,若服务器不识别该值将被忽略掉 可以多个值组合,但是no-store的优先级最高,本地不保存,每次都需要服务器发送资源。
public和private的选择。如果你使用了CDN,你需要关注一下这个值。CDN厂家一般会要求cache-control的值为public,提升缓存命中率。如果你的缓存命中率很低,而访问量很大的话,可以看下是不是设置了private,no-cache这类的值。如果定义了max-age,可以不用再定义public,他们的意义是一样的。
Last-Modified
在缓存中,我们需要一个机制来验证缓存是否有效。比如服务器的资源更新了,客户端要及时更新缓存;又或者客户端的资源过了有效期,但服务器上的资源还是旧的,此时并不需要重新发送。缓存校验就是用来解决这些问题的,在http1.1中,我们主要关注下Last-Modified和etag这两个字段。
服务端在返回资源时,会将该资源的最后更改时间通过
Last-Modified
字段返回给客户端。客户端下次请求时通过If-Modified-Since
或者If-Unmodified-Since
带上Last-Modified
,服务端检测该时间是否与服务器的最后修改时间一致:如果一致,则返回304状态码
,不返回资源;如果不一致则返回200和修改后的资源
,并带上新的时间.If-Modified-Since和If-Unmodified-Since的区别是:
If-Modified-Since:告诉服务器如果时间一致,返回状态码304
If-Unmodified-Since:告诉服务器如果时间不一致,返回状态码412etag
单纯的以修改时间来判断还是有缺陷,比如文件的最后修改时间变了,但内容没变.对于这样的情况,我们可以使用etag来处理.
etag的方式是这样的:服务器通过某个算法对资源进行计算,取得一串值(类似于文件的md5值),之后将该值通过etag返回给客户端,客户端下次请求时通过
If-None-Match
或者if-Match
带上该值,服务器对该值进行对比校验:如果一致则不要返回资源.If-None-Match和If-Match的区别是:
If-None-Match:告诉服务器如果一致,返回状态码304,不一致则返回资源
If-Match:告诉服务器如果不一致,返回状态码412
参考链接:https://blog.csdn.net/u012375924/article/details/82806617
12、手写订阅发布者模式
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!