乐趣区

CVTE2019春招前端二面凉经

前言:
3 月 5 日,从中山去往广州,一大早 7 点多就做好准备了,在高铁站了 30 分钟,转广州地铁又站了 90 分钟,去到地铁口,就有一辆 cvte 的大巴车过来接送,我选择的面试时间是 11:00-12:00,但前面的人还没面试完而且 12:00 的时候又去吃了饭,所以面试的开始时间是下午 1 点,直到下午 3 点才面完。
我面试的岗位的前端开发,一面问的挺基础的,那就过了,二面感觉大多数是业务的,由于我后台学的是 php,面试官喜欢考 node 的知识,估计这也是我凉的最大原因吧。作为一名普通二本非科班的我,能够闯进二面觉得是非常幸运的了,继续加油!
线上笔试:
线上笔试我是 2 月 21 日做的,其实做完之后自我感觉很一般,没想到能够进入面试的。题型分为选择题和两道编程题,其实那时我应该利用 python 后台截屏的,这样就能够把所有的题目截下来。选择题涉及的知识面涉及的挺广的,让我回想一下,有:
①、EventLoop 机制及微任务②、阻止相同事件的其他侦听器被调用(stopImmediatePropagation)③、css 中 margin 的 % 是父元素的宽度作为基准(这个真不知道呀)大概记得这么多。。。
编程题可以参考我这篇文章:https://segmentfault.com/a/11…
一面:
面试官人比较随和,所以我不怎么紧张,一面问的是基础,大部分我觉得都 ok,面试是一对一的,首先自我介绍,我就说我是非科班的,前端的知识都是自学的,然后就说了各种各样的自学方法。接下来看看问的都是什么知识
①、css 盒子模型:有两种,IE 怪异盒子模型(border-box) 和 W3C 标准盒子模型(content-box)
怪异:width = content + border + padding
标准:width = content
可以通过 css 的 box-sizing 属性来切换这两种盒子
box-sizing:border-box 怪异盒子模型
box-sizing:content-box 标准盒子模型

②、http 状态码:
1 开头:(被接受,需要继续处理。)
100:客户端继续请求、101:客户端切换协议
2 开头:(请求成功)
200:请求成功 202:服务器已接受请求,但尚未处理 204:服务器成功处理了请求,但未返回内容
3 开头:(请求被重定向)
301:(永久重定向)、302:(临时重定向)、303:http1.1 协议,禁止被缓存 304:(协商缓存成功(资源未修改)的返回值)
4 开头:(客户端请求错误)
400:客户端请求的语法错误,服务器无法理解 403:服务器理解请求客户端的请求,但是拒绝执行此请求 404:服务器无法根据客户端的请求找到资源(网页)
5 开头:(服务器错误)

③、强缓存和协商缓存:当说到 304 状态码的时候,面试问我控制协商缓存的字段有哪些:控制协商缓存的字段分别有:
Last-Modified / If-Modified-Since 和 Etag / If-None-Match
* 其中 Etag / If-None-Match 的优先级比 Last-Modified / If-Modified-Since 高然后又问了我知道 Etag 是通过什么生成的,这个我还真没了解,只是知道一个标识符而已,面试官就说了是通过时间值生成的
接着又问了强缓存的状态码我说强缓存成功的状态是 200,在读取缓存缓存的时候,分为两种情况,在 chrome 浏览器的 Network 下的 Size 可以看到两种字段
from memory cache 和 from disk cache

④、闭包的概念以及内存泄漏:
1、概念:有权访问另一个函数作用域和变量的函数,创建闭包最简单的方式就是在一个函数内部创建另一个函数。
2、好处:由于可以读取函数内部的变量,如果希望一个变量常驻于内存中又可全局访问,同时又想避免全局变量的污染,此时使用闭包就是一种恰当的方式
3、缺点:但正是因为函数内部变量被外部所引用,不会被垃圾回收,就会造成常驻内存,使用过多容易造成内存泄漏

有些时候真是给自己挖坑,哈哈哈,我说闭包使用过多会造成内存泄漏,紧接着他就问我怎么查看内存泄漏,我说 chrome 浏览器有个面板是专门用来查看内存泄漏的,但是平时不常用,就没怎么留意,接下来他就问我常见的内存泄漏方式
1. 意外的全局变量
a、在一个函数你忘记用变量声明符 (var 或 let) 来声明的变量,一个意外的全局变量就被创建了。
b、在函数中通过 this 赋予变量,在函数中,this 指向 window

2. 定时器 setTimeout setInterval 以及回调函数
当不需要 setInterval 或者 setTimeout 时,定时器没有被 clear,定时器的回调函数以及内部依赖的变量都不能被回收,造成内存泄漏。
比如:vue 使用了定时器,需要在 beforeDestroy 中做对应销毁处理。js 也是一样的。

3. 闭包(在全局作用域上保留着闭包局部变量的引用)
4. 循环引用的变量或者对象
⑤、防抖(debounce):手撕代码面试官把他的电脑转向我,我看到 lodash,之前我只是知道这个玩意可以用来克服 JSON 深拷贝的缺陷,他叫我实现一个 debounce 的加强版(随时点击次数增加,延迟也增加)。一开始,我没有好的思路,他就叫我先实现一个普通的 debounce,代码大致如下:
function debounce(fn, wait=1000) {
let timeout = 0;
return function(…args) {
if(timeout){
clearTimeout(timeout);
}
timeout = setTimeout(() => {
fn.apply(this, args)
}, wait);
}
}
写出来后,要求写个加强版的,可能我想太多了吧。。。当时没写出来,其实只要加一条语句即可
// 上面代码省略
timeout = setTimeout(() => {
wait = wait*1.5; // 主要增加这条语句
fn.apply(this, args)
}, wait);
⑥、css 三角形:手撕代码一开始我以为是三角箭头,挺兴奋的,觉得很简单,就说了使用两边的 border 然后在 rotate 即可,后来才发现是三角形,一时想不出来,他问我之前有没有实现过,我说没有,他就说如果之前没有实现的话,一时半会也是想不出来的
这里我百度的答案:
div{
width:0;
height:0;
border-right:40px solid transparent;
border-left: 40px solid transparent;
border-bottom:40px solid red;
}
对于 css 方面,代码的实现并不重要,面试官更注重思路
当他和我说了思路后,又叫我实现一个等边三角形 …. 这个我就说了等边三角形每个角是 60 度,哈哈,具体不知道怎么实现
⑦、原生 js 读取 cookie 一般读写 cookie 的时候我都是用 js-cookie 这个库的,所以对于原生忘得七七八八了因为原生 js 获取 cookie 只能通过
document.cookie
然后获得的是所有 cookie 集合在一起的字符串,需要使用正则什么的对此解析
二面:
从一面完到二面起码等了半个小时以上吧,面试我的又是另外一个面试官,这次面试的内容大多涉及到业务层次的,一上来就是问你使用过哪些库和框架,最后还是败在了二面
①、实现一个斐波那契数列 手撕代码斐波那契数列就是
1 1 2 3 5 8 13 21 34 55…
这里我采用的递归的思路,因为我是非科班的,数据结构和算法没怎么学,厉害点的同学这道题就会用动态规划的方案
function recurFib(num){
if(num < 3){
return 1;
}else{
return recurFib(num-1) + recurFib(num-2)
}
}
②、vue 和 react 的差异 React 和 Vue 有许多相似之处,它们都有:
使用 Virtual DOM
提供了响应式 (Reactive) 和组件化 (Composable) 的视图组件。
将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库。

然后又涉及到虚拟 dom:
Vitual DOM 是一种虚拟 dom 技术,本质上是基于 javascript 实现的,相对于 dom 对象,javascript 对象更简单,处理速度更快,dom 树的结构,属性信息都可以很容易的用 javascript 对象来表示
原生 JS 或 JQ 操作 DOM 时,浏览器会从构建 DOM 树开始从头到尾执行一遍流程。
操作 DOM 的代价仍旧是昂贵的,频繁操作还是会出现页面卡顿,影响用户体验。
创建虚拟 DOM 并将其映射成真实 DOM,这样所有的更新都可以先反应到虚拟 DOM 上,需要用到 Diff 算法。

③、上下固定,中间滚动布局这种布局一看就是移动端的,主要之前没有去了解移动端的布局,可能说的太不好,自己回来用代码实现了一下:功能:头部和底部自适应高度;中间占满剩余部分,超出自动滚动思路:让容器占满整个页面的高度,整体采用 flex 布局,中间滚动部分用 overflow: auto
<div class=”cotainer”>
<div class=”header”>
header<br/><br/><br/><br/>header
</div>
<div class=”middle”>
middle<br/><br/><br/><br/><br/><br/><br/><br/>
middle<br/><br/><br/><br/><br/><br/><br/><br/>
middle<br/><br/><br/><br/><br/><br/><br/><br/>
middle<br/><br/><br/><br/><br/><br/><br/><br/>
</div>
<div class=”footer”>
footer<br/><br/><br/><br/>footer
</div>
</div>
html, body{
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.cotainer{
display: flex;
flex-direction: column;
text-align: center;
height: 100%;
}
.middle{
background-color: aquamarine;
flex-grow: 1;
overflow: auto;
}
.header, .footer{
background-color: chartreuse;
}
/* 隐藏 PC 浏览器的滚动条,移动端无需考虑 */
.middle::-webkit-scrollbar {
display: none;
}
④、事件执行机制 javascript 是一门单线程语言 JS 在执行的过程中会产生执行环境,这些执行环境会被按照顺序的加入到执行栈中。同步和异步任务分别进入不同的执行 ” 场所 ”,同步的进入主线程,异步的代码,会被挂起并加入到 Task(有多种 task)队列中
除了广义的同步任务和异步任务,还包括有更加精确的微任务和宏任务微任务包括 process.nextTick,promise,Object.observe,MutationObserver 宏任务包括 script,setTimeout,setInterval,setImmediate,I/O,UI rendering
所以正确的一次 Event loop 顺序是这样的
1. 执行同步代码,这属于宏任务
2. 执行栈为空,查询是否有微任务需要执行
3. 执行所有微任务
4. 必要的话渲染 UI
5. 然后开始下一轮 Event loop,执行宏任务中的异步代码

⑤、node.js 的知识对 node 不太了解 … 看来要好好加油了
总结:
面试整体难度适中,其实对于这次面试我自己本身就是抱着一种尝试的心态,在面试的时候,我们应该要以一种学习者的心态,不会就去问面试官和面试官讨论,不断强化自己的实力,路还漫长,今天也要加油鸭!

退出移动版