两个部门,六轮面试,终与字节无缘

前端UpUp

共 22776字,需浏览 46分钟

 ·

2021-07-07 10:41

家好,我是TianTian

今天想分享的是一位来自读者投稿字节的面试记录

首发内容来自掘金,读者小K,和他接触后才发现,他是大专,学历跟我差不多, 本科学历,求职的艰辛我都明白。

好在他十分努力,最后拿下滴滴offer,真的挺不容易的。

替他高兴,终于卷进大厂啦,希望我的读者早日进入心仪的公司。

我们聊的还不错,在某些方面上,我们达成了共识。

他说过:

虽然这一路挺艰辛,也不知道自己下一步是迈向哪里,但是在心态和技术上让我成长了很多,回头看来我还算是挺幸运的吧。

共勉!!!

点赞超过50的话,后续更新他的求职经历!!!

两个部门,六轮面试


两个部门,六轮面试,终与字节无缘。

这个面试机会来的挺意外的,先在 Boss 投递的简历,后再牛客网看到了内推人的微信,加了微信问了下进度,挂了。

内推人给我打电话根据简历简单询问了一下情况(内推人很谦逊,毕业于一所 211 大学,和我说他的学历也很一般),然后和 hr 沟通捞了我一下,才有的这个面试机会,太感谢了。

一面

6 月 9 日 16:00

  • 自我介绍

  • 怪异盒模型和标准盒模型的区别

    • 给了一段代码说两个盒子背景为蓝色的区域

    • 两个盒子分别设置了 box-sizing: border-box, box-sizing: content-box

  • 如何触发 BFC

    • 给一段代码问效果是什么样的

    • 会有一个外边距合并的问题,怎么解决这个问题

  • 垂直水平居中

  • 你了解得数组遍历方式有哪些,你觉得那个性能最优那

  • this 指向谁,如何更改 this 的指向

    • // 非原题 非原题 非原题
      const o1 = {
          text'o1',
          fnfunction({
              return this.text;
          }
      }
      const o2 = {
          text'o2',
          fn: o1.fn
      }
      console.log(o2.fn());
  • 你常用的 React Hooks 有哪些,描述功能

    • 打出来
  • 服务端渲染了解吗 和 SPA(单页面应用) 的区别

  • Commonjs 和 ES6 Module 得区别

    • 还了解过其他的吗,不了解(AMD、CMD、UMD...)
  • 算法题

    • 题不难,但是思路跑偏了

    • 先用的递归O(n ^ 2)

    • 可以优化一下吗?

    • 改成了循环可以提前终止

    • 面试官: 其实你思路跑偏了,O(n)的复杂度就可以,用栈(瞬间顿悟),不过解出来就好

  • 反问

大概 45 分钟吧

说一面就给我过了,等会 17:00 二面

二面

  • 讲讲项目,说说你的亮点

    • 亮点,性能优化吧,怎么测量的,怎么优化的,优化前后的对比

    • Network, Lighthouse, Performace, Memory, Webpack、网络

    • 面试官也会提出一些问题,问我怎么优化,原理是什么

  • 有写过 webpack 的 plugins 吗

    • 没有
  • 看代码,css 选择器权重

  • 算法:二叉树

        有这么一个数据结构:

        const data = [
          {
            "id""1",
            "sub": [
              {
                "id""2",
                "sub": [
                  {
                    "id""3",
                    "sub"null
                  },
                  {
                    "id""4",
                    "sub": [
                      {
                        "id""6",
                        "sub"null
                      }
                    ]
                  },
                  {
                    "id""5",
                    "sub"null
                  }
                ]
              }
            ]
          },
          {
            "id""7",
            "sub": [
              {
                "id""8",
                "sub": [
                  {
                    "id""9",
                    "sub"null
                  }
                ]
              }
            ]
          },
          {
            "id""10",
            "sub"null
          }
        ]
        现在给定一个id,要求实现一个函数

        findPath(data, id) {

        }
        返回给定id在 data 里的路径
        示例:

        id = "1" => ["1"]
        id = "9" => ["7""8""9"]
        id = "100"=> []
        PS: id 全局唯一,无序
    • 考点递归回溯,非原题
  • 说下 EventLoop

  • 看代码

         async function async1({
             console.log('async1 start');
             await async2(); 
             console.log('async1 end');
         }
         async function async2({
             console.log('async2');
             // 注意:这里如果返回 Promise 的话执行顺序就不一样了
         }
         console.log('script start');
         setTimeout(function({
             console.log('setTimeout');
         }, 0)
         async1();
         new Promise(function(resolve{
             console.log('promise1');
             resolve();
         }).then(function({
             console.log('promise2');
         });
         console.log('script end');
    • 非原题

大概 40 分钟吧,等会 18:00 三面

三面

  • 自我介绍

  • 几几年的

  • 哪里人啊

  • 高考是出现了什么状况吗

    • 没有啊,就是当时没那个想法
  • 这个学历对你产生了多少影响

  • 还是聊聊技术吧,给一个场景,二分查找

    // 当时用的 js,用 ts 只是为了表达的更清晰一点
    interface Barrage {
      time: Number;
      barrage: String;
    }
    const binarySearch = (arr: Barrage[], time: number) => {
      let l = 0;
      let r = arr.length - 1;
      while (l <= r) {
        const mid = (l + r) / 2;
        if (arr[mid].time === time) {
          return arr[mid].barrage;
        } else if (arr[mid].time < time) {
          l = mid + 1;
        } else {
          r = mid - 1;
        }
      }
      return null;
    }
    • 那数组的边界

    • 我就在那看,看了大概十几秒吧,会越界吗...

    • 面试官:好吧,那我们先下一题

    • 写出来了

    • 你还能在优化一下吗

    • 额,时间复杂度O(logn), 空间复杂度 O(1),这挺优的啊(有点懵)

    • 不,这个优化不止是时间和空间复杂度,可以从工程化的角度出发

    • 还是有点懵

    • 提点了我一下(l 和 r 为什么要定义在外面)

    • 哦哦,关联太多,所以耦合就高,您是指的这个吗(没回复)

  • 一个异步任务调度器,最多同时执行两个异步任务

    • 有思路吗?

    • 用个数组先存起来,判断执行的数量,需要就取出来,

    • 好,那你写吧

    • 结果写了好久,半个小时起步,还没写出个结果

    • 执行逻辑大概写出来了,但返回的逻辑没写出来

    • 提点我一下,我改了一下

    • 又提点我一下,我又改了一下

    • 逻辑上离成功就差一步了(还差一个异步),但我傻呵呵的对着 C++ 的控制台打了半天 js 代码,给的是类我还少打了好几个 this,唉...

    • 时间问题打断了,确实写的太久了

  • 为什么学前端

  • 一个用户活跃度几千万的网站你会做哪些优化

    • 有点懵,说实话我对几千万和几十个人没什么概念,说了些关于首屏,用户体验的优化,减少请求...
  • 反问

    • 学习建议

    • 做题之前先想清楚,不要错在一些不该错的地方

每轮面试官问的问题都很开放,引导你自己说,再根据你所说的东西再去问一些问题 连着三面,因为三面比较惨所以对其他两面问题印象不是很深

复盘

异步任务调度器

这个异步任务调度器调用机制实际和 Proimse 的 reslove 触发 then 方法是相同的,reslove 内的执行逻辑需异步触发,等待 then 方法中的内容执行完(存储好)再触发,只是方法内部执行逻辑有细微的差异而已。

二分查找

// 这除出来可有可能是个分数啊
const mid = (l + r) / 2; // Math.floor((l + r) / 2);
// l + r 也可能超出数字范围
const mid = l + Math.floor((r - l) / 2);

这心一下就哇凉哇凉的,之前的 Promise 白手写了,索引还不取整,脑袋跟进了水一样,灌得满满的那种。

第二天下午,hr 和我说面试通过,但因学历 offer 审批有些困难,会努力帮我争取。很感谢,说实话能得到这个认可,我已经很开心了。三月一开始投递简历到现在,大专不要,必须本科,学历不符,BOSS 上投递大多回复都没有,大多的公司面试机会都没有,学历问题的我也早已经习惯了。

6月15日,收到 hr 通知,最终还是不行...

不过 hr 在他们的群里发了一下,我被另一个部门又捞起来了

互娱研发一面

6 月 17 日

  • 自我介绍

  • 亮点

    • 当然还是说的性能优化,这下可惨了
  • 那给一个网站 SEO 怎么优化

    • 通过 Lighthouse 进行测量,根据 Lighthouse 给出的建议 进行优化

    • title, keywords, description,语义化,img 的 alt,a 的 href

    • 知道 SEO 什么什么(不记得面试官说的什么了)?

    • 不知道

  • 如果不用 Lighthouse,Lighthouse 那不就只是能在谷歌上测吗(大概是这么个问题)

    • WebPageTest 不过我用的比较少,没深挖

    • Lighthouse 也可以通过 npm 进行下载使用

  • SSR 了解吗

    • 不了解,就跑过 next 的案例

    • 我当时可能理解错了,应该是说下概念就行

  • dns 预解析的怎么实现的?

    • dns 解析的过程?
  • 为什么要用 http2

    • 多路复用

    • 那说下 http1.1 和 http2 区别?

    • 头部压缩,多路复用,别的没啥印象(可以设置请求的优先级,服务器推送(Server Push))

    • Server Push 了解过吗?

    • 啥,我咋没听过(我是智障,我是智障,我是智障...)

  • session 了解吗?

    • 登录鉴权就聊到 token

    • JWT 了解吗?

    • 不太了解,只知道 T 是 token

  • CSRF 攻击了解吗?

    • 怎么预防那?还有其他办法吗?

    • 如果不通过 img 或者 script 标签,或者说用户不通过点击第三方连接怎么造成 CSRF 攻击吗?

    • 不知道啊,然后面试官给我讲了一些关于 dns 劫持

  • http 和 https

    • 说了对称加密和非对称加密,具体不清楚

    • 那你说下 https 握手过程?

    • 不知道啊

    • http 的缺点 明文不加密,内容可能被窃听;不验证通信方身份,可能遭遇伪装,无法证明报文的完整性,可能被篡改。https 就是披着 SSL 外壳的 HTTP,SSL 会建立安全通信线路,查明对手证书...

    • 知道 http 的内容是如何窃听的?

    • 不知道,不过可以一些抓包工具抓

    • 浏览器怎么验证证书的?

    • 那对称加密和非对称加密怎么之间选择?

  • 说下 cdn 缓存?

    • 不了解,说 HTTP 缓存可以吗

    • 也行

    • Cache-Control、Expires(因为效验问题,被 Cache-Control 替代)、Last-Modified、Etag

    • 说下请求头?

    • If-Modified-Since,Cache-Control 是看 max-age,(想不起来了If-None-Match) 因为上次一面让我都让我打出来,这次我也就习惯性把这些都打出来了,结果后面才知道面试看不到...

    • 那为什么会考虑用强缓存那?

    • 一个文件比较大,且不经常更新就会考虑用强缓存

    • 那文件要变了怎么办?

    • 啊,用 no-cache,让服务器处理

    • 那为什么不用协商缓存?

    • 额,我也在想

    • 面试官:用 hash ...

  • 热模块替换的原理了解吗?

    • 那他是怎么保留之前更改的状态那?

    • 不知道

  • webpack 怎么实现的知道吗?

    • 不知道
  • loader 和 plugins 的区别

    • plugins 作用于 webpack 那个生命周期?

    • 啊,不知道啊(plugins 对打包过程和结果进行干预), 说了下 webpack 构建流程

  • 你所知道的白屏原因

    • 怎么优化
  • 三列布局

    • flex: 1; 是复合属性,说下其他属性?

    • 扩展比例,缩放比列,基准大小(x轴覆盖宽度,y 轴覆盖高度)

  • ES6 新增的类型

    • Symbol, BigInt

    • Symbol 有用过吗?

    • 手写 bind 的时候用过,防止覆盖掉对象上的原有属性

  • ES6 新增的类

    • Promise

    • WeakMap 和 Map 了解吗? 说下他们的区别?

    • WeakMap 的键必须是对象

    • 有用过吗?

    • 深拷贝判断是否有重复引用的时候用过

    • 面试官:WeakMap 是和垃圾回收有一些关系...

    • MDN: 原生weakmap持有对关键对象的“弱”引用。由于这样的原生weakmap不阻止垃圾收集,从而最终删除对键对象的引用。“弱”引用还避免了对映射中的值进行垃圾收集。当将键映射到只有在键未被垃圾收集时才有价值的键的信息时,weakmap是特别有用的构造。

1 小时零 5 分(还有其他的想不起来了)

  • 看代码,变量提升,块级作用域

  • 算法:回文字符串(这个问题好常见),判断一个字符串最多只删1个字符,是否能成为一个回文字符串

    let str = "ABCDABA"
    let l = 0;
    let r = str.length - 1;
    • 要不要我提示你一下?

    • 那您提示一下吧。

    • 思路是没错的,不同的时候你判断删除那个字符是不是回文字符串

    • 先说思路再写,还是先写在说思路

    • 额,先说思路吧。

    • 判断是否为回文字符串的话,我可以这个字符串反转过来,判断是否原字符串相同,然后将每种情况都试一下

    • 暴力破解呗,是可以实现,但是这个复杂度就是 O(n^2) 的了啊,能不能在优化优化

    • 设置两个索引前后对比,两边字母相同向内靠拢,不同,呀,不同咋办(卡住了)...

const reverse = (str) => {
    let temp = '';
    for(let i = 0; i < str.length; i++) {
        temp += str[i];
    }
    return temp === str;

const isSymmetry = (str) => {
    let l = 0;
    let r = str.legnth - 1;
    while(l <= r) {
        if(str[l] === str[r]) {
            l++;
            r--;
        } else {
            if(!reverse(str.substring(l, r)) && !reverse(str.substring(l + 1, r + 1))) {
                return false;
            }
        
        }
    }
    return true;
}

面试结束复盘

当时没有测试用例,少测试了一种情况,当删除一个字母就是回文子串的情况,没有终止条件,这个代码死循环了,而且我既然想到用索引的方式判断是否为回文字符串,那么我就不应该再用反转再去判断,而的这个逻辑 isSymmetry 中就是,我也不应该再去重复写一个一样逻辑的函数。

const isSymmetry = (str, flag = false) => {
    let l = 0;
    let r = str.length - 1;
    while (l <= r) {
        if (str[l] === str[r]) {
            l++;
            r--;
        } else {
            if (flag) {
                return false;
            }
            if (
                !isSymmetry(str.substring(l, r), true) &&
                !isSymmetry(str.substring(l + 1, r + 1), true)
            ) {
                return false;
            }
            return true;
        }
    }
    return true;
};

这是我说不知道最多的一场面试,被虐的很惨,发现自己很多不足,接下来就是要弥补这些不足,去精读浏览器工作原理于实践这个专栏,按照之前的效率,应该是凉了...

互娱研发二面

6 月 22 日

  • 0.1 + 0.2 !== 0.3 为什么

  • IEEE 754 了解吗

  • 什么什么的几种(计算机组成原理相关的)算法?

    • 不会,这个,计算机基础确实比较薄弱,之前没重视到
  • TCP 拥塞控制?

    • 不知道,只了解丢包阻塞的情况,(网络的知识就看过图解HTTP和面经, 唉...)...

    • TCP 和 UDP 的区别

    • 三次挥手四次握手

  • TypeScript 高级用法, Pick 和 Omit

  • 泛型的理解

  • webpack 和一面差不多吧

    • devServe 做了哪些优化了解吗

    • 热模块更新

    • 其他的那

    • 不知道了

  • React Fibler

  • 实现一个自定义 hook, 刚开始案例是 useState,我没问明白一直以为实现一个 useState,后来才发现是实现自定义 hook...

  • 讲讲常用的 hook 打出来

  • 用正则表达式获取 url 中 query 参数

    let str = "https://juejin.cn?name=zhangsan&age=18&id=123";
    function getUrlParams = ()=> {
    let obj = {};
    for (let i = 0; i < splitStr.length; i++) {
      let temp = splitStr[i].split("=");
      obj[temp[0]] = temp[1];
    }
    return obj;
    }
    console.log(obj);
    • 可以不用正则吗,我不熟

    • split 功能记错了,以为只能分割成两个数组,还打算自己封装一个...中间面试官打了个哈欠,写了不到 10 分种,被打断了

    • 这么简单的题,我当时做的好像一个脑残,我要是面试官我也不想面了

  • 你总结一下这场面试

    • 计算机基础之前确实没重视到,之后也打算系统学习一下,但是说实话我对自己的编码能力挺自信的,虽然我不爱背 API

    • 前端基础其实还可以,就是你有点急,一急就什么都想不起来(您都打哈欠了,我能不急吗,本来就慌,这一下,心都凉了),那我再给你出道题

  • n 叉树层序遍历

    const levelOrder = (root) => {
      while (root.length) {
        const temp = root.shift();
        console.log(temp.val);
        for (let i = 0; i < temp.children.length; i++) {
          root.push(temp.children[i]);
        }
      }
    };
     const root = [
      {
        val1,
        children: [
          {
            val3,
            children: [],
          },
        ],
      },
      {
        val2,
        children: [
          {
            val4,
            children: [],
          },
        ],
      },
    ];

1 个小时 10 分左右

计算机基础很重要,后期一定要系统学一下,正则表达式用的太少了,参加比赛用的都是 C 语言,所以一直不爱背 API 现在吃大亏了,一面剪切字符串刚开始就是自己封装的,现在又不长记性,唉,当时心都凉了,晚上 hr 说通过了,周五三面...

互娱研发三面

6月25日

  • 自我介绍

  • 先写一道题吧两数之和

const twoSum = (arr, target) => {
    const obj = {};
    for(let i = 0; i < arr.length; i++) {
        if (obj[arr[i]] != null) {
            return [obj[arr[i]], i];
        } else {
            obj[target - arr[i]] = i;
        }
    }
    return [];
};
  • 返回所有的情况
const twoSum = (arr, target) => {
    const res = [];
    for(let i = 0; i < arr.length - 1; i++) {
        for(let j = i + 1; j < arr.length; j++) {
            if(arr[i] + arr[j] === target) {
                res.push([i, j]);
            }
        }
    }
    return res;
}
twoSum([2,7,117], 9);

// 打印个这个 0, 1, 0, 3

牛客把我的数组给展开了, 我当时就有点懵, 这是啥, 有检查一遍代码, 没问题啊, 您好我可以打开控制台调试一下吗

image.png
  • 分析一下时间复杂度, 能不能在优化一下

再上一个问题开始的时候, 我就一直再想怎么优化, 毕竟面试了好几次了, O(n^2)一定会让我去优化的

const twoSum = (arr, target) => {
    let obj = {};
    let res = [];
    for(let i = 0; i < arr.length; i++) {
        if(obj[arr[i]] != null) {
            let temp = obj[arr[i]];
             for(let j = 0; j < temp.length; j++) {
                 res.push([temp[j], i]); // res.push([temp[j], i); 当时这里少打一个 ]
             }
        } else {
            let temp = target - arr[i];
            obj[temp] = obj[temp] ? [...obj[temp], i] : [i];
        }
    }
    return res;
}
image.png

牛客这个报错信息, 不知道是面试官给的条件不一样还是怎么回事, 每次报错信息都不太一样, 最开始视频架构部门面试打错了, 提示的挺详细啊, 又看一遍代码逻辑没错啊, 然后我就申请打开控制台了

image.png

然后开始解释思路, 抬头看下时间已经 25 分钟, 写的有点久了啊

  • 学前端多久了

  • 怎么学前端的

  • 聊聊项目亮点

    • 我在说性能上做的一些优化, 面试官没追问我, 说到 http2, TCP 丢包阻塞问题, 问我有没有什么办法能解决这个丢包阻塞问题, 这好像解决不了或者很困难, 因为 http3 弃用了 TCP 直接采用的 UDP, UDP 有哪些特性
  • 闭包数据怎么检查

  • 实现一个搜索推荐组件会考虑哪些

    • 我组件库里有这个组件有链接, 防抖

    • 怎么监听数据变化

    • input 的值吗, React 中是 onChange,

    • 比如我先输入一个 a, 然后我在输入一个 b, a 请求后返回你怎么办

    • 想了想说, 后端将我请求值带回来, 我做一个判断是否更新推荐列表

    • 那不通过后端那

    • 额, 没什么想法(请求可以取消...)

  • webpack 了解多少

    • 之前面试有问过,主要还是再使用层面,原理没深入了解过,我主要还是想...

    • 嗯嗯嗯嗯嗯嗯...

    • 我该闭嘴了

  • 最大的优点和缺点(好像问的不是性格, 而是技术相关的)

  • 我看你面试过其他部门, 什么原因

    • 学历

    • 啊!(感觉面试官有点惊讶,眼睛都瞪大了)

    • 我大专吗, 然后 offer 审批不通过

  • 反问

    • 学习和技术上的建议

    • 我觉得你学习还可以,技术上吗,实习还是先多打基础吧,看一些教科书类的书籍

48 分钟

接着复盘

// 我当时觉得最差的情况是这个 
twoSum([2227], 9);
// n + n - 1
// 但一半一半才最差, 
twoSum([2277], 9);
// (n / 2) + (n/2) * (n/2)
// 而且我还忽略了一种情况, 这个 else 不应该加
twoSum([2727], 9);
const twoSum = (arr, target) => {
    let obj = {};
    let res = [];
    for(let i = 0; i < arr.length; i++) {
        if(obj[arr[i]] != null) {
            let temp = obj[arr[i]];
             for(let j = 0; j < temp.length; j++) {
                 res.push([temp[j], i]);
             }
        }
        let temp = target - arr[i];
        // obj[temp] = obj[temp] ? [...obj[temp], i] : [i];
        // 用 push 更好一点
        obj[temp] ? obj[temp].push(i) : obj[temp] = [i];
    }
    return res;
}

这场面试题写完之后, 后面也不那么紧张了, 但感觉题写的有点久了, 而且后面面试官也没问什么问题, 好像我也没什么值得他问的了,感觉到面试官对我不感兴趣了,后面聊天打了个哈欠,我可能耽误人家午休了吧(下午两点),之后又贴近了镜头整了整头发,缺少亮点啊。

6月28日,三天了,没消息,问下 hr, 果然没通过。

  1. 3年前端的职业成长与规划

    2021-07-01

    为什你应该使用picture标签而不是Img标签

    2021-06-30

    他入职腾讯一年,放弃和收获的那些事儿

    2021-06-28

最后

最近要跳槽的,可以加个微信。
无论是考虑跳槽,交个朋友也好。



喜欢这篇文章?点个“在看”吧~▼

浏览 34
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报