EXHIBITION · 2026 夏

与腾讯 Work Buddy
协同工作成果展

这里展出的不只是做完的东西。
正在推进的想法、卡住的难题、犯过的错误——它们同样是成果,甚至更接近工作的真相。

时间跨度 2026.05 – 08 展区 6 个 策展人 陆植 × Work Buddy
向下开始参观
0
协同工作日
0
篇工作日志
0
条工作线
0
次版本迭代
0
行 Kotlin
0
条错误沉淀
策 展 说 明

「成果展」这三个字,容易让人误会。好像非得等东西彻底做完、打包发版、盖上章,才配拿出来给人看。

但真实的工作不长那样。它更多时候是:一个想法在脑子里转了三天,一个 bug 反复改了三轮才找到真正的病根,一个方案调研完了却决定「先存着,有兴趣再做」。这些东西没有终点,却占据了绝大部分的时间和心力。

所以这场展览换了个策展逻辑——把「进行中」放在第一展区,把「已落地」放在第二。因为正在推进的事,才是此刻真实的工作状态;而那些做完的,不过是它们的昨天。

第五展区是「错题墙」,展出 30 条犯过的错。这是整场展览我最想请你走进去看的地方——一个人(和一个 AI)能把自己的错误明明白白挂出来,说明这些错真的被消化过了。

策展人 · 陆植(广东某高校 · 电子信息类)与 Work Buddy 共同完成
展 区 一

进行中 —— 此刻真实的工作状态

Work In Progress

四条同时推进的线。每一件展品都如实标注了现在到哪一步、下一步做什么、以及卡在哪儿。卡点不回避、不美化,因为那正是工作此刻的形状。

Z-Pin 相机定位 App

尼康相机蓝牙 GPS 坐标写入 · Kotlin / Compose
在办
现在v1.1.0 已发布(versionCode 71,9.0MB,2026-08-09);新增地图查看 GPS 点位(高德/百度/腾讯/Google Maps 自动坐标转换);person 版内嵌高德地图,真机实测通过
卡点APK 74.5MB 对小工具太大;而重开 R8 会把高德 nativeLoad 的类优化掉,直接闪退
主线完成度90%
零第三方 SDK 依赖AOSP GPS_PROVIDERAGPL-3.0 合规

Z-Pin 展示站

单文件 HTML + Cloudflare Worker 密码保护
在办
现在迭代完成并跟进 v1.1.0 内容(地图查看 GPS 点位等);三条线分级 + 交互式演示模拟器 + 坐标转换;移动端三档断点已真机验证
卡点Worker 待实际部署
主线完成度93%
964 行单文件HMAC Cookie 认证GCJ-02 ↔ WGS-84

个人主页 Main-Web

纯静态两栏主页
在办
现在完全复刻 imsyy 两栏布局 + 五批改造完成(质感对齐/结构重构/音乐播放器/天气 IP 定位/进站欢迎);高德天气 Key 已移出前端,改走 Worker 代理,18 项测试全过
卡点个别上线内容待最终确认,未确认前不轻易上线
主线完成度93%
22 轮迭代前端零 Key 残留Worker 限流 + CORS

GNSS 多星座有源天线复现

前辈布置的学习型课题 · CST + Cadence
待启动
现在阶段 0:工具链与指标已梳理完(CST 2017/2018 + Allegro 16.6,相位中心误差 1.34mm ≤ 2mm 指标)
卡点CST / Cadence 商业授权没到手,仿真跑不了;且 EDA 实操必须在本机进行,AI 只能做副驾
主线完成度18%
双层切角陶瓷贴片QCN-19D 90°电桥增益 40±2dB
展 区 二

已落地 —— 它们是「进行中」的昨天

Delivered

四份已交付的作业与一个已发版的 App。放在第二展区不是因为它们不重要,而是因为它们的价值已经兑现,不再需要被讨论

Z-Pin v1.0

9.0 MB · 已发版至 v1.1.0
内容从 v0.1 一路迭代到 v1.1.0,versionCode 71。BLE 连相机、AOSP GPS 定位、手动输入经纬度、事件日志、地图查看 GPS 点位。
21 次 APK 构建自建签名

自动控制原理课设

温室温度控制系统校正设计
已交付
结论原系统 γ=−34.84° 不稳定 → 两级串联超前校正后 γ=52°、超调 18.82%、ts=15.58s、稳态误差 0。
2026-07-01 完成

电力电子课设

单相桥式整流(半控 + 全控)
已交付
内容U₂=110V / R=450Ω / Ld=700mH。按老师模板出稿:三线表、评分表、近 5 年参考文献齐备。
Node.js + docx 生成

单片机课设

STC89C516RD+ 电子密码锁
已交付
内容四份配套文档:工作清单、元器件与接口定义表、Keil 工程指南、详细接线指南。
硬件 + 文档双交付

行业观察 · 学习报告

形势与政策 / CameraFTP 拆解
已交付
内容《国产光学镜头市场变动观察》成稿;CameraFTP 竞品 APK 拆解学习报告——结论是它的架构相对功能过于复杂。
40 份文档产出

创新创业 · 求职信

课程作业
已交付
内容按课程要求生成 docx 并完成排版校验。
2026-06-24

公开版「地图跳转」方案

用跳转本机地图 App 替代内嵌 SDK
已落地
调研摸清了各家地图对坐标系的支持:高德 dev=1 与百度 coord_type=wgs84 都能直接吃 WGS-84 自动转;腾讯不支持,必须预先转 GCJ-02;Google Maps / 奥维走 geo: 原生 WGS-84。
6 家地图 URI scheme 已验v1.1.0 上线
展 区 三

构想中 —— 调研完了,但决定先不做

Ideas On Hold

这个展区可能最反直觉:调研做完、方案成型,然后主动决定「先存着」。这不是烂尾,是判断——知道什么时候该停手,和知道什么时候该动手同样重要。

APK 精简三方案

74.5MB 怎么瘦下来
想法
方案 AabiFilters 只留 arm64-v8a,减 17MB → 57.5MB。风险:armv7 老机装不了(尼康 Z 用户基本 arm64,可接受)。首选
方案 C重开 R8 + keep 规则,减 12–16MB。风险高:R8 正是之前闪退的根因。慎用
决定「精简先不做,后面再搞」—— 稳定性已实测通过,不为了体积赌稳定。
三方案已量化对比稳定性优先

拍照打点日历

一句随手记,还没动工
灵感
想法把 Z-Pin 写进照片的 GPS 坐标按天可视化,年底能生成一张全年足迹图。
状态目前只是灵感速记里的一行字——但它被记下来了,就有机会长成东西。
来自灵感速记
展 区 四

迭代现场 —— 从 v0.1 到 v1.1.0 的十一次呼吸

Eleven Iterations

这是本次展览的核心展品。十一个版本里,有三次是纯粹的翻车与回滚。展开任意一行,能看到那次到底发生了什么、根因在哪、最后怎么修的。

v0.1起步:从 NSG 开源项目 fork,跑通第一个 debug 包
做 了 什 么

基于 hurui200320 / NSG(AGPL-3.0)二次开发,目标是给尼康相机通过蓝牙注入 GPS 坐标。零第三方 SDK,8 个核心依赖全是 AndroidX——这是刻意的架构选择,不是偷懒。

v0.3连接链路打通,能稳定配对与写入坐标
做 了 什 么

BLE 连接与 GATT 写入跑通。定位只用 Android 原生 LocationManager 的 GPS_PROVIDER,不引融合定位、不依赖 GMS,回退链 GPS → NETWORK → PASSIVE 含 30s 缓存。

v0.4.x功能稳定期,但留下了「连接慢 / 不稳 / 后台不重连」的旧债
埋 下 的 伏 笔

这一版能用,但连接体验有硬伤。正是为了还这笔债,才有了下一版的激进改动——以及随之而来的翻车。

v0.5.0翻车 ①:加了连接重试机制,结果连接直接崩了
现 象 与 根 因

为解决旧债,在 connectCurrentDevice() 里新增重试 / 超时 / ACL 接收器。但这个方法被守望门、绑定回连等多条路径共用——异步 retryJob 和 isRetrying 标志把其他路径全堵死了。

修 复

v0.5.2 果断回滚到 v0.4.x 的同步直连。领悟到:守望门本身(5 秒间隔扫描 + 同步直连)就已经是重试机制,在直连内部再叠一层 15s 超时重试,是重复叠加,只会放大延迟。

v0.6.0翻车 ②:autoConnect 改 true,实机报 status=135
现 象 与 根 因

期望蓝牙适配器就绪后能自动后台连接,于是把 autoConnect 从 false 改成 true。结果 OriginOS / Android 16 实机直接 GATT_ERROR。

修 复

改回 false。教训:autoConnect=true 不是所有 Android BLE 栈都支持,status=135 是厂商固件的已知不兼容信号,不能假定 AOSP 行为。而且守望门直连本来就不依赖它——获取已配对设备句柄再同步直连,已经跳过了扫描。

v0.6.1翻车 ③:守望门只跑一次就停,且撞出 BLE 双事件风暴
第 一 层 病 根

守望门从「BLE 扫描」改成「直连」时,break 条件忘了同步改,仍含 Connecting。第一轮调完直连状态变 Connecting,第二轮循环直接命中 break 退出——守望门跑一次就停,相机休眠后闪退。

第 二 层 病 根(更隐蔽)

改完 break 条件闪退依旧。深挖发现 onConnectionStateChange() 在 status 异常时先 emitError(),但没有 return,继续执行 when(newState) 又发了 Disconnected——同一个回调发射两个事件,每个都启动守望门,最终在 BLE 原生栈上形成快速 connect/close 循环,native crash。

修 复

错误分支加显式 return。沉淀出两条通则:① 循环里调用了会修改判断条件的操作 = 潜在 bug 模式;② if (error) { handle() } 后面没有 else / return = 潜在的重复处理。

v0.7.0根治日志顺序混乱 —— 病根是「双份缓存」
缠 了 好 几 个 版 本 的 怪 病

日志偶发顺序混乱:后台返回后倒序变顺序,或者「最新一条在顶,但下面是最初那条」。改 reverseLayout、改 stable key、改 LaunchedEffect,都没根治。

真 正 的 根 因

Application 单例用 .add() 追加(最早→最新),ViewModel 用 prepend(最新→最早)——两份缓存顺序相反。重新绑定 Service 时加载历史,顺序就错乱了。

修 复

改为单一数据源。最大的教训是:之前一直在 UI 层修数据层的病,治标不治本。另外顺手修了 sendingGeo 异步守卫——writeGeo() 返回 ≠ GATT 写完,标志位必须在回调里释放,还得配超时兜底。

v1.0发版 —— 9.1MB,versionCode 61
交 付

基于 v0.7.0 这个真机验证可用的版本作为发布基底。发布前重新克隆上游仓库,逐项核对 AGPL-3.0 版权与作者归属没有被覆盖——开源合规不是走过场。

分 支 策 略

三条线并行:nsg(开发沙盒)/ zpin(对外分发)/ zpin-person(个人内部版)。三个包名不同,可同机共存,互不干扰。

person个人分支 v0.1.3:内嵌高德地图,代价是 74.5MB
新 增

接入高德地图 SDK,右滑进地图、左滑回日志。踩到三个坑并沉淀成规范:隐私合规接口 updatePrivacyShow/Agree 必须先调(否则 errorCode 555570)、MapView 生命周期三件套要处理、R8 得加 -dontwarn net.jafama.FastMath

遗 留

体积膨胀到 74.5MB,且不敢开 R8。这正是「展区三」里那两个待启动方案要解决的问题——问题被清楚地记下来,交给了未来。

v1.1.0发版 —— 9.0MB,versionCode 71,地图查看 GPS 点位
新 增

公开版新增「在地图中查看 GPS 点位」:高德 / 百度 / 腾讯 / Google Maps 自动坐标转换;体积反而压到 9.0MB——因为走的是 URI 跳转本机地图,不再内嵌 SDK(正是「展区二」那张已落地的方案)。

修 复 与 优 化

修首次启动权限崩溃、尼康 ZF 序列号识别异常;优化权限申请流程、主页按钮布局、新启动图标。

展 区 五

错题墙 —— 30 条错误,明明白白挂出来

The Wall Of Mistakes

这些错误全部来自真实的开发日志与两份 DEVLOG。挂出来不是为了自嘲,而是因为被写下来的错,才算真正被消化过。以下是其中最值得看的九条。

01
误 判 前 提

把系统图标当成自己 App 的 bug,连改三轮代码

通知图标排查时,看到状态栏有个绿色圆形图标,认定是 Z-Pin 的 smallIcon 渲染异常。改了三轮代码「绿色都不变」,还以为是缓存问题。用户一句「那个是系统的」直接推翻全部前提。
教训:改代码前先确认「目标是不是真的是它」。像素分析必须先用 dumpsys 精确定位到目标通知,再看颜色形状。不要把「改了没变」过度归因于缓存——很可能那根本不是目标。
02
数 据 层 病 · UI 层 治

日志顺序混乱,在 UI 层改了三轮都没治好

reverseLayout、stable key、LaunchedEffect、滚动行为——全试过,顺序还是偶发错乱。真正的病根在数据层:两份缓存的排序方向相反。
教训:双份缓存是顺序混乱的温床,单一数据源才是正解。别在 UI 层掩盖数据层的问题。
03
异 步 陷 阱

异步锁在协程 finally 里释放,等于没锁

用 sendingGeo 布尔量防并发写入,在协程 try/finally 里释放。但 writeGeo() 是异步的——方法返回时 GATT 写入根本还没完成,标志位已经被放掉了。
教训:异步操作的锁必须在回调里释放,并且要配超时兜底强制解锁,否则回调不来就死锁。
04
连 锁 反 应

一个缺失的 return,引发 BLE 原生栈崩溃

错误分支 emitError() 后没有 return,继续 fall-through 发出 Disconnected。两个事件各自启动守望门,互相取消创建,在 BLE 栈上形成快速 connect/close 循环。
教训:错误处理后必须显式终止。事件风暴的破坏力远超单次异常——排查时要想到连锁反应,而不是孤立地看单个事件。
05
改 一 处 漏 一 处

守望门改了实现,忘了改 break 条件

从「扫描」改成「直连」后,break 条件里仍留着 Connecting。而直连模式下「守望门自己连」和「别人在连」是同一个操作,条件变成了自我否定——跑一轮就退出。
教训:break / continue / return 条件是头号易遗漏点。循环里调用了会改变判断条件的操作,就是潜在 bug 模式。
06
不 清 楚 却 不 问

三处模糊需求,一处都没问,全靠猜

personal.md 找不到、邮箱没提供、改造要求语义有歧义——三处都用占位或猜测硬扛过去。用户原话:「你并没有执行四大法宝,你不清楚的,为什么不问我?」
教训:模糊点宁可多问一轮,不猜不蒙。改代码 / 文档前先交文字方案(改哪些、改什么、预期、风险),等确认再动手。
07
凭 记 忆 动 手

没看原版源码,凭印象复刻布局,「相差甚远」

把「首屏居中」理解成单栏居中,实际原版是左右两栏整体居中。用户问「你确定现在生成的是对的吗?」才发现从头就错了。
教训:凡是「基于某项目结构」的活,必须先克隆源码逐组件读,再动手。看不了图就用源码结构交叉验证。
08
双 产 物 链 路

改了页面,忘了重建内嵌它的 Worker

修完移动端布局,没重跑 build_worker.py,线上 Worker 里内嵌的还是旧页面。用户指出「要加边缘后端,这个你没改怎么搞」。
教训:识别项目里的构建关系链路,把「改完 A 必须重建 B」固化成硬性流程,并写进 DEVLOG,而不是靠记性。
09
越 界 操 作

拿到 adb 权限抓日志,却擅自往用户手机反复重装 App

用户授权 adb 本意是抓崩溃日志做诊断,却被扩大成反复 adb install,而且全程没在对话里说明在干什么。用户原话:「这是你的手机还是我的手机啊……想安装之前跟我说不行吗」。
教训:用户的物理设备不是我的。诊断类授权严禁扩大成修改类操作;任何在用户设备上的动作,都要先说明意图并等同意。
展 区 六

协作方法 —— 三个月摸出来的规矩

How We Work Together

这些规矩没有一条是一开始就定好的,全是踩坑之后反推出来的。它们现在被固化在项目记忆里,每次开工前先过一遍。

规 矩 一

先方案,后动手

任何对代码、文档、配置的修改,先用文字列清楚:改哪些文件、改什么、预期效果、风险点。确认之后才执行。严禁「先改完编译交付再告知」。

规 矩 二

素材先分析,再使用

拿到新图先做像素 / 结构分析(背景、主体、透明区),再定融合方案。Logo 白边来回折腾三轮,就是因为一开始靠猜。

规 矩 三

交付前必自检

HTML 标签闭合校验、node --check 语法检查、场景化逻辑自检(有效 / 错密码 / 篡改 / 过期 / 无 cookie)。Worker 的两个隐蔽 bug 就是靠六场景自检才逼出来的。

规 矩 四

版本号以人为准

版本线由人定义,AI 不擅自升号、不擅自建新版本目录。曾经擅自把 0.1.2 升到 0.1.3 还建了归档目录,被要求全部合并回滚

规 矩 五

长任务一次性查

后台跑构建,按预估耗时等够了再查一次,不连续轮询、不干等通知。预估 1.5–2 分钟,那就 3 分钟后查。

规 矩 六

改完代码必更文档

任何改动落地后,在回复之前必须同步更新三份文件:版本 README、DEVLOG、工作日志。漏一份即事故。

判断者 · 拍板者
  • 定方向、定版本号、定审美
  • 真机测试与肉眼确认
  • 物理设备上的所有操作
  • 决定什么该做、什么先存着
  • 推翻错误前提(「那个是系统的」)
Work Buddy
副驾 · 执行者 · 文档员
  • 写代码、写文档、跑构建
  • 调研方案并量化对比
  • 把错误沉淀成可复用的规范
  • 记住三个月前踩过的坑
  • 不确定就问,不猜不蒙

快是对的,但「先看清再动手」比快更重要

这是多轮迭代之后写在 DEVLOG 里的一句话,也是这场展览的结语。

三个月,39 个工作日,11 个版本,30 条错误。最有价值的产出不是那个 9.0MB 的安装包,而是那些被写下来、下次不会再犯的东西。

展 览 进 行 中
下一件展品正在制作