前端面试题汇总大全二(含答案超详细,Vue,TypeScript,React,Webpack 汇总篇)-- 持续更新

news2024/11/26 12:22:52

前端面试题汇总大全(含答案超详细,HTML,JS,CSS汇总篇)-- 持续更新

前端面试题汇总二

  • 五、Vue 篇
      • 1. 谈谈你对MVVM开发模式的理解?
      • 2. v-if 和 v-show 有什么区别?
      • 3. r o u t e 和 route和 routerouter区别
      • 4.vue自定义指令
      • 5.vue项目优化
      • 6.vue模板如何编译
      • 7.vue2响应式原理
      • 8.vue3响应式原理
      • 9.刷新浏览器后,Vuex的数据是否存在?如何解决?
      • 10.vue和react共同点?区别
      • 11.vue双向数据绑定原理
      • 12.computed和watch区别
      • 13.Vuex
      • 14.vuex辅助函数
      • 15.vuex模块化使用
      • 16.vue中mixin
      • 17.Vue中给对象添加新属性时,界面不刷新怎么办?
      • 18.vue组件通讯方式
      • 19.vue3setup的父传子怎么去写?
      • 20.setup可不可以直接写async和await?
      • 21.vue生命周期
      • 22.说说 Vue 中 CSS scoped 的原理
      • 23.$nextTick原理
      • 24.data是函数不是对象
      • 25.路由守卫
      • 26.vue设置全局变量
      • 27.vue中keep-alive
      • 28.vue插槽
      • 29.vue2和vue3区别
      • 30.Vue3.0 所采用的 Composition Api (组合式)与 Vue2.x 使用的 Options Api(选项式) 有什么不同?
      • 31.vue3中hook
      • 32.vue组件和插件的区别
      • 33.vue修饰符
      • 34.Vue路由中,history和hash两种模式有什么区别?
      • 35.params和query区别
      • 36.vue2中assets和vue3中public区别 ?
      • 37.单页应用如何提高加载速度?
      • 38.Vue父组件调用子组件的方法
      • 39.vue3中dom获取,ref在组件上使用
      • 40.渐进式框架理解
      • 41.页面初始化闪烁
      • 42.vue属性名和method名称一致出现什么问题
      • 43.class和style如何动态绑定
      • 44.vue遇到的坑
      • 45.v-if和v-for 优先级
      • 46.vue核心原理
      • 47.vue自带动画组件, transition
      • 48.vue-loader工作原理
      • 49.vue的diff算法
      • 50.vue和jquery区别
      • 51.说说你对 SPA 单页面的理解,它的优缺点分别是什么?
      • 52. 怎样理解 Vue 的单向数据流?
      • 53. 父组件可以监听到子组件的生命周期吗?
      • 54.Vue3.0 性能提升主要是通过哪几方面体现的
      • 55.什么是 MVVM?比之 MVC 有什么区别?什么又是 MVP ?
      • 56.vue中hook和react中hook区别
      • 57.Redux和Vuex的区别
      • 58.vue服务端渲染(SSR),解决了哪些问题?
      • 59.Vue 3.0中Treeshaking特性是什么,并举例进行说明?
      • 60. 虚拟 DOM 的优缺点?
      • 61. 虚拟 DOM 实现原理?
      • 62. Vue 中的 key 有什么作用?
      • 62. Object.defineProperty怎么用, 三个参数?,有什么作用啊?
      • 63.reactive与ref的区别?
      • 64.v-on可以监听多个方法吗?
      • 65.vue3中如何获取refs,dom对象的方式?vue2中如何使用?
      • 66.shallowReactive和shallowRef的区别
      • 67.provide与inject如何使用
      • 68.toRaw 与 markRaw是什么作用?
      • 69.Readonly和shallowReadonly理解
      • 70.toref和torefs区别
      • 71.学习 EventBus
      • 72.vue2过滤器(vue3取消)
  • 六、Webpack 篇
      • 1. 谈谈你对Webpack的理解(Webpack是什么?)
        • webpack的主要作用如下:
      • 2. Webpack的打包过程/打包原理/构建流程?
      • 3. loader的作用
      • 4. 有哪些常见的Loader?他们是解决什么问题的?
      • 5. plugin的作用
      • 6. 有哪些常见的Plugin?他们是解决什么问题的?
      • 7. Webpack中Loader和Plugin的区别
      • 8. webpack的热更新是如何做到的?说明其原理?
      • 9. 如何解决循环依赖问题
      • 10. 如何提高Webpack构建速度
        • 1. 代码压缩
        • 2. 图片压缩
        • 3. Tree Shaking
        • 4. 缩小打包域
        • 5. 减少 ES6 转为 ES5 的冗余代码
        • 6. 提取公共代码
        • 7. 其他
  • 七、性能优化篇
      • 1. 浏览器缓存优化
      • 2. 渲染层面性能优化
        • CSS策略
        • DOM策略
        • 阻塞策略
        • 回流重绘策略
        • 异步更新策略
      • 3. 性能优化六大指标
  • 八、其他杂项篇
      • 1. 常见的浏览器内核有哪些?
      • 2. 网页前端性能优化的方式有哪些?
      • 3. 网页从输入网址到渲染完成经历了哪些过程?
      • 4. 线程与进程的区别?
      • 5. HTTP常见的状态码?
      • 6. 图片懒加载?
      • 7. 移动端性能优化?
      • 8. TCP 传输的三次握手、四次挥手策略
      • 9. HTTP 和 HTTPS,为什么HTTPS安全?
      • 10. axios和fetch区别对比
  • 九、主观题篇
      • 1. 你都做过什么项目呢?具体聊某一个项目中运用的技术.
      • 2. 你遇到过比较难的技术问题是?你是如何解决的?
      • 3. 常使用的库有哪些?常用的前端开发工具?开发过什么应用或组件?
      • 4. 除了前端以外还了解什么其它技术么?你最最厉害的技能是什么?
      • 5. 对前端开发工程师这个职位是怎么样理解的?它的前景会怎么样?
      • 9. HTTP 和 HTTPS,为什么HTTPS安全?
      • 10. axios和fetch区别对比
  • 九、主观题篇
      • 1. 你都做过什么项目呢?具体聊某一个项目中运用的技术.
      • 2. 你遇到过比较难的技术问题是?你是如何解决的?
      • 3. 常使用的库有哪些?常用的前端开发工具?开发过什么应用或组件?
      • 4. 除了前端以外还了解什么其它技术么?你最最厉害的技能是什么?
      • 5. 对前端开发工程师这个职位是怎么样理解的?它的前景会怎么样?

五、Vue 篇

1. 谈谈你对MVVM开发模式的理解?

MVVM是一种简化用户界面的实践驱动编程方式。在当前主流的前后端分离的开发模式中,MVVM模式的优越性日益体现,相较于经典的MVC模式,其对于程序模块的封装很好地解决了前后端信息交互的冗余和繁琐

MVVM分为Model、View、ViewModel三者。
Model 代表数据模型,数据和业务逻辑都在Model层中定义;
View 代表UI视图,负责数据的展示;
ViewModel 负责监听 Model 中数据的改变并且控制视图的更新,处理用户交互操作;
Model 和 View 并无直接关联,而是通过 ViewModel 来进行联系的,Model 和 ViewModel 之间有着双向数据绑定的联系。因此当 Model 中的数据改变时会触发 View 层的刷新,View 中由于用户交互操作而改变的数据也会在 Model 中同步。
这种模式实现了 Model 和 View 的数据自动同步,因此开发者只需要专注对数据的维护操作即可,而不需要自己操作 dom。

为什么使用MVVM:低耦合,可复用,独立开发,可测试

2. v-if 和 v-show 有什么区别?

  • 手段
    • v-if是动态的向DOM树内添加或者删除DOM元素;
    • v-show是通过设置DOM元素的display样式属性控制显隐;
  • 编译
    • v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译;
    • v-show是在任何条件下,无论首次条件是否为真,都被编译,然后被缓存,而且DOM元素保留;
  • 性能消耗:
    • v-if有更高的切换消耗;
    • v-show有更高的初始渲染消耗

3. r o u t e 和 route和 routerouter区别

  • $route 是“路由信息对象”,包括 path,params,hash,query,fullPath,matched,name 等路由信息参数
  • $router 是“路由实例”想要导航到不同URL 对象包括了路由的跳转方法,钩子函数等。通过push、replace、go、back等方法,来实现页面间的跳转

4.vue自定义指令

vue指令

vue2

局部注册:directive选项

directives: {
 'focus': {
   bind(el, binding, vnode) {
     el.focus()
   }
 }
}

全局注册:main.js

Vue.directives('focus',{
	bind(el, binding, vnode) {
     el.focus()
   }
})

生命周期

  • bind:只调用一次,指令第一次绑到元素调用,用于初始化
  • inserted:被绑定元素插入父节点时调用
  • update:所在组件vnode更新调用
  • componentUpdate:指令在组件的vnode及子组件的vnode全部更新完调用
  • ubind:只调用一侧,指令解绑

vue3

局部注册:引入 import { Directive , DirectiveBinding } from ‘vue’ 分别校验vFocus,binding

<template>
<input type="text" v-focus="{ color: 'red' }" />
</template>

<script setup>
const vFocus = {
created(el, binding) {
 el.style.backgroundColor = binding.value.color;
 console.log(el, binding.value.color); //<input type="text" style="background-color: red;"> 'red'
},
};
</script>

全局注册:main.js,app.vue如上引入

import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)

app.directive('focus', {
 created(el, binding) {
     el.style.backgroundColor = binding.value.color;
     console.log(el, binding.value.color); //<input type="text" style="background-color: red;"> 'red'
 }
})

app.mount('#app')

生命周期

  • created 元素初始化的时候
  • beforeMount 指令绑定到元素后调用 只调用一次
  • mounted 元素插入父级dom调用
  • beforeUpdate 元素被更新之前调用
  • update 这个周期方法被移除 改用updated
  • beforeUnmount 在元素被移除前调用
  • unmounted 指令被移除后调用 只调用一次

5.vue项目优化

  • 代码层面
    • 长列表性能优化
    • 事件销毁, beforeDestroy生命周期函数内执行销毁逻辑。
    • 图片懒加载
    • 路由懒加载
    • 按需加载插件
    • v-if,v-for避免同时使用
    • v-if,v-show选择
    • keep-alive组件缓存
    • input防抖节流
  • 基础的web技术优化
    • 开启gzip压缩
    • 浏览器缓存
    • CDN加速
  • webpack优化

6.vue模板如何编译

Vue的模板编译就是将“HTML”模板编译成render函数的过程。这个过程大致可以分成三个阶段:

  • 解析阶段:将“HTML”模板解析成AST语法树;
  • 核心 parseHTML( template ,{}) Vue定义了很多匹配HTML的正则表达式 ,parseHTML根据正则匹配
  • parseHTML是解析模板字符串的“主线程”,它的第一个参数是要解析的模板字符串, 也就是单文件组件中最外层 所包裹的部分;第二个参数是一个选项对象,它会包含一些回调,以及一些配置项。
  • 选项对象:
    • start( tag, attrs, unary ) 匹配到开始标签时的回调,tag为当前标签的标签名,attrs为该标签上的属性列表,unary为当前标签是否为自闭合标签
    • end() 匹配到结束标签时的回调
    • chars(text) 匹配到文本节点的回调
    • comment(text) 匹配到注释节点的回调,其处理逻辑跟文本的处理逻辑类似
  • 优化阶段:从AST语法树中找出静态子树并进行标记(被标记的静态子树在虚拟dom比对时会被忽略,从而提高虚拟dom比对的性能);
    • 上面简单介绍过,优化阶段的工作就是标记静态子树,标记静态子树后主要有以下两个优点:
      • 生成虚拟dom的过程中,如果发现一个节点是静态子树,除了首次渲染外不会生成新的子节点树,而是拷贝已存在的静态子树;
      • 比对虚拟dom的过程中,如果发现当前节点是静态子树,则直接跳过,不需要进行比对。
    • 标记静态子树的过程分为两个步骤:
      • 遍历AST语法树,找出所有的静态节点并打上标记(注:当前节点及其所有子节点都是静态节点,当前节点才会被打上静态节点的标记)
      • 遍历经过上面步骤后的树,找出静态根节点,并打上标记(注:静态根节点是指本身及所有子节点都是静态节点,但是父节点为动态节点的节点,找到了静态根节点也就找到了“静态子树”)
  • 代码生成阶段:通过AST生成代码字符串,并最终生成render函数。

7.vue2响应式原理

vue 采用了几个核心部件 : ObserverDep WatcherScheduler

  • observer把一个普通的对象转换成响应式的对象
  • observer 把对象的每个属性通过 object.defineProperty 转换为带有 getter 和 setter 的属性
  • Dep 表示依赖, vue 会为响应式对象中的每一个属性,对象本身,数组本身创建一个 dep 实例,每个 dep 实例都可以做两件事情 :
  • 记录依赖:是谁在用我
  • 派发更新:我变了,我要通知那些用我的人
  • watcher 在函数执行的过程中,如果发生了依赖记录,那么 dep 就会把这个全局变量记录下来,表示有一个 wathcer 用到了我这个属性。
  • Scheduler 不会立即执行更新,通过nexttick异步更新

8.vue3响应式原理

通过Proxy(代理): 拦截对象中任意属性的变化,包括:属性值的读写,属性的增加,属性的删除等。

通过Reffect(反射): 对源对象的属性进行操作, Reflect不是一个函数对象,因此它是不可构造的。

9.刷新浏览器后,Vuex的数据是否存在?如何解决?

不存在

原因: 因为 store 里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,store里面的数据就会被重新赋值初始化。

我们有两种方法解决该问题:

  1. 使用 vuex-along
  2. 使用 localStorage 或者 sessionStroage

10.vue和react共同点?区别

共同点:

  • 数据驱动视图
  • 组件化
  • 都使用 Virtual DOM

不同点

  • 核心思想不同
    • vue定位就是尽可能的降低前端开发的门槛,让更多的人能够更快地上手开发。这就有了vue的主要特点:灵活易用的渐进式框架,进行数据拦截/代理,它对侦测数据的变化更敏感、更精确
    • react 定位就是提出 UI 开发的新思路 React推崇函数式编程(纯组件),数据不可变以及单向数据流,当然需要双向的地方也可以手动实现, 比如借助onChangesetState来实现。
  • 组件写法
    • React推荐的做法是JSX + inline style, 也就是把 HTML 和 CSS 全都写进 JavaScript 中
    • Vue 推荐的做法是 template 的单文件组件格式(简单易懂,从传统前端转过来易于理解),即 html,css,JS 写在同一个文件(vue也支持JSX写法)
  • diff算法
  • 响应式原理
    • vue2采用object.defineProperty ,vue3采用proxy,reflect
    • React基于状态机,手动优化,数据不可变,需要setState驱动新的state替换老的state。

11.vue双向数据绑定原理

简易实现:v-model分为两部分,通过v-bind绑定值,再通过v-on:input来通步修改值

原理

  • 需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上setter和getter这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化
  • 通过dep来理清依赖关系,watcher在依赖中添加自身
  • compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
  • 待属性变动dep.notice()通知时,能调动watcher自身的update方法,并处罚compile回调渲染视图

12.computed和watch区别

computed计算属性,watch监听属性

  • 计算属性不在 data 中,它是基于data 或 props 中的数据通过计算得到的一个新值。watch 可以监听的数据来源:data,props,computed内的数据
  • component中有get和set方法,会默认缓存计算结果。watch不支持缓存,支持异步, immediate监听属性立即执行一次,deep开启深度监听

13.Vuex

Vuex是一种状态管理模式,存在的目的是共享可复用的组件状态。

主要包括以下几个模块:

  • State => 基本数据,定义了应用状态的数据结构,可以在这里设置默认的初始状态。
  • Getter => 从基本数据派生的数据,允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性。
  • Mutation => 是唯一更改 store 中状态的方法,且必须是同步函数。
  • Action => 像一个装饰器,包裹mutations,使之可以异步。用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。
  • Module => 模块化Vuex,允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。

14.vuex辅助函数

mapState, mapMutations, mapActions, mapGetters

mapState和mapGetters:

  • 两者都放在 computed中,以mapState举例
import { mapState } from 'vuex'

computed中
computed:{
	...mapState(['data'])  //data是vuex存放的state中的属性,此时{{data}}可使用
}

mapMutations, mapActions:

  • 放在组件的methods属性中 。使用与上类似

15.vuex模块化使用

当我们开发的项目比较大时,store中的数据就可能比较多,这时我们store中的数据就可能变得臃肿,为了解决这一问题,我们就需要将store模块化(module)

前提:创建两份js文件,含有属性与vuex写法相同,需要通过 namespaced:true开启命名空间store/index.js:在modules中引入文件

使用:

  • 访问state数据:
    • 第一种方式:this.$store.state.moduleA.sum
    • 第二种方式: ...mapState('moduleA',['sum','number'])
  • action提交mutation
  • 第一种方式:需要传参this.$store.dispatch('moduleB/addZhang',{name:'小明',age:18}) ,无需传参this.$store.dispatch('moduleB/addServer')
  • 第二种方式:...mapActions('moduleB',['addZhang'])
  • getters计算属性
  • 第一种方式: this.$store.getters['moduleB/firstName']
  • 第二种方式:...mapGetters('moduleB',['firstName'])

16.vue中mixin

mixin(混入): 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。

本质其实就是一个js对象,它可以包含我们组件中任意功能选项,如datacomponentsmethods createdcomputed等等

我们只要将共用的功能以对象的方式传入 mixins选项中,当组件使用 mixins对象时所有mixins对象的选项都将被混入该组件本身的选项中来

具体使用:

  • 创建mixins.js文件
let mixin = {
    created() {
        console.log('我是mixin中的');
    },
    methods: {
        hellow() {
            console.log('你好');
        },
    },
}
export default mixin
  • 局部使用
import mixin from "./mixins";
export default {
  mixins: [mixin],
  mounted() {
    this.hellow();//你好
  },
};
  • 全局使用main.js
import { createApp } from 'vue'
import App from './App.vue'
import mixins from "./mixins";
const app = createApp(App)
app.mixin(mixins)
app.mount('#app')

17.Vue中给对象添加新属性时,界面不刷新怎么办?

原因:vue2响应式采用object.defineProperty进行劫持,那个添加新属性时,新的属性不会具有get和set方法,不是一个响应式所以界面不刷新

解决:Vue.set() 向响应式对象中添加一个property,并确保这个新 property 同样是响应式的

vue3通过proxy劫持和reflect映射实现响应式,不会有这个问题

18.vue组件通讯方式

  • 通过 props 传递
    • props校验:name:{type:String,required:true,default:默认值} required是否必要
  • 通过 $emit 触发自定义事件
  • 使用 ref
  • EventBus
  • Provide 与 Inject
  • Vuex

19.vue3setup的父传子怎么去写?

介绍三种方法:

第一种:使用vue2写法通过props和$emit

第二种:setup函数写法

  • setup(props,context),通过props接收数据,通过context.emit(‘调用父组件方法’,传递参数)

第三种:script中setup

  • vue3自带defineProps,defineEmits
const emits = defineEmits(["changeNumber"]);
// 也可以不赋值,取值通过{{num}}获取
const props = defineProps({
  num: {
    type: Number,
    default: () => [],
  },
  list: {
    type: Array,
  },
});
const changeNum = function () {
  emits("changeNumber", 888);
  //   console.log(11111111111);
};

20.setup可不可以直接写async和await?

可以

setup 语法糖中可直接使用 await,不需要写 async , setup 会自动变成 async setup

<script setup>
  import Api from '../api/Api'
  const data = await Api.getData()
  console.log(data)
</script>

21.vue生命周期

vue2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qlfjtF6I-1685109549653)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1685089235304.png)]

beforeCreate – 首次访问data

created – 首次访问this生命周期

mounted – 页面展示

vue3

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7tHeS6mz-1685109549654)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1685089301710.png)]

区别

  • beforeCreate -> setup() 开始创建组件之前,创建的是data和method
  • created -> setup()
  • beforeMount -> onBeforeMount 组件挂载到节点上之前执行的函数。
  • mounted -> onMounted 组件挂载完成后执行的函数
  • beforeUpdate -> onBeforeUpdate 组件更新之前执行的函数。
  • updated -> onUpdated 组件更新完成之后执行的函数。
  • beforeDestroy -> onBeforeUnmount 组件挂载到节点上之前执行的函数。
  • destroyed -> onUnmounted 组件卸载之前执行的函数。dszhuoyi
  • activated -> onActivated 组件卸载完成后执行的函数
  • deactivated -> onDeactivated

22.说说 Vue 中 CSS scoped 的原理

添加scoped标签后会给组件中所有标签元素,添加一个唯一标识,这个唯一标识就是自定义属性,data-v-xxxxxxxx这样的字眼,同时对应的样式选择器也会添加这个唯一的属性选择器

23.$nextTick原理

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM

nextTick原理

24.data是函数不是对象

vue是一个单页面应用最终所有的实例都会挂载到app.vue文件,如果data是一个对象那么会导致数据污染。通过函数返回对象的方式,利用函数作用域的限制避免数据污染

25.路由守卫

vue路由守卫分为三种:全局路由守卫,独享路由守卫,组件路由守卫

to: 进入到哪个路由去

from: 来自哪个路由

next:是否跳转

  • 全局守卫: router.beforeEach((to,from,next)=>{})
  • 独享路由守卫: beforeEnter:(to,from,next)=>{}
  • 组件路由守卫: beforeRouteEnter:(to,from,next)=>{}, beforeRouteUpdate , beforeRouteLeave

26.vue设置全局变量

方法一:

  • vue2.x挂载全局是使用 Vue.prototype.$xxxx=xxx 的形式来挂载,然后通过 this.$xxx来获取挂载到全局的变量或者方法。
  • Vue 3 中,使用 config.globalProperties 、app.config.globalProperties.$data = ‘111’
 const {proxy} = getCurrentInstance()
 console.log(proxy.$data)

方法二:

  • provide/inject

27.vue中keep-alive

属性:includeexclude

语法:

// 指定home组件和about组件被缓存
<keep-alive include="home,about" >
    <router-view></router-view>
</keep-alive>

// 除了home组件和about组件别的都缓存
<keep-alive exclude="home,about" >
    <router-view></router-view>
</keep-alive>

钩子函数:

  • activated 当组件被激活(使用)的时候触发 可以简单理解为进入这个页面的时候触发
  • deactivated 当组件不被使用(inactive状态)的时候触发 可以简单理解为离开这个页面的时候触发

进入开启缓存的组件

初始进入和离开 created ---> mounted ---> activated --> deactivated
后续进入和离开 activated --> deactivated

28.vue插槽

slot又名插槽,是Vue的内容分发机制,组件内部的模板引擎使用slot元素作为承载分发内容的出口。插槽slot是子组件的一个模板标签元素,而这一个标签元素是否显示,以及怎么显示是由父组件决定的。slot又分三类,默认插槽,具名插槽和作用域插槽。

默认插槽:又名匿名插槽,当slot没有指定name属性值的时候一个默认显示插槽,一个组件内只有有一个匿名插槽。

具名插槽:带有具体名字的插槽,也就是带有name属性的slot,一个组件可以出现多个具名插槽。

作用域插槽:默认插槽、具名插槽的一个变体,可以是匿名插槽,也可以是具名插槽,该插槽的不同点是在子组件渲染作用域插槽时,可以将子组件内部的数据传递给父组件,让父组件根据子组件的传递过来的数据决定如何渲染该插槽。

实现原理:当子组件vm实例化时,获取到父组件传入的slot标签的内容,存放在vm. s l o t 中,默认插槽为 v m . slot中,默认插槽为vm. slot中,默认插槽为vm.slot.default,具名插槽为vm. s l o t . x x x , x x x 为插槽名,当组件执行渲染函数时候,遇到 s l o t 标签,使用 slot.xxx,xxx 为插槽名,当组件执行渲染函数时候,遇到slot标签,使用 slot.xxxxxx为插槽名,当组件执行渲染函数时候,遇到slot标签,使用slot中的内容进行替换,此时可以为插槽传递数据,若存在数据,则可称该插槽为作用域插槽。

29.vue2和vue3区别

双向绑定更新

vue2 的双向数据绑定是利⽤ES5 的⼀个 API ,Object.defineProperty()对数据进⾏劫持 结合 发布订阅模式的⽅式来实现的。

vue3 中使⽤了 ES6 的 ProxyAPI 对数据代理,通过 reactive() 函数给每⼀个对象都包⼀层 Proxy,通过 Proxy 监听属性的变化,从⽽ 实现对数据的监控。

这⾥是相⽐于vue2版本,使⽤proxy的优势如下

1.defineProperty只能监听某个属性,不能对全对象监听 可以省去for in、闭包等内容来提升效率(直接绑定整个对象即可)

2.可以监听数组,不⽤再去单独的对数组做特异性操作,通过Proxy可以直接拦截所有对象类型数据的操作,完美⽀持对数组的监听。

获取props

vue2在script代码块可以直接获取props,vue3通过setup指令传递

API不同

Vue2使⽤的是选项类型API(Options API),Vue3使⽤的是合成型API(Composition API)

建立数据data

vue2是把数据放入data中,vue3就需要使用一个新的setup()方法,此方法在组件初始化构造得时候触发。

生命周期不同

vue2 -------- vue3

beforeCreate -> setup() 开始创建组件之前,创建的是data和method

created -> setup()

beforeMount -> onBeforeMount 组件挂载到节点上之前执行的函数。

mounted -> onMounted 组件挂载完成后执行的函数

beforeUpdate -> onBeforeUpdate 组件更新之前执行的函数。

updated -> onUpdated 组件更新完成之后执行的函数。

beforeDestroy -> onBeforeUnmount 组件挂载到节点上之前执行的函数。

destroyed -> onUnmounted 组件卸载之前执行的函数。dszhuoyi

activated -> onActivated 组件卸载完成后执行的函数

deactivated -> onDeactivated

是否支持碎片:vue2.0 只允许有一个根标签,vue3.0支持碎片化,可以拥有多个根节点

main.js文件不同:vue2中我们可以使用pototype(原型)的形式去进行操作,引入的是构造函数 vue3中需要使用结构的形式进行操作,引入的是工厂函数

diff算法不同

更好的支持ts

30.Vue3.0 所采用的 Composition Api (组合式)与 Vue2.x 使用的 Options Api(选项式) 有什么不同?

  • options Api 当组件变得复杂,导致对应属性的列表也会增长,这可能会导致组件难以阅读和理解 。composition Api它将功能定义在一起,利于查找和理解
  • Composition API tree-shaking 友好,代码也更容易压缩
  • Composition API中见不到this的使用,减少了this指向不明的情况
  • 如果是小型组件,可以继续使用Options API,也是十分友好的

31.vue3中hook

本质是一个函数,把setup函数中使用的Composition API(组合式api)进行了封装,类似于vue2中的mixin

自定义hook优势:复用代码,让setup中的逻辑更清楚易懂

32.vue组件和插件的区别

组件: Vue 组件是一个可复用的 Vue 实例,可以带有自己的状态和方法。组件可以包含其他组件,从而形成一个复杂的 UI 列表。

优点

  • 可以将代码封装成一个可复用的组件,提高开发效率。
  • 组件具有良好的可维护性,易于修改和更新。

缺点

  • 组件的功能和作用比较独立,不太适用于全局功能的扩展。
  • 组件的管理和组织需要一定的规范,否则可能会导致混乱和不易维护。

插件: Vue 插件可以扩展 Vue 的全局功能,在应用程序中可以重复使用。常见的插件如 vue-routervuexaxios 等。

优点

  • 插件可以方便地扩展 Vue 的全局功能。
  • 插件可以使代码重复利用,提高开发效率。
  • 开源社区中已经有大量的插件可以用于解决常见的问题。

缺点

  • 插件具有一定的复杂性,需要更多的学习成本。
  • 插件功能可能比较复杂,可能会导致性能下降。

33.vue修饰符

Vue中,修饰符处理了许多DOM事件的细节,让我们不再需要花大量的时间去处理这些烦恼的事情,而能有更多的精力专注于程序的逻辑处理

  • 表单修饰符
    • .lazy 懒加载,光标离开标签时,才赋值给value
    • .trim 过滤首位空格
    • .number 限制输入类型为数字或转为数字
  • 事件修饰符
    • .stop 阻止事件冒泡
    • .prevent 组织事件默认行为
    • .once 事件只触发一次
    • .capture 开启事件捕获
    • .self 事件只在自身触发
  • 鼠标按键修饰符
    • left 左键点击
    • right 右键点击
    • middle 中键点击
  • 键值修饰符
    • 普通键(enter、tab、delete、space、esc、up…)
    • 系统修饰键(ctrl、alt、meta、shift…)
  • v-bind修饰符
    • .async 对props进行双向绑定
    • .prop 设置自定义标签属性,避免暴露数据,防止污染html结构
    • .camel 将命名为驼峰命名法

34.Vue路由中,history和hash两种模式有什么区别?

hash: hash 模式是一种把前端路由的路径用井号 # 拼接在真实 URL 后面的模式。当井号 # 后面的路径发生变化时,浏览器并不会重新发起请求,而是会触发 hashchange 事件。

  • 优点:浏览器兼容性较好,连 IE8 都支持
  • 缺点:路径在井号 # 的后面,比较丑

history: history API 是 H5 提供的新特性,允许开发者直接更改前端路由,即更新浏览器 URL 地址而不重新发起请求

  • 优点:路径比较正规,没有井号 #
  • 缺点:兼容性不如 hash,且需要服务端支持,否则一刷新页面就404了

35.params和query区别

paramsquery 都是用于传递参数的,但它们的传参方式和使用场景是不同的。

params 通过路由路径传递参数,在路由配置中使用 :paramName 的形式进行声明

const router = new VueRouter({
  routes: [
    {
      path: '/user/:id',
      component: User,
    },
  ],
})

query 通过 URL 查询字符串(即问号后面的部分)传递参数,在路由地址后面使用 ? 连接多个参数键值对

不需要在router中配置 /search?q=vue 会自动匹配到search组件

区别:

  • params 适合用于必须存在的参数传递,例如用户详情页或文章详情页的访问。
  • query 适合用于可选的参数传递,例如搜索功能中关键词的传递。

36.vue2中assets和vue3中public区别 ?

在 Vue 2 中,assets 目录是默认存在的,可以直接在项目的根目录下创建,它通常用来存放组件需要的图片、样式等静态资源文件。这些文件会被打包到 JavaScript 文件中,在代码中使用相对路径引用。

在 Vue 3 中,可以通过配置 vue.config.js 文件来设置 public 目录,它的作用与 assets 目录类似,用来存放静态资源文件。但是,与 Vue 2 不同的是,public 目录下的文件不会被打包,而是会直接复制到输出目录下

37.单页应用如何提高加载速度?

  • 使用代码分割:将代码拆分成小块并按需加载(懒加载),以避免不必要的网络请求和减少加载时间。
  • 缓存资源:利用浏览器缓存来存储重复使用的文件,例如 CSS 和 JS 文件、图片等。
  • 预加载关键资源:在首次渲染之前,先提前加载关键资源,例如首页所需的 JS、CSS 或数据,以保证关键内容的快速呈现。
  • 使用合适的图片格式:选择合适的图片格式(例如 JPEG、PNG、WebP 等),并根据需要进行压缩以减少文件大小。对于一些小图标,可以使用 iconfont 等字体文件来代替。
  • 启用 Gzip 压缩:使用服务器端的 Gzip 压缩算法对文件进行压缩,以减少传输时间和带宽消耗。
  • 使用 CDN:使用内容分发网络(CDN)来缓存和传递文件,以提高文件的下载速度和可靠性。
  • 优化 API 请求:尽可能地减少 API 调用的数量,并使用缓存和延迟加载等技术来优化 API 请求的效率。
  • 使用服务器端渲染:使用服务器端渲染(SSR)来生成 HTML,以减少客户端渲染所需的时间和资源。但需要注意,SSR 也可能增加了服务器的负担并使网站更复杂。

38.Vue父组件调用子组件的方法

vue中如果父组件想调用子组件的方法,可以在子组件中加上ref,然后通过this.$refs.ref.method调用

<child ref="child"></child>
调用:this.$refs.child.子组件方法

39.vue3中dom获取,ref在组件上使用

<template>
  <div class="ref">
    <h3>ref使用:</h3>
    <input type="text" ref="input" /> //  ref="input" 需要和 const input = ref(null); 相对应
  </div>
</template>

<script setup>
import { reactive, ref, createApp, onMounted } from "vue";

let state = reactive({ text: "信息按钮" });
// 同名的 input来进行获取节点
const input = ref(null);
onMounted(() => {
  if (input.value) {
    input.value.focus();
  }
});
</script>
<style scoped></style>

40.渐进式框架理解

渐进式: 可以理解为没有多做职责之外的事

个人理解:主张最少的,一开始仅基于基础框架构建,随着需求不断扩充

41.页面初始化闪烁

产生原因:当网速较慢,vue.js文件还没有加载完时,在页面上会显示{{message}}的字样,知道vue创建实例,编译模板时,dom才会被替换,所以这个过程屏幕是闪动的。

所以解决这个问题,需要在style样式中设置【v-cloak】{display:none}。在一般情况下,v-clock是一个解决初始化慢导致页面闪动的最佳实践,对于简单的项目很实用。

但是在具有工程化的项目里,比如使用了webpack和vue-router的项目中,html结构只是一个空的div元素,剩余的内容都是由路由去挂载不同的组件完成的,所以不需要v-cloak。

42.vue属性名和method名称一致出现什么问题

vue2中, 这个属性会覆盖掉 methods 中的方法。也就是说,这个方法将无法被正确调用。

vue3中,报错

43.class和style如何动态绑定

class 与 style 动态绑定一般通过对象或者数组来实现

对象写法:适用于要绑定的样式名字样式确定,但动态决定用不用。

数组写法:适用于要绑定的样式名字样式不确定。

<div v-bind:class="{ active: isActive }"></div> //对象写法
<div v-bind:class="[activeClass, errorClass]"></div> //数组写法

44.vue遇到的坑

  • data必须是一个函数,而不是一个对象
  • vue管理的函数不要写成箭头函数
  • 添加属性页面不刷新
  • 子路由path不需要添加**/**,path=‘new’

45.v-if和v-for 优先级

实践中不管是vue2或者vue3都不应该把v-if和v-for放在一起使用。

在 vue 2.x 中,在一个元素上同时使用 v-if 和 v-for 时, v-for 会优先作用。

在 vue 3.x 中, v-if 总是优先于 v-for 生效。

vue2中v-for的优先级是高于v-if的,放在一起,会先执行循环在判断条件,并且如果值渲染列表中一小部分元素,也得再每次重渲染的时候遍历整个列表,比较浪费资源。

vue3中v-if的优先级是高于v-for的,所以v-if执行时,它调用相应的变量如果不存在,就会导致异常

46.vue核心原理

数据驱动,组建系统

47.vue自带动画组件, transition

组件是 Vue 提供的用于包裹需要动画效果的元素组件。使用组件可以方便地实现元素的进入和离开动画效果。

<template>
  <div>
    <button @click="visible = !visible">Toggle</button>
    <transition name="fade">
      <p v-if="visible">Hello, World!</p>
    </transition>
  </div>
</template>

<script>
export default {
  data() {
    return {
      visible: false
    }
  },
}
</script>

<style>
.fade-enter-active, .fade-leave-active {
  transition: opacity .5s;
}
.fade-enter, .fade-leave-to {
  opacity: 0;
}
</style>

48.vue-loader工作原理

  1. 将一个 .vue 文件 切割成 templatescriptstyles 三个部分。
  2. template 部分 通过 compile 生成 renderstaticRenderFns
  3. 获取 script 部分 返回的配置项对象 scriptExports
  4. styles 部分,会通过 css-loadervue-style-loader, 添加到 head 中, 或者通过 css-loaderMiniCssExtractPlugin 提取到一个 公共的css文件 中。
  5. 使用 vue-loader 提供的 normalizeComponent 方法, 合并 scriptExports、render、staticRenderFns, 返回 构建vue组件需要的配置项对象 - options, 即 {data, props, methods, render, staticRenderFns…}

49.vue的diff算法

diff整体策略为:深度优先,同层比较

  • 当数据发生改变时,订阅者watcher就会调用patch给真实的DOM打补丁

  • 通过isSameVnode进行判断,相同则调用patchVnode方法

  • patchVnode

    做了以下操作:

    • 找到对应的真实dom,称为el
    • 如果都有都有文本节点且不相等,将el文本节点设置为Vnode的文本节点
    • 如果oldVnode有子节点而VNode没有,则删除el子节点
    • 如果oldVnode没有子节点而VNode有,则将VNode的子节点真实化后添加到el
    • 如果两者都有子节点,则执行updateChildren函数比较子节点
  • updateChildren

    主要做了以下操作:

    • 设置新旧VNode的头尾指针
    • 新旧头尾指针进行比较,循环向中间靠拢,根据情况调用patchVnode进行patch重复流程、调用createElem创建一个新节点,从哈希表寻找 key一致的VNode 节点再分情况操作

50.vue和jquery区别

设计理念

Vue.js 是一个现代化的JavaScript框架,专注于构建大型的、可维护的Web应用程序。Vue.js 的核心是组件化,它提供了一种将页面分解成独立、可重用的组件的方式,并且能够非常容易地管理这些组件之间的依赖关系。同时,Vue.js 还内置了状态管理、路由、构建工具等功能,使得构建复杂的 Web 应用程序更加容易。

而 jQuery 则是一个早期的 JavaScript 库,主要关注的是 DOM 操作和处理事件。它的设计理念是将 JavaScript 代码尽可能地简单化,使得使用者可以很容易地完成一些常见的操作(如选择元素、修改样式、处理事件等)。在 jQuery 中,通过链式调用和函数式变成的设计,可以使得代码变得非常简洁易读。

用途

Vue.js 主要用于构建大型的、复杂的 Web 应用程序,它提供了诸如组件化、状态管理、路由等功能,非常适合构建单页面应用(SPA)。

而 jQuery 则更多地用于简化 DOM 操作和事件处理,它适用于编写小型的 Web 应用程序或较为简单的交互效果。同时,由于 jQuery 在浏览器兼容性、性能等方面的优势,它也被广泛应用于一些成熟的网站和CMS系统中。

51.说说你对 SPA 单页面的理解,它的优缺点分别是什么?

SPA( single-page application )仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现HTML 内容的变换,UI 与用户的交互,避免页面的重新加载。

  • 优点:
    用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;
    基于上面一点,SPA 相对对服务器压力小;
    前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理;
  • 缺点:
    初次加载耗时多:为实现单页 Web 应用功能及显示效果,需要在加载页面的时候将 JavaScript、CSS 统加载,部分页面按需加载;
    前进后退路由管理:由于单页应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理;
    SEO 难度较大:由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势。

52. 怎样理解 Vue 的单向数据流?

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。
这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
子组件想修改时,只能通过 $emit 派发一个自定义事件,父组件接收到后,由父组件修改。

53. 父组件可以监听到子组件的生命周期吗?

比如有父组件 Parent 和子组件 Child,如果父组件监听到子组件挂载 mounted 就做一些逻辑处理,可以通过以下写法实现:

// Parent.vue
<Child @mounted="doSomething"/>

// Child.vue
mounted() {
  this.$emit("mounted");
}

以上需要手动通过 $emit 触发父组件的事件,更简单的方式可以在父组件引用子组件时通过 @hook 来监听即可,如下所示:

//  Parent.vue
<Child @hook:mounted="doSomething" ></Child>

doSomething() {
   console.log('父组件监听到 mounted 钩子函数 ...');
},

//  Child.vue
mounted(){
   console.log('子组件触发 mounted 钩子函数 ...');
},    

// 以上输出顺序为:
// 子组件触发 mounted 钩子函数 ...
// 父组件监听到 mounted 钩子函数 ...

当然 @hook 方法不仅仅是可以监听 mounted,其它的生命周期事件,例如:created,updated 等都可以监听。

54.Vue3.0 性能提升主要是通过哪几方面体现的

  • diff算法优化
  • 静态提升: Vue3中对不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用
  • 移除一些不常用的API,再重要的是Tree shanking
  • 响应式系统

55.什么是 MVVM?比之 MVC 有什么区别?什么又是 MVP ?

MVC 通过分离 Model、View 和 Controller 的方式来组织代码结构。 用户与页面产生交互时Controller 中的事件触发器就开始工作了,通过调用 Model 层,来完成对 Model 的修改,然后 Model 层再去通知 View 层更新。

MVVM 模式中的 VM,指的是 ViewModel, 它通过双向的数据绑定,将 View 和 Model 的同步更新给自动化了。当 Model 发生变化的时候,ViewModel 就会自动更新;ViewModel 变化了,View 也会更新。

MVP 模式 ,View 层的接口暴露给了 Presenter 因此我们可以在 Presenter 中将 Model 的变化和 View 的变化绑定在一起,以此来实现 View 和 Model 的同步更新

56.vue中hook和react中hook区别

在React中,hook是一种函数,它可以让你在函数组件中添加state、effect等功能。 React 中的hook有useState、useEffect、useContext等。使用hook可以避免使用类组件时可能会出现的繁琐的生命周期方法、this等问题。

在Vue中,hook被称为生命周期钩子函数,它们是在组件实例化过程中自动调用的回调函数。 Vue中的生命周期钩子函数包括beforeCreate、created、beforeMount、mounted等。它们可以用于控制组件的生命周期,以及在组件生命周期特定阶段执行特定的操作。

57.Redux和Vuex的区别

redux是一个范用的js库,vuex是专门服务vue的

相同点:

  1. state共享数据
  2. 流程一致:定义全局state,触发,修改state
  3. 原理相似,通过全局注入store。

不同点:

  1. Vuex定义了state,getter、mutation、action,module五个对象;redux定义了state、reducer、action;
  2. Vuex触发方式有两种commit同步和dispatch异步;redux同步和异步都使用dispatch;
  3. Vuex中action有较为复杂的异步ajax请求;redux中action中可简单可复杂,简单就直接发送数据对象({type:xxx, your-data}),复杂需要调用异步ajax(依赖redux-thunk插件)。
  4. Redux使用的是不可变数据,而Vuex的数据是可变的。Redux每次都是用新的state替换旧的state,而Vuex是直接修改;
  5. Redux在检测数据变化的时候,是通过diff的方式比较差异的,而Vuex其实和Vue的原理一样,是通过getter/setter来比较的。

58.vue服务端渲染(SSR),解决了哪些问题?

Vue服务端渲染(SSR)通过在服务器上预先生成Vue组件的HTML字符串,并将其发送到客户端,以实现更快的页面加载速度、更好的搜索引擎优化和更好的用户体验。服务端渲染解决了许多SPA(Single Page Application)应用程序中存在的问题,例如:

  1. SEO(搜索引擎优化)问题:由于传统的SPA应用程序是在浏览器中构建的,因此搜索引擎无法正确地索引它们的内容。使用Vue SSR,可以在服务器上呈现HTML字符串并向搜索引擎提供更好的友好的页面。
  2. 性能问题:SPA应用程序需要大量的JavaScript代码来初始化应用程序并交互。这可能导致页面加载时间缓慢,用户体验较差。使用Vue SSR,可以在浏览器中更快地呈现初始HTML的完整标志,并在其中嵌入必要的JavaScript。这样可以加快页面加载速度,并提高用户体验。
  3. 首屏渲染问题:传统的SPA应用程序在首次加载时可能会需要大量时间才能呈现第一个屏幕,直到JavaScript代码完成下载并执行。使用Vue SSR,可以在服务器上呈现组件,并将其作为HTML字符串发送到客户端,从而实现快速呈现首屏的目标。

59.Vue 3.0中Treeshaking特性是什么,并举例进行说明?

Tree shaking 是一种通过清除多余代码方式来优化项目打包体积的技术

Tree shaking是基于ES6模板语法(importexport),主要是借助ES6模块的静态编译思想,在编译时就能确定模块的依赖关系,以及输入和输出的变量

Tree shaking无非就是做了两件事:

  • 编译阶段利用ES6 Module判断哪些模块已经加载
  • 判断那些模块和变量未被使用或者引用,进而删除对应代码

作用:

  • 减少程序体积(更小)
  • 减少程序执行时间(更快)
  • 便于将来对程序架构进行优化(更友好)

60. 虚拟 DOM 的优缺点?

优点:

  • 保证性能下限: 框架的虚拟 DOM 需要适配任何上层 API 可能产生的操作,它的一些 DOM 操作的实现必须是普适的,所以它的性能并不是最优的;但是比起粗暴的 DOM 操作性能要好很多,因此框架的虚拟 DOM 至少可以保证在你不需要手动优化的情况下,依然可以提供还不错的性能,即保证性能的下限;
  • 无需手动操作 DOM: 我们不再需要手动去操作 DOM,只需要写好 View-Model 的代码逻辑,框架会根据虚拟 DOM 和 数据双向绑定,帮我们以可预期的方式更新视图,极大提高我们的开发效率;
  • 跨平台: 虚拟 DOM 本质上是 JavaScript 对象,而 DOM 与平台强相关,相比之下虚拟 DOM 可以进行更方便地跨平台操作,例如服务器渲染、weex 开发等等。

缺点:

  • 无法进行极致优化: 虽然虚拟 DOM + 合理的优化,足以应对绝大部分应用的性能需求,但在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化。

61. 虚拟 DOM 实现原理?

虚拟 DOM 的实现原理主要包括以下 3 部分:

  • 用 JavaScript 对象模拟真实 DOM 树,对真实 DOM 进行抽象;
  • diff 算法 — 比较两棵虚拟 DOM 树的差异;
  • pach 算法 — 将两个虚拟 DOM 对象的差异应用到真正的 DOM 树。

62. Vue 中的 key 有什么作用?

key 是为 Vue 中 vnode 的唯一标记,通过这个 key,我们的 diff 操作可以更准确、更快速。
Vue 的 diff 过程可以概括为:oldCh 和 newCh 各有两个头尾的变量 oldStartIndex、oldEndIndex 和 newStartIndex、newEndIndex,它们会新节点和旧节点会进行两两对比,即一共有4种比较方式:newStartIndex 和oldStartIndex 、newEndIndex 和 oldEndIndex 、newStartIndex 和 oldEndIndex 、newEndIndex 和 oldStartIndex,如果以上 4 种比较都没匹配,如果设置了key,就会用 key 再进行比较,在比较的过程中,遍历会往中间靠,一旦 StartIdx > EndIdx 表明 oldCh 和 newCh 至少有一个已经遍历完了,就会结束比较。
所以 Vue 中 key 的作用是:key 是为 Vue 中 vnode 的唯一标记,通过这个 key,我们的 diff 操作可以更准确、更快速!

  • 更准确:因为带 key 就不是就地复用了,在 sameNode 函数 a.key === b.key 对比中可以避免就地复用的情况。所以会更加准确。
  • 更快速:利用 key 的唯一性生成 map 对象来获取对应节点,比遍历方式更快,源码如下:
function createKeyToOldIdx (children, beginIdx, endIdx) {
  let i, key
  const map = {}
  for (i = beginIdx; i <= endIdx; ++i) {
    key = children[i].key
    if (isDef(key)) map[key] = i
  }
  return map
}

62. Object.defineProperty怎么用, 三个参数?,有什么作用啊?

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

     obj:需要定义属性的对象
     prop:需要定义的属性
     {}:要定义或修改的属性描述符。
	     value: "18",         // 设置默认值 (与 get() 互斥)
	     enumerable: true,    //这一句控制属性可以枚举 enumerable 改为true 就可以参与遍历了   默认值false
	     writable: true,      // 该属性是否可写   默认值false (与 set() 互斥)
	     configurable: true,  // 该属性是否可被删除   默认值false
	      get // 当有人读取 prop 的时候  get函数就会调用,并且返回就是 sss 的值
	      set // 当有人修改 prop 的时候  set函数就会调用, 有个参数这个参数就是修改后的值

63.reactive与ref的区别?

从定义数据角度对比:

  • ref用来定义:基本类型数据

  • reactive用来定义对象(或数组)类型数据

备注:ref也可以用来定义对象(或数组)类型数据, 它内部会自动通过reactive转为代理对象。

从原理角度对比:

  • ref通过Object.defineProperty()的get与set来实现响应式(数据劫持)。
  • reactive通过使用Proxy来实现响应式(数据劫持), 并通过Reflect操作源对象内部的数据。

从使用角度对比:

  • ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value。
  • reactive定义的数据:操作数据与读取数据:均不需要.value。

64.v-on可以监听多个方法吗?

可以一个元素绑定多个事件的两种写法

<a v-on='{click:DoSomething,mouseleave:MouseLeave}'>doSomething</a>
<button @click="a(),b()">点我ab</button>

65.vue3中如何获取refs,dom对象的方式?vue2中如何使用?

vue3:

(1) setup函数方法内,获取单个ref属性绑定的dom元素:先定义一个空的响应式数据ref定义的,你想获取哪个dom元素,在该元素上使用ref属性绑定该数据即可,通过ref.value即可获取到dom节点

(2) 获取多个ref属性绑定的dom元素。使用ref绑定一个函数,在函数里把dom添加到数组里面

//vue2
<h3 ref="myref">myref</h3>

//获取
this.$refs.myref

66.shallowReactive和shallowRef的区别

(1) shallowReactive:只处理对象最外层的响应式(浅响应式)

(2) shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理。

(3) 应用场景:

​ ① 如果有一个对象数据,结构比较深,但变化时候,只是外层属性变化,使用shallowReactive。

​ ② 如果有一个对象数据,后续功能不会修改改对象中的属性,而是生成新的对象来替换,使用shallowRef。

67.provide与inject如何使用

(1) 父子组件传参可以通过props和emit来实现,但是当组件的层次结构比较深时,props和emit就没什么作用了。vue为了解决这个提出了Provide / Inject;provider/inject:简单的来说就是在父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量

(2) provide需要先引入,我们将需要传递给下级组件的变量通过provider(‘传输key’,变量)

(3) Inject,下级组件通过变量方式接收,person= inject(‘传输key’)

68.toRaw 与 markRaw是什么作用?

(1) toRaw :将一个由reactive生成的响应式对象转化为普通对象

使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新.

(2) markRaw:标记一个对象,使其永远不会再成为响应式对象。

应用场景:有些值不应被设置为响应式的,例如复杂的第三方类的库,当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yazNqGD3-1685358312186)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1685349361040.png)]

69.Readonly和shallowReadonly理解

readonly:让一个响应式数据变为只读的(深只读),readonly是一个函数,他会接收一个响应式的数据

shallowReadonly:让一个响应式数据变为只读的(浅只读),shallowReadonly只限制对象中的第一层数据(不能改动,如:salary),但是嵌套的深层次的value属性值 是可以更改的,我们点击更改按钮测试就能发现,被shallowReadonly包裹的对象的深层次值改变了。

70.toref和torefs区别

toReftoRefs 可以用来复制 reactive 里面的属性然后转成 ref,而且它既保留了响应式,也保留了引用

toref(变量,属性),torefs(整个变量)

区别:

  • 在插值表达式中{{}}:
    • 访问 toRefs 的值,需要带上 .value 如果不带上,就会出现双引号 {{user.name.value}}
    • 访问 toRef 的值,不需要带上 .value {{user.name}}
  • 转换属性:
    • toRef: 复制 reactive 里的单个属性并转成 ref
    • toRefs: 复制 reactive 里的所有属性并转成 ref

71.学习 EventBus

首先,在你的项目中创建一个 eventBus.js 文件,并定义一个空的 EventBus 对象:

import Vue from 'vue';
export const EventBus = new Vue();

发送事件

import { EventBus } from './eventBus.js';

// 发送名为 'myEvent' 的事件
EventBus.$emit('myEvent', data);

接收事件

import { EventBus } from './eventBus.js';

EventBus.$on('myEvent', (data)=>{});

取消监听

EventBus.$off('myEvent');

72.vue2过滤器(vue3取消)

filter 过滤器是一种很常用的功能,它可以用于对数据进行格式化、排序、筛选等操作。在使用过程中,我们只需要在模板表达式中使用管道符 |,并将要使用的过滤器的名称作为参数传递进去即可。

全局过滤器:Vue.filter(‘过滤器名称’,function(){})

局部过滤器:filter选项

filters: {
    //filterName过滤器名,value是'|'之前的数据
    filterName(value) {
      if (!value) return '';
      return '你好'+value.toString()
    }
  }

六、Webpack 篇

1. 谈谈你对Webpack的理解(Webpack是什么?)

Webpack 是一个 静态模块打包器,可以分析各个模块的依赖关系,项目中的所有资源皆为模块,通过分析模块间的依赖关系,在其内部递归构建出一个依赖关系图,其中包含应用程序需要的每个模块,然后将这些模块打包成一个或多个 bundle。最终编绎输出模块为 HTML、JavaScript、CSS 以及各种静态文件(图片、字体等)。

webpack 就像一条生产线,要经过一系列处理流程(loader)后才能将源文件转换成输出结果。 这条生产线上的每个处理流程的职责都是单一的,多个流程之间有存在依赖关系,只有完成当前处理后才能交给下一个流程去处理。
插件就像是一个插入到生产线中的一个功能,在特定的时机对生产线上的资源做处理。 webpack 在运行过程中会广播事件,插件只需要监听它所关心的事件,就能加入到这条生产线中,去改变生产线的运作。

webpack的主要作用如下:

  • 模块打包 可以将不同模块的文件打包整合在一起,并且保证它们之间的引用正确,执行有序。利用打包我们就可以在开发的时候根据我们自己的业务自由划分文件模块,保证项目结构的清晰和可读性。
  • 编译兼容 在前端的“上古时期”,手写一堆浏览器兼容代码一直是令前端工程师头皮发麻的事情,而在今天这个问题被大大的弱化了,通过webpack的Loader机制,不仅仅可以帮助我们对代码做polyfill,还可以编译转换诸如.less,.vue,.jsx这类在浏览器无法识别的格式文件,让我们在开发的时候可以使用新特性和新语法做开发,提高开发效率。
  • 能力扩展 通过webpack的Plugin机制,我们在实现模块化打包和编译兼容的基础上,可以进一步实现诸如按需加载,代码压缩等一系列功能,帮助我们进一步提高自动化程度,工程效率以及打包输出的质量。

2. Webpack的打包过程/打包原理/构建流程?

  1. 初始化:启动构建,读取与合并配置参数,加载plugin,实例化Compiler
  2. 编译:从Entry出发,针对每个Module串行调用对应的Loader去翻译文件中的内容,再找到该Module依赖的Module,递归的进行编译处理
  3. 输出:将编译后的Module组合成Chunk,将Chunk转换成文件,输出到文件系统中

细节:

Webpack CLI 通过 yargs模块解析 CLI 参数,并转化为配置对象option(单入口:Object,多入口:Array),调用 webpack(option) 创建 compiler 对象。

如果有 option.plugin,则遍历调用plugin.apply()来注册 plugin,

判断是否开启了 watch,如果开启则调用 compiler.watch,否则调用 compiler.run,开始构建。

创建 Compilation 对象来收集全部资源和信息,然后触发 make 钩子。

make阶段从入口开始递归所有依赖,

每次遍历时调用对应Loader翻译文件中内容,然后生成AST,遍历AST找到下个依赖继续递归,

根据入口和模块之间关系组装chunk,输出到dist中的一个文件内。

在以上过程中,webpack会在特定的时间点(使用tapable模块)广播特定的事件,插件监听事件并执行相应的逻辑,并且插件可以调用webpack提供的api改变webpack的运行结果

3. loader的作用

webpack中的loader是一个函数,主要为了实现源码的转换,所以loader函数会以源码作为参数,比如,将ES6转换为ES5,将less转换为css,然后再将css转换为js,以便能嵌入到html文件中

默认情况下,webpack只支持对js和json文件进行打包,但是像css、html、png等其他类型的文件,webpack则无能为力。因此,就需要配置相应的loader进行文件内容的解析转换。

4. 有哪些常见的Loader?他们是解决什么问题的?

常用的loader如下:

  • image-loader:加载并且压缩图片文件。
  • less-loader:加载并编译 LESS 文件。
  • sass-loader:加载并编译 SASS/SCSS 文件。
  • css-loader:加载 CSS,支持模块化、压缩、文件导入等特性,使用css-loader必须要配合使用style-loader。
  • style-loader:用于将 CSS 编译完成的样式,挂载到页面的 style 标签上。需要注意 loader 执行顺序,style-loader 要放在第一位,loader 都是从后往前执行。
  • babel-loader:把 ES6 转换成 ES5
  • postcss-loader:扩展 CSS 语法,使用下一代 CSS,可以配合 autoprefixer 插件自动补齐 CSS3 前缀。
  • eslint-loader:通过 ESLint 检查 JavaScript 代码。
  • vue-loader:加载并编译 Vue 组件。
  • file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件 (处理图片和字体)
  • url-loader:与 file-loader 类似,区别是用户可以设置一个阈值,大于阈值会交给 file-loader 处理,小于阈值时返回文件 base64 形式编码 (处理图片和字体)。
  • source-map-loader:加载额外的 Source Map 文件,以方便断点调试。

5. plugin的作用

plugin是一个类,类中有一个apply()方法,主要用于Plugin的安装,可以在其中监听一些来自编译器发出的事件,在合适的时机做一些事情。

webpack中的plugin赋予其各种灵活的功能,例如打包优化、资源管理、环境变量注入等,它们会运行在webpack的不同阶段(钩子 / 生命周期),贯穿了webpack整个编译周期。目的在于「解决 loader 无法实现的其他事」。

6. 有哪些常见的Plugin?他们是解决什么问题的?

  • html-webpack-plugin:可以复制一个有结构的html文件,并自动引入打包输出的所有资源(JS/CSS)
  • clean-webpack-plugin:重新打包自动清空 dist 目录
  • mini-css-extract-plugin:提取 js 中的 css 成单独文件
  • optimize-css-assets-webpack-plugin:压缩css
  • uglifyjs-webpack-plugin:压缩js
  • commons-chunk-plugin:提取公共代码
  • define-plugin:定义环境变量

7. Webpack中Loader和Plugin的区别

运行时机
1.loader运行在编译阶段
2.plugins 在整个周期都起作用

使用方式
Loader:1.下载 2.使用
Plugin:1.下载 2.引用 3.使用

loader是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中;plugin赋予了webpack各种灵活的功能,例如打包优化、资源管理、环境变量注入等,目的是解决 loader无法实现的其他事。

在运行时机上,loader 运行在打包文件之前;plugin则是在整个编译周期都起作用。

在配置上,loader在module.rules中配置,作为模块的解析规则,类型为数组。每一项都是一个 Object,内部包含了 test(类型文件)、loader、options (参数)等属性;plugin在 plugins中单独配置,类型为数组,每一项是一个 plugin 的实例,参数都通过构造函数传入。

8. webpack的热更新是如何做到的?说明其原理?

热更新的核心就是客户端从服务端拉去更新后的文件,准确的说是 chunk diff (chunk 需要更新的部分),实际上webpack-dev-server与浏览器之间维护了一个websocket,当本地资源发生变化时,webpack-dev-server会向浏览器推送更新,并带上构建时的hash,让客户端与上一次资源进行对比。客户端对比出差异后会向webpack-dev-server发起 Ajax 请求来获取更改内容(文件列表、hash),这样客户端就可以再借助这些信息继续向webpack-dev-server发起 jsonp 请求获取该chunk的增量更新。

后续的部分(拿到增量更新之后如何处理?哪些状态该保留?哪些又需要更新?)由HotModulePlugin 来完成,提供了相关 API 以供开发者针对自身场景进行处理,像react-hot-loader和vue-loader都是借助这些 API 实现热更新。

详细:
1、在 webpack 的 watch 模式下,文件系统中某一个文件发生修改,webpack 监听到文件变化,根据配置文件对模块重新编译打包,并将打包后的代码通过简单的 JavaScript 对象保存在内存中。
2、webpack-dev-server 和 webpack 之间的接口交互,而在这一步,主要是 dev-server 的中间件webpack-dev-middleware 和 webpack 之间的交互,webpack-dev-middleware 调用 webpack 暴露的 API对代码变化进行监控,并且告诉 webpack,将代码打包到内存中。
3、webpack-dev-server 对文件变化的一个监控,这一步不同于第一步,并不是监控代码变化重新打包。当我们在配置文件中配置了devServer.watchContentBase 为 true 的时候,Server 会监听这些配置文件夹中静态文件的变化,变化后会通知浏览器端对应用进行 live reload。注意,这儿是浏览器刷新,和 HMR 是两个概念
4、webpack-dev-server 代码的工作,该步骤主要是通过 sockjs(webpack-dev-server 的依赖)在浏览器端和服务端之间建立一个 websocket 长连接,将 webpack 编译打包的各个阶段的状态信息告知浏览器端,
同时也包括第三步中 Server 监听静态文件变化的信息。浏览器端根据这些 socket 消息进行不同的操作。当然服务端传递的最主要信息还是新模块的 hash 值,后面的步骤根据这一 hash 值来进行模块热替换。
webpack-dev-server/client 端并不能够请求更新的代码,也不会执行热更模块操作,而把这些工作又交回给了 webpack,webpack/hot/dev-server 的工作就是根据 webpack-dev-server/client 传给它的信息以及 dev-server 的配置决定是刷新浏览器呢还是进行模块热更新。当然如果仅仅是刷新浏览器,也就没有后面那些步骤了。HotModuleReplacement.runtime 是客户端 HMR 的中枢,它接收到上一步传递给他的新模块的 hash 值,它通过 JsonpMainTemplate.runtime 向 server 端发送 Ajax 请求,服务端返回一个 json,该 json 包含了所有要更新的模块的 hash 值,获取到更新列表后,该模块再次通过 jsonp 请求,获取到最新的模块代码。
5、决定 HMR 成功与否的关键步骤,在该步骤中,HotModulePlugin 将会对新旧模块进行对比,决定是否更新模块,在决定更新模块后,检查模块之间的依赖关系,更新模块的同时更新模块间的依赖引用。最后一步,当 HMR 失败后,回退到 live reload 操作,也就是进行浏览器刷新来获取最新打包代码。

9. 如何解决循环依赖问题

Webpack 中将 require 替换为 *webpack_require*,会根据 moduleId 到 installedModules 找是否加载过,加载过则直接返回之前的 export,不会重复加载。

10. 如何提高Webpack构建速度

1. 代码压缩

  • JS 压缩
    webpack 4.0默认在生产环境的时候是支持代码压缩的,即mode=production模式下。实际上webpack 4.0默认是使用terser-webpack-plugin这个压缩插件,在此之前是使用 uglifyjs-webpack-plugin,两者的区别是后者对 ES6 的压缩不是很好,同时我们可以开启 parallel参数,使用多进程压缩,加快压缩。
  • CSS 压缩
    CSS 压缩通常是去除无用的空格等,因为很难去修改选择器、属性的名称、值等。可以使用另外一个插件:css-minimizer-webpack-plugin。
  • HTML 压缩
    使用HtmlWebpackPlugin插件来生成 HTML 的模板时候,通过配置属性minify进行 html 优化。
module.exports = {
plugin:[
  new HtmlwebpackPlugin({
    minify:{
      minifyCSS: false, // 是否压缩css
      collapseWhitespace: false, // 是否折叠空格
      removeComments: true // 是否移除注释
    }
  })
  ]
}

2. 图片压缩

配置image-webpack-loader

3. Tree Shaking

Tree Shaking是一个术语,在计算机中表示消除死代码,依赖于 ES Module 的静态语法分析(不执行任何的代码,可以明确知道模块的依赖关系)。在webpack实现Tree shaking有两种方案:

usedExports:通过标记某些函数是否被使用,之后通过 Terser 来进行优化的

module.exports = {
    ...
    optimization:{
        usedExports
    }
  }

使用之后,没被用上的代码在webpack打包中会加入unused harmony export mul注释,用来告知Terser在优化时,可以删除掉这段代码。

sideEffects:跳过整个模块/文件,直接查看该文件是否有副作用

sideEffects用于告知webpack compiler哪些模块时有副作用,配置方法是在package.json中设置sideEffects属性。如果sideEffects设置为false,就是告知webpack可以安全的删除未用到的exports。如果有些文件需要保留,可以设置为数组的形式,如:

"sideEffecis":[
    "./src/util/format.js",
    "*.css" // 所有的css文件
]

4. 缩小打包域

排除webpack不需要解析的模块,即在使用loader的时候,在尽量少的模块中去使用。可以借助 include和exclude这两个参数,规定loader只在那些模块应用和在哪些模块不应用。

5. 减少 ES6 转为 ES5 的冗余代码

使用bable-plugin-transform-runtime插件

6. 提取公共代码

通过配置CommonsChunkPlugin插件,将多个页面的公共代码抽离成单独的文件

7. 其他

组件懒加载、路由懒加载、开启gzip、公共的第三方包上cdn、配置cache缓存Loader对文件的编译副本、配置resolve提高文件的搜索速度(@: src)


七、性能优化篇

1. 浏览器缓存优化

为了让浏览器缓存发挥最大作用,该策略尽量遵循以下五点就能发挥浏览器缓存最大作用。

  • 「考虑拒绝一切缓存策略」Cache-Control:no-store
  • 「考虑资源是否每次向服务器请求」Cache-Control:no-cache
  • 「考虑资源是否被代理服务器缓存」Cache-Control:public/private
  • 「考虑资源过期时间」Expires:t/Cache-Control:max-age=t,s-maxage=t
  • 「考虑协商缓存」Last-Modified/Etag

缓存策略通过设置HTTP报文实现,在形式上分为**「强缓存/强制缓存」「协商缓存/对比缓存」**。为了方便对比,笔者将某些细节使用图例展示,相信你有更好的理解。
在这里插入图片描述
在这里插入图片描述
整个缓存策略机制很明了,先走强缓存,若命中失败才走协商缓存。若命中强缓存,直接使用强缓存;若未命中强缓存,发送请求到服务器检查是否命中协商缓存;若命中协商缓存,服务器返回304通知浏览器使用本地缓存,否则返回最新资源

有两种较常用的应用场景值得使用缓存策略一试,当然更多应用场景都可根据项目需求制定。

  • 「频繁变动资源」:设置Cache-Control:no-cache,使浏览器每次都发送请求到服务器,配合Last-Modified/ETag验证资源是否有效
  • 「不常变化资源」:设置Cache-Control:max-age=31536000,对文件名哈希处理,当代码修改后生成新的文件名,当HTML文件引入文件名发生改变才会下载最新文件

2. 渲染层面性能优化

**「渲染层面」**的性能优化,无疑是如何让代码解析更好执行更快。因此笔者从以下五方面做出建议。

  • 「CSS策略」:基于CSS规则
  • 「DOM策略」:基于DOM操作
  • 「阻塞策略」:基于脚本加载
  • 「回流重绘策略」:基于回流重绘
  • 「异步更新策略」:基于异步更新

上述五方面都是编写代码时完成,充满在整个项目流程的开发阶段里。因此在开发阶段需时刻注意以下涉及到的每一点,养成良好的开发习惯,性能优化也自然而然被使用上了。

渲染层面性能优化更多表现在编码细节上,而并非实体代码。简单来说就是遵循某些编码规则,才能将渲染层面性能优化发挥到最大作用。

**「回流重绘策略」**在渲染层面性能优化里占比较重,也是最常规的性能优化之一。上年笔者发布的掘金小册《玩转CSS的艺术之美》使用一整章讲解回流重绘,本章已开通试读,更多细节请戳这里。

CSS策略

  • 避免出现超过三层的嵌套规则
  • 避免为ID选择器添加多余选择器
  • 避免使用标签选择器代替类选择器
  • 避免使用通配选择器,只对目标节点声明规则
  • 避免重复匹配重复定义,关注可继承属性

DOM策略

  • 缓存DOM计算属性
  • 避免过多DOM操作
  • 使用DOMFragment缓存批量化DOM操作

阻塞策略

  • 脚本与DOM/其它脚本的依赖关系很强:对``设置defer
  • 脚本与DOM/其它脚本的依赖关系不强:对``设置async

回流重绘策略

  • 缓存DOM计算属性
  • 使用类合并样式,避免逐条改变样式
  • 使用display控制DOM显隐,将DOM离线化

异步更新策略

  • 异步任务中修改DOM时把其包装成微任务

3. 性能优化六大指标

六大指标基本囊括大部分性能优化细节,可作为九大策略的补充。笔者根据每条性能优化建议的特征将指标划分为以下六方面。

  • 「加载优化」:资源在加载时可做的性能优化
  • 「执行优化」:资源在执行时可做的性能优化
  • 「渲染优化」:资源在渲染时可做的性能优化
  • 「样式优化」:样式在编码时可做的性能优化
  • 「脚本优化」:脚本在编码时可做的性能优化
  • 「V8引擎优化」:针对V8引擎特征可做的性能优化

八、其他杂项篇

1. 常见的浏览器内核有哪些?

  • 主要分成两部分:渲染引擎(layout engineer或Rendering Engine)和JS引擎。
    • 渲染引擎:负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入CSS等),以及计算网页的显示方式,然后会输出至显示器或打印机。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核。
    • JS引擎则:解析和执行javascript来实现网页的动态效果。
  • 最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于只指渲染引擎。
  • 常见内核
    • Trident 内核:IE, MaxThon, TT, The World, 360, 搜狗浏览器等。[又称 MSHTML]
    • Gecko 内核:Netscape6 及以上版本,FF, MozillaSuite / SeaMonkey 等
    • Presto 内核:Opera7 及以上。 [Opera内核原为:Presto,现为:Blink;]
    • Webkit 内核:Safari, Chrome等。 [ Chrome的:Blink(WebKit 的分支)]

2. 网页前端性能优化的方式有哪些?

1.压缩 css, js, 图片
2.减少 http 请求次数, 合并 css、js 、合并图片(雪碧图)
3.使用 CDN
4.减少 dom 元素数量
5.图片懒加载
6.静态资源另外用无 cookie 的域名
7.减少 dom 的访问(缓存 dom)
8.巧用事件委托
9.样式表置顶、脚本置低

3. 网页从输入网址到渲染完成经历了哪些过程?

大致可以分为如下7步:

  • 输入网址;
  • 发送到DNS服务器,并获取域名对应的web服务器对应的ip地址;
  • 与web服务器建立TCP连接;
  • 浏览器向web服务器发送http请求;
  • web服务器响应请求,并返回指定url的数据(或错误信息,或重定向的新的url地址);
  • 浏览器下载web服务器返回的数据及解析html源文件;
  • 生成DOM树,解析css和js,渲染页面,直至显示完成;

4. 线程与进程的区别?

  • 一个程序至少有一个进程,一个进程至少有一个线程.
  • 线程的划分尺度小于进程,使得多线程程序的并发性高。
  • 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
  • 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
  • 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。

5. HTTP常见的状态码?

100 Continue 继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息
200 OK 正常返回信息
201 Created 请求成功并且服务器创建了新的资源
202 Accepted 服务器已接受请求,但尚未处理
301 Moved Permanently 请求的网页已永久移动到新位置。
302 Found 临时性重定向。
303 See Other 临时性重定向,且总是使用 GET 请求新的 URI。
304 Not Modified 自从上次请求后,请求的网页未修改过。
400 Bad Request 服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求。
401 Unauthorized 请求未授权。
403 Forbidden 禁止访问。
404 Not Found 找不到如何与 URI 相匹配的资源。
500 Internal Server Error 最常见的服务器端错误。
503 Service Unavailable 服务器端暂时无法处理请求(可能是过载或维护)。

6. 图片懒加载?

当页面滚动的时间被触发 -> 执行加载图片操作 -> 判断图片是否在可视区域内 -> 在,则动态将data-src的值赋予该图片

7. 移动端性能优化?

  • 尽量使用css3动画,开启硬件加速
  • 适当使用touch时间代替click时间
  • 避免使用css3渐变阴影效果
  • 可以用transform: translateZ(0) 来开启硬件加速
  • 不滥用float。float在渲染时计算量比较大,尽量减少使用
  • 不滥用web字体。web字体需要下载,解析,重绘当前页面
  • 合理使用requestAnimationFrame动画代替setTimeout
  • css中的属性(css3 transitions、css3 3D transforms、opacity、webGL、video)会触发GUP渲染,耗电

8. TCP 传输的三次握手、四次挥手策略

  • 三次握手:

    为了准确无误地吧数据送达目标处,TCP协议采用了三次握手策略。用TCP协议把数据包送出去后,TCP不会对传送后的情况置之不理,他一定会向对方确认是否送达,握手过程中使用TCP的标志:SYN和ACK

    • 发送端首先发送一个带SYN的标志的数据包给对方
    • 接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息
    • 最后,发送端再回传一个带ACK的标志的数据包,代表“握手”结束
  • 如在握手过程中某个阶段莫明中断,TCP协议会再次以相同的顺序发送相同的数据包


  • 断开一个TCP连接需要“四次挥手”
    • 第一次挥手:主动关闭方发送一个FIN,用来关注主动方到被动关闭方的数据传送,也即是主动关闭方告诫被动关闭方:我已经不会再给你发数据了(在FIN包之前发送的数据,如果没有收到对应的ACK确认报文,主动关闭方依然会重发这些数据)。但是,此时主动关闭方还可以接受数据
    • 第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号收到序号 +1(与SYN相同,一个 FIN占用一个序号)
    • 第三次挥手:被动关闭方发送一个 FIN。用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会给你发送数据了
    • 第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手

9. HTTP 和 HTTPS,为什么HTTPS安全?

  • HTTP协议通常承载与 TCP协议之上,在HTTP和TCP之间添加一个安全协议层(SSL或TSL),这个时候,就成了我们常说的HTTPS
  • 默认HTTP的端口号为80,HTTPS的端口号为443
  • 因为网络请求需要中间有很多的服务器路由的转发,中间的节点都可能篡改信息,而如果使用HTTPS,密钥在你和终点站才有,https之所有说比http安全,是因为他利用ssl/tls协议传输。包含证书,流量转发,负载均衡,页面适配,浏览器适配,refer传递等,保障了传输过程的安全性

10. axios和fetch区别对比

axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范,它本身具有以下特征

  • 从浏览器中创建 XMLHttpRequest
  • 支持 Promise API
  • 客户端支持防止CSRF
  • 提供了一些并发请求的接口(重要,方便了很多的操作)
  • 从 node.js 创建 http 请求
  • 拦截请求和响应
  • 转换请求和响应数据
  • 取消请求
  • 自动转换JSON数据

fetch优势:

  • 语法简洁,更加语义化
  • 基于标准 Promise 实现,支持 async/await
  • 同构方便,使用 isomorphic-fetch
  • 更加底层,提供的API丰富(request, response)
  • 脱离了XHR,是ES规范里新的实现方式

fetch存在问题

  • fetch是一个低层次的API,你可以把它考虑成原生的XHR,所以使用起来并不是那么舒服,需要进行封装。
  • fetch只对网络请求报错,对400,500都当做成功的请求,服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。
  • fetch默认不会带cookie,需要添加配置项: fetch(url, {credentials: ‘include’})
  • fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费
  • fetch没有办法原生监测请求的进度,而XHR可以

九、主观题篇

1. 你都做过什么项目呢?具体聊某一个项目中运用的技术.

注意:用心找自己做的项目中自己感觉最拿出来手的(复杂度最高,用的技术最多的项目),描述的时候尽可能往里面添加一些技术名词
布局我们用html5+css3
我们会用reset.css重置浏览器的默认样式
JS框架的话我们选用的是jQuery(也可能是Zepto)
我们用版本控制工具git来协同开发
我们会基于gulp搭建的前端自动化工程来开发(里面包含有我们的项目结构、我们需要引用的第三方库等一些信息,我们还实现了sass编译、CSS3加前缀等的自动化)
我们的项目中还用到了表单验证validate插件、图片懒加载Lazyload插件

2. 你遇到过比较难的技术问题是?你是如何解决的?

3. 常使用的库有哪些?常用的前端开发工具?开发过什么应用或组件?

4. 除了前端以外还了解什么其它技术么?你最最厉害的技能是什么?

5. 对前端开发工程师这个职位是怎么样理解的?它的前景会怎么样?

前端是最贴近用户的程序员,比后端、数据库、产品经理、运营、安全都近。
1、实现界面交互
2、提升用户体验
3、有了Node.js,前端可以实现服务端的一些事情
前端是最贴近用户的程序员,前端的能力就是能让产品从 90分进化到 100 分,甚至更好,
参与项目,快速高质量完成实现效果图,精确到1px;
与团队成员,UI设计,产品经理的沟通;
做好的页面结构,页面重构和用户体验;
处理hack,兼容、写出优美的代码格式;
针对服务器的优化、拥抱最新前端技术。

你发送数据了

  • 第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手

9. HTTP 和 HTTPS,为什么HTTPS安全?

  • HTTP协议通常承载与 TCP协议之上,在HTTP和TCP之间添加一个安全协议层(SSL或TSL),这个时候,就成了我们常说的HTTPS
  • 默认HTTP的端口号为80,HTTPS的端口号为443
  • 因为网络请求需要中间有很多的服务器路由的转发,中间的节点都可能篡改信息,而如果使用HTTPS,密钥在你和终点站才有,https之所有说比http安全,是因为他利用ssl/tls协议传输。包含证书,流量转发,负载均衡,页面适配,浏览器适配,refer传递等,保障了传输过程的安全性

10. axios和fetch区别对比

axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范,它本身具有以下特征

  • 从浏览器中创建 XMLHttpRequest
  • 支持 Promise API
  • 客户端支持防止CSRF
  • 提供了一些并发请求的接口(重要,方便了很多的操作)
  • 从 node.js 创建 http 请求
  • 拦截请求和响应
  • 转换请求和响应数据
  • 取消请求
  • 自动转换JSON数据

fetch优势:

  • 语法简洁,更加语义化
  • 基于标准 Promise 实现,支持 async/await
  • 同构方便,使用 isomorphic-fetch
  • 更加底层,提供的API丰富(request, response)
  • 脱离了XHR,是ES规范里新的实现方式

fetch存在问题

  • fetch是一个低层次的API,你可以把它考虑成原生的XHR,所以使用起来并不是那么舒服,需要进行封装。
  • fetch只对网络请求报错,对400,500都当做成功的请求,服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。
  • fetch默认不会带cookie,需要添加配置项: fetch(url, {credentials: ‘include’})
  • fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费
  • fetch没有办法原生监测请求的进度,而XHR可以

九、主观题篇

1. 你都做过什么项目呢?具体聊某一个项目中运用的技术.

注意:用心找自己做的项目中自己感觉最拿出来手的(复杂度最高,用的技术最多的项目),描述的时候尽可能往里面添加一些技术名词
布局我们用html5+css3
我们会用reset.css重置浏览器的默认样式
JS框架的话我们选用的是jQuery(也可能是Zepto)
我们用版本控制工具git来协同开发
我们会基于gulp搭建的前端自动化工程来开发(里面包含有我们的项目结构、我们需要引用的第三方库等一些信息,我们还实现了sass编译、CSS3加前缀等的自动化)
我们的项目中还用到了表单验证validate插件、图片懒加载Lazyload插件

2. 你遇到过比较难的技术问题是?你是如何解决的?

3. 常使用的库有哪些?常用的前端开发工具?开发过什么应用或组件?

4. 除了前端以外还了解什么其它技术么?你最最厉害的技能是什么?

5. 对前端开发工程师这个职位是怎么样理解的?它的前景会怎么样?

前端是最贴近用户的程序员,比后端、数据库、产品经理、运营、安全都近。
1、实现界面交互
2、提升用户体验
3、有了Node.js,前端可以实现服务端的一些事情
前端是最贴近用户的程序员,前端的能力就是能让产品从 90分进化到 100 分,甚至更好,
参与项目,快速高质量完成实现效果图,精确到1px;
与团队成员,UI设计,产品经理的沟通;
做好的页面结构,页面重构和用户体验;
处理hack,兼容、写出优美的代码格式;
针对服务器的优化、拥抱最新前端技术。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/585808.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

千万级oracle数据表定时同步到mysql表的方案

1&#xff1a;业务背景 第三方系统提供了一张oracle视图&#xff0c;该视图有六千多万条数据&#xff0c;后续每月会产生三百万条数据的数据。需要每天将数据定时同步到自己系统的mysql表中。 &#xff08;注&#xff1a;我们系统与外界系统访问都要经过一个中间系统的跳转才…

看我0~1精通自动化测试实战,暴涨18K...

前言 开头&#xff0c;先说一下现主流的接口自动化测试框架配套&#xff0c;也是很多企业在使用的。 接口自动化测试&#xff1a;PythonrequestspytestyamlalluerJenkins&#xff1b; Python自动化测试&#xff1a;7天练完这60个实战项目&#xff0c;年薪过35w。 除开测试脚本…

基于秒杀-----分布式锁----lua脚本

基于商品显示秒杀-一人一单业务_xzm_的博客-CSDN博客改进 分布式锁&#xff1a;满足分布式系统或集群模式下多进程可见并且互斥的锁 分布式锁的五个基本要求&#xff1a;多进程可见&#xff0c;互斥&#xff0c;高可用&#xff0c;高性能&#xff0c;安全性 三种实现方式 redi…

《斯坦福数据挖掘教程·第三版》读书笔记(英文版) Chapter 9 Recommendation Systems

来源&#xff1a;《斯坦福数据挖掘教程第三版》对应的公开英文书和PPT Chapter 9 Recommendation SystemsRecommendation systems use a number of different technologies. We can classify these systems into two broad groups. Content-based systems examine properties…

STL 函数对象,即仿函数

目录 1.函数对象 1.1函数对象的概念 1.2函数对象的使用 2.谓词 2.1谓词概念 2.2一元谓词 2.3二元谓词 3.内建函数对象 3.1内建函数对象的意义 3.2算术仿函数 3.3关系仿函数 3.4逻辑仿函数 1.函数对象 1.1函数对象的概念 1.2函数对象的使用 #include<iostream>…

文心一言 VS 讯飞星火 VS chatgpt (25)-- 算法导论4.2 7题

七、设计算法&#xff0c;仅使用三次实数乘法即可完成复数 abi和cdi 相乘。算法需接收a、b、c和d 为输入&#xff0c;分别生成实部 ac-bd 和虚部adbc。 文心一言&#xff1a; 可以使用如下算法来计算复数 abi 和 cdi 的积&#xff0c;且只需进行三次实数乘法&#xff1a; 1.…

Slower使用教程完整版本【2023年更新】

Slower软件的版本&#xff0c;目前市面上有多种。 如果你指的是Slower器加速软件的话&#xff0c;可以看下面的教程&#xff1a; Slower是一款很不错的安全国际互联网工具&#xff0c;广泛用于外贸与留学生行业&#xff0c;设计师行业与科研行业。但是&#xff0c;因为使用过…

注意:腾讯云轻量应用服务器十大限制说明

腾讯云轻量应用服务器相对于云服务器CVM是有一些限制的&#xff0c;比如轻量服务器不支持更换内网IP地址&#xff0c;不支持自定义私有网络VPC&#xff0c;内网连通性方面也有限制&#xff0c;轻量不支持CPU内存、带宽或系统盘单独升级&#xff0c;只能整个套餐整体升级&#x…

IO系统(计算机组成原理)

IO系统这一章主要讲的就是IO的四种控制方式&#xff0c;首先对这四种方式进行一个简单介绍&#xff0c;下面再对着四种方式分别进行介绍。 程序查询方式&#xff1a;由cpu通过程序不断查询IO设备是否已经做好准备&#xff0c;从而控制IO设备于主机进行信息交换 程序中断方式&am…

python自动化测试面试题,25K入职字节测试岗

问&#xff1a; http 和 https的区别   答&#xff1a; https需要申请ssl证书&#xff0c;https是超文本传输协议&#xff0c;信息是明文传输&#xff0c;https则是具有安全性的ssl加密传输协议http和https使用的是不同的链接方式&#xff0c;用的端口也不一样&#xff0c;前…

《深入理解计算机系统》读书笔记1

1.1信息就是位上下文 只由ASCLL字符构成的文件称为文本文件&#xff0c;所有其他文件都称为二进制文件。 系统中的所有的信息都由一串比特表示。区分不同数据对象的唯一方法是读到这些数据对象时的上下文。 1.2程序被其他程序翻译成不同的格式 预编译&#xff0c;编译&#xf…

【C++】类的访问权限

欢迎来到博主 Apeiron 的博客&#xff0c;祝您旅程愉快 &#xff01;时止则止&#xff0c;时行则行。动静不失其时&#xff0c;其道光明。 目录 1、缘起 2、示例代码 3、总结 1、缘起 在 C 中&#xff0c;类在设计时&#xff0c;可以把 属性 和 行为 放在不同的权限下加以…

智警杯赛前学习1.1---excel基本操作

修改默认设置 步骤一&#xff1a;打开“Excel选项”窗口&#xff0c;打开“文件”菜单&#xff0c;选择“选项”标签 步骤二&#xff1a;在“Excel选项”窗口中&#xff0c;选择“常规与保存”标签&#xff0c;在“常规与保存”标签中&#xff0c;可以修改录入数据时的默认字体…

【群智能算法改进】一种改进的沙丘猫群优化算法 改进沙丘猫群算法 改进SCSO[1]【Matlab代码#34】

文章目录 【获取资源请见文章第5节&#xff1a;资源获取】1. 原始沙丘猫群优化算法2. 改进沙丘猫群算法2.1 Logistic混沌映射种群初始化2.2 透镜成像折射反向学习策略2.3 动态因子2.4 黄金正弦策略 3. 部分代码展示4. 仿真结果展示5. 资源获取 【获取资源请见文章第5节&#xf…

国际标准 ISO 11898 解读

从 1993 第一个版 CAN 国际标准&#xff08;ISO 11898:1993 和 ISO 11519-2&#xff09;发布至今&#xff0c;ISO 11898 逐渐被分割整合成了相互独立的 6 个部分。分别以 Part 1 ~ Part 6 来标识。在旧版本&#xff08;2003年之前&#xff09;中 ISO 11898 是通信速度为 5kbps…

二维笛卡尔坐标系下的角的概念

文章目录 参考环境笛卡尔坐标系二维笛卡尔坐标系三维笛卡尔坐标系 任意角角的静态定义角的动态定义二维笛卡尔坐标系下角的概念方向正角、负角及零角 象限角象限象限角 终边相同角圆心角终边相同角 参考 项目描述搜索引擎Google 、Bing百度百科首页韩庆波正负角佟大大还是ETT【…

前端学习---Vue(6)路由

一、前端路由的概念和原理 Hash地址与组件的对应关系。 Hash:url中#之后的都是Hash地址 location.hash 1.1 前端路由的工作方式 ① 用户点击了页面上的路由链接 ② 导致了 URL 地址栏中的 Hash 值发生了变化 ③ 前端路由监听了到 Hash 地址的变化 ④ 前端路由把当前 Hash…

doris分区、join

动态分区和临时分区 动态分区 旨在对表级别的分区实现生命周期管理(TTL)&#xff0c;减少用户的使用负担。 目前实现了动态添加分区及动态删除分区的功能。只支持 Range 分区。原理 在某些使用场景下&#xff0c;用户会将表按照天进行分区划分&#xff0c;每天定时执行例行任…

tidyverse中filter行筛选时缺失值存在的一个坑

大家好&#xff0c;我是邓飞&#xff0c;好久没有更新博客了&#xff0c;是因为好久没有进步了。 之前我认为鲁迅说的对&#xff0c;他在《野草》中写道&#xff1a;“当我沉默着的时候&#xff0c;我觉得充实&#xff1b;我将开口&#xff0c;同时感到空虚”。现在确切的情况…

msvcr90.dll丢失的解决方法

在使用计算机的过程中&#xff0c;我们时常会遇到一些问题&#xff0c;比如应用程序无法正常启动&#xff0c;提示msvcr90.dll文件丢失&#xff0c;这个问题困扰了许多计算机用户。那么&#xff0c;怎么才能解决这个问题呢&#xff1f; 首先&#xff0c;让我们先了解一下msvcr…