字节跳动_用户增长部门实习生_视频面试_一面

前言

上次三面结束五天之后,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 发送到攻击者的服务器,得到浏览者的个人信息。

解决措施:前端替换关键字,例如替换 < 为 &lt; > 为 &gt;  或者 后端替换

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

 

发布了51 篇原创文章 · 获赞 27 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_39446719/article/details/88555229