面试流程

1.自我介绍

上家公司情况
技术栈(主要使用什么技术)
主要项目情况
离职原因

2.基础部分

css 
	
	怎么实现多个块元素一行展示
		display: inlin-block;
		float(clear:both)
			一个块级元素如果没有设置 height,那么其高度就是由里面的子元素撑开,如果子元素使用浮动,脱离了标准的文档流,那么父元素的高度会将其忽略,如果不清除浮动,父元素会出现高度不够,那样如果设置 border 或者 background 都得不到正确的解析。
		flex
	弹性布局 flex 
		flex-direction
		flex: 0  1 auto;三个参数的含义
		flex-warp
			如何实现宽度不固定,换行左对齐
		align-content:多轴方向
	
	垂直居中实现方式
		transfrom: translate(50%,50%);

	块级格式化上下文 BFC
		内部的盒子会在垂直方向,一个个地放置; (2)盒子垂直方向的距离由margin决定,属于同一个BFC的两个相邻Box的上下margin会发生重叠; (3)每个元素的左边,与包含的盒子的左边相接触,即使存在浮动也是如此; (4)BFC的区域不会与float重叠; (5)BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也如此; (6)计算BFC的高度时,浮动元素也参与计算。
	
	margin塌陷 
		什么时候会出现这种情况
		如何解决
			(1)为父盒子设置border,为外层添加border后父子盒子就不是真正意义上的贴合  (可以设置成透明:border:1px solid transparent)。
			(2)为父盒子添加overflow:hidden;
			(3)为父盒子设定padding值;
			(4)为父盒子添加position:fixed;
			(5)为父盒子添加 display:table;
			(6)利用伪元素给子元素的前面添加一个空元素
			
	positiont属性有几个值,怎么使用
		在父元素样式中有transfrom属性,会造成什么样的效果,如何解决
		
	rgba()和opacity的透明效果有什么不同
	
	怎么实现自适应
		viewpoint,rem
	sass,less怎么使用,怎么编译成我们需要的css
	
	怎么让 Chrome 支持小于 12px 的文字 ?
		-webkit-transform: scale(0.8);
	
	如何使用css实现抽奖转动效果,转动速度如何控制
		transform: `rotate(${rotate}deg)`;
        transition: "all 5s cubic-bezier(0.24, 0.57, 0.54, 0.82)";
   
   	移动端有没有处理过兼容性的问题
   		比如底部定位,input输入框调出键盘时,会出现往上顶的现象
   		ios滚动不顺畅  -webkit-overflow-scrolling: touch;

	页面插入大量的dom,如何优化
	
		1. css 先将页面脱离文档流
		2. document.createDocumentFragment()
			 javascript提供了一个文档片段DocumentFragment的机制。如果将文档中的节点添加到文档片段中,就会从文档树中移除该节点。把所有要构造的节点都放在文档片段中执行,这样可以不影响文档树,也就不会造成页面渲染。当节点都构造完成后,再将文档片段对象添加到页面中,这时所有的节点都会一次性渲染出来,这样就能减少浏览器负担,提高页面渲染速度
   		
   	重绘和重排
   		重排: 
   			添加/删除可见的DOM元素
			改变元素位置
			改变元素尺寸,比如边距、填充、边框、宽度和高度等
			改变元素内容,比如文字数量,图片大小等
			改变元素字体大小
			改变浏览器窗口尺寸,比如resize事件发生时
			激活CSS伪类(例如::hover)
			设置 style 属性的值,因为通过设置style属性改变结点样式的话,每一次设置都会触发一次reflow
			查询某些属性或调用某些计算方法:offsetWidth、offsetHeight等,除此之外,当我们调用 getComputedStyle方法,或者IE里的 currentStyle 时,也会触发重排,原理是一样的,都为求一个“即时性”和“准确性”。
		重绘:
			当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘
		减少重排的方法
			1.样式集中改变:更改类名而不是修改样式
			2.分离读写操作
			3.将 DOM 离线:display:none
			4.使用 absolute 或 fixed 脱离文档流
			

js
	数据类型
		原始类型-- String、Number、 Boolean、 Undefined、Null、Symbol
		种引用类型-- Object
		什么时候是undefined  (变量已经定义,但没有赋值)
		什么时候是Null  (空对象引入)
		
	怎么判断一个变量是一个数组
		Array.isArray()
		arr instanceof Array (判断原型链是否相等)
		arr.constructor === Array
		Object.prototype.toString.call() (返回一个对象,里面有constructName: Array);
	
	问题(引入深拷贝,浅拷贝)
		var arr1 = [1,2,3];
		var arr2 = arr1;
		arr2[1] = "4";
		console.log("数组的原始值:" + arr1 );  // [1, 4, 3]
		console.log("数组的新值:" + arr2); // [1, 4, 3]
	

	深拷贝,浅拷贝
		数组深拷贝的方法
			ES5方法 扩展运算符
			ES5方法 slice,concat
		对象深拷贝的方法
		    1. JSON.stringfy()和JSON.parse()
		    2. function deepCopy(obj) {
			      var result = Array.isArray(obj) ? [] : {};
			      for (var key in obj) {
			        if (obj.hasOwnProperty(key)) {
			          if (typeof obj[key] === 'object' && obj[key]!==null) {
			            result[key] = deepCopy(obj[key]);   //递归复制
			          } else {
			            result[key] = obj[key];
			          }
			        }
			      }
			      return result;
		    }
		    3. cloneDeep模块包

		问题(引出对象数组的深拷贝)
			var arr1 = [{
				id: 1
			}, {
				id: 2
			}]
			var arr2 = [...arr1];
			arr2[1].id = 3
			console.log(arr1);
			console.log(arr2);
			
	js一些原生的方法
		字符串截取
			slice() //方法返回一个索引和另一个索引之间的字符串
			substring()  // 返回一个索引和另一个索引之间的字符串
			substr() // 返回从指定位置开始的字符串中指定字符数的字符
		字符串以-分割
			split()
		数组
			Array.join()
			Array.splice()
		for in 和 for of 的区别
			for in 遍历数组出来的索引值, 遍历对象出来的是key值
		
	ES6使用那些新特性
		let
			let 声明的变量具有块作用域的特征。
			在同一个块级作用域,不能重复声明变量。
			let 声明的变量不存在变量提升,换一种说法,就是 let 声明存在暂时性死区(TDZ)
		const
			const 定义的变量,一旦定义后,就不能修改,即 const 声明的为常量 ( 原因 const 声明创建一个值的只读引用。但这并不意味着它所持有的值是不可变的,只是变量标识符不能重新分配)
			
			const obj = {a:1,b:2};
			console.log(obj.a); // 1
			obj.a = 3;
			console.log(obj.a); // 3
			
		问题(状态提升)
			var a = 1;
			function b () {
				console.log(a); // undefind
				a = 2;
			}
			b();
			js的var变量只有全局作用域和函数作用域两种,且申明会被提升,因此实际上a只会在最顶上开始的地方申明一次,var a=2的申明会被忽略,仅用于赋值。

	this指向问题
	https://segmentfault.com/a/1190000020013532?utm_medium=hao.caibaojian.com&utm_source=hao.caibaojian.com&share_user=1030000000178452
	箭头函数和构造函数的区别
		箭头函数的this是在定义是就确定了
		箭头函数没有prototype属性,不能new实例化

	模板运算符
		`${name}`
		
	拓展运算符
			数组合并,深拷贝
			(说到合并数组再问) 合并对象 Object.assign()
			
	解构表达式
			let {age , name} = {age:'23',name:'wind'}
			问题 a=1; b=2 俩个变量怎么不使用第三个变量使其值互换
				1
					a = a + b;
					b = a - b;
					a = a - b;
				2
					a = [a,b];
					b = a[0];
					a = a[1];
				3
					a = {a:b,b:a};
					b = a.b;
					a = a.a;
				4
					[a,b] = [b,a];
					
	rest运算符
			getRest(a, ...rest){
				console.log(a);  // 1
				console.log(rest)  // [2,3,4]
			}
			getRest(1,2,3,4);
			
	include函数和indexOf()的区别
	
	Set类型和Map类型相关的api
		Set: 
			add(), has(key), delete()
			keys(), values() // 由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值)
			entries() // 同时包括键名和键值,所以每次输出一个数组,它的两个成员完全相等。
			取值 [...set]
		Map:
			set(key, value)
			has(key)
			delete(key)
			keys():返回键名的遍历器。
   	 		values():返回键值的遍历器。
    		entries():返回所有成员的遍历器。
    		forEach():遍历 Map 的所有成员。
			

	promise 状态的状态 (pending、fulfilled、rejected)	
		promise怎么使用,何时使用
		promise.all()
		peomise.resolve()		// 将现有对象转为 Promise 对象,Promise.resolve方法就起到这个作用
		promise.allSettled()

	Array方法
		map
		filter
		some
		reduce
		every
	
	使用 sort() 对数组 [3, 15, 8, 29, 102, 22]
		let arr = [3, 15, 8, 29, 102, 22]
		arr.sort()   // [102, 15, 22, 29, 3, 8] 默认的排序方法会将数组元素转换为字符串,然后比较字符串中字符的UTF-16编码顺序来进行排序
		arr.sort((a, b) => b - a)  // [102, 29, 22, 15, 8, 3]
		arr.sort((a, b) => a - b) // [3, 8, 15, 22, 29, 102]

	数组扁平化方法
	
		https://juejin.cn/post/6844903597000359944
		1. reduce
		2. toString & split
		3. join & split
		4. 递归
		5. 扩展运算符
	
	async、await ?
		实现原理 generation yield()
		https://mp.weixin.qq.com/s/-Jf48IVOoOSLgOV60rm0Wg
	
	事件循环机制
		eventloop 
		    调用栈Stack
		    宏任务(事件)队列 microtask或者task
		        setTimeout
		        setInterval
		        I/O 文件读取,网络请求等
		        UI rendering 
		    微任务队列 microtask
		        Promise.then()
		        Object.observe
		        MutationObserver
		
		    1.执行全局Script同步代码,这些同步代码有一些是同步语句,有一些是异步语句(比如setTimeout等);
		    2.全局Script代码执行完毕后,调用栈Stack会清空;
		    3.从微队列microtask queue中取出位于队首的回调任务,放入调用栈Stack中执行,执行完后microtask queue长度减1;
		    4.继续取出位于队首的任务,放入调用栈Stack中执行,以此类推,直到直到把microtask queue中的所有任务都执行完毕。注意,如果在执行microtask的过程中,又产生了microtask,那么会加入到队列的末尾,也会在这个周期被调用执行;
		    5.microtask queue中的所有任务都执行完毕,此时microtask queue为空队列,调用栈Stack也为空;
		    取出宏队列macrotask queue中位于队首的任务,放入Stack中执行;
		    6.执行完毕后,调用栈Stack为空;
		    7.重复第3-7个步骤;
		    总结:
				在执行一个宏任务之前,会去微任务队列中依次取出所有的微任务将其执行完(包括执行过程中产生的微任务).

框架

	react
		react的生命周期

在这里插入图片描述
在这里插入图片描述

React16新的生命周期弃用了componentWillMount、componentWillReceivePorps,componentWillUpdate

			1. 新增了getDerivedStateFromProps、getSnapshotBeforeUpdate来代替弃用的三个钩子函数(componentWillMount、componentWillReceivePorps,componentWillUpdate)
			2. React16并没有删除这三个钩子函数,但是不能和新增的钩子函数(getDerivedStateFromProps、getSnapshotBeforeUpdate)混用,React17将会删除componentWillMount、componentWillReceivePorps,componentWillUpdate
			3. 新增了对错误的处理(componentDidCatch)

react相关问题
https://blog.csdn.net/qq_37815292/article/details/91416565

		setState批量更新机制
		
		setState同步实现方式
		
		React 中 key 的作用是什么
			在 React Diff 算法中 React 会借助元素的 Key 值来判断该元素是新近创建的还是被移动而来的元素,从而减少不必要的元素重渲染。
			为什么key推荐使用唯一性的id,使用index有什么弊端	
			fiber
			
		如何获取子组件中的State值
			refs
			React.CreateRef()
			ForwardRef的如何使用
		
		方法的绑定
			bind(this)
			apply、call、bind三者的区别?
				相同点
					a、都是用来改变函数的this对象的指向的。
					b、第一个参数都是this要指向的对象。
					c、都可以利用后续参数传参。
				不同点
					a.bind不会立即调用,其他两个会立即调用
					b.apply传参是以数组形式

		react组件间的数据传递方式
			props
			store
		react hooks
			useState
			useEffect 如何选择性执行 []
			useEffect第二个参数
		
		状态管理 redux 和 mobx
			redux 
				createAction handerAction combineReducer是否使用过
				怎么在组件中使用redux定义的store和dispatch方法
					connect(mapStateToProps, mapDispatchToProps);
				redux如何处理异步
					redux-thunk
					react-promise
					redux-promise-middleware
					react-saga
			mobx
				autoRun(), toJs()
			俩者的区别
				redux面向函数 mobx面向对象
				redux处理异步的方式比较复杂,mobx可以更好的使用es6的语法处理异步
				redux单一数据源state,mobx可以有多个state
				
		为什么Redux需要reducers是纯函数
			https://www.zcfy.cc/article/why-redux-need-reducers-to-be-pure-functions-freecodecamp-2515.html

	react-router使用方式
		v3 和 v4 的区别
		BrowserRouter和HashRouter的区别
		如何跳转(带参数跳转)

	如何实现组件异步加载
	
	使用过什么UI组件
		antd,antv,antd-mobile

vue

Vue常见指令有哪些

Vue的生命周期
	beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed

computed 和 watch 有什么区别

Vue 的响应式原理
	Vue 的响应式是通过 Object.defineProperty 对数据进行劫持,并结合观察者模式实现。
	Vue 利用 Object.defineProperty 创建一个 observe 来劫持监听所有的属性,把这些属性全部转为 getter 和 setter。Vue 中每个组件实例都会对应一个 watcher 实例,它会在组件渲染的过程中把使用过的数据属性通过 getter 收集为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。
	Object.defineProperty有哪些缺点?
		1. Object.defineProperty 只能劫持对象的属性,而 Proxy 是直接代理对象
			由于 Object.defineProperty 只能对属性进行劫持,需要遍历对象的每个属性。而 Proxy 可以直接代理对象。
			Object.defineProperty 对新增属性需要手动进行 Observe,由于 Object.defineProperty 劫持的是对象的属性,所以新增属性时,需要重新遍历对象,对其新增属性再使用 Object.defineProperty 进行劫持。也正是因为这个原因,使用 Vue 给 data 中的数组或对象新增属性时,需要使用 vm.$set 才能保证新增的属性也是响应式的。
		2. Proxy 支持13种拦截操作,这是 defineProperty 所不具有的。
		3. 新标准性能红利
		Proxy 作为新标准,长远来看,JS引擎会继续优化 Proxy ,但 getter 和 setter 基本不会再有针对性优化。
		Proxy 兼容性差
		目前并没有一个完整支持 Proxy 所有拦截方法的Polyfill方案

组件的 data 为什么要写成函数形式

Vue中如何检测数组变化?
	data: {
		arr: [1, 2]
	}
	某个方法中赋值
	this.arr[1] = 3
	页面会发生怎么样的变化? 

$nextTick是做什么用的,其原理是什么?
	在下次 DOM 更新循环结束后执行延迟回调,在修改数据之后立即使用 nextTick 来获取更新后的 DOM。
	nextTick 对于 micro task 的实现,会先检测是否支持 Promise,不支持的话,直接指向 macro task,而 macro task 的实现,优先检测是否支持 setImmediate(高版本IE和Etage支持),不支持的再去检测是否支持 MessageChannel,如果仍不支持,最终降级为 setTimeout 0;
	默认的情况,会先以 micro task 方式执行,因为 micro task 可以在一次 tick 中全部执行完毕,在一些有重绘和动画的场景有更好的性能。		
	
路由守卫
	全局前置/钩子:beforeEach、beforeResolve、afterEach
	路由独享的守卫:beforeEnter
	组件内的守卫:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
	
vue-router hash 模式和 history 模式有什么区别?
	传参的方式及区别
		query,params
	
Vuex
	mutation中为什么不建议处理异步
		Vuex中所有的状态更新的唯一途径都是mutation,异步操作通过 Action 来提交 mutation实现,这样使得我们可		以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。每个mutation执行完成后都会对应到一个新的状态变更,这样devtools就可以打个快照存下来,然后就可以实现 time-travel 了。如果mutation支持异步操作,就没有办法知道状态是何时更新的,无法很好的进行状态的追踪,给调试带来困难
	Vuex的模块化

需求处理能力
求两个日期中间的有效日期如何实现
找出字符串中出现最多的字符和个数

webpack

	webpack打包原理	
		1.识别入口文件
		2.通过逐层识别模块依赖。(Commonjs、amd或者es6的import,webpack都会对其进行分析。来获取代码的依赖)
		3.webpack做的就是分析代码。转换代码,编译代码,输出代码
		4.最终形成打包后的代码
	
	webpack怎么生成全局变量  new webpack.ProvidePlugin({})
	
	怎么实现多个入口文件
		entry以数组的方式定义入口文件
		
	loader
		执行顺序:从下往上,每次执行过后的文件传递给接下来的loader
		常见的loader
	
	balel
		实现原理
			AST
			如何将es6转化es5 babel-loader @babel/core @babel/preset-env @babel/polyfill	

后端交互

cookie,sessionStorage,localStorage的区别
	
请求头

数据类型 content-type
	application/x-www-form-urlencoded
		HTTP会将请求参数用key1=val1&key2=val2的方式进行组织,并放到请求实体里面,注意如果是中文或特殊字符如"/"、","、“:" 等会自动进行URL转码
	multipart/form-data
		与application/x-www-form-urlencoded不同,这是一个多部分多媒体类型。首先生成了一个 boundary 用于分割不同的字段,在请求实体里每个参数以------boundary开始,然后是附加信息和参数名,然后是空行,最后是参数内容。多个参数将会有多个boundary块。如果参数是文件会有特别的文件域。最后以------boundary–为结束标识。multipart/form-data支持文件上传的格式,一般需要上传文件的表单则用该类型。
	application/json
		JSON 是一种轻量级的数据格式,以“键-值”对的方式组织的数据。
		
axios拦截器
	axios.request
	axios.response
	怎么设置请求头 如token
	
跨域 
	开发中怎么去解决本地起的环境去访问接口
		ngnix
		charls
		node proxy转发
	cookie跨域
		
iframe通信
	postMessage()

怎么配置环境变量
	webpack生成全局变量
	自己写判断逻辑,生成全局变量

微信相关开发是否有过经验

微信公众号授权流程
	判断是否授权,没有授权需要跳转至授权页面,授权之后会回调我们的访问地址,会带上一个参数code,拿code去请求后端接口去换取授权token

经常处理的一些问题

是否使用typeScript,谈谈你对其理解,为什么现在都推崇使用它
	泛型指的是什么
	减少不必要的代码低级错误
	interface和type的区别



节流和防抖
	节流: 在规定的时间过后会再次执行
	防抖: 在规定的时间中如果还有操作,不会执行(无法控制触发频率)
	
location.href 和 location.replace的区别
	history中不会存入

encodeURL, encodeURIComponent的区别
	encodeURI()着眼于对整个URL进行编码,特殊含义的符号"; / ? : @ & = + $ , #“不进行编码
	encodeURIComponent()对URL的组成部分进行个别编码,所以”; / ? : @ & = + $ , #"在这里是可以进行编码

加密,埋点可用过

发布流程

性能优化

开发中越到过哪些比较印象深刻的问题,你是如何解决的

git命令

怎么回滚到指定版本
代码冲突如何解决
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值