字节国际化电商前端开发一二三面凉经
一面50min
1.自我介绍
2.怎么学习前端
3.输入url到页面渲染完成
4.TCP/IP协议分层,TCP在哪一层
5.三次握手 四次挥手,为什么挥手多一次
6.浏览器缓存,强缓存、协商缓存,为什么cache-control优先级更高
7. no-cache,no-store分别代表什么
8. html、css、js文件会放在磁盘缓存还是内存缓存
9. DOM树和css om树是互斥的还是同时的
10. JS脚本阻塞DOM构建,js脚本会不会对css om树影响
11.重绘、重排概念
12.看题说输出
var name = 'window' const obj = { name: 'obj', sayName:function() { console.log(this.name) }, } obj.sayMyName = () => { console.log(this.name) } const fn1 = obj.sayName() const fn2 = obj.sayMyName() fn1() // window obj.sayName() // obj fn2() // window obj.sayMyName() // window
13.箭头函数和普通函数的区别,箭头函数如何表示不定长的参数
14.有哪些类型的作用域
15.var let const区别
16.实现eventbus
class eventBus { constructor() { this.eventMap = {} } addEventListener(eventname, fn, isOnce) { const taskObj = {fn,isOnce} if (!this.eventMap[eventname]) { this.eventMap[eventname] = [taskObj] } else { this.eventMap[eventname].push(taskObj) } } on(eventname, fn) { this.addEventListener(eventname, fn, false) } once(eventname, fn) { this.addEventListener(eventname, fn, true) } off(eventname) { this.eventMap[eventname] = [] } trigger(eventname) { const tasks = this.eventMap[eventname] const onceTasks = [] tasks && tasks.forEach((item, index) => { const { fn,isOnce } = item fn && fn() if (isOnce) { onceTasks.push(index) } }) onceTasks.forEach((index) => { this.eventMap[eventname].splice(index, 1) }) } } const bus = new eventBus() const fn1 = () => { console.log('fn1') } const fn2 = () => { console.log('fn2') } bus.on('fn', fn1) bus.once('fn', fn2) bus.on('fn', fn1) bus.trigger('fn') // fn1 fn2 fn1 bus.trigger('fn') // fn1 fn1 bus.off('fn') bus.trigger('fn') // null
17. 岛屿数量
18. 反问:表现,业务
总结
no-cache没了解到,cssom构建和js之间的关系之前没了解过
作用域没说好,变量提升、暂时性死区也没讲到
eventbus实现比较丑陋,但是面试官很友好,给了提示
二面50min
1.自我介绍
2.http2.0和http1.0的区别
3.多路复用怎么实现的
4.https和http之间的区别,https握手过程
5.中间人攻击如何实现?怎样防范?
6.position取值,reletive相对谁
7.flex属性,flex布局
8.第二个子元素的高度是多少
<div class="container"> <div style="height: 100px"></div> <div style="min-height: 10px"></div> </div> <style> .container{ display: flex; } .container > div { width: 100px; } </style>
9.事件循环讲解
10.看代码说输出
async function async1(){ console.log('async1') await async2() console.log('async1 end') } async function async2(){ console.log('async2') } console.log('script start') setTimeout(() =>{ console.log('setTimeOut') },0) async1() new Promise((resolve) => { console.log('promise') resolve() }).then(() =>{ console.log('promise2') }) console.log('script end')
11. 继承有哪些方法
12. Vue常见的组件通信方法
13. 兄弟组件通信你会考虑用哪些方法
14. Vue MVVM实现思路
15. proxy对比defineproperty的优势
16. 实现lodash _get方法,后面给了优化思路
function _get(obj,path){ let splitedPath = path if(typeof path === 'string'){ splitedPath = path.replace(/\[(\d+)\]/g, '.$1').split('.') } const firstPath = splitedPath.shift() if(splitedPath.length === 0){ return obj[firstPath] }else{ return _get(obj[firstPath],splitedPath.join('.')) } }
17. 实习过程中遇到的困难,最有成就感的事
18. 实习的时候做的浏览器插件简单讲一下
19. 反问
总结
flex那个高度没说对,继承说的乱七八糟
get写的有点丑陋,不过算是把case都跑通了,面试官挺友好的
感觉面试官是个开源社区的贡献者,比较在意这个
三面 70min
1.自我介绍
2.介绍一下实习的项目
3.遇到的困难和问题,怎么解决
4.线上出问题是怎么排查的
5.React和Vue的区别
6.如何理解闭包
7.如何理解面向对象
8.设计模式
9.输入url到渲染的过程(对服务器如何定位到具体文件追问了)
10.keep-alive,websocket
11.最大连续子数组,输出值和索引
总结
#前端工程师##面经#几乎没问前端向的东西,几乎都答得不好
最后的算法题写出来了,但是对复杂度不满意,优化了大概得有20分钟都没优化出来