三年前端寒冬入大厂,收获蚂蚁P6+、字节2-1 offer 面经分享

最近由于一些缘由想要换份工做,经过猎头帮我投递了几家公司,收到了蚂蚁、字节和拼多多的面试邀约,先来讲下面试的结果css

  • 蚂蚁:收到 offer,定级 P6+
  • 字节:收到 offer,定级 2-1
  • 拼多多:1 面以后未继续流程

拼多多

先来讲说拼多多,原本投的是 C 端,结果鬼使神差简历去到了 A 端(管理后台),一面简单了解以后并不肯意去作 A 端,以后也就没有继续后续的流程了。前端

一面

合并两个数组vue

concat、for 循环、扩展运算法、push.apply 这些方法均可以node

合并两个对象mysql

Object.assign、扩展运算法、手写深浅拷贝 均可以ios

interface 和 type 的区别git

常规题,网上资料不少了,仍是看官网的说明比较好github

  • An interface can be named in an extends or implements clause, but a type alias for an object type literal cannot.
  • An interface can have multiple merged declarations, but a type alias for an object type literal cannot.

flex: 0 1 auto 表示什么意思web

flex: 0 1 auto 其实就是弹性盒子的默认值,表示 flex-grow, flex-shrinkflex-basis 的简写,分别表示放大比例、缩小比例、分配多余空间以前占据的主轴空间。面试

详细的能够看下 第 154 题:弹性盒子中 flex: 0 1 auto 表示什么意思

求字符串数组的最长公共前缀

好比输入: [“flower”,“flow”,“flight”],输出: “fl”

解题思路是先获取数组中的最大值及最小值字符串,最小字符串与最大字符串的最长公共前缀也为其余字符串的公共前缀,即为字符串数组的最长公共前缀

var longestCommonPrefix = function(strs) {
    if (strs === null || strs.length === 0) return "";
    if(strs.length === 1) return strs[0]
    let min = 0, max = 0
    for(let i = 1; i < strs.length; i++) {
        if(strs[min] > strs[i]) min = i
        if(strs[max] < strs[i]) max = i
    }
    for(let j = 0; j < strs[min].length; j++) {
        if(strs[min].charAt(j) !== strs[max].charAt(j)) {
            return strs[min].substring(0, j)
        }
    }
    return strs[min]
};

固然还有其余解法,能够看下这篇,图解拼多多&leetcode14:最长公共前缀

手写 Koa 的 compose 方法

这里实现一个简化版,若是问你异步如何处理的话,dispatch 函数里面 return promise 就行了

function compose(middleware) {
  return function() {
    return dispatch(0)
    function dispatch(i) {
      let fn = middleware[i]
      if (!fn) return
      return fn(function next() {
        return dispatch(i + 1)
      })
    }
  }
}

获取精度更高的时间

  • 浏览器使用 performance.now() 能够获取到 performance.timing.navigationStart 到当前时间之间的微秒数

  • Node.js 使用 process.hrtime 返回一个数组,其中第一个元素的时间以秒为单位,第二个元素为剩余的纳秒

获取首屏时间

  • H5 若是页面首屏有图片
首屏时间 = 首屏图片所有加载完毕的时刻 - performance.timing.navigationStart
  • 若是页面首屏没有图片
首屏时间 = performance.timing.domContentLoadedEventStart - performance.timing.navigationStart
  • 小程序经过拦截 setData 调用方式计算

git rebase 和 merge 的区别

常规题了,主要的区别在因而否保留分支的 commit 提交节点,rebase 会给你一个简洁的线性历史树

蚂蚁

蚂蚁一共是 4 轮技术面 + 1 轮 HR 面,耗时 10 天,流程相对来讲还算快了。4 轮技术面都是电话面,最后的终面(HR 面)是视频面。蚂蚁的面试主要仍是根据简历提问,因此简历上写的点都须要好好准备下。

其中比较难的是第 4 面和 HR 面,由于这两面才是最终决定是否录用你以及肯定录用以后的职级,4 面的面试官通常是 P8 或者 P9,Level 比较高,会从聊天的过程当中考察你,另外 HR 面拥有一票否决权,若是被 HR 否决,前面面的再好也没用,这两面都须要好好准备下。

一面

一面又叫简历评估面,主要对简历上的东西进行提问,一面结束以后会经过邮件发几道编程题,难度比字节大,可是不限定时间,最好当天作完发过去

有没有作过 node 端

介绍了下个人「高级前端面试」小程序和写过的几个 node 脚本,聊了下总体的架构、数据库(mysql + redis)、部署、监控这些方面

大型复杂项目开发协做经验、遇到的问题和解决方案

主要介绍下 git 协做流程

若是让你负责一个新项目,如何选择技术栈,如何避免多端合做可能遇到的问题

脚手架开发、约定团队开发规范、Lint 等;根据团队的技术栈、成员能力等去选择

TSLint、ESLint 的区别

TS 已经建议使用 ESLint 了

对 TS 的认识,项目中是否使用

那必须使用了

介绍一些开源框架的原理

Koa、Axios、Vue、React、Taro 等

对开源框架的一些贡献

先吹下个人前端 100 问,再虚心的表示下后续对开源框架作些贡献

介绍我开发的性能监控 SDK、行为埋点 SDK 的工做、背景、遇到的问题等

个人业务问题,介绍了下总体的架构、遇到的一些难点、解决方案等

性能监控的一些实现原理,包括异常、网络请求、加载时间等

业务问题,吹就完事了

介绍下灰度功能

聊了下业务场景,实现原理,迭代优化的过程

对于后端的数据收集落库、web 搭建等的认识

不是主要开发,可是仍是有些参与和了解

其余的项目难点

聊了下 SDK 的缓存优化

介绍下写博客和公众号的初衷、运营、推广等

主要仍是提高本身,聊了下运营模式

二面

和一面同样都是聊项目,可是换了一个方向切入,主要仍是根据简历上的点去深刻提问

小程序的技术架构和方案、小程序的出现主要解决什么问题?

包含小程序容器、渲染引擎和 JavaScript 引擎。UI 层运行在 WebView 中,而逻辑层运行在独立的 JS 引擎中。

下降获客成本、打通跨端

view 层、js 层分别在哪里、怎么通讯 ?

业务逻辑的 JS 在独立的 JavaScript 引擎(ServiceWorker)中,每一个页面的 view 和 css 运行在各自独立的 webview 里面,页面之间是经过函数 navigateTo 进行页面的切换;

JS 层和 view 层经过消息服务 MessageChannel 进行通讯

Taro 和其余小程序框架的横向对比,如何选型

Taro、uni-app、kbone、WePY、mpvue

Taro 的一些好用的点和很差用的点,聊下想法

一些特性不支持,不过随着 Taro 的升级也在解决

Taro 自己的限制

对 React 的语法支持有限,好比不能使用 Array#map 以外的方法操做 JSX 数组

React 代码转成小程序代码的原理

编译器修改和运行时修改,同时配合 babel 作编译、转译

Babel 的转换过程,好比把 JSX 的 map 转成 wxml

根据 AST 中的 JSXElement 生成对应的数据结构,好比

oddNumbers.map(number => <Text onClick={this.handleClick}>{number}</Text>)

生成的数据结构是

{
  type: 'element',
  tagName: 'text',
  attributes: [
    { bindtap: 'handleClick' },
    { 'wx:for': '{{oddNumbers}}' },
    { 'wx:for-item': 'number' }
  ],
  children: [
    { type: 'text', content: '{{number}}' }
  ]
}

再根据这个结构转成 wxml 就行了,能够参考 himalaya 的代码

真实数据和缓存的竞争如何处理,第一次如何处理,第二次有更新如何处理

优先使用缓存、真实数据替换缓存等

npm 版本号 ^ ~ 的区别

  • 脱字符(^)来限定所安装模块的主版本号

    • ^1.2.1 表明的更新版本范围为 >=1.2.1 && < 2.0.0,即 1.x

    • ^0.2.1 表明的更新版本范围为 >=0.2.1 && < 0.3.0,即 0.2.x

    • ^0.0.2 表明的更新版本范围为 0.0.2(至关于锁定为了0.0.2版本),即 0.0.2

  • 波浪号(~)是限定模块的次要版本

    • ~1.5.1容许安装版本号大于1.5.1但小于1.6.0版本的模块,即 1.5.x

    • ~0.5.1容许安装版本号为0.6.0,即0.5.x

怎么发 beta 版本

npm publish --tag beta

埋点数据上报的方案

Ajax 请求、img、script

图片方案的原理和优点

img 自然支持跨域;跨域友好、不占用 Ajax 请求、执行无阻塞

埋点上报数据的设计

介绍了下抽象数据模板,如何对不一样业务场景进行拆分

介绍下曝光埋点

埋点数据服务端相关的逻辑

异常数据的排查

是否作过 SQL 表查询

写过的最复杂 SQL 查询

介绍下技术运营

最近在看的书

三面、四面

这两轮面试聊得比较轻松,主要聊些项目、规划、思考这些方面

有亮点的项目

写的 SDK 对比同类产品的优点

遇到的问题以及有哪些反思

技术规划

技术的优点和不足

个性、协做方面的优势和缺点

工做地点选择

工做节奏

抗压能力怎么样

HR 面

HR 面仍是须要准备下,不能在最后一步功亏一篑了

介绍最近几年的工做经验

换工做的缘由

目前在看的工做机会

如何考虑将来发展

每家公司离职的缘由

以前跳槽拿到哪些 offer

考虑工做机会的优先级(公司、团队、技术、薪资等排序)

成长特别快的公司和经历

生活、工做遇到的一些有挑战的地方

面对压力通常是怎么应对的

以前工做的绩效

团队中的定位、排名如何

字节

字节的话比蚂蚁少一轮技术面,一共是 3 轮技术面 + 1 轮 HR 面,全程是视频面试,其中比较难的是第 一、2 面,由于前 2 轮会有 3 道左右的笔试题,3 面就是聊聊项目比较简单,HR 面就彻底和技术无关了,纯粹问些你的指望、离职缘由等基本信息,没有一票否决权。

因此若是你打算面试字节的话,必定必定必定提早准备下笔试题,包括但不限于算法题、编程题、手写实现题等。

一面

这里介绍下遇到的手写题,其余的问题和项目关联,就再也不重复了

下面这几道题目已经更新到了个人题库中,能够去那里查看解析,Daily-Interview-Question / 字节

弹性盒子中 flex: 0 1 auto 表示什么意思

求最终 left、right 的宽度

<div class="container">
    <div class="left"></div>
    <div class="right"></div>
</div>

<style>
  * {
    padding: 0;
    margin: 0;
  }
  .container {
    width: 600px;
    height: 300px;
    display: flex;
  }
  .left {
    flex: 1 2 500px;
    background: red;
  }
  .right {
    flex: 2 1 400px;
    background: blue;
  }
</style>

输出如下代码运行结果,为何

若是但愿每隔 1s 输出一个结果,应该如何改造?注意不可改动 square 方法

const list = [1, 2, 3]
const square = num => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(num * num)
    }, 1000)
  })
}

function test() {
  list.forEach(async x=> {
    const res = await square(x)
    console.log(res)
  })
}
test()

实现一个批量请求函数 multiRequest(urls, maxNum)

要求:

  1. 要求最大并发数 maxNum
  2. 每当有一个请求返回,就留下一个空位,能够增长新的请求
  3. 全部请求完成后,结果按照 urls 里面的顺序依次打出

二面

这一面主要对我以前写过的文章进行提问,找了一些文章中能够再深刻的点进行提问

介绍原型鸡生蛋、蛋生鸡问题

能够看我以前的文章,深刻探究 Function & Object 鸡蛋问题

输出如下代码的结果

Object instanceof Function
Function instanceof Object

Object instanceof Object
Function instanceof Function

结果都是 true

手写深拷贝

能够看我以前的文章,面试题之如何实现一个深拷贝

如何实现正则的深拷贝

能够看我以前的文章,Lodash是如何实现深拷贝的

模拟实现 Array.prototype.splice

能够看个人题库,已经收录这道题了,第 158 题:如何模拟实现 Array.prototype.splice

三面

前面两面经过以后,三面就比较简单了,主要就是聊项目,聊我以前作过的项目,亮点,以后的规划,以及加入团队以后所要作的项目

HR 面

比较简单,聊以前的经验,还有指望薪资之类的,没有蚂蚁 HR 的一票否决,整个过程仍是比较轻松愉快

面试感想

先来讲下大环境,感受很是很差,就一二线互联网来讲招人的没几家公司,裁人的、内部调整的、锁 HC 的确是一大堆,因此你们在换工做的时候必定不要裸辞,风险太大。

今年面试和往年感觉有些不一样,对于项目的重难点、亮点、我的在团队中作的贡献、对项目的 Owner 意识等比较关注,还有就是编程能力的考察会更多一些。

对于社招小伙伴来讲,除了常规的 CSS / JS / 网络 / 浏览器 / 异步 / 框架 / 工程化等方面,还须要在以上说的这两方面多加准备准备,准备越充分,拿到的面试评价越高,能拿到的薪资也将越多,加油!!!

面试小程序

最后的最后,推广一波我写的面试小程序,如今用户快突破 3 万了。小程序的功能比较多,包括了编程题、算法营、选择题、简答题、计划每周还会弄一次抽奖活动等。功能写了好几个月,如今在扩充题库的过程当中。欢迎你们使用,欢迎提 Bug,会持续更新维护。

支持

若是你以为这篇内容对你挺有启发,我想邀请你帮我三个小忙:

  • 点个「赞」,让更多的人也能看到这篇内容
  • 关注个人官网 https://muyiy.cn,让咱们成为长期关系