[{"data":1,"prerenderedAt":1072},["ShallowReactive",2],{"\u002F2026\u002F20265161":3,"surround-\u002F2026\u002F20265161":1061},{"id":4,"title":5,"body":6,"categories":1038,"date":1040,"description":1041,"draft":1042,"extension":1043,"image":1044,"meta":1045,"navigation":1047,"path":1048,"permalink":1044,"published":1044,"readingTime":1049,"recommend":1044,"references":1044,"seo":1054,"sitemap":1055,"stem":1056,"tags":1057,"type":1058,"updated":1059,"__hash__":1060},"content\u002Fposts\u002F2026\u002F20265161.md","携程暑期面经1",{"type":7,"value":8,"toc":1006},"minimark",[9,17,24,93,99,158,164,186,196,202,208,260,266,311,317,322,369,375,381,395,401,431,437,440,446,452,455,460,491,497,517,523,537,543,572,578,644,651,660,666,696,702,708,714,733,736,768,775,794,804,810,836,842,848,886,892,922,928,931,937,940,946,968,974,977,983,986],[10,11,13],"h2",{"id":12},"一-javascript-es-基础",[14,15,16],"strong",{},"一、 JavaScript & ES 基础",[18,19,21],"h3",{"id":20},"_1-讲讲原型链",[14,22,23],{},"1. 讲讲原型链",[25,26,27,47,67,77],"ul",{},[28,29,30,33,34,38,39,42,43,46],"li",{},[14,31,32],{},"核心机制："," 在 JavaScript 中，对象是基于原型继承的。每个实例对象都有一个内部属性 ",[35,36,37],"code",{"code":37},"[[Prototype]]","（可通过 ",[35,40,41],{"code":41},"__proto__"," 访问），指向它的构造函数的 ",[35,44,45],{"code":45},"prototype"," 对象。",[28,48,49,52,53,55,56,58,59,62,63,66],{},[14,50,51],{},"查找链路："," 当我们访问对象的一个属性或方法时，引擎会先在对象自身查找；如果找不到，就会沿着 ",[35,54,41],{"code":41}," 指针去它的原型对象上找；如果还找不到，就继续沿着原型对象的 ",[35,57,41],{"code":41}," 向上查找，直到终点 ",[35,60,61],{"code":61},"Object.prototype.__proto__","（即 ",[35,64,65],{"code":65},"null","）。这根链条就是原型链。",[28,68,69,72,73,76],{},[14,70,71],{},"性能与陷阱："," 原型链查找是耗时的，过深的原型链会影响性能。同时，修改原型上的引用类型属性（如数组），会导致所有实例共享这个修改，这也是为什么在 Vue 组件的 ",[35,74,75],{"code":75},"data"," 必须是一个函数的原因。",[28,78,79,82,83,86,87,89,90,92],{},[14,80,81],{},"判断方法："," 常用 ",[35,84,85],{"code":85},"instanceof"," 操作符来判断原型链，它的原理就是顺着实例对象的 ",[35,88,41],{"code":41}," 一直往上找，看是否能找到对应构造函数的 ",[35,91,45],{"code":45},"。",[18,94,96],{"id":95},"_2-es6新特性",[14,97,98],{},"2. ES6新特性",[25,100,101,114,124,147],{},[28,102,103,109,110,113],{},[14,104,105,108],{},[35,106,107],{"code":107},"Promise"," & 异步控制："," 解决了回调地狱，是现在 ",[35,111,112],{"code":112},"fetch"," 和各类异步请求的基础。",[28,115,116,123],{},[14,117,118,119,122],{},"解构赋值 & 扩展运算符 (",[35,120,121],{"code":121},"...",")："," 在处理复杂的数据流（如合并配置项、深浅拷贝一层数据）时非常高频。",[28,125,126,136,137,131,140,143,144,146],{},[14,127,128,131,132,135],{},[35,129,130],{"code":130},"Map"," 和 ",[35,133,134],{"code":134},"Set","："," 在需要频繁增删键值对，或者对大数组去重时，性能远超普通 ",[35,138,139],{"code":139},"Object",[35,141,142],{"code":142},"Array","。比如在处理前端大量埋点数据或图表节点关系时，",[35,145,130],{"code":130}," 的键可以是对象，这点非常有用。",[28,148,149,157],{},[14,150,151,131,154,135],{},[35,152,153],{"code":153},"Proxy",[35,155,156],{"code":156},"Reflect"," 这是 Vue3 响应式的基石，用于拦截对对象的各种操作。",[18,159,161],{"id":160},"_3-es7-新特性",[14,162,163],{},"3. ES7 新特性",[165,166,167,170,171,174,175,178,179,182,183,185],"p",{},[35,168,169],{"code":169},"Array.prototype.includes()","： ",[35,172,173],{"code":173},"includes()"," 比 ",[35,176,177],{"code":177},"indexOf()"," ",[14,180,181],{},"更好用、更语义化、还能识别 NaN","，而 ",[35,184,177],{"code":177}," 做不到。",[165,187,188,191,192,195],{},[35,189,190],{"code":190},"指数运算符 ()","： 替代 ",[35,193,194],{"code":194},"Math.pow()","，例如在一些复杂的物理引擎或动画计算中会用到。",[10,197,199],{"id":198},"二-框架与技术栈-vue-ts",[14,200,201],{},"二、 框架与技术栈 (Vue & TS)",[18,203,205],{"id":204},"_4-为什么要用-typescript怎么用的",[14,206,207],{},"4. 为什么要用 TypeScript，怎么用的？",[25,209,210,216,235],{},[28,211,212,215],{},[14,213,214],{},"根本原因："," 解决 JS 动态弱类型在大型工程中的维护灾难。它把运行时错误提前到了编译时发现。",[28,217,218,221],{},[14,219,220],{},"工程价值：",[25,222,223,229],{},[28,224,225,228],{},[14,226,227],{},"重构利器："," 修改一个基础接口，IDE 会提示所有不兼容的地方。",[28,230,231,234],{},[14,232,233],{},"代码即文档："," 配合现代 IDE，写代码时有极佳的属性提示，不需要频繁翻阅后端 API 文档。",[28,236,237,240,241,131,244,247,248,251,252,255,256,259],{},[14,238,239],{},"高级用法："," 在实际开发中，除了基础的 ",[35,242,243],{"code":243},"interface",[35,245,246],{"code":246},"type","，还会大量使用",[14,249,250],{},"泛型 (Generics)"," 来封装通用的网络请求方法，或者使用内置工具类型如 ",[35,253,254],{"code":254},"Partial\u003CT>","（将属性变为可选）、",[35,257,258],{"code":258},"Pick\u003CT, K>","（提取部分属性）来处理复杂的组件 Props 传递。",[18,261,263],{"id":262},"_5-vue-2-和-vue-3-的区别与技术演进",[14,264,265],{},"5. Vue 2 和 Vue 3 的区别与技术演进",[25,267,268,285,305],{},[28,269,270,273,274,277,278,281,282,284],{},[14,271,272],{},"响应式系统重构："," Vue 2 的 ",[35,275,276],{"code":276},"Object.defineProperty"," 只能劫持对象的已有属性，对于新增属性（需 ",[35,279,280],{"code":280},"$set","）、删除属性以及数组下标修改无能为力。Vue 3 改用 ",[35,283,153],{"code":153},"，直接代理整个对象，支持更丰富的拦截操作，性能也大幅提升。",[28,286,287,290,291,293,294,293,297,300,301,304],{},[14,288,289],{},"逻辑复用（Options API -> Composition API）："," Vue 2 按 ",[35,292,75],{"code":75},"、",[35,295,296],{"code":296},"methods",[35,298,299],{"code":299},"computed"," 组织代码，导致同一个功能的逻辑被物理打散（碎片化），后期维护非常痛苦。Vue 3 的 ",[35,302,303],{"code":303},"setup"," 允许按“功能”聚集代码，并且可以通过组合式函数（Hooks）轻松地跨组件复用逻辑。",[28,306,307,310],{},[14,308,309],{},"编译优化："," Vue 3 引入了静态提升（Static Hoisting）和 PatchFlag。它在编译模板时会标记动态节点，在 Diff 算法对比时，直接跳过静态节点，只对比带有标记的动态节点，极大提升了渲染性能。",[18,312,314],{"id":313},"_6-componentsutilshooks-的区别与选择",[14,315,316],{},"6. Components、Utils、Hooks 的区别与选择",[165,318,319],{},[14,320,321],{},"判断逻辑（重要）：",[323,324,325,335,348],"ol",{},[28,326,327,330,331,334],{},[14,328,329],{},"这个功能包含 UI 渲染吗？"," -> 是，用 ",[14,332,333],{},"Components","。例如：一个带有时序播放控制的进度条。",[28,336,337,330,340,343,344,347],{},[14,338,339],{},"这个功能纯逻辑，且不涉及任何组件的状态（响应式数据\u002F生命周期）吗？",[14,341,342],{},"Utils","。例如：一个将时间戳转换为 ",[35,345,346],{"code":346},"YYYY-MM-DD"," 的纯函数。",[28,349,350,330,353,356,357,360,361,364,365,368],{},[14,351,352],{},"这个功能是纯逻辑，但它需要维护状态，或者需要挂载到组件的生命周期上吗？",[14,354,355],{},"Hooks","。例如：",[35,358,359],{"code":359},"useWebSocket","，它需要在内部维护 ",[35,362,363],{"code":363},"isConnected"," 状态，并且在组件 ",[35,366,367],{"code":367},"onUnmounted"," 时自动断开连接。",[10,370,372],{"id":371},"三-前端工程化",[14,373,374],{},"三、 前端工程化",[18,376,378],{"id":377},"_7-webpack-vs-vite",[14,379,380],{},"7. Webpack vs Vite",[25,382,383,389],{},[28,384,385,388],{},[14,386,387],{},"Webpack 的痛点（Bundle 机制）："," Webpack 在冷启动时，需要从入口文件开始，静态分析所有的依赖，编译、打包成一个或多个巨大的 Bundle（束，捆） 后，才启动开发服务器。项目一旦变大，哪怕只改一行代码，HMR（热更新）也可能需要好几秒。",[28,390,391,394],{},[14,392,393],{},"Vite 的破局（No-Bundle 机制）："," Vite 巧妙利用了现代浏览器原生支持 ESM 的特性。冷启动时，它只是启动一个极快的静态文件服务器。当浏览器请求某个文件时，Vite 才在服务端拦截请求，即时编译（如把 Vue\u002FTS 转成 JS）并返回。更新速度属于 O(1) 级别，完全不受项目规模影响。",[18,396,398],{"id":397},"_8-tree-shaking-代码分割原理",[14,399,400],{},"8. Tree-shaking & 代码分割原理",[25,402,403,417],{},[28,404,405,408,409,412,413,416],{},[14,406,407],{},"Tree-shaking","，我理解它就像摇树一样把“死代码”摇掉。它的实现依赖于 ES Modules 的静态结构。因为 ",[35,410,411],{"code":411},"import"," 和 ",[35,414,415],{"code":415},"export"," 在编译时就能确定依赖关系，所以打包工具可以分析出哪些代码是没被用到的，然后在压缩阶段把这部分代码删掉，以此来减小包的体积。",[28,418,419,422,423,426,427,430],{},[14,420,421],{},"代码分割 (Code Splitting)"," 的核心是",[14,424,425],{},"按需加载","。它主要是通过 ",[35,428,429],{"code":429},"import()"," 动态导入语法实现的。打包工具遇到动态导入时，会把这部分代码单独打包成一个文件（chunk）一大块。这个文件只有在用户触发特定操作，比如访问某个路由时，才会被浏览器下载和执行。这样做能极大地提升应用的首屏加载速度。",[18,432,434],{"id":433},"_9-按需加载",[14,435,436],{},"9. 按需加载",[165,438,439],{},"通过动态导入（Dynamic Import）实现。在路由层（Vue Router）或大型组件层使用 () => import('.\u002FMyComp.vue')，只有当用户访问该路径或触发该动作时，浏览器才会去下载对应的 JS chunk。",[18,441,443],{"id":442},"_10-esm-和-cjs-的区别",[14,444,445],{},"10. ESM 和 CJS 的区别",[165,447,448,449,92],{},"面试官您好，ESM 和 CJS 是 JavaScript 生态中最主流的两种模块系统。",[14,450,451],{},"CJS（CommonJS）是 Node.js 诞生初期为解决服务端模块化问题制定的社区标准，而 ESM（ECMAScript Modules）是 ES6 推出的官方语言级模块标准，现在已经成为浏览器和 Node.js 通用的跨平台标准",[165,453,454],{},"它们的核心区别主要体现在以下 5 个方面：",[323,456,457],{},[28,458,459],{},"语法与使用方式不同\n这是最直观的区别：",[25,461,462,480],{},[28,463,464,467,468,471,472,475,476,479],{},[14,465,466],{},"CJS"," 使用 ",[35,469,470],{"code":470},"require()"," 函数导入模块，使用 ",[35,473,474],{"code":474},"module.exports"," 或 ",[35,477,478],{"code":478},"exports"," 对象导出内容",[28,481,482,467,485,487,488,490],{},[14,483,484],{},"ESM",[35,486,411],{"code":411}," 关键字导入模块，使用 ",[35,489,415],{"code":415}," 关键字导出内容",[323,492,494],{"start":493},2,[28,495,496],{},"加载时机与原理不同（最本质区别）",[25,498,499,508],{},[28,500,501,504,505,507],{},[14,502,503],{},"CJS 是运行时同步加载","：代码执行到 ",[35,506,470],{"code":470}," 语句时才会去加载并执行模块文件，加载完成后才继续执行后续代码。它本质上是一个函数调用，无法在编译阶段进行静态分析。",[28,509,510,513,514,516],{},[14,511,512],{},"ESM 是编译时静态加载","：JS 引擎在代码运行前的编译阶段，就会扫描所有 ",[35,515,411],{"code":411}," 语句，提前加载所有依赖模块。这使得 ESM 支持 Tree Shaking（摇树优化），可以剔除未使用的代码，显著减小打包体积。",[323,518,520],{"start":519},3,[28,521,522],{},"导出值的特性不同",[25,524,525,531],{},[28,526,527,530],{},[14,528,529],{},"CJS 导出的是值的拷贝","：模块导出后，导出值与模块内部变量就断开了联系。如果模块内部后续修改了这个变量，外部导入的值不会同步更新。",[28,532,533,536],{},[14,534,535],{},"ESM 导出的是值的只读引用","：外部导入的只是模块内部变量的一个 \"指针\"，当模块内部修改了变量值时，外部导入的值会同步更新。同时，ESM 不允许在导入方修改导出的值。",[323,538,540],{"start":539},4,[28,541,542],{},"动态性支持不同",[25,544,545,561],{},[28,546,547,135,550,552,553,556,557,560],{},[14,548,549],{},"CJS 天然支持动态加载",[35,551,470],{"code":470}," 可以写在任何地方，包括 ",[35,554,555],{"code":555},"if"," 条件语句、",[35,558,559],{"code":559},"for"," 循环内部，可以根据运行时条件动态决定加载哪个模块。",[28,562,563,135,566,568,569,571],{},[14,564,565],{},"ESM 原生是静态的",[35,567,411],{"code":411}," 语句只能写在文件的最顶层，不能出现在任何代码块内部。不过 ESM 提供了 ",[35,570,429],{"code":429}," 函数来实现动态导入，返回一个 Promise。",[323,573,575],{"start":574},5,[28,576,577],{},"运行环境与其他细节差异",[25,579,580,586,608,624,641],{},[28,581,582,585],{},[14,583,584],{},"运行环境","：CJS 主要用于 Node.js 环境；ESM 同时支持浏览器和 Node.js 14+ 版本。",[28,587,588,591,592,595,596,599,600,603,604,607],{},[14,589,590],{},"文件扩展名","：CJS 默认使用 ",[35,593,594],{"code":594},".js","；ESM 需要将文件改为 ",[35,597,598],{"code":598},".mjs","，或在 ",[35,601,602],{"code":602},"package.json"," 中添加 ",[35,605,606],{"code":606},"\"type\": \"module\""," 字段。",[28,609,610,613,614,617,618,620,621,92],{},[14,611,612],{},"顶层作用域","：CJS 中顶层 ",[35,615,616],{"code":616},"this"," 指向当前模块；ESM 中顶层 ",[35,619,616],{"code":616}," 是 ",[35,622,623],{"code":623},"undefined",[28,625,626,629,630,293,633,636,637,640],{},[14,627,628],{},"内置变量","：CJS 中有 ",[35,631,632],{"code":632},"__dirname",[35,634,635],{"code":635},"__filename"," 等模块级变量；ESM 中没有这些变量，需要通过 ",[35,638,639],{"code":639},"import.meta.url"," 来实现类似功能。",[28,642,643],{},"总结与实际应用",[165,645,646,647,650],{},"目前 ",[14,648,649],{},"ESM 已经成为 JavaScript 模块化的未来趋势","，所有现代前端框架（React、Vue、Angular）和工具链（Vite、Rollup）都默认使用 ESM。但由于历史原因，Node.js 生态中仍然存在大量使用 CJS 的存量项目和第三方库。",[165,652,653,654,656,657,659],{},"在实际开发中，Node.js 支持 ESM 和 CJS 互相导入，但有一些注意事项：比如 ESM 可以导入 CJS 模块，但只能导入其默认导出；CJS 不能直接使用 ",[35,655,411],{"code":411}," 导入 ESM 模块，需要使用 ",[35,658,429],{"code":429}," 函数。",[18,661,663],{"id":662},"_11-sass-和-less-区别为什么用-sass",[14,664,665],{},"11. Sass 和 Less 区别，为什么用 Sass",[25,667,668,682],{},[28,669,670,673,674,677,678,681],{},[14,671,672],{},"客观对比："," 两者都是优秀的 CSS 预处理器，支持变量、嵌套、混合（Mixin）。但 Sass（特别是基于 Dart 编译的最新版）在控制指令（",[35,675,676],{"code":676},"@if",", ",[35,679,680],{"code":680},"@each","）和数学函数库方面更为强大。",[28,683,684,687,688,691,692,695],{},[14,685,686],{},"为什么用："," Sass 的 ",[35,689,690],{"code":690},"@use"," 模块化系统比传统 ",[35,693,694],{"code":694},"@import"," 更先进，解决了全局变量污染问题。在构建大型组件库或复杂的主题定制系统时，Sass 的生态和工具链更为成熟。",[10,697,699],{"id":698},"四-nodejs-与后端思维",[14,700,701],{},"四、 Node.js 与后端思维",[18,703,705],{"id":704},"_12-node-用过吗怎么用的中间件机制",[14,706,707],{},"12. Node 用过吗？怎么用的？中间件机制？",[165,709,710,713],{},[14,711,712],{},"使用场景："," 作为全栈开发方向，Node 常用来做中间层（BFF，Backend For Frontend），用于接口聚合、数据清洗过滤，或者用来写自动化脚本（CLI 工具）。",[165,715,716,717,720,721,724,725,728,729,732],{},"中间件是 Node.js 后端框架（Express、Koa 等）最核心的设计思想之一。",[14,718,719],{},"中间件的本质就是一个函数","，它可以访问请求对象（Request）、响应对象（Response），以及应用的请求 - 响应循环中的下一个中间件函数（通常命名为 ",[35,722,723],{"code":723},"next","）。中间件的作用是在",[14,726,727],{},"请求到达最终的路由处理器之前","，或者",[14,730,731],{},"响应返回给客户端之前","，对请求和响应进行统一的加工和拦截。",[165,734,735],{},"中间件的典型应用场景：",[25,737,738,744,750,756,762],{},[28,739,740,743],{},[14,741,742],{},"鉴权中间件","：统一验证用户的登录状态和权限，拒绝未授权的请求",[28,745,746,749],{},[14,747,748],{},"日志中间件","：记录所有请求的 URL、方法、状态码、耗时等信息",[28,751,752,755],{},[14,753,754],{},"跨域处理中间件","：统一设置 CORS 响应头，解决跨域问题",[28,757,758,761],{},[14,759,760],{},"请求体解析中间件","：解析 POST 请求的 JSON、FormData 等格式的请求体",[28,763,764,767],{},[14,765,766],{},"错误处理中间件","：统一捕获和处理应用中的所有错误，返回标准化的错误响应",[165,769,770,771,774],{},"中间件的执行流程：\n当一个请求到达服务器时，会按照中间件的",[14,772,773],{},"注册顺序","依次执行。每个中间件可以选择：",[323,776,777,784,787],{},[28,778,779,780,783],{},"执行自己的逻辑，然后调用 ",[35,781,782],{"code":782},"next()"," 函数将控制权传递给下一个中间件",[28,785,786],{},"直接返回响应，结束请求 - 响应循环",[28,788,789,790,793],{},"调用 ",[35,791,792],{"code":792},"next(err)"," 将错误传递给错误处理中间件",[795,796,801],"pre",{"className":797,"code":799,"language":800},[798],"language-text","面试官您好，BFF 全称是 Backend For Frontend，也就是 \"服务于前端的后端\"，是一种架构设计模式。\n它是随着微服务架构普及出现的，主要解决前端需要调用多个微服务接口导致的请求多、数据处理复杂、前后端耦合的问题。\nBFF 层位于前端和后端微服务之间，核心职责是接口聚合、数据转换、统一鉴权和错误处理，为前端提供定制化的接口服务。\n技术上通常用 Node.js 实现，因为前后端语言统一，前端工程师可以无缝开发。在组织架构上，BFF 层一般由前端团队维护，这样前端可以根据需求快速迭代接口，不需要依赖后端团队。\n","text",[35,802,799],{"__ignoreMap":803},"",[18,805,807],{"id":806},"_13-洋葱模型-onion-model",[14,808,809],{},"13. 洋葱模型 (Onion Model)",[25,811,812,830],{},[28,813,814,817,818,131,821,823,824,826,827,829],{},[14,815,816],{},"原理："," 以 Koa 为例，通过 ",[35,819,820],{"code":820},"async\u002Fawait",[35,822,782],{"code":782}," 实现。请求像穿透洋葱一样进入，依次执行中间件 ",[35,825,782],{"code":782}," 前的逻辑（通常用于处理请求数据）；到达最核心的处理逻辑后，再由内向外反向执行 ",[35,828,782],{"code":782}," 之后的逻辑（通常用于处理响应数据、计算总耗时）。",[28,831,832,835],{},[14,833,834],{},"优势："," 使得请求和响应的拦截逻辑可以写在同一个函数体内，代码高内聚，处理异步流非常优雅。",[10,837,839],{"id":838},"五项目优化与-ai-时代的前端",[14,840,841],{},"五、项目优化与 AI 时代的前端",[18,843,845],{"id":844},"_14-讲讲项目性能优化-建立体系化回答",[14,846,847],{},"14. 讲讲项目性能优化 (建立体系化回答)",[25,849,850,856,862],{},[28,851,852,855],{},[14,853,854],{},"构建时优化："," Tree-shaking、配置合理的 SplitChunks 进行代码分割、压缩图片资源、去除 console。",[28,857,858,861],{},[14,859,860],{},"网络时优化："," 强缓存与协商缓存策略、开启 Gzip\u002FBrotli 压缩、HTTP\u002F2 多路复用。",[28,863,864,867],{},[14,865,866],{},"运行时优化（重点）：",[25,868,869,872,883],{},[28,870,871],{},"长列表：虚拟列表（Virtual List）只渲染可视区域的 DOM。",[28,873,874,875,878,879,882],{},"动画\u002F可视化：使用 ",[35,876,877],{"code":877},"requestAnimationFrame"," 替代 ",[35,880,881],{"code":881},"setTimeout","，复杂的大量数据图表使用 Canvas\u002FWebGL 替代 DOM 渲染（例如数字孪生或大屏展示）。",[28,884,885],{},"防抖（Debounce）与节流（Throttle）处理高频事件。",[18,887,889],{"id":888},"_15-chunk-是什么及其命名",[14,890,891],{},"15. Chunk 是什么及其命名",[25,893,894,900,909],{},[28,895,896,899],{},[14,897,898],{},"概念："," Chunk 指的是 Webpack 打包过程中生成的代码块。",[28,901,902,905,906,92],{},[14,903,904],{},"命名策略："," 典型如 ",[35,907,908],{"code":908},"[name].[contenthash].js",[28,910,911,914,915,92,918,921],{},[14,912,913],{},"为什么要用 contenthash："," 这是为了",[14,916,917],{},"长效缓存（Long-term Caching）",[35,919,920],{"code":920},"contenthash"," 是根据文件本身的内容计算出来的哈希值。如果只修改了业务代码 A，那么 A 的 chunk 名会变（强迫浏览器下载新文件），而没有修改的第三方库包（Vendor Chunk）的哈希值不变，浏览器依然可以使用本地缓存，极大提升二次加载速度。",[18,923,925],{"id":924},"_16-ai-怎么用的",[14,926,927],{},"16. AI 怎么用的：",[165,929,930],{},"不要说用来写增删改查。可以说用来处理复杂正则表达式、编写繁杂的单元测试、快速生成某种特定的算法（如贝塞尔曲线计算），或者用于技术选型方案的对比调研。",[18,932,934],{"id":933},"_17-claude-code-用的什么套餐价格",[14,935,936],{},"17. Claude Code 用的什么套餐价格",[165,938,939],{},"Claude Code 是一个运行在终端的命令行工具（CLI），它是包含在 Anthropic 的 Claude 订阅套餐中的功能。",[18,941,943],{"id":942},"_18-页面空白报错如何保证-ai-修复的正确性",[14,944,945],{},"18. 页面空白报错，如何保证 AI 修复的正确性：",[25,947,948,954],{},[28,949,950,953],{},[14,951,952],{},"Prompt 技巧："," 不要只扔报错截图。要提供：1. 报错堆栈；2. 发生错误前后的相关代码片段；3. 期望的输入和输出。",[28,955,956,959,960,963,964,967],{},[14,957,958],{},"验证机制（核心）："," AI 给的代码绝对不能直接 ",[35,961,962],{"code":962},"git commit","。必须放入沙箱或本地环境跑通。（如果是核心逻辑，我会要求 AI 顺便把对应的",[14,965,966],{},"单元测试","写出来，通过跑通单测来反向验证它逻辑的正确性。）",[18,969,971],{"id":970},"_19-印象深的-bug",[14,972,973],{},"19. 印象深的 bug：",[165,975,976],{},"（你需要结合你自己的项目来说，举个例子：）在开发一个涉及多设备状态同步的看板时，遇到了竞态条件导致的数据覆盖问题。AI 帮我分析了网络请求的时序，并建议我引入队列机制或使用具有取消功能的 Promise（AbortController）来丢弃过期的请求，这超出了我当时纯 UI 开发的思维局限。",[18,978,980],{"id":979},"_20-最近学了什么新技术",[14,981,982],{},"20. 最近学了什么新技术",[165,984,985],{},"结合你目前的知识储备，建议可以说一些偏底层或前沿的。比如：",[25,987,988,994,1000],{},[28,989,990,993],{},[14,991,992],{},"Rspack\u002FTurbopack："," 基于 Rust 的新一代构建工具，了解前端工具链向底层语言迁移的趋势。",[28,995,996,999],{},[14,997,998],{},"WebRTC 或 WebSocket 进阶："," 在做双向通信同步时的实践。",[28,1001,1002,1005],{},[14,1003,1004],{},"大模型在前端的接入："," 比如如何处理 Server-Sent Events (SSE) 来实现类似 ChatGPT 的流式输出打字机效果。",{"title":803,"searchDepth":539,"depth":539,"links":1007},[1008,1013,1018,1025,1029],{"id":12,"depth":493,"text":16,"children":1009},[1010,1011,1012],{"id":20,"depth":519,"text":23},{"id":95,"depth":519,"text":98},{"id":160,"depth":519,"text":163},{"id":198,"depth":493,"text":201,"children":1014},[1015,1016,1017],{"id":204,"depth":519,"text":207},{"id":262,"depth":519,"text":265},{"id":313,"depth":519,"text":316},{"id":371,"depth":493,"text":374,"children":1019},[1020,1021,1022,1023,1024],{"id":377,"depth":519,"text":380},{"id":397,"depth":519,"text":400},{"id":433,"depth":519,"text":436},{"id":442,"depth":519,"text":445},{"id":662,"depth":519,"text":665},{"id":698,"depth":493,"text":701,"children":1026},[1027,1028],{"id":704,"depth":519,"text":707},{"id":806,"depth":519,"text":809},{"id":838,"depth":493,"text":841,"children":1030},[1031,1032,1033,1034,1035,1036,1037],{"id":844,"depth":519,"text":847},{"id":888,"depth":519,"text":891},{"id":924,"depth":519,"text":927},{"id":933,"depth":519,"text":936},{"id":942,"depth":519,"text":945},{"id":970,"depth":519,"text":973},{"id":979,"depth":519,"text":982},[1039],"技术","2026-05-15 18:08","看的第一篇完整面经。",false,"md",null,{"slots":1046},{},true,"\u002F2026\u002F20265161",{"text":1050,"minutes":1051,"time":1052,"words":1053},"20 min read",19.8,1188000,3960,{"title":5,"description":1041},{"loc":1048},"posts\u002F2026\u002F20265161",[],"tech","2026-05-16 12:22","4qVrlWcPdJthoPPV8g06dnholeBPu_bQrTrSty1Ohp0",[1062,1067],{"title":1063,"path":1064,"stem":1065,"date":1066,"type":1058,"children":-1},"场景题汇总1","\u002F2026\u002F2026516","posts\u002F2026\u002F2026516","2026-05-15 15:43",{"title":1068,"path":1069,"stem":1070,"date":1071,"type":1058,"children":-1},"高频八股合集","\u002F2026\u002F20260528","posts\u002F2026\u002F20260528","2026-05-28 12:00",1779968289640]