2年经验面试网易灵犀!太注重工程化了!

SegmentFault

共 6559字,需浏览 14分钟

 ·

2022-02-13 12:45

作者:Sunshine_Lin

简介:「前端之神」的号主江湖人称林三心,现已有100+篇原创文章,全网粉丝高达1w+,面试过超过100+个前端程序员,全网获赞2w+,全网阅读量播放量超过60w,更是B站「面试进阶成为大佬」系列视频的Up主。喜欢分享Vue,React,Typescript等高级前端知识。

来源:SegmentFault  思否社区 


前言



大家好,我是林三心,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心。


今天给大家分享一个大厂的面经——网易灵犀


题目



一面


  • 聊项目

  • webpack和rollup的区别,打包出来的产物有什么区别?

  • postcss的原理

  • webpack babel vue都用到了AST,你是怎么理解AST的?

  • 如何提高webpack的构建速度?

  • 用到了vite了么?为什么会快?

  • npm打包时需要注意哪些?如何利用webpack来更好的构建?

  • 如何在vue项目中实现按需加载?

  • webpack怎么优化前端性能

  • 是否写过loader和plugin,大概思路是什么样的?

  • 实现Array中的reduce方法?


二面


  • 聊简历,聊项目

  • vue中的nexttick的原理

  • vue的响应式原理

  • 小程序的架构

  • 小程序如何跟native层通信的

  • 算法题

要求:

求字符串公共前缀,例如  ['abcaaa''abcddd''abcadad'] ==> 'abc'
  • 算法题

要求:

// 区间合并:
// 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。
// 请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
 
// 示例 1:
// 输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
// 输出:[[1,6],[8,10],[15,18]]
// 解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
 
// 示例 2:
// 输入:intervals = [[1,4],[4,5]]
// 输出:[[1,5]]
// 解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。


解答


一面


  • 聊项目


  • webpack和rollup的区别,打包出来的产物有什么区别?

webpack:代码拆分,按需加载,适用于应用的打包,webpack2后已支持 tree-shaking
rollup:所有资源打包到同一个地方,一次性加载,适用于库的打包,支持 tree-shaking


  • postcss的原理?

第一步:调用postcss相关的loader并传入参数
第二步:将css文件转成AST
第三步:根据第一步的参数,对AST进行修改枝叶
第四步:将修改后的AST转化为正常代码
第五步:输出代码,交给下一个loader处理

  • webpack babel vue都用到了AST,你是怎么理解AST的?

现在的很多工具,例如webpack、vite、eslint、babel等等都离不开一个东西——AST。AST是正常代码,使用工具,根据不用的代码节点类型,转化成的一个JSON格式的数据

  • 如何提高webpack的构建速度?

后面会单独出一篇文章

  • 用到了vite了么?为什么会快?

esbuild预构建依赖:代码分为 依赖 和 源码 , 依赖 就是那些npm包,一般不会变,缓存起来; 源码 是会频繁更改的那一部分代码
利用浏览器可以运行 ES Module ,将代码转成 ES Module 后交给浏览器,把压力放在浏览器那边,从而提高项目启动速度
按需加载:浏览器根据 ES Module 去使用http请求,按需加载所需页面
利用协商缓存,缓存文件,无变化的文件不需要重新加载


  • npm打包时需要注意哪些?如何利用webpack来更好的构建?

后面会单独出一篇文章


  • 如何在vue项目中实现按需加载?

箭头函数 + import


  • webpack怎么优化前端性能?

后面会单独出一篇文章


  • 是否写过loader和plugin,大概思路是什么样的?

loader
loader 的作用是用来处理 非js文件 ,它是一个函数,实现原理是:将所需处理的文件内容使用相应的转换插件转成 AST(抽象语法树) ,然后按照loader规则对于这个 AST 进行处理,处理之后再转成原本的内容格式,然后输出,达到了处理内容的效果
plugin
plugin 的作用是拓展webpack的打包功能。它是一个类,使用方式是new Plugin(option),这个类内部有一个 apply 方法,打包时会执行这个方法,且这个 apply 方法接收的参数中有一个 plugin 方法,此方法中有许多钩子函数,使用这些钩子函数可以在不同的打包阶段做一些事,例如修改文件,新增文件,删除文件等等


  • 实现Array中的reduce方法?

Array.prototype.sx_reduce = function(cb, ...args) {
  let pre, start = 0
  if (args.length) {
    pre = args[0]
  } else {
    pre = this[0]
    start = 1
  }
  for (let i = start; i < this.length; i++) {
    pre = cb(pre, this[i], i, this)
  }
  return pre
}

二面


  • 聊简历,聊项目


  • vue中的nexttick的原理?

nexttick首选微任务,然后才是宏任务。内部设置一个回调队列,将渲染watcher还有用户自定义的nexttick事件放到这个队列里,并异步执行循环这个队列,达到异步更新


  • vue的响应式原理

使用Object.defineProperty拦截对象属性的get和set,再通过dep收集依赖的Watcher,当属性更新时触发set,并触发notify函数通知dep中的watcher进行更新。watcher分为渲染watcher、用户watcher、计算watcher。

缺点是:

  1. 有对数组进行拦截get和set,而是修改原型方法。

  2. 没有兼顾对象新增属性的响应式处理

  3. 费性能,毕竟是通过递归拦截

  • 小程序的架构

不懂


  • 小程序如何跟native层通信的

不懂


  • 算法题

要求:
求字符串公共前缀,例如  ['abcaaa''abcddd''abcadad'] ==> 'abc'

解题:
var longestCommonPrefix = function (strs) {
  if (!strs.length) return ''
  if (strs.length === 1) return strs[0]
  const start = strs[0]
  let prefix = '',
    pre = ''
  for (let i = 0; i < start.length; i++) {
    prefix += start[i]
    if (strs.some(str => str.indexOf(prefix) !== 0)) return pre
    pre = prefix
  }
  return pre
};

  • 算法题

要求:
// 区间合并:
// 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。
// 请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
 
// 示例 1:
// 输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
// 输出:[[1,6],[8,10],[15,18]]
// 解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
 
// 示例 2:
// 输入:intervals = [[1,4],[4,5]]
// 输出:[[1,5]]
// 解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。

解答:
const merge = function(intervals) {
  if (intervals.length === 1) return intervals
  intervals.sort((a, b) => a[0] - b[0])
  const res = []
  let i = 0, j = 1
  while(j < intervals.length) {
    const iArr = intervals[i]
    const jArr = intervals[j]
    if (iArr[1] >= jArr[0]) {
      intervals[i] = [Math.min(iArr[0], jArr[0]), Math.max(iArr[1], jArr[1])]
      j++
      if (j === intervals.length) res.push(intervals[i])
    } else {
      res.push(iArr)
      i = j++
      if (j === intervals.length) res.push(jArr)
    }
  }
  return res
};

  • 算法题

要求:
// 仿模板字符串处理功能,
// 如 "Title: ${ title }, MainArtist: ${ artist[0] }, Album: ${ album.name }",
// {
//     title: '珊湖海',
//     artist: ['周杰伦''梁心颐'],                                 
//     album: {
//         publishTime: '2006-11-1',
//         name: '十一月的萧邦'
//     }
// };




点击左下角阅读原文,到 SegmentFault 思否社区 和文章作者展开更多互动和交流,扫描下方”二维码“或在“公众号后台回复“ 入群 ”即可加入我们的技术交流群,收获更多的技术文章~

- END -


浏览 16
点赞
评论
收藏
分享

手机扫一扫分享

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

手机扫一扫分享

分享
举报