1. 最擅长哪方面的技术?用 AI 编程怎么去实现一个东西?
我最擅长前端工程化、性能优化、微前端架构和 AI 辅助开发。用 AI 编程时,我会先把需求、技术栈、约束一次性说清楚,让 AI 生成基础代码,再自己做业务适配、边界处理和自测,确保代码符合规范、没有坑。
2. 怎么去控制 AI 不要乱改?
关键是给足约束:明确禁止它改哪些逻辑、必须用什么规范、不能引入哪些库,并且分小块生成,每一步都只让它做一件事,写完后再让它自检一遍。
3. RAG 项目是一个 prompt 工程吗?还是有什么样的一个实践?
不只是 prompt 工程,是一整套工程化实践,包括数据清洗、文档分块、向量化存储、检索召回、重排序、prompt 编排和结果生成,prompt 只是其中一环。
4. RAG 召回和重排是怎么做的?
召回阶段:把用户问题向量化,和向量库做相似度匹配,返回 TopN 相关文档。重排阶段:用交叉编码器或 LLM 对召回结果做相关性打分,过滤无关内容,提升上下文质量。
5. 召回的可能不是预期想要的怎么办呢?
可以从几方面优化:调整分块策略、优化 embedding 模型、加入关键词检索做混合召回、用重排过滤噪声,也可以通过改写用户问题来提升召回精准度。
6. 向量检索的一些变种研究过吗?这个 RAG 用了什么框架?
了解过混合检索、多模态检索、多级索引等变种。我做的 RAG 项目用了 LangChain 框架,搭配向量数据库做存储和检索。
7. RAG 的这个 AI 框架是 LangChain 吗?
是的,我用的是 LangChain,它能快速搭建 RAG 的完整链路,包括文档加载、分块、向量化、检索和生成。
8. 它现在新版有什么功能?怎么实习这个 RAG 的?
新版 LangChain 支持更完善的工具调用、多模态 RAG、持久化记忆和更细粒度的组件拆分。实习时我先跟着官方教程搭了一个基础的问答 Demo,再一步步优化分块、召回和 prompt,最后对接业务数据。
9. LangChain 这个框架有什么缺点?
封装度较高,底层细节不够透明,遇到复杂场景调试成本高;部分组件更新快,API 变动频繁,长期维护有一定成本。
10. 有做过一些比如测评吗?
有,我做过不同分块策略、embedding 模型和 prompt 模板的效果测评,对比召回准确率、生成质量和响应速度,选出了最适合业务场景的方案。
11. 你那个分片是怎么分片呢?说一下分片的方式有哪些?然后你具体用的是什么样的方式?
常见分片方式有固定长度分片、递归字符分片、语义分片、结构化文档分片。我用的是递归字符分片,兼顾了分块效率和语义完整性,同时设置了重叠窗口避免上下文断裂。
12. React Native 有写过吗?为什么学这个东西?
有写过简单的 Demo。我学它是为了了解跨平台开发的思路,掌握一套代码同时跑在 iOS 和 Android 上的能力,也能更好地理解前端跨端技术的底层原理。
13. 用 Web Worker 统一管理接口缓存,这个能不能展开讲一下?
可以,我用 Web Worker 把接口请求和缓存逻辑放到后台线程处理,主线程只负责发起请求和接收结果,避免大量请求和缓存计算阻塞主线程,提升页面响应速度和用户体验。
14. 如果有一些比较耗性能的计算,比如涉及到 canvas 这个东西?
耗性能的 canvas 操作,比如图片处理、滤镜计算、像素级操作,都可以放到 Web Worker 里做,避免阻塞主线程导致页面卡顿。
15. 比如我们在 Canvas 上有一张图片,要将图片进行一个保存,但直接保存会卡住,因为它在主线程里面的。假如要把这个图片的保存放到一个 Web Worker 里面,怎么做呢?
可以先在主线程把 canvas 的图像数据转成 ImageData,再通过 postMessage 传递给 Web Worker,由 Worker 处理压缩、编码,生成 Blob 后再传回主线程保存,避免主线程阻塞。
16. 我看你封装了一个组件的优化,列表每个东西不一样宽有什么区别怎么优化?
不等宽列表用普通虚拟滚动会有问题,我用了基于 Intersection Observer 的动态高度虚拟滚动,提前预估每个列表项的位置和高度,只渲染可视区域的元素,减少 DOM 节点数量,提升滚动性能。
17. 你在哪个产品里面有类似这种列表优化方式?
在微前端后台管理系统的订单列表里,订单卡片宽度不固定,我用了这种不等宽虚拟滚动优化,解决了大数据量列表卡顿的问题。
18. 比如钉钉的滚动列表优化要怎么优化?
钉钉这类产品的列表优化一般会用虚拟滚动 + 预加载 + 缓存,结合 Intersection Observer 做可视区域判断,同时做图片懒加载和骨架屏,提升滚动流畅度和首屏加载速度。
19. 如何计算可视区域?
可以用 Intersection Observer API 监听列表项和视口的交叉状态,或者通过 scroll 事件结合元素的 getBoundingClientRect () 方法,计算元素是否在可视区域内。
20. 有没有封装一些自定义 hooks,要怎么封装呢?
有,我封装过 useVirtualList、useIntersectionObserver、useDebounce 等自定义 hooks。封装时会把通用逻辑和状态抽离,传入配置项,返回需要的状态和方法,同时做好类型定义和清理逻辑。
21. 这个 Hook 有什么情况下它会容易造成内存泄漏?
比如在 useEffect 里注册了事件监听、定时器,没有在组件卸载时清理;或者引用了外部的大对象,没有及时释放,都会导致内存泄漏。
22. 除了这种 case 还有哪些会导致前端内存泄漏的?
全局变量未释放、闭包引用、DOM 元素引用未清空、iframe/websocket 连接未关闭、第三方库实例未销毁,这些都是常见的内存泄漏场景。
23. 怎么去发现这种内存泄漏和怎么解决?
可以用 Chrome DevTools 的 Memory 面板做堆快照对比,或者用 Performance 面板录制分析。解决的关键是找到泄漏源,及时清理事件监听、定时器、全局引用和第三方实例。
24. 在做项目或者实习过程中,有去解决过一些比较疑难杂症的性能问题吗?
有,我解决过微前端子应用切换时的内存泄漏问题,通过完善 unmount 生命周期的清理逻辑,销毁定时器、事件监听和第三方实例,解决了页面卡顿和内存持续增长的问题。
25. 算法题 有效的括号(先是用栈的方式写,之后用了不断替代成对括号)
栈的方式是遍历字符串,遇到左括号入栈,遇到右括号就和栈顶匹配,匹配成功出栈,最后栈空则有效。替代法是不断把成对的括号替换成空字符串,直到无法替换,若最后字符串为空则有效。
26. 这个替代法解法会导致其他问题吗?
会,时间复杂度高,对于超长字符串效率很低,而且会创建大量中间字符串,内存占用大,不适合处理大规模数据。
27. 死循环?
如果字符串里有无法匹配的括号,替代法会一直循环替换,虽然不会真的死循环,但时间复杂度很高,性能很差,所以栈的方式更稳定高效。