关于javascript:前端面试面试题梳理总结持续更新

39次阅读

共计 4809 个字符,预计需要花费 13 分钟才能阅读完成。

面试血泪史

不要问我面的是不是架构师。我只是面的低级前端。总结不易点个赞吧。

JS

1. 包装类跟一般类有什么区别?new String() 和 String()的区别

答::js 提供了 3 个包装类 别离是 new String()new Number()new Boolean()。因为根底类型不能增加属性和办法,js 的包装类的作用是将根底类型包装成一个对象,这样就能够有属性和办法。

tips: 当咱们对一些根本数据类型的值去调用属性和办法时,浏览器会长期应用包装类将其转换为 对象,而后在调用对象的属性和办法;调用完当前,在将其转换为根本数据类型。

2. promise.then 是怎么实现链式调用的

:通过从新 return 一个 new Promise 来实现链式调用

3. 多调用几次 bind 比方 bind a bind b 最初 this 指向谁 为啥

答: 永远指向第一次调用 bind 时传入的上下文,因为 bind 之后的调用都是绑定在这个上下文上。

4. v8 引擎回收机制简述

答: v8 垃圾回收次要通过两个策略:

  • 标记革除
  • 援用计数

    标记革除 是 js 最罕用的垃圾回收机制。垃圾回收程序运行的时候,会标记内存中存储的所有变量。而后,它会将所有在上下文中的变量,以及被在上下文中的变量援用的变量的标记去掉。在此之后再被加上标记的变量就是待删除的了,起因是任何在上下文中的变量都拜访不到它们了。随后垃圾回收程序做一次内存清理,销毁带标记的所有值并发出它们的内存。

    援用计数 是对每个值都记录它被援用的次数。申明变量并给它赋一个援用值时,这个值的援用数为 1。如果同一个值又被赋给另一个变量,那么援用数加 1。相似地,如果保留对该值援用的变量被其余值给笼罩了,那么援用数减 1。当一个值的援用数为 0 时,就阐明没方法再拜访到这个值了,因而能够平安地发出其内存了。垃圾回收程序下次运行的时候就会开释援用数为 0 的值的内存。(以上摘自 js 红宝书第四版)

5. v8 回收算法运行时会阻塞 js 吗?为什么

答: 会阻塞。

6. 怎么优化垃圾回收机制

答: https://www.cnblogs.com/cheng… 总结就是多用新生代算法

7. 作用域链简述。怎么能获取函数外部变量?

答: 作用域链就是变量向上查找过程。能够通过函数外部 return 一个携带函数外部变量的闭包使得内部能够拜访函数外部的变量

8. 闭包简述,怎么防止内存透露

答: 无论何时申明新函数并将其赋值给变量,都要存储函数定义和闭包,闭包蕴含在函数创立时作用域中的所有变量,相似于背包,函数定义附带一个小背包,他的包中存储了函数创立时作用域中的所有变量。及时将指针指向 null 能够防止内存透露。

9. class 类能够枚举吗?类 instanceof Function 输入什么?

答: 类的外部所有定义的办法,都是不可枚举的 类的数据类型就是函数,类自身就指向构造函数。代码如下:

class Point {constructor(x, y) {// ...}

  toString() {// ...}
}

Object.keys(Point.prototype)
// []
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]
class Fn{}
Fn instanceof Function // true

const a = new Fn()
a instanceof Function // false

webpack

1. webpack 是怎么实现分模块打包的?

答: 能够通过splitChunks 实现。

webpack 中以下三种常见的代码宰割形式:

  • 入口终点:应用 entry 配置手动地拆散代码。
  • 动静导入:通过模块的内联函数调用来拆散代码。
  • 避免反复:应用 splitChunks 去重和拆散 chunk。第一种形式,很简略,只须要在 entry 里配置多个入口即可。

splitChunks 代码拆分

splitChunks: {
    // 示意抉择哪些 chunks 进行宰割,可选值有:async,initial 和 all
    chunks: "async",
    // 示意新拆散出的 chunk 必须大于等于 minSize,默认为 30000,约 30kb。minSize: 30000,
    // 示意一个模块至多应被 minChunks 个 chunk 所蕴含能力宰割。默认为 1。minChunks: 1,
    // 示意按需加载文件时,并行申请的最大数目。默认为 5。maxAsyncRequests: 5,
    // 示意加载入口文件时,并行申请的最大数目。默认为 3。maxInitialRequests: 3,
    // 示意拆分出的 chunk 的名称连接符。默认为~。如 chunk~vendors.js
    automaticNameDelimiter: '~',
    // 设置 chunk 的文件名。默认为 true。当为 true 时,splitChunks 基于 chunk 和 cacheGroups 的 key 主动命名。name: true,
    // cacheGroups 下能够能够配置多个组,每个组依据 test 设置条件,合乎 test 条件的模块,就调配到该组。// 模块能够被多个组援用,但最终会依据 priority 来决定打包到哪个组中。默认将所有来自 
    // node_modules 目录的模块打包至 vendors 组,将两个以上的 chunk 所共享的模块打包至 default 组。cacheGroups: {
        vendors: {test: /[\\/]node_modules[\\/]/,
            priority: -10 // 缓存组优先级
        },
        // 
    default: {
            minChunks: 2,
            priority: -20,
            reuseExistingChunk: true  // 可设置是否重用该 chunk
        }
    }
}

通过 cacheGroups,咱们能够定义自定义 chunk 组,通过 test 条件对模块进行过滤,符合条件的模块调配到雷同的组。

2. webpack4 的 tree-shaking 是什么?怎么实现的?在什么状况下会生效?为什么?

答: tree-shaking 实质是 webpack 打包时用来舍弃无用的代码。

工作原理: 在 ES6 以前,咱们能够应用 CommonJS 引入模块:require(),这种引入是动静的,也意味着咱们能够基于条件来导入须要的代码

let module
if(true){module = require('a')
}else{module = require('b')
}

CommonJS标准无奈确定在理论运行前须要或者不须要某些模块,所以 CommonJS不适宜 tree-shaking 机制

ES6 的 import 语法能够完满应用 tree shaking,因为能够在代码不运行的状况下就能剖析出不须要的代码。

因为 tree shaking 只能在动态 modules 下工作。ECMAScript 6 模块加载是动态的, 因而整个依赖树能够被动态地推导出解析语法树。

side effects是指那些当 import 的时候会执行一些动作,然而不肯定会有任何 export

tree shaking 不能主动的辨认哪些代码属于side effects,因而手动指定这些代码显得十分重要。如果所有代码都不蕴含副作用,咱们就能够简略地将该属性标记为 false,来告知 webpack,它能够平安地删除未用到的 export 导出。

总结: ES6 Module 引入进行动态剖析,故而编译的时候正确判断到底加载了那些模块。再判断那些模块和变量未被应用或者援用,进而删除对应代码。

另外,webpack 中能够在我的项目 package.json 文件中,增加一个“sideEffects”属性, 手动指定由副作用的脚本。

3. env 晓得吗?是用来干什么的?我的项目须要独自装置吗?为什么?

env 是 nodejs 里内置的一个对象,能够利用 process.env 拿到以后我的项目运行环境的信息。不须要独立装置,因为是 nodejs 的内置对象。

4. import 和 require 的区别

答:

  1. CommonJS 模块输入的是一个值的拷贝,ES6 模块输入的是值的援用。
  2. CommonJS 模块是运行时加载,ES6 模块是编译时输入接口。
  3. CommonJs 是单个值导出,ES6 Module 能够导出多个
  4. CommonJs 是动静语法能够写在判断里,ES6 Module 动态语法只能写在顶层
  5. CommonJs 的 this 是以后模块,ES6 Module 的 this 是 undefined

5. 晓得什么是动态剖析吗?

答: es modules 能够在代码不运行的状况下对代码进行剖析,能够晓得哪些模块有没有被应用。

6. webpack babel 是如何工作的?

答:

    1. 词法解析。将字符串模式的代码转换为 Tokens(令牌),Tokens 能够视作是一些语法片段组成的数组。
    1. 语法解析。把 Tokens 转换为形象语法树 AST
    1. 转换阶段。会对 AST 进行遍历,在这个过程中对节点进行增删查改。Babel 所有插件都是在这个阶段工作, 比方语法转换、代码压缩。
    1. 输入阶段 。将通过转换的 AST 通过 babel-generator 再转换成 js 代码,过程就是深度优先遍历整个 AST,而后构建能够示意转换后代码的字符串。 同时这个阶段还会生成 Source Map

7. webpack plugins 的执行机会?

答: 加载文件实现后,输入文件前,不同的 plugins 有不同的执行机会。

node

1. koa 源码理解过,是怎么实现的?

答: koa 通过对 http 模块的封装,在外部实现了一个 context 上下文的概念,把 res 跟 req 都放在 ctx 下面,并且对 req 和 res 进行优雅的 setter/getter 解决,调用形式更简略。

洋葱模型通过将中间件数组里的异步办法通过 dispatch 去递归调用,因为在 app.use 中去调用 next 办法时去调用下一个中间件。

洋葱模型实现伪代码

function compose(middlewares){return function(){return dispatch(0)
        function dispatch(i){let fn = middlewares[i]
            if(!fn) return Promise.resolve()
            return Promise.resolve(fn(function next(){
                // promise 实现之后在执行下一个
                return dispatch(i+1)
            }))
        }
    }
}

2. koa 洋葱模型

答: 见上

http

1. http 和 https 的区别

答: HTTPS 就是将 HTTP 运行在 TLS/SSL 的加密安全措施下。

  • https 须要申请 CA 证书
  • https 更平安。使用了加密伎俩
  • https 端口 443 http 是 80

2. udp 和 tcp 的区别

答: 见我的另一篇文章 TCP/IP

3. http3.0 是基于 udp 的,为什么 udp 面向无连贯还会抉择 udp?

答: 因为 udp 高效。而且在应用层解决了 udp 的不可靠性问题。

4. http3.0 怎么解决 udp 的丢包问题?

答: http3 不仅仅只是简略将传输协定替换成了 UDP。还基于 UDP 协定在「应用层」实现了 QUIC 协定。它具备相似 TCP 的连贯治理、拥塞窗口、流量管制的网络个性,相当于将不牢靠传输的 UDP 协定变成“牢靠”的了,所以不必放心数据包失落的问题。而且,QUIC 协定会保障数据包的可靠性,每个数据包都有一个序号惟一标识。当某个流中的一个数据包失落了,即便该流的其余数据包达到了,数据也无奈被 HTTP/3 读取,直到 QUIC 重传失落的报文,数据才会交给 HTTP/3。

5. tcp 除了你刚刚说的窗口管制,还有哪些管制?

答: 重发管制,流控制,拥塞管制

6. tcp 重发机制是基于哪个工夫节点

答: 引入两个概念:

  • RTT(Round Trip Time):往返时延,也就是数据包从收回去到收到对应 ACK 的工夫。RTT 是针对连贯的,每一个连贯都有各自独立的 RTT。
  • RTO(Retransmission Time Out):重传超时,也就是后面说的超时工夫。

我个别认为是两倍的 RTT。

正文完
 0