2022年终总结-两年Androider的成长之路
金句分享
生活金句
1.可难道我们生命中做的每一件事不都是为了被爱得更多一点吗
2.这不只是一种对承诺的恐惧,也不是我缺乏关心和爱的能力,因为我做得到,只不过,老老实实讲。我想 我宁愿为了某件我擅长的事,我能表现的出色的事去死,也不愿仅仅为了一段美好贴心的感情去死
3.他这一生 时间都用在考虑他的事业和工作,他那时五十二岁,他突然意识到,他还从来没有真正付出过自己,他的一生没有为了任何人或任何事,他说这话的时候,他差点哭了
4.如果世间有魔法,一定存在于理解别人和分享的尝试之中谁在乎呢?可是,说真的,答案一定就在尝试之中
5.时间就那么多,怎么选择。各个阶段有各个阶段的疑惑,也有不同的答案
看到大家都已经走上了职业发展的正轨,我很害怕,看到这句话的时候释怀了
6.经历反哺普世知识,普世知识拓展预测经历,没有经历和反思过得东西必然索然无味,自己的想法和别人提到的信息如果只是记录的话,没什么用处。因为没有经历所以觉得不重要,没有实际的用处必然不会深刻领悟其主旨内涵,一切的智慧都是通过经历体现的,而所谓的学习可能只是让你有了大概了解,对于真正的懂你还差的还远
感情的金句
沈亦斐老师的小粉丝,以下是老师的一些摘录。如果因为我的某些总结而引起您情绪的变化,请放心一定是我的错而不是老师。没有对应的上下文环境进行铺垫这些话听起来确实很容易引起情绪波动
1.现代人会思考会有人爱我吗?使得进入爱情更加谨慎,进入爱情风险更高,进入到爱情就会遇到一种困境,要不断地衡量我的价值是不是足够,我把自己放在竞争的位置上很难受,所以算了 不参与竞争不育保平安。也就不会有人来评判我是不是值得。
2.很多年轻人逃避爱情是在逃避什么?因为好的爱情是促进你的,为什么不愿意进去是因为你会发现是要拿自己出来碰的。
3.为什么会碰到奇葩男,是因为介绍人认为你们两个人的价值是相匹配的,才把他介绍给你。要让自己承认和奇葩男一样是很难受的,所以就叫人家奇葩,这样就可以把我的低价值给载出来
4.忠诚和承诺更为复杂,在当代他还包括这样一种意味:爱情是一种持续进行,永无休止的“验证过程”:即对一个人自身的个体性和价值的重复确认
5.被拒绝和被背叛意味着自我价值感大厦的倾覆:我的那个自我还不够好,价值不够高,不值得被爱;
6.男性的自我向外扩张,征服世界,所以男性不会内化这些东西,他的重点是外部也就很少听到奇葩女。
女人的自我内向审视,需要认同,所以会叫对方奇葩男
现代爱情变得越来越难以持续是因为男女对自我的追求南辕北辙
7.爱情对于两性的意义是不同的:
- 对于男性:性资源的获取和男性气质的彰显
- 对于女性:独特自我的发现,个体价值的赋予
8.男性的自我强调自我实现:修饰齐家治国平天下,女性的自我强调自我救助:不完善的自我需要爱情来修补
9.在婚姻市场上男性被进一步要求提供更为强大的经济基础,女性在追求经济独立的过程中,却被消费注意进一步“物化”
10.今天这个时代,做选择本来就是很不容易的。
11.爱情是个勇敢者的游戏,在未来,爱情不是所有人能拥有的东西,是个奢侈品。爱情恰恰跟钱没关系,有钱就一定能买到爱情吗?
是个奢侈品是因为你一定是勇敢的,你得面对挑战,你要去摘那个最美的果子,你就要把自我拿出去,这恰恰是成长路上最重要的一步。
职业的金句
1.首先要有积极乐观的心态和做事态度,能正确认识自身的不足并保持学习,面对困难能抗压。
在遇到问题时要勇于挑战,在解决问题的途中积累经验,发现自身需要补足的漏洞,通过不断的学习,拓宽技术广度,培养系统设计思维,对前沿性的课题保持好奇心,敢于接触和使用新技术。
具体的就是要有高于标准的技术深度、开发能力和解决技术难题的能力,在工作过程中对自己负责的模块重点深挖,不断优化,对于复杂问题从多角度出发,利用发散思维寻找解决办法;
同时面对各种繁杂的问题,要能找出共性,发现隐患,合理解决问题的同时也要减少未来的问题;提高技术广度,对不同领域都要有清晰的认知,培养大局意识,从系统设计的思维出发,对于项目未来技术发展有预判,能通过这种方式规避可能的风险;
2.多做笔记,多总结,多复盘。
凡事有交代,件件有着落,事事有回音。
在空闲时间持续学习,保持对技术和游戏的热情,多看看游戏开发领域的前沿方向,培养举一反三的能力,发现复杂问题之间的共性,在解决问题的同时,发现可能存在的隐患,避免或减少未来可能出现的问题。
树立一个清晰的目标,可以职业成长围绕这一个点去积累经验,围绕职业目标方向这个核心,才能构建竞争力,形成核心竞争力。只要方向明确,哪怕走得再慢,也可以比那些走弯路的人走得快。
坚持不懈,更加有效地投入时间。
遇到无法预判的情况时,保持冷静思考,通过理智分析,从多个角度寻找解决办法,同时也要总结经验,多复盘,这样才能对突发事件有足够的预见性。
3.毕玄:我在阿里的十年技术感悟
4.《技术成长之路》精华回顾
5.优秀复盘:先介绍问题背景,提出问题给出问题的定义(让大家对问题有个具象化的理解),提出常见解决方案和这些解决方案的缺点,提出自己的观点(自己的突破点是什么)论证自己的观点,综合起来说效果
技术
系统
1.Android系统优化的那10年
2.如何判断dexopt失败?
dexopt是可以判断出来失败的,校验一下这个dexopt是否完成(校验方法是loadDex这个dex里面的类看他能不能load进来)
出现dexopt失败问题:1. 空间不足(转换之后的opt信息已经写不进去了),2.安装时空间不足(读apk的时候读不进来)
3.关于meminfo的值介绍
PrivityDirty=应用自己本身使用的内存,不包含Davilk的共享内存
HeapAlloc=Privity Dirty(应用本身自己使用的内存)+Davlik进程的内存(预加载资源+预加载类)
DavlikHeap的PSS Total=Privity Dirty+(Davlik进程内存/App个数)
运行dumpsmeminfo的时候有可能会让当前虚拟机进行一次GC
(也可以使用dumpsys meminfo --local不进行GC),如果对meminfo的结果不太满意想进一步分析,就使用smaps(/proc/< pid >/smaps)分析
smaps可以吧mmaps映射那些文件可以详细的列出来,主要消耗内存的地方主要是: dex,so,jar,apk
4.内存碎片指标分析:
表现:PSS和PrivatedIPrity还有HeapFree都有了很大的提升,但是HeapAlloc却没有什么变化
原因就是内存碎片的产生,分给你的空间还是那么大,之前的内存页都满满当当用完了,但是现在有了临时数据产生所以需要的页也多了,由于临时数据,所以GC完成后Heap Free也有很大的增长
5.Davlik Other和mmaps构成:
Davlik Other构成:
- 这个类加载进来之后有哪些成员变量成员函数以及指向这些成员函数的指针
- 基本上和载入类的数目是相关的
mmaps构成:
- 存储了类信息的结构,从映射dex结构中读进来的
- 编译之后的字节码也是从mmaps部分读进来的
- 包括字符串常量数据等等都是映射在这里面的
- 基本上也是随着载入的class数量增加而增加的
6.new一个对象对于虚拟机来说需要执行这两个步骤:
第一部分是loadclass,内存增长分为两部分区域:
- dexmmap:从.dexmmap里面读这个类的信息,会使dexmmap增加
- 解析读到的数据之后,虚拟机会在linaerAlloc和aux里面存储一些类的信息和指针之类的
第二部执行 new Instance,内存增长分为三部分:
- dexmmap:又会去从dexmmap里面找这个类的构造函数(为了执行这块代码虚拟机也要把这块代码加载进内存)
- davlik-heap:加载进内存执行之后才会在真正在dalvik-heap真正分配对象真正实际占用的内存
- davlik-bitmap和jit-code-cache:还是会分配到davlik-other里面分配些内存辅助进行运行
渲染
7.渲染发展史:
-
Android1.6:渲染采用Skia软件绘制,SF层合成采用OPengles1.0和copybit
-
Android3.0:**渲染非默认采用HWUI(2.0)**可以手动开启属于实验室项目
-
Android4.0:渲染只要你target的api大于4都是用的HWUI,也可以手动开启Skia。移除CopyBit(拷贝比较快,4.0之后的手机都有GPU了,所以被舍弃了)SF使用的还是opengles1.0
-
Android4.1:黄油计划(顺滑)
-
Android4.3:延时的DisaplyList,渲染开始支持ES3.0(ES3.0此时并没有为UI使用,主要是为游戏使用)HWUI用的ES2.0,游戏用的3.0
-
Android4.4:SF使用ES2.0合并图层贴出来
-
Android5.0:引出了一个新的线程RenderThread渲染线程(之前做绘制和渲染都是在主线程的)现在主线程救就是主线程以前即是主线程也是UI线程。UI线程是RenderThread,渲染支持3.1(此时用于UI)
-
Android6.0之后:支持Vulkan(哇卡)用于取代OPENGL的新的图形API,比OPENGL更加榨取GPU的渲染能力
8.SKIA
Skia软件渲染流程:
- SKCanvas对应于java层的canvas
- SKCanvas持有着SKDevice设备
- SKDevice持有着SKBitamap(Surafce其实就是一个缓冲区,通过Bitamp吧这个缓冲区的指针封装起来)
canva通过androidRuntimeGNI接口吧数据参数给到SKCanvas的draw调用skiadevice最终会调用到skDraw(最后的drawpath,drawXXXapi最后都会到SKDraw中),SKDraw通过SKRasterizer把他画的东西进行光栅化,然后调用SKBliiet的blit方法传输到Surface的缓冲区中(blit是一个快传输),接着SF进行合成
这里面每一步都是CPU在参与,所以它的光栅化是CPU进行的,但是SF是基于GPU合成的(一开始就是用的1.0)
在4.1之后Skia也支持了硬件加速(GPUCanvas,gpudevice,glcontext【gpu的context】),通过gl接口硬件加速画出来而不是之前软件渲染通过bitmap一个一个像素去渲染
9.skia也使用硬件加速的功能,为什么安卓还要在实现一套?
渲染模式差异
渲染一般有两种:
-
立即模式:APP维护场景【里面东西变了你需要调用图形库的一些方法反映到屏幕上绘制出来】,通过调用渲染库的api上屏,每次发生变化都需要CPU调用生成图形给到GPU
-
保持模式:场景由图形库自己维护,图形库跟踪或者更新变化。APP是调用的图形库的方法构建图形库里面的场景,如果场景发生变化,图形库会吧这个场景转换成会绘制命令了给GPU执行上屏(对于细微变化不需要CPU重新生成图形,只需要告知变化给GPU,GPU自己维护的图像做了变化就可以用)
保持模式的每一帧都是从GPU到VRAM(GPU和显存之间非常高速的)。不像立即模式通过bus总线传输(和CPU沟通的话受bus总线带宽影响)立即模式的瓶颈在bus的带宽(如果io占用了bus就会有瓶颈)
矩阵变化旋转位移透明度都属于细微变化都不需要去重新加载场景,继续操作显存里面的场景进行变化(这个时候应用程序完全不需要重绘只需要告诉变化)
10.黄油计划
-
4.1开始三缓冲减少卡顿:
GPU你慢可以,但是你需要吧慢的那帧给缓存起来。显示就不只是GPU渲染完哪个就显示哪个了,而是GPU上一次渲染的图像。总结就是两个卡顿变成一个卡顿,减少卡顿
N缓冲也无法避免卡顿,因为有时候你的cpu就是很卡需要处理或者GPU很慢 -
rendernode对displaylist的属性进行了封装
4.1之后displalist会生成一份对于修改自己的属性,对于简单的变化是操作displaylist的属性。之前的话不管是不是复杂简单都会重新生成diaplaylist。
表现:属性动画在黄油之后会更快,因为这些属性都对应到displaylist中的属性了,不需要调用ondraw方法了只需要进行修改displaylist属性就好了不用view在inviladeta了
- DeferredDisplaylist
安卓渲染慢,有部分原因是浪费在了opengl的上下文切换:不同的上下文做的事情是不一样的(绘制背景,绘制位图,绘制文本),其次指令数量没有经过整合。
在优化之后经过重新排序后吧相同类型的操作放到一块(减少切换上下文次数),同时指令数量会减少【两个三角形需要两次绘制,但是现在可以执行一次就行合并是通过合并顶点数组和纹理数组实现的,可以看成多张图变成一张图】
- Shared Atlas共享纹理集
以前是把内存里面的位图加载到显存里面。进程之间是无法共享的,所以每个APP按需往GPU里面加载纹理(如果多个APP都是用同一个纹理那么并不会共享重新加载gpu是不知道的,会加载相同的纹理)。用那些就把那些传到GPU的显存里面
共享纹理集:把系统的资源拼起来拼成一张大图(不超过模拟的最大尺寸就行)上传到显存里面里面有很多纹理集,用的时候通过坐标去取。
大图是维护在SurfaceFliger这边用的时候像SF拿就行。
通过SF进行统一纹理集,应用像SF拿到操作纹理集的句柄(显存对内存的映射指针),就能拿到显存里面的纹理。
应用的drawable文件夹也会进行同样的上传操作,到时候进行上传(这个解决的倒不是共享纹理集的优化,而是解决了内存碎片)每次用的时候不是直接加载而是提前加载纹理集到显存中,这个时候会做内存碎片的整理。文件夹特别大就会有多个纹理集
11.图形性能调优的一些方法论:
- OverDraw去除冗余渲染
- Profile Rendering:根据竖线不同颜色来优化
- HardWare layers updates:动画开始之前给view设置的硬件加速的layer,渲染到纹理上下次用的时候直接从纹理拿非常非常快不需要重新渲染(没有总线的开销),播放结束之后设置为NONE默认的layer。因为需要连续播放会受bus总线带宽限制
如果在动画播放过程中内容发生变化,则会有个绿色的蒙层在闪,如果在闪说明内容一直变化。说明不适合开启硬件加速变化太频繁(一直需要内存upload到显存中一直在load很耗时还不如不开按正常方式构建displaylist渲染,不用纹理)
- 开启OpenGl trace:不同级别的日志,可以看到swap和drawXXX还有上传纹理到显存等不同的级别
所有的插件化,插件启动干得事情都是一模一样的(classloader,资源,上下文,loadedapk),只是插件框架的初始化不一样
推荐书籍:
- 《建筑模式语言》
- 《分析模式:可复用的对象模型》
- 《企业集成模式》
- 《反模式》
- 《面向模式的软件架构》五部曲
此外最有收获的就是看了掘金的关于职业发展的直播,希望掘金以后能多举办这种活动,大佬们的成功是有方法可循的,我们可以借鉴大佬的做法事半功倍,沸点链接,截图如下:
公司经历
从20年十月份毕业到现在,我已经成长为一个拥有两年开发经验的Android er了。
2021我的年终总结里面讲了我毕业一年的一些感想,一年好快又好慢,这一年我不管是认知上还是技术上都成长了不少
我一共呆了五家公司
回顾我第一份工作,那甚至都称不上是工作,第一家和第二家呆的时间为五天和三天。
那就把第三家公司当做我的第一份工作吧,外包在里面呆了半年后来因为教育改革被开,在这家公司我浑水摸鱼,平常的需求完成了就是玩,不可能学习。
这家公司的正式员工福利很好很羡慕他们,有自己的咖啡机有自己的休息室,还有每天的下午茶,公司团建每个月都会有一次,在这里我呆的很幸福也很安逸,但是残酷的是外包不享有大部分福利。当时我就立下了一个flag,以后我也要努力学习去大厂,这些福利真的好
组长知道我是培训出身的,所以一些难的活帮我做了,也帮我拦下来了很多,很感谢老安卓和组长的照顾,总之我在外包呆的那半年时间是我两年以来工作最幸福的时候。
后来被开之后开始了一个月的面试,这段时间是不用上班的在公司看面试题就行,然后得到了一家算是大厂的offer,工资涨了一半很开心,也是这个时候我才知道我要的太少了HR直接就答应了,对于培训出身的人来说,互联网这个行业的薪资真的是个迷啊
第四家公司呆了一个月同样也走了,是我主动提的离职(组长也很照顾我,但是组里的气氛很压抑,我受不了这种氛围)。 现在回想起来当时编的理由真的很搞笑,组长顶的压力也很大(当时正在重构,因为我离职,进度还延期了)。离职那天组长在楼梯口等我,我想起来忘记打卡了,拿了工卡回来后,组长不见了,可能因为我太不厚道了吧,现在想起来真的很对不起那个组长。
第五家公司就是现在这家,由于只呆了一个月所以工资我并没有涨,HR还变相压了我一千。来了之后应聘的是系统部门,所以降一千我也接受了,那时候就听应用再说懂系统的人做应用会有优势。于是我入职了
去年的下半年年终,由于系统知识不足,我一直在学习,组长也给了很多资料(包括四大组件启动流程,稳定性方面的文章);
但是由于实力不足还是被调岗去了应用组,部门组长很厉害,给了我很多指导和帮助,也是我的偶像(代码写的那叫一个优雅)。刚进组里,组长就罗列了一大堆技术清单,想看懂我的代码,必须要懂这些,然后又开始了我的学习之路。
技能清单如下(感兴趣的jy可以自行学习):
1.gradle apk打包流程
2.gradle Transfrom 方案
3.AOP 面向切面编程思想
4.字节码增强技术方案,比如ASM,JAVAASSIST
5.JAVA 源码生成技术方案 javapoet
6.Application,Activity,Service,BroadcaseRecive,ContentProvider启动原理
7.apk解析安装过程
8.Classloader类加载机制
9.代理等设计模式
技术成长
说说我这今年的技术成长吧;
看的技术书籍和笔记(用的软件叫当当云阅读):
当当云想法截图 | |
---|---|
~~~ |
我的学习方式在今年年终的时候我才觉察过来效率太低,总的而言我喜欢研究一些自己感兴趣的东西但是回报比并不高的东西上,比如图形渲染,我花了整整两个月的空闲时间去研究,但是回报对于业务来说几乎没有。我好像花了很多的时间在研究同事说的无用的东西上
看了很多人的年终总结,大家对一年的学习方式都有思考,其中我觉得让我心安的是这篇文章《2020:非适应性完美主义、存在主义哲学、架构、基金翻倍、有效休息|掘金年度征文
》
其中 标题《错误地理解了“基础”的意思;解决:深究的心》中写到的 :一定要切记,打基础,是和工作任务相关的基础,而不是整个计算机行业的基础。 妄想把 编译原理、Linux底层、操作系统 都掌握,这是不可能的。 对现在的我最有感悟
研究一个东西的时候会发现底下有很多基础知识牵动着,你要想理解上层的做法必须先把底层搞明白,但是底层需要你花费大量时间而且太广,回报周期太长而且不感兴趣的东西我是不会去浪费时间到上面的
今年把计算机网络的大致流程看了一下,对于数据结构和算法依然没有动静,设计模式倒是在项目里用上了,操作系统和机组也是大致过了下,博主的一段话点醒了我:这样,很容易把时间投入在无任何产出的基础上。浪费时间,还让自己产生一种虚幻的很强的错觉,既不利于能力提升,也会让自己心态失衡。
So 技术成长是有道路的,你要学的就是那些东西,根据技术清单查缺补漏。但是我并没有列出我的技术图谱进行查缺补漏,没有进行体系化的总结,只是对自己喜欢的进行了细致的研究,我也不打算整理技术图谱了,反正都是不感兴趣与其看与业务无关的东西还不如多立足与业务出身,进行优化SDK
技术总结
半年里收获的一些技术
- 动态技术(热修复,插件化的原理)
图形渲染&opengl
输出专栏:渲染专栏
- 设计模式
- 四大组件启动流程
- 计算机网络相关知识
输出专栏:计算机网络
gradle的生命周期和可以新增简单task逻辑
输出专栏:Gradle
计算机组成原理
输出专栏:计算机科学
- 并发&多线程
Android源码笔记,输出专栏:Android源码系列
待加强:
- 计算机网络
- 安卓开发必会的一些操作系统知识(妄想学懂时间成本太高,非科班加上时间不够)
- 数据结构(这个一定要开始看了)
- 继续加强设计模式方面的能力
- 关注性能方面的知识