【面试题】2024-04,05面试集合,搞钱要紧 【抓紧面试】(1)

let arr = [0,1,2,3,4,5,6,7];
let newArr = arr.slice()//newArr = [0,1,2,3,4,5,6,7];


// 2.#### 原数组改变的
push()数组的最后面,添加一个或者多个元素。
结构: arr.push(值)
返回值:返回的是添加元素后数组的长度.

pop()删除数组最后一个元素。
结构: arr.pop()
返回值:返回的是刚才删除的元素.

unshift()在数组的最前面添加一个或者是多个元素。
结构: arr.unshift(值)
返回值: 返回的是添加元素后数组的长度

shift()删除数组最前面的一个元素。
结构: arr.shift()
返回值: 返回的是刚才删除的元素.

splice()两个参数是删除/三个是替换。

结构1: arr.splice(start,deletedCount) 纯删除
从start下标开始,删除几个

结构2: arr.splice(start,deletedCount,item) 替换
从start下标开始,删除几个,并在该位置添加item

结构3: arr.splice(start,0,item) 纯添加
从start下标开始,删除0个,并在该位置添加item,start开始全部往后移动



// ### 数组的翻转和排序(改变数组)
reverse() 翻转数组
结构:arr.reserse()

sort()排序
let arr = [1,3,5,2,4,23,122,34];
//没有参数:时按照首字符的先后排序
arr.sort()//arr=[1,122,2,23,3,34,4,5];
//有参数
arr.sort(function(a,b){
return a-b;//从小到大排序
return b-a;//从大到小排序
})

filter()过滤,有返回值, 过滤出符合条件的元素。
let arr = [1, 3, 5, 2, 4, 6];
let res3 = arr.filter(function(item, index) {
return item % 2 === 0;
});
console.log(res3);


find()查找符合条件的项,并且返回第一项。
findIndex()查找符合条件的下标,并且返回第一项。

lastIndexOf()查找元素最后一次在数组中出现的位置。

indexOf()查找符合条件的元素,找到就返回该元素,找不到就返回-1.
includes()判断一个数组中是否包含某一个元素,并返回true 或者false。

some()判断数组中有没有符合条件的项,有就返回true,一个都没有惨返回false。
every()判断数组中的所有项是否的满足条件,全部满足才返回true,否则false。
reduce()
- 1.求和计算
-2.扁平化数组,拼接数组
- 计算数组中每个元素出现的次数。


* 7.js字符串的方法?
* 8.防抖和节流
* **节流:限制执行频率,有节奏的执行**
* **防抖:限制执行次数,多次密集触发只执行一次**


	+ 防抖(Debounce):指在一段时间内触发的多次事件只执行最后一次,以防止事件重复执行。
		- 例如,在输入框中连续输入时,前几次的输入并不需要实时处理,而只需要等在一定时间内不再输入时再执行一次即可。防抖的实现方式是使用  setTimeout  或者  setTimeOut  和  clearTimeout,通过一定的延迟等待实现选择最后一次执行。
	+ 节流:指在指定时间间隔内只执行一次事件,以防止高频率重复执行。
		- 例如,在用户频繁触发页面滚动事件时,需要等待一定时间后才执行一次函数,以减少执行次数。节流的实现方式有两种:时间戳和定时器方式。
* 1.深浅拷贝,理解,常用的有哪些,会有什么问题?


	+ 浅拷贝:
	+ object.assion()合并对象
	+ 扩展运算符,
	+ slice(0)截取 返回值:返回截取出来的字段,放到新的数组中,不改变原数组。
* 2.浏览器从输入url到页面显示发生了什么事情?
* 重绘回流?日常中的场景?
* webpack了解吗?怎么做优化?大概说一下
* 模块化开发和组件开发


	+ 都可以将大型复杂的系统分解成更小、更简单的可重用部件,从而提高开发效率和维护性。
	+ 个模块通常是指一组相关联的功能或资源,可以独立地进行开发和测试。模块化开发的一个典型案例是Node.js,它将应用程序拆分成多个模块,每个模块都有自己的作用域和依赖关系。这使得开发者可以更加轻松地管理代码库,减少了代码耦合度,并且可以更容易地测试和维护各个模块。
	+ 组件开发是指将页面或应用程序拆分成多个可重用的组件,每个组件都具有明确定义的接口和功能。组件化开发的一个典型案例是React.js,它可以将UI界面拆分成多个组件,并将它们组合在一起来构建复杂的应用程序。这使得开发人员可以更加轻松地管理UI界面,增强了代码的可重用性,并且可以更容易地实现前端功能和交互。
	+ + 总之,模块化和组件化开发都是现代软件开发中不可或缺的技术,它们能够帮助开发人员更高效地开发和维护软件,减少了代码的复杂性和耦合度。
* http和https的区别?常见状态码


	+ HTTP和HTTPS都是常用的协议,用于客户端(如浏览器)与服务器之间的通信。HTTP代表“超文本传输协议”,而HTTPS代表“安全的超文本传输协议”。
	+ `HTTP是一种无状态协议,使用明文传输数据。`
	+ `HTTPS通常用于传输敏感信息,加密通信。例如登录凭据、信用卡号码等.`



HTTP是一种无状态协议,它使用明文传输数据。
这意味着HTTP请求和响应中的所有内容都以纯文本形式进行传输,因此可能会被攻击者窃听和篡改。HTTP通常用于传输非敏感信息,例如公共网站上的静态页面。

HTTPS通常用于传输敏感信息,加密通信。例如登录凭据、信用卡号码等。
HTTPS则提供了更高的安全性,它通过使用SSL或TLS加密机制来保护传输的数据,从而实现加密通信。 HTTPS可以保护数据在传输过程中不被黑客窃取或篡改,并且还能验证服务器的身份。

以下是一些关于HTTP和HTTPS的常见面试问题:

  1. HTTP和HTTPS有什么区别?
    答:HTTP是一个无状态协议,数据以明文形式传输,而HTTPS使用SSL/TLS加密机制将数据加密并保护其完整性和机密性。
  2. HTTPS是如何保证数据的安全性的? 答:HTTPS使用SSL/TLS协议来加密数据,同时还使用公钥和私钥来验证服务器的身份,并确保数据在传输过程中不被篡改。
  3. HTTPS比HTTP更安全,但它是否完全无懈可击? 答:虽然HTTPS可以大大提高安全性,但攻击者仍可能通过某些方式攻击HTTPS连接。例如,攻击者可能会使用伪造的数字证书来欺骗用户,或使用中间人攻击窃听和篡改HTTPS通信。
  4. HTTP/2是什么?它如何改进HTTP协议? 答:HTTP/2是一种新的HTTP协议版本,旨在提供更快的加载速度,减少延迟和增加安全性。它引入了多路复用、头部压缩和服务器推送等新功能,并支持加密通信。

HTTP是一种用于在网络上传输超文本和其他资源的应用层协议。它基于客户端-服务端架构,通过请求-响应模式进行通信。

HTTP协议定义了以下常见的请求方法:

  1. GET:获取一份资源,不会对服务器上的资源产生任何影响。
  2. POST:向服务器提交数据,可能导致服务器上的资源状态发生变化。
  3. PUT:将数据存储到服务器上指定的位置。
  4. DELETE:删除服务器上指定的资源。

HTTP协议还定义了许多状态码,用于表示服务器处理请求时的结果。以下是常见的状态码及其含义:

  1. 200 OK:服务器成功处理了请求,并返回了所请求的数据。
  2. 201 Created:请求已经被实现,而且有一个新的资源已经依据请求的需要而建立。
  3. 204 No Content:服务器成功处理了请求,但没有返回任何内容。
  4. 400 Bad Request:服务器无法理解请求的格式,客户端应该检查请求是否正确。
  5. 401 Unauthorized:请求未授权,客户端应该提供身份验证信息。
  6. 403 Forbidden:服务器拒绝执行请求,客户端没有访问权限。
  7. 404 Not Found:服务器无法找到请求的资源,路径问题。
  8. 500 Internal Server Error:服务器遇到了意外的情况,无法完成请求


4-1.说说JS中的数据类型
4-2.JS中的 ==和===有什么区别?
4-3.JS中的深拷贝和浅拷贝**有什么区别?
4-4.如果让你实现一个深拷贝,有什么思路?
4-5.简述一下对原型,构造函数以及实例的理解
4-6.什么是闭包?闭包解决了什么问题?闭包会导致什么问题呢?
4-7.如何理解JS中的this关键词?
4-8.之前有没有解决过跨域问题?在你们项目里。当时是怎么解决的?


#### 浏览器缓存原理


![](https://img-blog.csdnimg.cn/img_convert/ec091bf7484ec31b783933427704f072.webp?x-oss-process=image/format,png)


 // 理解:  // 协商缓存 


![](https://img-blog.csdnimg.cn/img_convert/b64e79a3959e4bc817b04b7670722f24.webp?x-oss-process=image/format,png)


### 3. vue2相关


说说对vue的理解?



vue是一套用于构建用户界面的渐进式框架,与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层(viewmodel),不仅易于上手,还便于与第三方库或既有项目整合。


* 1.v2的生命周期,并且可以做什么事情?
* 2.路由 如何监听hash变化?


	+ 1.hash路由:监听 url 中 hash 的变化,然后渲染不同的内容,这种路由不向服务器发送请求,不需要服务端的支持;
	+ 2.history路由:1. 监听 url 中的路径变化,需要客户端和服务端共同的支持;
	+ 利用H5的 history中新增的两个API pushState() 和 replaceState() 和一个事件onpopstate监听URL变化history模式。
	+ hash 就是指 url 尾巴后的 # 号以及后面的字符,history没有底带#,外观上比hash 模好看些hash回车刷新会加载到地址栏对应的页面,history一般就是404掉了。hash 能兼容到IE8, history 只能兼容到 IE10;
* hash 模式的优缺点:


	+ 优点:浏览器兼容性较好,连 IE8 都支持
	+ 缺点:路径在井号 # 的后面,比较丑
* 总结一下 history 模式的优缺点:


	+ 优点:路径比较正规,没有井号 #
	+ 缺点:兼容性不如 hash,且需要服务端支持,否则一刷新页面就404了
	+ history API 是 H5 提供的新特性,**允许开发者直接更改前端路由,即更新浏览器 URL 地址而不重新发起请求**。
	
	 ![](https://img-blog.csdnimg.cn/img_convert/8201951d0b6319bd3b2fcedd9b21c072.webp?x-oss-process=image/format,png)
	+ **history 路由**
	
	
		- 在 history 路由中,我们一定会使用`window.history`中的方法,常见的操作有:
	+ back():后退到上一个路由;
	+ forward():前进到下一个路由,如果有的话;
	+ go(number):进入到任意一个路由,正数为前进,负数为后退;
	+ pushState(obj, title, url):前进到指定的 URL,不刷新页面;
	+ replaceState(obj, title, url):用 url 替换当前的路由,不刷新页面;
* 注意:调用这几种方式时,都会只是修改了当前页面的 URL,页面的内容没有任何的变化。
* 3.路由传参数


	+ query
	+ params  ![](https://img-blog.csdnimg.cn/img_convert/f701bdb5cd7e65f9b896f2c038c415fc.webp?x-oss-process=image/format,png)
* 4.# vue中route和router有什么区别?


	+ route
		- 通过 this.$route 访问的是当前路由,获取和当前路由有关的信息。只读属性。
	+ this.$ router是 router 实例
		- 通过 this.������访问路由器,相当于获取了整个路由文件,在router访问路由器,相当于获取了整个路由文件,在router.option.routes中,或查看到当前项目的整个路由结构 具有实例方法。如:this.$router.query.id
* 5.vue2组件通信:


	+ 常见可以分为三类:
		- 父子通信
			* 父传子:父组件先引用子组件,并且绑定需要传的数据(如:),子组件用 `props:{ list:{type:Array, default:null}}接收使用`,
			* 子传父:子组件自定义事件,并且调用这个事件函数,this.$emit('事件函数名称',this.要传的数据)。在父组件中(引用子组件的时候要绑定,如:<child @add=“add” />)监听这个事件函数,vlaue值就是子组件给父组件的值。



// 父组件给子组件传值用:props
·在父组件中定义要传给子组件,调用子组件并且把 要传的值绑定在子组件上

·在子组件中用props:{ list:{ type:Array,default:null }}接收,使用

// 子组件给父组件传值用:KaTeX parse error: Expected '}', got 'EOF' at end of input: … this.emit(‘方法名’,this.要传的值)
}
}
// 在父组件中监听子组件的这个方法
·<child @add=“add”/>
methods:{
add(value){
console.log(value) // 子组件给父组件的值
}
}


* 兄弟组件通信
* 跨级组件通信



3-4.vue.js中组件之间是如何通信的?

  • 父子组件 》父传子:用props接受,子传父:子组件触发事件函数this.$emit(‘key’,要传的数据)来传递。
  • 兄弟组件 》用eventbus来传,vuex
    • 1.创建一个eventbus.js文件
    • 2.传数据的组件用eventbus.$emit()
    • 3.接受数据的组件用eventbus.$on()
  • 祖孙组件(跨多极组件)vuex或者是依赖注入的方式
    • 祖先组件中使用:provide(‘唯一的key’,要传递的值)
    • 子孙组件中:inject(‘key’)接收。

#### map和foreach的区别:



foreach(){}
arr.forEach(function(item,index,arr){
//里面的function是一个回调函数,
//item: 数组中的每一项;
//index:item 对应的下标索引值
//arr: 就是调用该方法的数组本身
})

该方法等同于for循环,没有返回值.

map(){}
//里面的function是一个回调函数,
//item: 数组中的每一项;
//index:item 对应的下标索引值
//arr: 就是调用该方法的数组本身
有返回值,返回一个新数组,新数组的长度和原数组长度相等.
let arr = [1,32,54,6,543];
let res = arr.map(function(item,index,arr){
return item*2;
})



计算数组中每个元素出现的次数
var names = [‘Alice’, ‘Bob’, ‘Tiff’, ‘Bruce’, ‘Alice’];
var countedNames = names.reduce(function (allNames, name) {
// console.log(allNames, '| ’ + name);
if (name in allNames) {
allNames[name]++;
} else {
allNames[name] = 1;
}
return allNames;
}, {});
console.log(countedNames);




---


6.vue怎么检测数组变化的?说说了解



Vue  提供了一种名为“响应式”的机制,能够检测到数组中某个元素的变化,当某个数组元素发生变化时,Vue  会立即通知相关的组件进行更新.这些方法在使用的时候,会通知  Vue  数组的变化,并即时更新视图。
例如:

  • push() 尾部添加 返回新数组的长度
    -  pop() 尾部删除 返回的是被删除的元素
    -  shift() 头部删除
    -  unshift()头部添加
    -  splice() – 增加 删除 修改;本质上是删除数组(从哪里开始的下标,删除的长度,要替换的值)

-  sort() 排序,返回排序后的数组。
-  reverse() 反转数组

如果我们使用了其它不被重写的数组方法,Vue  无法自动检测到数组的变化,会导致界面不刷新。可以使用  Vue.set()  或者  this.$set()  方法手动触发更新。

// this.$forceUpdate() // 手动触发更新
// Vue.set(this.items, this.items.length, ‘qux’)

理解:vue2是可以监听数组数据的变化的,但基本都是只能监听到数组方法对于数组的变化,也就是有没有改变原数组。(简单理解为数组的长度发生了变化并修改了原数组),不可以监听到数组某一元素内容的数据变化。在这种情况下才需要使用vue提供的set方法,而如果是说v-for对数组的监听的话应该就是diff算法的对比了,我个人是这么理解的。


* 7.this.$nextTick()
	+ 在我们开发项目的时候,总会碰到一些场景:当我们使用vue操作更新dom后,需要对新的dom做一些操作时,但是这个时候,我们往往会获取不到跟新后的DOM.因为这个时候,dom还没有重新渲染,所以我们就要使用vm.$nextTick方法。



// nextTick接受一个回调函数作为参数,它的作用将回调延迟到下次DOM跟新周期之后执行。
this.$nextTick(function(){
//dom现在跟新了
//可以获取新的dom数据,执行操作
this.doSomeThing()
})


综合题


* 7.为什么要选择vue.js呢,它给你们解决了什么问题?
	+ Vue.js  是一个轻量级的  MVVM  框架,相比其它框架具有以下几个优点:
	+ 易上手:Vue.js  使用模板和组件的方式,让代码更加易懂易读。
	+ 响应式数据绑定:Vue.js  提供了依赖追踪和异步队列更新机制,能够实时追踪数据变化,并及时更新视图。这带来的好处是,数据和视图之间可以更加解耦,代码可读性更高,开发效率更高。
	+ 前端路由和动画:Vue.js  自带的  Vue  Router  和  Transition  组件,可以让前端路由和动画变得更加容易,同时也提高了代码的可维护性。
	+ 组件化开发:Vue.js  是一款面向组件的框架。通过组合不同的组件,可以构建出复杂的  UI  界面。组件可以很容易地进行组合、嵌套和复用,极大地提升了代码的重用性和可维护性。
	+ 需要大量复杂数据操作、可重用组件、动态路由或动画的应用。生态圈完善,社区活跃,能够大幅提高我们构建  Web  应用的开发效率。
* 8.数据改变,视图没有改变的情况有遇到吗?是为什么?怎么处理的?



3-1.为什么要选择vue.js呢,它给你们解决了什么问题?
3-2.谈谈对vue生命周期的理解?
-
3-3.v-if 和 v-show有什么区别?
-
3-4.vue.js中组件之间是如何通信的?
- 父子组件 》父传子:用props接受,子传父:子组件触发事件函数this. e m i t (‘ k e y ’,要传的数据)来传递。 − 兄弟组件》用 e v e n t b u s 来传, v u e x − 1. 创建一个 e v e n t b u s . j s 文件 − 2. 传数据的组件用 e v e n t b u s . emit(‘key’,要传的数据)来传递。 - 兄弟组件 》用eventbus来传,vuex - 1.创建一个eventbus.js文件 - 2.传数据的组件用eventbus. emitkey,要传的数据)来传递。兄弟组件》用eventbus来传,vuex1.创建一个eventbus.js文件2.传数据的组件用eventbus.emit()
- 3.接受数据的组件用eventbus.$on()
- 祖孙组件(跨多极组件)vuex或者是依赖注入的方式
- 祖先组件中使用:provide(‘唯一的key’,要传递的值)
- 子孙组件中:inject(‘key’)接收。

3-5.vue中数据双向绑定原理了解吗?
3-6.如果让你实现一个基本的双向数据绑定,那你是什么思路呢?
3-7.MVVM和MVC有什么区别?
3-8.有没有用过其他的JS框架?
3-9.对前端代码的自动化测试有没有了解?有没有使用过前端代码自动测试框架呢?


### 4. vue3相关



  • 在另外一个文档里面,后面整理之后补发

### 5.综合能力



1.你在项目中遇到过哪些大坑,那当时是怎么解决的?
2.在你们团队中,你有没有一些突出的亮点可以在这分享一下
3.那你提到前端工程实践,那项目中的package.json有什么作用?它里面都有哪些内容?
6.对webpack比较熟是吧,那你对webpack的使用有哪些优化建议呢?


![](https://img-blog.csdnimg.cn/img_convert/baa137ae8d11acc54f02acb40da56e6b.webp?x-oss-process=image/format,png)


#### 5.1 **常见web性能优化的方式?AAAa**\*\*



性能优化基本是我们开发都要面对的问题,但是怎么做合适?收益怎么样?都是我们要考虑的?
// 在单页面应用中,一个路由对应一个页面,如果不做处理,打包的时候会把所有的页面打包成一个文件,
// 当用户打开首页的时候就会一次性加载所有的资源,造成首页加载很慢,用户体验不好。

通用的方法:
1.路由懒加载(es中的箭头函数+import的方式),组件懒加载等(需要触发的组件,如弹窗组件)
2.引入骨架屏插件(移动端),提升用户体验
3.大数据列表:使用虚拟滚动技术,加载可视化区域的内容,或滚动加载但是要注意节流的问题(单位时间内多次点击只是触发一次)
4.无需滚动加载:要注意外层盒子加上overflow:auto,一定要限定高度。
5.更多的情况下
图片优化**会带来很大的性能提升。

图片优化如下:
  • 1.使用 SVG 格式。webp等格式的图片(之前打包的时候发现好几张gif图片基本都是1m以上,png500多k),

  • 2.配置image-webpack-loader,处理并压缩图片,基本可以压缩到1/4或者1/5左右。

  • 3.图片列表使用七牛云提供的图片动态裁剪的功能。按文档配置即可****移动端完全没必要加载原图压缩图片可以更快的显示。

  • 4.使用 Webpack 配合compression-webpack-plugin插件,在前端工程的打包阶段,对静态资源进行“预压缩”,从而移除服务器端的压缩时间。

  • 5.缓存图片,将图片缓存在浏览器中可以减少页面加载时间。

  • 6.CDN加速主要是加速静态资源,如网站上面上传的图片、媒体,以及引入的一些Js、css等文件。我们使用的是七牛云来存储讲台资源,

  • 使用cdn加速相当于你的图片资源不是放到你自己的服务器,而是放到七牛云的服务器上了,只是把你的域名解析到七牛云服务器上而已。


1.路由懒加载:把路由用import的方式引入


a) **C** **onst** ******home** **= ()=>** **import** **(** **“** **@/** **views/index** **”** **)******


2.**组件懒加载** **,** **比如弹窗组件** **,** **通过条件触发的组件** **,** **触发操作之后再加载该组件** **。**\*\*\*\*


3.**移动端可以使用骨架屏** **,** **锁定白屏时间** **,** **提升用户体验** **。** **可以引入插件** **。** **V** **ue** **-** **skeletion** **-** **webpack** **-** **plugin**\*\*\*\*


4.**长列表虚拟滚动加载** **,** **只是渲染可视区域的列表** **,** **引入插件配置** **。**\*\*\*\*


a) **计算出total数据列表总高度** **,** **并且在触发滚动事件的时候根据滚动的位置不断更新开始位置start和end的位置** **,** **然后从列表数据中截取对应的元素** **。**\*\*\*\*


5.**长列表使用触底加载** **,**\*\*\*\*


a) **第一次传** **20** **条数据** **,** **或者是其他** **,** **获取当前滚动时候位置** **,** **窗口的高度** **,** **整个网页的实际高度** **。** **设置一个加载的动画** **,** **如果当前滚动的位置** **+** **窗口的高度** **+** **距离底部的高度的时候就触发动画** **,** **增加的请求的数据量** **。**\*\*\*\*


6.**将小图转成base** **64** **格式的图片** **,** **减少http请求** **。**\*\*\*\*


7.尽可能的使用字体图标,而非图片


8.**图片懒加载** **。** **引入插件**\*\*\*\*


9.**图片优化**


* 1.技能超市列表**使用七牛云提供的图片动态裁剪的功能** **,** **按文档配置即可** **。** **移动端完全没必要加载原图** **,** **压缩图片可以更快的显示** **。**
* 2.使用 SVG 格式。webp等格式的图片(打包的时候发现好几张gif图片基本都是1m以上,png500多k),
* 3.配置image-webpack-loader,处理并压缩图片,基本可以压缩到1/4或者1/5左右。
* 4.使用 Webpack 配合`compression-webpack-plugin`插件,在前端工程的打包阶段,对静态资源进行“预压缩”,从而移除服务器端的压缩时间。
* 5.缓存图片,将图片缓存在浏览器中可以减少页面加载时间。
* 6.CDN加速主要是加速静态资源,如网站上面上传的图片、媒体,以及引入的一些Js、css等文件。我们使用的是七牛云来存储讲台资源,
	+ 相当于你的图片资源不是放到你自己的服务器,而是放到七牛云的服务器上了,只是把你的域名解析到七牛云服务器上而已。


#### 5.2 前端该如何优化网站性能?



前端该如何优化网站性能?

前端性能优化大概分为七种
1、减少请求数量
1.1 图片处理:
1-1 Base64:
将图片的内容以 Base64 格式内嵌到 HTML 中,可以减少 http 请求数量,但是编码之后的大小比图片大了

1-2 使用字体图标来代替图片
1.2 避免使用空的 src 和 href
1.3 不使用 css@import

2、减少资源大小
2.1 html 压缩
html 代码压缩就是压缩在文本文件中有意义,但是在 html 中不显示的字符,包括空格,制表符

2.2 css 压缩
css 压缩包括无效代码删除与 css 语义合并

2.3 js 压缩与混乱
js 压缩与混乱包括无效字符及注释的删除、代码语义的缩减和优化、降低代码的可读性、实现代码的保护

2.4 图片压缩
3、优化网络连接
3-1 使用 CDN

CDN 是内容分发网络,它能够实时地根据网络流量和各个节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上,其目的是使用户可以就近的取得所需内容,解决网络拥挤的状况,提高网站的响应速度

3-2 使用 DNS 预解析

4、优化资源加载
4.1 资源加载位置
通过优化资源加载位置,更改资源加载时机,使尽可能快地展示出页面内容,尽可能快地使用功能可用
1、css 文件放在 head 中,先外链,后本页
2、js 文件放在 body 底部,先外连,后本页
3、处理页面、处理页面布局的 js 文件放在 head 中,如 babel-polyfill.js 文件、flexible.js 文件
4、body 中尽量不写 style 标签和 script 标签


#### 5.3 前端seo优化


* 参考[blog.csdn.net/ww\_5211314/…](https://bbs.csdn.net/topics/618166371)



// 搜索引擎优化,也就是需要被收录的网站.meta中的,description,keywords,以及一些简单的[语义化标签].
// 总结下来大概就是首页,商品详情页,分类页面,店铺页面,搜索页面保证商品被搜索引擎收录就可以在google中搜索到自己网站的产品了。

// 第一个问题:## 如何让您的网站出现在谷歌的搜索引擎中(seo)?

// # 如何做到seo优化的?

1.网站title的描述
-1.如果是网站首页则描述该网站的内容,  
-2.如果是商品详情页面则是针对该商品的描述,  
-3.如果是分类页则是对所有分类的描述。
2.在seo中,其实meta标签是很重要的一部分。填写:content=“有关网站的关键词”。
3.代码层面需要优化的事项:
1,所有的img标签要加alt属性,产品列表要加产品列表索引.
2,所有跳转到商品详情,店铺页面,分类页面,搜索页面都要是用a标签跳转,这样爬虫才能沿着链接爬取下一个链式页面.
3,所有a标签要写完整的路径:例如: <a href="https://buydo.com/item/a18f4cf96bc041d4979ddca4c2fd1d78.html"></a>
4,当在网站中输入错误的链接以及产品id,网站必须有正确的404,500页面以用来引导爬虫走完整个流程,而不是弹出错误的选项卡来告诉用户没有该商品之类的.
第四步:Last-Modified 和 If-Modified-Since非常重要

所有页面都必须设置Last-Modified 和 If-Modified-Since标头,这个对于爬虫搜索的索引和检索索引页面的速度非常重要。




---


#### 5.4 在工作中有用到webpack吗?如何配置的?大概说一下:


1. `entry:指定入口文件,可以是单个文件或多个文件。`
2. output:指定`输出`文件的路径和文件名,可以使用占位符来生成动态文件名。
3. `module:配置模块`的加载方式,可以使用不同的loader来处理不同类型的文件,例如使用babel-loader来处理ES6代码,使用css-loader和style-loader来处理CSS文件。
4. `plugins:配置插件`,可以用于优化代码、生成HTML文件、提取公共代码等。
5. resolve:配置模块的解析方式,可以指定模块的搜索路径、别名等。
6. devServer:配置开发服务器,可以实现自动刷新、热替换等功能。


在配置webpack时需要注意以下几点:


1. 版本兼容性:不同版本的webpack可能存在差异,需要根据实际情况选择合适的版本。
2. 文件路径:需要注意文件路径的正确性,避免出现文件找不到的情况。
3. loader和plugin的顺序:需要按照正确的顺序配置loader和plugin,避免出现错误。


#### 5.5 说一下浏览器事件循环机制(一定会问,会现场给题目做),node事件循环机制(可能会问)


* 理解:
	+ 在js代码执行时,会将对象存在堆(heap)中,在栈(stack)中存放一些基础类型变量和对象的指针。在执行方法时,会根据当前方法的执行上下文,来进行一个执行。对于普通函数就是正常的入栈出栈即可,涉及到异步任务的时候,js执行会将对应的任务放到事件队列中(微任务队列、宏任务队列)。
	+


我们知道js是一门单线程非阻塞的脚本语言,在执行js代码时,只有一个主线程来处理所有任务。非阻塞是指当代码需要处理异步任务时,主线程会挂起(pending),当异步任务处理完毕,主线程根据一定的规则去执行回调。事实上,当任务执行完毕,js会将这个事件加入一个队列(事件队列)。`被放入队列中的事件不会立刻执行其回调,而是当前执行栈中所有任务执行完毕后,主线程会去查找事件队列中是否有任务。`异步任务有两种类型,微任务和宏任务。不同类型的任务会被分配到不同的任务队列中。  
 执行栈中所有任务执行完毕后,主线程会去查找事件队列中是否有任务,如果存在,依次执行所有队列中的回调,只到为空。然后再去宏任务队列中取出一个事件,把对应的回调加入当前执行栈,当前执行栈中所有任务都执行完毕,检查微任务队列是否有事件。无限循环此过程,叫做事件循环。



什么是浏览器事件循环机制?

我们知道js是一门单线程非阻塞的脚本语言,意思是执行js代码时,只有一个主线程来处理所有任务。非阻塞是指当代码需要处理异步任务时,主线程会挂起(pending),当异步任务处理完毕,主线程根据一定的规则去执行回调。事实上,当任务执行完毕,js会将这个事件加入一个队列(事件队列)。被放入队列中的事件不会立刻执行其回调,而是当前执行栈中所有任务执行完毕后,主线程会去查找事件队列中是否有任务。
异步任务有两种类型,微任务和宏任务。不同类型的任务会被分配到不同的任务队列中。
执行栈中所有任务执行完毕后,主线程会去查找事件队列中是否有任务,如果存在,依次执行所有队列中的回调,只到为空。然后再去宏任务队列中取出一个事件,把对应的回调加入当前执行栈,当前执行栈中所有任务都执行完毕,检查微任务队列是否有事件。无线循环此过程,叫做事件循环。


![](https://img-blog.csdnimg.cn/img_convert/1994f2b18a5f651b228a24020ccf98a8.webp?x-oss-process=image/format,png)


* 微任务:queueMicrotask、Promise、MutationObserve等
* 常见宏任务:ajax、setTimeout、setInterval、script(js整体代码)、IO操作、UI交互、postMessage等



故事件循环可以理解为是一个桥梁,连接着应用程序的js和系统调用之间的通道。其过程为:

  1. 执行一个宏任务(一般为一段script),若没有可选的宏任务,就直接处理微任务。
  2. 执行中遇到微任务,就将其添加到微任务的任务队列中。
  3. 执行中遇到宏任务,就将其提交到宏任务队列中。
  4. 执行完当前执行的宏任务后,去查询当前有无需要执行的微任务,有就执行
  5. 检查渲染,若需要渲染,浏览器执行渲染任务
  6. 渲染完毕后,Js线程会去执行下一个宏任务。。。(如此循环)

console.log(“script start”);

const promiseA = new Promise((resolve, reject) => {
console.log(“init promiseA”);
resolve(“promiseA”);
});

const promiseB = new Promise((resolve, reject) => {
console.log(“init promiseB”);
resolve(“promiseB”);
});

setTimeout(() => {
console.log(“setTimeout run”);
promiseB.then(res => {
console.log("promiseB res :>> ", res);
});
console.log(“setTimeout end”);
}, 500);

promiseA.then(res => {
console.log("promiseA res :>> ", res);
});

queueMicrotask(() => {
console.log(“queue Microtask run”);
});

console.log(“script end”);

// script start
// init promiseA
// init promiseB
// script end
// promiseA res :>> promiseA
// queue Microtask run
// setTimeout run
// setTimeout end
// promiseB res :>> promiseB


微任务是指由  JavaScript  引擎自身发起的任务,比如  Promise  的回调函数、MutationObserver  的回调函数。`会在当前任务完成后、下一个宏任务开始前执行。`比如,在一个宏任务中,Promise  状态从等待变为完成(fulfilled)或拒绝(rejected)时,会将对应的回调函数放入一个微任务队列中,等待当前宏任务执行完毕后立即执行。


简单来说,`当一个宏任务执行完毕后,会检查是否有微任务需要执行,如果有,就立即执行所有微任务,执行完毕后再执行下一个宏任务。`



console.log(‘start’);
setTimeout(() => {
console.log(‘timeout’);
}, 0);
Promise.resolve().then(() => {
console.log(‘promise’);
});
console.log(‘end’);
// 运行上述代码,会先输出  “start”、“end”,然后才会输出  “promise”、“timeout”,
// 因为  Promise  的回调函数是微任务,比  setTimeout  回调的执行优先级更高,
// 会在当前宏任务执行完毕后立即执行,而  setTimeout  回调则是一个新的宏任务,需要放到任务队列中等待执行。


`new Promise((resolve, reject) => {}),构造器函数中的代码是同步执行的。`



Promise运行机制
async/await 你用过吗?怎么用的,有返回对象吗?
组件传值,父子组件兄弟组件BUSvuex运行机制,如何通过 vuex 实现登录验证?
router和route区别
路由传参,获取参数
延时路由
如何提高页面的加载性能
跨域解决方式(jsonp,cros)你配置过没有
created 生命周期不可以干什么事情

作用域链
vue 实例化
computed 和 watch 的区别?什么时候使用 computed 什么时候使用 watch
vuex 怎么模块化
了解 vue3.0 吗?
数据拦截是发生在哪个生命周期的?什么情况下不会对属性数据拦截,要怎么解决?
对 Es6 掌握的怎么样,项目中用过 promise 吗?



1. 为什么选择前端?
2. 讲讲浏览器从输入网址到打开网页的整个过程,越细致越好。
3. 说一说你理解的JS 事件循环机制
4. es6都有哪些新内容?
5. 你提到了map,讲讲和object有什么区别?
6. 箭头函数和普通函数的区别?
7. 跨域,相关的几个请求头的含义。
8. 一个盒子从中间开始,碰到最左边的边界往右移动,碰到最右边的边界往左移动,如此循环,问怎么做?
9. 你提到了requestAnimationFrame,讲讲和setInterval的区别?
10. 用过canvas吗,如果要实现一个一笔一画写汉字的效果,应该怎么做?


### 5.6. 闭包三连,部分面试题


#### 闭包


![](https://img-blog.csdnimg.cn/img_convert/66539b1b00c4bcdd9825aa99630ce0ae.webp?x-oss-process=image/format,png)



5.6. 闭包三连?、为什么会出现闭包?闭包有什么作用?

- **闭包就是一个能够访问其他函数**是将函数内部和函数外部连接起来的一座桥梁**。
- **创建闭包最常见方式,就是在一个函数内部创建另一个函数**内部变量的函数。**
  • 1.为什么会出现闭包?

    • 函数的作用域及其所有变量都会在函数执行结束后被销毁。
      但是,在创建了一个闭包以后,这个函数的作用域就会一直保存到闭包不存在为止
  • 2.闭包的缺点
    闭包长期占用内存,内存消耗很大,可能导致内存泄露

  • 3.闭包的作用:****
    1.访问其他函数内部变量****
    2.保护变量不被内存回收机制回收****
    3.避免全局变量被污染 方便调用上下文的局部变量 加强封装性

-4.如何避免闭包引起内存泄漏?******
1,在退出函数之前,将不使用的局部变量全部删除。可以使变量赋值为null;****
2,避免变量的循环赋值和引用。****
利用Jquery释放自身指定的所有事件处理程序


2.说一下让一个盒子垂直水平居中都有啥方法
3.原型链是啥
4.promise 用过吧,可以说一下吗
5.Es6 有接触过吧,怎么去重呢
6.v-if 和 v-show 的区别是啥
7.数据双向绑定你是怎么理解的,
8.可以介绍一下自己的项目中参与的模块吗?

9.说一下深浅拷贝,

基本类型(保存在栈内存中)
引用类型(保存在堆内存中,引用数据类型的变量是一个指向堆内存中中实际对象的引用,存在栈中)
  • 浅拷贝:

    • 将对象p1赋值给p2,改变p2里面属性的值,p1里面对应的值也会被改变。
    • 因为赋值的时候,是直接拷贝对象栈里面的地址,p1和p2的地址相同,所以修改会将两个一起改变。
      将一个对象的所有属性拷贝到另一个对象,一个对象属性改变,另外一个也会改变。
      浅拷贝: 只能拷贝一层对象,或者一层数组。
      浅拷贝的问题: 当原始对象里面的属性值是复杂数据类型的时候,
    • 1.扩展运算符
    • 2.Object.assign()合并对象。

    //注意:slice() concat()一维数组时候深拷贝,多维数组时候浅拷贝。都会返回新的数组。

    • 3.slice截取
    • 4.concat合并数组
  • 深拷贝:

    • **深拷贝开辟一个新的栈,两个对象属性完成相同,但是对应两个不同的地址。
    • 修改一个对象的属性,不会改变另一个对象的属性**。
      • 1.用for-in对象的属性进行遍历,递归实现。
      • 2.JSON.parse(JSON.stringify())。会忽略undefined、symbol和函数。
      • 3.通过嵌套扩展运算符实现深复制

10.数组去重
- 1.利用Array.from(new Set(arr))去重Set中的元素是唯一的
- const res1 = Array.from(new Set(arr));
-2.利用includes+forEach去重用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false。
-3.利用双层for循环去重
- 4.**利用Array.filter和map对象数组去重 (性能较高)
-5.# 利用数组的[indexOf方法],思路:新建一个空数组,遍历需要去重的数组,将数组元素存入新数组中,存放前判断数组中是否已经含有当前元素,没有则存入。


### 6.无感登录


![](https://img-blog.csdnimg.cn/img_convert/acf007745e128c396fe35c152fd19acc.webp?x-oss-process=image/format,png)


#### 6.1说一下前端token的理解




**ES6**

*   列举常用的ES6特性:

*   箭头函数需要注意哪些地方?

*   let、const、var

*   拓展:var方式定义的变量有什么样的bug?

*   Set数据结构

*   拓展:数组去重的方法

*   箭头函数this的指向。

*   手写ES6 class继承。

![](https://img-blog.csdnimg.cn/img_convert/aac1740e50faadb9a6a7a5b97f9ccba8.png)

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**

**微信小程序**

*   简单描述一下微信小程序的相关文件类型?

*   你是怎么封装微信小程序的数据请求?

*   有哪些参数传值的方法?

*   你使用过哪些方法,来提高微信小程序的应用速度?

*   小程序和原生App哪个好?

*   简述微信小程序原理?

*   分析微信小程序的优劣势

*   怎么解决小程序的异步请求问题?

![](https://img-blog.csdnimg.cn/img_convert/60b1dbe5c76e264468aa993416a9a031.png)
  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值