前言
上次三面结束五天之后,hr打来电话,说我的简历已经通过,很激动。约好了面试时间,怎料到是另一个部门的一面。在询问了面试官为什么这么做之后,面试官给我的回答是,在上次三轮面试过后发现我更适合用户增长这个部门,于是让这个部门再来面我。
真的,我直接和面试官说:“我心累了。”,面试官说别太在意,就当交流学习。累了,offer爱给不给吧。第一次面试就要面两个部门,double 的面试量,我上网看那么多其他面经都没遇到过这种情况。
面试时长:40 分钟
题目
1.给一段代码,说出输出结果(this 的指向)
let obj = {
name: 'bytedance',
getName() {
return this.name;
}
};
let fb = obj.getName;
fb();
结果是 undefined 。面试官问我为什么,fb 在调用的时候 this 指向的是 window ,是顶层对象。
面试官追问:那么如果让上面这段代码正常运行,有没有什么操作
我回答:bind call apply 都行
2.call apply bind 的区别
bind 是定义函数的时候使用的,改变函数的默认this 指向。
而 call 和 apply 是在函数调用的时候使用的,同样也可以改变 this 的指向
call 和 apply 的区别在于 传参 的形式不同
3.知道常见的网络安全吗?
这个还好之前了解过,看面试官 噢 的神情应该是给了他惊喜。
XSS跨站请求攻击:
举例:在新浪博客写一篇文章,同时插入一段<script>;一旦有人来看文章,脚本就执行。在攻击代码中,获取他人的cookie,发送到自己的服务器。这么做会把查看者的cookie 发送到攻击者的服务器,得到浏览者的个人信息。
解决措施:前端替换关键字,例如替换 < 为 < > 为 > 或者 后端替换
XSRF跨站请求伪造:
举例:登录一个购物网站,正在浏览商品。该网站付费接口是 xxx.com/pay?id=100 但是没有任何验证;然后你收到一封邮件,隐藏着 <img src='xxx.com./pay?id=100'>。你查看邮件的时候,就已经悄悄地付费购买了。
解决措施:增加验证流程,如输入指纹,密码,短信验证码
4.知道闭包吗,写一下,每隔一秒输出数组的元素
function outputArr(arr) {
const len = arr.length;
for (var i = 0; i < len; i++) {
(function (index) {
setTimeout(() => {
console.log(arr[index]);
}, index * 1000);
})(i);
}
}
// let 版本
function outputArr(arr) {
const len = arr.length;
for (let i = 0; i < len; i++) {
setTimeout(() => {
console.log(arr[i]);
}, i * 1000);
}
}
我先写了一个 var 版本的,因为 var 版本才能体现出使用了闭包;然后面试官追问有没有更简单的办法,我写了一个let版本;面试官继续追问,为什么这么写可以。
for循环的括号里面是一个父级作用域,每一次的for循环都是一个子级作用域,let 有块级作用域的概念,所以每一次for循环的子级作用域里面的 i 有自己的值。
5.盒子模型
一面已经问过了,margin border padding 文本内容或者嵌套盒子
*6.了解过BFC吗
我说不太了解,面试官没有追问了。
FC(Formatting Context):指页面中的一个渲染区域,并且拥有一套渲染规则,他决定了其子元素如何定位,以及与其他元素的相互关系和作用。
BFC:块级格式化上下文,它是指一个独立的块级渲染区域,只有Block-level BOX参与,该区域拥有一套渲染规则来约束块级盒子的布局,且与区域外部无关。
参考博客:https://www.cnblogs.com/dojo-lzz/p/3999013.html
https://www.cnblogs.com/heimanba/p/3774086.html
面试官看我不了解BFC,抛出下一问
7.你写一个田字布局吧
<div class="up">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="down">
<div class="left"></div>
<div class="right"></div>
</div>
<!---css--->
.up,.down {
width: 100%;
height: 50%;
overflow: hidden;
}
.left,.right {
width: 50%;
height: 100%;
}
.left {
float: left;
}
.right {
float: right;
}
刚写完的时候我是忘了写 overflow: hidden; 消除浮动的,面试官提醒我是不是忘了清除浮动,然后补充上了。
于是面试官继续追问
8.*为什么这么写就能清楚浮动呢?
我说不了解,博客上就是这么说的,这样能清除浮动。
其实这个考点还是 BFC 的考点。
设置了 overflow: hidden 之后,其实给父元素设置了一个 BFC 区域,内部浮动元素也会被计算在内。
参考博客:https://www.jianshu.com/p/7e04ed3f4bea
9.了解http请求吗?说一下http的方法
get post put delete head 等
10.get 和 post 的区别
之前的一面问过了,这次我补充了 安全性 和 幂等性
get 安全且幂等
post 不安全且不幂等
11.你有了解过UA吗?或者其他的一些东西
我一开始没懂 UA 是什么,后来面试官解释是 userAgent。
面试官问http请求头里面还有什么,我说除了这个还了解一些缓存啊状态码
12.*你说到了状态码,说下304
又考3开头的状态码。
304:客户端发送了一个带条件的GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个304状态码。简单来说就是,客户端已经执行了GET,但文件未变化。
13.你说到了缓存,说下浏览器有什么缓存机制
cookie、localStorage和 sessionStorage 可以缓存数据
http请求头里面设置 cache-control 之类的可以缓存静态文件
14.说下cookie、localStorage、sessionStorage
cookie 用于存储的缺点:
1.存储量太小,只有4 kb
2.所有http请求都带着,会影响获取资源的效率
3.API简单,需要封装才能用 document.cookie = ...
sessionStorage:
1.浏览器关闭,回话结束,就会被清理
2.最大容量 5M
localStorage:
1.存储在本地,不会随着浏览器关闭被清理
2.最大容量 5M
3.API简单易用
15.*模拟 vuex 写一个 事件类
class Event {
constructor() {
this.queue = [];
}
// 绑定
on(name,callback) {
this.queue.push({
name,
callback,
isOnce: false
});
}
// 绑定一次,即执行完之后移除
once(name,callback) {
this.queue.push({
name,
callback,
isOnce: true
});
}
// 移除
remove(name) {
const len = this.queue.length;
for(let i = 0;i < len;i++) {
if(name === this.queue[i].name) {
this.queue.splice(i,1);
}
}
}
// 执行
run(name,params) {
const len = this.queue.length;
for(let i = 0;i < len;i++) {
if(name === this.queue[i].name) {
const result = this.queue[i].callback(params);
if(this.queue[i].isOnce) {
this.remove(name);
}
return result;
}
}
}
}
一开始不理解考查什么,后面在面试官的引导下了解到,这是要我实现一个简陋的 vuex 的事件监听-发布模式。最后也是在面试官的引导下一步一步写出来了。
16.*现假如数组没有map方法,请使用reduce 实现map
Array.prototype.map = function (fn, thisArg) {
if (typeof fn !== 'function') {
throw new TypeError(fn + 'is not a function');
}
if (!Array.isArray(this)) {
throw new TypeError('list must be a Array');
}
if (this.length === 0) {
return [];
}
return this.reduce((acc, value, index) => {
acc.push(fn.call(thisArg, value, index, this));
return acc;
}, []);
}
参考博客:https://www.codercto.com/a/44456.html
https://www.cnblogs.com/shuiyi/p/5058524.html