链表和数组的区别
链表:
一种上一个元素的引用指向下一个元素的存储结构,链表通过指针来连接元素与元素。
单向链表、双向链表、循环链表
不同:
- 链表是链式的存储结构;数组是顺序的存储结构。
- 链表通过指针来连接元素与元素,数组则是把所有元素按次序依次存储。
- 链表的插入删除元素相对数组较为简单,不需要移动元素,且较为容易实现长度扩充,但是寻找某个元素较为困难;
- 数组寻找某个元素较为简单,但插入与删除比较复杂,由于最大长度需要再编程一开始时指定,故当达到最大长度时,扩充长度不如链表方便。
相同:
- 两种结构均可实现数据的顺序存储,构造出来的模型呈线性结构。
Vue题型
Vue.use原理
vue 首先判断这个插件是否被注册过,不允许重复注册,并且接收的 plugin 参数的限制是 Function | Object 两种类型。
对于这两种类型有不同的处理。
首先将传入的参数整理成数组:const args = toArray(arguments, 1);
再将 Vue 对象添加到这个数组的起始位置 args.unshift(this) ,这里的 this 指向 Vue 对象;
如果传入的 plugin(Vue.use的第一个参数) 的 install 是一个方法。也就是说如果传入一个对象,对象中包含 install 方法,那么就调用这个 plugin 的 install 方法并将整理好的数组当成参数传入 install 方法中, plugin.install.apply(plugin, args);
如果传入的 plugin 就是一个函数,那么就直接调用这个函数并将整理好的数组当成参数传入, plugin.apply(null, args);
之后给这个插件添加至已经添加过的插件数组中,标示已经注册过 installedPlugins.push(plugin);
最后返回 Vue 对象。
源码
toArray
export function toArray (list: any, start?: number): Array<any> { start = start || 0 let i = list.length - start const ret: Array<any> = new Array(i) while (i--) { ret[i] = list[i + start] } return ret }
import { toArray } from '../util/index' export function initUse (Vue: GlobalAPI) { Vue.use = function (plugin: Function | Object) { const installedPlugins = (this._installedPlugins || (this._installedPlugins = [])) if (installedPlugins.indexOf(plugin) > -1) { return this } // additional parameters const args = toArray(arguments, 1) args.unshift(this) if (typeof plugin.install === 'function') { plugin.install.apply(plugin, args) } else if (typeof plugin === 'function') { plugin.apply(null, args) } installedPlugins.push(plugin) return this } }
Keep alive生命周期
作用:缓存组件内部状态,避免重新渲染
用法keep-alive可以接收3个属性做为参数进行匹配对应的组件进行缓存:
- include包含的组件(可以为字符串,数组,以及正则表达式,只有匹配的组件会被缓存)
- exclude排除的组件(以为字符串,数组,以及正则表达式,任何匹配的组件都不会被缓存)
- max缓存组件的最大值(类型为字符或者数字,可以控制缓存组件的个数)
生命周期
- 初次进入时:created > mounted > activated;退出后触发 deactivated
- 再次进入:会触发 activated;事件挂载的方法等,只执行一次的放在 mounted 中;组件每次进去执行的方法放在 activated 中
vue3 Proxy双向绑定的原理
定义:
Proxy对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。
对目标对象的操作之前提供了拦截,可以对外界的操作进行过滤和改写,修改某些操作的默认行为,这样我们可以不直接操作对象本身,而是通过操作对象的代理对象来间接来操作对象,达到预期的目的~
const toto = new Proxy(target, handler) // target: 是指将被代理/包裹的对象 // handler: 是代理的配置,它将拦截对目标的操作(获取、设置等)
demo
const toto = { name: 'toto', age: 25, _secret: '***' } const handler = { get(target, prop) { if (prop.startsWith('_')) { throw new Error('Access denied') } return target[prop] }, set(target, prop, value) { if (prop.startsWith('_')) { throw new Error('Access denied') } target[prop] = value // set方法返回布尔值 // 以便让我们知道该值是否已被正确设置 ! return true }, ownKeys(target, prop) { return Object.keys(target).filter(key => !key.startsWith('_')) }, } const totoProxy = new Proxy (toto, handler) for (const key of Object.keys(proxy1)) { console.log(key) // 'name', 'age' }
v-model语法糖原理
在vue2.0中v-mode语法糖简写的代码:
<Son :value="msg" @input="msg=$event" /> 简写: <Son v-model="count" />
在vue3.0中v-model语法糖有所调整:
<Son :modelValue="msg" @update:modelValue="msg=$event" /> 简写: <Son v-model="count" />
总结:
- vue3.0封装组件支持v-model的时候,父传子:modelValue 子传父 @update:modelValue
Tips:vue2.0的 xxx.sync 语法糖解析 父传子 :xxx 子传父 @update:xxx 在vue3.0 使用 v-model:xxx 代替。
React题型
hooks使用中有什么要注意的?
1. useState--不使用函数就set依赖之前状态的的状态
// initialState const [visible, setVisible] = useState(false) // modify the state // bad setVisible(!visible) // good setVisible(visible => !visible)
2. useState--它的setter方法其实是异步的
3. 有时候使用hook莫名其妙组件卡顿了,这个时候可以考虑用useMemo
4.区分好useCallback与useMemo一个是「缓存函数」, 一个是缓存「函数的返回值」
5. 在组件内部,会成为其他useEffect依赖项的方法,建议用 useCallback 包裹,或者直接编写在引用它的useEffect中。
6. 如果function会作为props传递给子组件,一定要使用 useCallback 包裹
7. 使用高阶函数的场景,建议使用 useMemo
react更新的流程是怎样的?
React在props或state发生改变时,会调用render()方法,创建一棵不同的树。
- 同层节点之间相互比较,不会垮节点比较
- 不同类型的节点,产生不同的树结构
- 通过key来指定哪些节点在不同的渲染下保持稳定
Diffing算法(调和算法):
1.对比不同类型的元素,节点不同就会拆解原来的树,建立新树
2.对比同类型元素
3.对子节点进行递归
hooks中为什么不能使用if else 逻辑判断?
确保 Hook 在每一次渲染中都按照同样的顺序被调用。这让 React 能够在多次的 useState 和 useEffect 调用之间保持 hook 状态的正确
在hooks/src/index.js 下,找到 useState源码,底层调用了 useReducer是通过全局索引去获取 Hook state。
hooks和类组件有什么区别?
hooks与类组件的区别,根本的原因,心智模型(mental model)上的区别。
1、函数式组件更加“声明式”
2、函数式组件更加“函数式和易复用”
使用 React Hooks 相比于从前的类组件有以下几点好处:
- 1. 代码可读性更强,原本同一块功能的代码逻辑被拆分在了不同的生命周期函数中,容易使开发者不利于维护和迭代,通过 React Hooks 可以将功能代码聚合,方便阅读维护
- 2. 组件树层级变浅,在原本的代码中,我们经常使用 HOC/render/Props 等方式来复用组件的状态,增强功能等,无疑增加了组件树层数及渲染,而在 React Hooks 中,这些功能都可以通过强大的自定义的 Hooks 来实现
hooks的限制
1. hook只能用在函数组件中,class组件不行2. 普通函数不能使用hook3. 函数组件内部的函数也不行4. hook定义时要注意先后顺序5. hook函数一定要放在函数组件的第一层,别放在if/for中
开放题型
做过哪些性能优化
web 性能优化?降低请求量:合并资源,减少 HTTP 请求数,minify / gzip 压缩, webP,lazyLoad。加快请求速度:预解析 DNS,减少域名数,并 行加载,CDN 分发。缓存:HTTP 协议缓存请求,离线缓存 manifest,离线数据缓存 localStorage。渲染:JS/CSS 优化,加载顺序,服务端渲染,pipeline
小程序的首屏加载时间提前请求:异步数据数据请求不需要等待页面渲染完成利用缓存:利用 storage API 对异步请求数据进行缓存,二次启动时 先利用缓存数据渲染页面,再进行后台更新避免白屏:先展示页面骨架和基础内容 及时反馈:及时地对需要用户等待的交互操作给出反馈,避免用户以 为小程序没有响应性能优化:避免不当使用 setdata 和 onpagescroll
也可以回答webpack等其他自己做过的优化内容,最好回答自己有把握的内容。
最近在学的新技术
这个因人而异,自由发挥,最好回答一些比较热门,主流的技术。
三、最后
这套题目,考到的知识点比较全面,所以我们在平时学习的时候要多多去挖掘,"蜻蜓点水 "的背后是要深入。