作者:马上就有offer别急! 链接:https://www.nowcoder.com/discuss/634244?type=post&order=recall&pos=&page=1&ncTraceId=&channel=-1&source_id=search_post_nctrack&gio_id=3EB8F4DA34F6E607742764CE88DC6427-1638960250830 来源:牛客网 2021-04-08
学习渣渣 + 垫底211,非科班,寒假有一段小红书的实习(自认为没做什么事情)今年大三,申请的暑期实习,中午刚接到hr电话,然后10min后就收到offer,但是内心还是很慌,由于申请的是暑期实习和hr沟通后的入职时间确定在6月底,虽然是发了offer但是总觉得这么晚入职心里就是不踏实。
3.28 一面,一个多小时,在牛客网,过了之后以为自己被KPI了,面试官全程无表情而且感觉不太想我过的感觉
1.自我介绍
2.实习有没有遇到什么困难?怎么解决的?
我自己在小红书做的事情也不是很厉害就是对项目做一些小的交互优化,一点点的功能迭代而已,看得出面试官确实不怎么pick我的实习经历全程冷漠脸
3.有做过各种显示的配置吗?
实习没做过,但是自己的项目做过,讲了一下自己用过rem,面试官追问了rem和em的区别,接着追问有没有做过媒体查询,讲了一下自己做过根据媒体查询实现背景图更换,以及就是常用flex做一些自适应的布局这样。
4.冒泡和事件捕获了解吗?
八股文了,我是按照红宝书那样回答的,追问了什么是事件委托,然后我回答了一下顺便说了事件委托的优点,然后追问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; } }
面试官问我为什么终止条件是!left,我说原型链找到最后就是null了,这个时候说明不是right的实例,然后面试官就问那上一个问题你怎么没说最顶层是null,顿时尴尬,连忙解释自己太紧张忘了(事实是这种代码都已经背熟了)
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.平时怎么学习的前端?
我回答看书看视频,小哥哥问所以是自学的多,我说是的(不然呢哪个学校前端课程教框架...)
总结:问的都是前端的东西,没有涉及计算机基础的知识(浏览器渲染算计算机基础吗个人觉得不算)
1.小红书的实习经历
没有问技术问题,由于自己在小红书做的时生态安全的审核平台,面试官一直问这个平拍的审核机制,审核队列的建立,问我自己做的两个组件是做啥的,有什么收获(搞不懂问这些干嘛,我觉得可能是想考察是否了解部门整体业务把)
2.HTTP报文的构成
报文的请求头,请求体啊这些,说的没有很全不是很记得了,重点讲了头部,请求头,响应头实体头部和通用头部,具体的字段都说了一下
3.HTTP请求方法
巴拉巴拉
4.了解HEAD吗?
好像自己说成了了OPTION的,紧接着就问我OPTION
5.那你知道OPTION吗 巴拉巴拉八股文,这里我扯到了简单请求和复杂请求
6.说一下简单请求和复杂请求 巴拉巴拉,追问了怎么区分。简单请求就是请求方法是get,post和head,同时content-type不可以是application/json
四种请求方式的区别 这里自己准备到了,重点提到了幂等性,四种方法只有post不是幂等性,结合四种方法的常用场景做了一些解释
文件上传是什么格式? 我说是一个什么mu的东西不记得了(卑微),追问了怎么编码,我说就是content-type设置mu的那个东西,编码的话不清楚
知道cookie吗?有哪些属性 说了一些,面试官不知道httpOnly吗,我说那个算属性吗怕面试官以为自己不知道还说了一下httpOnly的作用,还给我讲了一些别的,忘了
代码题:实现一个模态框(带遮罩的弹窗),要求如下:
其他都好说,一开始使用display实现居中,后来发现这样动画不好做,于是改成transform去实现居中但是动画又不好实现,因为我自己觉得transform里面translate包括两个方向,使用transition会给两个方向添加动画,面试官说这个方案可行但是你对transform的用法还不是很熟悉。我说确实哈哈哈
代码题:JS实现一个带并发限制的异步调度器Scheduler,保证同时运行的任务最多有两个
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
里面是自己的一些理解注释,可能不正确,有错误还请多多指正!
小红书实习问一下 我也忘了问啥,但是自己答得还不错把
一个业务场景,上传文件的时候怎么去写一个原生的上传进度? 一开始有点懵,我的想法是这个进度其实是做给用户看的是假的,所以可以自己mock这个进度数据不需要真的监听文件上传速度。自己在项目里面使用的是axios里面一个方法叫做onDownloadProgress这个方法,面试官表示没听过???奇怪
那怎么让服务端判断一个文件是不是已经上传过了? 我说可以给文件一个hash值把,类似于协商缓存里面这种,面试官说了个ok就没了
如果一个文件上传了一般中断了,怎么继续上传? 我说这个中断也是给用户看的,用户点击继续上传其实就是重新上传。面试官不是很满意问有没有别的方法,我实在不知道咋说,这题确实不会,求教
怎么写一个原生的上传文件 用post请求呗,然后说了一下content-type这个首部字段的设置,和一般post没啥区别只是传的是一个文件罢了(我觉得是),面试官说了个ok就没了
业务场景,怎么实现一个函数,这个函数有两个参数,第一个是一个DOM树/节点,第二个是一个数组,里面是违禁词,函数需要返回一个新的DOM树,可以高亮那些违禁词 这道题和面试官讨论了一半的时间估计,我说进行遍历吗,我也不记得说了啥,反正说了好多还写了伪代码,面试官说这个挺负责的你多想想就结束了。有大佬知道怎么操作吗?其实我想说小红书的高亮才不会这么做是刻意折磨前端吗?(当然没敢说)
开始聊人生,从小红书学到了啥?
自己的职业规划 我的嘴巴:早日成为架构师 我的内心:谢邀 没有规划
字节的价值观你知道吗?认同吗?
觉得自己和字节的企业文化匹配度怎么样?
最近在看什么书?学些啥?
其实自己啥都没学在刷面经哈哈哈,我说自己在学习小程序
所以只有我把这个真的当作暑期实习6月底入职吗...我是真的想早点去但是学校不让啊,哭了。总的来说没想过自己可以拿到字节的offer,感觉运气成分很大,面试的话感觉也就只能说中规中矩把,最后offer写的部门仍然是直播,反正我也不懂这种东西管他呢哈哈哈。 文中有什么不对的地方欢迎大家指出来一起交流啊~也希望大家都可以拿到自己想要的offer,也要感谢牛客网嘿嘿~