41

前端面试基础问题梳理

 4 years ago
source link: https://blog.callmewhy.com/post/qian-duan-mian-shi-ji-chu-wen-ti-shu-li/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

HTML

Web Worker 特点

  • 同源限制:Worker 线程的脚本文件必须和主线程脚本文件同源
  • DOM 限制,无法获取 document window ,可以获取 navigator 和 location
  • 通信限制:无法与主线程直接通信,必须通过消息完成
  • 脚本限制:无法执行 alert confirm 函数,但是可以发送 ajax 请求
  • 文件限制:无法读取本地文件,脚本来源自网络
  • 应用场景:后台轮询

事件处理

事件开始是由最具体的元素(目标元素)接收,然后逐级向上传播到较为不具体的节点(文档)

CSS

几种布局

  • 正常布局流,display 属性为 block inline inline-block 这些标准属性,是浏览器默认的HTML布局方式
  • table 布局,优点是兼容性好,缺点是需要等内容全部加载完才可以展示
  • 浮动布局,通过 float 属性,例如 float: left 可以让块级元素并排而不是堆叠
  • position 属性布局
    • 静态定位 static:默认属性
    • 相对定位 relative:允许元素的相对移动
    • 静态定位 absolute:相对第一个非 static 的父类元素定位
    • 固定定位 fixed:相对浏览器视图固定
  • CSS Grid,display 属性为 grid,兼容性差
  • Flexbox,display 属性为 flex

盒模型

  • content、padding、border、border
  • 标准盒模型(content-box)的宽高就是 content 的宽高,IE 盒模型(border-box)的宽高是 content+padding+border 宽高的总和

选择器及其优先级

  • !important
  • 内联样式 style=""
  • ID 选择器 #id
  • 类选择器/属性选择器/伪类选择器
  • 元素选择器/关系选择器/伪元素选择器
  • 通配符选择器

BFC

BFC(Block Formatting Context),格式化上下文,是 Web 页面中盒模型布局的 CSS 渲染模式,指一个独立的渲染区域或者说是一个隔离的独立容器。

  • 内部的 Box 会在垂直方向上一个接一个地放置,垂直方向的距离由 margin 决定
  • 属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠
  • 每个元素的 margin box 的左边, 与包含块 border box 的左边相接触。即使存在浮动也是如此
  • BFC 的区域不会与 float 的元素区域重叠
  • 计算 BFC 的高度时,浮动子元素也参与计算
  • BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素

伪类和伪元素

伪类(一个冒号)

  • 获取不存在与DOM树中的信息。比如a标签的:link、visited等,这些信息不存在与DOM树结构中,只能通过CSS选择器来获取;
  • 获取不能被常规CSS选择器获取的信息。比如:要获取第一个子元素,我们无法用常规的CSS选择器获取,但可以通过 :first-child 来获取到。

伪元素(两个冒号,CSS3 中区分开)

  • 伪元素用于创建一些不在文档树中的元素,并为其添加样式。比如说,我们可以通过:before来在一个元素前增加一些文本,并为这些文本添加样式。虽然用户可以看到这些文本,但是这些文本实际上不在文档树中。常见的伪元素有 ::before、::after 等

JavaScript

7 种数据类型

  • Undefined
  • Null
  • Boolean
  • String
  • Number
  • Symbol
  • Object

原型对象

每个函数都会有一个 prototye 属性指向函数的原型对象,每个原型对象都会获取一个 constructor 属性指向构造函数,即:Function.prototype.constructor == Function

new 运算符的原理

__proto__
var myNew = function (func) {
    var o = Object.create(func.prototype)
    var i = func.call(o)
    return typeof i === 'object' ? i : o
}

判断数据类型的方法

  • typeof:JS 在底层存储变量的时候,会在变量的机器码的低位 1-3 位存储其类型信息,number(010), string(100), object(000), boolean(110), undefined(-2^30),null :所有机器码为0
    • 优点:能够快速区分基本数据类型,number, string, object, boolean, function, undefined, symbol
    • 缺点:不能将 Object、Array 和 Null 区分,都返回 object
  • instanceof:判断一个实例是否属于某种类型,检查左边实例的 __proto__ 和右边类的 prototype 是否在同一条原型链上
    • 优点:可以用来判断类型的具体类型
    • 缺点:Number,Boolean,String 基本数据类型不能判断
  • Object.prototype.toString.call 准确判断对象实例的类型

call、apply 和 bind 区别

三个函数的作用都是将函数绑定到上下文中,用来改变函数中 this 的指向

// call 方法接受的是若干个参数列表
fun.call(thisArg[, arg1[, arg2[, ...]]])
// apply 接收的是一个包含多个参数的数组
fun.apply(thisArg, [argsArray])
// bind 会创建一个新的函数
var bindFn = fun.bind(thisArg[, arg1[, arg2[, ...]]])
bindFn()

防抖(Debouncing)和节流(Throttling)

  • 防抖(Debouncing):将触发频繁的事件合并成一次执行。适用场景: input 实时反馈、scroll 事件优化。
  • 节流(Throttling): 设置一个阀值,在阀值内,将触发的事件合并成一次执行,且当到达阀值,必定执行一次事件。防止浏览器频繁响应事件,严重拉低性能。适用场景:resize 事件、鼠标移动事件

HTTP

HTTPS 的工作原理

  • 客户使用https url访问服务器,则要求web服务器建立ssl链接
  • web服务器接收到客户端的请求之后,会将网站的证书(证书数中包含了公钥),传给客户端。
  • 客户端和web服务器开始协商ssl链接的安全等级
  • 客户端浏览器通过双方协商一致的安全等级,建立会话密钥,然后通过网站的公钥来加密会话密钥,并传送给网站。
  • web服务器通过自己的私钥解密出会话密钥
  • web服务器通过会话密钥加密与客户端之间的通信。

HTTP 报文组成部分

请求报文:请求行、请求头、空行、请求体

响应报文:状态行、响应头、空行、响应体

浏览器

浏览器渲染机制

  • 构建DOM树(parse):渲染引擎解析HTML文档,首先将标签转换成DOM树中的DOM node
  • 构建渲染树(construct):解析对应的CSS样式文件信息
  • 布局渲染树(reflow/layout):从根节点递归调用,计算每一个元素的大小、位置等,给出每个节点所应该在屏幕上出现的精确坐标;
  • 绘制渲染树(paint/repaint):遍历渲染树,使用UI后端层来绘制每个节点。

重绘(repaint)和重排(reflow)

  • 重绘:一个元素外观的改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制。重绘发生在元素的可见的外观被改变,但并没有影响到布局的时候。比如,仅修改 DOM 元素的字体颜色(只有Repaint,因为不需要调整布局)
  • 重排:当渲染树中的部分因为元素的规模尺寸,布局,隐藏等改变而需要重新构建, 这就称为重排。每个页面至少需要一次重拍,就是在页面第一次加载的时候。触发条件:
    • 页面渲染初始化(无法避免)
    • 添加或删除可见的 DOM 元素
    • 元素位置的改变
    • 元素尺寸的改变(大小,外边距,边框)
    • 浏览器窗口尺寸的变化
    • 填充内容的改变,比如文本的改变或图片大小改变而引起的计算值宽度和高度的改变

重排必定会引发重绘,但重绘不一定会引发重排。

几个常见线程

  • GUI 渲染线程:负责解析HTML,CSS,构建DOM树,布局和绘制,与 JS 引擎线程互斥
  • JS 引擎线程:负责处理 JavaScript 脚本,当 JS 引擎执行 JS 代码时间过长时会造成页面的阻塞,也就是为什么我们要把 script 标签在 body 的最后面引入
  • 定时器触发线程:负责执行定时器一类函数的进程,如 setTimeout、setInterval。主线程执行代码遇到计时器时,会将计时器交给该线程处理,当计时完毕之后,定时器线程会将计时完毕后的事件加入到事件队列的尾部,等待 JS 引擎线程的执行
  • 事件触发线程:主要负责将准备好执行的事件交给 JS 引擎线程执行,如计时器计时完毕后的事件,AJAX 请求成功返回并触发的回调函数和用户触发点击事件时,事件触发线程会将回调函数加入到任务队列的尾部,等待 JS 引擎线程的执行
  • 异步 HTTP 请求线程:当主线程依次执行代码时,遇到异步请求,会将函数交给改线程处理,当监听状态码变更时,如果有回调函数,会将回调函数加入到任务队列的尾部,等待 JS 引擎线程的执行

Event Loop

主线程从任务队列中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop。

异步任务的执行顺序准确的划分方式是:

  • 宏任务(macro-task):包括整体代码 script,setTimeout,setInterval
  • 微任务(micro-task):Promise,process.nextTick

其他

安全概念

  • CSRF:跨站请求伪造,挟持用户在当前已登录的 Web 应用程序上执行非本意的操作
    • 防御措施:Token 验证和 Referer 验证
  • XSS:跨域脚本攻击,将攻击脚本提交到服务器,服务器解析时执行
    • 防范措施:cookie 设置 httpOnly 防止读取和篡改,对服务端请求做过滤

页面优化方案

  • 请求优化
    • 资源压缩合并,减少 HTTP 请求
    • 非核心代码异步加载
    • script 标签使用 defer 属性:HTML 解析后执行,多个任务按顺序执行
    • script 标签使用 async 属性:加载后立即执行,多个任务执行顺序与加载顺序无关
    • 利用浏览器缓存资源
    • 使用 CDN
    • 预解析 DNS
  • 资源优化
    • 雪碧图
    • 图片懒加载,用 data-src 存储图片地址,初始化的时候图片无内容,监听 scroll 事件,执行防抖函数滞后执行避免掉帧,通过 getBoundingClientRect 判断图片是否出现在屏幕中,在展示的时候再加载图片。
  • 前端优化
    • 减少 DOM 操作

参考资料


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK