Android 开发面试备战春招之“你做过那些性能优化?”(2)

//分发之前打印

final Printer logging = me.mLogging;

if (logging != null) {

logging.println(">>>>> Dispatching to " + msg.target + " " +

msg.callback + ": " + msg.what);

}

try {

//分发消息

msg.target.dispatchMessage(msg);

//分发之后打印

if (logging != null) {

logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);

}

}

}

  1. 基于 Choreographer 回调函数 postFrameCallback 来监控

  1. 基于开源框架 BlockCanary 来监控

  2. 基于开源框架 rabbit-client 来监控

怎么避免卡顿:

一定要避免在主线程中做耗时任务,总结一下 Android 中主线程的场景:

  1. UI 生命周期的控制

  2. 系统事件的处理

  3. 消息处理

  4. 界面布局

  5. 界面绘制

  6. 界面刷新

还有一个最重要的就是避免内存抖动,不要在短时间内频繁的内存分配和释放。

基于这几点去说卡顿肯定是没有问题的。

  • 3.减少内存占用

可以从如下几个方面去展开说明:

  1. AutoBoxing(自动装箱): 能用小的坚决不用大的。

  2. 内存复用

  3. 使用最优的数据类型

  4. 枚举类型: 使用注解枚举限制替换 Enum

  5. 图片内存优化(这里可以从 Glide 等开源框架去说下它们是怎么设计的)

  • 选择合适的位图格式

  • bitmap 内存复用,压缩

  • 图片的多级缓存

  1. 基本数据类型如果不用修改的建议全部写成 static final,因为 它不需要进行初始化工作,直接打包到 dex 就可以直接使用,并不会在 类 中进行申请内存

  2. 字符串拼接别用 +=,使用 StringBuffer 或 StringBuilder

  3. 不要在 onMeause, onLayout, onDraw 中去刷新 UI

  4. 尽量使用 C++ 代码转换 YUV 格式,别用 Java 代码转换 RGB 等格式,真的很占用内存

  • 4.减少程序异常

减少程序异常那么我们可以从稳定性和 Crash 来分别说明。

这个我们将在第四点会详细的介绍程序的稳定性和 Crash 。

如果说出这些,再实际开发中举例说明一下怎么解决的应该是没有问题的。

3、你在项目中有没有遇见卡顿问题?是怎么排查卡顿?又是怎么优化的?


程序员:

有遇见, 比如在主线程中做耗时操作、频繁的创建对象和销毁对象导致 GC 回收频繁、布局的层级多等。

面试官:

嗯,那具体说说是怎么优化的。

程序员:

这里我们还是可以从显示原理和优化建议来展开说明,参考如下:

  1. 显示原理:
  • 绘制原理:

  • 刷新原理:

View 的 requestLayout 和 ViewRootImpl##setView 最终都会调用 ViewRootImpl 的 requestLayout 方法,然后通过 scheduleTraversals 方法向 Choreographer 提交一个绘制任务,然后再通过 DisplayEventReceiver 向底层请求 vsync 垂直同步信号,当 vsync 信号来的时候,会通过 JNI 回调回来,在通过 Handler 往消息队列 post 一个异步任务,最终是 ViewRootImpl 去执行绘制任务,最后调用 performTraversals 方法,完成绘制。

详细流程可以参考下面流程图:

  1. 卡顿的根本原因:

从刷新原理来看卡顿的根本原理是有两个地方会造成掉帧:

一个是主线程有其它耗时操作,导致doFrame 没有机会在 vsync 信号发出之后 16 毫秒内调用;

还有一个就是当前 doFrame 方法耗时,绘制太久,下一个 vsync 信号来的时候这一帧还没画完,造成掉帧。

既然我们知道了卡顿的根本原因,那么我们就可以监控卡顿,从而可以对卡顿优化做到极致。我们可以从下面四个方面来监控应用程序卡顿:

  • 基于 Looper 的 Printer 分发消息的时间差值来判断是否卡顿。

//1. 开启监听

Looper.myLooper().setMessageLogging(new

LogPrinter(Log.DEBUG, “ActivityThread”));

//2. 只要分发消息那么就会在之前和之后分别打印消息

public static void loop() {

final Looper me = myLooper();

if (me == null) {

throw new RuntimeException(“No Looper; Looper.prepare() wasn’t called on this thread.”);

}

final MessageQueue queue = me.mQueue;

for (;😉 {

Message msg = queue.next(); // might block

//分发之前打印

final Printer logging = me.mLogging;

if (logging != null) {

logging.println(">>>>> Dispatching to " + msg.target + " " +

msg.callback + ": " + msg.what);

}

try {

//分发消息

msg.target.dispatchMessage(msg);

//分发之后打印

if (logging != null) {

logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);

}

}

}

  • 基于 Choreographer 回调函数 postFrameCallback 来监控

  1. 怎么可以提高程序运行流畅

1.布局优化:

1.1 布局优化分析工具:

1.2 优化方案:

  1. 提升动画性能
  • 尽量别用补间动画,改为属性动画,因为通过性能监控发现补间动画重绘非常频繁

  • 使用硬件加速提高渲染速度,实现平滑的动画效果。

  1. 怎么避免卡顿:

一定要避免在主线程中做耗时任务,总结一下 Android 中主线程的场景:

  • UI 生命周期的控制

  • 系统事件的处理

  • 消息处理

  • 界面布局

  • 界面绘制

  • 界面刷新

基于这几点去说卡顿肯定是没有问题的。

4、怎么保证 APP 的稳定运行?


程序员:

保证程序的稳定我们可以从内存、代码质量、Crash、ANR、后台存活等知识点来展开优化。

面试官:

那你具体说说你是怎么做的?

程序员:

1.内存

可以从第二点内存优化来说明

2.代码质量

  1. 团队之前相互代码审查,保证了代码的质量,也可以学习到了其它同事码代码的思想。

  2. 使用 Link 扫描代码,查看是否有缺陷性。

3. Crash

  1. 通过实现 Thread.UncaughtExceptionHandler 接口来全局监控异常状态,发生 Crash 及时上传日志给后台,并且及时通过插件包修复。

  2. Native 线上通过 Bugly 框架实时监控程序异常状况,线下局域网使用 Google 开源的 breakpad 框架。发生异常就搜集日志上传服务器(这里要注意的是日志上传的性能问题,后面省电模块会说明)

4. ANR

5. 后台存活

面试官:

嗯,你对知识点掌握的挺好。

说完这些,这一关也算是过了。

5、说说你在项目中网络优化?


程序员:

有,这一点其实可以通过 OKHTTP 连接池和 Http 缓存来说一下(当然这里不会再展开分析 OKHTTP 源码了)

面试官:

那你具体说一下吧

程序员

说了这些之后,再说一下你当前使用网络框架它们做了哪些优化比如 OKHTTP(Socket 连接池、Http缓存、责任链)、Retrofit(动态代理)。说了这些一般这关也算是过了。

6、你在项目中有用过哪些存储方式? 对它们的性能有过优化吗?


程序员:

主要用过 sp,File,SQLite 存储方式。其中对 sp 和 sqlite 做了优化。

面试官:

那你说说都做了哪些优化?

程序员:

这一块如果你使用过其它第三方的数据库,可以说说它们的原理和它们存取的方式。

7、你在项目中有做过自定义 View 吗?有对它做过什么优化?


程序员:

有做过。比如重复绘制,还有大图长图有过优化。

面试官:

那具体说一说

程序员:

最后也是结合真实场景具体说一个。

8、你们项目的耗电量怎么样? 有做过优化吗?


程序员:

在没有优化之前持续工作 30 分钟的耗电量是 8%, 优化后是 4%。

面试官:

那你说一说你是怎么优化的。

程序员:

因为我们产品是一款社交通信的软件,有音视频通话、GPS 定位上报、长连接的场景,所以优化起来确实有点困难。不过最后也还是优化了一半的电量下去。主要做了如下优化:

说出这些之后,在结合项目一个真实的优化点来说明一下。

9、有做过日志优化吗?


程序员:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

总结

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的14套腾讯、字节跳动、阿里、百度等2021最新面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。

2020面试真题解析
腾讯面试真题解析

阿里巴巴面试真题解析

字节跳动面试真题解析
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img
节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-hAljruLi-1712921981305)]

总结

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的14套腾讯、字节跳动、阿里、百度等2021最新面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。

[外链图片转存中…(img-9N2uegLs-1712921981305)]
[外链图片转存中…(img-JZRnJjtF-1712921981306)]

[外链图片转存中…(img-Z5qBnHSq-1712921981306)]

[外链图片转存中…(img-h9iFiCXD-1712921981306)]
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-yarhuF72-1712921981307)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值