「前端」美团一面面经(已过)
总体体验很好,团子永远这么暖,面试官笑眯眯的,有些答不上来的也不纠结,春天面暑期实习的时候就感觉团子的面试体验是最好的,我觉得他们内部肯定对面试官有培训,而且面完了一个小时就打电话约二面了,我爱团子😇。
一开始没让自我介绍,只让我介绍了我认为成熟度最高的一个项目,项目里用了 GSAP 的动画库,就从动画开始聊起了
- 你了解 GSAP 的动画是如何实现的吗
- 用 js 实现的动画,具体的不太清楚
- 还有什么方式?
- css
- Three.js(项目里用了)可以做动画吗?
- 可以,镜头调度或者物体移动都可以实现动画效果
- CSS 动画, JS 动画和 Three.js 动画有什么区别?
- css 动画使用了 GPU 硬件加速,相对来说性能更好,但交互性比较差,难以做到实时打断等交互;JS 就是反过来,Three.js 就是性能开销更大,毕竟是个 3D 引擎
- 在性能以外的方面,比如说渲染效果上有什么区别?
- 跟面试官纠结了一下什么叫渲染效果,原来说的是流畅度,我答的 CSS 的渲染效果会更好,比如帧率之类的,因为 JS 毕竟跑在主线程上,如果有一些别的任务可能导致 js 动画掉帧
- 了解重排和重绘吗?
- 八股复读
- CSS 和 JS 动画会导致重排吗?
- 像 transform 这样的不会改变文档流的是不会的,相反比如改变大小之类的会导致文档流变化的就会
- 项目里提到的 Sentry 做了性能分析,提了一些指标,问了我分别是什么意思
- 有几个比如 INP 和 TTFB 实在不是很熟悉,面板上给了我就贴上去了,所以大家写上去的性能指标自己一定要至少知道是什么意思😅,还好面试官人不错没纠结
- 请问这些性能指标是怎么测出来的?
- 在 JS 里加入一些监控代码,在对应的时间节点纪录时间然后计算出来
- sentry 给出的性能指标是平均值还是什么?一个开放性问题,你如何收集各种性能数据?怎么分析数据?
- 给定合理范围内有差异化的的硬件指标(比如 CPU 性能和网络状态各异,合理范围就是说像 80%loss 这样的网络环境啥网站都不可能有好性能,就不用考虑这种极端场景了)
- 指标除了平均值以外,还可以使用中位数、1% low 这样的指标来评价大多数人的体验和极端情况下最坏的体验(1%low 这个是平时显卡评测看多了临时胡诌的😅,但我感觉还蛮合理的)
- 分析最坏的情况,针对性的对其进行一定的优化
- 继续追问,比如我们发现一部分用户在初始化渲染上花的时间很长,你如何优化?
- 在自己的测试环境下可以用 performace 标签录制去看哪个任务开销比较大,然后针对性的优化
- 如果是用户打上来的 log 呢?
- 那就根据 log 里的设备类型去判断,根据这类用户的共性和这类用户与别的用户的差异性两个方面去寻找可能发生问题的点,比如这类用户可能普遍 CPU 比较差,那就可以在本地测试过后去尝试优化 CPU 开销最大的部分;如果网络普遍比较差就去优化一些资源大小
- TailwindCSS 和 CSS 有什么区别?
- 以类似行内样式的方式去写样式,不用想类名了,写起来读起来都更清晰,不用来回跳
- 性能上有什么差异吗?
- 作为一个 css 预处理器,他的性能提升基本上局限于优化 css 能做到的范围,比如按需构建可以移除未使用的类,从而 css 文件会更小;同时都会尽量使用性能更好的类/标签选择器而不是高级选择器;
- React 用的什么版本
- 我老是不知道用的什么版本,都回答的最新版,面试官好像还挺喜欢问的,毕竟最近两个版本的 React 引入了 Fiber 架构之类面试官很喜欢问的问题,我后来看了一下是 18.3.1,建议大家自己去看一下 package.json
- 看你还用过 Vue3,有了解过其他 UI 框架吗?
- 主要就了解了这两个比较主流的
- memo, useMemo, useCallback 分别是干什么的?
- 缓存组件/函数的计算结果/回调函数的引用
- 什么场景下需要缓存
- 计算开销很大的组件/函数,以及缓存回调函数可以避免父组件重新创建的时候传递给子组件的回调函数被重新创建,从而让子组件以为自己拿到了新的回调函数,导致无意义的重新渲染
- 子组件怎么判断我拿到了一个新的回调?
- 引用发生改变
- 我把所有的组件都用 memo 包起来有什么问题?
- 缓存本质上是用空间换时间,如果随便使用就会导致内存开销很大,有些组件可能就是个 100 个 a+b 这样的组件,缓存带来的性能提升可以忽略不计,但内存消耗却很大
- 那我怎么判断该不该用 memo?
- 衡量每次重新渲染的成本和缓存的成本,就可以衡量使用缓存的性价比
- 那 memo 具体做了什么事?
- React 的组件更新机制父组件重新渲染的情况下也会重新渲染子组件,memo 将其变为只有在 props 变化的时候才会重新渲染子组件,具体的方式是缓存渲染结果,并只在 props 发生改变时重新渲染
- 发现你 Vite 和 Next.js 都用过,你会做 SSR 吗?
- 我的项目都部署在静态服务器上,所以只用了 SSG,没有 SSR
- Next.js 内部使用了什么工具进行构建?
- 没答出来,搜了一下是 Webpack/TurboPack,说了我知道 Vite 用的是 ESBuild 和 Rollup
- 那这两个工具都做了什么?
- 分别负责开发和生产阶段的构建,讲了一下开发阶段的 ESModule 开发服务器/即时启动/按序编译/热模块替换以及打包阶段的入口/依赖图构建/loader/plugin/输出
- 用过 TS 吗,跟 JS 有什么区别?
- 支持静态类型标注/接口/泛型/枚举
- 手撕:数组拉平(flatten)
- 看你用了for…of循环,他跟 for…in 有什么区别?
- 前者遍历可迭代对象,需要具有Symbol.iterator方法;后者遍历可枚举属性,比如对象的 key
- 在你这个场景下两个都可以吗?
- 都可以
- 了解过 Native 开发和小程序开发吗?
- 玩过 uni-app 和 React Native,但不是很了解
- 如果给你一个 app,你怎么知道它是原生开发还是 web 开发的?
- 如果他卡大概率就是 web 开发的(我问了 gpt,这还真是一条判断标准,剩下的可以通过抓包来看有没有大量的 html/css 之类的)
- 追问下说 web 开发的页面加载的时候基本都是一片白,但是原生开发的只有数据会加载,基本上组件都是就位的,体验上差很多
- 小程序的渲染机制是什么样的?
- 我说就是个套壳的 web 应用
- 有原生的东西吗?
- 我觉得可能有,面试官让我再了解了解,实际上在渲染层完全就是 Webview,只会在通信层面调用一些 native 能力
- React Native 渲染的是 native 还是 web?
- native(人家把 native 都写名字里了,猜也该猜 Native 吧🤣)
- 有没有了解过其他比较热门的语言,比如 rust?
- 有兴趣,但是找工作的角度上没什么帮助,可能拿到 Offer 后再从个人兴趣的角度出发去玩玩,我知道现在有 rust everything 的趋势,我用的很多命令行工具都在被 rust 重写
- 了解过为什么这些工具会被 rust 重写吗?
- 性能强,媲美 C/C++
- 内存安全
- 查了一下还有并发安全、cargo 的工具链支持等
- 反问环节