字节跳动前端面经(一面)
面试的抖音电商前端岗位,已拿offer。
岗位薪资还不错,福利也多,需要内推的同学可以私信我!!
1. 讲一下浏览器的盒模型,以及IE和chrome中盒模型的区别
答:
浏览器中的元素占据的空间都是一块一块的长方形,长方形从外到内是margin,border,padding和内部元素
- IE盒模型:box-sizing: border-box。元素的宽高会计算padding和border。
- Chrome盒模型:box-sizing: conent-box。元素的宽高不计算padding和border。
2. 子元素css上添加的flex有三个属性,分别代表什么意思
答: 这三个属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto,后两个属性可选。
- flex-grow 子元素放大比例。
- flex-shrink 子元素缩小比例,为0表示不缩小。如果一个子元素的flex-shrink属性为0,其他子元素都为1,则空间不足时,前者不缩小。
- flex-basis 可以设置固定px或百分比,设置占据固定的空间
3. var为什么会被let和const替换,var有什么缺陷
答:
- var的作用于是函数级的,而非块级。比如在if块中定义的var的作用于会提升到if所在的函数中。let和const声明的变量在块级作用域内。
- var声明的参数可以再次被声明。let和const不行
4. 有多个请求同时发出,要在所有请求结束时一起处理,请问有几种方案。
答:当时回答的不好,只答出了两种。面试完后专门去研究了下,写了篇博客,《JS处理并行请求的四种方式》 ,供参考。
5. co函数了解吗,co函数怎么实现异步函数并行处理的
答:这个是问题4的后续问题,当时也没答出来在。这篇文章中的方法三实现了co函数《JS处理并行请求的四种方式》
6. 手写promise
答:面试问的手写promise不会要写很难的,写一个简单的包含同步异步逻辑就行了,不需要完全实现A+规范
class MyPromise { static PENDING = 'pending' static FULFILLED = 'fulfilled' static REJECTED = 'rejected' constructor (executor) { let self = this // 初始状态为等待 self.state = MyPromise.PENDING self.value = undefined self.reason = undefined this.onResolvedCallbacks = [] this.onRejectedCallbacks = [] // 成功 let resolve = function (value) { if (self.state === MyPromise.PENDING) { self.state = MyPromise.FULFILLED self.value = value self.onResolvedCallbacks.forEach(fn => fn()) } } // 失败 let reject = function (reason) { if (self.state === MyPromise.PENDING) { self.state = MyPromise.REJECTED self.reason = reason self.onRejectedCallbacks.forEach(fn => fn()) } } // 立即执行 try { executor(resolve, reject) } catch (err) { reject(err) } } then (onFulfilled, onRejected) { // 同步直接处理 if (this.state === MyPromise.FULFILLED) { onFulfilled(this.value) } if (this.state === MyPromise.REJECTED) { onRejected(this.reason) } // 异步将函数放入数组,待resolve或reject时处理 if (this.state === MyPromise.PENDING) { this.onResolvedCallbacks.push(() => { onFulfilled(this.value) }) this.onRejectedCallbacks.push(() => { onRejected(this.reason) }) } } }
7. A网站调用B网站接口会发生什么
答:分为三种情况,非跨域请求、跨域简单请求和跨域复杂请求
非跨域请求
- 请求排队
- DNS解析URL对应的IP。
- 根据IP建立TCP连接(三次握手)。
- HTTP发起请求。
- 服务器处理请求
- 服务器返回处理结构,浏览器接收HTTP响应。
- 浏览器处理响应数据
- 如需要,渲染页面,构建DOM树。
- 关闭TCP连接(四次挥手)。
跨域简单请求
- 前6步同上,第七步浏览器拿到返回数据后,根据响应header判断是跨域请求,于是丢弃数据,不做响应
跨域复杂请求
- 会在上面的第1步前发送一个预校验的options请求,询问服务端是否可以发起跨域请求,得到肯定的回复才会发起接口调用
8. 跨域解决方案
答:
- 1 jsonp,只支持get请求
- 2 cors,需要服务端配置响应头,包括Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers等
- 3 nginx反向代理,后端发送请求没有跨域限制
- 4 如果是iframe 可以使用window.postMessage