惠东移动(微信小程序)— 速记版
📋 速记表(面试前快速扫)
| 题 | 一句话结论 | 关键词 |
|---|---|---|
| Q1 | UniApp 保多端余量,Vue3+RCS 三层 | UniApp 多端 三层分层 |
| Q2 | 微信 code 换 openid→JWT,两层登录态要分 | code换openid JWT 两层态 |
| Q3 | 统一 request 封装:环境/Token/错误分级/Loading | 统一封装 401清缓存 省 |
| Q4 | 统一订单表+extraData JSON,查询字段单独建列 | 统一表 JSON 索引列 |
| Q5 | base-detail+插槽,业务 detail 拆组件 | base+插槽 多态组件 |
| Q6 | autoFill 空字段才填,不覆盖用户内容 | 映射表 空才填 复用 |
| Q7 | 双重库存校验+编辑/浏览双模式 | 双重校验 防超卖 双模式 |
| Q8 | Route-Controller-Service 三层+req.user 越权过滤 | MVC三层 越权过滤 |
| Q9 | pages.json+switchTab/navigateTo 自动判 | pages.json 传参 |
Q1: UniApp + Vue3 架构
面试官可能问:为什么用 UniApp?整体架构?
🗣️ 口述稿:
UniApp 基于 Vue 语法、学习成本低,一套代码可编微信/H5/App。虽然只上了微信端,但架构留了多端余量。前端 30+ 页面由 pages.json 配路由和四 TabBar,蓝色主题;后端 Express+TS 按 Route-Controller-Service 三层,Prisma+MySQL 落库,JWT 认证,Winston 日志。
💡 关键词提示:UniApp多端 pages.json MVC三层
⚠️ 备注:
- 选 UniApp 的真实动机:熟了 Vue、原生要重新学+可能出 H5。代价要能接:对复杂原生能力封装不完整,得条件编译兜底
- [需自行确认]:多端"H5/App 余量"是架构留口子没实测,别吹"都跑过"
- 后端也用 Node:一个人全栈用 TS 省上下文切换,不是"Node 更好"
追问①:多端只上微信,"余量"是吹的吗?
是架构上留了口子但没真正验证,理论上 compile 过去、没实测 H5/App 的真跑。承认反而诚实。
追问②:为什么后端也用 Node 不是 Java?
一个人独立完成,前端熟 JS,全栈 TS 减少上下文切换。这是个人全栈效率优先,不是 Node 更好。
Q2: 微信 OAuth + JWT
面试官可能问:微信登录怎么设计?JWT 怎么用?
🗣️ 口述稿:
前端 uni.login 拿临时 code → 后端换 openid/session_key → 判断新旧用户 → 签 JWT 返回。前端存 token+24h 过期时间,请求统一带 Bearer,401 清缓存跳登录;手机号绑定走 button open-type=getPhoneNumber 拿加密数据后端解密。
💡 关键词提示:code换openid JWT 两层登录态
⚠️ 备注:
- 最能加分的是认知:JWT 过期≠微信登录态过期——openid 还在,进小程序自动静默 uni.login 换 code 再拿新 token,只有微信态过期才重授权
- [需自行确认]:
checkLoginStatus()等前端函数名我没在仓库里逐个核对,别背死;简历若写"refreshToken 无感续期",仓库是否真做双 token 刷新没核对,更可能只是"过期重登"
追问①:为什么过期时间跟 token 一起存前端?
避免每次请求不知道过期、提前本地判断少发无效请求;但真实判据还是 401,前端是缓存,双层判据更稳。
追问②:JWT 存哪里?
存 uni.setStorageSync,小程序有自身隔离。若不核对 refreshToken 无感续期就别说是实现了,更可能是过期重登。
Q3: 网络请求层封装
面试官可能问:请求层怎么封装?
🗣️ 口述稿:
src/utils/request.ts 统一 request。核心:环境切换(DEV 判断本地/线上)、Token 自动注入、错误分级(2xx 正常/401 清缓存跳登录/其它 4xx5xx 弹消息/fail 统一网络异常)、Loading 自动管理、URL 智能拼接、get/post/put/del 快捷方法。
💡 关键词提示:统一封装 错误分级 环境切换
⚠️ 备注:
- 设计驱动:让上层 API 不关心认证和 Loading;值得讲的小点——URL 判断 http(s) 开头是为了复用第三方接口+给 uni.uploadFile 预留
- 401 直接清缓存不做无感刷新:小程序 token 失效概率低、双 token+队列复杂度高收益低,是"按场景砍需求"
追问①:401 为什么不做无感刷新?
小程序 token 失效概率低,双 token+请求队列复杂度高收益低,当时判断不值得。是按场景砍需求不是不会。
追问②:要升级无感刷新怎么做?
拦截器统一:刷新期间其他请求进等待队列、完成批量重发、isRefreshing 锁防并发。能讲一遍说明能从够用迁到更稳。
Q4: 多业务订单系统
面试官可能问:宽带/手机卡/流量包这么多业务订单怎么统一?
🗣️ 口述稿:
难点是 7 种订单数据结构差异大。我用"统一订单表+extraData JSON 字段":通用字段(订单号/状态/金额/联系方式/时间)放表列,业务特有数据全塞 JSON,前端 order-detail 按 source 动态渲染对应详情子组件,一套列表/状态流转复用。
💡 关键词提示:统一订单表 extraData JSON 按source渲染
⚠️ 备注:
- 决策逻辑:先问"建 7 张表会怎样"——列表/流转/详情都要 7 套才选 1 表+JSON;代价是 JSON 不能随便查
- 关键兼得:要查询的字段(手机号/状态)单独建索引列,JSON 只放展示用不查询字段
追问①:JSON 字段怎么查?按手机号找流量包订单?
MySQL 可用 JSON_EXTRACT 但性能差,所以把要查询的字段单独建索引列、JSON 只放展示不查询字段。这个兼得显示踩过坑。
追问②:新增一种业务要改多少?
加一张 detail 组件+登记 source,不碰订单表和其他业务组件。把扩展成本说清就证明设计值。
Q5: 订单详情多态组件
面试官可能问:不同订单详情页怎么组织?
🗣️ 口述稿:
base-detail 放公共展示(状态卡片/联系信息/底部按钮),用 slot extra-details 开插槽,每种业务(宽带/SIM/流量包/商品/维修/回收/快捷)塞进特有字段,order-detail 按 orderType 动态 v-if 加载,底部按钮用 actions prop 按状态动态配。
💡 关键词提示:base+插槽 动态v-if 按钮actions
⚠️ 备注:直接动机是"全写一文件 7 种字段叠一起怕动",拆后每业务只关心自己、base 统一状态样式。
追问①:为什么用插槽不各自成卡?
插槽让"共性卡片骨架+差异内容"分离,布局/状态样式统一不重复;各自成卡就每套都写。
追问②:加"门店自提"新业务复杂度?
加一个 detail 组件插进插槽+登记 source,base 不动。扩展成本小证明设计值。
Q6: 自动填充
面试官可能问:信息自动填充怎么做的?
🗣️ 口述稿:
autoFill.ts 封装"用户信息填一次全局复用":getUserInfo 读登录信息,autoFillCommonFields 用字段映射表(phoneNumber→mobile 等)遍历表单 key,空字段自动填,宽带/手机卡/报修页加"自动填充"按钮一键复用。
💡 关键词提示:映射表 空才填 不覆盖
⚠️ 备注:核心安全前提:只在目标字段为空/空白才填,否则自动填覆盖用户内容坑人。
追问①:映射表太脆,字段名变?
会失效,这是映射表方案脆弱点,我承认它是"够用但脆",更稳改成 UI 字段名统一、后端返回先归一。
Q7: 购物车与库存
面试官可能问:购物车/库存有什么特别?
🗣️ 口述稿:
四件事:商品可用性检测(下架/缺货 isAvailable=false 加灰不可勾选);库存双重校验(不仅看列表返回的 stock,加量时再 getProductDetail 二次确认防超卖);编辑/浏览双模式(批量删除和数量控制互不干扰);购物车下单数据用 setStorageSync 传不用 URL 避免超长。
💡 关键词提示:双重校验 防超卖 编辑/浏览双模式
⚠️ 备注:为什么双重校验——只信列表库存,页面停留久/并发后有人多点几件会超卖,下单前再拉实时库存。但双重校验不能绝对防超卖,真正靠后端下单事务扣减+锁,前端只是第一道。
追问①:双重校验绝对防超卖吗?
不能,真正防超卖要在后端下单事务里扣库存+锁;前端双重校验只减"明摆着超"的情况。边界说清才成熟。
Q8: 后端 MVC 三层(全栈佐证)
面试官可能问:后端怎么分层?权限怎么做?
🗣️ 口述稿:
Express+TS 分 Route→Controller→Service:Route 绑中间件(认证/校验),Controller 只拼参数和响应,Service 放业务规则+Prisma CRUD,Prisma schema 定义模型→migrate 生成迁移→类型安全查询。认证是 JWT 中间件把 userId 挂 req.user,权限分 user/admin 角色。
💡 关键词提示:Route薄Service厚 req.user 越权过滤
⚠️ 备注:
- 真正体现思考的是"普通用户只能查自己数据"——Controller 里处处带 req.user.id 过滤防越权,最易被忽略
- 为什么 Prisma:类型安全+schema/migrate 一体,改 schema 跑 migrate 就行
追问①:JWT 会担心传被推翻吗?怎么加固?
会,JWT 无状态靠签名,单靠它风险偏高;会用更短过期+refresh+必要时机黑名单/服务端会话。知道局限说明不是默认选了就完事。
Q9: 小程序路由与 TabBar
面试官可能问:30 多页面路由怎么管?
🗣️ 口述稿:
pages.json 集中配路由,四 TabBar 页用 uni.switchTab,其余 20+ 普通页 navigateTo。首页封装 navigateTo(url) 自动判断目标是不是 TabBar 决定用哪个。简单参数走 URL query,复杂数据(购物车列表)用 setStorageSync 避免 URL 超长,事件用 uni.$emit/$on。
💡 关键词提示:pages.json switchTab/navigateTo自动判 Storage传参
⚠️ 备注:
- 为什么封"自动判断":TabBar 必须 switchTab,混用会报错/无法切换,收口到一处防坑
- 为什么不能用 Vue Router:小程序页面栈由微信管理、非 DOM history
- 页面返回刷新:getCurrentPages 拿上一页 vm 调 onRefresh,小程序特有
追问①:为什么不用 Vue Router?
小程序页面栈由微信框架管理不是 DOM history,UniApp 编译后映射原生页面配置,pages.json 才是根源。
🎙️ 行为面试
为什么做这个项目?
公司接通信代理门店需求:在线办宽带/买卡/买流量包/报修,替代线下排队。我从 0 独立搭了小程序前端+Node 后端,一人全栈到上线。
💡 关键词:客户需求 一人全栈
⚠️ 备注:一人全栈是亮点但要接住后端问题(Q8),别只讲前端。
最大难点?
多业务订单建模——7 种订单差异大,硬建 7 张表会 7 套列表/流转/详情。最后"统一订单表+extraData JSON+前端多态组件"同时解决表数量、复用、扩展,同时接受"JSON 不能随便查"的代价。
💡 关键词:统一表 extraData JSON 接受代价
⚠️ 备注:把"做了选择+接受代价"讲全,比只讲方案强。
遗憾/弯路?
- 前后端几乎没自动化测试
- 错误码规范不统一——有的中文有的英文,前端处理乱,该定一套
- 图标用外链(iconify)依赖网络,挂了全没,应本地化([需自行确认] 按仓库自查)
💡 关键词:零测试 错误码乱 图标外链
⚠️ 备注:三条都是真实短板;第 3 条若仓库没外链就别编,按实际调整。
怎么跟后端配合?(答全栈/团队两种)
这项目后端也是我写的;若是团队,我会先用 Prisma schema 定好模型、前后端基于它对齐,再用 Apifox/Swagger 维护接口文档。没有团队时也讲清协作边界显得有团队意识。
💡 关键词:schema先行 接口文档
⚠️ 备注:体现"一个人也能讲团队协作姿势"。
上线审核经验?
微信审核严:要 ICP 备案/营业执照;不能诱导分享/跳外链;审核一般 1-3 工作日。[需自行确认] 粤ICP 备案是否真在代码展示,按仓库自查。
💡 关键词:ICP备案 审核红线
⚠️ 备注:老生常谈但答得顺可以,别展开太长。
🃏 极简速记卡(面试前5分钟看)
- Q1 架构:UniApp保多端,Vue3+RCS三层
- Q2 登录:code换openid→JWT,两层态分
- Q3 请求层:统一封装/401清缓存/环境切换
- Q4 订单:统一表+extraData JSON,查询字段建列
- Q5 详情:base+插槽,业务拆组件
- Q6 填充:映射表+空才填+不覆盖
- Q7 购物车:双重校验防超卖+双模式
- Q8 后端:RCS三层+req.user越权过滤
- Q9 路由:pages.json+自动判switchTab
- 行为 动机:门店在线化;难点:多业务建模;遗憾:零测试+错误码乱
上一篇:03-知乎摸鱼 zhihu-fisher 下一篇:05-EMI智慧SOP看板