字节前端暑期实习/直播/影像一二三面+HR面(已OFFER)
学习渣渣 + 垫底211,非科班,寒假有一段小红书的实习(自认为没做什么事情)今年大三,申请的暑期实习,中午刚接到hr电话,然后10min后就收到offer,但是内心还是很慌,由于申请的是暑期实习和hr沟通后的入职时间确定在6月底,虽然是发了offer但是总觉得这么晚入职心里就是不踏实。
3.28 一面,一个多小时,在牛客网,过了之后以为自己被KPI了,面试官全程无表情而且感觉不太想我过的感觉
1. 自我介绍
2. 实习有没有遇到什么困难?怎么解决的?
我自己在小红书做的事情也不是很厉害就是对项目做一些小的交互优化,一点点的功能迭代而已,看得出面试官确实不怎么pick我的实习经历全程冷漠脸
3. 有做过各种显示的配置吗?
实习没做过,但是自己的项目做过,讲了一下自己用过rem,面试官追问了rem和em的区别,接着追问有没有做过媒体查询,讲了一下自己做过根据媒体查询实现背景图更换,以及就是常用flex做一些自适应的布局这样。
***冒泡和事件捕获了解吗?
八股文了,我是按照红宝书那样回答的,追问了什么是事件委托,然后我回答了一下顺便说了事件委托的优点,然后追问mousemove可以做事件委托吗,我说不行,面试官说了个ok就下一个问题了。所以到底可不可以...
5. 事件委托的好处你说了那缺点呢?
我说会引起混乱哈哈哈因为我自己觉得确实是会引起混乱啊,但是又觉得混论这个词不准确然后结合一些场景说了一下。
6. 原型和原型链知道吗?
就是八股文回答了,追问了object的proto属性是啥,然后function的是啥。这里我答的一点都不好,明明几天前还看了这里然后突然忘掉了,只是大概的说对象也是构造函数new出来的巴拉巴拉扯一些东西把。。。然后面试官说好吧,反正这里答得不是很好
7. 判断元素宽高,涉及box-sizing的问题
直接判断就好了,content-box和border-box的区别,回答完宽高我还讲了一下border-box和content-box的区别以及如何转换(boox-sizing)
8. 代码题:手写实现instance
function myInstanceOf(left, right) { let prototype = right.prototype; left = left.proto; while(true) { if(!left) { return false; } if(left === prototype) { return true; } left = left.proto; } }
9. 了解fetch吗?
我用过fetch但是不了解原理,就和面试官说了解和axios类似都是一个promise结果返回,然后面试官问我axios怎么实现的,我说就是返回一个promise对象哈哈哈,其实后面想一下axios的实现应该也是说基于最基本的XMLHttpRequest去实现的把,只不过把结果包装为一个promise对象?这个方面我确实不了解只会用不了解底层,还要再去了解一下。
10. ajax是啥,具体流程
这里非常尴尬,ajax是什么呢,这个定义我知道但是讲不出,然后流程不太记得所有了,就停停顿顿的,说自己主要是记得有一个状态码,有i个onready啥啥啥的监听事件去监听,然后再去调用回调函数。
11. 怎么跨域?
回答了CROS和jsonp,追问怎么带cookie,在cros中设置参数Access-Control-Allow-Credentials。
12. JSONP原理?支持get和post吗?
原理就是老八股文了,但是还是讲的比较细,争取挽回前面丢人的局面;不支持post只可以get
13. get和post的区别
幂等性问题,参数设置的问题,这里自己提了一个点就是get的参数相对于post来说是明文可见,没有post那么安全,所以登录使用post去做。
14. 幂等是啥?
这里我大概讲了一下幂等的场景作用,因为具体的定义忘了,救命,但是大概是那个意思讲出来了
15. vue和react的区别
个人觉得最大的区别是数据绑定方式,vue是双向绑定,而react是单项绑定,还一个最大区别就是vue的写法(temple)还是尽量靠近html的,包括整个组件也是,但是react是jsx,就是思想靠近函数式编程,巴拉巴拉扯了一些
16. 浏览器的渲染方式
我个人习惯分成四步:
-
解析DOM树 - 渲染引起首先解析HTML树生成DOM树
-
构建render树 - DOM树和CSS树一起生成DOM树
-
布局render树 - 对render树的每个节点进行布局处理,确定在屏幕的位置
-
绘制render树 - 最后遍历render树并用UI后端将每一个节点绘制出来
17. css树的解析,选择器是从左到右还是从右到左
不会 救命,我一开始说了一个方向但是好像不对,面试官这样不觉得效率低吗,我说那是另一个方向面试官问为啥,要死我真的不会
18. 回流重塑知道吗?
讲了一下区别以及会造成的问题(性能损耗),追问了display:none会不会回流,我说会,面试官问那不是重绘都造成回流,我说不是,然后我就蒙了,救命
19. 还有什么方式支持节点在页面上消失
opacity:0,visibility:hidden,display:none以及vue中的v-if/v-show控制,追问了opacity:0会不会继承。会,追问怎么取消,我居然脑袋一热说了子元素设置opacity:1事后才知道自己答错了不可以的,救命
20. vue的数据绑定知道吗?怎么实现
发布订阅模式+数据劫持,数据劫持是在object.defineProperty里面做的,设置get属性和set属性,没有说的很深
21. get和set是啥?通过这个做了什么?
我说做了数据劫持,然后set就是设置属性会触发,get就是取这个属性的值会触发,但是面试官表情不对,也许回答的方向错了?
22. diff了解过么?diff是怎么比对更新DOM的
说了diff就是比较更新虚拟DOM的算法,大概就是比较同一层节点,不同的话后面都不会比较直接全部替换,没有说的很深把自己也不是很懂,懂一点点皮毛
23. computed和watch有什么区别?
computed有缓存,和method做了比较,watch的话涉及一些改动操作,而computed不推荐进行改动而是说计算出一个值,类似于多对一。
24. computed的缓存时什么?
和method作比较,只有需要用到这个属性才会进行计算更新
25. 算法题:最长不重复字串
md这个题刷过但是忘了,不过还好自己写出来了,最后还要求讲了一下思路,钥匙写不出来就无了感觉
26. 平时怎么学习的前端?
class Scheduler { add(promiseCreator) { ... } // ... } const timeout = (time) => new Promise(resolve => { setTimeout(resolve, time) }) const scheduler = new Scheduler() const addTask = (time, order) => { scheduler.add(() => timeout(time)) .then(() => console.log(order)) } addTask(1000, '1') addTask(500, '2') addTask(300, '3') addTask(400, '4') // output: 2 3 1 4 // 一开始,1、2两个任务进入队列 // 500ms时,2完成,输出2,任务3进队 // 800ms时,3完成,输出3,任务4进队 // 1000ms时,1完成,输出1 // 1200ms时,4完成,输出4哭了,我写出来了但是做不到根据时间去输出,后来发现自己其实离正确答案差一点,气死了
class Scheduler { constructor() { this.queue = []; this.another = []; } // promiseCreator是一个异步函数,返回promise add(promiseCreator) { return new Promise((resolve, reject) => { promiseCreator.resolve = resolve; if(this.queue.length < 2) { this.run(promiseCreator); } else { this.another.push(promiseCreator); } }) } run(promiseCreator) { this.queue.push(promiseCreator); promiseCreator().then(() => { /** * 给promiseCreator绑定add中的resolve,就可以实现执行顺序的问题, * 首先执行promiseCreator,这个时候会根据不同的时间返回promise对象, * 然后执行then的回调,这个时候执行add中的函数,为的是返回add的promise, * 这样add返回的promise对象就可以调用then方法去做回调函数里面的事情。 * 由于run函数自身的递归保证了永远会有两个任务在并发执行, * 所以这个时候哪个promiseCreator先执行完,就会被删掉加进下一个promiseCreator */ promiseCreator.resolve(); this.remove(promiseCreator); if(this.another.length > 0) { /** * 这里实现并发执行,在执行第一个promiseCreator的时候, * 会自动执行run函数,并且后面执行的每一个promiseCreatoe都会如此, * 保证了永远是有两个任务在并发执行,每跑完一个就加一个进去直到another为空 */ this.run(this.another.shift()) } }) } remove(promiseCreator) { let index = this.queue.findIndex(promiseCreator); this.queue.splice(index, 1); } } const timeout = (time) => new Promise(resolve => { setTimeout(resolve, time) }) const scheduler = new Scheduler() const addTask = (time, order) => { scheduler.add(() => timeout(time)).then(() => console.log(order)) } addTask(1000, '1') addTask(500, '2') addTask(300, '3') addTask(400, '4') // output: 2 3 1 4 // 一开始,1、2两个任务进入队列 // 500ms时,2完成,输出2,任务3进队 // 800ms时,3完成,输出3,任务4进队 // 1000ms时,1完成,输出1 // 1200ms时,4完成,输出4里面是自己的一些理解注释,可能不正确,有错误还请多多指正!
我说这个中断也是给用户看的,用户点击继续上传其实就是重新上传。面试官不是很满意问有没有别的方法,我实在不知道咋说,这题确实不会,求教