the first 论被离职的无奈
跟往常一样乐乐呵呵的上班,突然间被通知办公地点要搬到几十公里外的新办公区(仅仅是外包同学),听到这个不幸的消息心里哇凉哇凉的。这可咋办呢?前一个月闲的无聊投过一些简历,结果面试反馈是基础不行。害
离搬地方还有半个月时间,真的是时间紧任务重呀。顿时觉得压力山大,本身工作乐乐呵呵该上班上班该下班下班,leader都明确表示让我再找工作机会了,没办法上号吧!
上号(BOSS直聘)
对于没有学历的我,流下了没学历的泪水。对于投简历的策略我采取的是广撒网政策哈哈哈,无论是外包还是正式,大公司or小企业,约了面试就行
这个结果就是一天可能会排四五个面试,对此,还在上班的我只能偷摸搬着电脑到楼下视频面~~~
前期准备
因为上次找工作还是一年多之前,所以前端面试题也都忘的差不多了。并且这次面试时间也比较紧张只能边面试边记录面试题了,很仓促的感觉呀
面试ing
大大小小面了几十个,总结了一下的几个面试题:
1.js数据类型
值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symboly
引用数据类型:对象(Object)、数组(Array)、函数(Function)
2.宏任务和微任务
宏任务:(macro)task,可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)。
w微任务:microtask,可以理解是在当前 task 执行结束后立即执行的任务。也就是说,在当前task任务后,下一个task之前,在渲染之前。
具体见:https://zhuanlan.zhihu.com/p/78113300
3.继承的几种方式及优缺点
1. 原型链继承
实现方式:将子类的原型链指向父类的对象实例
优点:可继承构造函数的属性,父类构造函数的属性,父类原型的属性
缺点:无法向父类构造函数传参;且所有实例共享父类实例的属性,若父类共有属性为引用类型,一个子类实例更改父类构造函数共有属性时会导致继承的共有属性发生变化
2. 构造函数继承
实现方式:使用call或者apply更改子类函数的作用域,使this执行父类构造函数,子类因此可以继承父类共有属性
优点:可解决原型链继承的缺点
缺点:不可继承父类的原型链方法,构造函数不可复用
3. 组合继承
实现方式:综合使用构造函数继承和原型链继承
优点:可继承父类原型上的属性,且可传参;每个新实例引入的构造函数是私有的
缺点:会执行两次父类的构造函数,消耗较大内存,子类的构造函数会代替原型上的那个父类构造函数
4.什么是闭包
“闭包就是能够读取其他函数内部变量的函数。
例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。
在本质上,闭包是将函数内部和函数外部连接起来的桥梁。”
5.数组去重
1. 利用ES6 Set去重
2. 利用for嵌套for然后splice去重
3. 新建一个空数组,循环遍历旧数组判断如果新数组中没有就放进去
4. 利用sort排序,然后在对比相邻的两个数
5. hasOwnProperty判断是否存在
6. 使用递归去重
...
6.get和post的区别
1. 传送方式:get通过地址栏传输,post通过报文传输
2. 传输长度:get有长度限制,post无限制
3. 缓存:get请求可以被缓存,post不可以被缓存
4. 编码:get请求只URL编码,post支持多种编码方式
5. 历史记录:get请求的记录会留在历史记录中,post请求不会留在历史记录
6. 字符限制:get只支持ASCII字符,post没有字符类型限制
7.vue生命周期
beforeCreate:在实例初始化之后、进行数据侦听和事件/侦听器的配置之前同步调用。
created:在实例创建完成后被立即同步调用。
beforeMount->onBeforeMount:在挂载开始之前被调用。
mounted->onMounted:在实例挂载完成后被调用。
beforeUpdate->onBeforeUpdate:在数据发生改变后。
updated->onUpdated:在数据更改导致的虚拟 DOM 重新渲染和更新完毕之后被调用。
beforeDestroy->onBeforeUnmount:在卸载组件实例之前调用。在这个阶段,实例仍然是完全正常的。
destroyed->onUnmounted:卸载组件实例后调用。调用此钩子时,组件实例的所有指令都被解除绑定,所有事件侦听器都被移除,所有子组件实例被卸载。
8.localStorage和sessionStorage和cookie
共同点:
都是保存在浏览器端、且同源的
不同点:
cookie 数据始终在同源的 http 请求中携带(即使不需要)sessionStorage 和 localStorage 不会自动把数据发送给服务器,仅在本地保存
存储大小限制也不同,cookie 数据不能超过 4K,同时因为每次 http 请求都会携带 cookie、所以 cookie 只适合保存很小的数据,如会话标识。sessionStorage 和 localStorage虽然也有存储大小的限制,但比 cookie 大得多,可以达到 5M 或更大
数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭之前有效;localStorage: 始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的 cookie 过期时间之前有效,即使窗口关闭或浏览器关闭
作用域不同,sessionStorage 不在不同的浏览器窗口中共享,即使是同一个页面; localstorage 在所有同源窗口中都是共享的;cookie 也是在所有同源窗口中都是共享的
9.vue2和vue3区别
1. vue2和vue3双向数据绑定原理发生了改变。vue2 的双向数据绑定是利用ES5 的一个 API Object.definePropert()对数据进行劫持 结合 发布订阅模式的方式来实现的。
2. 生命周期钩子使用不同。具体见第七条
3. vue3的template支持多个根标签,vue2不支持
4. vue3引入了tree-shaking功能,按需打包体积更小
10.call apply bind的区别
相同点:
三个函数都会改变this的指向(调用这三个函数的函数内部的this)
不同点:
bind会产生新的函数,(把对象和函数绑定死后,产生新的函数)
call和apply不会产生新的函数,只是在调用时,绑定一下而已。
call和apply的区别,第一个参数都是要绑定的this,apply第二个参数是数组(是函数的所有参数),call把apply的第二个参数单列出来。
11.单页面性能优化
1. 减少http请求
2. 非核心代码异步请求
3. 优化图片,压缩图片
4. 将脚本置底
12. vue2中data为什么不是个函数?
重点解释:各个组件中的数据不受影响
vue组件是可复用的vue实例,一个组件被创建好之后,就可能被用在各个地方,而组件不管被复用了多少次,组件中的data数据都应该是相互隔离,互不影响的.基于这一理念,组件每复用一次,data数据就会被复制一次,之后,当某一处复用的地方组件内data数据被改变时,其他复用地方组件的data数据不受影响。
13. 解释promise原理
为了解决回调地域的问题,说到底,Promise 也还是使用回调函数,只不过是把回调封装在了内部,使用上一直通过 then 方法的链式调用,使得多层的回调嵌套看起来变成了同一层的,书写上以及理解上会更直观和简洁一些。Promse.all在处理多个异步处理时,只有全部返回才执行thenPromse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态Promise.any() 接收一个Promise可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise
14. webpack打包
用的不太多,暂时没有总结汗
15.防抖和节流
函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数 才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时节流:
函数节流(throttle):当持续触发事件时,保证一定时间段内只调用一次事件处理函数 节流通俗解释就比如我们水龙头放水
16.eval作用
把字符串参数解析成 JS 代码并运行,并返回执行的结果
17.判断是否是数组
1.Array.isArray(arr)
2.arr instnceof Array
3.arr.constructor === Array
4.Object.prototype.toString.call(arr) === ‘[object Array]’
18.左侧固定右边自适应
1.css实现左侧固定,右侧自适应布局
2.左侧float定位,右侧margin-left:左侧的宽度
3.左侧absolute,右侧margin-left:左侧宽度
4.flex布局
5.table-cell表格布局
19.Json.stringfy缺点(问了好几遍)
1.如果包含function,undefined,Symbol这几种类型,不可枚举属性,键值会消失。
2.转换的数据中包含Date对象,JSON.Stringify序列化之后,会变成字符串。
20.js中let和var的区别
1.作用域不同:var是函数作用域,let是块作用域。在函数中声明了var,整个函数内都是有效的,而let由于是块作用域,所以如果在块作用域内定义的变量,在其外面是不可被访问的
2.let不能在定义之前访问该变量,但是var可以
3.let不能被重新定义,但是var是可以的
4.let是ES6新增的命令,之前是没有的
21.什么是跨域以及产生原因
跨域是指a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,或是a页面为ip地址,b页面为域名地址
所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源
22.回流跟重绘
回流:当 render tree 的一部分或全部的元素因改变了自身的宽高,布局,显示或隐藏,或者元素内部的文字结构发生变化 导致需要重新构建页面的时候,回流就产生了重绘:当一个元素自身的宽高,布局,及显示或隐藏没有改变,而只是改变了元素的外观风格的时候,就会产生重绘。例如你改变了元素的
background-color....因此得出了一个结论:回流必定触发重绘,而重绘不一定触发回流
23.解释下http和https
https协议需要到CA申请证书,一般免费证书较少,因而需要一定费用。
http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl/tls加密传输协议。
http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。http的连接很简单,是无状态的;
HTTPS协议是由SSL/TLS+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
24.keep-alive
keep-alive是什么?keep-alive是一个抽象组件:它自身不会渲染一个DOM元素,也不会出现在父组件链中;使用keep-alive包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。什么地方用?有时候我们不希望组件被重新渲染影响使用体验;或者处于性能考虑,避免多次重复渲染降低性能。而是希望组件可以缓存下来,维持当前的状态。这时候就可以用到keep-alive组件。keep-alive的生命周期初次进入时:created > mounted > activated;退出后触发 deactivated再次进入:会触发 activated;事件挂载的方法等,只执行一次的放在 mounted 中;组件每次进去执行的方法放在 activated 中
25.异步和同步
同步异步 , 举个例子来说,一家餐厅吧来了5个客人,同步的意思就是说,来第一个点菜,点了个鱼,好, 厨师去捉鱼杀鱼,过了半小时鱼好了给第一位客人,开始下位一位客人,就这样一个一个来,按顺序来相同,
异步呢,异步的意思就是来第一位客人,点什么,点鱼,给它一个牌子,让他去一边等吧,下一位客人接着点菜,点完接着点让厨师做去吧,哪个的菜先好就先端出来
同步的优点是:同步是按照顺序一个一个来,不会乱掉,更不会出现上面代码没有执行完就执行下面的代码,缺点:是解析的速度没有异步的快;
异步的优点是:异步是接取一个任务,直接给后台,在接下一个任务,一直一直这样,谁的先读取完先执行谁的, 缺点:没有顺序 ,谁先读取完先执行谁的 ,会出现上面的代码还没出来下面的就已经出来了,会报错;
26.css权重
第一优先级:无条件有限的属性只需要在属性后面使用! important。它会覆盖页面内任何位置定义的元素样式。IE6不支持该属性。
第二优先级:在HTML中给元素标签加style,即内联样式。该方法会造成CSS难以管理,所以不推荐使用。
第三优先级:有一个或多个id选择器来定义。例如,#id{margin: 0}会覆盖.classname{margin: 3px}
第四优先级:有一个或多个类选择器、属性选择器、伪类选择器定义。如.classname{margin:
3px}会覆盖div{margin: 6px}
第五优先级:有一个或多个类型选择器定义。如div{margin: 6px}覆盖*{margin: 10px;}
第六优先级:通配选择器,如*{margin: 6px;}
27.this指向
1.普通函数->window
2.对象函数调用->调用的这个对象
3.构造函数->新创建的这个对象
4.箭头函数->函数外面的环境
28.route router区别
route对象表示当前的路由信息,包含了当前 URL 解析得到的信息。包含当前的路径,参数,query对象等
router对象是全局路由的实例,用来更改路由
29.New操作符具体干了什么?
1.创建了一个空对象:并且this变量引入该对象,同时还继承了函数的原型
2.设置原型链:空对象指向构造函数的原型对象
3.执行函数体:修改构造函数this指针指向空对象,并执行函数体
4.判断返回值:返回对象就用该对象,没有的话就创建一个对象
复制代码
总结
这次仓促的找工作历时两周,最终兜兜转转也拿到的了满意的薪资。不过如果条件允许的话,还是应该多面几家并且做好充足的准备,我这次就没背面试题啥的,全靠临场发挥,在面试中积累经验。
记录这次面试,我们明年再战哈哈