Vue+网络协议+Webpack高频面试题
Posted 前端加油
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue+网络协议+Webpack高频面试题相关的知识,希望对你有一定的参考价值。
文章目录
- Vue
- vue的优点是什么?
- vue生命周期
- created和mounted的区别
- 什么是 MVVM?
- 双向数据绑定原理
- Vue组件之间的的通信(传值)方式
- v-show和v-if的区别
- 开发中常用的指令有哪些
- vue自定义指令
- vue自定义组件
- computed和watch有什么区别?
- vuex的组成和原理
- 如何让css只在当前组件中起作用
- vue.nextTick()的用处?
- vue-router 路由模式
- vue-router有哪几种导航钩子
- vue-router实现路由懒加载( 动态加载路由 )
- diff算法
- 虚拟DOM的优缺点
- **Vue的Key的作用**
- keep-alive的实现
- Vue-CLi是啥?
- 对 Vue 项目进行哪些优化?
- git常用的命令(记住这个就可以)
- webpack
- 网络协议
- 性能优化
- 面试常见的其他问题
Vue
vue的优点是什么?
- 低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
- 可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
- 独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计
- 可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。
vue生命周期
对生命周期的理解(什么是vue生命周期,vue生命周期钩子,划分阶段)
Vue 实例从创建到销毁的过程,就是vue生命周期,每个Vue
实例在创建时都会经过一系列的初始化过程,vue
的生命周期钩子,就是说在达到某一阶段或条件时去触发的函数,目的就是为了完成一些动作或者事件
它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后
create阶段
:vue实例被创建
mount阶段
: vue实例被挂载到真实DOM节点
update阶段
:当vue实例里面的data数据变化时,触发组件的重新渲染
destroy阶段
:vue实例被销毁
beforeCreate 创建之前,此时还没有data和Method
Created 创建完成,此时data和Method可以使用了,在Created之后beforeMount之前如果没有el选项的话那么此时生命周期结束,停止编译,如果有则继续
beforeMount 在渲染之前
mounted 页面已经渲染完成,并且vm实例中已经添加完$el了,已经替换掉那些DOM元素了(双括号中的变量),这个时候可以操作DOM了(但是是获取不了元素的高度等属性的,如果想要获取,需要使用nextTick())
beforeUpdate data改变后,对应的组件重新渲染之前
updated data改变后,对应的组件重新渲染完成
beforeDestory 在实例销毁之前,此时实例仍然可以使用
destoryed 实例销毁后
第一次页面加载会触发哪几个钩子?
第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子
DOM 渲染在 mounted 中就已经完成了
每个生命周期适合哪些场景?
- beforeCreate在实例初始化之后,数据观测和事件配置之前被调用。
- created在实例创建完成后被立即调用。
- beforeMount在挂截开始之前被调用。
- mounted : 挂载元素,获取到DOM节点 ajax操作是在monted生命周期中完成的。(activated: keep-alive组件激活时调用)
- beforeUpdate数据更新时调用,发生在虚拟DOM打补丁之前。
- updated由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子
- beforeDestroy实例销毁之前调用。
- destroyed实例销段后调用。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kliaxvtm-1630839733734)(初中级前端面试题.assets/5.15.png)]
vue生命周期在真实场景下的业务应用
created: 进行ajax请求异步数据的获取、初始化数据
mounted: 挂载元素内dom节点的获取
nextTick: 针对单一事件更新数据后立即操作dom
updated: 任何数据的更新,如果要做统一的业务逻辑处理
watch: 监听具体数据变化,并做相应的处理
created和mounted的区别
created:是在模板渲染成html前调用的,此时data已经准备完毕,el仍是undefined,因为没有渲染成HTML,所以不能操作dom节点,它主要用来初始化一些数据;
即使created中的方法没有执行完,mounted也会被调用!
mounted:是在模板渲染成HTML之后调用的,此时data,el都已准备好,可以操作html的dom节点,可以通过id什么的来查找页面元素,也可以加载一些组件什么的
v-if:判断是否隐藏;v-for:数据循环;v-bind:class:绑定一个属性;v-model:实现双向绑定
什么是 MVVM?
- MVVM是
Model-View-ViewModel
缩写,也就是把MVC
中的Controller
演变成ViewModel。Model
层代表数据模型,View
代表UI组件,ViewModel
是View
和Model
层的桥梁,数据会绑定到viewModel
层并自动将数据渲染到页面中,视图变化的时候会通知viewModel
层更新数据。
双向数据绑定原理
双向数据绑定
,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化。Vue中双双向绑定使用v-model
指令来实现标签内容的绑定(双向绑定)
.如表单元素和数据的双向绑定
简答版本 :当一个Vue实例创建时,Vue会遍历data选项的属性,用 Object.defineProperty 将它们转为 getter/setter并且在内部追踪相关依赖,在属性被访问和修改时通知变化。每个组件实例都有相应的 watcher 程序实例,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher重新计算,从而致使它关联的组件得以更新。
vue采用数据监听和发布者-订阅模式。通过Object.defineProperty()来劫持各个属性的setter和getter,当数据变动时候发布消息给订阅者,触发相应回调。
1.需要observer递归的遍历对象,包括对象的对象,给对象的某个值赋值或者改变,触发setter,那么监听到了数据的变化。
2.complie解析各个v-的操作指令,将模板的变量替换成数据,初始化页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦有数据变动,接收通知,更新视图。
3.watcher是observer和complie的桥梁,首先自身实例化向属性订阅器dep中添加自身,其次自身有一个update方法,在属性变动时,dep.notice()通知,调用自身的update方法,触发complie的回调。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ihlN1Yxc-1630839733748)(初中级前端面试题.assets/20210108140237683.png)]
Vue组件之间的的通信(传值)方式
父向子传值
:子组件设置props + 父组件设置v-bind
属性绑定 props传递数据原则:单向数据流,只能父传子
子向父传值
: 子组件的$emit + 父组件设置v-on
事件绑定
兄弟组件任意组件通信
: 新建一个空的全局Vue对象,利用$emit
发送 , $on
接收
v-show和v-if的区别
v-show指令是通过修改元素的display的CSS属性让其显示或者隐藏
v-if指令是直接销毁和重建DOM达到让元素显示和隐藏的效果
开发中常用的指令有哪些
- v-if:判断是否隐藏;
- v-for:数据循环出来;
- v-bind:class:绑定一个属性;
- v-model:实现双向绑定
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>
computed和watch有什么区别?
computed
计算属性,依赖其他属性,当其他属性改变的时候下一次获取computed值时也会改变,computed的值会有缓存
watch
类似于数据改变后的回调
如果想深度监听的话,后面加一个deep:true
如果想监听完立马运行的话,后面加一个immediate:true
小结:
1. 当我们要进行数值计算,而且依赖于其他数据,那么把这个数据设计为computed
2. 如果你需要在某个数据变化时做一些事情,使用watch来观察这个数据变化
vuex的组成和原理
vuex 是什么?
vuex:专门为Vue服务,用于管理页面的数据状态、提供统一数据操作的生态系统
vuex有哪几种属性?
有五种,分别是 State、Getter、Mutation、Action、Module
state:存储数据,存储状态;在根实例中注册了store 后,用 this.$store.state 来访问;对应vue里面的data;存放数据方式为响应式,vue组件从store中读取数据,如数据发生变化,组件也会对应的更新。
getter:可以认为是 store 的计算属性,它的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
mutation:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
action:包含任意异步操作,通过提交 mutation 间接更变状态。
module:将 store 分割成模块,每个模块都具有state、mutation、action、getter、甚至是嵌套子模块。
Vuex 的好处
①能够在 vuex 中集中管理共享的数据,易于开发和后期维护
②能够高效地实现组件之间的数据共享,提高开发效率
③存储在 vuex 中的数据都是响应式的,能够实时保持数据与页面的同步
vue.js中ajax请求代码应该写在组件的methods还是vuex的actions中
如果请求来的数据 是 不需要被其他组件公用 仅仅在请求的组件内使用 就不需要放入 vuex的 state中
若被其他地方复用 则将请求放入action中 方便复用
如何让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
vue-router 路由模式
vue-router是vue.js官方路由管理器。vue的单页应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来 .前端路由实现起来其实很简单,本质就是监听 URL 的变化,然后匹配路由规则,显示相应的页面,并且无须刷新页面。
- hash模式
监听hashchange事件实现前端路由,利用url中的hash来模拟一个hash,以保证url改变时,页面不会重新加载。 - history模式
利用pushstate和replacestate来将url替换但不刷新,但是有一个致命点就是,一旦刷新的话,就会可能404,因为没有当前的真正路径,要想解决这一问题需要后端配合,将不存在的路径重定向到入口文件。
vue-router有哪几种导航钩子
第一种:是全局导航钩子:router.beforeEach(to,from,next),作用:跳转前进行判断拦截
第二种:组件内的钩子
第三种:单独路由独享组件
vue-router实现路由懒加载( 动态加载路由 )
当打包构建应用时,Javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载.
component: () => import('@/components/Two')
const Index = () => import(/* webpackChunkName: "group-home" */ '@/views/index')
const routers = [
{
path: '/',
name: 'index',
component: Index
}
diff算法
diff算法是指对新旧虚拟节点进行对比,并返回一个patch对象,用来存储两个节点不同的地方,最后利用patch记录的消息局部更新DOM
虚拟DOM的优缺点
- 缺点
- 首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHTML插入慢
- 优点
- 减少了dom操作,减少了回流与重绘
- 保证性能的下限,虽说性能不是最佳,但是它具备局部更新的能力,所以大部分时候还是比正常的DOM性能高很多的
Vue的Key的作用
- key主要用在虚拟Dom算法中,每个虚拟节点VNode有一个唯一标识Key,通过对比新旧节点的key来判断节点是否改变,用key就可以大大提高渲染效率,这个key类似于缓存中的etag。
keep-alive的实现
keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,避免重新渲染 ,实现组件缓存
钩子函数:
`activated `组件渲染后调用
`deactivated `组件销毁后调用
复制代码
原理:Vue.js
内部将DOM
节点抽象成了一个个的VNode
节点,keep-alive
组件的缓存也是基于VNode
节点的而不是直接存储DOM
结构。它将满足条件(pruneCache与pruneCache)
的组件在cache
对象中缓存起来,在需要重新渲染的时候再将vnode
节点从cache
对象中取出并渲染。
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 clone 网站上的仓库地址
新增文件的命令:git add .
提交文件的命令:git commit –m或者git commit –a
查看工作区状况:git status –s
拉取合并远程分支的操作:git fetch/git merge或者git pull
查看提交记录命令:git reflog
项目中用到的命令
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分支
webpack
webpack
是一个打包模块化javascript的工具,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。
webpack打包原理
webpack只是一个打包模块的机制,只是把依赖的模块转化成可以代表这些包的静态文件。webpack就是识别你的 入口文件。识别你的模块依赖,来打包你的代码。至于你的代码使用的是commonjs还是amd或者es6的import。webpack都会对其进行分析。来获取代码的依赖。webpack做的就是分析代码。转换代码,编译代码,输出代码。webpack本身是一个node的模块,所以webpack.config.js是以commonjs形式书写的(node中的模块化是commonjs规范的)
- babel(ES6转ES5) 下载插件
babel-loader
,在module(loader)中配置
模块热更新
模块热更新是webpack的一个功能,可以使代码修改过后不用刷新就可以更新,是高级版的自动刷新浏览器
devServer中通过hot属性可以控制模块的热替换
通过配置文件
const webpack = require('webpack');
const path = require('path');
let env = process.env.NODE_ENV == "development" ? "development" : "production";
const config = {
mode: env,
devServer: {
hot:true
}
}
plugins: [
new webpack.HotModuleReplacementPlugin(), //热加载插件
],
module.exports = config;
复制代码
通过命令行
"scripts": {
"test": "echo \\"Error: no test specified\\" && exit 1",
"start": "NODE_ENV=development webpack-dev-server --config webpack.develop.config.js --hot",
},
复制代码
如何提高webpack构建速度
1、通过externals配置来提取常用库
2、利用DllPlugin和DllReferencePlugin预编译资源模块 通过DllPlugin来对那些我们引用但是绝对不会修改的npm包来进行预编译,再通过DllReferencePlugin将预编译的模块加载进来
3、使用Happypack 实现多线程加速编译
要注意的第一点是,它对file-loader和url-loader支持不好,所以这两个loader就不需要换成happypack了,其他loader可以类似地换一下
4、使用Tree-shaking和Scope Hoisting来剔除多余代码 5、使用fast-sass-loader代替sass-loader 6、babel-loader开启缓存
babel-loader在执行的时候,可能会产生一些运行期间重复的公共文件,造成代码体积大冗余,同时也会减慢编译效率 可以加上cacheDirectory参数或使用 transform-runtime 插件试试
// webpack.config.js
use: [{
loader: 'babel-loader',
options: {
cacheDirectory: true
}]
// .bablerc
{
"presets": [
"env",
"react"
],
"plugins": ["transform-runtime"]
}
复制代码
不需要打包编译的插件库换成全局"script"标签引入的方式
比如jQuery插件,react, react-dom等,代码量是很多的,打包起来可能会很耗时 可以直接用标签引入,然后在webpack配置里使用 expose-loader 或 externals 或 ProvidePlugin 提供给模块内部使用相应的变量
// @1
use: [{
loader: 'expose-loader',
options: '$'
}, {
loader: 'expose-loader',
options: 'jQuery'
}]
// @2
externals: {
jquery: 'jQuery'
},
// @3
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
}),
复制代码
8、优化构建时的搜索路径
在webpack打包时,会有各种各样的路径要去查询搜索,我们可以加上一些配置,让它搜索地更快 比如说,方便改成绝对路径的模块路径就改一下,以纯模块名来引入的可以加上一些目录路径 还可以善于用下resolve alias别名 这个字段来配置 还有exclude等的配置,避免多余查找的文件,比如使用babel别忘了剔除不需要遍历的
webpack的优缺点
优点
专注于处理模块化的项目,能做到开箱即用,一步到位
可通过plugin扩展,完整好用又不失灵活
使用场景不局限于web开发
社区庞大活跃,经常引入紧跟时代发展的新特性,能为大多数场景找到已有的开源扩展
良好的开发体验
缺点
webpack的缺点是只能用于采用模块化开发的项目
网络协议
从浏览器输入url后都经历了什么(具重要)
先进行DNS域名解析,先查看本地hosts文件,查看有没有当前域名对应的ip地址,若有直接发起请求,没有的话会在本地域名服务器去查找,该查找属于递归查找,如果本地域名服务器没查找到,会从根域名服务器查找,该过程属于迭代查找,根域名会告诉你从哪个与服务器查找,最后查找到对应的ip地址后把对应规则保存到本地的hosts文件中。
如果想加速以上及之后的http请求过程的话可以使用缓存服务器CDN,CDN过程如下:
- 用户输入url地址后,本地DNS会解析url地址,不过会把最终解析权交给CNAME指向的CDN的DNS服务器
- CDN的DNS服务器会返回给浏览器一个全局负载均衡IP
- 用户会根据全局负载均衡IP去请求全局负载均衡服务器
- 全局负载均衡服务器会根据用户的IP地址,url地址,会告诉用户一个区域负载均衡设备,让用户去请求它。
- 区域负载均衡服务器会为用户选择一个离用户较近的最优的缓存服务器,并把ip地址给到用户
- 用户想缓存服务器发送请求,如果请求不到想要的资源的话,会一层层向上一级查找,知道查找到为止
进行http请求,三次握手四次挥手建立断开连接
服务器处理,可能返回304也可能返回200
- 返回304说明客户端缓存可用,直接使用客户端缓存即可,该过程属于协商缓存
- 返回200的话会同时返回对应的数据
客户端自上而下执行代码
-
其中遇到CSS加载的时候,CSS不会阻塞DOM树的解析,但是会阻塞DOM树的渲染,并且CSS会阻塞下面的JS的执行
-
然后是JS加载,JS加载会影响DOM的解析,之所以会影响,是因为JS可能会删除添加节点,如果先解析后加载的话,DOM树还得重新解析,性能比较差。如果不想阻塞DOM树的解析的话,可以给script添加一个defer或者async的标签。
- defer:不会阻塞DOM解析,等DOM解析完之后在运行,在DOMContentloaed之前
- async: 不会阻塞DOM解析,等该资源下载完成之后立刻运行
-
进行DOM渲染和Render树渲染
- 获取html并解析为Dom树
- 解析css并形成一个cssom(css树)
- 将cssom和dom合并成渲染树(render树)
- 进行布局(layout)
- 进行绘制(painting)
- 回流重绘 ""回流必将引起重绘,重绘不一定引起回流
讲一讲三次握手四次挥手,为什么是三次握手四而不是两次握手?
客户端和服务端之间通过三次握手建立连接,四次挥手释放连接
三次握手
,客户端先向服务端发起一个SYN包,进入SYN_SENT状态,服务端收到SYN后,给客户端返回一个ACK+SYN包,表示已收到SYN,并进入SYN_RECEIVE状态,最后客户端再向服务端发送一个ACK包表示确认,双方进入establish状态。
之所以是三次握手而不是两次,是因为如果只有两次,在服务端收到SYN后,向客户端返回一个ACK确认就进入establish状态,万一这个请求中间遇到网络情况而没有传给客户端,客户端一直是等待状态,后面服务端发送的信息客户端也接受不到了。
四次挥手
,首先客户端向服务端发送一个FIN包,进入FIN_WAIT1状态,服务端收到后,向客户端发送ACK确认包,进入CLOSE_WAIT状态,然后客户端收到ACK包后进入FIN_WAIT2状态,然后服务端再把自己剩余没传完的数据发送给客户端,发送完毕后在发送一个FIN+ACK包,进入LAST_ACK(最后确认)状态,客户端收到FIN+ACK包后,再向服务端发送ACK包,在等待两个周期后在关闭连接
之所以等待两个周期是因为最后服务端发送的ACK包可能会丢失,如果不等待2个周期的话,服务端在没收收到ACK包之前,会不停的重复发送FIN包而不关闭,所以得等待两个周期
HTTP的结构
请求行 请求头 请求体 ,其中请求行包括 http版本号,url,请求方式 ,响应行包括版本号,状态码,原因
HTTP头都有哪些字段
- 请求头
- cache-control 是否使用缓存
- Connection:keep-alive 与服务器的连接状态
- Host 主机域
- 返回头
- cache-control
- etag 唯一标识,缓存用的
- last-modified最后修改时间
说说你知道的状态码
-
2开头的表示成功
- 一般见到的就是200
-
3开头的表示重定向
- 301永久重定向
- 302临时重定向
- 304表示可以在缓存中取数据(协商缓存)
-
4开头表示客户端错误
- 400:语义有误,当前请求无法被服务器理解
- 401:当前请求需要用户验证
- 403跨域
- 404请求资源不存在
-
5开头表示服务端错误
-
500-599 用于指出服务器错误
503:服务不可
-
网络OSI七层模型都有哪些?TCP是哪一层的
- 七层模型:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层
- TCP属于传输层
http1.0和http1.1,还有http2有什么区别?
http0.9只能进行get请求
http1.0添加了POST,HEAD,OPTION,PUT,DELETE等
http1.1增加了长连接keep-alive,增加了host域,而且节约带宽
http2 多路复用,头部压缩,服务器推送
HTTP和HTTPS的区别(必考)
HTTP 的URL 以http:// 开头,而HTTPS 的URL 以https:// 开头
HTTP 是明文传输,HTTPS 通过 SSL\\TLS 进行了加密
HTTP 的端口号是 80,HTTPS 是 443
HTTPS 需要到 CA 申请证书,一般免费证书很少,需要交费
HTTP 的连接很简单,是无状态的;
HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 协议安全。
get和post的区别(必考)
- 提交数据存储位置不同
GET请求会将数据放到URL后面
POST请求会将数据放到请求体中
- 对提交的数据大小限制不同
GET请求对所发信息量的限制是2000 个字符
POST请求对信息量没有限制
- 对提交的数据编码不同
GET请求的参数只能是ASCII码,所以中文需要URL编码
POST请求传参没有这个限制
- 应用场景不同
GET请求用于提交非敏感数据和小数据
POST请求用于提交敏感数据和大数据
- get请求可以被缓存,post不可以被缓存
- get后退不会有影响,post后退会重新进行提交
- get请求的记录会留在历史记录中,post请求不会留在历史记录
TCP 和UDP有什么区别?
连接方面 :TCP面向连接,UDP不需要连接 ,TCP需要三次握手四次挥手请求连接
可靠性 :TCP是可靠传输;一旦传输过程中丢包的话会进行重传,udp是不可靠传输,但会最大努力交付
工作效率 :UDP实时性高,比TCP工作效率高,因为UDP不需要建立连接,更不需要复杂的握手挥手以及复杂的算法,也没有重传机制
是否支持多对多:TCP是点对点的UDP支持一对一,一对多,多对多
首部大小 :TCP首部占20字节,udp首部占8字节
什么是XSS?什么是CSRF?
XSS跨站脚本攻击:攻击者想尽一切办法,将可以执行的代码注入到网页中。
- 不需要你做任何的登录认证,它会通过合法的操作(比如在url中输入、在评论框中输入),向你的页面注入脚本(可能是js、hmtl代码块等)。
- 解决方式
编码:对用户输入的数据进行HTML Entity 编码。把字符转换成 转义字符。Encode的作用是将$var等一些字符进行转化,使得浏览器在最终输出结果上是一样的。
过滤:移除用户输入的和事件相关的属性。
CSRF跨域请求伪造:攻击者诱导受害人进入第三方网站,在第三方网站中,向被攻击网站发起跨域请求,利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。
- 在未退出A网站的前提下访问B,B使用A的cookie去访问服务器
- 解决方式:token,每次用户提交表单时需要带上token(伪造者访问不到),如果token不合法,则服务器拒绝请求
什么是回流? 什么是重绘?
回流 :当元素的内容、结构、位置、或尺寸发生了变化,需要重新计算元素样式,这个过程叫做回流
回流必将引起重绘
重绘 :当元素的样式(背景色、边框颜色、文字颜色等)发生变化,需要重新绘制元素,该过程叫做重绘
页面至少经历一次回流和重绘(第一次加载的时候)
HTTP和HTTPS的区别
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
HTTP缓存
Http缓存主要分为两种:强缓存和协商缓存。
强缓存基本原理是:所请求的数据在缓存数据库中尚未过期时,不与服务器进行交互,直接使用缓存数据库中的数据。
当强缓存过期未命中或者响应报文Cache-Control
中有must-revalidate
标识必须每次请求验证资源的状态时,便使用协商缓存的方式去处理缓存文件。
协商缓存主要原理是从缓存数据库中取出缓存的标识,然后向浏览器发送请求验证请求的数据是否已经更新,如果已更新则返回新的数据,若未更新则使用缓存数据库中的缓存数据
性能优化
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 格式文件使用 - 尽量整合在一起使用方便将来的管理
移动端(Android IOS)怎么做好用户体验?
清晰的视觉纵线、
信息的分组、极致的减法、
利用选择代替输入、
标签及文字的排布方式、
依靠明文确认密码、
合理的键盘利用
以上是关于Vue+网络协议+Webpack高频面试题的主要内容,如果未能解决你的问题,请参考以下文章
前端面试Vue 高频原理篇+详细解答,还有105道vue面试题集合