字节前端二面凉经,无偿分享给兄弟们

字节前端二面凉经,无偿分享给兄弟们
最新回答
风向决定发型

2020-06-27 04:22:20

字节前端二面问题解答如下

1. JS中一个函数返回另一个函数,是否叫高阶函数?
  • 。高阶函数的定义是满足以下任一条件的函数:

    接收一个或多个函数作为参数;

    返回一个函数作为结果。例如:

    function outer() { return function inner() { console.log('高阶函数示例'); };}
2. 块级元素和行内元素绝对居中,用Flex如何实现?
  • 块级元素:.parent { display: flex; justify-content: center; /* 水平居中 */ align-items: center; /* 垂直居中 */}
  • 行内元素:需先将其设为display: inline-block或flex子项,再应用上述Flex布局;或直接对父容器使用Flex并设置子项为margin: auto(需子项为块级或inline-block)。
3. 节流(Throttle)与防抖(Debounce)详解及使用场景
  • 节流:固定时间间隔内只执行一次函数,适用于高频触发但无需实时响应的场景(如滚动事件、窗口调整)。function throttle(fn, delay) { let lastTime = 0; return function() { const now = Date.now(); if (now - lastTime >= delay) { fn.apply(this, arguments); lastTime = now; } };}
  • 防抖:触发后等待一段时间再执行,若期间再次触发则重新计时,适用于输入框搜索、按钮连续点击等场景。function debounce(fn, delay) { let timer = null; return function() { clearTimeout(timer); timer = setTimeout(() => fn.apply(this, arguments), delay); };}
4. Chrome插件相关问题
  • 插件文件结构

    manifest.json:配置文件,定义插件元数据、权限、入口脚本等;

    background.js:后台脚本,处理全局逻辑;

    content.js:注入页面的脚本,可操作DOM;

    popup.html/js:插件弹窗界面及逻辑。

  • 劫持/篡改请求

    可通过chrome.webRequestAPI拦截请求,但需在manifest.json中声明webRequest和webRequestBlocking权限;

    限制:仅能修改HTTP头或阻止请求,无法直接修改请求体(需结合content.js覆盖原生XMLHttpRequest或fetch)。

5. Base64编码是否会导致文件变大?
  • 。Base64将3字节二进制数据编码为4字节ASCII字符,体积增加约33%,适用于小文件(如图标)内联嵌入,但大文件(如视频)会显著增加传输负担。
6. Keepalive实现原理及数据结构
  • 实现思路

    维护一个缓存池(如Map或对象),存储已挂起的组件实例;

    通过唯一标识(如name)匹配组件,复用时直接从缓存中获取。

  • 数据结构

    通常用WeakMap(避免内存泄漏)或普通Map存储组件实例;

    示例:

    const cache = new WeakMap();function keepAlive(vnode) { const key = vnode.key; if (!cache.has(key)) cache.set(key, vnode.componentInstance);}
  • 注意事项

    需合理设置缓存大小,避免内存占用过高;

    及时清理无效缓存(如组件卸载时)。

7. WeakMap的作用及深拷贝中的应用
  • WeakMap:键为弱引用对象,值可为任意值,适用于需要自动垃圾回收的场景(如缓存、私有属性存储)。
  • 深拷贝优化

    常规递归深拷贝可能因循环引用导致栈溢出;

    用WeakMap记录已拷贝对象,遇到循环引用时直接返回缓存结果,避免重复拷贝。

    function deepClone(obj, map = new WeakMap()) { if (map.has(obj)) return map.get(obj); if (typeof obj !== 'object' || obj === null) return obj; const clone = Array.isArray(obj) ? [] : {}; map.set(obj, clone); for (const key in obj) clone[key] = deepClone(obj[key], map); return clone;}
8. HTTP/1.1的Keep-Alive功能及原理
  • 功能:复用TCP连接,避免每次请求都重新建立连接,减少延迟和资源消耗。
  • 原理

    客户端在请求头中添加Connection: keep-alive;

    服务器响应后不立即关闭连接,而是保持一段时间(可配置);

    后续请求复用同一连接,直到超时或主动关闭。

  • 复用规则

    同一客户端与服务器间的多个请求可复用;

    不同域名或端口的连接需重新建立。

9. HTTP/2.0新特性
  • 多路复用:单个连接并行处理多个请求/响应,避免队头阻塞;
  • 头部压缩:使用HPACK算法压缩HTTP头,减少传输量;
  • 服务器推送:服务器可主动向客户端发送资源(如CSS/JS),无需客户端请求。
10. Promise中断问题
  • 无法直接中断:Promise设计上不可取消,但可通过以下方式模拟:

    使用标志位控制后续操作(如.then()中检查标志);

    结合AbortController(需配合fetch等支持取消的API)。

    const controller = new AbortController();fetch(url, { signal: controller.signal }) .then(response => response.json()) .catch(err => { if (err.name === 'AbortError') console.log('请求已取消'); });controller.abort(); // 中断请求
11. TypeScript类型处理
  • 避免使用any

    优先使用联合类型、类型守卫或泛型;

    示例:用unknown替代any,再通过类型断言或类型保护处理。

  • unknown与any

    unknown更安全,需显式类型检查后才能操作;

    不可直接互换,需通过断言(如as)转换。

  • 永远返回错误的函数:function fail(message: string): never { throw new Error(message);}
12. Vite的打包工具
  • 开发阶段:基于ES Module原生导入,无需打包;
  • 生产阶段:默认使用Rollup打包,支持配置其他工具(如Webpack)。