前言(人生第一次写掘金文章,望轻喷!)
虽然自己是计科院的学子,虽然接触前端已经一年半+,虽然系统复习理论知识体系已经一个月+,虽然又花了两周时间专门针对网上各种面经不难其烦的梳理,虽然有跟着大佬偷偷窃取头条面试第一手情报,奈何自己真的是太菜了还是被吊起来打!偷偷记个小本本,回顾一下面试时自己是多么愚钝,主要为了记录下自己面试时的心路历程,以及对知识点的天马行空(贬义)(┬_┬)也希望有面试头条的同志能收获一些情报
面试正文呈上(回答的仅是个人拙见,欢迎指正)
- 头条面试官真是亲和呀,一上来就跟你嘘寒问暖,瞬间让人心里放松了很多。一开始就是基本情况了解,什么时候开始接触前端的呀?大学都学过什么课程呀? 最让人诧异的,面试官居然丝毫不想问项目经历相关的问题(暗自庆幸,之前面试的大佬项目也是一带而过)!
- 谈谈JS中的类吧。 着重说了传统语言中类通过拷贝实现继承,而JS通过原型链实现继承。 那就谈谈原型吧。 说了构造函数创建的时候,会生成一个原型对象,本质上是一个对象,当在实例上找不到属性的时候会通过原型链在原型对象上查找该属性。那就谈谈对象吧。 瞬间就懵逼了,好像从来都没思考过这个问题吗,大脑瞬间过滤一下,大致说了下对象是JS中引用数据类型的一种等等不知所云。(ps: 面完之后躺在床上思绪万千,一直以来看各种原型,原型链的略高深内容本以为略有成长,还曾沾沾自喜,却不曾想面试的时候对于一些最基础的概念竟不知从何答起,无法也没想到要把回答内容引导到熟悉的知识范畴,太沉溺与知识本身,没重视知识点的基本概念与知识点间的交错关系)
- 对继承有了解吧。 说了好几种继承方法,主要强调了组合继承的优缺点,以及寄生组合继承如何解决组合继承的缺点,本来还想说一下Class继承,一想自己没深入了解过就没敢说了。那就手写个继承吧。 大致实现了个寄生组合继承。
- 谈一谈es6的新特性吧 首先说了箭头函数中this的特殊性,又说了let,const形成块作用域等等,接着结构赋值,模板字符串,函参默认值等等。 (本来看到有人的见解说,可以理解为箭头函数中没有this,因此其this是通过作用域查找的,没想到嘴贱的我居然一不小心顺嘴说出了根据闭包查找,结果面试官就反问通过闭包?我冷静一想按照这个理解,setTimeout中的箭头函数应该就是通过闭包呀,但瞬间慌了正常调用的箭头函数可不是这样,赶紧纠正)
- 能实现个三栏布局吗 首先说了下flex布局,又说了absolute+margin布局,最后又说了float+margin/BFC布局,嘴贱的我说了BFC实现自适应有一些弊端,然后又巴拉巴拉说了一大堆,还好之前有准备。
- 说一说数组的方法吧。 先想到map、filter、forEach、every、some、reduce,又说了pop、push、shift等等。那应该对map挺熟悉的吧,来用reduce实现一个map函数吧。 菜是原罪啊(┬_┬),尽管面试官提醒了一下还是没有实现,面完之后网上搜了一下,很懊悔很自责,感觉应该能做出来的呀!如果一开始想太多无处下笔的时候,能想到先不用reduce实现个map,然后再将其改成reduce的形式,感觉是能做出来的吧 (聊以自慰罢了,还是代码写少了,之前手写代码的时候大多是网上各种call、apply、bind、debounce之类,现在换了一下就不会写了,只能说明对JS这个语言没有完全深入的了解,还是浮于表面的这个怎么实现,那个怎么实现,哦,看了别人的代码后我也能自己写出来了,我会了!我真棒!一遇到新的问题就懵逼就去找答案,没有想过自己实现能做到哪里,实现了之后又与别人的实现差在哪里。归根结底开发还是要多写代码,多思考,注重理论和实践的结合啊!!!)
- 对JS事件循环有了解吧。 说了下JS是单线程执行的,用异步来实现非阻塞,而事件循环机制是协调执行栈顺序执行消息队列的一种机制。又说了脚本开始运行的时候代码从上而下执行,遇到异步事件就挂起交给对应的工作线程执行,主线程继续执行后面的任务,待异步完成后将回调放到对应消息队列里,JS同步代码执行完后会清空微任务队列,然后取一个宏任务执行,再清空微任务队列,又说了宏,微任务都有哪些。(感觉自己回答的挺好的,还沾沾自喜,却不想言多必失) 你刚刚说工作线程,但是你不是说JS是单线程执行的吗? JS是单线程执行的呀,浏览器有好多线程啊,比如渲染,定时器,网络请求线程,但这不妨碍JS是单线程执行的呀(天真傲娇脸)。我又反问面试官,那JS事件循环到底是什么样的啊?面试官说的啥我记不太清了,大致是说JS执行环境有浏览器和Node之别, 浏览器V8引擎的事件循环大致也就是你说的那样,但是node依托于libuv线程池。(本来对浏览器和node事件循环都有深入了解过,但没想到问到JS事件循环的时候本能想到的是浏览器事件循环,且忽略了node事件循环。而且自己好像也只是知道两个事件循环有不同,且学习了相关机制以备出题能写出执行顺序,但是却并没认真思考过JS及其宿主环境与事件循环的关系,真是不小心就成了洋洋得意的井底之蛙啊)
- 学过数据结构是吧,那实现个二叉树任意两节点间路径的查找吧。 (ps: 对不起我太菜了!!!)
面后总结
虽然写代码很菜,但是一直觉得自己回答的时候做的很好,但当躺在床上的时候才发觉自己回答的也很屎,心得如下:
- 头条是要招能手写简单业务逻辑,且对理论基础有一定认知的人,大概6:4开吧。而我本身代码就写的少,准备的还都是各种理论假大空,结果一动手就暴毙!
- 我对基础知识还算比较重视,经常会对一个知识点看各种文章,然后看到亮点且对自己有收获的知识点就偷走,记在小本本上。本以为是一种摸索出来的很优秀的学习方法,却不曾想这些我认为正常的"真理"往往禁受不了事实的考验,大概是太沉溺与自己满足的"真理",却并没有对其进行进一步的验证。
- 关于手写代码这一块,觉得还是平时要多写,多深挖各种实现的关联,这样对JS语言就会有更好的认识。而不是我会这个,我会那个,咦新人?我不会!
- 引导面试官,把问题引导到自己确信的,熟悉的知识,而不是自己主观臆测的地方。大忌呀,不过还是因为对知识的不熟悉的原因吧!
一些我认为很棒的知识讲解清单
- 前端缓存 看完以后收获颇多,把一直以来缓存位置的疑惑也给解决了
- Jsonp详解 终于知道Jsonp的真正运作原理了
- 跨域详解 各种跨域详解,用promise封装Jsonp实现方式,让我眼前一亮
- js常见的内存泄漏及解决方法总汇 不错的总结
- JS手写代码 其他都挺好的,感觉防抖节流还见过更好的版本
- 前端安全知识 终于对XSS,CSRF有个清晰的认识了
终于写完了,人生第一次,真好!