最近面试一些前端的感悟
前言
之前一直想要回老家工作,但是小城市机会不多,今年11月初遇到个还不错的公司,工作内容待遇都可以接受,就准备回来了。那么肯定要招一个来接替我的前端,但是由于负责人个人原因,面试这个事情只能落到我头上,我自己是很不愿意这样的,人招进来然后我走了,有点不负责任的感觉。
但是在面试了一些前端以后,发现还是有很多相似的问题的,也引起了我的一些思考,所以准备写篇文章记录下,同时如果有相同情况的看完以后,希望能带给你一些思路。
面试前准备
主要就是筛选了一些简历后约面,大部分都是视频面试,我们这是一个小作坊,做低代码平台的,但是招人待遇其实一般,所以收到的简历基本上水平都不太行。
面试题都不是从网上找到的那种常见面试题,基本上都是我平常工作遇到的问题然后简化一下。 为什么不直接找现成的面试题,而是自己出呢?很大一部分原因是我个人的偏见,网上常见的面试题要么太浅显了,要么就是偏离前端主要知识太多,最受不了的就是天天研究js一开始的设计缺陷去提问,这些都不具备普遍性,而且知识间没有连贯,我很讨厌。
一个面试官也是要有责任的,不是只服务于公司,而是对每一个面试的人可以指出他们的问题,提出一些建议,让别人有些收获,这样的机会并不多。
过程
在面试前,我会根据简历中的项目决定问哪些问题,但是这次大部分的简历项目经历都是机械的写完成了哪些任务,或者直接写用到哪些api去实现什么功能。
这些面试官都不想看到,他想看到的一个是否和当前项目技术有交叉点,一个是你解决过什么问题。所以简历可以着重的描写一个项目,把你遇到的问题、解决的方法、优化的效果写上去。
因为没多少可以从项目中去提取信息去提问,我就按照js、vue、css的顺序去问了。我个人更看重js基础这块,框架也是js写的嘛。
面试题目
下面就简单列一些我常问的问题,这里不写出答案是什么,面试题我觉得一个很大的用处就是让人感到好奇,然后去了解这一块的内容。然后罗列一下大多数人回答的情况
第一个问题基本上就是你平常用过哪些es6+的特性,然后根据你说的特性,进行一些相关的提问。
JS
1. 如果你说了let,const,我会让你说下区别,然后会考一个输出题,在script标签里面执行以下代码,输出什么?
const a = 1
console.log(window.a)
回答情况:大多数回答是1,已经在说区别的时候提到暂时性死区了,但是执行结果还是靠蒙。
2.如果你说了解构赋值,我会问怎么在解构赋值的时候起别名还有怎么设置默认值。
回答情况:这个基本上都说没有用过,感觉在写Vue3的时候应该会很常用,尤其是一套use在移动端和PC去使用。
3.如果你说了函数参数默认值,我会出一个场景题,如果有一个函数
function add(a=1,b=1){
return a+b
}
const res = add(null,null)
console.log(res)
这个基本上都是回答2或者NaN的,回答NaN我基本上也就过了,因为null+null = 0。隐式转换我觉得可以考考,因为有些涉及计算,还是要了解的。
4.如果说了和promise、async await相关的
我首先会问它们的使用场景是什么,用promise封装一些异步操作需要注意什么?
如果你提到了宏微任务,我会问你宏微任务用途,为什么需要俩个不一样的任务?
如果你答出来了,我会问浏览器提供的api如定时器等异步api都是宏任务,而promise等js提供的异步api都是微任务,这是为什么?
这个基本上都是回答调后台接口的时候使用,宏微任务没有人提到。还要就是promise去封装一些像是confirm的操作很好用,这个也没有人去提到。
5.如果你说了箭头函数
我会让你先说和普通函数的区别,然后问你箭头函数bind硬绑定this会改变指向吗?
如果你说了箭头函数没有prototype,我会问你怎么创建一个没有prototype的对象?
如果你答出来了,我会问你Object.create和SetPrototypeOf的区别?原型链的应用场景?
这个基本上都能说出来,在硬绑定this上可能有些出入。Object.create和SetPrototypeOf基本上都没了解过,原型链的使用场景没有人答上来(这个你不能只说继承,而是具体的业务场景)。
6.如果你说了Map、Set
我会问你Map和Object的区别是什么?为什么需要Map?Map使用的场景在哪里?
至于Set,基本上都会说出去重,比如去重一些基础类型,但Set在实现发布订阅时储存函数非常好用。
然后会问下WeakMap有没有用过?用于解决什么问题?使用场景是什么?
这个提到Set好像都了解,只有一俩个人提到了Map,其余的都是说Array.map。至于和Object的区别以及WeakMap就没人知道了。
基本上就是你提了哪些就一直深入的聊下去。
我个人非常喜欢问的是下面这个题目
7.如何使一个对象的某个属性只读,其他属性不只读?
// name属性只读,其余属性不只读
const obj = {
name: 'obj',
age: 12,
a: 'a',
……
}
// 对obj做了一些操作后
obj.name = '222'
console.log(obj.name) // obj
我问这个问题会说提供思路就行了,不需要具体的实现。大多数人给到的答案是深拷贝这些,很少的人回答用Object.defineProperty,这些都是具象的,我更想听到的思路应该是:
1.我们可不可以在对name赋值的时候进行拦截?
2.我们可不可以在获取name值的时候进行拦截返回?
3.js有没有什么api可以让对象的属性只读?
4.有没有办法弄一个key,只有拿到这个key才能做修改?
思路决定了你解决问题的方式,记住某些api是没用的,和学数学一样,记住一个题目是没用的,换个方式提问你就不会了。
上述思路对应的解决方案如下:
1.Object.defineProperty、Proxy拦截set
2.Object.defineProperty、Proxy拦截get
3.Object.defineProperty writable
4.Symbol
比如大家都知道vue2和vue3用Object.defineProperty和Proxy去实现响应式,依赖收集和触发大家都懂,那我们能用他们做些什么呢?
7.聊下闭包、作用域链、this,并说下闭包的使用场景有哪些?
vue的面试题和css的面试题就不列出来了,vue的都是和对渲染的理解有关的,css就简单问了下布局。至于http网络还要其他的我就不打算问了,这些都是次要的,除非特定的岗位,没必要拿这些次要的东西去衡量一个人的水平。
我发现到的一个情况就是概念大家都懂,一问使用场景就都不知道了。这也引发了我对项目和学习的思考。
思考
从结果来看,大部分人的基础、解决问题的能力都很弱。
先从项目分析,项目太过简单,无法接触到复杂的问题,无法与学习联系起来。同时由于项目的简单,造成技术浅薄,换工作也只能找到类似的项目去做,这样一直恶性循环下去。
再从学习上面看,问了一下,所有人的学习方式都是跟着B站的视频去做项目学习,然后遇到问题了到掘金或者CSDN上面找答案。这样零散的学习方式无法将知识联系起来,也无法组织成你自己的知识网,也就是不够系统。
关于视频学习,只针对前端,我的观点就是像B站上的免费视频,作为了解非常推荐你去看,但是后续就不建议浪费时间在上面了,也就是作为了解即可;像掘金或者极客上面收费的课程,像是针对于某一块的,比如WebRTC这样资料繁杂的你可以买来看一看,至于什么JS基础、CSS、设计模式或者具体的框架不建议去买视频课程,直接买书系统的学习,花时间去啃,一些复杂的概念你肯定要来来回回的去理解。像视频这一块我还是觉得做一些简短的入门即可,太复杂的概念视频不是很好表达。
所以关于学习,我的建议是首先要打牢js的基础,买一些经典的书去学,比如红宝石、你不知道的JavaScript、JavaScript设计模式等,花时间去啃。像是Css、Html,平常开发尽可能用较新的特性,然后对照着MDN或者书去看用法,这类知识在实践当中去记忆最好,不用专门花时间去学,就算去学也一定要用起来才行,不然很快就忘记了,这类属于没有太多逻辑关联的知识。至于网络知识要有个总体的概念,不用多熟。前面的时间多花在JS上,这样即使项目经历简单,最起码还能通过基础知识获得一些机会。
再回头看问题,我觉得问题的很大比重在于项目,没有遇到复杂的项目,知识面和知识深度都没法在实践中得到扩展。即使你学习了相关技术,但是不能在实践中去反馈就不能说掌握了。至于学习,不管学习方式如何,要让自己学习的东西组成一个系统才行。还有一点就是目前自己的学习方式不论是什么样的,不管是差也好,或是高效,都不要在看到别人的技术水平高以后就厌恶摒弃自己现在的学习方式,要做一个思考,哪些适合自己、哪些不适合。也不要对别人抨击你目前的学习方式感到怀疑,做了思考再判断。
我记得之前刷掘金的时候,看到一个老哥的面经,好像是快手的哪个面试官对他说:“阿巴阿巴……整天泡在MDN能把前端学好?”,大概是这个意思,能不能学好我不知道,你要真能把MDN里面的东西都了解了,你绝对很厉害了。
对于技术比自己厉害的心生敬意很正常,不用去吹捧,自己要去努力学习;对于技术比自己差的,也不用看不起人家,觉得有什么优越感,可以对人家评头论足否定别人的一切了,像上面那种装逼的人不会到达多高的高度的,可以给对方一些建议和经验,帮助别人。
从这里延申出来的就是我对现在掘金等一些论坛的现象很不满,就是流量高的人、文章普遍没有干货。大家都在恭维吹捧,大家都喜欢被人捧在高处的感觉。
再说一些和文章主题无关的,其实从我发文章的速度来看,今年就只有这一篇,是的,这一年半我基本上没有怎么学习技术,有也只是从项目当中学到了一些。我花了大量的时间去了解近代历史,了解我们的国家还有世界,想表达的一点是首先你要构建一个正确的历史观,一个正确的历史观能帮助你搭建一整套对人的认知、对社会的认知体系,帮助你认识到什么是对的,什么是错的。否则你的技术水平再强,你就只是个工具而已,无法懂得自己的责任。