+ {items.map((item, index) => (
+
handleClick(item)}>
+ {item.name}
+
+ ))}
+
+ );
+};
+```
+
+A. 使用 item.id 作为 key 而非 index
+B. 使用虚拟滚动
+C. 使用 useMemo 包裹 items
+D. onClick 使用 useCallback
+
+**正确答案:** ABD
+**作答答案:** ABD ✅
+
+> [!TIP] 🔑 为什么不选 C?
+> `useMemo` 包裹 items 并不能直接优化列表渲染性能——items 来自 props,其变化由父组件决定。关键在于 **key 稳定性**(A)、**渲染策略**(B)和**事件处理器引用稳定**(D)。
+
+---
+
+#### 4. useEffect + 键盘事件监听
+
+【多选题】关于下面代码说法正确的是?(4分)
+
+```js
+useEffect(() => {
+ const onKeyDown = (e) => {
+ const userAgent = navigator.userAgent;
+ const isMac = /Macintosh|MacIntel|MacPPC|Mac68K/.test(userAgent);
+ if ((isMac && e.metaKey && e.key.toLowerCase() === 'k') ||
+ (!isMac && e.ctrlKey && e.key.toLowerCase() === 'k')) {
+ e.preventDefault();
+ inputRef.current?.focus();
+ }
+ };
+ window.addEventListener('keydown', onKeyDown);
+ return () => window.removeEventListener('keydown', onKeyDown);
+}, []);
+```
+
+A. 在 Mac 设备上按下 Command+K 键,或在非 Mac 设备上按下 Ctrl+K 键时,让 inputRef 对应的输入框获取焦点
+B. 该 useEffect 仅在组件挂载时执行一次,因为其依赖数组为空
+C. 清理函数会在组件卸载时执行,用于移除添加的 keydown 事件监听,避免内存泄漏
+D. 清理函数的主要作用是阻止键盘事件的默认行为
+
+**正确答案:** ABC
+**作答答案:** ABCD
+
+> [!FAIL] 💔 易错点
+> **D 是错误的**:`e.preventDefault()` 阻止的是浏览器默认行为(如 Cmd+K 的搜索框聚焦),而清理函数 `removeEventListener` 的作用是**移除事件监听器本身**,二者职责完全不同。
+
+---
+
+#### 5. GIF 埋点 vs AJAX
+
+【多选题】相比较 AJAX,有些公司前端监控都喜欢用 GIF 做埋点上报,以下哪些是 GIF 的优势?(4分)
+
+```js
+// GIF 方案
+const report = (data) => {
+ const img = new Image();
+ img.src = `https://log.example.com/track.gif?data=${encodeURIComponent(JSON.stringify(data))}`;
+};
+
+// Ajax 方案
+const report = (data) => {
+ fetch('https://log.example.com/track', {
+ method: 'POST',
+ body: JSON.stringify(data)
+ });
+};
+```
+
+A. GIF 请求不需要等待响应,发送即走
+B. GIF 可以跨域,不受 CORS 限制
+C. 页面卸载时 GIF 请求不会被取消
+D. GIF 体积最小(1x1 像素)
+
+**正确答案:** ABD
+**作答答案:** ABD ✅
+
+> [!NOTE] ℹ️ 为什么不用 C?
+> 页面卸载(unload)时,`navigator.sendBeacon()` 可以保证请求发送,但普通 `