【2023秋招面经】20220713兴业数金前端一面

前言

本系列主要整理博主2023秋招的面试情况。本节介绍20220713兴业数金前端一面。

文章目录

  • 前言
    • 1. 自我介绍
    • 2. 为什么要学习vue?
    • 3. 双向数据绑定和单向数据绑定的区别,以及双向数据绑定的优缺点?
    • 4. 双向数据绑定报错的话要怎么寻找问题?
    • 5. 解释一下防抖和节流?
    • 6. 项目用什么打包的?
    • 7. 说一下webpack里做了哪些前端优化?
    • 8. 对一个绝对定位的盒子怎么水平垂直居中?
    • 9. 隐藏元素的方法?
    • 10. Promise().then()返回的也是Promise对象,要怎么判断这个Promise对象的状态?
    • 11. import 和 export的都是什么?
    • 12. 解释一下项目中的菜单权限的实现?
    • 13. 登录中的token是怎么存储的?
  • 同学问到的一些通用问题:
    • 1. 良好的编码习惯有什么?
    • 2. Promise()中的race和all的区别?
    • 3. 解释一下组件化?
    • 4. 解释一下微任务和宏任务?
    • 5. 解释一下深浅拷贝?


1. 自我介绍

2. 为什么要学习vue?

答:首先因为vue是当前前端较为流行的框架,使用vue的公司较多,也证明了这是一个非常成功的框架;第二是因为这个框架是国人编写的,简单易学,上手较快;第三因为这个框架使用了双向数据绑定,数据和视图的交互更加方便;最后因为它含有组件化、视图数据结构分离、虚拟DOM、运行速度快等特点。

3. 双向数据绑定和单向数据绑定的区别,以及双向数据绑定的优缺点?

答:双向数据绑定就是当我们采用MV模式时,就是模型-视图模式时,通常,我们需要编写代码,将从服务器获取的数据进行“渲染”,展现到视图上。每当数据有变更时,我们会再次进行渲染,从而更新视图,使得视图与数据保持一致。而另一方面,页面也会通过用户的交互,产生状态、数据的变化,这个时候,我们则编写代码,将视图对数据的更新同步到数据,以致于同步到后台服务器。而单向数据绑定只有模型----->视图的一个方向的数据传递。

双向数据绑定的优缺点:

①优点:用户在视图上的修改会自动同步到数据模型中去,数据模型中值的变化也会立刻同步到视图中去;无需进行和单向数据绑定的那些相关操作,会简化大量业务无关的代码。

②缺点:增加了出错时的debug的难度、消耗较大,部署很大网站的时候会出现问题。

4. 双向数据绑定报错的话要怎么寻找问题?

答:可以打开开发者模式,会有相应的报错,比如props不存在、期待一个Object你传入了一个Array之类的,可以直接从报错中找到。

5. 解释一下防抖和节流?

  • 防抖:前面的所有的触发都被取消,最后一次执行在规定的时间之后才会触发,也就是说如果连续快速的触发,只会执行最后一次
  • 节流:在规定的间隔时间范围内不会重复触发回调,只有大于这个时间间隔才会触发回调,把频繁触发变为少量触发

6. 项目用什么打包的?

答:webpack。

7. 说一下webpack里做了哪些前端优化?

  • 压缩代码:删除多余的代码、注释、简化代码的写法等等⽅式。可以利⽤webpack的 UglifyJsPlugin 和 ParallelUglifyPlugin 来压缩JS⽂件, 利⽤ cssnano (css-loader?minimize)来压缩css
  • 利⽤CDN加速: 在构建过程中,将引⽤的静态资源路径修改为CDN上对应的路径。可以利⽤webpack对于 output 参数和各loader的 publicPath 参数来修改资源路径
  • Tree Shaking: 将代码中永远不会⾛到的⽚段删除掉。可以通过在启动webpack时追加参数 --optimize-minimize 来实现
  • Code Splitting: 将代码按路由维度或者组件分块(chunk),这样做到按需加载,同时可以充分利⽤浏览器缓存
  • 提取公共第三⽅库: SplitChunksPlugin插件来进⾏公共模块抽取,利⽤浏览器缓存可以⻓期缓存这些⽆需频繁变动的公共代码

8. 对一个绝对定位的盒子怎么水平垂直居中?

①绝对定位+margin:auto ②绝对定位+margin负值 ③绝对定位+translate

9. 隐藏元素的方法?

(1)dispaly:none 消失+重排+重绘+绑定事件不触发+无过渡;

(2)visibility:hidden 存在+不重排+重绘+绑定事件不触发+有过渡;

(3)opacity:0 存在+不重排+不一定重绘+触发自身绑定+有过渡;

(4)position:absolute 移除视线;

(5)z-index:负值 使用其他元素遮盖;

(6)transform:scale(0,0) 缩放元素为0 存在+绑定事件不触发。

10. Promise().then()返回的也是Promise对象,要怎么判断这个Promise对象的状态?

let p1 = new Promise(function(){})
let p2 = p1.then((resolve,reject)=>{})
  • 如果p1的状态的pending,那么p2的状态也是pending;

  • 如果p1的状态的resolved,then会执行resolve,那么p2的状态由resolve的返回值决定;

    • 如果resolve()的返回值不是一个promise对象,那么p2的状态是resolved,且p2的值就是resolve()的return值。
    • 如果resolve()的返回值是一个promise对象,那么p2的状态以及值由这个promise对象为准。
    • 如果resolve()的返回值内部出现了错误(或者是用户抛出错误),那么p2的状态是rejected,且p2的值就是错误对象。
  • 如果p1的状态是rejected,then会去执行reject(),那么p2的状态由reject()的返回值决定。

    • 如果reject()的返回值不是一个promise对象,那么p2的状态是resolved,且p2的值就是resolve()的return值。
    • 如果reject()的返回值是一个promise对象,那么p2的状态以及值由这个promise对象为准。
    • 如果resolve()的返回值内部出现了错误(或者是用户抛出错误),那么p2的状态是rejected,且p2的值就是错误对象。

11. import 和 export的都是什么?

  • export方式导出对象、方法、引用,但是导入的时候不可直接指定对象、方法,需要通过大括号"{}"来指定属性、变量名,如下:
//test1.js
import axios from 'axios'

export function get({url,params = {}}) {
    return new Promise((resolve,reject) => {
        axios.get(url,{
            params:params
        }).then( response =>{
            landing(url, params, response.data);
            resolve(response.data);
        }).catch(error =>{
             reject(error)
        })
    })

}

//test2.js
import { get } from '../utils/http';
//import { get as http } from '../utils/http';
  • export default导出可不必须指定函数名、类名等,在一个文件或模块中,export、import 可以有多个,export default 仅有一个,export default 向外暴露的成员,可以使用任意变量来接收且import时不需要用大括号嵌套,也不能用大括号嵌套,如:
//test1.js
export default function HttpData (fecth,url, parm) {
	let _data = "";
	return new Promise((resolve, reject) => {
		switch (fecth){
			case "get":
				get(url, parm).then(function (response) {
					resolve (response);
				}).catch(function (error) {
					console.log("get request failed.",error);
				});
				break;
			case "post":
				post(url, parm).then(function (response) {
					resolve (response);
				}).catch(function (error) {});
				break;
			default:
				break;
		}

	});
}

//test2.js
import http from '../utils/http';

12. 解释一下项目中的菜单权限的实现?

答:由于不同用户登录以后应该有不同的权限,可以看到不同的内容,因此需要给不同的用户在菜单上分配不同的权限。菜单权限最重要的一点就是:**当获取用户信息的时候,服务器会把响应的用户拥有菜单的权限信息返回,需要根据用户身份对比出,当前这个用户需要展示哪些菜单。**本项目中,服务器会返回给用户拥有的菜单权限信息,在vuex中可以获取到,然后通过提取路由、对比路由、重组路由就可以得到当前用户用户的异步路由+常量路由,进一步修改路由的渲染数组,就能最终展示出菜单权限。

13. 登录中的token是怎么存储的?

答:服务器下发的token,是用户唯一的标识符,token不应该存在vuex中,因为如果存在vuex中,刷新页面token就会消失,因此要把token放在本地存储中,这样在导航守卫的过程中就可以获取token,进而判断是否还能点击登录页面。


同学问到的一些通用问题:

1. 良好的编码习惯有什么?

  • 善于用语义化标签给网页布局,如header , footer , aside , content ,nav等;
  • 将HTML标签和CSS样式表分割开来;
  • 注意文件的命名规范,如global.css , layout.css 等;
  • CSS中class与id不重名,书写样式的时候遵循布局定位属性–>自身属性–>文本属性–>其他属性的顺序;
  • 为复杂的代码逻辑编写注释。

2. Promise()中的race和all的区别?

Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。Promise.race()将里面返回最快的结果返回,不管结果本身是成功状态还是失败状态。当要做一件事,超过多长时间就不做了,可以用这个方法来解决:

Promise.race([promise1,timeOutPromise(5000)]).then(res=>{})

3. 解释一下组件化?

  • 组件是独立和可复用的代码组织单元。组件系统是Vue核心特性之一,它使开发者使用小型、独立和通常可复用的组件构建大型应用;
  • 组件化开发能大幅提高应用开发效率、测试性、复用性等;
  • 组件使用按分类有:页面组件、业务组件、通用组件;
  • vue的组件是基于配置的,我们通常编写的组件是组件配置而非组件,框架后续会生成其构造函数,它们基于VueComponent,扩展于Vue;
  • vue中常见组件化技术有:属性prop,自定义事件,插槽等,它们主要用于组件通信、扩展等;
  • 合理的划分组件,有助于提升应用性能;
  • 组件应该是高内聚、低耦合的;
  • 遵循单向数据流的原则。

4. 解释一下微任务和宏任务?

答:JS是一门单线程语言,JS实现单线程非阻塞的方法就是事件循环。JS把任务分为同步任务和异步,当执行遇到同步任务时,则立即执行,如果遇到异步任务,则挂起任务,异步任务也分为宏任务和微任务,微任务比如Promise.then、nextTick、await/async、MutonObserver、Object.observe,微任务要在主函数执行结束、当前宏任务结束之前执行,而宏任务包括执行script标签内部代码、setTimeout/setInterval、ajax请求、postMessageMessageChannel、setImmediate,I/O。

5. 解释一下深浅拷贝?

答:深拷贝和浅拷贝是针对引用数据类型来说的。浅拷贝就是只拷贝一层,深层次的引用类型则共享内存地址。通过浅拷贝得到的引用数据,如果修改第一层的数据,那么新数据改变不会影响原数据;如果修改第二层的引用类型数据,则新旧数据会一起改变。存在浅拷贝现象的有:①Object.assign ;②Array.prototype.slice()、Array.prototype.concat();③使用拓展运算符实现的复制。

深拷贝开辟一个新的栈,两个对象属完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。常见的深拷贝方式有:①_.cloneDeep()、②jQuery.extend()、JSON.stringify()、手写循环递归。

你可能感兴趣的:(2023秋招面经笔经,面试,前端,javascript)