这篇文章主要是关于前端面试相关内容的分享,包括群友的阿里面经,涵盖 ES6 转译、工程化打包工具、命令行工具实现、框架特点、开源项目、性能优化、监控等方面的问题及回答,还涉及组件库开发维护的诸多问题及解决方案,如版本管理、适配迭代、臃肿处理等。
关联问题: 前端工程化难点在哪 组件库优化咋实现 虚拟列表有何局限
开局闲聊
老规矩,先闲聊一下,本来都已经特别不想写这个系列了,但想着把做事还是有始有终,这期是分享一下群友的面试内容。
标题也没其他意思,就是字面意思劝退,难点确实挺好的。
然后有的问题我自己尝试答一下。
开始
来自群友的阿里面经
1、 什么时候开始做前端
略
1.1、项目开发中都是es6,实际浏览器里面运行的时候是不是要做一个处理?
1.2、正常前端里面一般用什么来做这个事情
em,其实现在很多的浏览器都已经支持ES6的解析了,但因为并不是所有的API和特性都支持,一方面是通过那些转译器,例如Babel去把ES6转译成ES5,然后浏览器的编译器去生成字节码,解释器去生成机械码,就落到执行上洛。
Babel的话能做的事太多了,其中的babel其实可以拆成几个包,你可能在编写插件,loader,向下兼容,垫片,上报等等等。这个根据实际需求来把。
1.3、class,里面有一些成员变量和方法,转成es5后,浏览器里面实际运行是什么样
实际就是转译成构造函数了,毕竟class是构造函数的语法糖。对于成员就是prototype下对象的属性,静态属性直接xxx.这种,class类的构造函数就是构造函数本身。呜,我没具体看过class在babel编译下会是什么样。
1.4、call 使用的场景是什么样
对象寄生、绑定参数立即调用、改变指向。好像我只能答出这些了。
2、刚说到babel转换,那工程化打包用什么工具
呜!多鸭,rollup,webpack,vite,swc,turbopack还有马上的rspack等。
2.1、webpack 中 babel 属于什么,以什么样的方式存在?
属于一个内置插件(好像是把)。
2.2、webpack中具体要配哪些东西?
解析资源的一系列Loabder,代码转译,代码压缩,垫片,排除cdn,系列优化插件。
2.3、 webpack 怎么匹配到对应的loader的
rules中,正则表达式去匹配文件,然后调用对应的Loabder。resolve.extensions,还有就是webpack的路由加载了,就类似行内路径那种。
3、如果要开发一个类似 cli 的交互命令行工具怎么实现?
3.1、node 里面怎么做命令行交互
Commander、CAC好像是现在最火的把,有点跑题prompts去与用户交互输入或者下拉等,然后如果是那种命令式的在后面跟option,入参传入执行的函数,然后指定Bin目录,把files也指定好也是需要的。
3.2、你平时有负责工程类工具的研发吗,node层面的工具?
有点,typescript to graph,json to Typescrips等,其实小工具还做了挺多了,都是从大需求上拔下来的。
3.2.1. 自定义lint 的工具怎么做的,就官方会有一些rules,怎么做一个自定义的一个 rules ?
我会把官网推荐的rule拉下来以extends这样的形势,然后就overrides覆盖上面对应不同类型的文件去增加和删除一些规则。
4. react框架的特点是什么,跟传统的框架对比?渲染层面有没有什么特别,跟document 的方式有什么区别吗?
答得有点多了这问题,略。
4.1. 追问: 虚拟dom变成实际 dom 是怎么发生的?或者vue,或者其他框架也行,怎么实现虚拟dom 和实际dom 的分离和衔接?
呜,这个问题挺开放的,就其实是在缓冲层(虚拟Dom)内存中表示网页结构,通过diff算法,计算出最小的变化量,就再最小化真实dom操作。感觉现在有虚拟dom的框架都是这个思路,只是实现上不同把,react更像是一种快照的思想,新旧树对比。
4.2. 为什么同样的代码,能跑个RN版本又能跑个 web版本?为什么RN也能跑前端 react的代码?RN 和 react写 web 的差别是什么?
其实我两天在恶补Rn,其实就是组件 render 得到 element,接下来形成新的虚拟 DOM ,都是在 js 层完成的,而最后涉及到渲染绘制的时候,在通过不同的平台做差异化处理就可以了,比如在 web 交给浏览器去绘制,在移动端交给Native去绘制,再加上独立的事件系统去磨平差异。
面对不同环境,不同的引擎,JSCore,V8(得益于JSI框架的引擎切换,比如在 iOS 平台运行的 JSCore ,在 Andriod 中运行的是 v8 引擎,好像说错了吗,现在是Hermes),对于两端的原生组件再次封装形成的核心组件,默认纵轴,大量的社区库等等等,算了不丢人了,学艺不精。
忘了问是哪家了
1. 笔试:根据id 和 parentid 将数组数据转成嵌套结构
2. 白屏检测有了解吗?图片是怎么判断白屏的?
3. 页面性能监控以及接口监控
5. 讲一下工作中做的比较有意思的东西,或者说有一些主动发起推进去解决业务问题、痛点的事情
其实这里我想说个事,就是我经常会被问到,你做这个开源项目的动力是什么,对你的实际业务是否有反馈,是怎么去反馈的,希望大家自己想想写的简历的开源项目面对拷问的时候怎么办。
6. vue 是怎么做性能优化的? 从1递增到10000,不可能每个都渲染一遍,是怎么处理的?
题目有点迷,没更多上下文了。
7. 工程化相关,.vue ,.tsx,.ts 这些文件是怎么编译成用户可以访问的页面的?越细越好。可以先讲一下大体有哪几步,然后再讲细节,比如先进的API怎么在旧版浏览器里面运行。
上篇文章说到过vue从编译开始的整个流程,先进api要不转译要不就垫片。
8. vite 是用什么去编译的?
分环境,开发环境esbuild,去作为预构建bundle、单文件编译,可选的代码压缩工具,生产环境rollup。
10. sourcemap 有了解过吗(写了监控系统),讲一讲是什么?在生产环境下,怎么去使用,讲一下这个流程。
sourcemap 是关联编译后的代码和源码的,通过行列号映射,在源码末尾可以加一行路径去解析sourcemap,运行时会关联到,监控系统的话,就这样在生产打包后把sourcemap传到你的监控后台,然后本地删掉,需要调试的时候vscode指明路径和userdir。然后也有sourcemap这个库可以去消费和生成sourcemao。其实如果是自研监控的话,会有生成sourcemap和反解的两个过程
11. 搜索框远程搜索要保证可用性要考虑的点?
频率过快的防抖?防止SQL注入?接口报错的异常处理?搜索记录和搜索结果的缓存?搜索参数的设置?结果排序?性能? 我大概就只能想到这些了。
12.(讲到了监控),监控是怎么实现的
略,掘金多的是。
12.1 监控会展示什么信息
报错信息,堆栈信息,时间,接口信息,操作人人等。尽可能在不影响性能的情况下详尽。
12.2 如何将 try catch 里面的错误也做到被动上报里面去,怎样用一个侵入式最小的方式实现这个
最开始第一眼看,不就是里把catch的错误也上报吗。唔!被动鸭,babel的ast节点中的catch节点类型,找到它,然后在traverse去添加上报函数。em,算了这题我不会,我有点没理解到这个问题里的被动(还是自动)上报和最小侵入。
13 多页和单页的区别和各自优缺点
略
14. 按需加载的时候,HTML 上会提供一些标识,比如 pre-load 和 pre-fetch,你知道这是干什么的吗
pre-load是将某些资源在用户请求资源之前进行预先加载,pre-fetch是当浏览器或者用户未来可能请求的资源加载到缓存中,以便在用户真正请求资源时可以更快地访问和加载
15.笔试:动态规划(爬楼梯)
15.1 讲一下解题逻辑
16.通过什么方式学习和提升自己
略
17有没有特别喜欢的公众号或者大佬
略
18讲一讲最近看的比较有意思的知识点或者技术
略
马消
1、js垃圾回收机制
略。
2、原型和原型链
略。
3、如何最快的执行垃圾回收机制
这个有意思了,是问的代码细节吗,直接把变量设置为Null,断开引用,node的话手动触发global.gc()。我其实有点迷茫,正常的思路难道不该是处理好该断掉的东西剩下的交给浏览器吗。 总不能就是问增量标记清除法,使用复制算法,分代收集等这些把。
4、防抖和节流
略
5、组件库的开发和维护
唔,可以从文档、打包、组件设计、版本管理、限制、CI/CD、断言测试、组件库类型这些方面去说,开放题。
6、架构设计要考虑什么
其实我觉得,所有架构的最终目的都是降低系统复杂度,提高易用性和性能。再多不行了,积累不够,架构我感觉是一个解决方案的积累,也是程序员最宝贵的财富。
7、组件库版本管理如何做
我不允许都2023年了前端还不知道语义化版本
8、如何解决组件库适配迭代频率很高的问题
唔,这个问题是指的什么,有必要的更新很正常把,是说的用工具和脚本还有自动化测试来管理组件库,自动文档更新,定时拉取这样子吗。适配迭代频率高?就开源把,众测,众改,把CI/CD流和测试脚本搞好?
可能我也没get到点伤。
群友前端白茶:我只能给出他想问的场景可能是,组件库开发协同人数较多,或者是碰到类似vue2升3,框架大升级,技术翻新,重构的这种情况。分两个方面讨论,一个是适配,组件库创建之初应该确定好适配的具体内容,是适配小程序、H5、浏览器,还是跨端,我认为如果关于适配在频繁修改的话,那么组件库的立项都有问题了,如果时间充裕,应该推到重做。如果时间不够,那么应该需求最佳解决方案,比如使用通用Api、无兼容性写法等手段。如果是多人协同开发导致的,应该制定规范的开发流程,定时定量更新,这个我也建议参考美团技术文档他们的发版模式。
9、如果组件库一个组件长时间没有更新或者后续没有项目使用了,该如何解决
群友:首先你得知道这个组件为什么长久没有更新,这类组件要么就是业务需求极少,要么就是有新的组件可替代,要么是为业务而设计的组件,但是后面又没有相关的业务,自然这个组件就被没人用了,怎么解决?为什么要解决,不用解决。
群友前端白茶:长时间不更新和后续项目不再使用,均代表该组件的生命周期已经快到尾声。视该组件重要程度,可以决定是停止维护、从组件库中剔除,亦或者该组件和其他组件功能类似,但表现不好,可以进行重构或者优化。
但其实把,现在的组件都是按需引入了,感觉留在那并不是什么问题。
10、如何解决组件库不停的添加组件导致组件库臃肿的问题
1、检查组件库中是否存在一些冗余的组件,例如旧版的组件或已经过时的组件等等,提出解决方案,重构Or干掉,是否需要资源等。
2、更新组件库的依赖管理,使用更高效的依赖管理工具(pnpm),使组件库变得更易于管理。
3、使用新的构建工具,可以帮助更快地构建组件库;。
4、组件库分层洛,业务组件,基础组件,自定义Hook,工具类等。
5、使用统一的代码规范,保证组件库的质量,减少后期维护和维护成本。
6、及时通知、详细的文档!!!!!!
11、table渲染,同步加载,数据量很大如何展示和渲染,解决方案有哪些
虚拟列表,懒加载,做缓存,增量更新。
说到底咋们不能分页吗?(我就吐槽一下,因为上面的方案或多或少都会有一些体验丧失,比如虚拟列表的移动端抖动参考掘金移动端列表,懒加载和增量更新始终会让dom节点递增页面内存变大,缓存不易于正确的管理状态等)
12、table数据量几十万,有复选框checkbox和table行可编辑表单,如何解决状态保存和渲染问题。
每次其实一提到这个十几万夸张的数据,就会想到虚拟列表,对于数据可以放在indexDb,而对于状态来说。
这个其实因为正常来说我们在页面上去编辑一个东西,是只存在一个焦点的,当一个输入框的焦点激活则其他的输入框应该就是失活,实际上如果保存是编辑的状态我们只需要以行列去记录,在虚拟列表滚回去的时候通过高度去(一般来说表格高度其实也比较好计算)计算行当滚到了记录的位置,就使得编辑框激活,实际上就是在管理激活的那一个焦点所在的行列何时去重新计算,何时去缓存这样。
而对于复选框,则是维护一个idArr和indexDb里的数据做映射(信息量有点少)。
群友前端白茶:处理这个问题,你永远记住,你的页面可视区只有那么大,不可能一次性渲染。后来出来了以下拉加载的第一代虚拟列表,可是此类虚拟列表仍然导致了DOM节点太多,性能依旧有问题。再后来的解决方案是,只渲染可视区的动态列表(可参考抖音)。如果是遇到大数据存储,可以看看h5的indexDb。但是京东在无限累加DOM节点的过程中,依旧实现了非常高性能的页面渲染,这个我就没有去深入研究了,大家可以看看京东移动端的DOM树结构
群友猜测:复用了dom 实现累加,dom属性都基本一致 如果我们把 单个dom中百分之90以上的同样属性取出来 。dom说白了就是一个object modal,合理操作指针。应该怎么做都OK
结束
本来还有好多的,就一大堆大厂中厂,都快凑够1w字题目了,但我接下来段时间太忙了,这事确实有点费时间,就到这把。
果然吗,约不到面试的只针对我们这些菜的,人家天天面哎!就这样把心累了。加群看沸点。