我的字节跳动前端实习生面试

1,099 阅读4分钟

导言

本人目前大三,半个月之前投了字节跳动。在写这个文章的时候,刚刚面完字节跳动的第三轮面试,还不知道结果。希望能够吧。
好了,话不多说, 来点干货吧。

如果有什么地方不对,大佬们可以在评论区指出来

第一轮

  1. 自我介绍(面过那么多了,都快背下来了)
  2. 项目介绍
    问:当后端有多台服务器,其中一台获得前端数据,怎么保证其他服务器也可以有相应的数据。
    答:我有点懵,说了两种方式
  • 广播
  • 中间代理服务器
<div class="parent">
    <div class="child1">child1 content</div>
    <div class="child2">child2 content</div>
    <div class="child3">child3 content</div>
</div>
.child2{
    transform: translateY(200px)
}

问: child1 和 child2 的位置怎么变?为什么? 我说, transform 不会引发回流, 所以 child1 和 child2 的位置不会改变。

let el = document.getElementById('app');
el.style.width = (el.offsetWidth+1) + 'px';
el.style.width = 1 + 'px'

回引发几次回流?几次重绘? 我说,2次。 当获取 offsetWidth 时,会触发一次。 因为 必须保证 offsetWidth 的值是最新的所以触发一次, 当设置 width 时,又会触发一次。

function Foo() {}
let oldName = Foo.name;
Foo.name = "bar";
console.log([oldName, Foo.name]);

打印出来什么? Foo , Foo

let a = Foo.prototype;
let b = new Foo();
let c = b.prototype;
console.log(a === c) ;

打印什么? false
怎么为 true?

let name = 'global';
function getName() {
    name = 'local';
    return function() {
        return name;
    }
}
let getPrivate = getName();
console.log(name);
console.log(getPrivate());

打印什么?

事件循环 这个就说说就行

外部的css或js 等处理 应该是 <\script> 的一些属性

  • defer
  • async <\script>的位置, 阻塞加载等
  1. 写代码
let node = {
    id : '1',
    name : 1,
    children : [
        {
            id : '2',
            name : 2,
            children : []
        },
        {
            id : '3',
            name : 3,
            children : []
        }
    ]
}
写一个函数, 根据 id 查找 name 值

我一开始使用 递归

function findNameById(root,id) {
    if(root.id === id) {
        return root.name;
    }
    let child = root.children;
    for(let i = 0 ; i < child.length ; i ++) {
        let c = child[i];
        let result = findNameById(c , id);
        if(result === undefined) {
            continue;
        } else {
            return result;
        }
    }
}

后面说 , 可不可以不使用递归呢?
我便想到使用 栈

function findById(root,id) {
    if(root.id === id) {
        return root.name;
    }
    let stack = [];
    stack.push(root);
    while(stack.length) {
        let node = stack.pop();
        let child = node.children;
        for(let i = 0 ; i < child.length ; i ++) {
            let c = child[i];
            if(c.id === id) {
                return c.name;
            }
            stack.push(c);
        }
    }
}

第二轮

第一轮结束, 晚上我就收到第二轮的通知了,有点小开心
不过,不得不说, 第二面直接上升了一个档次。

  1. 算法题 海洋中的岛屿问题
问题: 给你一个二维数据, 大概是下面这个
- - - - + + - -
- - - - + + - -
+- - -  - -  - -
+- - -  - - - +

首先
 - 代表 海洋   + 代表陆地

请问海洋中有多少个岛屿呢?
比如图中 output : 3

我的天,看到这个问题,我就慌了。想了快20分钟,硬是没有憋出啥。后面,面试官看我没有思路,就做下一题

  1. 求字符串数组中的,最长公共前缀
input: ['fly', 'floor', 'flower']
output: 'fl'

这个还是比较正常的
我大概有两种思路:
第一种 : 类似于归并排序, 使用分治思想,进行数组切割,再求 公共前缀

function findTow(str1 , str2) {
    let i = 0;
    let j = 0;
    let min_len = str1.length > str2.length ? str2.length : str1.length;
    while(j  < min_len) {
        if(str1[i] === str2[j]) {
            i++;
            j++;
        } else {
            break;
        }
    }
    return str1.slice(0,i);
}

function findByStrs(strs) {
    if(strs.length === 0) {
        return '';
    } else if(strs.length === 1){
        return strs[0];
    }
    let mid = strs.length >> 1;
    let left = strs.slice(0,mid);
    let right = strs.slice(mid);
    return findTow(findByStrs(left), findByStrs(right));
}

第二种: 直接循环,不使用递归.
求出两个 公共前缀后 , 与第三个比 , 返回的结果再与第四个比。

  1. async/await
async function test() {
   return 1;
}
async function call() {
   const a = test();
   const b = await test();
  console.log(a, b)
}
call()

打印出来什么?

  1. flex 布局
flex : 0 0 auto 什么意思?
flex-grow
flex-shrink
flex-basis
  1. 实现一个自适应的正方形,宽度等于屏幕宽度的一半

相对单位

  • vw
  • vh

第三轮

第二轮除了那个 什么岛屿问题外 , 还算得上比较正常, 下面是第三轮

  1. websocket建立连接的原理

这个请自行百度

  1. http2.0 与 http1.0 的区别 , http 与 https 的区别

  2. cookie/session

  3. 小程序与 浏览器的渲染有什么不同? 为什么小程序不能操作 DOM

  4. 简单介绍一下 vuex

  5. 如果让你实现一下类似 vuex 的工具 , 你会怎么想呢? 我认为 vuex , 可以理解为一个全局对象 , 使用 OOB 思想

class Vuex {
    constructor() {
        this.state = {};
    }
    
    getter() {
        
    }
    
    mutations() {
        
    }
    
    actions () {
        
    }
}
  1. 树的路径之和
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,
这条路径上所有节点值相加等于目标和。

给定如下二叉树,以及目标和 sum = 22,
      5
     / \
    4   8
   /   / \
  11  13  4
 /  \      \
7    2      1

可以查考, leetcode 112

  1. 平时怎么学习的

  2. 反问

总结

哎,现在结果还没有出来,还是有点小担心。面一次字节真是快累死了,这都不让我过的话。
我就再面一次, 哈哈哈, 这是我最后的倔强