当前位置:   article > 正文

Android 开发面试备战春招之“你做过那些性能优化?”,2024年最新面试真题及答案解析_android性能优化面试题

android性能优化面试题

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

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

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

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

如果你需要这些资料,可以添加V获取:vip204888 (备注Android)
img

正文

  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 (;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/891997
推荐阅读
相关标签