远去哪
一面
4.25 15:00 三十分钟
- 问项目
- React 与 CSS 的结合是有很多种方案的,你能谈谈他们各自的优缺点吗
- 现在有哪些跨域的方法
- JS 中的同步和异步是什么概念
- 出了两个题目问微任务与宏任务的执行顺序
- setTimeout 到整点的时间执行回调吗?为什么不能准确执行
- 你对响应式是怎么理解的
- 现在的主流框架,它们是怎么实现这个响应式设计的呢
- React 全量更新会带来性能损耗,这个问题它是怎么解决的
- 它是通过什么机制来判断这个节点是老的,还是需要更新的呢
- useMemo 与 useCallback 是通过什么机制来判断是否更新的呢
- React hook 为什么不能在条件判断和循环中用呢
- 对 Vue3 与 React 这两个框架,有没有自己的理解
- Vue3 引入组合式 API 解决了什么根本性的问题呢
- Vue 的组合式 API 和 React hook 在执行上有什么区别
- Vue3 可以在条件判断和循环中写组合式 API,你知道为什么吗
- 反问
二面
非常好的一位面试官,感觉像是前辈在教导后辈 😂
4.26 19:00 八十五分钟
- 我刚看你啊就是说你是在那个,字节那边的青训营对吧,你感觉与你没有参加青训营之前做到事情,有什么差别
- 你是怎么解决小组之间的沟通问题
- 这么大的一个项目,你是分模块的对吧,那的话你怎么保证他们的功能是按预期来做的。比如说决定产品或者说对应的人对吧,给你分配的这个功能组件,你怎么知道你要做成什么样;另外一个,怎么知道功能最终完成是 OK 的。从需求到上线,你是怎么控制这个逻辑的。
- 假如说有一个组合逻辑,就拿面包屑举例。假如我这样有个功能是面包屑,再加上某个按钮对吧,或者说再加上你这个滚动条,组成一个新的组件出来,他们两个组件之间是怎么 协作的呢
- 那,你想就是,我举个例子,你这 icon 的话这里面呃,它重不重要?然后呢它会设有哪些功能场景?就实际你使用它的时候,比如我要使用这个 icon 组件,那么它有什么诉求,那我怎么样去满足这个诉求,怎么保持我的 icon 的一个迭代。
- 你想,icon 这东西对吧,他大多数是来自于谁呢?来自于设计师对吧。那么设计师的话,他怎么提供这个 SVG 给你,那么你怎么接入进来。举个例子,我要用这个 icon,用的时候我都要去引这个文件,那我觉得这个不够便捷,或者你看别人组建库应该不是这样子的,就不是一个依赖于 SVG 来做的,而是说我有一套名称对应 SVG 文件的这么一个映射表,然后呢我只是传一个名称,它就能找到文件对应的 SVG。对于 icon 来说,它可能并不仅是实现组件本身,而是怎么在真实的场景里去使用它。我想将这个就是想说明,你做组件的时候要考虑一个易用性,而不是只做一个底层的封装就好了。
- 那你觉得组件库的哪些部分比较复杂呢
- 这里有个核心点在组件的版本,就是组件的版本怎么管理的事情。你有碰到过版本管理相关的东西吗?
- 这个,其实我只是在跟你将一个事情,并不是说考你什么,你懂吗。毕竟你是个实习生,就是我只想了解一下,你对于组件这块有碰到版本管理相关的问题吗?比如说我举个例子,我有一个按钮对不对,现在我有一个功能用到了按钮这个组件,那么这边就有两个点。第一个点就是我按钮的版本升级以后会有功能更新,我怎么通知用到我的按钮这个组件也跟着升级版本;第二点就是说我怎么样能够让它保持兼容关系。
- 组件测试你怎么做的呢?手动写一个用例,还是说做什么逻辑来测这个东西
- 一般一个组 件你会写多少给测试用例,你会覆盖哪些逻辑
- 手动写用例的话,那你这样的话就是,第一次可以这么做这个。比如刚做出来的时候,你的兴致比较高对吧,你可以每一次都测一遍,后续迭代了怎么办,比如你加个功能,你怎么保证你每一次都测到那么多的场景。假设你写了个 10 个场景对不对,或你知道有什么办法,让你这个更轻松一点对吧
- 你想作为程序员是要偷懒的对不对,就像我怎样能够让我自己能更轻松的做很多事情,而不是说纯靠人肉做的事情对吧。特别是做组件库来说的话,是更重要的。
- 你可以讲一下用 CSS 变量实现主题切换的逻辑吗
- 那它的兼容性呢,有考虑过吗
- 再问一下 CI/CD 吧,那你觉得 CI/CD 是什么
- 这样,就是 CI 的话,它是可持续集成嘛对不对。比如说我们前端常见的,我把这代码编译一下对吧,或者说打包一下生成个生成物对吧,这个其实就是 CI 的某个流程场景。只是 CI 可能会包含那些,比如说,代码的风格校验,这些即是 CI 里的一些流程吧,让你代码变得更好的、健壮性更高的一个东西对吧。CD 呢就是说把你这个生成物,部署到服务器上面去,就是持续的部署对不对。CD 就是一个个流程节点去做对应的事情。你想象中的 CD 可能就是把某个生产物件推到服务器上面就好了,但其实不仅仅是这样子啊。举个例子,你可能需要把代码压缩后对不对,生成一个 SourceMap 放到服务器上面去做一个监控的映射,让它开启某个服务。比如说起一个 Docker 容器去做部署,部署完以后再检测一下你对应的数据有没有问题、检测有没有问题,然后再去做对应的切换。如果假如有问题,可能会做报警或者什么逻辑,甚至对它做一个统计,甚至还有灰度这样的东西,这些其实都是 CD 里面的一部分。
- (问另一个项目的一些功能实现)
- 你用到了 Tailwind CSS,那你为什么选它呢
- 那它的缺点是什么呢
- 这其实是一点,它会导致你 HTML 可能会很大,相对来讲。我们没用它,就是原因是因为,我从老的项目改过来时候是很困难的,我从原来 CSS 写法改成这样成本很高。另外一点就是,它会导致 HTML 文件会变大,其他文件可以可以缓存,但是 HTML 是缓存不了的
- Vite 这个东西你有了解过吗,那你觉得它什么更快
- 讲一下 React 的调度
- React Router 这个,它怎么实现的呢
- 我访问一个地址,它为什么能访问到这个路由对应的组件
- 这个 React Query,它是干什么用的呢
- 为什么用它来管理服务端状态呢
- Mobx,你为什么考虑用它,而不是 Redux
- 为什么不用 Context,states 这样的一些东西呢,Mobx 它的优点是什么
- 其实 Mobx 是模仿 Vue 双向绑定的一个逻辑实现的,你懂吧,其实它的好处就在这个。我也不确定啊,反正我之前我的理解是,它是模仿的 Vue 的实现,因为 Vue 的那个双向绑定是很不错的。但是 Redux 的话,它是跟 React 的逻辑是一样的,都是单向流的
- 说到状态管理这东西吧对吧,比如说有两个模块,它们属于兄弟元素,如果不用 Mobx,你怎么去做它们之间的消息传递
- 如果它们的父级很高呢
- 那 Context 的话,它有什么缺点,或者用它的话要注意什么问题
- 那怎么防止其他组件意外修改数据呢
- 你可以传数据对不对,那么你可以传函数对不对,那我就把函数传给它,让它调用我的函数好了,不会让它什么改我 Context 里面真实的数据。比如说我现在有 10 个函数和 10 个数据在里面,我只允许你改某个数据对不对,你调我的时候或者你改我数据的时候,你告诉我你是谁,那我根据它来判断,是不是应该你改或者说什么样的情况。
- 能讲讲柯里化吗
- 它的话,常用来做什么逻辑呢
- 其实主要是就能生成一个通用的一个初始化函数,后续你可以只要传额外的、有差异性的东西进来
- 一个网站,它反馈很慢,那么你应该从哪方面入手优化它
- 渲染的话,光是做这一方面应该是不够的。比如说用户有很多,访问都很慢,你服务器的带宽是有限的对吧,那又怎么办呢,或者你看别的网站是怎么做的
- 你可以讲一下什么是强缓存,用什么逻辑来判断它是强缓存
- 用什么来判断,是强缓存还是协商缓存
- 哪些文件可以做强缓存
- HTML 为什么不可用做强缓存
- 其实也不是不行啊,只是麻烦而已,你要改 nginx,要重启
- 你有见过其他的状态码吗(八股吟唱...)
- 你们前后端怎么沟通呢,就是接口文档用的什么
- 都不是常见的,后端一般常见的就是用 swagger。因为他们这种方案好处在什么,就是他可以做注解的方案,就是说在代码里写注释,注释写完以后它自动会生成对应的接口文档,不用手动维护。
- 写接口文档的话,要么手写,要么通过 swagger 的一个接口去转,因为它要做自动逻辑而不是走这种手动逻辑,手动其实并不不稳妥。因为你想代码跟你的接口文档分两块东西的话,很有可能出现实际代码与文档不符的情况。
- 你了解网络协议有哪些呢(HTTP,HTTPS,TCP,UDP)
- 他们有什么区别呢
- TCP 与 UDP 有什么区别 呢
- 也不是叫那个逻辑,TCP 是要握手后才能去传出对不对,UDP 相对于传出去之后我都不知道你有没有接收到,少了一层,所以它才更快。其实最常见的 UDP 场景是什么,就是以前的 QQ,QQ 用的就是 UDP。QQ 以前的访问量很大嘛对不对,每次用 TCP 的话服务器压力会很大。
- 目前常见的 HTTPS,那么你想想为什么要用 HTTPS
- 为什么它能防止冒充呢
- 为什么签名可以验证身份呢
- (给我解释了一遍)
- 目前常见的是 HTTP2.0,那 HTTTP2 与之前的有什么区别呢
- (解释了一下头部压缩与并发传输)
反问
- 我:您对组件库有什么自己的见解吗
- 我觉得这样的,组件库其实只是前端日常工作中的一小块内容。它并不算特别复杂,复杂的点在,哪些功能你应该封装成组件,程度是什么样的。比如说,你封装的过于规范,那么他就自由度就丢失了对不对;太自由的话,你组件就收不住了,怎么让这两个点达到一个平衡,能让你的组件既能满足业务需求,又易扩展。就是说怎么能让你满足每一次迭代,又能不出问题。比如我改了一个基础的按钮组件,它这个组件升级以后,我怎么知道有哪些组件都依赖这个按钮组件,那么就会引入 monorepo,它带有工作区的概念,它可以帮你管理版本的互相依赖关系,这才是组件的核心点。其实抽象什么的都是小问题,问题在于后续怎么管理它。很多人包括我们都会基于 Ant Design 的某个版本,去自己做一个和自己业务相关的一些封装
- 我们还是用 Webpack,没有用 Vite
- 我:公司还是以稳定性为主 吧
- 也不是以稳定性为主,而是在于,我们考虑的是一个成本的问题。假如说,我把它迁移到 Vite 上面以后,它对我们来说,我们要投入多少的工作量,成本有多大。第二是我们为它付出的成本能不能带来更大的收益,就不是单纯的是为了技术升级而升级,要在升级这技术后能给团队带来什么样的价值。就比如说举个例子,Webpack 比 Vite 要慢,它对于我们来说的差异。比如说一个人对吧,开发的时候,因为 Webpack 慢,导致他一天损失了一个小时,那假如我们有 30 个人,一天就 30 个小时,能算出来一个月要多少钱。把它改成 Vite 需要多少钱,Vite 会提高多少工作效率,以及可能会出现什么问题,这样能算出它的一个性价比。并不是说不能升,而在于我们需要一个机会来做对应的事情
- 前辈有了解 rspack 吗
- 我们其实是有想把 rspack 集成进来的,但我发现它只是 CSR 方面比较快,我们有 SSR 的需求,我们没有接完,只接了 CSR 的方面。我们的目标是能做,但是要花点成本,rspack 还挺快的
- 我:我一直以为要等到真正成熟之后,公司才会考虑
- 这个不一定,其实做什么事情都一样,就是说你对这东西有没有把握,能不能控制住它。像在公司里面,其实它都已经那么慢了,也不差那一会,就比如说不差那十天半个月的,时间对于研发来说,效率没有那么的重要。除非是你能够证明大幅度的提升研发效率
- 那前辈是组内的 leader 吗,感觉前辈看问题非常的稳重
- 我确实是管前端的,但是呢年龄比较大,考虑的会比较多一点。毕竟很多事情的话,要站在老板的角度考虑,毕竟他花钱让我们干活,那么我干的活肯定要有价值,那不是说为了技术而技术,对吧其实每个公司都一样的。