Skip to content

Latest commit

 

History

History
321 lines (188 loc) · 19.7 KB

面试总结2022.md

File metadata and controls

321 lines (188 loc) · 19.7 KB

vue数据双向绑定的原理?

Vue数据双向绑定原理是通过数据劫持结合“发布者-订阅者”模式的方式来实现的,首先是对数据进行监听,然后当监听的属性发生变化时则告诉订阅者是否要更新,若更新就会执行对应的更新函数从而更新视图。

vue Object.defineProperty和Proxy的区别?

  • Proxy可以直接监听整个对象而非属性。
  • Proxy可以直接监听数组的变化。
  • Proxy有13种拦截方法,如ownKeys、deleteProperty、has 等是 Object.defineProperty 不具备的。
  • Proxy返回的是一个新对象,我们可以只操作新的对象达到目的,而Object.defineProperty只能遍历对象属性直接修改;
  • Proxy做为新标准将受到浏览器产商重点持续的性能优化,也就是传说中的新标准的性能红利。

Object.defineProperty 的优势如下

  • 兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平。

Object.defineProperty 不足在于

  • Object.defineProperty 只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历。
  • Object.defineProperty不能监听数组。是通过重写数组的那7个可以改变数据的方法来对数组进行监听的。
  • Object.defineProperty 也不能对 es6 新产生的 Map,Set 这些数据结构做出监听。
  • Object.defineProperty也不能监听新增和删除操作,通过 Vue.set()Vue.delete来实现响应式的。

js如何创建线程?

其实JS为我们提供了一个Worker的类,它的作用就是为了解决这种阻塞的现象(JS作为脚本语言,它的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。但是单线程的语言,有一个很致命的确定。如果说一个脚本语言在执行时,其中某一块的功能在执行时耗费了大量的时间,那么就会造成阻塞。这样的项目,用户体验是非常差的,所以这种现象在项目的开发过程中是不允许存在的)。当我们使用这个类的时候,它就会向浏览器申请一个新的线程。这个线程就用来单独执行一个js文件。

var worker = new Worker(js文件路径);

那么这个语句就会申请一个线程用来执行这个js文件。

当然,在主线程中有一些方法来实现对新线程的控制和数据的接收。在这里,我们只说比较常用的几个方法。

 1 //postMessage(msg);
 2 //postMessage方法把在新线程执行的结果发送到浏览器的js引擎线程里
 3 worker.onmessage = function(){
 4     //获取在新线程中执行的js文件发送的数据 用event.data接收数据
 5     console.log( event.data )
 6 };
 7 setTimeout( function(){
 8     worker.terminate();
 9     //terminate方法用于关闭worker线程
10 },2000)
11     
12 setTimeout( function(){
13     worker = new Worker("js/test22.js");
14     //再次开启worker线程
15 },3000)

在新线程中使用postMessage()方法可以向主线程中发送一些数据,主线程中使用worker的onmessage事件来接收这些数据,这样就实现了js的多线程执行和多线程之间数据的传递。

js如何实现动画?

1、是通过JS控制CSS属性变化实现动画;

2、是通过JS控制类的添加或删除来实现动画(animation.css库)。

3、requestAnimationFrame

用js来实现动画,我们一般是借助setTimeout或setInterval这两个函数,css3动画出来后,我们又可以使用css3来实现动画了,而且性能和流畅度也得到了很大的提升。但是css3动画还是有不少局限性,比如不是所有属性都能参与动画、动画缓动效果太少、无法完全控制动画过程等等。所以有的时候我们还是不得不使用setTimeout或setInterval的方式来实现动画,可是setTimeout和setInterval有着严重的性能问题,虽然某些现代浏览器对这两函个数进行了一些优化,但还是无法跟css3的动画性能相提并论。这个时候,就该requestAnimationFrame出马了。

requestAnimationFrame 是专门为实现高性能的帧动画而设计的一个API,目前已在多个浏览器得到了支持,包括IE10+,Firefox,Chrome,Safari,Opera等,在移动设备上,ios6以上版本以及IE mobile 10以上也支持requestAnimationFrame,唯一比较遗憾的是目前安卓上的原生浏览器并不支持requestAnimationFrame,不过对requestAnimationFrame的支持应该是大势所趋了,安卓版本的chrome 16+也是支持requestAnimationFrame的。

requestAnimationFrame 比起 setTimeout、setInterval的优势主要有两点:

1、requestAnimationFrame 会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。 2、在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的的cpu,gpu和内存使用量。

操作系统原理?

操作系统是管理电子设备中的硬件和软件资源,然后控制设备上的程序去运行,并且提供一个可以让用户操作的交互的界面。它可以看做是系统软件的集合,会决定资源的优先次序,以及控制输入和输出的设备,并且完成管理文件以及操作网络等等任务,它是非常庞大复杂的。

操作系统的主要功能是什么

1、管理处理器。计算机中最重要的部件之一就是处理器,操作系统会对处理器进行管理和控制,让它进行处理工作,并且会设定处理的先后顺序。

2、管理存储。操作系统还会对内存进行管理比如说内存的分配、保护、共享等等,它会将内存分配到各个程序当中,确保它们能够顺利的运行。

3、管理设备。操作系统还会对各种设备进行管理,比如输入的和输出的,让这些设备的利用率更高,对设备的缓冲进行管理,对设配的地址进行分配。

4、管理文件。文件在计算机或手机中写入或者读取的时候,需要通过操作系统来进行,所以它会对文件进行组织、存储、操作以及保护,并且还会对它进行目录的管理以方便我们查找。

5、管理进程。操作系统中会对各种进程进行管理,而我们在运行某些程序的时候,就会在系统中产生进程,它受到操作系统的控制,达到同步、通信的效果。

插入排序?

插入排序,一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法 。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动

快速排序?

快速排序算法通过多次比较和交换来实现排序,其排序流程如下: (1)首先设定一个分界值,通过该分界值将数组分成左右两部分。 (2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于分界值,而右边部分中各元素都大于或等于分界值。 (3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。 (4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。

路由的几种模式?

1、hash模式。任何情况下都可以做前端路由,缺点是SEO不友好(服务器收不到hash,浏览器是不会把#后面的内容发给服务器)。#后面的就是hash

2、history模式。后端将所有前端路由都渲染到同一个页面(不能是404页面),缺点是IE8以下不兼容。number修改成从pathname里获取。

3、memory 模式。首先number不从路径里获取,从localStorage里获取。

三者区别:

hash和history都是把路径存在url上面,而memory模式路径没有放在url上而是在localStorage里,缺点是没有url是一个单机版的路由。

js有哪些异步操作?

1、promise

2、async/await

3、ajax

4、generator

5、addEventListener(事件监听)

6、setTimeout、setInterval(定时器)

7、回调函数(不是严格的异步操作)

MVC、MVP、MVVM?

参考1:MVC、MVP、MVVM三种区别

参考2:MVC、MVP、MVVM三种架构模式

1、MVC是模型-视图-控制器,它是MVC、MVP、MVVM这三者中最早产生的框架,其他两个框架是以它为基础发展而来的。

MVC的目的就是将M和V的代码分离,且MVC是单向通信,必须通过Controller来承上启下。

Model:模型层,数据模型及其业务逻辑,是针对业务模型建立的数据结构,Model与View无关,而与业务有关。

View:视图层,用于与用户实现交互的页面,通常实现数据的输入和输出功能。

Controller:控制器,用于连接Model层和View层,完成Model层和View层的交互。还可以处理页面业务逻辑,它接收并处理来自用户的请求,并将Model返回给用户。

2、MVP是模型-视图-表示器,它比MVC框架大概晚出现20年,是从MVC模式演变而来的。它们的基本思想有相同之处:Model层提供数据,View层负责视图显示,Controller/Presenter层负责逻辑的处理。将Controller改名为Presenter的同时改变了通信方向。

Model:模型层,用于数据存储以及业务逻辑。

View:视图层,用于展示与用户实现交互的页面,通常实现数据的输入和输出功能。

Presenter:表示器,用于连接M层、V层,完成Model层与View层的交互,还可以进行业务逻辑的处理。

3、MVVM是模型-视图-视图模型。MVVM与MVP框架区别在于:MVVM采用双向绑定:View的变动,自动反映在ViewModel,反之亦然。

Model:数据模型(数据处理业务),指的是后端传递的数据。

View:视图,将Model的数据以某种方式展示出来。

ViewModel:视图模型,数据的双向绑定(当Model中的数据发生改变时View就感知到,当View中的数据发生变化时Model也能感知到),是MVVM模式的核心。ViewModel 层把 Model 层和 View 层的数据同步自动化了,解决了 MVP 框架中数据同步比较麻烦的问题,不仅减轻了 ViewModel 层的压力,同时使得数据处理更加方便——只需告诉 View 层展示的数据是 Model 层中的哪一部分即可。

MVVM模型中数据绑定方法一般有三种:

  • 数据劫持
  • 发布-订阅模式
  • 脏值检查

**补充:**Vue.js使用的就是数据劫持和发布-订阅模式两种方法。了解Vue.js数据绑定流程前,我们需要了解这三个概念:

Observer:数据监听器,用于监听数据变化,如果数据发生改变,不论是在View层还是在Model层,Observer都会知道,然后告诉Watcher。 Compiler:指定解析器,用于对数据进行解析,之后绑定指定的事件,在这里主要用于更新视图。 Watcher:订阅者。 接下来看看Vue.js数据绑定的流程:首先将需要绑定的数据劫持方法找出来,之后用Observer监听这堆数据,如果数据发生变化,Observer就会告诉Watcher,然后Watcher会决定让那个Compiler去做出相应的操作,这样就完成了数据的双向绑定。

webview组件?

参考1:webview详解

1、webview是一个嵌入式的浏览器。

2、传统浏览器分为两个部分,UI(地址栏、导航栏)和浏览器引擎。webview就是原生应用中的浏览器引擎。

3、webview只是一个可视化的组件,是作为原生APP的视觉部分。

4、用webview展示的内容是不需要存储在本地的,可以直接从服务器获取。

5、这种灵活性打开了浏览器端的web应用和希望展示在原生应用中的web应用代码直接可重用的世界。

6、运行在webview中的JS代码有能力调用原生的系统API,没有传统浏览器沙箱的限制。

7、沙箱的存在是因为,你永远不能完全信任加载的web内容,所以不能允许它调用原生的系统API。而在webview中开发人员通常可以完全控制加载的内容,恶意代码进入并在设备上造成混乱的可能性很低。

8、在webview中,JS代码可以跟原生应用代码相互通信,也可以调用原生API集成酷炫的系统级功能,如传感器、存储、日历、联系人等。

webview和iframe的区别

webview是网页的原生载体,用于在原生环境中加载一个页面,iframe是网页的html载体,用于在网页中加载一个页面

vue动画?

参考:vue的Transition组件

组件 配合 v-enter-from、v-enter-active、v-enter-to、v-leave-from、v-leave-active、v-leave-to

HTTP状态码(也叫协议状态码)

分类 分类描述
1** 服务器收到客户的请求,需要客户机继续发送请求完成整个请求过程
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误

前端性能优化

参考1:前端性能优化七大手段

mixins原理

vuex设计模式

参考1:什么是vuex以及它的思想

使用单例模式

前端有哪些设计模式

vue为什么使用单向数据流

为了更好的解耦,在开发中如果有多个子组件依赖与父组件的某个数据,万一子组件真的可以直接修改父组件的数据,那么一个子组件的变化将会引发所有依赖于这个数据的子组件的变化,所以vue不推荐子组件直接修改父组件的数据,直接修改prop会抛出警告。

nextTick使用什么实现的

参考1:1000字带你掌握nextTick背后的原理

Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部对异步队列尝试使用原生的 Promise.then、MutationObserversetImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0)代替。

参考2:nextTick原理

Vue 不止使用 setTimeout 实现nextTick; 会判断promise是否存在,选择任务类型。如果promise存在,就使用微任务。

Vue在一个tick中多次更新数据页面只会更新一次

即使在 Vue 中多么频繁地修改数据,最后 Vue 页面只会更新一次。

例如: 数据 name 被 页面引用,name 会收集到 页面的 watcher; name 被修改时,会通知所有收集到的 watcher 进行更新(watcher.update); 如果name 一时间被修改三次时,按道理应该会通知三次 watcher 更新,那么页面会更新三次,但是最后只会更新一次。 这是因为: 当数据变化后,把 watcher.update 函数存放进 nextTick 的 回调数组中,并且会做过滤。 通过 watcher.id 来判断 回调数组 中是否已经存在这个 watcher 的更新函数不存在,才 push。 之后 nextTick时 遍历回调数组,便会执行了更新。

所以当三次修改数据的时候,会 push 回调数组 三个 watcher.update,但是只有第一次是 push 成功的,其他的会被过滤掉,因为已经存在了。 所以,不管你修改多少次数据,nextTick 的回调数组中只存在唯一一个 watcher.update,从而页面只会更新一次。

new的时候发生了什么

参考1:new地时候fa'sheng

1:首先会隐秘的创建一个空的实例对象 var fn = {} 2:会将构造函数的prototype等于实例对象的__proto__ Fn.prototype = fn.__proto 3:通过使用call方法执行构造函数并把this绑定到实例对象身上call(fn) 4: 执行函数体中的语句 4:如果函数没有返回其他对象,那么 new 构造函数会自动返回这个新对象

构造函数中一定要有this 如果没有this 就相当于没有办法给新创建的空对象绑定属性 当一个函数被new调用的时候 会创建一个空对象 this指向的就是这个空对象 函数中的语句将会被执行 并返回一个新对象 空对象–执行语句–新对象 构造函数可以称之为类 new出来的东西被称为类的实例

promise原理

css的:not选择器

promise的allSettled方法

参考1:allSettled方法

async的作用

参考1:async的作用

1、async 用于声明一个 function 是异步的,而 await 用于等待一个异步方法执行完成,async 返回的是一个Promise 对象。 2、async 的主要作用是回调地狱的处理看起来比 Promise 更美观,而且使用 async 来 传参的时候比较方便。 3、async 函数必须要等到方法体中所有的 await 声明 Promise 函数执行完后, async 函数才会得到一个resolve 状态的 Promise 对象。 4、async/await 在遇到异步请求的情况下,能让代码以看似同步的方式来解决异步回调

promise.resolve()

手写promise.all

手写Array.flat(),实现数组扁平化

观察者模式和发布订阅模式的区别

参考1:观察者模式和发布订阅模式的区别

前端设计模式

参考1:前端开发几种常见的设计模式

变量存放在堆栈的什么里