Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

笔试面试题 #4

Open
hujiejeff opened this issue Jul 7, 2020 · 9 comments
Open

笔试面试题 #4

hujiejeff opened this issue Jul 7, 2020 · 9 comments

Comments

@hujiejeff
Copy link
Owner

No description provided.

@hujiejeff
Copy link
Owner Author

hujiejeff commented Jul 7, 2020

简述XMLHttpRequest和JSONP应用场景、以及二者的错误检测?

  1. XMLHttpRequest用于浏览器端与服务器端异步请求数据从面实现对页面的无刷新修改,支持GET/POST请求,一般用于非跨域的场景。如果需要使用XMLHttpRequest跨域请求数据,需要通过CORS头支持。 JSONP用于跨域请求数据的场景,只支持GET请求。
  2. XMLHttpRequest异常判断一般通过该对象的readystate和http状态码status来判断,JSONP的异常判断一般是onerror事件和超时timer来判断。

@hujiejeff
Copy link
Owner Author

hujiejeff commented Jul 7, 2020

请简述下浏览器渲染过程、以及重绘和重排?

理解浏览器渲染机制

浏览器渲染过程因不同内核可能会有差异,现以webkit为例描述浏览器渲染原理,浏览器渲染过程主要分为三个阶段,先详述如下:
第一阶段:

  1. 用户输入URL时,webkit依赖网络模块加载网页或资源数据
  2. 网页被交给HTML解释器转变成一系列的词语
  3. 解释器根据词语构建节点并形成DOM树
  4. 如果节点是CSS、图片、视频等资源,会调用资源加载器加载他们,因该类资源加载是异步的,不会阻塞当前DOM树的继续创建
  5. 如果节点是javascript,停止当前DOM树的创建,直到javascript资源加载完成并被javascript引擎执行后才继续进行DOM的创建
    第二阶段:
  6. CSS解释器解析CSS文件成内部表示结构,并在DOM树上附加样式信息形成RenderObject树
  7. RenderObject节点在创建的同时,webkit会根据网页的层次结构创建RenderLayer树,同时创建一个虚拟的绘图上下文
    第三阶段:
    1.根据生成的绘图上下文和2D或3D图形库生成最终的图像
    对于包含动画和用户交互的动态网页,浏览器的渲染过程会重复的执行,可能会触发不同程度的重排和重绘。

重绘:节点属性发生变化、内容需要变更、比如颜色,就是重新绘制。
重排:节点的尺寸相关信息发生变化、影响到盒子大小、所以要重排,也就是重新布局。

重排属性:height、line-height、font-size、border
重绘属性:height、line-height、font-size 、border、background-color、visibility

最小化重排和重绘

使用documentFragment进行dom操作

const list = document.querySelector('#list');
const fruits = ['Apple', 'Orange', 'Banana', 'Melon'];

const fragment = document.createDocumentFragment();

fruits.forEach(fruit => {
  const li = document.createElement('li');
  li.innerHTML = fruit;
  fragment.appendChild(li);
});

list.appendChild(fragment);

@hujiejeff hujiejeff changed the title 笔试面试题 # 笔试面试题 Jul 7, 2020
@hujiejeff hujiejeff changed the title # 笔试面试题 笔试面试题 Jul 7, 2020
@hujiejeff
Copy link
Owner Author

hujiejeff commented Jul 7, 2020

<script>和<script defer>以及<script async> 不同之处

1、【普通加载+普通执行】普通的<script>,会阻塞html的解析,直到js处理完,恢复html的解析
2、【延迟执行】defer,不会阻塞html的解析,并行加载,执行会延迟到html解析完毕,而且加载的js会顺序加载
3、【异步加载】async,异步加载js,而且无顺序,加载完毕,阻塞html开始执行。

@hujiejeff
Copy link
Owner Author

hujiejeff commented Jul 7, 2020

JavaScript并发模型和事件循环是怎样的?

what

经常听说js执行时单线程,其实也没错,只是不够完全。
浏览器运行html过程存在以下几个线程:
1、 JS引擎线程,直接执行我们代码的线程,也就是大家感知的那个单线程
2、事件触发线程,维持一个线程用于触发事件,并且添加到事件队列,供JS引擎线程调用
3、定时器触发线程,同上,触发定时,送入事件队列,供JS引擎调用
4、异步HTTP请求线程
5、渲染线程,用于渲染页面,和JS引擎互斥,因为二者都会涉及UI。

JS引擎线程

首先包含着以下几个东西:

  • 执行栈 ,存放着栈帧
  • 堆,存放着对象
  • 事件队列,也可以称为消息队列
    偷张MDN的形象看下

并发模型和事件循环
执行栈中存放着栈帧,每个栈帧的入栈出栈对应着函数的调用执行过程,通俗的说执行的也就是我们书写的同步代码。

执行栈中执行完了同步代码之后回去检查事件队列,不断的从事件队列中拿去“消息”,也就是我们之前设置回调函数,拿去到放在执行栈执行。

@hujiejeff
Copy link
Owner Author

hujiejeff commented Jul 7, 2020

关于BFC有了解吗?

what

Block Format Contex:块格式化上下文。通俗的来说是一个封闭的盒子,里面的元素不会影响到外部。

how

满足以下特性,即是要给BFC块
根元素(<html>)
浮动元素(元素的 float 不是 none)
绝对定位元素(元素的 position 为 absolute 或 fixed)
行内块元素(元素的 display 为 inline-block)
表格单元格(元素的 display为 table-cell,HTML表格单元格默认为该值)
表格标题(元素的 display 为 table-caption,HTML表格标题默认为该值)
匿名表格单元格元素(元素的 display为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是HTML table、row、tbody、thead、tfoot的默认属性)或 inline-table)
overflow 值不为 visible 的块元素
display 值为 flow-root 的元素
contain 值为 layout、content或 paint 的元素
弹性元素(display为 flex 或 inline-flex元素的直接子元素)
网格元素(display为 grid 或 inline-grid 元素的直接子元素)
多列容器(元素的 column-count 或 column-width 不为 auto,包括 column-count 为 1)
column-span 为 all 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug)。

why

1、通常两个块之间会发生外边距塌陷,以及父和子元素的maring也会重叠,切换成BFC块之间则不会塌陷。
2、帮助清除浮动,即可以实现:

  • 防止被浮动元素覆盖
  • 包含浮动元素

@hujiejeff
Copy link
Owner Author

hujiejeff commented Jul 10, 2020

关于缓存的问题?

按照缓存位置区分

Service Worker缓存

待补充

Memory Cache

基于内存的缓存,这个更多的控制是交由了浏览器,短时间有相同的请求,启动内存缓存。

Disk Cache也即Http Cache

这个则是我们经常见到的,通过设置头读取头来判定哪些资源的缓存是否命中

按照缓存策略区分

强缓存

what
强缓存是一个比较强制的策略,命中即不会发送请求,优化直接减少了请求数。

how
影响强缓存策略的头是Cache-ControlExpires
Cache-Control取值

  • no-store:不缓存
  • no-cache:缓存但重新验证
  • private : 缓存私有,中间人不得缓存
  • public: 缓存共有,中间人可以缓存
  • max-age=31536000:设置过期时间,这里指的是请求发起后维持的秒数
  • must-revalidate:重新验证

Expires这个头则是比http1.0的头,设置一个绝对的过期时间,由于c端可能和s时间不同步,或者本地时间修改原因,命中不准确。导致缓存失效

协商缓存

协商缓存顾名思义,回去和服务端询问一下,我这个资源新不新鲜,新鲜的话返回304使用缓存,不新鲜就返回200拉取新的资源并设置缓存。当然也就会发起一个http的请求。
how

  • Last-Modified & If-Modified-Since 方式
    服务器响应设置Last-Modified,最后修改时间,客户端接收并且存入数据库,下次请求中,找出不确定是否过期的缓存,设置请求头 If-Modified-Since为之前存入的时间,服务端通过比对这个If-Modified-Since和之前的`Last-Modified进行比较来判定缓存是否命中,命中则放回304响应,客户端使用缓存,否则返回200,拿取最新数据。

  • Etag & If-None-Match
    Etag是服务端对于资源的一个唯一版本标志,通过hash等实现。服务端会存储文件的唯一Etag。流程和和上述类似,进行比对资源标志来判定缓存是否命中。

最佳实践

对于强缓存来说,即使设置了过期时间,但是如果在这个过期时间内服务端的资源发生变化,而仅仅通过强缓存命中的策略是不会发送请求,这样就客户端获取到的数据不是最新,甚至导致不可预期的错误。

而协商缓存来说是会进行http请求来,那不还是没有减少http请求。

所以综合解决策略是:html进行协商缓存,其它的js,css,img资源使用强缓存。同时通过webpack打包是配置其它资源的文件名使用hash变化。

@hujiejeff
Copy link
Owner Author

hujiejeff commented Jul 11, 2020

词法作用域和动态的作用域的区别?

作用域是定义一套标识符的查找规则,用于在某个区域查找标识符

词法作用域

在js中的作用域是采用的词法作用域,也即静态作用域。作用域的形成是在定义期间完成的,也即定义完成编译器进行扫描,构建作用域。比如函数定义内容访问外部作用域变量。

动态作用域

与之静态相对的是动态作用域,动态的作用域是在函数调用的时候决定的,比如在调用某个函数时,函数内部访问正在调用作用域变量。js中this查找在一定程度上类似于动态作用域的实现。

@hujiejeff
Copy link
Owner Author

hujiejeff commented Jul 11, 2020

MVVM理解、以及Vue中MVVM

MVVM

首先MVVM是架构分为三层,视图层、模型层、视图模型层。视图层是负责视图渲染、模型层负责数据获取和存储。视图模型层负责连接视图层和模型层,将业务数据映射尾视图数据,从而驱动视图层的修改。数据流的走向是:视图层->视图模型层->模型层。整个阶段视图不会和模型打交道。视图层调用视图模型层进行数据行为变更。视图模型层通过数据变化,影响视图。即数据驱动视图,这是一个观察者模式实现完成双向绑定。即视图调用视图模型业务,视图模型数据变更驱动视图变更。

Vue中的MVVM

首先template自然是我们的视图层,然后Vue的组件就是我们的ViewModel。模型层则是我我们Vue组件的data和prop的数据来源,简单情况下可以简单数据对象,或者自定义一个数据源对象和操作封装成模型,也可以封装到vuex中

@hujiejeff
Copy link
Owner Author

hujiejeff commented Jul 17, 2020

两个tab页面如何通信

1、websocket

2、监听localStorage

3、共享的webworker

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant