Advertisement

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

阅读量:

最近因某些原因想寻求一份新的工作机会,在猎头的帮助下我已经向多家公司提交了我的简历。获得了蚂蚁、字节跳动和拼多多等公司的面试邀请函,请问您指的是这次面试吗?

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

拼多多

首先介绍一下拼多多的情况。原本参与了C 端项目的相关工作后, 却误打误撞转向了 A 端(管理后台)。在初步了解后, 并不希望从事A端相关工作, 因此也未能继续后续流程。

一面

合并两个数组

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

合并两个对象

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

interface 和 type 的区别

常规题,网上资料很多了,还是看官网的说明比较好

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

flex: 0 1 auto 表示什么意思

在Flexbox布局中,默认设置为 flex: 0 1 auto 是一种标准配置;它等同于将 flex-grow、flex-shrink 和 flex-basis 分别设为放大比例、缩小比例和分配多余空间之前的主轴空间。

该问题深入探讨了弹性盒子中的 flex 属性设置,请查看第 154 题以了解具体细节

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

比如输入: [“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]
    };

除此之外还可以参考一篇题解文章

手写 Koa 的 compose 方法

在此处实现一个简化的版本,在该dispatch函数内部返回一个Promise就足够了。若有人询问异步处理的方式时,请告知在该dispatch函数内部返回一个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)
      })
    }
      }
    }

获取精度更高的时间

现代主流浏览器可以通过调用 JavaScript 函数 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面试。这两项环节直接决定了录用与否以及职位晋升。其中第四轮的主考官多为高级专家P8或P9,考察层级较高。而且若HR阶段判定不合格,则前面所有环节的努力均将付诸东流。

一面

面试通常被称为简历评估环节,在这一阶段中主考官会通过问题考察应聘者的简历信息。在面试结束时, 通常会发送几道编程测试题, 难度略高于字节跳动, 但为了保证公平性, 不需要额外时间准备. 建议当天完成并提交.

有没有做过 node 端

简单介绍一下我的「高级前端面试」小程序以及我开发过的几个 Node 脚本,并谈谈整体架构设计、数据库配置(MySQL 和 Redis)、服务器部署以及服务器监控这些内容。

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

主要介绍下 git 协作流程

如果让你承担一个新的项目,请详细说明您将采取哪些步骤来选择合适的开发平台,并提出具体的策略以规避跨平台协作中常见的问题。

搭建脚手架构造项目框架;基于团队的技术配置和成员专业能力等因素来决定具体的实现方案

TSLint、ESLint 的区别

TS 已经建议使用 ESLint 了

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

那必须使用了

介绍一些开源框架的原理

Koa、Axios、Vue、React、Taro 等

对开源框架的一些贡献

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

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

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

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

业务问题,吹就完事了

介绍下灰度功能

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

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

不是主要开发,但是还是有些参与和了解

其他的项目难点

聊了下 SDK 的缓存优化

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

主要还是提升自己,聊了下运营模式

二面

如同一面都涉及聊项目的情况而言,则采取了不同的切入方式。

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

该系统由小程序容器、渲染引擎及JavaScript引擎构成。其中UI层位于WebView环境中运行,而逻辑层则位于独立的JS引擎运行环境中。

降低获客成本、打通跨端

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

JavaScript 代码被部署到独立运行的 JavaScript 引擎(如ServiceWorker)中进行处理;各个页面对应的视图层和样式文件分别运行在独立且互不干扰的 webview 环境中以确保数据完整性;不同页面之间的切换操作由自定义函数 navigateTo 执行以实现平滑过渡。

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

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

Taro、uni-app、kbone、WePY、mpvue

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

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

Taro 本身的限制

React 对其语法的支持不够灵活;例如,在操作 JSX 数组时,除了Array.prototype.map以外的方法外

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

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

成长特别快的公司和经历

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

面对压力一般是怎么应对的

之前工作的绩效

团队中的定位、排名如何

字节

字节的话相较于蚂蚁而言少了一次技术面环节,在整个申请流程中总共包含三轮技术面试加一轮HR面试。整个过程采用视频形式进行。其中较为困难的是前两轮环节,在这两轮中应聘者还需要解答几道相关的笔试题目。而第三轮则是主要涉及项目经验交流的内容,在这一环节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()

构建一个批量处理多个URL的接口函数multiRequest()

二面

这一个部分主要是针对之前已经撰写过的内容进行提问,并从中筛选出一些值得进一步深入探讨的问题

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

我可以参考我之前的文章内容深入探究 Function & Object 鸡蛋问题

输出以下代码的结果

复制代码
    Object instanceof Function
    Function instanceof Object
    
    Object instanceof Object
    Function instanceof Function

结果都是 true

手写深拷贝

参考往期文章面试题之如何实现一个深拷贝

如何实现正则的深拷贝

参考我的早期内容, 跳转至GitHub Issues详细讨论了Lodash的具体细节.

模拟实现 Array.prototype.splice

我可以使用我的题库来查看此问题,并已将第158题收入囊中进行学习。

三面

在经过前面两项的审核或确认后, 第三项相对较为容易处理, 主要内容包括与项目的交流, 讨论过往参与的项目及其核心亮点, 同时还要安排后续的工作安排, 包括团队协作中的相关工作.

HR 面

相对容易处理的话题包括分享一些经验交流以及涉及的薪资预期方面。公司目前不实行全体人员的一致通过制度,在整个流程上较为轻松愉快。

面试感想

当前就业市场状况不容乐观。就一二线互联网企业而言招聘需求十分有限,在此背景下裁员公司数量众多。大量岗位被"锁 HC"更是显示出这些岗位难以流动。因此求职者在求职过程中应避免盲目脱岗以规避较高的离职风险。

今年的面试形式与往年相比有所变化,在关注项目核心问题的同时也更加注重候选人对工作内容的理解能力以及在团队协作中的具体表现。值得注意的是,在以往的面试中我们特别关注候选人的责任感和服务意识,在今年这一块依然有较高的重视度;而编程能力作为核心考察指标之一,在以往的基础上要求更为严格。

对于应届毕业生而言,在求职过程中需要注重以下几个方面的积累:首先是掌握基础的技术栈(包括CSS/JS/网络/浏览器/异步/框架/工程化)之外,在项目经验积累和实战能力培养这两个方面还需要下足功夫。唯有不断强化自身实力,在求职中才能获得更好的评价和更高的薪资水平。

说明

面试小程序

最近的小程序已经吸引了近3万人参与使用!它包含多种类型的练习题如编程练习题、算法学习营等,并非仅仅是一些基础的选择或填空题目。目前我们正在致力于扩展题库资源的同时也会定期举办趣味抽奖活动让用户体验更加丰富和完善的功能服务哦!如果觉得不错欢迎提供建议我们会持续优化并完善服务

支持

如果你觉得这篇内容对你挺有启发,我想邀请你帮我三个小忙:

  • 请各位读者在阅读本文时给予「点赞」
    • 请访问我的官网地址 https://muyiy.cn,并期待与您建立长期合作关系。

全部评论 (0)

还没有任何评论哟~