字节跳动前端面经(一面)
面试的抖音电商前端岗位,已拿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