个人信息

- 李承雨,男,2027 届 
- 求职意向:web 前端工程师 
- 福建师范大学,软件工程专业 (2023.9 ~ 2027.6)
- CET-4/CET-6 证书
 15023182754
  lichengyu2005119@gmail.com
  Akiyama
  My Blog

技术栈

  • 前端核心: 熟练使用 React 生态(TS/Zustand/TanStack)与组件化架构,具备扎实的 Web 底层功底。

  • 全栈跨端: 掌握 Electron 跨端开发及 Java/Go/Node 后端 CRUD,能够深度参与全链路协作流程。

  • 工程素养: 深入实践 Docker、GitLab CI/CD、Shell 及自动化部署,具备 Shell 脚本编写与性能优化经验

实习经历

用友 - 废钢判级产品与解决方案部 前端工程师 2026/03 ~ 至今

产品概述:基于深度学习与物联网技术,实现废钢全周期闭环管理与全自动精准判级的智能化一体化平台。

  • 设计新版监控大屏:参照 Google StitchDESIGN.md设计标准,精心编排 UI/UX 相关Skills以及业务详情 md 文档,利用 Claude Code/Codex 快速生成可用原型,与产品经理围绕着原型进行迭代直到最终定版

  • 基于 Websocket 的状态机构建:参与废钢智能判级自助终端核心链路开发,在自助终端模块中实现基于 WebSocket 的多步骤流程状态机,覆盖设备实例初始化、步骤流转、心跳重连、异常兜底与人工补录刷新,支撑现场复杂判级流程闭环。

  • 监控点视频播放适配: 负责监控点视频播放兼容方案建设,基于 WebSocket + MSE MSE) 与海康 SDK 双链路实现多浏览器实时预览、复核场景适配。

杭州深维智元科技有限公司 前端工程师 2025/12 ~ 2026/02

产品概述元点引擎是一个类酒馆(Sillytavern)平台,核心价值在于对酒馆的复杂配置进行封装,为用户提供一站式的游玩体验

工作概述:参与角色扮演/故事推演叙事平台,元点引擎前端项目的从 0 到 1 前端重构,负责核心业务模块开发与工程化建设。

  • 核心酒馆式对话场景搭建:主导 AI 角色对话主链路构建,基于 TanStack Query + react-virtuoso + Zustand 搭建游标分页与虚拟列表体系,解决长会话上拉历史时的滚动跳动、消息乱序和异步回写竞态问题,轮分支对话的稳定性与实时性。

  • 首页性能优化:针对发现页高频搜索触发 API、分页加载卡顿及布局留白痛点,设计三层优化架构。通过自定义防抖 Hook 拦截无效搜索,配合**“哨兵”检测与TanStack Query 自动管理分页加载,并引入响应式瀑布流优化布局。最终降低 80%+ 冗余请求**,首屏提速 40%,实现万量级数据下的无感知滚动体验

  • 动态主题系统:针对多主题切换导致的 FOUC 闪烁及重新编译痛点,设计**“预加载 + 状态同步”双层架构**。通过原生 DOM 注入 CSS 变量结合 React Context 运行时计算,实现系统主题跟随。实现运行时无感主题切换,支持不停机热加载新增主题,减少约 90% 的主题维护成本

项目经历

AgentCTF-platform - Agent 智能靶场教学平台

项目简述:基于 AI Agent 自主攻防演练、助力用户复盘决策逻辑的网安教学平台。

项目成果:海峡两岸信息服务创新大赛暨福建省计算机软件设计大赛金奖

  • 前后端契约式开发:作为唯一前端需与 6 个后端服务协作,接口频繁变更导致联调困难。主导推行 OpenAPI 契约先行,使用 Orval 自动生成 TS 类型与 API 客户端消除手写类型成本,实现强类型安全,将联调返工时间缩短约 40%

  • 双模式 SSE 实时通信:AI 推演需 POST 复杂配置,而标准 SSE 仅支持 GET。设计双模式机制:原生 EventSource (GET) + fetch + ReadableStream (POST)突破了 SSE 方法限制,保留低延迟优势,保障了 AI 攻防推演核心数据流的稳定

  • 路由鉴权体系:针对页面刷新掉线与复杂权限控制痛点,基于 TanStack Router 钩子与 Zustand Store 实现声明式中心化鉴权。结合 Token 持久化与状态自动恢复机制,保障鉴权拦截与登录后的平滑跳转。完整实现**“刷新无感知登录”,使业务与认证逻辑完全解耦**,路由守卫性能开销控制在 5ms 以内

标注回答搞

1. 核心酒馆式对话场景搭建 “这个项目里我主导的是 AI 角色对话的主链路,核心目标是把‘历史消息加载、用户发言、AI 异步返回’这三条数据流稳定地收敛到一个聊天视图里,保证长会话下的体验可控。

我当时把职责拆成了三层。TanStack Query 负责服务端状态,包括游标分页、缓存、分页加载和轮询相关请求;Zustand 负责前端会话态和消息视图态,比如当前消息列表、是否还可以加载历史、轮询任务状态、待处理结果;react-virtuoso 负责动态高度消息的虚拟渲染和滚动跟随。

历史消息这块,后端接口是按倒序分页返回,也就是从新到旧。我在 Query 层把分页结果展平后再反转成 UI 需要的从旧到新顺序。上拉加载不是自己手写滚动监听,而是直接接 Virtuoso 的顶部触发回调。为了避免 prepend 历史消息后视口跳动,我用了 大数锚点方案 做索引锚定,让旧视口在头部插入数据后还能保持稳定。

发送和 AI 返回这块,用户消息先做乐观追加,服务端返回 taskId 后再进入轮询。轮询结果回来时不会直接写 UI,而是先校验是否属于当前期望任务,旧任务结果直接丢弃;确认有效后再通过中间态统一写回消息列表,避免多处副作用同时改消息数组导致乱序或重复消费。这样处理后,长会话下历史翻页、实时返回和用户交互可以并存,体验上比较稳定。

如果不用 react-virtuoso 自己实现,最难的是动态高度场景下的滚动补偿。因为消息内容有 Markdown、选项区、不同端布局差异,prepend 数据后不仅要重算累计偏移,还要修正 scrollTop,同时兼顾‘用户在看历史’和‘系统要跟随最新消息’这两种状态切换。”

这一题的短版收尾 “所以这个亮点我最核心的贡献不是‘用了几个库’,而是把分页、轮询和视图同步三条链路拆开治理,最后稳定收敛到同一个聊天消息流里。”

2. 首页性能优化 “发现页优化我当时主要解决三个问题:搜索时高频无效请求、分页加载过程中的卡顿,以及卡片布局留白比较严重。

我的做法也是分层处理。第一层是输入层,我加了自定义防抖 Hook,避免用户连续输入时每个字符都打一次搜索请求,只在输入稳定后再真正发起查询。第二层是数据层,把列表分页和加载状态统一交给 TanStack Query,包括翻页、缓存和去重,减少重复请求和手写状态同步成本。第三层是视图层,我把卡片列表调整成响应式瀑布流,让不同尺寸内容能更充分利用横向空间,减少大面积留白,也降低了用户在滚动时对‘页面空、加载慢’的感知。

结果上,这次优化最明显的变化是两点。一个是无效搜索请求明显下降,因为请求不再跟着每次击键走;另一个是首屏和翻页体验更稳定了,尤其在数据量大时,用户主观上不会感觉页面一直抖或者一直在空转。

如果面试官追问数据口径,我会明确说:我会把‘冗余请求’定义成连续输入过程中最终没有贡献给结果的请求数,把‘首屏时间’定义成从进入页面到首批卡片完成可见渲染的耗时。测量上会用固定输入脚本、关闭缓存、固定网络节流条件,做前后多轮对照,取中位数,而不是只凭体感报数字。

这个亮点里我想强调的是,我不是只做了一个防抖,而是把输入、请求和布局三个层面一起看,最后得到的是整体链路的性能提升。”

这一题的安全说法 “如果没有严格线上 A/B,我不会在面试里死咬 80%40% 这种精确数字,我会说‘显著减少冗余请求、明显改善首屏响应和滚动体验’,这样更专业也更可信。”

3. 动态主题系统 “动态主题这块我当时主要解决两个问题:一是多主题切换时会有 FOUC,也就是页面先闪默认样式再切到目标主题;二是新增主题的成本高,如果每次都要改构建产物或者到处改样式变量,维护会越来越重。

我的方案可以理解成两层。第一层是主题样式的预加载和提前注入,我在页面真正渲染前就把主题相关的 CSS 变量准备好,优先让首帧拿到正确的颜色和基础 token,这样能避免页面先用默认主题渲染再闪一下。第二层是运行时状态同步,我用 React Context 管理当前主题和系统主题状态,把主题切换、系统跟随和组件消费统一到同一套上下文里。

具体实现上,我把主题能力尽量收敛到 CSS 变量层,而不是让业务组件自己判断颜色。组件只消费语义化 token,比如背景、前景、边框、强调色,主题切换时本质上是切变量,不是重刷组件逻辑。这样做的好处是运行时切换几乎无感,同时后续新增主题也只需要补一套 token 映射,而不是改一堆组件样式。

如果面试官追问为什么能减少维护成本,我会说核心不是一个绝对数字,而是主题能力从‘组件级分散判断’收敛成了‘token 级集中配置’。一旦抽象到这层,新增主题更多变成配置工作,而不是全站找颜色、逐个组件打补丁,所以维护复杂度会明显下降。”

这一题的短版收尾 “这个亮点的本质不是‘会切皮肤’,而是把主题从样式细节提升成了一套运行时设计 token 系统。”

统一答题模板 以后你答项目亮点,尽量都按这个顺序:

  1. 先讲问题背景
  2. 再讲你怎么拆层
  3. 再讲关键机制
  4. 再讲为什么这么选而不是别的方案
  5. 最后讲结果和边界

一句通用结尾 “我在这个项目里比较看重的一点,是把问题拆成稳定的数据流和职责边界,而不是靠堆代码把功能先跑起来。”

如果你要,我下一条可以继续帮你做两件事里的一件:

  1. 把这三段压缩成“1 分钟面试版”
  2. 把这三段扩成“面试官追问 3 层版本”