2023前端面试重点知识点总结
- css
- js
-
-
-
-
-
- js数据类型有哪些?有什么区别
- 谈一下你对作用域的理解:变量和函数(标识符)的作用范围。作用域分三类:全局,局部,块级作用域({}里去定义)。在JS去查找某个变量的时候,所形成的查找路径就是作用域链。
- 谈一下你对原型的理解:每一个构造函数都有一个原型对象
- 什么是闭包:优点:延长数据生命周期。缺点:有内存溢出/泄露的风险。概念:在一个函数外部调用另一个函数内部。
- 如何修改函数的this指向,这些方法之间有什么区别?
- 事件委托或者事件代理的原理是什么?
- 事件冒泡和事件捕获的区别是什么?
- 你知道的es6新特性有哪些?
- js异步编程方式有几种
- 谈一谈对promise的理解
- js如何浅拷贝和深拷贝一个对象
- rem和em和px的区别
- for循环中break和continue的区别是什么?
- 如何用原生js给一个按钮的点击事件绑定两个事件处理函数
- js引擎如何实现异步的?
- 什么是函数柯理化?
- DOMContentLoaded和load事件的区别
- 防抖和节流有什么区别,如何实现
- 代码题
-
-
-
-
- vue
-
-
-
-
-
- vue3和vue2的区别
- vue组件中watch和computed的区别
- vue常用的生命周期钩子函数有哪些?分别有什么作用?
- vue如何实现组件通信(组件传值)? 父子 兄弟 复杂组件关系
- vue项目如何做路由拦截?
- vue的响应式原理 Object.defineProperty
- v-if和v-show的区别
- v-if和v-for能一起用吗
- keep-alive组件有什么作用
- this.$nextTick有什么作用
- this.$set有什么作用
- vuex核心概念
- vue如何做路由懒加载
- 你认为vue 框架和jquery有什么区别?
- vue如何自定义指令
- 如何封装一个vue插件
- vue中什么是过滤器(filter)
- vue如何提取组件的公共逻辑
-
-
-
-
- react
-
-
-
-
-
- shouldComponentUpdate有什么作用?
- setState有什么特性
- react列表渲染时,key的作用
- react组件之间如何通信
- 解释一下redux核心概念
- react常用的生命周期钩子函数有哪些?分别有什么作用
- react中refs有什么作用?
- redux中间件是什么,有什么作用,你常用的中间件有哪些?
- redux三大原则是什么?
- react中容器组件和展示组件有什么区别?
- 函数组件和类组件有什么区别(16.8以前)?
- react如何提取组件之间的公共逻辑
- 什么是高阶组件?有什么作用?你常用的高阶组件有哪些
- 受控组件和不受控组件有什么区别?
- 谈一谈你对jsx的理解?
- react组件的数据来源有哪些?他们之间有什么区别?
- react插槽是什么?(或者react中如何实现组件复合?)
- react中context是什么?
- react中废弃了哪些和新增了哪些生命周期钩子函数
-
-
-
-
- 小程序
- 其他
-
-
- 性能优化
- SSR(Server Side Render)和CSR(Client Side Render)
- webpack
- 网络相关
- 业务相关
-
-
-
- 如何处理权限问题
- 前端如何实现身份验证
- 数据可视化如何实现(echart)
- 在项目中如何做到token的无感刷新
- uni-app中要路径跳转,如何提高效率
- 请说一下你项目中微信支付流程如何做的
- 说一下项目中微信授权登录的流程。前后端是如何去交互的
- 项目中权限如何如何渲染,如果后端的权限粒度要控制到每个功能如何实现
- 为什么使用uni-app,你在项目开发的过程中遇到哪些兼容问题,以及如何处理的
- 项目中遇到的最大的问题是什么
- 在页面中如果要同时发送5个接口,当所有接口都成功相应之后,再去做其他操作,这个如何实现
- 项目是如何打包上线的,打包的时候需要配置些什么内容
- 项目中如何实现上拉加载,下拉刷新的,如果要自己实现,说一下思路
- 前端登录后,传递id给后端获取数据,这种方式安全吗?你是如何来避免的
- 项目如何打包为apk,如果是ios系统,如何打包呢
- 团队中各个成员是如何配合的
- 微信小程序如何发布上线
-
-
- 浏览器
- 数据结构相关
-
赶紧点赞收藏起来吧!
css
如何让一个盒子在水平方向和垂直方向都居中
less或者sass相比于css有什么优势?
如何做响应式布局或者如何适配
css sprite(雪碧图或者精灵图) 有什么优缺点?缺点:UI工作量加大。本身只要一个小毛病,全部就要修改
你知道哪些css3新特性和h5新特性
rgba()和opacity的透明效果有什么不同
rgba() 和 opacity 都能实现透明效果,但最⼤的不同是 opacity 作⽤于元素,以及元
素内的所有内容的透明度,
⽽ rgba() 只作⽤于元素的颜⾊或其背景⾊。(设置 rgba 透明的元素的⼦元素不会继承
透明效果!)
js
赶紧点赞收藏起来吧!
js数据类型有哪些?有什么区别
谈一下你对作用域的理解:变量和函数(标识符)的作用范围。作用域分三类:全局,局部,块级作用域({}里去定义)。在JS去查找某个变量的时候,所形成的查找路径就是作用域链。
谈一下你对原型的理解:每一个构造函数都有一个原型对象
prototype(显示原型),改prototype上面会有一个constructor属性指向的是该构造函数本身。通过该构造函数new出来的实例对象上面,会有一个隐式原型__ ‘proto’ __指向的是构造函数的本身
原型链:当JS引擎在查找某个对象的属性时,所形成的查找路径为原型链。先查找对象本身有没有该属性,如果没有则沿着隐式原型找到原型对象,看原型对象上面有没有。如果没有,则继续沿着隐式原型查找上一层的原型对象,知道Object.prototype—>null。如果整条函数都没有找到,则返回undefined
什么是闭包:优点:延长数据生命周期。缺点:有内存溢出/泄露的风险。概念:在一个函数外部调用另一个函数内部。
如何修改函数的this指向,这些方法之间有什么区别?
call,apply,bind。前两个直接在后面加括号,括号内加要指定的位置。bind则是需要接受了以后再调一下。call中接受数组,直接传元素。apply则需要用数组的方式
事件委托或者事件代理的原理是什么?
冒泡传递:从里到外,依次传递。最里面的叫目标事件源。
addEventListener:监听
事件冒泡和事件捕获的区别是什么?
你知道的es6新特性有哪些?
语义化标签,拓展运算符,解构赋值,箭头函数,promise事件,let、const
js异步编程方式有几种
三种:1.回调风格(存在回调地狱,代码阅读性差) 2.promise,但是也没有彻底解决回调地狱的问题。3. async / await
谈一谈对promise的理解
pending fulfilled rejected 当我们创建一个Promise对象的时候,它的状态默认是pending ,要修改它的状态必须调用resolve方法或者reject方法。是一种异步的解决方案。
promise.all([p1,p2,p3]).then().catch() 。有一个失败就进catch
promise.settleter([p1,p2,p3]).then() 。全部执行完毕
promise.race([p1,p2,p3]) 。先进的先执行,只执行一个
const myPromiseObj = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve()
})
})
myPromiseObj.then(()=>{}).catch(()=>{})
js如何浅拷贝和深拷贝一个对象
拷贝几层的区别。浅拷贝只拷贝一层数据
浅拷贝:Object.assign 或者拓展运算符...
如果有对象在里面,那么只会拷贝对象地址。所以修改拷贝对象数据时,原数据也会发生变化。const newObj = Object.assign({},obj)
(obj为原数组)
深拷贝:const deepCopiedObj = JONS.parse(JSON.stringify(obj))
深拷贝在面对特殊字符的时候会出问题
rem和em和px的区别
px是固定单位,rem和em是响应式单位,1rem的大小取决于根节点html的字体大小(即font-size属性),1em的大小取决于其父节点的字体大小,在移动端我们一般用rem,但是要注意:这时html的fontSize属性应该是动态计算的,而不是写死,一般是把当前可视窗口的宽度除以一个经验值得到的比值作为html的fontSize属性值的。
for循环中break和continue的区别是什么?
break:跳出整个循环
continue:跳出档次循环,继续执行后面的循环
如何用原生js给一个按钮的点击事件绑定两个事件处理函数
addEventListener
xxx.addEventListener(‘click’,function(){
});
xxx.addEventListener(‘click’,function(){
})
click:事件类型。function:事件处理函数
js引擎如何实现异步的?
js引擎是通过事件循环(Event Loop)实现异步的。
浏览器是多线程的,常用的主要线程有:js引擎,GUI渲染引擎,http请求线程,事件触发线程,定时触发线程
js引擎的两个核心:
1.执行栈:所有的js代码都会加载到执行栈去执行。(先进后出)
2.任务队列:存放是所有待执行异步任务的回调函数。
当js引擎在执行栈中执行代码的时候,如果发现有异步任务(如:发送请求),则把异步任务交给浏览器的其他线程(http请求线程)来处理。然后继续执行后续的代码。
两条线:
1.js引擎继续执行后面的同步任务。当把执行栈清空以后,会到任务队列中查找有没有待执行的回调函数。有则拿到执行栈中去执行,执行完了,又会去任务队列中查找,如此循环往复的过程,就是事件循环(Event Loop)
2.其他线程(http请求线程)在处理异步任务。当把异步任务处理完成以后(请求成功相应之后),会把之前设置的回调函数,推送到js引擎的任务队列中。
什么是事件循环??
js引擎里面有两个非常重要的部分:执行栈和任务队列
所有的代码都要加载到执行栈里面进行执行
在执行过程中如果发现有异步任务,则js引擎会把这个异步任务交给浏览器的其他线程去处理,比如在执行的时候遇到
接口发送,则js引擎会把它交给http请求线程去处理,然后js引擎继续执行后边的同步任务,但是同http请求线程也在同时
运作,当请求发送成功之后,即数据拿到之后,http请求线程会将我们之前在js里面设置的回调函数推送到js引擎的任务队列里面
当js引擎在执行栈里面把任务清空之后,则回到任务队列里面去寻找有没有待执行的回调函数,有则拿到执行栈里面去执行
执行完了之后,又会到任务队列里面去寻找有没有待执行的回调,如此循环往复的过程就是事件循环,理解了事件循环就理解了
* 浏览器是多线程的,js引擎只是其中一个线程,除此之外还有http请求线程,定时触发线程,事件处理线程,GUI渲染线程
什么是函数柯理化?
通过函数返回函数的方式(闭包),让一个一次性接受多个参数的函数,分解为一次只接受一个参数的若干函数的组合
其作用是为了参数的复用,
function towSum(a,b){
return a + b;
}
//现在对上面的函数进行柯理化
function towSum(a){
return function(b){
return a + b;
}
}
或者
const res = (a)=>(b)=>a+b;
DOMContentLoaded和load事件的区别
区别:执行时机。前者早于load事件。
防抖和节流有什么区别,如何实现
在高频触发的事件中,可能会导致一些性能问题,比如在PC端浏览器缩放时(resize事件),我们在事件处理函数里面如果操作DOM,则用户缩放的时候,可能会导致浏览器卡顿,这是我们就可以通过防抖节流来控制操作DOM的频率,避免过快的操作DOM,但是这两者的区别在于:
防抖的思路是:设置一个延时器,延时n秒在执行相应的逻辑(即频繁执行可能会影响性能的逻辑),如果在n秒内,再次执行了,则清空延时器,并从当下开始从新设置延时器,n秒后再执行。用户动作结束之后执行
节流的思路是:在特定的时间段内,相应的逻辑必须有且只能执行一次。
//防抖
function debunce(func,time){
let timer = null;
return function(){
if(timer)clearInterval(timer);
timer = setTimeout(()=>{
func.apply(this,arguments)
},time);
}
}
//节流
function throttle(func,time){
let preTime = +new Date()
return function(){
const curTime = +new Date()
if(curTime - preTime >= time){
func.apply(this,arguments);
preTime = curTime;
}
}
}
代码题
for(var i=0;i<10;i++){
setTimeout(()=>{
console.log(i)
},1000);
}
for(let i=0;i<10;i++){
setTimeout(()=>{
console.log(i)
},1000);
}
var age = 100;
let years = 6;
if(age > 12){
let age = 10;
var years = age*3;
}
//问:以上代码有问题吗?
//var没有块级作用域一说。let 声明是不能重复定义的。外面定义的var不会影响块级作用域的let
componentDidMount() {
this.setState({ count: this.state.count + 1 });
console.log('1', this.state.count);
this.setState({ count: this.state.count + 1 });
console.log('2', this.state.count);
setTimeout(() => {
this.setState({ count: this.state.count + 1 });
console.log('3', this.state.count);
this.setState({ count: this.state.count + 1 });
console.log('4', this.state.count);
}, 0);
}
//打印结果
showName();//1
function Cat() {
let showName = function () {
console.log(1);
}
return this;
}
Cat.showName = function () { console.log(2) };
Cat.prototype.showName = function () { console.log(3) };
var showName = function () { console.log(4) };
function showName() { console.log(5) };
Cat.showName();//2
showName();//3
Cat().showName();//4
showName();//4
new Cat.showName();//5
new Cat().showName();//6
//打印结果??
function Cat() {
showName = function () {
console.log(1);
}
console.log('this',this)
return this;
}
Cat.showName = function () { console.log(2) };
Cat.prototype.showName = function () { console.log(3) };
var showName = function () { console.log(4) };
function showName() { console.log(5) };
Cat.showName();
showName();
Cat().showName();
showName();
new Cat.showName();
new Cat().showName();
//打印结果,注意跟上一题的区别
-
这段代码有什么问题吗?
this.setState((state,props)=>{ return {total:state.total + props.count} });
-
查看以下代码:如果你在页面中创建了一个React元素,请完成他的组件定义?
<Profile username="sofn"> {user=>user===null ? <Loading/> : <Badge info={user}/>}{" "} </Profile> import React ,{Component} from 'react'; import PropTypes from 'prop-types'; import fetchUser from 'utils'; //fetchUser接收用户名,并返回promise //当得到用户数据的时候返回resolve状态 class Profile extends Component{ //在这里写下你的代码 }
vue
vue3和vue2的区别
vue组件中watch和computed的区别
1. watch中一个值的变化可能会引起多个值的变化,而compouted中多个值的变化会只会影响一个值的变化(即该计算属性返回的值)。可以监听属性,data中的数据。
2. 在watch中我们可能会有副作用,比如发送请求等,而computed则没有副作用,仅仅是根据母体数据衍生出新的数据而已。
1.watch里面可能会有副作用。即,一个函数在执行过程当中对函数的外部造成了一定的影响,该影响就称之为副作用
vue常用的生命周期钩子函数有哪些?分别有什么作用?
钩子函数 | created | mounted | updated | beforeDestory |
---|---|---|---|---|
执行时机 | 数据初始化完毕之后 | DOM渲染完毕之后 | 数据更新完毕并且DOM更新完毕之后 | 组件卸载之前 |
作用 | 发送请求 | 发送请求、获取DOM等 | 发送请求(注意加上条件判断)、获取DOM等 | 性能优化相关,比如清除定时器、延时器、解绑事件等 |
vue如何实现组件通信(组件传值)? 父子 兄弟 复杂组件关系
组件关系 | 父子 | 兄弟 | 复杂组件关系 |
---|---|---|---|
通信方式 | props/绑定自定义事件、$emit | 状态提升、事件总线 | 状态机vuex |
vue项目如何做路由拦截?
全局路由守卫(router.beforeEach)、局部(页面内部)路由守卫
vue的响应式原理 Object.defineProperty
vue组件中data里面的数据,在初始渲染之前都会被Object.defineProperty转化成响应式数据,然后这些数据的访问和修改就能够被监听了,每当数据被访问的时候就会触发getter,接着会通知watcher,watcher这是会做一次依赖的收集或者更新,然后watcher会负责通知渲染界面(先转化为虚拟DOM,在映射为真正的DOM)。每当数据被设置的时候会触发setter,接着setter也会通知watcher,watcher在去通知渲染界面
v-if和v-show的区别
前者操作节点,后者操控样式。前者消耗更大,频繁切换用v-show
v-if和v-for能一起用吗
打灭。后者优先级更高
keep-alive组件有什么作用
缓存组件
this.$nextTick有什么作用
类似updated,你可以称作移动版的updated,如果你想获取数据更新过后,DOM的最新状态,则可以使用该方法(如果你直接获取DOM状态是拿不到的,因为在vue里面数据更新虽然是同步的,但是DOM的更新是异步的),当然你也可以利用updated生命周期钩子函数,但是不方便
this.$set有什么作用
在组件data中预定义的数据,一定是响应式的,但是我们后续,通过常规的方式(比如someObject.propName = xxx)为data中某些对象添加新的属性时,这些新的属性并不是响应式的,这是可以使用该方法。 this.$set(target,prop,value) 这里的prop属性就是响应式的
vuex核心概念
vue如何做路由懒加载
路由配置中component属性的值修改为:()=>import(组件路径)
你认为vue 框架和jquery有什么区别?
开发思想不同,vue是数据驱动,并且可以组件化开发,jquery则是DOM驱动的,开发效率低
vue如何自定义指令
如何封装一个vue插件
vue中什么是过滤器(filter)
vue如何提取组件的公共逻辑
vuex/mixins/自定义指令/插件
react
shouldComponentUpdate有什么作用?
它是react组件的一个 生命周期钩子函数,每次数据更新时,首先会执行该钩子函数,如果返回true,表示可以更新界面,然后后续的钩子函数才会陆续执行,返回false,则表示不可以更新,后续的钩子函数也不会执行,当然它默认返回true,
我们一般不会直接在组件中使用该钩子函数,而是会选择PureCompopnent来代替Component,在PureComponent里面就利用来该钩子函数来做优化
setState有什么特性
它的作用是更新组件内部状态,可以接受两个参数,参数一个一般是个对象,在底层react会通过Object.assign把传入的对象和原来的state进行合并,当然也可以传入一个函数,这个函数会接受两个形参(一个表示state,一个表示props),并返回个对象,要注意的是,这个函数在执行是会保证之前的state已经更新完毕,最后在把该函数返回的对象和原来的对象进行合并。当新的状态值会基于老的状态值时,我们会倾向于给setState的第一个参数传递一个函数进去。它的第二个参数则是一个回调函数,会在数据更新完毕,并且dom更新完毕时执行。
另外,当我们在react事件体系或者组件生命周期钩子函数里面直接调用setState的时候,它是异步的,其他情况是同步的,比如在setTimeout/setInterval里面调用就是同步的
this.setState({name:'张三'});
this.setState((state,props)=>({})
react列表渲染时,key的作用
提升渲染性能
react组件之间如何通信
父子(props)、兄弟(状态提升、事件总线)、复杂组件关系(状态机)
解释一下redux核心概念
store action reducer
react常用的生命周期钩子函数有哪些?分别有什么作用
钩子函数名 | constructor | render | componentDidMount | componentDidUpdate | componentWillUnmount |
---|---|---|---|---|---|
执行时机和作用 | 组件初始化时负责数据的初始化 | 渲染界面 | DOM渲染完毕时执行,可以在这里发送接口,获取DOM等 | 数据更新完毕且界面更新完毕后执行 | 组件即将卸载的时候执行,可以在这里清除定时器,延时器,解绑事件等等 |
react中refs有什么作用?
1. 获取DOM
2. 获取组件实例
redux中间件是什么,有什么作用,你常用的中间件有哪些?
redux三大原则是什么?
- 单一数据源
- store中的数据(state)是只读的
- 必须通过纯函数reducer来执行修改
react中容器组件和展示组件有什么区别?
函数组件和类组件有什么区别(16.8以前)?
react如何提取组件之间的公共逻辑
什么是高阶组件?有什么作用?你常用的高阶组件有哪些
受控组件和不受控组件有什么区别?
谈一谈你对jsx的理解?
react组件的数据来源有哪些?他们之间有什么区别?
react插槽是什么?(或者react中如何实现组件复合?)
react中context是什么?
react中废弃了哪些和新增了哪些生命周期钩子函数
小程序
小程序一个页面有几个文件构成?
小程序怎么跟后台交互
(1)直接用微信官方提供的接口 wx.request接口,跟jquery的ajax差不多
小程序怎么做扫码功能,怎么做支付功能
(1)调用微信提供的现成的接口(wx.开头的),即可,具体参数怎么传参照文档即可
微信里面怎么获取用户的手机号??
(1)简单,直接用微信官方提供的现成组件button即可,具体用法是在button上加一个属性opent-type,方它的值为getPhoneNumber,不知道怎么用的去找微信官文档看看、
小程序分包是什么?有什么作用?
提示:跟vue路由懒加载有类似的作用,提升用户体验度,减少首屏渲染速度
https://developers.weixin.qq.com/miniprogram/dev/framework/subpackages/basic.html
https://blog.csdn.net/acmdown/article/details/80037660
其他
性能优化
从用户在浏览器中输入url,到浏览器渲染出界面,中间发生了什么?
DNS域名解析------》发起http或者https请求------》服务端处理请求-------》浏览器接受请求响应,并渲染界面
SPA(single page application)如何提高首屏(注意:不是首页,一般你在url中输入一个新的路劲,然后回车,即是一个首屏)的渲染速度
DNS域名解析部分优化
- DNS prefetch(DNS预解析)
在html头部使用link标签进行DNS预解析
<link rel="dns-prefetch" href="//www.baidu.com">
发起请求部分
-
减少请求次数
-
采用css sprinte(也叫雪碧图或者精灵图),即:如果有多张比较小的背景图,可以合成一个,然后通过background-position去设置背景,而不用每个都去发送请求
-
某些图片编译成可以是用base64格式(webpack中的url-loader会自动把大小小于某些值的图片编译成base64格式的,然后内嵌到js文件中,所以后续在访问这些图片时,不在需要单独发送请求)
-
何时用base64格式的图片??,可以参考以下几个因素
-
这类图片不能与其他图片以CSS Sprite的形式存在,只能独行
-
这类图片从诞生之日起,基本上很少被更新
-
这类图片的实际尺寸很小
-
这类图片在网站中大规模使用
-
-
-
合并脚本和样式表,但是要视情况而定,如果合并脚本或者样式表后,包的体积变得非常大,反而会过度延长网络请求时间,从而导致首先渲染更慢
-
利用http缓存(新鲜度限值和服务器在验证)
-
-
减少请求或者服务端响应式时(当然主要是响应),网络数据包的大小
- 压缩css/js、图片等
- 路由懒加载
-
缩短网络的传输距离,优化网络传输路径
- 利用CDN(内容分发网络),一般我们会把静态资源,即很少变化,体积有比较大的资源交给CDN服务商管理
服务端优化:不需要关注
使用单独的图片服务器、使用redis缓存、使用负载均衡等等
浏览器渲染
-
css放在body之前,script放在body之后
-
ssr(server side render—服务端渲染)
-
requestAnimationFrame
对于动画来讲:定时器为什么不是一个好的方案
1. 开发人员并不知道,间隔多少时间出发一个动画何时,间隔时间如果太短,则会损耗浏览器的性能,如果间隔时间太长,则用户就会感觉卡顿。并且定时器自身机制的问题,它的回调函数触发的时机可能并不是你设置的时间,因为他要等到执行栈里面的任务清空之后再去执行
优化要达到的目的:间隔时间合适,同时用户不会觉得卡
分析:
第一:间隔时间要合适,你自己手动设置肯定不行,因为延时器或定时器触发的时机本就不精确。
第二:用户不会觉得卡顿,首先我们要搞清楚是什么原因导致的卡顿,所以接下来,我们要解释一下浏览器帧的概念
帧:浏览器中的页面是有一帧一帧绘制出来的,当每秒钟绘制的帧数(FPS–Frame Per Second)大于或等于60的时候,用户是感觉不到卡顿的,换言每一帧的时间控制在1s/60,也就是大约16.6毫秒之内时,用户是感觉不到卡顿的。
在一帧中浏览器大致做了如下事情(有时不一定每一步都会执行):
1. 处理用户的交互
2. js解析执行(例如用户事件处理函数中的逻辑)
3. 调用window.requestAnimationFrame中注册的函数(注意:这个函数其实是上一帧中注册的函数,且如果在这一帧中发现有注册的函数,则该函数一定会被执行)
4. Layout(布局,如果第二次触发,我们就称之为回流)
5. Paint(绘制,如果第二次触发我们就称之为重绘)
6. 如果前五步骤执行完了之后,这一帧还有剩余时间,则调用window.requestIdleCallback中注册的函数
也就是说这前五个步骤(其他我们先暂时不用考虑)执行时间总和要在16.6毫秒内,才能保证用户体验。
结论:我们可以利用requestAnimationFrame实现动画逻辑,并且不需要传递时间,在这里触发动画,一般情况1秒钟也能达到60帧(当然动画里的逻辑也不能太复杂,在这一步,如果执行时间过长也会导致掉帧(1秒钟没有达到60次),从而让用户决定卡顿),具体用法如下(实现一个元素,在水平方向上左右移动的效果)
<div style="width:50px;height:50px;background-color: red;" id="myDiv"></div> let originStep = 10; let step = 10;//每次移动的距离 let direction = 1;//移动的方向1表示向右,-1表示向左 let left = 0;//元素的偏移量 const offsetWidth = document.body.offsetWidth;//body的宽度 const el = document.getElementById('myDiv'); const eleWidth = el.offsetWidth;//元素的宽度 const runAnimation = () => { if(direction === 1){ const remainOffset = offsetWidth - (left + eleWidth);//向右移动时,距离右边距剩余距离 if(remainOffset < step && remainOffset !== 0){ step = remainOffset;//保证向右的移动不会超出右边接线 } }else{ step = originStep;//当向左移动的时候恢复移动速度 } if(left <=0){ direction = 1; }else if(offsetWidth <= left + eleWidth){ direction = -1; } const xOffset = left += step*direction; el.style.transform = `translate(${xOffset}px,0)`; requestAnimationFrame(runAnimation);//在注册回调 } requestAnimationFrame(runAnimation)
-
requestAnimationFrame执行过后会返回一个id,跟定时器一样,我们可以根据这个id取消对应的requestAnimationFrame
const cancelId = requestAnimationFrame(runAnimation); cancelAnimationFrame(cancelId);
-
-
requestIdleCallback
SSR(Server Side Render)和CSR(Client Side Render)
SSR
浏览器中显示的页面,是由服务器拼接好模板,然后通过网络传送到浏览器,在有浏览器直接渲染的,由于在网络传输路径中携带了网页的内容,所以ssr模式非常适合做SEO,同时服务器拼装模板的速度会比浏览器快很多,所以SSR模式也会提升网站的首屏渲染速度。但是也会增加服务端的压力。
ssr两个优势
利于seo
缩短首屏渲染速度
CSR
webpack
webpack有什么作用?
什么是webpack ? 模块化的打包工具,原理是,我们必须向它提供一个入口js文件,然后webpack会根据这个入口文件生成一张依赖图,然后在堆这张依赖图里面的文件进行转义和打包,最后生成浏览器能够识别的资源文件(css js 。。。)
作用:
1. 让项目模块化
2. 编译scss/less .vue jsx
3. 性能优化:压缩、代码拆分、图片转base64格式。。。
4. 工程化:自动编译、打包
webpack常用配置项有哪些?(webpack.config.js)
-
entry:入口文件
-
output:出口文件
-
module
module:{ rules:[ { test:/\.css$/, use:['style-loader','css-loader'],//从后往前执行 } ] }
网络相关
常用的http状态码有哪些,
1. 200
2. 404
3. 401
4. 500
5. 304
6. 301 资源永久重定向
http和https的区别
安全:https协议在传输数据的时候,会对数据进行加密,http则是明文传输
性能:http协议的传输性能更高,因为对于传输同样的数据量来讲,由于https协议需要加密处理,所以最终在线路上它的数据量要大一点
费用:https需要购买证书,http则免费
默认端口不同:https–443 http—80
websokect和http的区别
websokect能够实现客户端和服务端的双向通信,http则只能是单向通信,由客户端去请求服务端,服务端不能主动的向客户端推送数据
应用场景不同
websokect 实时通信 数据的实时更新
http 简单的客户端请求服务端
业务相关
如何处理权限问题
比如后台管理系统,不同的角色看到的侧边栏项是不同的,如何实现?
首先把侧边栏抽象成一个数组,数组里面每一元素(对象)则表示每一个侧边栏,并且在每一个元素里面,我们需要添加一个表示角色的字典,以此来区分,何种角色能够看到当前侧边栏项,
接线来,就要根据当前登录人的角色 去 过滤当前数组,并返回当前角色能看到的侧边栏数据
最后在根据得到的数据,进行遍历循环,渲染侧边栏
前端如何实现身份验证
- session 早些年在token出现之前都是通过session来实现浏览器客户端的身份验证的,每次用户登录时把用户名和密码传到后端服务器,后端服务器验证用户名和密码,如果验证通过就会生成一个sessionId,并存储到服务器中,同时该请求在响应给客户端时,会通过
Set-Cookie
字段把sessionId投放并存储到客户端(浏览器)的HTTP-cookies
,当客户端下一次发送请求到服务端的时候会自动携带上存有sessionId的cookie。这样后端服务器拿到sessionId和之前存储的sessionId一对比,如果一样就确定该用户是之前的用户,然后就把数据响应到客户端了。 - token 每次用户登录时把用户名和密码传到后端服务器,后端服务器验证用户名和密码,如果验证通过一般会用过
JWT
结合用户信息通过一个秘钥(该秘钥会存储到服务器)加密生成一个token,然后把该token返回给客户端,客户端一般把token存储到本地存储,比如localStorage
或者sessionStorage
中。后续在在发送接口的时候会把token从本地存储中取出来,放到请求头Header
中发送给后端服务器。后端拿到token,然后通过之前的秘钥尝试去解该token,如果能解密出来就说明该token是合法的,否则就是不合法的。 - session和token的区别
- session需要借助于cookie,而cookie只有浏览器支持,如果要做app则没办法用session来实现身份验证。只能用token
- seesion需要在服务器中存储每位用户对应的sessionId,而token只需要存一份秘钥即可。
数据可视化如何实现(echart)
option setOption(option)
如何实现数据的实时更新 websocket
在项目中如何做到token的无感刷新
uni-app中要路径跳转,如何提高效率
使用uni.preloadPage页面预加载,但是该方法有兼容性问题,只在app端和H5端有效
请说一下你项目中微信支付流程如何做的
说一下项目中微信授权登录的流程。前后端是如何去交互的
参照:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
项目中权限如何如何渲染,如果后端的权限粒度要控制到每个功能如何实现
为什么使用uni-app,你在项目开发的过程中遇到哪些兼容问题,以及如何处理的
- 页面预加载,只有H5和APP端支持,小程序不支持
- css中给元素设置背景图,H5端支持,小程序不支持(在小程序端用行内样式设置背景图即可)
- css中通配符*在H5端支持,但是小程序不支持
- 在非H5端不能使用ref的方式引用内置组件(比如view等)
- 如果想为不同的平台写不同的代码,可以使用条件编译
项目中遇到的最大的问题是什么
在页面中如果要同时发送5个接口,当所有接口都成功相应之后,再去做其他操作,这个如何实现
promise.all同时注意与promise.allSettled做对比
项目是如何打包上线的,打包的时候需要配置些什么内容
项目中如何实现上拉加载,下拉刷新的,如果要自己实现,说一下思路
前端登录后,传递id给后端获取数据,这种方式安全吗?你是如何来避免的
1. 把get方式换成POST
2. 如果我用抓包工具,把数据抓下来,在伪装发送接口,怎么办?-----http-->https
项目如何打包为apk,如果是ios系统,如何打包呢
团队中各个成员是如何配合的
微信小程序如何发布上线
微信小程序上线发布,通过有上角的上传按钮即可哈,上传后,微信官方会做一个审核,审核通过之后,我们就能够通过微信搜索到该小程序了
浏览器
什么是跨域?如何解决
跨域是浏览器的同源策略导致的问题,当我们的协议、域名和端口号,任意一个不同的时候,就会导致跨域的出现
常见的一个场景,前端请求后端api的时候出现跨域,如何解决?
-
前端处理:代理服务器 webpack-dev-server (vue.config.js)
devServer:{ proxy:{ "/api":{ target:"http://localhost:8000" } } }
-
后端处理
- 设置响应头
浏览器渲染页面的流程
GUI渲染线程负责界面的渲染过程
同时解析html/css
解析html ---->DOMTree
解析css—>CSSTree
然后合并DOMTree和CSSTree形成RenderTree(渲染树)
接下来开始layout (布局,回流)
绘制(重绘)
根据这些过程我们可以知晓在写html的时候需要注意的一些事项(性能优化)
1. css放在头部
2. js放在尾部,因为js是有js引擎去编译和执行的,而js引擎和GUI渲染引擎是互斥的
重绘和回流有什么区别
数据结构相关
你知道的数据结构有哪些?
栈、队列、链表、二叉树
空间复杂度和时间复杂度
这个两个概念是用来衡量一个算法优劣的两个维度,空间复杂度表示,算法所消耗的内存大小,而时间复杂度,表示一个算法所消耗的时间。一般情况下,我们更看重一个算法在时间上的消耗。如果时间太长,则认为这个算法是不太好的需要优化,所以才会有用空间换时间这个说法。
时间复杂度可以用大O表示法。