一、概述
如果想自己写公司的apm,可以参考koom和matrix这2个来源框架
做完a任务和b任务,就可以做c任务,这时候可以用countdownLatch来实现
做性能优化,很重要的一点就是线上的APM
二、Java层的实现
简历中一定要有指标
cpu指标,如负载,线程数等
内存指标
FPS
ANR
卡顿
GC/oom还是和内存相关,gc日志
网络,hook到okhttp
远程下发,日志回捞,下发shell,执行动态代码
crash怎么监测?其实就是监视线程,java层有uncatchexception
anr怎么监测?就是监测文件,file obsever,监测anr文件
用户行为链路,其实就是监测activity和fragment。在application中通过lifecyclecallback即可
可以说我们公司有做了类似头条的 APM,有几个人做,参考了xx,xx框架实现了
三、APM
首先讲设计思路。
1、配置
做 APM 肯定是有配置的,类似于:
1 | String[] params default {} |
配置都是使用 注解 + Json 实现 (课程里面还没说怎么用到的注解)
2、cpu与gc
使用linux命令如prco/stat等
3、anr
面试官问一个问题,首先要回答有哪些知识点,看过哪些框架,比如做性能监测,面试官问你是启动优化吗?可能不那么好回答,但是可以说做了类似抖音,类似快手的APM,别人就明白了。然后就是几个人做,大概做什么我负责哪些部分,我看了哪些框架源码,我自己是怎么想的。
anr监测主要就是文件监听,监听data/anr/trace.txt
4、fps帧率
使用 Geographer(单词可能写错,翻译为:编舞者)
四、如何看项目源码
首先看构造函数
其次浏览属性,不一定能全部看懂,粗略知道含义
看其重要的 api 中的具体实现
看代码的时候,需要思考别人为什么这么设计。比如别人使用数据结构是基于什么考虑,空间换时间,还是时间换空间。 老师以 ArrayList 为例分析了这个过程。
这里有个知识点,ArrayList 扩容的时候,变成以前的1.5倍
HashMap 的 getNode() ,这个方法很精华:
1 | final Node<K,V> getNode(Object key) { |
由于在一定时候会将链表转为红黑树,所以在 get 的时候需要判断是树还是链表:
1 | if (first instanceof HashMap.TreeNode) |
这个判断是否是树,是树就从红黑树中获取,是链表就do-while 遍历链表,直至找到或者遍历到最后一个结点为止。
这里面有个值得注意的点,用 & 符做求余的操作,根据 hash 值求 index :
1 | if ((tab = table) != null && (n = tab.length) > 0 && |
通过 (n - 1) & (hash = hash(key)) 确定当前 key 应该在 HashMap 中数组的位置。注意一下,只有当 n 是 2 的 多少次方的情形才适用,采用 & 操作进行求余的原理可以参考:
java取余位运算_使用位运算&取余_陈安研究员的博客-CSDN博客
五、代码性能评测
在公司证明自己做的事情需要做测试数据,比如说 SparseArray 、ArrayMap 来替换 HashMap ,怎么证明性能更高?那就适用 几个,几千,几万个数据,然后通过 Android Studio 的 Profiler 去可视化查看Memory 指标中 Java 方面占用的空间。
老师解析 SparseArray 源码的时候,put 操作值得关注:
1 | public void put(int key, E value) { |
如果已经存在key-value了,那就直接覆盖,否则,看起来通过
1 | i = ~i; |
即对 i 取反操作就能获取到要存入的位置,这是什么原理?其实这是个技巧,避免了再次计算一次 index ,总而言之就是取反操作(~) 的性质:
当 n 为正数时, ~(n) = -(n + 1)
当 n 为负数时, ~n = (-n) - 1
所以,上述判断 i 的逻辑就比较通顺了:
1 | if (i >= 0) { |
如果找到位置当前有值了,直接覆盖;否则,取反得到真正的 index ,然后根据判断将 key 和 value 存入。附 binarySearch (二分查找)的源码:
1 | static int binarySearch(int[] array, int size, int value) { |
1、SparseArray 和 HashMap 比较:
2个数组key数组和value数组
默认是10的大小,hashmap为16
不需要包装
二分查找,稍微低了点点,HashMap 的hash算法效率高
所以,SparseArray 的主要优势是节省内存。
堆
本质:二叉树来维护一维数组
堆它和树有什么区别?堆不用指针(Node),树会有指针,所以堆更省内存。
二叉树最后一个非叶子节点:(length - 1) /2,排序首先动这个结点。
《算法导论》太难就看《算法4》
opencv 和 ffmpeg 不建议去做,深入太难了
flutter 也不要去写 API ,要去架构,引擎的东西
路哥活得很通透:
大起大落,讲课的时候失去了所有,名言:
人总要失去些什么才能成长
除了生与死,其他的都是小事
算法不用怕,早晚半个小事,坚持3年,大厂没问题
总要去做架构,假如以后的部门黄了
vulcan 是 openGL 的升级版
录音分析,自己面试为什么会失败,一句话一句话听