文章目录

Vue

vue的优点是什么?

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式JavaScript框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。

渐进式: 声明式渲染→组件系统→客户端路由→集中式状态管理→项目构建

  • 低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
  • 可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
  • 独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计
  • 可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。

vue生命周期(重要)

对生命周期的理解(什么是vue生命周期,vue生命周期钩子,划分阶段)

Vue 实例从创建到销毁的过程,就是vue生命周期,vue生命周期钩子,在达到某一阶段或条件时去触发的函数,目的是完成一些动作或者事件

它可以总共分为8个阶段:创建前/后, 挂载前/后,更新前/后,销毁前/销毁后

create阶段:vue实例被创建

mount阶段: vue实例被挂载到真实DOM节点

update阶段:当vue实例里面的data数据变化时,触发组件重新渲染

destroy阶段:vue实例被销毁

第一次页面加载会触发哪几个钩子?

第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子

DOM 渲染在 mounted 中就已经完成了

每个生命周期适合哪些场景?

  1. beforeCreate在实例初始化之后,数据观测和事件配置之前被调用。
  2. created在实例创建完成后被立即调用。
  3. beforeMount在挂载开始之前被调用。
  4. mounted : 挂载元素,获取到DOM节点 ajax操作是在mounted生命周期中完成的。(activated: keep-alive组件激活时调用)
  5. beforeUpdate数据更新时调用,发生在虚拟DOM打补丁之前。
  6. updated由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子
  7. beforeDestroy实例销毁之前调用。
  8. destroyed实例销段后调用。
    在这里插入图片描述

data为什么用函数的方式写?
data是一个函数时,每个组件实例都有自己的作用域,每个实例相互独立,不会相互影响

vue生命周期在真实场景下的业务应用

created:初始化数据(ajax请求异步数据的请求)

mounted: 挂载元素,获取dom节点

nextTick: 针对单一事件更新数据后立即操作dom

updated: 任何数据的更新,做统一的业务逻辑处理

watch: 监听具体数据变化,并做相应的处理

created和mounted的区别(重点)

created:是在模板渲染成HTML之前调用的,此时data已经准备完毕,el仍是undefined,不能操作dom节点,主要用来初始化一些数据;

即使created中的方法没有执行完,mounted也会被调用

mounted:是在模板渲染成HTML之后调用的,此时data,el都已准备好,可以操作html的dom节点

什么是 MVVM?

MVVMModel-View-ViewModel缩写,是一种基于前端开发的架构模式。Model代表数据,View代表视图,ViewModel视图模型是ViewModel的桥梁,ViewModel是View和Model的桥梁,ViewModel会通过Data Binding(数据绑定)将model的改变渲染到视图中,会通过DOM Listener(DOM监听)监听view的变化更新数据。
MVC是Model-View- Controller的简写。即数据-视图-控制器,MVC 框架解决了代码大杂烩的问题,它把代码分成了职责分明的三层,M 指的是数据模型 Modal,V 指的视图模板 View,C 指的是控制器 Controller。MVC 强调的是数据、视图和逻辑之间松耦合,其文件结构也是按这三类分门别类地组织起来的。
实现: 在Controller里面把数据赋值给视图
缺点:不适合小型项目的开发,视图与控制器间的连接过于紧密,妨碍了他们的独立重用

双向数据绑定原理(重点)

双向数据绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化。Vue中双向绑定使用v-model指令来实现标签内容的绑定.如表单元素和数据的双向绑定
原理:vue采用数据监听和发布者-订阅模式,通过Object.defineProperty()来劫持各个属性的setter和getter,当数据变动时候发布消息给订阅者,触发相应回调。

简答版本 :当一个Vue实例创建时,Vue会遍历data选项的属性,用 Object.defineProperty 将它们转为 setter/getterr并且在内部追踪相关依赖,在属性被访问和修改时通知变化。每个组件实例都有相应的 watcher 程序实例,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher重新计算,从而致使它关联的组件得以更新。

单向数据流props传递数据原则:单向数据流,只能父传子所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解
1.需要observer递归的遍历对象,包括对象的对象,给对象的某个值赋值或者改变,触发setter,那么监听到了数据的变化。

2.complie解析各个v-的操作指令,将模板的变量替换成数据,初始化页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦有数据变动,接收通知,更新视图。

3.watcher是observer和complie的桥梁,首先自身实例化向属性订阅器dep中添加自身,其次自身有一个update方法,在属性变动时,dep.notice()通知,调用自身的update方法,触发complie的回调。

在这里插入图片描述

vue自定义指令

内置指令不满足需求需要自定义指令 分为局部指令(只能在本组件使用)和全局指令

1.创建局部指令 
var app = new Vue({
    el: '#app',
    data: {    
    },
    // 创建指令(可以多个)
    directives: {
        // 指令名称
       focus: {
          inserted: function(el) {
            el.focus();
          }
        }
    }
})
 
2.创建全局指令
Vue.directive('foucs', {
    //当被绑定元素插入到DOM中时调用
    inserted:function(el){
	 //获取元素的焦点  e1:指令所绑定的元素,可以用来直接操作DOM.
	el.focus()
	}
})
 
3.指令的使用
<div id="app">
    //foucs为指令名称  调用时加v-
    <div v-foucs></div>
</div>

vue自定义组件

全局组件组成语法: 使用Vue.component('button-counter', cpnc)方式注册,直接使用<button-counter></button-counter>调用。button-counter是全局组件的名字,cpnc是定义的组件对象。

     Vue.component("button-counter", {
        data: 组件数据,
        template: 组件模块内容
      });
     <div id="app">
      <!-- 组件的使用 -->
      <button-counter></button-counter>
      <button-counter></button-counter>
    </div>

组件组成注意事项:1.**data必须是一个函数 **保证每个模板的数据是相互独立的 2.组件模板内容必须是单个跟元素只能有一个父元素,如上面代码中的div 3.**组件模板内容可以是模板字符串**ES6 引入新的声明字符串的方式 4.组件命名方式短横线方式 my-component (推荐)驼峰方式 MyComponent

局部组件注册:只能在当前vue实例挂载的对象中使用,类似于局部变量,有块级作用域。使用方式与全局变量一样,直接使用<hello-world></hello-world>调用。 'hello-world’为组件命名的名字,HelloWorld为定义的组件对象。

<body>
  <div id="app">
    <hello-world></hello-world>
  </div>
  <script type='text/javascript' src='js/vue.js'></script>
  <script type='text/javascript'>
    var HelloWorld = {
      data: function () {
        return {
          msg: 'helloworld'
        }
      },
      template: `
  <div>{{msg}}</div>
  `
    }
    const app = new Vue({
      el: "#app",
      data: {},
      components: {
        'hello-world': HelloWorld
      }
    })
  </script>
</body>

Vue组件之间的的通信(传值)方式(重点)

父向子传值:子组件设置props + 父组件设置v-bind属性绑定

子向父传值: 子组件的$emit + 父组件设置v-on事件绑定

兄弟组件任意组件通信:通过事件车的方式传递数据, 新建一个空的全局Vue对象 EventBus,利用$emit发送 , $on接收

v-show和v-if的区别(重点)

v-show指令是通过修改元素的display属性让其显示或者隐藏

v-if指令是直接销毁和重建DOM达到让元素显示和隐藏的效果

开发中常用的指令有哪些

v-if:判断元素显示与隐藏;v-for:数据循环;v-bind:标签属性绑定;v-model:实现双向绑定 v-on事件绑定
v-if只有在为true的时候才会显示数据,v-if为true的时候执行if,否则,执行else

vue如何导入插件在main.js中导入插件,然后在use

computed和watch有什么区别?(重点)

computed:计算属性,依赖其他属性,当其他属性改变的时候,下一次获取computed值时也会改变,computed的值会有缓存
watch:监听属性,监听具体数据变化,当数据属性变化时, 回调函数handler自动调用, 在函数内部进行计算

区别:

  1. computed能完成的功能,watch都可以完成。watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。
  2. 当我们要进行数值计算,而且依赖于其他数据,那么把这个数据设计为computed
  3. 如果你需要在某个数据变化时做一些事情,使用watch来观察这个数据变化

计算属性computed和方法的区别

  • 计算属性是基于它们的依赖进行缓存,如果多次使用时,计算属性只会调用一次,性能上计算属性明显比methods好,如果依赖改变则重新缓存
  • 方法不缓存

vuex的组成和原理(重点)

vuex 是什么?

vuex:全局状态(数据)管理机制,可以方便的实现组件之间数据的共享

vuex有哪几种属性?

有五种,分别是 State、Getter、Mutation、Action、Module

state:存储数据,所有共享的数据都要统一放到 Store 的 State 中进行存储,在根实例中注册了store 后,用 this.$store.state 来访问;对应vue里面的data;存放数据方式为响应式,vue组件从store中读取数据,如数据发生变化,组件也会对应的更新。

getter:可以认为是 store 的计算属性,它的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

mutation:用于变更 Store中的数据。

action:用于处理异步任务,通过提交 mutation 间接更变状态。

module:将 store 分割成模块,每个模块都具有state、mutation、action、getter、甚至是嵌套子模块。

Vuex 的好处

①能够在 vuex 中集中管理共享的数据,易于开发和后期维护

②能够高效地实现组件之间的数据共享,提高开发效率

③存储在 vuex 中的数据都是响应式的,能够实时保持数据与页面的同步

vue.js中ajax请求代码应该写在组件的methods还是vuex的action中

ajax请求如果是公用,还是写在 vuex 的action 中,而私有 则 写在methods中。

如何让css只在当前组件中起作用

将当前组件的 (style)修改为(style scoped 组件私有) 通过ref标注DOM元素,通过$refs获取DOM元素

slot-scope='scope’本身父组件使用slot插槽是无法获取子组件的数据的,但是使用了slot-scope就可以获取到子组件的数据( 可以获取row, column, $index 和 store(table 内部的状态管理)的数据)

vue.nextTick()的用处?

nextTick 在DOM更新循环结束之后执行延迟回调,用于获得更新后的DOM。

  • 应用

    想要在Vue生命周期函数中的created()操作DOM可以使用Vue.nextTick()回调函数

    在数据改变后要执行的操作,而这个操作需要等数据改变后而改变DOM结构的时候才进行操作,需要用到nextTick

后端路由 前端路由 SPA(重点)

路由的本质就是对应关系,请求什么响应什么
后端路由根据不同的URL地址分发不同的服务器资源(URL 请求地址与服务器资源之间的对应关系)
前端路由负责事件监听,触发事件后通过事件函数渲染不同内容(用户事件与事件处理函数之间的对应关系)本质就是监听 URL 的变化,然后匹配路由规则,显示相应的页面,并且无须刷新页面。
SPA(Single Page Application)单页面应用程序:整个网站只有一个页面,基于URL地址的hash实现,只有第一次会加载页面, 以后的每次请求,内容的变化通过Ajax局部更新实现、同时支持浏览器地址栏的前进和后退操作
SPA实现原理之一:基于URL地址的hash(hash的变化会导致浏览器记录访问历史的变化、但是hash的变化不会触发新的URL请求),只有第一次会加载页面, 以后的每次请求, 仅仅是获取必要的数据.然后, 由页面中js解析获取的数据, 展示在页面中

vue-router 路由模式(重点)

vue-router是vue.js官方路由管理器。 前端路由实现本质就是监听 URL 的变化,然后匹配路由规则,显示相应的页面,并且无须刷新页面。
vue路由跳转方式:
<router-link :to=“{name:‘aa’}”
导航路由跳转 this.$router.push(‘/home’),

  • hash模式
    监听hashchange事件实现前端路由,利用url中的hash来模拟一个hash,以保证url改变时,页面不会重新加载。
  • history模式
    利用pushstate和replacestate来将url替换但不刷新,但是有一个致命点就是,一旦刷新的话,就会可能404,因为没有当前的真正路径,要想解决这一问题需要后端配合,将不存在的路径重定向到入口文件。

vue-router有哪几种导航钩子

vue-router导航钩子即路由的生命周期函数,主要用来拦截导航,让它完成跳转或取消。

第一种:是全局导航钩子 最常用前置守卫router.beforeEach(to,from,next),作用:跳转前进行判断拦截

第二种:局部导航钩子

第三种:路由独享守卫

页面导航的两种方式

  • 声明式导航:通过点击链接实现导航的方式 例如:普通网页中的<a></a> 链接或vue 中的<router-link></router-link>
  • 编程式导航:通过调用JavaScript形式的API实现导航的方式 例如:普通网页中的location.href
  • 常用的编程式导航API :
    跳转: this. r o u t e r . p u s h ( ′ h a s h 地 址 ′ ) ‘ 前进或后退 ‘ : t h i s . router.push('hash地址') `前进或后退`: this. router.push(hash)前进或后退:this.router.go(n)

vue-router实现路由懒加载( 动态加载路由 )(重点)

路由懒加载:当打包构建应用时,js 包会变得非常大,影响页面加载。把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,效率更高
结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载.
安装 @babel/plugin-syntax-dynamic-import
在babel.config.js中声明该插件,打开babel.config.js
将路由更改为按需加载的形式,打开router文件夹的index.js文件夹

component: () => import('@/components/Two')

const Index = () => import(/* webpackChunkName: "group-home" */  '@/views/index')
const routers = [
    {
        path: '/',
        name: 'index',
        component: Index
    }

Vue事件修饰符

once 设置事件只能触发一次(第二次以及以上将不会触发)
prevent阻止默认事件的发生(例如,点击超链接,不会进行跳转)
stop 阻止冒泡(阻止事件向上级DOM元素传递)
number:表单输入的字符串转化为数值
trim:去掉开始和结尾的空格
lazy:将input事件切换为change事件 input事件立即触发 change事件失去焦点触发

diff算法(重点)

diff算法用于比较新旧虚拟节点之间差异的一种算法,每个虚拟节点都有一个唯一标识Key,通过对比新旧节点的key来判断节点是否改变,将两个节点不同的地方存储在patch对象,最后利用patch记录的消息局部更新DOM

虚拟DOM的优缺点

虚拟DOM(VNode)也可以理解为虚拟节点
虚拟DOM是一个用来描述真实dom结构的js对象

  • 优点
    • 减少了dom操作,减少了回流与重绘
    • 保证性能的下限,比正常的DOM性能更好
  • 缺点
    • 首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHTML插入慢

Vue的(v-if)Key的作用

key主要用在虚拟Dom算法中,每个虚拟节点都有一个唯一标识Key,通过对比新旧节点的key来判断节点是否改变,可以大大提高渲染效率

keep-alive的实现(重点)

keep-alive 是 Vue的 内置组件,可以使被包含的组件保留状态,实现缓存,避免重新渲染 ,

钩子函数:

`activated `组件渲染后调用
`deactivated `组件销毁后调用

原理:keep-alive组件缓存是基于虚拟节点而不是直接存储DOM结构。(Vue.js内部将DOM节点抽象成了一个个的虚拟节点)它将满足条件的组件在cache对象中缓存起来,在需要重新渲染的时候再将虚拟节点从cache对象中取出并渲染。

组件插槽

插槽的目的是让我们原来的设备具备更多的扩展性。比如电脑的USB我们可以插入U盘。
组件插槽是Vue的内置组件,为了让我们封装的组件更加具有扩展性,让使用者可以决定组件内部的一些内容到底展示什么。组件插槽的作用:父组件向子组件传递内容

  1. 匿名插槽 唯一存在 <slot></slot>
  2. 具名插槽 可存在多个 <slot name="up"></slot>
  3. 插槽的使用 子组件定义插槽的位置 父组件定义插槽的内容, 控制内容的显示与隐藏

Vue-CLi是啥?

它是一个vue.js的脚手架工具。自动生成项目目录,配置好Webpack和各种依赖包

对 Vue 项目进行哪些优化?

代码层面的优化

v-if 和 v-show 区分使用场景
computed 和 watch  区分使用场景
v-for 遍历必须为 item 添加 key,且避免同时使用 v-if
长列表性能优化
事件的销毁
图片资源懒加载
路由懒加载
第三方插件的按需引入
优化无限列表性能
服务端渲染 SSR or 预渲染

Webpack 层面的优化

Webpack 对图片进行压缩
减少 ES6 转为 ES5 的冗余代码
提取公共代码
模板预编译
提取组件的 CSS
优化 SourceMap
构建结果输出分析
Vue 项目的编译优化

基础的 Web 技术的优化

开启 gzip 压缩
浏览器缓存
CDN 的使用
使用 Chrome Performance 查找性能瓶颈

git常用的命令(记住这个就可以)

Git是一个版本管理控制系统(缩写VCS),它可以在任何时间点,将文档的状态作为更新记录保存起来,也可以在任何时间点,将更新记录恢复回来。Git是在本地下载安装的,然后通过git可以将代码上传到gitee和github中
git常用的命令
git checkout -b xxxxx:创建一个名为xxxxx的分支

git branch:查看当前所在的分支

git status:查看当前的文件状态

git add .:将修改和新增的文件提交到暂存区

git commit -m “xxxxxxxx”:将暂存区的所有代码提交到本地仓库(xxxxx为提交信息比如完成了什么功能)

git chenkout xxxx:切换到已有的分支(xxx为分支的名称)

git merge xxx:合并xxx分支到当前的分支

git push:把本地最新的当前的分支的代码推送到码云中

git push -u origin xxxx:将当前的子分支推送到云端origin仓储的xxxx分支

git提交代码时发生冲突:
代码提交的时候常常会发生冲突的情况,尤其是协同开发的情况下。在合并分支的时候,master分支和dev分支恰好有人都修改了同一个文件,git不知道应该以哪一个人的文件为准,也就是说两个分支相同文件相同位置的的不同操作! 所以就产生了冲突了
git stash将工作区的修改部分进行保存
git pull拉取远程分支上的代码并合并到本地分支,目的是消除冲突;
git stash pop把保存在工作区的修改部分合并到最新的工作空间中

Webpack

什么是Webpack

webpack是一个打包模块化的工具,在webpack里一切文件皆模块,通过loader转换文件,通过plugin注入钩子,最后输出由多个模块组合成的文件。(打包原理:将所有依赖打包成一个bundle.js,通过代码分割成单元片段按需加载)
打包流程:初始化参数、编译模块、输出资源
模块热更新,可以使代码修改过后无需刷新浏览器就可以局部更新,是高级版的自动刷新浏览器
entry 入口,构建项目的起点位置,默认为./src/index.js
output 出口,打包之后的输出位置,默认为./dist

webpack 和 vite 的区别

webpack和vite都是前端构建工具,但它们有一些区别:

  • 构建速度:Vite 的构建速度比 Webpack 更快,因为 Vite 在开发环境下使用了浏览器原生的 ES 模块加载,而 Webpack使用打包后的文件进行模块加载。在 Vite 中,每个模块都可以独立地进行编译和缓存,这意味着vite的HMR(模块热更新)只需要重新编译修改过的模块,而不是整个应用程序。这使得 Vite 开发起来更加高效。
  • 配置复杂度:Vite开箱即用,配置相对简单,只需指定一些基本的选项就可以开始开发。Webpack 的配置更加复杂,需要针对具体项目进行不同的配置,且需要理解各种插件、Loader 等概念。
  • 生态环境:Webpack 的生态环境更加成熟,在社区中拥有广泛的支持和丰富的插件库。而 Vite 尚处于发展阶段,尽管其已经获得了很多关注,但其生态系统仍然不太完善。
  • 功能特性:Webpack 是一个功能更加全面的打包工具,支持各种 Loader 和插件,可以处理多种类型的文件和资源。而 Vite 的设计初衷是专注于开发环境下的快速构建,因此其对一些高级特性的支持相对较少。
    总结:Vite 更适合用于开发环境下的快速构建,而 Webpack 则更适合用于生产环境下的复杂应用程序的打包处理

webpack 中的 plugin 和 loader 分别是什么作用?

loader:加载器,让webpack拥有了加载和解析非JavaScript文件的能力
babel-loader:把 ES6 转换成 ES5
image-loader:加载并且压缩图片文件
css-loader:解析 CSS
plugin:插件,扩展webpack的功能,让webpack具有更多的灵活性。
define-plugin:定义环境变量
html-webpack-plugin: 压缩html
plugin是用来扩展webpack功能的,它可以在整个构建过程中监听各种事件,并执行相应的操作。plugin可以通过在webpack配置中的plugins属性中添加插件实例来使用。
loader是用来处理模块的,它可以对模块进行转换、编译、压缩等操作。loader可以通过在require()语句中使用loadername!前缀来激活,或者通过webpack配置中的rules属性来自动应用。

webpack性能优化

webpack性能优化可以从两个方面进行:提升webpack编译速度和提升输出代码的质量。

提升webpack编译速度:

  • 升级webpack版本,使用最新的特性和优化。
  • 使用多进程/多实例构建,利用 happypack 或者 thread-loader 来并行执行任务。
  • 使用缓存,利用 cache-loader 或者 hard-source-webpack-plugin 来缓存模块和依赖,避免重复构建。
  • 使用DllPlugin,将一些不经常变动的库提前打包成动态链接库,减少打包时间。
  • 减少文件搜索范围,配置 resolve.modules、resolve.mainFields 和 resolve.extensions 来缩小模块查找的范围。
    提升输出代码的质量:
  • 使用Tree Shaking,移除未引用的代码,减少代码体积。
  • 使用Code Splitting,按需加载或者并行加载资源,避免加载过多无用代码。
  • 使用Preloading/Prefetching,预先加载或者预取一些将来可能需要的资源,提高用户体验
  • 使用Lazy Loading,懒加载一些非关键资源,降低首屏渲染时间。
  • 使用CompressionPlugin,对输出的文件进行压缩处理。

dependencies与devDependencies的区别

npm install在安装node模块时,有两种命令参数可以把它们的信息写入package.json文件:

//–save会把依赖包名称添加到package.json文件dependencies键下
//–save-dev则添加到package.json文件devDependencies键下
npm install  --save
npm install  --save-dev

devDependencies 里面的插件只用于开发环境,不用于生产环境,而 dependencies 是需要发布到生产环境的。 比如我们写一个项目要依赖于jQuery,没有这个包的依赖运行就会报错,这时候就把这个依赖写入dependencies ; 而我们使用的一些构建工具比如glup、webpack这些只是在开发中使用的包,上线以后就和他们没关系了,所以将它写入devDependencies。

网络协议

从浏览器输入url后都经历了什么(具重要)

解析URL,判断是否是合法的url格式,如果不是,则将其作为搜索关键字进行搜索;
DNS(域名系统)域名解析
三次握手建立TCP连接
发送HTTP请求,服务器处理请求,返回响应结果
四次挥手关闭TCP连接
浏览器渲染:
解析HTML生成DOM树。,解析CSS生成CSSOM规则树。如果遇到 script 标签,则判断是否含有 defer 或者 async 属性,要若没有script 会阻塞页面的加载
将DOM树与CSSOM规则树合并在一起生成渲染树。遍历渲染树开始布局,计算每个节点的位置大小信息,最后绘制到屏幕上。

在这里插入图片描述

讲一讲三次握手四次挥手,为什么是三次握手而不是两次握手或四次?

三次握将他理解为三步握手,是一次握手分三个步骤进行,而不是一共握三次手
为什么要握手?
TCP是可靠的双向通信传输协议,体现在通信的双方都需要确认对方是否收到了自己发的数据包是完整无差错的,如果不是就需要重发

客户端和服务器端之间通过三次握手建立连接,四次挥手释放连接, 两次不可靠四次不高效

SYN(Synchronize)包是TCP/IP协议中的一种数据包。在TCP三次握手过程中,首先客户端向服务器发送一个SYN包来请求建立连接。 FIN(Finish)是TCP/IP协议中的一种数据包
ACK(Acknowledgment)是TCP/IP协议中的一种确认包
三次握手,客户端先向服务端发起一个SYN包建立连接,服务器端收到SYN后,给客户端返回一个ACK包,表示已收到SYN,最后客户端再向服务器端发送一个ACK包表示确认
三次握手过程中的报文是不含数据的,只包含tcp协议首部。

为什么不是两次或四次握手?
三次握手可以保证数据包的传输, 两次握手没有第三步的同步信号,不知道双方是否达成一致的状态,不可靠, 四次握手不高效,因为三次握手可以保证数据包的传输,

四次挥手,首先客户端向服务器端发送一个FIN包,服务器端收到后,向客户端发送ACK确认包 随后再把自己剩余数据发送给客户端,并发送FIN/ACK包,客户端收到后,再向服务端发送ACK确认包,在等待两个周期后关闭连接.
之所以等待两个周期是因为最后客户端发送的ACK包可能会丢失,如果不等待2个周期的话,服务端在没收收到ACK包之前,会不停的重复发送FIN包而不关闭,所以得等待两个周期

HTTP的结构

请求报文和响应报文
请求报文 :请求行 请求头 空行、请求数据
响应报文:响应行 响应头 响应体

HTTP头都有哪些字段

  • 请求头
    • cache-control 是否使用缓存
    • Connection:keep-alive 与服务器的连接状态
    • Host 主机域
  • 返回头
    • cache-control
    • etag 唯一标识,缓存用的
    • last-modified最后修改时间

说说你知道的状态码(必考)

分类描述
1**信息。服务器收到请求,请继续执行请求
2**成功。请求被成功接收并处理
3**重定向。需要进一步操作来完成请求
4**客户端错误。无法完成请求,或请求包含语法错误
5**服务器错误。服务器在处理请求的过程中发成错误
200请求成功 301永久重定向 302临时重定向 304协商缓存 400语法错误 401请求需要用户验证 403跨域 404请求资源不存在 503服务不可用 - 2开头的表示成功 - 一般见到的就是200 - 3开头的表示重定向 - 301永久重定向 - 302临时重定向 - 304表示可以在缓存中取数据(协商缓存)
  • 4开头表示客户端错误

    • 401:当前请求需要用户验证
    • 403跨域
    • 404请求资源不存在(请求地址错误)
  • 5开头表示服务端错误

    • 500-599 用于指出服务器错误

      503:服务不可使用

网络OSI七层模型都有哪些?TCP是哪一层的

TCP/IP四层模型 应用层、传输层、网络层、数据链路层
OSI 七层模型:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层
应用层:决定了向用户提供应用服务时的活动。HTTP协议属于应用层 ,TCP/UDP属于传输层

TCP 和UDP有什么区别?

传输层:提供处于网络连接中的两台计算机之间的数据传输
TCP(传输控制协议 )和UDP(用户数据报协议)都是传输层协议
TCP(传输控制协议)提供的是面向连接,可靠的字节流服务。即客户和服务器交换数据前,必须现在双方之间建立一个TCP连接,之后才能传输数据。并且提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
UDP(用户数据报协议)是一个简单的面向数据报的运输层协议。它不提供可靠性,只是把应用程序传给IP层的数据报发送出去,但是不能保证它们能到达目的地。由于UDP在传输数据报前不用再客户和服务器之间建立一个连接,且没有超时重发等机制,所以传输速度很快。

连接方面 :TCP面向连接,UDP不需要连接 ,TCP需要三次握手四次挥手请求连接

可靠性 :TCP是可靠传输;一旦传输过程中丢包的话会进行重传,udp是不可靠传输,但会最大努力交付

工作效率 :UDP实时性高,比TCP工作效率高,因为UDP不需要建立连接,更不需要复杂的握手挥手以及复杂的算法,也没有重传机制

是否支持多对多:TCP是点对点的UDP支持一对一,一对多,多对多

首部大小 :TCP首部占20字节,udp首部占8字节

http1.0和http1.1,还有http2有什么区别?

http0.9不涉及数据包传输,规定客户端和服务器之间通信格式,只能进行get请求

http1.0传输内容格式不限制添加了POST,HEAD,OPTION,PUT,DELETE等

http1.1增加了长连接keep-alive和host域,而且节约带宽

http2 多路复用,头部压缩,服务器推送
http3多路复用、有序交付、重传等等功能

HTTP和HTTPS的区别(必考)

http是超文本传输协议
https是在http基础上增加了ssl加密传输协议
区别
HTTP直接通过明文在浏览器和服务器之间传递信息。
HTTPS采用 对称加密 和 非对称加密 结合的方式来保护浏览器和服务端之间的通信安全。

对称加密算法加密和解密都是同一个密钥。密钥在传输的过程中容易被人截取,无法保证秘钥的安全传输
非对称加密算法密钥成对出现,分为公钥和私钥,公钥加密需要私钥解密,私钥加密需要公钥解密

HTTPS加密传输过程

1.客户端通过三次握手建立TCP连接
2.服务端通过非对称加密算法生成一对公钥与私钥,公钥去权威机构生成CA证书,返回给客户端
3.客户端根据内置根证书验证CA证书的合法性,
4.若合法,客户端生成随机的对称加密密钥,然后对公钥加密,发送给服务端
5.服务端收到后,使用私钥进行解密,双方通过对称加密算法进行通讯

get和post的区别(必考)

  • 提交数据存储位置不同

GET请求会将数据放到URL后面

POST请求会将数据放到请求体中

  • 对提交的数据大小限制不同

GET请求对所发信息量的限制是2000 个字符

POST请求对信息量没有限制

  • 应用场景不同

GET请求用于提交非敏感数据和小数据

POST请求用于提交敏感数据和大数据

  • get请求可以被缓存,post不可以被缓存
  • get后退不会有影响,post后退会重新进行提交
  • get请求的记录会留在历史记录中,post请求不会留在历史记录

什么是XSS?什么是CSRF?

XSS(跨站脚本攻击):攻击者想尽一切办法,将可以执行的恶意代码注入到网页中,当用户浏览时,恶意代买会被执行,从而达到攻击用户的目的。(偷取网站任意数据 偷取用户资料 偷取用户密码和登陆态)

  • 防御方式:
    1.转义字符:普通的输入 - 编码,富文本 - 过滤,较正
    2.CSP 内容安全策略:本质是建立空白名单,开发者明确告诉浏览器哪些外部资源可以加载和执行

CSRF(跨域请求伪造):攻击者构造出一个后端请求地址,诱导用户点击或者通过某些途径自动发起请求。如果用户是在登录状态下的话,后端就以为是用户在操作,从而进行相应的逻辑。(攻击者盗用了你的身份,以你的名义发送恶意请求)

  • 解决方式:
    1.请求时附带验证信息,比如验证码或者 Token
    2.阻止第三方网站请求接口

什么是回流(重排)? 什么是重绘?

回流 :当元素的内容、结构、位置、尺寸发生了变化,需要重新构建,这个过程叫做回流(加上浏览器渲染机制)
回流必将引起重绘,但重绘不一定会引发回流
触发回流的条件:
任何页面布局和几何属性的改变都会触发回流,比如:
  1、页面渲染初始化(无法避免)
  2、添加或删除可见的DOM元素;
  3、元素位置的改变,或者使用动画;
  4、元素尺寸的改变——大小,外边距,边框;高边宽高
  5、浏览器窗口尺寸的变化(resize事件发生时);
  6、填充内容的改变,比如文本的改变或图片大小改变而引起的计算值宽度和高度的改变;
  7、读取某些元素属性:(offsetLeft/Top/Height/Width, clientTop/Left/Width/Height, scrollTop/Left/Width/Height, width/height, getComputedStyle(), currentStyle(IE) )

重绘 :指一个元素外观的改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观,该过程叫做重绘
页面至少经历一次回流和重绘(第一次加载的时候)
触发重绘的条件:改变元素外观属性。如:color,background-color等。

HTTP缓存

http缓存是一种客户端缓存,当Web浏览器向服务器发起资源请求时,服务器可以在响应报文头中包含缓存相关的信息。这些HTTP Header会告诉浏览器是否以及如何缓存资源,再次请求时如果命中缓存将直接读取本地缓存不再发出请求。
在这里插入图片描述

浏览器发起请求: 当浏览器需要请求一个资源时,它会向服务器发送一个HTTP请求。
检查强制缓存: 浏览器首先会检查缓存是否有强制缓存副本。它会查看响应的缓存头字段,如Cache-Control和Expires。如果资源在缓存有效期内(根据max-age或Expires字段),浏览器直接从缓存中获取资源,不会向服务器发起请求。
检查协商缓存: 如果资源不在强制缓存有效期内,浏览器会向服务器发送一个条件请求,带上缓存相关的标识,如ETag或If-Modified-Since。服务器会检查这些标识,如果资源未发生改变,服务器返回一个状态码为304(Not Modified)的响应,告诉浏览器可以使用缓存副本。浏览器接收到304响应后,从缓存中获取资源。
获取完整的响应: 如果资源未命中强制缓存和协商缓存,或者缓存副本失效,服务器会返回一个完整的响应,包含新的资源内容。浏览器将接收到的响应存储在缓存中,并将其用于未来的请求。

Http缓存主要分为两种:强缓存协商缓存

强缓存基本原理是:所请求的数据在缓存数据库中尚未过期时,不与服务器进行交互,直接使用缓存数据库中的数据。

协商缓存主要原理是 从缓存数据库中取出缓存的标识,然后向浏览器发送请求验证所请求的数据是否已经更新,如果已更新则返回新的数据,若未更新则使用缓存数据库中的缓存数据
在这里插入图片描述

性能优化

HTML优化

1、避免 HTML 中书写 CSS 代码,因为这样难以维护。
2、使用 Viewport 加速页面的渲染。
3、使用语义化标签,减少 CSS 代码,增加可读性和 SEO。
4、减少标签的使用,DOM 解析是一个大量遍历的过程,减少不必要的标签,能降低遍历的次数。
5、避免 src、href 等的值为空,因为即时它们为空,浏览器也会发起 HTTP 请求。
6、减少 DNS 查询的次数
复制代码

CSS优化

1、优化选择器路径:使用 .c {} 而不是 .a .b .c {}。
2、选择器合并:共同的属性内容提起出来,压缩空间和资源开销。
3、精准样式:使用 padding-left: 10px 而不是 padding: 0 0 0 10px。
4、雪碧图:将小的图标合并到一张图中,这样所有的图片只需要请求一次。
5、避免通配符:.a .b * {} 这样的选择器,根据从右到左的解析顺序在解析过程中遇到通配符 * {} 6、会遍历整个 DOM,性能大大损耗。
7、少用 float:float 在渲染时计算量比较大,可以使用 flex 布局。
8、为 0 值去单位:增加兼容性。
9、压缩文件大小,减少资源下载负担。
复制代码

JavaScript优化

1、尽可能把 <script> 标签放在 body 之后,避免 JS 的执行卡住 DOM 的渲染,最大程度保证页面尽快地展示出来
2、尽可能合并 JS 代码:提取公共方法,进行面向对象设计等……
3、CSS 能做的事情,尽量不用 JS 来做,毕竟 JS 的解析执行比较粗暴,而 CSS 效率更高。
4、尽可能逐条操作 DOM,并预定好 CSs 样式,从而减少 reflow 或者 repaint 的次数。
5、尽可能少地创建 DOM,而是在 HTML 和 CSS 中使用 display: none 来隐藏,按需显示。
6、压缩文件大小,减少资源下载负担。
复制代码

面试常见的其他问题

常问

1、自我介绍

2、你的项目中技术难点是什么?遇到了什么问题?你是怎么解决的?

3、你认为哪个项目做得最好?

4、平时是如何学习前端开发的?

5、你最有成就感的一件事

6、你是怎么学习前端的

人事面

1、面试完你还有什么问题要问的吗

2、你有什么爱好?

3、你最大的优点和缺点是什么?

4、你为什么会选择这个行业,职位?

5、你觉得你适合从事这个岗位吗?

6、你有什么职业规划?

7、你对工资有什么要求?

8、如何看待前端开发?

9、未来三到五年的规划是怎样的?

其他

谈谈你对重构的理解?

网络重构:在不改变外部行为的前提下,简化结构、添加可读性,而在网站前端保持一致的行为。也就是说是在不改变UI的情况下,对网站进行优化, 在扩展的同时保持一致的UI

对于传统的网站来说重构通常是:

  • 表格(table)布局改为DIV+CSS
  • 使网站前端兼容于现代浏览器(针对于不合规范的CSS、如对IE6有效的)
  • 对于移动平台的优化
  • 针对于SEO进行优化

什么样的前端代码是好的?

高复用低耦合,这样文件小,好维护,而且好扩展

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

前端是最贴近用户的程序员,

  • 实现界面交互
  • 提升用户体验
  • 有了Node.js,前端可以实现服务端的一些事情

前端是最贴近用户的程序员,前端的能力就是能让产品从 90分进化到 100 分,甚至更好,

与团队成员,UI设计,产品经理的沟通;

做好的页面结构,页面重构和用户体验;

你觉得前端工程的价值体现在哪?

1、为简化用户使用提供技术支持(交互部分)

2、为多个浏览器兼容性提供支持

3、为提高用户浏览速度(浏览器性能)提供支持

4、为跨平台或者其他基于webkit或其他渲染引擎的应用提供支持

5、为展示数据提供支持(数据接口)

平时如何管理你的项目?

  • 先期团队必须确定好全局样式(globe.css),编码模式(utf-8) 等;
  • 编写习惯必须一致(例如都是采用继承式的写法,单样式都写成一行);
  • 标注样式编写人,各模块都及时标注(标注关键样式调用的地方);
  • 页面进行标注(例如 页面 模块 开始和结束);
  • CSS跟HTML 分文件夹并行存放,命名都得统一(例如style.css);
  • JS 分文件夹存放 命名以该JS功能为准的英文翻译。
  • 图片采用整合的 images.png png8 格式文件使用 - 尽量整合在一起使用方便将来的管理

前端性能优化

1、使用雪碧图。
2、使用语义化标签。
3、防抖节流。
4、图片懒加载和路由懒加载。
5、加载外部CDN
6、组件的按需导入
7、开启gzip压缩
8、封装可复用组

To B和To C

To B 指面向政府企业(比如政府、大型企业);To C指直接面向个体消费者,提供产品服务(比如淘宝、京东)
在这里插入图片描述

平时项目中怎么实现公共组件的

比如我的王者荣耀移动端页面封装了顶栏公共组件,因为不同页面下都有相同的顶栏,新建一个顶栏组件,使用了具名插槽:位置由子组件自身决定 内容及显示隐藏由父组件决定(比如有团队成就更多这几个字,有的页面需要显示,有的页面不需要显示,全靠父组件的显示与隐藏了) 写入界面内容,在需要的页面上导入公共组件:import TopBar from ‘components/content/TopBar’

说一下你对Node的了解

首先服务器端开发要做的事情:实现网站的业务逻辑 ,数据的增删改查
Node是一个基于Chrome V8引擎的JavaScript代码运行环境,其中有一个Express框架,是基于Node平台web应用开发框架,创建Web服务器。
然后就是第三方模块,npm node的第三方模块管理工具,npm install 安装模块 npm unintall 卸载模块
全局安装与本地安装nodemon监控文件的保存操作,当文件发生保存操作时,就会重新执行该文件。nrm npm下载地址切换工具
浏览器中全局对象是window,在Node中全局对象是global
Nodejs遵循Commonjs模块加载机制,使用require加载文件,使用 module.exports导出文件

token被劫持的解决方法

a、在存储的时候把 token 进行对称加密存储,用的时候解开。
b、将请求 URL、时间戳、token 三者进行合并加盐签名,服务端校验有效性。
c、HTTPS 对 URL 进行判断。

Logo

前往低代码交流专区

更多推荐