睡前面经

81 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第26天,点击查看活动详情

1.线程和进程是什么?举例说明

进程:cpu分配资源的最小单位(是能拥有资源和独立运行的最小单位) 线程:是cpu最小的调度单位(线程是建立在进程的基础上的一次程序运行单位,一个进程中可以有多个线程) 栗子:比如进程=火车,线程就是车厢

一个进程内有多个线程,执行过程是多条线程共同完成的,线程是进程的部分。 一个火车可以有多个车厢 每个进程都有独立的代码和数据空间,程序之间切换会产生较大的开销;线程可以看作轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器,线程之间切换的开销小。 【多列火车比多个车厢更耗资源】 【一辆火车上的乘客很难换到另外一辆火车,比如站点换乘,但是同一辆火车上乘客很容易从A车厢换到B车厢】 同一进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的 【一辆火车上不同车厢的人可以共用各节车厢的洗手间,但是不是火车上的乘客无法使用别的火车上的洗手间】

为什么js是单线程 JS是单线程的原因主要和JS的用途有关,JS主要实现浏览器与用户的交互,以及操作DOM。 如果JS被设计为多线程,如果一个线程要修改一个DOM元素,另一个线程要删除这个DOM元素,这时浏览器就不知道该怎么办,为了避免复杂的情况产生,所以JS是单线程的。

为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。

  1. js中的基础数据类型有哪几种? 了解包装对象吗?

答:六种,string, number, boolean, undefiend, null, symbol 基础数据类型临时创建的临时对象,称为包装对象。其中 number、boolean 和 string 有包装对象,代码运行的过程中会找到对应的包装对象,然后包装对象把属性和方法给了基本类型,然后包装对象被系统进行销毁。

3.对内存泄漏的了解

  1. 理解
  • 定义:程序中已在堆中分配的内存,因为某种原因未释放或者无法释放的问题
  • 简单理解: 无用的内存还在占用,得不到释放和归还,比较严重的时候,无用的内存还会增加,从而导致整个系统卡顿,甚至崩溃。
  1. 生命周期

  2. 分配期 分配所需要的内存,在js中,是自动分配的

  3. 使用期 使用分配的内存,就是读写变量或者对象的属性值

  4. 释放期 不需要时将该内存释放,js会自动释放(除了闭包和一些bug以外) 内存泄漏就是出现在这个时期,内存没有被释放导致的

  5. 可能出现内存泄漏的原因

  6. 意外的全局变量

  7. DOM元素清空时,还存在引用

  8. 闭包

  9. 遗忘的定时器

如何优化内存泄漏?

全局变量先声明在使用 避免过多使用闭包。 注意清除定时器和事件监听器。 4.js中数组合并的方法 js 数组合并 let arr1 = ['温情', '刘聪'] let arr2 = ['杨和苏', '邓紫棋'] let arr3 = ['周延']

  1. arr1.concat(arr2, ······) es5 Array.concat() 合并两个数组, 返回新数组,不会改变原数组 arr = arr1.concat(arr2, arr3); console.log(arr); // ["温情", "刘聪", "杨和苏", "邓紫棋", "周延"]

  2. […arr1, …arr2,······] es6 展开运算符(…) arr = [...arr1, ...arr2, ...arr3]; console.log(arr); // ["温情", "刘聪", "杨和苏", "邓紫棋", "周延"]

  3. push(…arr) push 结合 ...[] 来实现, 会更改原数组 arr1.push(...arr2, ...arr3) console.log(arr1); // ["温情", "刘聪", "杨和苏", "邓紫棋", "周延"

适合两个数组,不适合多个数组的方法

  1. for + push for(let i in arr2) { arr1.push(arr2[i]) } console.log(arr1); // ["温情", "刘聪", "杨和苏", "邓紫棋"]

  2. arr1.push.apply(arr1, arr2) arr1.push.apply(arr1, arr2) console.log(arr1); // ["温情", "刘聪", "杨和苏", "邓紫棋"]

5.合并对象的方法 Object.assign() es6 Object.assign()方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target) Object.assign()方法的第一个参数是目标对象,后面的参数都是源对象。 let obj1 = {name: '温情'} let obj2 = {age: '22'}

const newObj = Object.assign({}, obj1, obj2); console.log(newObj); // {name: "温情", age: "22"}

!注意! Object.assign()实行的是浅拷贝,也就是说如果源对象的属性是一个对象,那么目标对象得到的是这个对象的引用

let obj1 = {name: {chinese: '杨和苏', english: 'keyNG'}} const newObj = Object.assign({}, obj1); console.log(newObj); // name: {chinese: "杨和苏", english: "keyNG"} obj1.name.english = 'pig'; console.log(newObj); // name: {chinese: "杨和苏", english: "pig"}

6.什么是作用域,什么是作用域链? 规定变量和函数的可使用范围称为作用域 查找变量或者函数时,需要从局部作用域到全局作用域依次查找,这些作用域的集合称作用域链。 7.JS如何实现异步编程(5种)?

1)回调函数(callback) 优点:解决了同步的问题(只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。) 缺点:回调地狱,每个任务只能指定一个回调函数,不能 return.

2)事件监听。这种思路是说异步任务的执行不取决于代码的顺序,而取决于某个事件是否发生。比如一个我们注册一个按钮的点击事件或者注册一个自定义事件,然后通过点击或者trigger的方式触发这个事件。

3)Promise

4)Generator

5)生成器 async/await,是ES7提供的一种解决方案。