大家好,我是 shixin。
一转眼,我从事安卓开发工作已经六年有余,对安卓开发甚至软件开发的价值,每年都有更进一步的认识。对未来的方向,也从刚入行的迷茫到现在逐渐清晰。我想是时候做一个回顾和展望了。
这篇文章会先回顾我从入行至今的一些关键点,然后讲一下经过这些年,我对软件开发的认知变化,最后分享一下后面的规划。
人太容易在琐碎生活中迷失,我们总是需要记住自己从哪里来,才能清楚要到哪里去。
入行至今的一些关键节点
2014~2015:开始安卓开发之旅
说起为什么做安卓开发,我很有感慨,差一点就“误入歧途”😄。
当初在大学时,加入了西电金山俱乐部,俱乐部里有很多方向:后端、前端、安卓、Windows Phone 等。
由于我当时使用的是三星 i917,WindowsPhone,所以就选了 WinPhone 方向。
当时还是 iOS、安卓、WinPhone、塞班四足鼎立的时代,WinPhone 的磁贴式设计我非常喜欢,加上设备的流畅性、像素高,一度让我觉得它可能会统治移动市场。
结果在学习不到 2 个月以后,我的 WinPhone 意外进水了!我当时非常难过,一方面是对手机坏了的伤痛,另一方面也是对无法继续做 WinPhone 开发很遗憾。对于当时的我来说,再换一台 WinPhone 过于昂贵,只好换一台更加便宜的安卓机,因此也就转向学习安卓开发。
后面的故事大家都知道了,因为 WindowsPhone 缺乏良好的开发生态,支持应用很少,所以用户也少,用户少导致开发者更少,恶性循环,如今市场份额已经少的可怜。
现在回想起来,对于这件事还很有感慨,有些事当时觉得是坏事,拉长时间线去看,未必是这样。
当时还有一件目前看来非常重要的决定:开始写博客,记录自己的所学所得。
在开发项目时,我经常需要去网上搜索解决方案,后来搜索的多了,觉得总不能一直都是索取,我也可以尝试去写一下。于是在 CSDN 注册了账号,并于 2014 年 10 月发布了我的第一篇原创文章。
后来工作学习里新学到什么知识,我都会尽可能地把它转换成别人看得懂的方式,写到播客里。这个不起眼的开始,让我逐渐有了解决问题后及时沉淀、分享的习惯,受益匪浅。
2015~2017:明白项目迭代的全流程
在学习安卓开发时,我先看了一本明日科技的《Android 从入门到精通》,然后看了些校内网的视频,逐渐可以做一些简单的应用。安卓开发所见即所得的特点,让我很快就可以得到正反馈。后来又去参加一些地方性的比赛,获得一些名次,让我逐渐加强了从事这个行业的信心。
在 2015 年时,偶然参加了一家公司的招聘会,在面试时,面试官问了一些简单的 Java 、安卓和算法问题。其中印象最深的就是会不会使用四大组件和 ListView。在当时移动互联网市场飞速发展时,招聘要求就是这么低。以至于现在很多老安卓回忆起当初,都很有感慨:“当初会个 ListView 就能找工作了,现在都是八股文” 哈哈。
到公司实习后,我感触很多,之前都是自己拍脑袋写一些简单的功能,没有开发规范、发布规范,也没有工程结构设计、系统设计,更没有考虑性能是否有问题。真正的去开发一个商业项目,让我发现自己不足的太多了。
因此在完成工作的同时,我观察并记录了项目迭代的各个流程,同时对自己的技术点做查漏补缺,输出了一些 Java 源码分析、Android 进阶、设计模式文章,也是从那个时候开始,养成了定期复盘的习惯,每次我想回顾下过去,都会看看我的成长专栏。
2017~2020:提升复杂项目的架构能力和做事意识
第一个项目中我基本掌握了从 0 到 1 开发一个安卓应用的流程,但对安卓项目架构还只停留在表面,没有足够实践。
在 2017 年,我开始做喜马拉雅直播项目,由于喜马拉雅在当时已经有比较多年的技术积累,加上业务比较复杂,在架构设计、编译加速、快速迭代相关都做了比较多的工作,让我大饱眼福。
同时直播业务本身也是比较复杂的,在一个页面里会集成 IM、推拉流等功能,同时还有大量的消息驱动 UI 刷新操作,要保证业务快速迭代,同时用户体验较好,需要下不少功夫。
为了能够提升自己的技术,在这期间我学习了公司内外很多框架的源码,通过分析这些框架的优缺点、核心机制、架构层级、设计模式,对如何开发一个框架算是有了基本的认识,也输出了一些文章,比如 《Android 进阶之路:深入理解常用框架实现原理》。
有了这些知识,再去做复杂业务需求、基础框架抽取、内部 SDK 和优化,就容易多了。
在开发一些需求或者遇到复杂的问题时,我会先想想,之前看的这些三方框架或者系统源码里有没有类似的问题,它们是怎么解决的? 比如开发 PK 功能,这个需求的复杂性在于业务流程很多,分很多状态,咋一看好像很复杂,但如果了解了状态机模式,就会发现很简单。借用其他库的设计思路帮我解决了很多问题,这让我确信了学习优秀框架源码的价值。
除了技术上的提升,在这几年里,我的项目全局思考能力也提升很多。
由于我性格外向,和各个职能的同学沟通交流比较顺畅,领导让我去做一个十人小组的敏捷组长,负责跟进需求的提出、开发、测试、上线、运营各个环节,保证项目及时交付并快速迭代。
一开始我还有些不习惯,写代码时总是被不同的人打断,比如产品需求评审、测试 bug 反馈、运营反馈线上数据有问题等等,经常刚想清楚代码怎么写,正准备动手,就被叫去开会,回来后重新寻找思路。
后来在和领导沟通、看一些书和分享后,逐渐对写代码和做事,有了不同的认识。代码只是中间产物,最终我们还是要拿到对用户有价值、给公司能带来收入的产品,要做到这个,眼里除了代码,还需要关注很多。
2020~至今:深入底层技术
在进入字节做基础技术后,我的眼界再一次被打开。
字节有多款亿级用户的产品,复杂的业务常常会遇到各种意想不到的问题,这些问题需要深入底层,对安卓系统的整个架构都比较熟悉,才能够解决。
上图是安卓系统架构图,之前我始终停留在一二层,在这一时期,终于有了纵深的实践经验。
比如帮业务方解决一个内存问题,除了要了解内存指标监控方式,还要知道分析不同类型内存使用的工具及基本原理,最后知道是哪里出了问题后,还要想如何进行体系化的工具,降低学习成本,提升排查效率。
问题驱动是非常好的学习方式。每次帮助业务解决一个新问题,我的知识库都会多一个点,这让我非常兴奋。之前不知道学来干什么的 Linux 编程、Android 虚拟机,终于在实际问题中明白了使用场景,学起来效率也高了很多。
对软件开发的认识
前面讲了个人的一些经历,包括我怎么入的行,做了什么项目,过程中有什么比较好的实践。下面讲一下我从这些具体的事里面,沉淀出哪些东西有价值的结论。
主要聊下对这两点的认识:
- 职业发展的不同阶段
- 技术的价值
职业发展的不同阶段
第一点是对职业发展的认识。我们在工作时,要对自己做的事有一个清晰的认识,它大概属于哪一个阶段,怎样做可以更好。
结合我这些年的工作内容、业内大佬所做的事情,我把软件开发者的职业发展分这几个阶段:
- 使用某个技术方向的一个点开发简单项目
- 使用某个技术方向的多个点及某条线,开发一个较为复杂的业务或系统
- 掌握某个方向的通用知识,有多个线的实践,可以从整体上认识和规划
- 不限于该方向,能从产品指标方面出发,提供全方位的技术支持业务角度,端到端关注指标
第一个阶段就是使用某个技术方向的一个点完成业务需求。拿安卓开发者来说,比如使用 Android SDK 自定义布局,完成产品要求的界面功能。这个阶段比较简单,只要能够仔细学习官方文档或者看一些书即可胜任。拿后端来说,比如刚接手一个小项目,日常工作就是使用 Spring 等库开发简单的接口,不涉及到上下游通信、数据库优化等。
第二个阶段,你做的项目更加复杂了,会涉及到一个技术方向的多个点,这时你需要能把这些点连起来,给出一个更体系化的解决方案。
拿安卓开发者来说,比如在自定义布局时,发现界面很卡顿,要解决这个问题的话,你就要去了解这个自定义 View 的哪些代码流程影响了这个页面的刷新速度。这就相当于是从一个点到另一个点。怎么连起来呢?你需要去研究渲染的基本原理,分析卡顿的工具,找到导致卡顿的原因,进行优化。这个过程会对流畅性有整体的认识,能够对相关问题有比较全面的分析思路、解决手段,从而可以开发相关的分析工具或优化库。 如果能达到这个程度,基本就算是一个高级工程师了,不只是做一个模块,还能够负责一个具体细分方向的工作。
第三个阶段,掌握某个技术方向的通用知识,有多个线的实践,能够连线为面,同时给工作做中长期的技术规划。
拿安卓开发来说,刚才提到你通过解决卡顿问题,在流畅性这方面有了比较多的实践;然后你又发现内存有问题,去了解了内存分配、回收原理,做出内存分析优化工具,这样就也有了内存的一个体系化的实践。再加一些其他的优化经验,比如启动速度、包大小等。把这些线连起来,就得到了一个性能监控平台,这就是有把多条线连成一个面。
还有比如说你发现项目打包和发布过程中的一些痛点,并且能够做一些实践解决,最后如果能够把这些优化项连起来做一个统一的系统,给出完整的 DevOps 方案,提升开发、发布、运维的效率。能够把这个系统搭建起来,有比较深入的经验,那就可以成为“技术专家”了。
再往上走就不只是做技术,而要更多思考业务。技术最终都是要为业务服务。职业发展的第四个阶段,就是不局限于某个技术方向,能够从产品的业务规划、业务指标出发,给产品提供技术支持。
你首先要明白公司业务的核心指标是什么,比如说拿一个短视频应用来说,它核心指标除了常规的日活、用户量,还更关注视频的播放率、停留时长、页面渗透率等。了解这些指标以后,你要思考做什么可以有助于公司提升这些指标。结合业务指标反思当前的项目哪里存在优化空间。
有了这个思路并且知道可以做什么以后,你可以做一个较为全面的规划,然后拉领导去讨论可行性。这时你不能再局限于某一端,不能说我只是个安卓开发,其他部分都找别人做。一般在项目的价值没有得到验证之前,领导不会轻易给你资源,因此第一个版本迭代肯定是要靠你自己,从前到后独立完成,做一个 MVP 版本,然后让领导认可了这个系统的价值,才有可能会分给你更多的资源做这件事。
总结一下对职业发展的认识:第一阶段只做一些具体的点;第二阶段做多个点,需要能够连点成线;第三个阶段需要围绕这些线提炼出通用的知识,然后做到对业务/技术项目有整体的认识;第四阶段能够从业务指标出发,做出有价值的系统/平台。
技术的价值
说完职业发展的不同阶段,接下来聊下技术对业务的价值。
技术是为业务服务的。根据业务的不同阶段,技术的价值也有所不同:
- 业务从 0 到 1 时,帮助业务快速确定模式
- 业务从 1 到 100 时,帮助业务快速扩大规模
- 最卓越的,用技术创新带动业务有新的发展 (Google、AWS、阿里云)
业务从 0 到 1 时
我一开始做的工作,业务就是处于确定模式期间。业务上反复试错,项目常常推倒重来,会让程序员觉得很有挫败感。
这个阶段很多程序员都会发挥复制粘贴大法,产品经理说要新增一个功能,就复制一份代码稍微改一改。
如果说目前就是在这种业务中,该怎么做呢?如果我回到当时那个情景,我可以做什么让公司业务变得更好呢?
我总结了两点:在高效高质量完成业务的同时,思考如何让业务试错成本更低。
如何让业务试错成本更低呢?大概可以有这些方式:
- 提供可复用的框架
- 提供便捷的数据反馈机制
- 多了解一些竞品业务,在产品不确定的时候,给一些建议
第一点:尽可能的抽象相似点,减少重复成本。
如果产品每次都给你类似的需求,你可以考虑如何把这些重复需求抽象成一些可以复用的逻辑,做一个基本的框架,然后在下次开发的时候能够去直接用框架,而不是每次都从头开始。我平时工作也常常问自己“我现在做的事有哪些是重复的,哪些是可以下沉的”。
就安卓开发来说,这个阶段,可以做好基础建设,提供插件化、热修复、动态化框架,帮助业务快速发版,自研还是第三方看公司财力。
如果你说这些太复杂了我做不来,那就从更小的层面做起,比如某个功能原本需要多个接口多个界面,看能不能改成接口参数可配置,界面根据参数动态生成(也就是 DSL)。
第二点:提供便捷的数据反馈机制。
在产品提需求时,你可以问问产品这个需求出于什么考虑,有没有数据支撑?比如说产品需求是某个按钮换个位置,那你要搞清楚,为什么要换,换完之后会导致页面打开率提升吗?要有这种数据驱动的理念。
如果公司做决策时缺乏相应的数据,你可以主动地去提供这种数据反馈机制。比如说开发一个埋点平台、数据监控平台。尽可能地让业务有数据可看,能够数据驱动,而不是像无头苍蝇一样盲目尝试。
如果无法做一个这么大的系统,那可以先从力所能及的做起,比如说战略上重视数据;做好数据埋点;思考做的功能,目前有哪些数据是核心的,这些数据有没有上报,不同版本的数据是升还是降等。
好,这是第一个阶段,技术对业务价值就是帮助业务快速确定模式。第二个阶段就是业务快速扩大规模时,技术的核心价值是什么呢?
业务从 1 到 100 时
业务正在快速扩大规模时,需要把当前跑通的业务模式复制到更多的地方,同时能够服务更多的用户。这个阶段,技术能够提供的价值主要是两点。
- 快速迭代(这一点其实无论什么阶段)
- 提升质量(用户规模日活上亿和日活一万,需要面对的挑战差异也是这个数量级)
第一点:快速迭代
虽然快速迭代是业务各个阶段都需要做到,但和从 0 到 1 相比,从 1 到 100 的阶段会有更多的挑战,除了个人速度,更要关注团队的速度。
团队的速度如何提升?可以参考后端的单体到微服务、前端的单仓到多仓的演变过程及原因。
这个阶段主要有这几点问题:
- 多人协作代码冲突
- 发布速度慢
- 出问题影响大,不好定位
具体到安卓项目,几百人开发和三两个人开发的,复杂度也是几百倍。我们可以做的是:
- 下沉基础组件,定义组件规范,收敛核心流程
- 拆分业务模块,设计业务模板,单独维护迭代
- 探索适合业务的新方式:跨端(RN Flutter KotlinMultiplatform)、动态化、多端逻辑一致(C/C++ Rust)
第二点:提升质量
和日活几万的项目相比,日活千万甚至上亿的产品,需要应对的质量问题更加显著。在这个阶段,我们不仅要满足于实现功能,还要能够写的好,更要能够了解底层原理,才能应对这样大的业务量。
有了大规模的用户后,你会遇到很多奇怪的问题,不能疲于每天去解决一样重复的问题,那你就需要从这些问题中找到一些共通的点,然后提炼出来,输出工具、解决方案甚至平台。
这就需要你从问题中磨练本领,站在更高的层面思考自己该具体的能力、思路和工具。
在解决问题的时候,除了当下这个问题,更需要做的是把这个问题解构、归类,抽象出不同问题的相似和差异,得出问题分析流程图。
同样是分析内存泄漏,有的人可能只知道使用 Leakcanary,但你还可以思考的更深入,比如:
- 先定义问题:什么是泄露?
- 泄露是申请了没有释放或者创建了没有回收
- 内存泄露怎么分析?
- 找到创建和销毁的点
- 在创建的时候保存记录,销毁的时候删除这个记录,最终剩下来的就是泄露的
有了基础的逻辑,就可以把它套用到各种问题上:
- Native 内存泄漏:在 Native 内存分配和释放 API,做记录
- 图片使用不当:在图片创建、释放的 API 里做记录
- 线程过多:在线程创建、释放的 API 里做记录
在遇到一个新问题时,发现和之前解决过的有点像,但又不知道哪里像。怎么办?回头去思考新旧的两个问题,它的本质是什么?有什么相似的分析思路?
这个思考训练的目的,就是提升举一反三的能力。大规模应用可能各种问题,需要你一方面提升技术,另一方面分析问题的思路和能力上也要提升,不能看着一个问题就是一个问题,要做到看到一个问题,想到一类问题。
技术上达到一专多能,软实力上持续提升。
硬实力
专业
如果你是安卓开发,最好在某个有细分领域很擅长,比如音视频、跨端、动态化、性能优化。
我目前主要是做优化,后面需要继续补充的知识:
- Linux 内核原理
- Android 虚拟机原理
- 项目从开发、编译、发布、数据分析各个流程的效率提升方式
多能
前面提到职业发展的第四个阶段:
不限于该方向,能从产品指标方面出发,提供全方位的技术支持
我希望可以具备独立完成一个从前到后的能力。目前已有的经验:
- 使用 TypeScript + React + Electron 开发桌面端软件
- 使用 SpringMVC 开发简单的内部系统
后面需要加强的点:
- 熟练掌握前端的 js、打包、优化等知识
- 后端技术达到中级
还有这些点需要长期关注:
- Flutter 更新频繁,有一些尝试效果还不错,一套代码多端运行,节省开发成本
- 掌握 DevOps 理念及实践
最终目的:
- 具备独立完成一个有价值的系统的能力
- 具备对研发整个流程的完善、优化能力
软实力
除了技术,我也有很多软实力需要继续提升,今年主要想提升的就是同频对话的能力。
什么是同频对话?
同频对话就是根据听众的角色和他的思考角度去转换你的表达内容。
比如说我们在和领导汇报的时候,你要去讲你做的一个系统,你就要从他角度去表达。他可能关注的是整体流程、系统的难点、瓶颈在哪里,带来的收益是什么。那你就不能只讲某个模块的细节,而要从更高的层面去思考和表达。
为什么要提升呢?
随着工作年限的增加,市场对我们的要求是越来越高的,除了写代码,对表达能力的要求也是越来越高的。
一开始刚入行,你就是做一个执行者,只要多动耳朵、眼睛、手,实现别人要求你做的功能。
后来你的能力逐渐提升以后,有机会设计一个模块的时候,你就需要多动脑力去思考,去复设计这个系统的输入输出、内部数据流转等。
再往后走的话,你可能会有一些资源,那就需要能把你的想法完整地表达出来,让别人帮你去贯彻落地。这其实是一种比较难得的能力。我今年计划通过多分享、多与不同的人交流等方式,提升自己的这种能力,争取做到满意的程度。
好了,这篇文章就到这里了,这就是我这六年的技术回顾和展望,感谢你的阅读❤️。
人生的多重境界:看山是山、看水是水;看山不是山、看水不是水;看山还是山、看水还是水。
我想,我对软件开发,还没有达到第三层,相信用不了多久,会有更多不同的观点冒出来。
但,怕什么真理无穷,进一寸有一寸的欢喜!