校招 未知部门 / 前端 / 一面
[面试日期] 2024-08-15 [面试时长] 未知
[学校背景] 东南大学 | 985 [学历背景] 未知
[发布人] 面试之星官方收录
<h2>「前端」快手一面面经</h2>
<h2>面经</h2>
<p>一开始简单聊了一下项目,问我 react 和 Vue 哪个比较熟,我说 React,然后就开始问我 React 面经了</p>
<ol>
<li>React 有哪些 Hooks?
<ol>
<li>答了useRef, useState, useMemo, useCallback</li>
</ol>
</li>
<li>你了解类组件的生命周期吗?
<ol>
<li>只用过函数组件,没答上来</li>
<li><strong>其实跟 Vue 一样,挂载/更新/卸载(同时也提供一些生命周期钩子)</strong></li>
</ol>
</li>
<li>对于 React 的组件,我希望在挂载之后执行一段逻辑,应该写在哪儿?
<ol>
<li>写一个 watchEffect,放在回调里,依赖数组传一个空的</li>
</ol>
</li>
<li>那如果希望卸载的时候执行呢?
<ol>
<li>在这个回调的 return 里写一个函数体</li>
</ol>
</li>
<li>Hooks 有什么限制吗,比如不能在什么场景下用?
<ol>
<li>不能在 if 和 for 里写,因为 React 的响应式实现严格依赖 Hooks 的调用顺序来管理状态,if/for 里写会导致这个顺序发生改变</li>
</ol>
</li>
<li>继续追问:具体是怎么影响的?
<ol>
<li>答的不太好,其实是因为 <strong>React 依据 Hooks 的调用顺序来识别每个 Hook,一但这个顺序发生改变可能导致状态错位等问题</strong></li>
</ol>
</li>
<li>React 在什么地方保存这个 Hooks 的顺序?
<ol>
<li>那更是答不出来了</li>
<li><strong>React 在 Hook 调用栈追踪了每个组件在一次渲染中调用的所有 Hooks,每当组件渲染时,React 就会开始重新填充这个栈;由于 Hook 的位置是固定的,就可以通过索引去匹配到之前存储的状态和副作用x</strong></li>
</ol>
</li>
<li>之前提到的 useCallback 和 useMemo有什么区别?
<ol>
<li>前者用于缓存回调函数,避免匿名的回调函数被重新创建,或者传递给子组件时导致子组件重新渲染;</li>
<li>后者用于缓存计算结果,只在依赖项变化时重新计算</li>
</ol>
</li>
<li>用过 useLayoutEffect 吗?
<ol>
<li>没用过</li>
<li><strong>就是一个在 DOM 发生改变后,页面重绘前触发的一个 Hook</strong></li>
</ol>
</li>
<li>React 组件通讯有几种方式?
<ol>
<li>父子通讯:传 state, setState</li>
<li>兄弟通讯:提升状态到父组件</li>
<li>深层通讯:Context</li>
<li>复杂的状态管理:Redux</li>
</ol>
</li>
<li>你提到了 Redux,那 Redux 的更新是怎么触发视图更新的?
<ol>
<li>没答上来</li>
<li><strong>Action 被 Dispatch</strong></li>
<li><strong>Reducer 处理 state</strong></li>
<li><strong>store 更新并通知所有订阅者</strong></li>
<li><strong>通过 react-redux 的 connect 或 useSelector 来通知 React 组件发生改变(最重要的其实是这一点)</strong></li>
</ol>
</li>
<li>你了解事件总线吗?
<ol>
<li>没答上来</li>
<li><strong>通过一个中央总线来管理和分发事件,通过在中央总线上订阅发布事件,从而避免复杂的组件间通讯</strong></li>
</ol>
</li>
<li>了解 React18 的 Fiber 架构吗?
<ol>
<li>也没答上来</li>
<li>这个一句两句也说不清楚了,贴个链接吧<a href="https://gw-c.nowcoder.com/api/sparta/jump/link?link=https%3A%2F%2Ffe.azhubaby.com%2FReact%2FFiber.html">https://fe.azhubaby.com/React/Fiber.html</a></li>
</ol>
</li>
<li>我说我比较熟悉 Vue3 的性能优化手段,面试官说你可以说说
<ol>
<li>Proxy 代替 getter/setter</li>
<li>使用 patch flag 标记更新内容,依赖数组追踪依赖,加上树结构打平,实现了高效的 diffing 算法</li>
<li>静态提升、事件缓存和 slot 生成优化</li>
</ol>
</li>
<li>你提到 Proxy 比 getter、setter 性能更好,那好在哪儿?
<ol>
<li>对于大型的对象,proxy 可以直接对整个对象进行代理,但 getter、setter 需要遍历整个对象去添加 getter、setter</li>
</ol>
</li>
<li>Proxy 是深层还是浅层的?
<ol>
<li>答了 reactive 反正是深层的</li>
<li>又追问了 Proxy 呢?答成了深层的,但应该是<strong>浅层的</strong></li>
</ol>
</li>
<li>了解过 Vue2 中数组是怎么代理的吗?
<ol>
<li>没有</li>
<li>Vue 2 通过<strong>拦截数组的原型来实现响应式(一般使用 Object.defineProperty,但对于数组这个方法不能拦截数组的索引变化或者方法)</strong></li>
</ol>
</li>
<li>ES 6 中 Promise 有哪些方法?
<ol>
<li>all, catch, finally, then</li>
</ol>
</li>
<li>追问了 all 方法里 catch 行为,如果一个 promise 被拒绝了,还会等待其他的吗?
<ol>
<li>不会</li>
</ol>
</li>
<li>then 方法是会每一个 Promise 完成了执行一次,还是等所有 Promise 执行完了再执行一次?
<ol>
<li>后者</li>
</ol>
</li>
<li>了解 WeakMap 吗?
<ol>
<li>WeakMap 与 Map 不同的点在于前者只能用对象类型作为 key,并且是弱引用的,所以不提供遍历方法,且一旦作为 key 的对象失去引用就会被垃圾回收</li>
</ol>
</li>
<li>聊聊箭头函数?</li>
<li>了解 V8 的垃圾回收机制吗?
<ol>
<li>聊了比较简单的引用计数法垃圾回收机制,聊了这个算法会受循环引用的限制;</li>
<li><strong>现在的浏览器使用的是标记-清除算法,即会从根出发,所有无法从根取得的对象都会被垃圾回收</strong></li>
<li>详细的可以参考这个:<a href="https://gw-c.nowcoder.com/api/sparta/jump/link?link=https%3A%2F%2Fdeveloper.mozilla.org%2Fzh-CN%2Fdocs%2FWeb%2FJavaScript%2FMemory_management">https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Memory_management</a></li>
</ol>
</li>
<li>开始问 css,怎么居中一个元素?</li>
<li>css 中的定位</li>
<li>手撕:
<ol>
<li>手写一个 compose 函数,返回一个函数,能够对传入的不定量个函数进行链式调用</li>
<li>二叉树的 Z 型遍历(一层从左到右输出,一层从右到左输出)</li>
</ol>
</li>
</ol>
<h2>总结</h2>
<p>大部分问题就算答不出来也能跟面试官聊两句,有些问题提前准备到了但是没有准备的那么深,有的问题明明看过文档,但还是答的不够完善;总体来说八股部分还算过得去,手撕也很快,看起来面试官还是比较满意的,希望后续能收到二面吧</p><a>#快手#</a><a>#秋招#</a><a>#前端#</a>
AI 推荐面试题
