字节跳动-教育业务 前端三轮面试总结(已拿offer)
个人背景:华中科技大学 信息管理与信息系统专业。
实习经历:2019年7月~12月在小米武汉实习,负责小米网海外站点的产品展示页开发
投递渠道:在牛客网上看到内推的帖子就试了一下。25号投简历,3月3号一面,3月4号二面,3月6号三面,3月9号收到offer,字节的效率是真的快,一周走完所有流程。
投递的时候好像没注意,投到社招方向上去了,二面面完给转到校招岗。非常的贴心,这也可能是没有等15号笔试,就直接面试的原因吧。(只是我的猜测,并不推荐大家模仿)
字节跳动(一面 1h)3.3
-
自我介绍(大一兴趣团队,大二培训营,大三小米实习,React重构,JS高程,你不知道的JavaScript)
-
介绍一下小米做的产品页的效果怎么实现的(nav吸顶效果,鼠标滚动动画,transform,clip-path)
-
国际化实现,国际化字符拼接,怎么实现的?(现有的系统,配置文件了解操作过程,拼接不是我做的)
-
BFC的作用,怎么产生BFC(块级上下文,内外布局互不影响,会影响到浮动定位、清除浮动以及外边距折叠,具体作用与产生方式推荐看MDN上的解释,传送门)
-
Rem与em的区别(转换成px时,参照的对象不一样,em根据当前节点font-size计算,rem跟根节点计算)
-
怎么更新rem的布局(更新根节点 html的font-size)
-
Vue跟React哪个更熟?后面就针对性的问了
-
Vue 数据双向绑定(数据劫持+发布订阅)(Object.defineProperty,Proxy,EventEmiter)
-
Vue的 template模板怎么渲染的?(不清楚)
-
Vue 改变数据后,视图怎么更新的(劫持数据变化,通过发布订阅通知视图更新)
-
render方法怎么展示数据(抽象语法树,好像答偏了,直接说对virtual dom里面的原理不是很懂)
-
怎么知道virtual dom更新了哪些(不了解)(这里应该想听到diff算法实现原理,我的理解是,对比新对象与原对象的属性,看子节点有没有变化,然后遍历子节点以此类推)
-
-
Vuex了解多少?讲讲(说了一下 view=>action=>mutation=>store=>view 的单向流动)
-
action与mutation的区别(action支持异步,mutation只能同步)
-
怎么触发action与mutation(dispatch,commit)
-
-
事件循环机制(宏任务与微任务、执行栈、执行一个宏任务就清空一次微任务队列,然后再执行宏任务)
-
跨域解决方案
jsonp (只支持get、利用script无同源限制,以函数参数形式获取返回值)
CORS Access-Control-Allow-Origin,Method,Header,Credentials
Nginx 反向代理(服务器无同源限制)
-
Promise、async与Generator(Promise是为了解决回调地狱,但是Promise状态不可中断,就有了Generator,async则是自执行的Generator语法糖)
-
CSS布局,上中下,上下固定,中间撑满,中间分层三块,左右固定,中间撑满(绝对定位+margin)
-
absolution计算时包括父元素margin吗?(把margin换成padding)
-
- 一个高阶函数的输出值
function fun(n,o){ console.log(o) return { fun:function(m){ return fun(m,n) } } } c = fun(0).fun(1) c.fun(2) c.fun(3) // undefined -> 0 -> 1->1
-
promise链式调用输出的结果
new Promise((resolve,reject)=>{ reject(1) }).catch(()=>{ console.log(2) }).then( ()=>console.log(3) (v)=>console.log(v) ) // 2 -> 3
-
实现函数(深度优先遍历)
const chapterTree = { name: '总章节', children: [ { name: '章节一', children: [{ name: '第一节', children: [{ name: '第一小节' }, { name: '第二小节' }] }, { name: '第二节' }] }, { name: '章节二', children: [{ name: '第三节' }, { name: '第四节' }] }] }; function serialize(tree) { // TODO } // 测试 const result = serialize(chapterTree); console.log(result); // ["总章节", "章节一", "第一节", "第一小节", "第二小节", "第二节", "章节二", "第三节", "第四节"]
function serialize(tree) { let arr = []; arr.push(tree.name); if (tree.children == null) return arr; for (let item of tree.children) { arr = arr.concat(serialize(item)); } return arr; }
- 改进上面的程序,输出章节号同时输出对应的序号
// ["总章节", "(1)章节一", "(1.1)第一节", "(1.1.1)第一小节", "(1.1.2)第二小节", "(1.2)第二节", "(2)章节二", "(2.1)第三节", "(2.2)第四节"]
- 输入当前索引的数组,然后递归前拷贝一份(或者先push后pop)
function serialize(tree, locate = []) { let arr = []; let before = locate.length ? `(${locate.join('.')})` : ""; arr.push(before+tree.name); if (tree.children == null) return arr; tree.children.forEach((item, index) => { let copyLocal = locate.slice(); copyLocal.push(index + 1); arr.push(...serialize(item, copyLocal)); }); return arr; }
字节跳动(二面 1h)3.4
-
自我介绍
-
擅长的技术,亮点(HTML+CSS布局,JS原理)
-
追问:(HTML、CSS、JS、Vue框架)最熟练的?(JS)
-
-
Html中的Doctype的作用(声明页面渲染的机制,严格模式,怪异模式,HTML5时代设为html即可)
-
小米做的额移动端还是PC端(PC、移动端都有)
-
移动端的多端适配(rem+padding,媒体查询)
-
解释rem(相对根节点计算)
-
怎么做单位换算(固定比率)
- 移动端在PC预览时会布局会随着字体放大到不合适的比例,怎么解决。(固定页面最大宽度)
- 面试官解释可以用媒体查询,把字体和盒子布局分开。布局用rem,更新字体用媒体查询
-
-
html 常用的meta标签常用的name(description,keyword,作者,版权等信息)MDN参考
-
这种信息给谁用的?(搜索引擎爬虫用来做索引)
-
如何设置网页编码?(charset)
-
viewport的作用?(设置页面视窗宽高缩放)(width、height、initial-scal之类的,)
-
-
布局问题 ,三列布局,左右固定宽度,中间自适应,有哪些方法,怎么实现(圣杯布局,双飞翼布局)
-
这两个布局有点老,用绝对定位怎么做?(position:absolute+padding)
-
flex怎么做,(父节点display:flex,左右固定宽度,中间自己会 撑开)
-
-
实现一个全屏居中的盒子布局,全屏弹窗的内容框
flex+justify-content+align-items
position+transform
position+负的margin
-
为什么要清除浮动(父元素高度塌陷)
-
清除浮动的方法(父元素生成BFC,伪元素+clear)
-
-
css选择器权重(转换成十进制数字)id 3 class 4 tag 1 =>341
-
css性能优化
CSS动画 回流和重绘 减少选择器嵌套(组合高于继承) 用 transform替换left
复杂动画设置独立图层,
-
CSS Reset与CSS Reboot
-
reset,重置所有样式()reboot没听过(其实听过normalize,是一样的效果)
-
怎么一行reset(*{margin,padding,下划线} 归零)
-
解释了一下关于reboot:reboot不是归零,按需要保留margin,padding,比如h1这种标题
-
-
JSON的操作函数(parse,stringify)
-
JS基本数据类型(Number, String, Boolean(这个忘记说了,面试官也没管),Undefined, Null,Object,Symbol,BigInt)
-
== 与=== 的区别(非严格等于与严格等于,前者会进行类型转换,后者没有)
-
检测数据类型(typeof Obejct.prototype.toString.call(),instacnceof 各自的原理与缺点)
-
addEventListener 的第三个参数(useCapture 默认false使用冒泡,true在捕获阶段触发)
-
addEventListener 与on 的区别(前者不会被替换可以设置多个,on后面监听会替换掉前面的监听)
-
-
HTTP请求有哪些方式(GET,POST,PUT,DELETE,UPDATE,OPTION)
-
什么时候会发起options请求(非简单请求,方式不是get与post或者类型为application/json,设定自定义请求头,第一次发送options,返回100继续后发送后面的请求)
-
-
HTTP的状态码(2345分别对应成功,重定向,客户端错误,服务器错误,分别解释了一下200,301,302,304,404,403,502)
-
编码题--幼儿园分饼干(先排序,贪心算法,按饼干最小满足小朋友遍历了一下饼干数组)大致思路如下
function dispatchCookies(children,cookies){ if(cookies == null||cookies.length == 0) return 0 cookies.sort((a,b)=>a-b); children..sort((a,b)=>a-b); var count = 0 for(var i = 0,j=0; i< cookies.length;i++){ if(cookies[i] >= children[j]){ count++;j++ } } return count }
-
前面提到了SEO优化,说一下吧(自己给自己挖坑,就说了一下标题标签的使用,图片加alt以及用chrome的lighthouse分析有更多的(逼逼不下去了) 面试官OS:看你还装逼不)
-
讲一下gitflow工作流(简历里面写的,Release,test,dev,本地调试,测试环境合并 ,发起MR,code review,合并到 Release)
-
设计一个即时搜索框,怎么设计,考虑哪些技术点
-
监听oninput,获取值,正则匹配,获取内容,组合字符串,添加到页面
-
技术点,
-
compositionStart,compositionEnd处理中文输入
-
debounce 回调函数防抖
-
-
-
接下来一年的学习规划(框架实战,JS机制研究,性能优化)
-
有什么想问的吗?
-
团队用到的技术栈与业务(PS+React+webpack|教育中台pc 60%+ HTML5移动端 20% + nodejs10%)(迷之数学,加起来不等于100%。哈哈)
-
面完之后对我有什么改进的方向与学习的建议(JS深入,框架学习,Ts学习,多做项目)
-
字节跳动(三面 50min)3.6
-
记不太清了,只能大概的回忆一下
-
自我介绍(大二参加培训营,大三暑假小米实习,看了YDK-JS,JS高程,ES6入门,了解性能优化、SEO优化巴拉巴拉的)
-
讲一讲小米框架重构过程中你了解到的吧(SEO优化,服务端渲染)
-
性能优化有哪些(减少http请求,非首屏资源懒加载,图片压缩,Lighthouse分析耗时的任务)
-
常见图片的格式(jpg,png,gif,webp以及各自的优势)
-
从输入Url到页面展示的过程(DNS解析=>缓存判断=>TCP握手=>解析DOM+CSSOM,解析JS=>生成渲染树=>布局=>绘制=>看到页面)
-
进程与线程的区别(进程是资源分配的基本单位,线程是执行的最小单位,同一进程不同线程可以共享进程资源。线程间切换效率更高)
-
数组,链表,堆栈的区别(顺序存储与链表存储,先进后出,hash映射表)
-
反转链表
function reverse (head){ if(head.next == null)return head let tail = reverse(head.next) head.next.next = head; head.next = null; return tail; }
-
以k个为一组进行反转链表(在面试官的提示下完成,可继续优化)
function reverse_k(head,k){ let [p,q] = [head,head] for(let i = 0;i<k;i++){ if(p == null)return head; p = p.next } q = p.next; p.next = null; head = reverse(head); p.next = reverse_k(q,k); return head; }
总体来看,字节跳动对算法考核比较多(每轮压轴来一个),然后就是对JS原理、性能优化,CSS基础的考察比较多,再就是问实习经历与具体的技术实践