Android开发的现状貌似已经是一个老生常谈的问题了。但今天不想写Android开发的现状,什么Android前景如何、Android凉凉之类被别人写烂了的话题。
今天我们来聊聊我们自己,我们Android程序员的现状。
各位朋友也都是从标题看起点进来的。确实,标题很扎心,也很真实。架构师是程序员晋升的顶点,谁不想成为一名架构师呢?为什么大部分程序员从入行到转行,自始至终还是一个码农呢?我们带着思考看下去。
大部分程序员都是从小公司、小团队做起。特别是非科班出身的程序员,除非技术过硬,不然很难进到大公司或BAT之类的大厂。小团队一般 10个 人左右,其中常常是技术最好的做架构师(或CTO)。所以,架构师在广大码农中的占比平均不到 10%。
而架构师也可以分为初级、中级、高级,江湖上真正高水平的软件架构师就更少了。
所以,可以说90%以上码农肝了几年、甚至十几年,还是做不了架构师,这是什么原因造成的呢?
什么是架构师?
架构( Architecture)这个词,来自于建筑领域。我们经常将编程比喻成造建筑。工地上分工明确,各有等级,按照一所建筑的流程来看:
首先是开发商提出需求(公司客户)
到承包商拦下项目(公司本身)
总工程师画出建筑图纸,这一步最为关键,房子的总体框架,模型,建好后长什么样子,钢筋水泥瓷砖地板装修用料都要给出明确的流程和步骤(架构师)
工头领队施工(TL)
和水泥的和水泥,砌砖师傅砌砖等等(码农,业务代码)
可以说,建房子和编程开发的流程,完美的契合。
插一个自己的小故事
要明白一点:写业务代码和做架构是两个完全不同的事情。
刚踏进大学入门Android开发的时候,对架构师这个词并没有太多的概念,就觉得肯定很牛13,我以后工作了也肯定是个架构师。
后来开始写代码,从Java学起,然后四大组件,写Activity,然后学UI,学布局等等等。
学校毕业出来,我已经能独立开发自己的APP,虽然就是些什么图书借还APP,壁纸下载APP。但我依旧觉得自己很牛13。但是这份资历加上科班出身,毕业后我还是轻松得到了一家小公司的offer。工作一年后,我已经能基本上独立解决自己开发岗位上的问题了。
我贼牛逼。但是我不会口头上说出来,我要跳槽,这家小公司的舞台已经不够我发挥了,但我不会说出来,先找好下家,再提辞职,刚步入社会的我,就有如此远见,佩服自己。
于是我拿着自己1年工作经验的简历,投给了阿里巴巴,Android研发工程师。淦,面试都没收到。
然后我又投了当时如日中天的字节跳动,号称年轻人的天下。淦,又没收到面试。
是我眼高手低了?投了一家上市公司,金融行业,程序员最赚钱的行业,我**,又不给面试。
???
最后终于面到了一家中大型的企业,嗯...中级Android工程师。
自我介绍完,说了一下我做过的项目后,leader脸上一副:就这?就这?的表情。
当然,作为成年人的他,还是有着该有的涵养和礼貌,并没有打断我说话之类的。
然后到面试问题环节
leader一上来就问:看你简历上写熟悉 AIDL,说一说 oneway 吧
我:啊?oneway 是什么?跟 AIDL 没关系吧,我熟悉 AIDL 指的是使用 AIDL 接口进行跨进程通信。
面试官:...
啊哈,接下来的15分钟我羞耻的恨不得立马破门而出!binder通信原理是什么?说不清。子线程可以创建Handler吗?母鸡啊。activity启动流程总能说一说吧?哈哈哈,忘记了....
我人生中的第一次跳槽就这样羞辱的结束了。。。。。。。
这件事过后,我如梦方醒。光会砌砖(写业务代码)就想当总工头(架构师)?不可能。
这也是大部分码农无法成为架构师的一个原因。一直停留在业务层面,把砖砌的再好,终究只是砌砖师傅。
怎样能成为一名架构师?
我们依旧比喻成造房子,也就是说,从一个砌砖师傅怎么才能一步步成为总工头呢?
一、把砖砌好
代码是写给别人看的,写好业务代码是成为架构师的第一步。
没有哪一个架构师不是从写业务代码成长过来的。没有不懂业务的架构师,所有的架构,都依赖于业务。所有的架构师,也必须要去写业务代码,不把自己设计的东西,用在真正的项目里,恐怕他们自己都不会知道,这种架构设计的合理性在哪里。
这里我想表达的代码质量优化,并不单指日常编程。
我想表达的是一种架构思想:面向未来编程
一个好的工程师,在听到需求的时候,可以根据自己的业务能力,判断出来这些需求中,哪些是有可能变化的,哪些是不太可能变化的。
针对这些变化的内容,在编写的过程中,不会写死,而反复确认不可能会变化的需求,会写的简单一些,防止过度设计引起的复杂度。
简单说,当他拿到需求时,并不单纯是考虑这个需求怎么实现,还会考虑,自己设计的架构体系,扩展性在哪里,在他的眼里,看到的需求会被分解,折分,然后自己的技术方案,会挨个分解,分配。
在完成设计之后,他会很清楚的知道 ,自己设计的系统里,哪些变化是支持的,随便你改,我只需要改动一个很简单的内容,哪些是你绝对不能改的,你要改,我就必须花很大的代价,特别是在已经有线上数据的时候。
而且会拿着自己的架构体系跟 PM 沟通,讲清楚。
如果你编程时已经有了这种思想,说明你已经具备了一名架构师的基本素养。
二、清楚砖头钢筋水泥的成分
房子要建好,必定要选用好的材料。这些便是房子的底层、基础。
在编程中,我们所用的语言便是砖头,各种工具类便是水泥,各种框架便是钢筋。
光会用当然不行,必然要“知其然,知其所以然”,“所以然”便是各种方法、工具类、应用框架的底层源码以及他的实现原理。
对于绝大多数编程从业开发者而言都面临一个普遍的问题:广度与深度难以兼顾。
每个企业的业务方向都不一样,用的技术也不一样。运气好,面试的时候甲方公司用的技术刚好跟你学的一样,结果技术面一问,你只答的出四大组件有哪些,生命周期支支吾吾也说不太清楚,view的绘制流程模棱两可,垃圾回收算法一知半解,性能优化一窍不通。这要是能找到offer,那就见鬼了。
很多人在开发过程中只是浮在表面,忽略底层源码分析,面试求职的简历也没有进行修缮和突出重点,自然求职不顺,加薪无望。
所以解决这个问题的最好办法就是:抓住不变量。要知道,底层知识永远都不过时。算法数据结构永远都不过时。基本的程序设计理论永远都不过时。良好的编码习惯永远都不过时。分析问题和解决问题的能力永远都不过时。强大的学习能力和旺盛的求知欲永远都不过时。你大脑的思维方式永远都不过时。
举个栗子
大家应该知道也懂得性能优化的重要性,可工作中由于对整个知识掌握不够,所以会在性能优化上没有自己的理解。比如,Glide,这个是我们经常用的技术,相信大家都会用:
Glide.with(context).load("图片url").into(imageView)
但是大家谁知道这个里面有性能上面的坑啊?
如果我们不能体系的去掌握activity,fragment,application的生命周期,而且也不了解glide源码,因而我们可能是直接在context的地方传this,或者,直接给application的context,那么此时Glide的生命周期就和this,或者application绑定了,那么结果大家可想而知,在嵌套的fragment+viewPager的代码结构中,生命周期的管理不到位,就会带来生命周期问题的内存碎片。自然大家就知道,类似的情况多了性能就会一点一点的损失,最后导致app的运行过程中偶现的OOM,结果可想而知。
底层知识学扎实了,上层的东西像风筝一般千变万化,而你是在底下扯线的那个人,顺着线往下拉,便能轻松看清楚这个风筝长什么样。
三、房子要漂亮,装修少不了
这个点相信大家很容易就能想到我接下来要说什么了。没错,就是Android开发少不了的—性能优化。
性能优化绝对是一个老Android必修的课题,没有过性能优化的经验,去哪里找工作都免不了碰壁。
一名Android架构师,必定要掌控整个APP的总体构成,用户体验,是最为重要的一点。
作为Android开发,大部分朋友可能会对性能优化这个Topic如数家珍,Google官方在几年前也有“Android性能最佳实践系列”(Android Performance Patterns),当然,其中大部分的Tips都是需要大家遵循的规范,但是无论理论上怎么说,我们所做的工作最终还是需要为业务服务,不管你是为了提高下载量、优化用户评价、还是提高业务的转化率,都需要给出性能优化的ROI。
经过近十年的发展,Android技术优化日新月异,如今Android 10.0 已经发布,Android系统性能也已经非常流畅,可以在体验上完全媲美iOS。到了各大厂商手里,改源码、自定义系统,使得Android原生系统变得鱼龙混杂,然后到了不同层次的开发工程师手里,因为技术水平的参差不齐,即使很多手机在跑分软件性能非常高,打开应用依然存在卡顿现象。
APP进行性能优化已成为开发者该有的一种综合素质,也是开发者能够完成高质量应用程序作品的保证。
小结一下
从Android小白到架构师的职业规划到底是怎样的?
我们初入这行是可能出于兴趣,可能出于前景。
入行这个职业就代表着你需要不断的学习、学习,进阶、进阶。
在我们入行之初,为了就业,我们不得不让自己的知识体系更具有“广度”
入职后,你发现并不是之前所学的知识都需要用到,你开始需要进阶某一知识模块的“深度”
此时你具备初级开发的:知识点
工作了几年后,你发现你需要更大的舞台,你需要好几个连起来模块的深度进修。
此时你具备了中级工程师的:知识面
又过了几年,你已是职场老鸟,你几乎能解决工作中所有日常问题。你具有许多的知识面,你将你所有的知识面串联,形成了一套完整的知识体系。
此时你是一名高级工程师:知识体系
可是,你已经到了30+,快要退休的年纪,你身后有无数的高级工程师随时可取代你的位置。
此时,你需要探索代码更深处的奥妙,你不再是只会建房子的“砌砖师傅”
你懂得每块砖头的组成、结构,你知道一所房子哪个地方需要这块“砖头”,哪个地方适合另一种“砖头”。你知道这所房子需要怎样建造,怎样设计更坚固、合理且美观。
此时,你是一名架构师。
最后
为什么很多程序员做不了架构师。
1、良好健康的职业规划很重要,但大多数人都忽略了
2、学习的习惯很重要,持之以恒才是正解。
3、编程思维没能提升一个台阶,局限在了编码,业务,没考虑过选型、扩展
4、身边没有好的架构师引导、培养。所处的圈子对程序员的成长影响巨大。
文末:
放上我整理的一份Android架构师技能树,有点长,有兴趣的可以看一下收藏起来,没兴趣可不看。
以下技术知识点在我的GitHub都有详细的讲解。
必备Java基础
泛型
作用于定义
通配符于嵌套
Rxjava中的泛型
注解
自定义注解与元注解
APT,编译时注解处理器
插桩
反射,运行时动态获取注解信息
Retrofit
并发线程
线程共享与实现实现
CAS原理
Android AsyncTask原理
Java虚拟机
Dalvik虚拟机
CG算法、机制
内存分配策略
Hook技术动态编程
动态代理模式
双亲委托机制
JavaIO体系
IO操作Dex加密
数据结构及算法
数据结构
栈和队列
数组和链表,自定义一个动态数组
Hash表,及Hash冲突的解决
二叉树
B+ B-树
基础排序算法:重点 快排、归并排序、堆排序(大根堆、小根堆)
快排的优化
二分查找与变种二分查找
哈夫曼树、红黑树
字符串操作,字符串查找,KMP算法
图的BFS、DFS、prim、Dijkstra算法(高阶技能)
经典问题:海量数据的处理 (10亿个数中找出最大的10000个数 TOP K问题)
算法
分治算法
动态规划
贪心算法
分支限界法
Android基础
Android Activity生命周期
Application生命周期
Android Service、IntentService,Service和组件间通信
Activity的onNewIntent
Fragment的懒加载实现,参数传递与保存
ContentProvider实例详解
BroadcastReceiver使用总结
Android消息机制
Binder机制,共享内存实现原理
Android 事件分发机制
Android 多线程的实现:Thread、HandlerThread、AsyncTask、IntentService、RxJava
ActivityThread工作原理
嵌套滑动实现原理
RecyclerView与ListView(缓存原理,区别联系,优缺点)
View的绘制原理,自定义View,自定义ViewGroup
View、SurfaceView 与 TextureView
主线程Looper.loop为什么不会造成死循环
ViewPager的缓存实现
requestLayout,invalidate,postInvalidate区别与联系
AndroidP新特性
Android两种虚拟机
ADB常用命令
Asset目录与res目录的区别
Android SQLite的使用入门
Android开发高级
Android技术难点
AIDL、Binder、多进程、View的绘制流程、事件分发、消息队列等。
这类知识对于定位自己为高级Android工程师的人来说是必须掌握的,同时他也是能鉴别高级和初中级工程师的一块试金石,其中binder是Android系统进程间通信最重要的手段之一,现阶段app的发展离不开多进程的运用,经常会启动例如定位、推送等需要在后台开启动的进程来来保证主进程的内存运行;所以合理的使用多进程也是十分必要的;view的绘制是我们自定义控件的理论基础,只有掌握了view是如何绘制的才能个性化的自定义控件;事件分发一直是Android开发的难点之一,也是必须掌握的;关于handler机制也是android的一块难点,因为包括Asynctask、系统启动、Intentservice等底层都是通过handler来实现的,所以掌握后handler机制不仅能提高你的实战开发能力,更能让你系统的了解整个android系统运作的情况。
Android框架层源码掌握
Android包管理机制,核心PackageManagerService
Window管理,核心WindowManagerService
Android Activity启动和管理,核心ActivityManagerService
根Activity工作流程
Context关联类
各种原理,经典第三方库源码系列
自定义LayoutManager,RecyclerView中如何自定义LayoutManager
VLayout实现原理,即如何自定义LayoutManager
Glide加载原理,缓存方案,LRU算法
Retrofit的实现与原理
OKHttp3的使用,网络请求中的Intercept
EventBus实现原理
ButterKnife实现原理
RxJava实现原理
Dagger依赖注入
热修复实现原理,解决方案
组件化原理和解决方案
Android进程通信以及多进程开发
Android 多进程和Application关系
经典解决方案:多进程通信解决方案:Andromeda
Android动画机制
Android绘图原理
Android页面恢复
Android的页面恢复采用以下两个方法:
onSaveInstanceState(Bundle outState)
onRestoreInstanceState(Bundle savedInstanceState)
onSaveInstanceState :当Activity容易被系统销毁时,会触发该方法。具体的说:
用户点击Home键
用户点击Home键,切换到其他应用程序
有电话来了等附加操作
混合开发及Android WebView应用
混合开发涉及到的知识点主要包括:
APP调用WebView加载url
掌握WebView的封装,了解所有的WebSettings配置,掌握WebViewClient、* WebChromeClient
掌握WebView和Native双向通信机制,会自己封装双向通信中间件
对WebView的封装可参考:GitHub: AgentWeb
对通信中间件原理理解:GitHub:webprogress
Gradle,自动化构建,持续集成相关
Android系统
Android Studio编译过程
其中使用到的编译工具:
aapt、aidl、Java Compiler、dex、 zipalign
主要步骤描述:
通过aapt打包res资源文件,生成R.java、resources.arsc和res文件(二进制 & 非二进制如res/raw和pic保持原样)
处理.aidl文件,生成对应的Java接口文件
通过Java Compiler编译R.java、Java接口文件、Java源文件,生成.class文件
通过dex命令,将.class文件和第三方库中的.class文件处理生成classes.dex
通过apkbuilder工具,将aapt生成的resources.arsc和res文件、assets文件和classes.dex一起打包生成apk
通过Jarsigner工具,对上面的apk进行debug或release签名
通过zipalign工具,将签名后的apk进行对齐处理。
App启动加载过程
Android虚拟机 Android App运行的沙箱原则
Android架构
在Android源码中最重要的三个类:ActivityManagerService/PackageManagerService/View,推荐大家周末的时候可以去阅读下这部分的源码,阅读源码能提高我们今后设计架构自己代码的能力,同时也能从底层了解整个android系统的运行原理,其他一些比如主线程的消息循环、主线程如何和AMS如何跨进程交互、SystemServer进程中的各种Service的工作方式、AsyncTask的工作原理等。这些知识也是作为一个Android高级开发工程师必须掌握的,不能整天沉溺于ui和四大组件的交互,要站在更高的角度去考虑Android的有些问题。
MVC模式
MVP模式
MVVM模式
CLEAN模式
组件化开发
跨平台开发:Flutter、ReactNative(RN未来要黄,了解一下就好)
移动开发外围
服务器开发相关
SpringBoot技术
Restful API开发
网络协议理解:TCP/IP、HTTP/HTTPS、OSI七层协议
授权认证协议:OAuth2.0 等
基本的数据库技术
数据缓存技术v:Memcached、Redis,Web缓存原理
消息队列技术
监控、日志分析技术
前端开发相关
前端开发知识很多,框架层出不穷,本质的东西却只有以下这些。
核心必备:HTML、CSS、JavaScript
入门提高:浏览器兼容性、自定义UI和动效
中级技能:框架层出不穷,当前以vue.js、react.js 为核心
协作开发技能:包管理、模块化,工具采用 npm、webpack等
高级技能:框架原理源码研究
开发调试各种工具
性能分析工具:Memory Monitor
性能追踪及方法执行分析:TraceView
视图分析:Hierarchy Viewer
ApkTool- 用于反向工程Android Apk文件的工具
Lint- Android lint工具是一个静态代码分析工具
Dex2Jar- 使用android .dex和java .class文件的工具
链接:https://www.jianshu.com/p/6e9bb7224311