智能回潮率检测仪 — 速记版
📋 速记表(面试前快速扫)
| 题 | 一句话结论 | 关键词 |
|---|---|---|
| Q1 | 三层主进程架构,ServiceManager 管 12+ 服务,优雅关闭 | 启动层 服务管理器 优雅关闭 |
| Q2 | Prisma client 迁出 node_modules + asarUnpack 解引擎 | 迁目录 binaryTargets asarUnpack |
| Q3 | MQTT 控制面 + UDP 数据面,内置 Aedes Broker | Aedes MQTT/UDP 离线优先 |
| Q4 | 请求-响应重构为 100ms 轮询 + 滑动窗口 | 持续轮询 滑动窗口 5点去极值 |
| Q5 | Decimal.js 全精度 + 品种化公式,烘干法对照 | Decimal.js 双模式 回归拟合 |
| Q6 | 设备注册+心跳保活,SQLite 全量上传 5min | 设备注册 心跳 全量同步 |
| Q7 | 三层兜底:心跳重连/60s超时/异常自重启 | 心跳 超时复位 自重启 |
| Q8 | Prisma 六模型数据闭环 + calculationDetails 溯源 | 数据闭环 可追溯 |
| Q9 | 双操作模式+触摸键盘+rAF 降频 | 快捷模式 触摸键盘 降频 |
Q1: Electron 主进程架构
面试官可能问:Electron 主进程怎么设计?启动和生命周期怎么管?
🗣️ 口述稿:
我拆成三层:index.ts 启动层 → ApiServer 服务层 → ServiceManager 统一管 12 个服务。因为这更像一个小操作系统,把启动顺序、依赖、报错隔离、优雅关闭都交给自己管,而不是散在主进程一串 init。有依赖的 await,能并行的并行,单个服务失败只记日志不阻断其它。
💡 关键词提示:三层架构 ServiceManager单例 优雅关闭will-quit
⚠️ 备注:
- 内嵌 Express 不单独进程的代价:主进程承载过重,重的计算单独拆 service;被问反思主动认"单进程是省资源+部署简单的妥协"
- 用真实代码佐证:
manager.service.ts每个 init 都 try-catch 包着,启动失败不阻断整体
追问①:全局异常为什么不直接退出?
工业场景退出=停线,所以能不崩就不崩,先记日志,uncaughtException 这种严重错误延迟 1 秒再 relaunch,轻的不致命继续跑。
追问②:崩溃自重启,正写的数据会怎样?
崩溃那一刻的数据会丢,我做的是"能重启"不是"崩溃前 checkpoint 恢复",这层最薄,要彻底得加日志重放或 WAL 事务。
Q2: ✅ Prisma + Electron 打包攻坚
面试官可能问:Prisma 在 Electron 打包难在哪?output 怎么配?
🗣️ 口述稿:
根本问题是 Prisma 默认把生成的 client 和原生查询引擎二进制放 node_modules,Electron 打包成 asar 后引擎 require 不到、也找不着,生产环境启动即炸。我的做法是把 generated client 从 node_modules 迁到源码目录当普通代码一起打包,引擎走 asarUnpack 解出来,再用 binaryTargets 锁平台。
💡 关键词提示:output迁出 asarUnpack binaryTargets锁平台
⚠️ 备注:
- 配置实证:
output="../src/generated/client"+binaryTargets=["native","windows"]+electron-builder.yml里asarUnpack: prisma/**、sql.js - [需自行确认]:若简历写过"本地软链接 link:...",仓库当前实现里没有;按你真实版本对齐,别保留找不到的 link 说法
- 演进逻辑:先迁 client 才能加载、再解引擎才稳定——别一句话带完“我配了 output”,要讲成两步演进
追问①:为什么用 binaryTargets 锁平台?
不锁会在 Windows 上拉错或拉一堆平台的引擎;锁 native+windows 是"当前就跑 Windows 上位机"的务实做法,发 Mac 要再加 target。我一开始没锁,打包跨平台才崩才发现。
追问②:driverAdapters 是干嘛的?
让 Prisma 通过自定义 driver(这里是 SQL.js 内存/SQLite)工作,配合把引擎解出 asar 才能离线跑,是受限环境下用 Prisma 的适配层。
Q3: MQTT + UDP 多协议通信
面试官可能问:为什么又要 MQTT 又要 UDP?不统一?
🗣️ 口述稿:
角色完全不同:MQTT 走控制面,和物联网关通信,管状态、开关测量、指令下发,要可靠可解析(JSON+请求/响应);UDP 走数据面,直接高频采样 FL-WAPP 探头的 Q/M 值,一行 ASCII 数字,要低延迟低开销。用 MQTT 做 100ms 高频轮询太重,用 UDP 做状态指令又丢可靠性,所以各走各的。
💡 关键词提示:MQTT控制面 UDP数据面 Aedes离线Broker
⚠️ 备注:
- 内置 Aedes 而非外部/云 Broker 的根因:产线可能不联网,依赖外部每次部署都要折腾。
concurrency500/queueLimit1000顶高频,ENABLE_INTERNAL_MQTT_BROKER可开关回退外部 - [需自行确认]:简历写"监控延迟<100ms",代码里没有延迟埋点,能对上的是采集周期
requestInterval:100。别讲成测量出的端到端延迟,讲"单机 UDP→前端显示毫秒级体感"
追问①:UDP 丢包怎么办?
多发多采+统计折叠:连采 5 个 Q 值、10s 超时兜底,5 点去极值取中值(排序→掐最值→取中),再加 0.5~3.5 值域校验和 slice(-100) 滑动窗口。丢包=采不够 5 个,走超时重采不拿坏值。
追问②:换个带确认的协议(RS485+CRC)呢?
那要引入确认/重传/序号另一套,UDP 统计折叠就不一定适用。我的方案在"单探头高频小包"成立,换协议不硬套。
Q4: 实时数据采集引擎重构
面试官可能问:实时采集这块为什么重构?
🗣️ 口述稿:
早期是请求-响应,点一下发一次等一个回包,现场时序不稳、偶发无响应、前端还卡 UI。我重构成持续轮询:抽独立 RealtimeDataCollectorService,setInterval 100ms 定时发 UDP 请求,把 Q/M 值灌进定长数组,前端取最后一位就是最新值,彻底绕开"等不到回包"的问题。
💡 关键词提示:请求-响应→持续轮询 100ms 环形缓存
⚠️ 备注:
- 重构动机是现场翻车不是"想写更好",git 里能翻到
- 缓存窗口设 100 是"计算需要+内存可控"的经验值,没有压测标定,被问承认
追问①:100ms 轮询压力大吗?
UDP 一包几十字、探头固件够响应,用 setInterval 非递归避免回调堆叠,协议本身轻。
追问②:窗口为什么设 100?
既要留够计算用的最近 N 个值,又不能让数组无限涨。100 是我按需求+内存拍的,没有压测标定,是经验值。
Q5: 高精度回潮率计算引擎
面试官可能问:回潮率公式怎么设计的?为什么 Decimal.js?
🗣️ 口述稿:
微波穿过纱线测 Q 值(品质因数)和直径 D,通过数学模型反推回潮率 M,里面有去中心化 Q 值、Q 标准差、有效检测比、材质参数等特征项。公式连平方连除乘,JS 浮点
0.1+0.2≠0.3在要求 0.01% 的工业场景会被放大,所以中间计算全走 Decimal.js,最后才 toFixed(2)。
💡 关键词提示:Decimal.js 多面/单面双模式 品种独立参数
⚠️ 备注:
- 难点不是引 Decimal,是"多面/单面双模式+每品种独立参数"建模:同一 Q 值不同品种按下不同系数,按 detection_range 自动切,前后端配置要一致
- [需自行确认]:"公式经烘干称重回归验证、MSE 最小"仓库没有对应精度报告,别说成有正式报告;能讲拟合思路但别报"误差 0.01%"
追问①:怎么验证公式准确?
烘干称重对照——同一批纱线走微波再送实验室烘干称重(国标),回归拟合系数让 MSE 最小,是拟合调参不是拍脑袋。
Q6: 云端设备管理与数据同步
面试官可能问:设备怎么注册、怎么同步?
🗣️ 口述稿:
设备首启生成 UUID 调 /api/device/register 拿 deviceId/secret/JWT,之后 login 续 token,凭据存 electron-settings;云端用 HeartbeatService 保活;数据同步因本地 SQLite、远端 MySQL,用"每 5 分钟串行化整个 db 文件→FormData 上传→后端解析入库→返回 syncedIds 打标记"。
💡 关键词提示:设备注册续token 心跳保活 全量上传5min
⚠️ 备注:
- 为什么全量不做增量:产线数据量小(一次测量一条记录、库几 MB),全量最简可靠。判断有边界:到 GB 就得 Binlog/WAL 增量。答题重点是"按量级选方案"
- 上传中途断/读半坏文件:先 copyFileSync 临时文件再串行读,避免写锁读一半不一致
追问①:上传中断会读到坏文件吗?
先 copyFileSync 成临时文件再串行读取,避免 SQLite 写锁读到一半,上传有超时,断了下次再传容忍短暂不一致。
追问②:云端 401"设备不存在"?
清掉本地凭证重新注册。现实中云端库可能被重置,这是必然遇到的容错。
Q7: 测量稳定性兜底
面试官可能问:产线 7×24 怎么保证不卡死?
🗣️ 口述稿:
三层兜底:① WebSocket 心跳+自动重连(Socket.IO);② 前端测量 60 秒超时自动复位 UI,后端也有对应超时;③ 主进程全局异常捕获(unhandledRejection/uncaughtException 等),严重错误 1 秒后 app.relaunch() 自重启,配开机自启断电也能自恢复。
💡 关键词提示:心跳重连 60s超时复位 全局异常自重启
⚠️ 备注:
- [需自行确认][重点]:"7×24 不间断"和"有没有真实故障率"——仓库没有 uptime/故障率/MTBF 统计,被问别编数,说"靠日志+现场盯、没建成自动化故障率报表",把三层机制讲足
- 自重启掩盖根因:真正的深层 bug 可能被藏住,这层是治标——想说后能加分
追问①:为什么选 Socket.IO 不原生 WebSocket?
自带心跳、重连、房间省了自己写,代价是包大一点;工业场景可靠性>>体积,值。
追问②:自重启会不会掩盖真 bug?
会,自重启治标,根因可能在日志深处。我想把"崩溃现场"做成可分析档案但没做,这是诚实的技术债。
Q8: 检测报告与数据闭环
面试官可能问:从品种配置到报告打印,数据怎么流转?
🗣️ 口述稿:
用 Prisma 建了六模型闭环:品种库(Standard/Mixed)→批次→每次检测→检测报告→ExcelJS/打印。检测记录存 Q、温度、直径、压力、回潮率、判级,还存 calculationDetails 中间过程方便溯源。
💡 关键词提示:六模型 品种双类 calculationDetails溯源
⚠️ 备注:
- 能体现工程质感的三处:品种分"标准(国标写死)/混纺(自定义配比自动算)"、每品种公式独立、记录留中间过程可追溯——挑一个讲"为什么"
- 为什么 SQLite:单机离线,一个 .db 文件备份迁移最简;被问"会不会膨胀"承认到 GB 要分表归档
追问①:为什么用 SQLite 不 MySQL?
上位机单机离线,一个 .db 文件备份/迁移超简单,分布式并发不是场景——按部署形态选库,不是只会 SQLite。
Q9: 操作模式与触摸屏体验
面试官可能问:工业触摸屏交互有什么特殊?
🗣️ 口述稿:
产线工人戴手套+触摸屏,跟 Web 两回事。做了"标准多面/快捷单面自动保存"双模式减少操作步;按钮加大防误触;集成中文输入键盘带手写识别,解决触摸屏没法打字;ECharts 实时曲线用 requestAnimationFrame 合帧渲染避免 100ms 推送卡顿。
💡 关键词提示:双模式 触摸键盘+手写 rAF降频
⚠️ 备注:
- 最有含金量:把键盘搬进上位机(不依赖系统输入法)、手写 TensorFlow.js 离线识别、实时图降频不卡
- [需自行确认]:"TensorFlow.js WebGL 后端""按钮≥48px"这种要么按仓库 package.json 确认、要么注明是策划口径
追问①:实时图怎么防卡?
高频数据不直接 setOption,用 requestAnimationFrame 合并到一帧再渲染,避免 100ms 级推送导致图表每帧都重绘。
🎙️ 行为面试
为什么做这个项目?
公司给纺织厂做智造,客户还在用烘干称重法(一次两小时、误差大),要配套微波检测仪软件。硬件/下位机是对方的,主机+上位机这套从 0 到 1 独立架构开发,我负责让它成为能上产线设备的完整软件层。
💡 关键词:客户痛点 独立0到1 软硬分工
⚠️ 备注:把"硬件不是我的"边界讲清,避免被当吹牛;这是别人后端/硬件不归属你的诚实分割。
最大难点?
- Prisma 在 Electron 打包,查遍 issue、试了好几方向才稳(迁出+asarUnpack+binaryTargets)
- 实时采集从请求-响应改成 100ms 轮询+滑动窗口,是现场翻车逼出来的重构
💡 关键词:Prisma打包 采集重构
⚠️ 备注:讲 1 个真心痛的即可别贪多,把"试错过程"比"我会"更可信。
遗憾/弯路?
- 自动化测试几乎为零——设备不在工位,改一次跑产线验证一遍,效率低;重来先搭 Mock UDP/MQTT 补通信层和计算引擎
- 稳定性"自重启"掩盖根因——兜底能自愈但没把崩溃现场做成可分析报告,深层 bug 可能被藏
- "延迟<100ms""7×24 无故障"没落成可量化监控——是主观/体感结论,不是埋点数据
💡 关键词:零测试 自重启掩盖根因 数字无量化
⚠️ 备注:第三条主动把简历口号降级为"体感",反而显诚实、占主动。
怎么跟前端/后端选型?
桌面上位机不需要前后端分离部署,所以 Express 塞主进程、渲染进程经 IPC 间接调用,比再养一套 Dev Server+反向代理简单;数据库按"单机离线"选 SQLite。每次选型先问"这个场景真要它吗"再选。
💡 关键词:按场景选型 单机离线
⚠️ 备注:把"我会什么用什么"反过来讲成"这个场景要什么"是这题的分水岭。
🃏 极简速记卡(面试前5分钟看)
- Q1 架构:三层+ServiceManager管12服务,优雅关闭
- Q2 Prisma:client迁出+asarUnpack解引擎+锁平台
- Q3 通信:MQTT控制面/UDP数据面,内置Aedes
- Q4 采集:请求-响应→100ms轮询+滑动窗口5点取中
- Q5 公式:Decimal.js全精度+品种化,烘干法对照
- Q6 同步:注册+心跳保活,SQLite全量5min上传
- Q7 稳定:心跳重连/60s超时/异常自重启
- Q8 闭环:六模型数据闭环+calculationDetails溯源
- Q9 交互:双模式+触摸键盘+rAF降频
- 行为 动机:客户烘干痛点;难点:Prisma打包+采集重构;遗憾:零测试+自重启藏bug+数字无量化
上一篇:01-基金助手 fund-helper 下一篇:03-zhihu-fisher