前端工程师---面试知识总结(持续更新)

251 阅读18分钟

知识点参考链接,前面几个链接是手机端的可以在浏览器开启手机调试模式浏览 - 50个vue知识点自我检测

简答题

1. 元素水平垂直居中的方式

2. 定位有几种,分别的基准是

  • a.定位为四种static、relative、absolute、fixed
  • b.static:无定位的意思
  • c.relative:相对定位;相对于本身的位置定位
  • d.absolute:绝对定位;对于最近的拥有relative的父级,如若没有,一直向上查找,直到Document
  • d.fixed:固定定位;对于浏览器可视区的位置定位 更多扩展

3. :和::区别是

  • a.:伪类,是元素的一种动态变化时会产生的特定状态,在这个状态下需要设置一些样式。它的功能和class有些类似,但它是基于文档之外的抽象,所以叫伪类。例如:hover、:active、:first-child
  • b.::伪元素,是所控制的内容和一个元素控制的内容一样,但是伪元素不存在于文档树中,不是真正的元素,所以叫伪元素.。例如:::first-letter、::first-line、::before、::after 更多扩展

4. 盒模型

  • a.盒模型=content+padding+border+margin
  • b.标准盒模型:width和height是内容区域即content的width和height
  • c.iE盒模型:又称怪异盒模型,width和height除了content区域外,还包含padding和border
  • d.通过box-sizing属性可以改变和模型
    • (1)当设置为box-sizing:content-box时,将采用标准模式解析计算,也是默认模式;
    • (2)当设置为box-sizing:border-box时,将采用怪异模式解析计算; 标准盒模型IE盒模型

5. 去除浮动的方法

a.在浮动元素后面加个空标签 <div style='clear:both'></div>

b.在浮动元素的父元素加伪元素

.clearfix:after{

    content:"";

    display:block;

    visibility:hidden;

    clear:both;

    }

c.给父元素设置了overflow样式,不管是overflow:hidden或overflow:auto都可以清除浮动只要它的值不为visible就可以了,它的本质就是建构了一个BFC,这样使得达到撑起父元素高度的效果

.box{border:1px solid #ccc;background:#eff2f4;overflow: auto}

d.双伪元素方法的使用


.clearfix:before,.clearfix:after {

     content: "";

     display: block;

     clear: both;

}

更多扩展

6. 响应式布局

  • a.响应式布局是同一页面在不同的屏幕上有不同的布局,即只需要一套代码使页面适应不同的屏幕

  • b.媒体查询@media

  • c.布局利用百分比

  • d.vw/vh单位:是视口单位,即根据浏览器的窗口大小进行适配

  • e.rem单位:指相对于根元素的字体大小的单位,rem只是一个相对单位

    更多扩展

7. es6的新特性(面试官可能会深入的去问你所说的特性解决了es5中存在的哪些问题)

  • a.const、let变量声明
  • b.模版字符串
  • c.结构赋值
  • d.rest参数
  • e.默认参数
  • f.promise
  • g.新增Symbol数据类型,代表唯一的值
  • h.新增Set数据结构,类似于数组,但是每一项是唯一值,多应用于数组去重
  • i.新增Map数据结构,类似于对象,但是键的类型不限于字符串
  • j.迭代器(lterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署lterator接口,就可以完成遍历操作
  • k.生成器Generator函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同,是一种特殊的函数, function* functionName(){yield '111}; functionName.next() l.展开运算符‘...' 更多扩展

8.谈谈对promise的理解,解决的什么问题

  • a.promise是es6新增的一个异步编程的一种解决方案.用来解决异步操作(回调地狱)问题。
  • b.promise有三种状态,pending(等待中)、fulfilled(成功)、rejected(失败)。
  • c.两个过程,pending=>fulfilled进入then;pending=>rejected进入catch
  • d.promise是同步的,then和catch是异步的 扩展更多

9.请求get和post的区别

  • a.get和post都是http请求的一种方式
  • b.get向服务端传输数据是拼接在url后面,安全性低,长度是有限的,并且编码格式一定得是ASCII编码;
  • c.post向服务端传输数据是将数据包装到请求体里(request body),安全性好,长度没有限制,数据可以是多种格式。
  • d.get请求在浏览器刷新和回退操作是无害的,而post会被重新提交
  • e.get请求数据可以被浏览器缓存在历史中,而post不可以
  • f.GET查询的结果可以加入书签中,因为它以URL的形式存在;而POST查询的结果无法加入书签中。 扩展更多

10.说说前端路由原理hash和history

  • a.hash模式是将路由的路径用“#”拼接到url后面,当井号 # 后面的路径发生变化时,浏览器并不会重新发起请求,而是会触发 onhashchange 事件进一步引起页面跳转。hash 可以改变 url ,但是不会触发页面重新加载(hash的改变是记录在 window.history 中),即不会刷新页面。也就是说,所有页面的跳转都是在客户端进行操作。因此,这并不算是一次 http 请求,所以这种模式不利于 SEO 优化。hash 只能修改 # 后面的部分,所以只能跳转到与当前 url 同文档的 url 。
  • b.history模式是h5新增的一种路由模式,允许开发者直接更改前端路由,即更新浏览器 URL 地址而不重新发起请求
  • c.history模式,通过 pushState 、 replaceState 来实现无刷新跳转的功能 扩展更多

11. 三次握手和四次挥手

在这里插入图片描述

a.在客户端向服务端发送请求连接时,tcp会进行一个叫“三次握手”的操作才能建立起链接 (1)第一次握手:客户端携带SYN(同步序列号为1)请求报文发往服务端,告诉服务,我要请求连接,发送数据过来。 (2)第二次握手:服务端接收到客户端发送的请求连接的报文,将SYN=1和ACK=0应答域报文一同发往客户端,意思就是告诉客户端我收到你的连接请求了,并为这次连接分配好资源,你可以发送数据了。 (3)第三次握手:客户端接收到服务端发送的ACK=0报文后也向Server段发生ACK=1报文,意思是说我收到你的回复了,接下来我要发送数据了 在这里插入图片描述

b.客户端向服务端请求断开连接,tcp会进行一次叫做“四次挥手”的操作来断开连接 (1)第一次挥手:假设Client端发起中断连接请求,也就是发送FIN报文 (2)第二次挥手:Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。 (3)第三次挥手:当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。 (4)第四次挥手:Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了 在这里插入图片描述

[扩展更多](https://blog.csdn.net/su_bao/article/details/80845246)

12 当你打开浏览器页面,从请求到响应的过程请描述一下

  • a.在浏览器中输入url地址,按下回车键
  • b.浏览器先在缓存中寻找,是否存在,如果存在直接从缓存中读取返回,如果不存在进入下一步
  • c.将域名通过DNS域名解析服务器解析成ip地址发送请求
  • d.tcp的“三次握手”,监理链接
  • e.服务器响应返回数据
  • f.接收到数据,开始渲染
  • d.渲染完成,请求断开连接(TCP的‘四次挥手’) 扩展更多

13. js的原型和原型链

扩展更多

14. var,const,let的区别

  • a.const 和let都是es6新增的声明变量的方式
  • b.let声明变量,const声明常量,若声明的常量为基本数据类型(Number,String,Boolean,underfine,Symbol,null),是不可修改的;若声明的常量为引用类型(Array、Object、Function、Map、Set),指向数据地址的指针不能变但是可以修改里面的值的

穿插一个小的知识点,注意这里要特别注意null的歧义 如何让const声明的引用数据类型的常量数据值也不能修改

c.var声明的变量存在变量提升的问题,而const、let不存在。所谓的变量提升就是可以“先引用,后声明”。 d.var 声明的变量属于函数作用域,let 和 const 声明的变量属于块级作用域; e.var 变量可以重复声明,而在同一个块级作用域,let 变量不能重新声明,const 变量不能修改。

15. this的指向问题,如何改变this的指向

  • a.以函数的形式(包括普通函数、定时器函数、立即执行函数)调用时,this 的指向永远都是 window。比如fun();相当于window.fun();
  • b.以方法的形式调用时,this 指向调用方法的那个对象
  • c.以构造函数的形式调用时,this 指向实例对象
  • d.以事件绑定函数的形式调用时,this 指向绑定事件的对象
  • e.使用 call 和 apply 、bind调用时,可以改变this的指向,this 指向指定的那个对象
  • f.call、apply、bind第一个参数传的都是this所指定的对象,第二个参数传入函数的实参。
  • g.call、bind的第二个参数传的的参数列表,而apply传的是参数数组。
  • h.call、apply是立即调用的,而bind是返回一个函数,可以之后需要的时候在调用。 扩展更多 call,bind,apply

16. 数组去重的方法你可以列举哪些

a.ES6新语法new Set()

const arr =[1,2,34,54,1,2]
const newArr = [...(new Set(arr))]

b.Array.reduce()

const arr =[1,2,34,54,1,2]
const newArr=arr.reduce((pre,cur,index)=>{
if(!pre.includes(cur)){
pre.push(cur)
}
return pre
},[])

c.forEach和includes方法

const arr =[1,2,34,54,1,2]
const newArr =[]
arr.forEach(item=>{
if(!newArr.includes(item)){
newArr.push(item)
return;
}
return;
})

扩展更多

17.vue Router路由守卫

扩展更多

18. vue中的常用指令有哪些

v-for,v-if,v-bind,v-on,v-html,v-show

19.computed和watch

扩展更多 扩展更多2

20. 什么是虚拟dom

  • a.虚拟dom:就是 通过js对象表示的DOM结构。
  • b.尝试虚拟dom的原因:操作一次的dom的渲染成本远远超过与操作虚拟dom的成本,操作dom是最耗费性能的,所以通过将dom对比操作放在js层,提高效率,也就是虚拟dom。 在这里插入图片描述

21. 简述vuex

  • a.vuex是一个统一的状态管理仓库
  • b.由五大模块组成,state、get、mutation、action、module
  1. state:提供唯一的公共数据源,所有共享的数据都要统一放到State中进行存储

  2. get:对store中的数据进行加工处理形成新的数据

    • Getter可以对store中的数据加工处理之后形成新的数据,类似于Vue中的计算属性

    • Store中的数据发生变化,Getter的数据也会跟着变化

  3. mutation:唯一改变state的途径,同步方法

    • 触发mutations的第一种方式:“this.$store.commit()”

    • 触发mutations的第二种方式:从vuex中导入mapMutations函数

methods: {
...mapMutations(['add','addN'])
}
  1. action:用于处理异步任务,如果通过异步操作变更数据,必须通过Action,而不能使用Mutation,但是Action中还是要通过触发Mutation的方式变更数据

    • 触发Actions的第一种方式“this.$store.dispatcht()”

    • 触发Actions的第二种方式导入mapActions函数 methods:{ ...mapActions(['addAsync','addNAsync ']) }

  2. module:根据不同功能模块,拆分出来管理自己的store仓库

22. 如何做性能优化

在这里插入图片描述

23. 简述你在做项目过程中遇到的难题,是如何解决的,思路是什么

24.MVC与MVVM的区别

a.mvc是单向绑定的,mvvm双向绑定 b.mvc,视图层是依赖model层,而MVVM是完成的视图和model分离 扩展更多

25.弹性布局

扩展更多

26.Vue的优缺点

在这里插入图片描述

27.uni-app的生命周期

    1. onLoad:首次进入页面加载时触发,可以在 onLoad 的参数中获取打开当前页面路径中的参数。
    1. onShow:加载完成后、后台切到前台或重新进入页面时触发
    1. onReady:页面首次渲染完成时触发
    1. onHide:从前台切到后台或进入其他页面触发
    1. onUnload:页面卸载时触发
    1. onPullDownRefresh:监听用户下拉动作
    1. onReachBottom:页面上拉触底事件的处理函数
    1. onShareAppMessage:用户点击右上角转发

28.uni-app的路由跳转

传送门

29.js中的循环

传送门

30.href和src的区别

  • a. href用于建立当前页面与引用资源之间的关系(链接),通常在a、link等标签中使用。而src则会替换当前标签,src常用在img、iframe、video、audio、script等标签中。
  • b.遇到href,页面会并行加载后续内容;而src则不同,浏览器需要加载完毕src的内容才会继续往下执行。这也就是为什么我们建议js文件放在HTML文档的最后面。如果js文件放在了head标签中,可以使用window.onload()方法,实现js的最后加载。;

31.哪些数组方法会改变原数组

传送门

32.谈谈对Map和Set的理解

  • a. Map是一种叫做字典的数据结构;【键,值】方式存储;
  • b. Map的键值对个数可以从size属性获取,而对象的键值对个数只能手动计算;键的数据类型不仅仅仅限于字符串,且无序(和Object的区别)
  • c. Set是一种叫做集合的数据结构;【值,值】方式存储;集合中的值是唯一的(和Array的区别) 传送门

33.开发过程中有没有遇到过小数运算精度缺失的问题,是如何处理的

  • a. 原因其实就是js number类型运算都需要先将十进制转二进制,但小数点后的位数转二进制会出现无限循环的问题,只能舍0入1,所以会出现小数点丢失问题
  • b. 方法一:保留小数位数toFix()计算(注意:toFixed()保留完是字符串,需要转数字类型
parseFolat((0.1+0.2).toFixed(2))   //0.3
  • c. 方法二:乘以10的倍数,计算完之后在除以10的倍数

34.浏览器存储方式有哪些

image.png IndexeDB-传送门

35. session和cookie的区别以及应用场景

  • a. 保存的位置不同:cookie保存在浏览器端,session保存在服务端。
  • b. 使用方式不同: cookie如果在浏览器端对cookie进行设置对应的时间,则cookie保存在本地硬盘中,此时如果没有过期,则就可以使用,如果过期则就删除。如果没有对cookie设置时间,则默认关闭浏览器,则cookie就会删除。 session:我们在请求中,如果发送的请求中存在sessionId,则就会找到对应的session对象,如果不存在sessionId,则在服务器端就会创建一个session对象,并且将sessionId返回给浏览器,可以将其放到cookie中,进行传输,如果浏览器不支持cookie,则应该将其通过encodeURL(sessionID)进行调用,然后放到url中。
  • c. 存储内容不同:cookie只能存储字符串,而session存储结构类似于hashtable的结构,可以存放任何类型。
  • d. 存储大小:cookie最多可以存放4k大小的内容,session则没有限制。
  • e. session的安全性要高于cooKie
  • f. cookie的session的应用场景: cookie可以用来保存用户的登陆信息,如果删除cookie则下一次用户仍需要重新登录 session就类似于我们拿到钥匙去开锁,拿到的就是我们个人的信息,一般我们可以在session中存放个人的信息或者购物车的信息。
  • g. session和cookie的弊端: cookie的大小受限制,cookie不安全,如果用户禁用cookie则无法使用cookie。如果过多的依赖session,当很多用户同时登陆的时候,此时服务器压力过大。sessionId存放在cookie中,此时如果对于一些浏览器不支持cookie,此时还需要改写代码,将sessionID放到url中,也是不安全。

36.如何取data中定义的初始值

this.$option.data().属性值

37.不需要响应式的数据如何处理

  • a. vue2.x:定义在data函数之外,或者使用Object.freeze()
  • b. vue3:普通方式定义变量,不使用ref,reactive包裹变量

38.相同的路由文件如何渲染

使用key

const routes = [
    { path: "/a", component: MyComponent }, 
    { path: "/b", component: MyComponent }, 
];

...

<router-view :key="$route.path"></router-view>

39.vue中路由跳转方式

//方式一 <router-link to="{需要跳转到的页面的路径}">

//方式二 this.$router.push()(常用)

//方式三 this.$router.replace()

//方法四 this.$router.go(n)

传送门

40.vue中routeroute和router的区别

  • a. router为VueRouter的实例,相当于一个全局的路由器对象,里面含有很多属性和子对象,例如history对象。经常用的跳转链接就可以用this.$router.push,和router-link跳转一样
  • b. route相当于当前正在跳转的路由对象,可以从里面获取name,path,params,query等

传送门

41.什么是同步和异步,异步的解决方案有哪些

js是单线程语言,在同一个时间只能做一件事,单线程意味着,如果在同个时间有多个任务的话,这些任务就需要进行排队,前一个任务执行完,才会执行下一个任务。

  • a. 同步任务

    同步任务是指在主线程上排队执行的任务,只有前一个任务执行完毕,才能继续执行下一个任务,当我们打开网站时,网站的渲染过程,比如元素的渲染,其实就是一个同步任务

  • b. 异步任务

    异步任务是指不进入主线程,而进入任务队列的任务,只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程,当我们打开网站时,像图片的加载,音乐的加载,其实就是一个异步任务

解决方案

  • a.回调函数:回调函数是作为参数传递给另一个函数并在其父函数完成后执行的函数。
function doSomething(msg, callback){
    alert(msg);
    if(typeof callback == "function") 
    callback();
 } 
doSomething("回调函数", function(){
    alert("匿名函数实现回调!");
 }); 

  • b.事件监听:思路是采用事件驱动模式。任务的执行不取决于代码的顺序,而取决于某个事件是否发生
 element.addEventListener("click", function(){ 
	alert("Hello World!"); 
});

  • c.发布-订阅:发布-订阅模式其实是一种对象间一对多的依赖关系,当一个对象的状态发送改变时,所有依赖于它的对象都将得到状态改变的通知。

订阅者(Subscriber)把自己想订阅的事件 注册(Subscribe)到调度中心(Event Channel); 当发布者(Publisher)发布该事件(Publish Event)到调度中心,也就是该事件触发时,由 调度中心 统一调度(Fire Event)订阅者注册到调度中心的处理代码。

◾ 例子 比如我们很喜欢看某个公众号号的文章,但是我们不知道什么时候发布新文章,要不定时的去翻阅;这时候,我们可以关注该公众号,当有文章推送时,会有消息及时通知我们文章更新了。

上面一个看似简单的操作,其实是一个典型的发布订阅模式,公众号属于发布者,用户属于订阅者;用户将订阅公众号的事件注册到调度中心,公众号作为发布者,当有新文章发布时,公众号发布该事件到调度中心,调度中心会及时发消息告知用户。

◾ 发布/订阅模式的优点是对象之间解耦,异步编程中,可以更松耦合的代码编写;缺点是创建订阅者本身要消耗一定的时间和内存,虽然可以弱化对象之间的联系,多个发布者和订阅者嵌套一起的时候,程序难以跟踪维护。

  • d. ES6提供:Promise函数
  • e. ES8提供:async/await函数

传送门

42.vue的响应式是如何实现的

  • a. vue2.x:数据劫持+观察者模式,Object.definePrototy对象方法
  • b. vue3:proxy代理

传送门

编程题

  1. 元素水平垂直居中的方式
  2. 手写节流函数
//时间戳节流
function throttle(fn,delay){
    let cur = Date.now()
    return funtion (){
        let now = Date.now(),ctx = this 
        if(cur+delay>=Date.now){
            cur = Date.now
            return  fn.apply(ctx,arguments)
        }
    }
   
}
//定时器版节流
function throttle(fn,delay){
let timer =null
return function(){
    let ctx = this 
    if(!timer){
        timer = setTimeout(()=>{
        fn.apply(ctx,arguments)
        timer = null
        },delay)
    }
}

}
  1. 防抖函数的实现
function debouce(fn,delay){
    let timer = null
    return function(){
        let ctx = this 
        if(timer){
            clearTimeOut(timer)
        }
        timer = setTimeout(()=>{
            fn.apply(ctx,arguments)
        },dealy)
    }
}
  1. 实现去除字符串两端的空白函数(不能用trim函数)
function myTrim(e) {
    return e.replace(/^\s+/, '').replace(/\s+$/, '')
}

let str = '   34gy sdgg8 4mdijo  '
console.log(myTrim(str)) // '34gy sdgg8 4mdijo'


let str = '   xin xiang   ';

console.log('去掉左边空格');
console.log(str.replace(/^\s*/g, ''));     

console.log('去掉右边空格');
console.log(str.replace(/\s*$/g, '')); 

console.log('去掉中间空格');
console.log(str.replace(/[ ]/g,''));  

console.log('去掉两端空格');
console.log(str.replace(/^\s*|\s*$/g, '')); 

console.log('去掉全部端空格');
console.log(str.replace(/\s+/g, '')); 
  1. 冒泡排序
  2. 手写bind函数
Function.prototype.myBind = function(){
    if(typeof this != Function){
        console.log('type error')
        return
    }
    //类数组转换成数组
    let realArrArg = Array.from(arguments)
    const _this = realArrArg.shift()
    const self = this
    retutn function(){
        return self.fn.apply(_this,realArrArg)
    }
}


传送门

  1. 手写apply方法
Funciton.prototype.myApply = function (ctx,arr=[]){
    if(typeof this != Function){
        console.log('type error')
        return
    }
    const obj = ctx == underfined || ctx == null ? window : Object(ctx)
    obj.fn =this
    const result = obj.fn(...arr)
    delete obj.fn
    return result
}

传送门

  1. 实现promise函数