战五渣在金三银四的摸爬打滚之路

240 阅读8分钟

好运来不灵了,分享一波面经攒人品,求捞求不挂~

背景:本人19年毕业,创业公司划水党(希望别被HR看到~)

虾皮

面的第一波公司,对不起我来蹭面筋一轮游了。。

  • 暂时性死区
  • 为什么要有last-modified etag,他们各自有什么问题
  • http2.0 与 HTTP1.1
  • 跨域
  • redux跟mobx的理解,redux的缺点
  • useRef可以存放那些值,为什么要用current获取
  • react的diff算法,fiber节点里面有哪些东西,fiber跟之前的jsx节点的区别,节点的移动
  • 大数相乘
  • 原型题
const a=function(){}
a.prototype.b=1
const h=new a()
a.prototype={
    b:3
}
const s=new a()
console.log(h.b,'kk',s.b)  // 1 kk 3
  • 事件循环
const a=new Promise((resolve,reject)=>{
    console.log(3)
    resolve()
    console.log(5)
})
a.then(()=>{
    console.log(9)
    Promise.resolve().then(()=>{
        console.log(8)
    })
})
setTimeout(()=>{
    console.log(7)
},0)
// 35987
  • 其他:计算机网络...

滴滴

easy题都做错了还自我感觉良好(一面挂。。。透心凉,心拔凉)

  • 二叉树的翻转
  • react的生命周期
  • react的性能优化
  • 乾坤原理
  • 移动端键盘回弹问题中,如果有多个输入框,按照我的方式当我完成第一个输入框之后失去焦点滑动到上面了然后点击下一个输入框的时候会发生上下滑动的一个不好的效果,(提示的解决对策是防抖)
  • 其他

去哪儿

  • cluster是干嘛的
  • git相关
  • 数组去重
  • react基础
  • createRef跟useRef的区别
  • 手撕代码

设置定时器每隔一秒发送一次请求,总共六次,当服务器返回complete为true的时候停止,并需要获取返回的数据

  • 项目相关
  • 读过哪些源码
  • node怎么读取大文件
  • node用来做什么

百度

百度一面相当简单,差点误会成是刷KPI的,其实不是哈哈哈

  • hooks的原理
  • this跟普通函数的区别
  • async中的await后面的如果是一个promise reject了还会执行剩下的吗
  • flex的几种取值
  • react的portal
  • 怎么统一成标准的盒模型
  • 自己实现过的困难组件
  • js基础...

高德

  • 一面也很简单都是基础,不是刷KPI的,许愿二面顺利~
  • 二面也都是基础,面试官的建议的深度不够
  • 三面基本都是项目相关,还有你在团队的定位,你的上级跟你反映过你什么缺点,你的同事反映过你什么问题跟优点,工作节奏怎么样,能适应什么样的节奏,你印象最深的成长最快的项目?在上一家公司有没有什么不舒服的地方?

面试官的建议:做一个新东西的时候,探索还不够,因为我提到用SSR是为了优化SEO,被问到市面上常用的优化SEO的手段有哪些答的不好。

猿辅导

  • 你对构建部署做出过什么贡献
  • 怎么构建部署的
  • 原型链等js基础知识
  • 项目相关,移动端适配。。。
  • 看代码输出
  • 函数式编程跟面向对象编程
  • babel的原理
const S={}
S.prototype.say=function(){...}
(new S.say)()
new S.say()
  • ca证书的作用
  • 二叉树求根节点到叶子节点的路径和(面试官说用栈实现不好,求解)
  • 求小于n的重复数字数量(力扣上的)
  • 合并数组题
  • interface跟type的区别
  • HTTPS会对get数据进行加密吗?会对post数据进行加密吗?post的data有哪些类型,流类型什么时候用到
  • SSR是怎么做的
  • 四道编程题(十五分钟写前三道能做多少做多少,最后一道算法题求树的最大深度,人品大爆发基本都做出来了嘿嘿嘿)

360

  • css相关,grid实现三栏布局,翻转动画,多种方式画等腰三角形
  • 项目相关
  • 构建部署做了哪些贡献
  • 官网数据是可配置的,那么是怎么判断是服务端的错误还是node层的错误
  • 一个矩形,中间一根斜着的轴线,鼠标在里面移动,怎么判断光标是在上面还是在下面还是在轴线上?(提示坐标轴)
  • react的diff算法的优化
  • mixin extends hoc的区别
  • 不记得了

青云

  • react怎么解决UI不连续的问题 state批量更新

  • 实现setTimeout并且不阻塞主线程 1.webworker(缺点是如果要写多个settimeout的话要多个worker,而worker的数量是有限制的) 2.window.cancelanimationframe 3.window.requestidlecallback(缺点是浏览器只会在这一帧剩余的时间内执行,但是时间可能会不够)

  • 垃圾回收

  • 多个异步任务然后同时只能有n个一起进行,并且有优先级的限制,如果是后续有优先级高的进来了的话先执行优先级高的,优先级低的会被打断

  • vue和react的区别

  • es6的寄生组合继承跟es5继承的差别 前者是先生成一个实例。。。

  • 各种继承方式

  • express中间件的执行顺序

搜狐

  • 项目遇到的难点
  • 怎么构建部署的
  • 不记得了

58

  • 控制翻转 依赖注入
  • 看过的源码
  • 组件库怎么打包的,生成的目录结构是啥,怎么打包出index.d.ts
  • fiber root
  • redux的原理
  • 策略模式(深入,如果rule1对应的handler1中调用了handler2怎么办,一个rule对应多个handler,怎么办。。。)
  • 乾坤 怎么打快照的
  • webpack相关
  • 有过node的线上项目吗
  • 用过哪些策略模式
  • 为什么用乾坤
  • 遇到哪些难点(父子应用间的样式已经实现了隔离了的)
  • 用装饰器写过啥

面试官的建议:多了解了解架构,为什么要用XXX,怎么用好XXX等等

字节跳动

三面面的奇差,前面两面也不咋地不知道HR咋给我捞的。。。

  • 对称加密跟非对称加密
  • 二叉树的层序遍历
  • 缓存相关
  • js基础
  • 项目相关
  • 怎么获取到用户的白屏时间并分析
  • 一道promise的题
  • webpack相关
  • 实现一个功能

题目:JS实现一个带并发限制的异步调度器Scheduler,保证同时运行的任务最多有两个。完善代码中Scheduler类,使得以下程序能正确输出。

class Scheduler {
  add(promiseCreator) { ... }
  // ...}const timeout = (time) => new Promise(resolve => {
  setTimeout(resolve, time)
})
const scheduler = new Scheduler()
const addTask = (time, order) => {
  scheduler.add(() => timeout(time))
    .then(() => console.log(order))
}
 
addTask(1000, '1')
addTask(500, '2')
addTask(300, '3')
addTask(400, '4')

// 我的解法 错误版本
class Scheduler {
  constructor() {
    this.doing = new Proxy([], {
      set: (target, prop, value) => {
      // 新增任务
        if (prop > target.length - 1) {
        // 要是当前的执行任务队列已经满了 就不执行,依旧停留在待执行池子
          if (target.length >= 2) {
          // 必须要return true 不然会报错,只要不写:target[prop] = value return true也是不会赋值的
            return false;
          } else {
          // 否则执行它 这里没有将即将执行的任务从待执行任务中删除
            target[prop] = value;
            value()
            return true;
          }
        } else {
          if (this.tasks.length) {
            const current = this.tasks.shift();
            current();
            // 即将删除当前执行任务中完成的任务 又push了新的,导致中间产生空的项
            target.push(current);
          }
          return true;
        }
        return true;
      },
    });
    this.tasks = [];
  }
  add(promiseCreator) {
    return new Promise((resolve) => {
      const wrap = () => {
        promiseCreator().then((res) => {
          resolve(res);
          const index = this.doing.findIndex((item) => item === wrap);
          this.doing.splice(index, 1);
        });
      };
      this.tasks.push(wrap);
      this.doing.push(wrap);
      // 上面返回false导致的错误被catch了走到了下面的then。。。
    }).catch((err) => {});
  }
}
const timeout = (time) =>
  new Promise((resolve) => {
    setTimeout(resolve, time);
  });
const scheduler = new Scheduler();
const addTask = (time, order) => {
  scheduler.add(() => timeout(time)).then(() => console.log(order));
};

addTask(1000, '1'); // 1000
addTask(500, '2'); // 500
addTask(300, '3'); // 800
addTask(400, '4'); // 1200
// 2 3 4 1

//  debug后
class Scheduler {
  constructor() {
    this.doing = new Proxy([], {
      set: (target, prop, value) => {
        if (prop > target.length - 1) {
          if (target.length >= 2) {
          } else {
            this.tasks.shift();
            value()
            target[prop] = value;
          }
        } 
        return true;
      },
    });
    this.tasks = [];
  }
  add(promiseCreator) {
    return new Promise((resolve) => {
      const wrap = () => {
        promiseCreator().then((res) => {
          resolve(res);
          const index = this.doing.findIndex((item) => item === wrap);
          this.doing.splice(index, 1);
          if (this.tasks.length) {
            const current = this.tasks.shift();
            current();
            this.doing.push(current);
          }
        });
      };
      this.tasks.push(wrap);
      this.doing.push(wrap);
    })
  }
}
const timeout = (time) =>
  new Promise((resolve) => {
    setTimeout(resolve, time);
  });
const scheduler = new Scheduler();
const addTask = (time, order) => {
  scheduler.add(() => timeout(time)).then(() => console.log(order));
};

addTask(1000, '1'); // 1000
addTask(500, '2'); // 500
addTask(300, '3'); // 800
addTask(400, '4'); // 1200
// 2314

面试官的建议:多理解少背概念,加强数据结构

其他

  • docker的理解
  • 堆栈
  • react的diff
  • react vs vue
  • 查找所有回文串

HR面相关

  • 为什么要做前端
  • 为什么毕业之后还在实习?(死亡三连问之一)
  • 你的缺点是什么(死亡三连问之二)
  • 高考成绩。。。(我怎么就这么实诚呢?死亡三连问之三)
  • 你的优点
  • 为什么来北京
  • 为什么要换工作
  • 现在的工资
  • 以前的导师叫什么名字
  • 以前的面试官(我提到来了头条,挖了个大坑。。)叫啥名字
  • 学习能力强(没办法程序员最看重这个只好瞎编)体现在哪里

总结

算法很重要,计算机网络也很重要,然后运气也很重要。。当然实力更重要。插个题外话,遇到一次面试啥都没问直接让我过了并且确定不是刷KPI的甚至还愿意帮我,说明脸缘也很重要哈哈哈。 人品已攒,求勿挂呀求勿挂。许愿剩下的面试能顺利。顺便立个flag:今年一定要刷两百道力扣!

4.29更新:来自滴滴面试官的建议:回答一个什么问题结论先行,别人感兴趣再继续,回答问题要有条理,不然让人觉得我的知识体系比较混乱,推荐了《金字塔原理》,简历没有重点,没有阐述清楚自己的核心工作,解决了什么问题。