工作总结

发表时间:2026-04-28

【最新】高级Android开发工程师工作总结。

接手这份总结的时候,我刚从仓库管理系统的线上性能排查里抽身。客户那边的技术对接人在工单里留了一句:“问题解决了,今天没再报卡顿。”就这一句话,比什么感谢电话都实在。这半年的工作,我盯了三块:线上性能的真实改善、带团队的方式调整、以及跨团队协作里那些扯皮又不得不磨的事。

一、性能治理:别只看平均值,看设备分布

一季度线上监控显示冷启动P95耗时3.2秒,比上季度涨了0.7秒。我把Top 20的机型数据拉出来,发现低端机(4GB内存以下)的P95高达5.1秒,中高端机只有1.8秒。这个差距说明问题不在网络或接口,就在本地。

用Systrace跟启动流程,发现三个Fragment初始化时,分别往SharedPreferences里写了一个大字符串——每个接近200KB。这倒不是代码写错,而是历史遗留:某个推送SDK要求缓存设备信息,三个模块各自独立实现,没人串起来。修改后统一用一个内存缓存先hold住,等到Application的onTrimMemory回调里再统一落盘。上线后低端机P95降到2.3秒。

但灰度时出了个岔子。一个分支版本的低端机数据没变,排查发现同事合并代码时把判断设备等级的条件写反了——低端机走了旧的同步写入路径。那以后我加了一条规则:所有性能相关的配置开关,必须用单独的单元测试覆盖,并且CI里跑一遍模拟低端设备的测试用例。这比单纯代码审查管用。

二、带人的教训:纸上画图不如让他踩坑

团队里三个年轻人,水平参差。小张写UI快,但一碰线程就懵。我让他把扫码模块里的AsyncTask改成协程,给了他两天。他交上来后,我看了代码:协程用了GlobalScope.launch,页面关了还在后台跑,log里全是CancellationException。我叫他过来,让他自己开Logcat,然后疯狂开关扫码页面十几次。他看着满屏的异常堆栈,自己说“哦,生命周期没绑”。我让他重写,这次必须用viewModelScope,并且在页面销毁时主动cancel一个正在进行的任务。他花了一下午,最后写出来还多了一个防抖——这算他自己悟出来的。

小李相反,逻辑不错,代码写得像天书。变量名叫a、b、tmp,函数五十行不换行。有次他改了一个网络重试逻辑,MR里我看不懂,让他当面给我讲。他讲了五分钟,我提了五个问题,他自己发现漏掉了超时后重试的场景。后来我定了个规矩:每周五下午每人挑自己上周的一个MR,录屏讲五分钟逻辑,放群共享。第一个月大家都不乐意,觉得浪费时间。第三周小张录了一个协程取消的bug排查过程,群里另外两个人说“原来这个地方也会出问题”,气氛才松下来。

三、跨端协作:文档不如抓包,抓包不如一起蹲现场

蓝牙打印模块的固件升级那次,硬件同事发了个协议文档,说“支持重连”。我们按常规写轮询,结果现场信号一抖,同一张单子打了三遍。硬件说是我们的业务层该复位状态,我们说协议没写清楚。最后两个人蹲在实验室,用串口助手把整个通信过程dump出来,发现协议里有两个标志位确实需要业务层主动清零。解决方案很简单:打印成功回调里清标志位,再加一个500毫秒的防抖窗口。从那以后,每次协议变更我都要求对方提供至少三个异常场景的抓包原始数据,不提供我就不接单。

MockServer那套也是。后端经常接口定义和实现不一致,联调阶段才暴露。我搭了一个MockServer,把OpenAPI里所有错误码和边界值都模拟出来,让Android端先跑通再联调。后端有意见,说“这不是增加工作量吗”。我把一个月因为接口不一致导致的返工时间统计出来——累计18小时——发到项目群,后端leader看完就不吭声了。

四、那个仓库系统的卡顿,最后查出来是什么?

上面说的仓库系统卡顿,一开始定位到SQL。用户连续扫五十个条码后返回主界面,界面卡死好几秒。我们用Database Inspector抓到了checkpoint触发频繁。SQLite的WAL模式下,checkpoint默认每积累1024页或每3秒触发一次。扫码动作密集,写入频繁,checkpoint反复跑,阻塞了读操作。改动很简单:把checkpoint改成手动触发,在用户空闲时(监听触摸事件,2秒无操作)执行一次。上线后监控显示,相同场景下帧率从15fps提到52fps。

但这个方案第一版写错了。我同事把手动checkpoint写在了每批写入的最后,结果写入耗时直接翻倍。回退后重新设计状态机,只有写入量超过阈值且当前不在批量操作中才触发。这个弯路花了三天。我把过程写成了故障报告,贴在团队wiki里,标题就叫《一个checkpoint引发的三天折腾》。

五、质量堵在编码阶段的两条硬杠

我不再把问题留给测试团队。今年推了两条规则:第一,每个网络请求必须显式写超时和重试,不写的话Lint直接报错;第二,每个页面销毁时,必须清空Handler的消息队列和协程Job。我写了一个自定义Lint规则,检测Activity的onDestroy里有没有调用clearHandlerAndJobs()。一开始同事觉得烦,有次线上出了个内存泄漏,leakcanary定位正是某个页面没清Handler,大家才认了。

六、说说没做好的

技术债务的取舍上我犯过犹豫。历史模块里有一个图片加载框架,版本很老,但跑得还算稳。我一直想换Coil,评估工作量要两个人两周。产品那边催新功能,我就压下来了。结果那个旧框架在某次系统WebView更新后触发了灰度中的崩溃,修复反而花了三天。教训是:技术债务不是“以后再说”,得给它设一个过期时间,比如下个季度必须动,否则优先级永远排不上。

还有一次版本发布,灰度开到50%时发现crash率从0.1%升到0.4%。我凭经验觉得是某个第三方SDK的问题,没仔细看堆栈就回滚了。后来查出来其实是自己的代码里一个空指针,回滚时连同另一个修复也一起撤了,导致用户多忍受了三天另一个bug。那次以后我定了个规矩:回滚前必须把根因分析写在版本记录里,不能靠直觉。

七、写在最后的话

这半年解决了不少问题,也制造过新问题。技术的本质是取舍,代码写多了反而觉得,守住那些基础的东西——生命周期、线程模型、异常边界——比追新框架重要得多。带人也是,逼他画十遍生命周期图,不如让他自己在线上的log里看到协程没取消的Exception。下阶段我打算把Compose UI迁移提上日程,不过会从那几个边缘页面开始慢慢试。毕竟,摔跟头也得挑个不疼的地方。

    我们精彩推荐工作总结专题,静候访问专题:工作总结

本文网址://www.w286.com/gaofenzuowen/191442.html