安卓端性能优化
- 兼容性测试:云测,阿里云,umeng,真机top100 monkey测试(尤其是针对版本更新)
- Crash
- 可修复性异常
- 可忽略性异常:使用 Looper Hook
- 测试环境多进程 异常捕获
- ANR
- 应用层:主线程阻塞(死循环,IO,超级计算,主线线程等待子线程的锁)
- 系统层:CPU资源优先级过低,导致应用在后台ANR(当应用进入后台时,它可能会被系统赋予更低的CPU资源优先级,以便其他前台应用可以使用更多的资源。但是,这并不意味着应用的CPU资源优先级一定过低,因为系统的资源分配取决于多种因素,包括应用的优先级、当前系统负载等。如果应用在后台中运行了长时间的工作,并且消耗了大量的CPU资源,那么它可能会受到ANR的影响,即使它在后台中运行。)
- ANR触发场景
- Service forground 绑定前台通知,5s
- 广播,前台10s,后台60
- 事件输入反馈,5s(个别手机ROM会自行拦截,无提示)
- contentProvider 也会导致(很少用,未处理过)
- ANR 检测方法(local 与线上)
- watch-dog,通过向主线程插入线程并在子线程做等待检查判断是否有可能发生了ANR
- Matrix
- 第三方crash平台,bugly,阿里云emas,umeng等等
- 启动优化
隐私策略,启动任务管理(有向无环图,多线程初始化,多进程管理,延时初始化,递进初始化),第三方初始化管理,排除ContentProvider流氓初始化行为
- 首屏加载优化
配合启动优化后,权衡业务与用户体验。优化布局,class初始化(减少巨型class,比如retrofit的service),分屏加载,布局预初始化(这部分时间从启动优化哪里并行扣出来)
- 卡顿
- 卡顿监听(本地编舞者(测试小米120fps是有水分的),线上阿里云,umeng等)
- UI布局性能,重绘,重测(降低布局层级,自定义view 无xml化,或constrantlayout,禁止relativelayout)
- 内存使用:内存滥用(view 不重用,滥用静态存储,数据缓存无释放策略)主要是导致频繁GC造成卡顿
- 代码质量,框架
- 多进程分担主进程内存压力
- 内存泄漏:在充分接入 lifecycle 之后这两年很少再碰到了
- 内存抖动:典型的是draw方法中 创建大量新对象导致,触发年轻代gc,造成一定的卡顿
- 网络
- 网络协议层错误上报(http,tcp,dns)
- 业务侧接口数据异常解析报错监听上报,预警
- 用户网络场景质量 ping值
- 网络服务容灾,多域名,多资源(最早是在广告业务中应用)
研发流程优化,提升研发效率
深入参与不同的项目,深入参与各个环节的协作过程,收集分析问题,优化流程制度。配合工具与团队协作流程一起发力,核心是:为团队的每个角色服务,而不是角色为流程服务
Gradle插件,插桩
用kotlin写极大的降低插件开发门槛,提升效率
在CI建设中大量开发Gradle插件,打包插件,lint插件重写,lint支持动态从服务器读取lint配置,支持局部降级容错,支持增量扫描(自定义扫描范围)(自定义lint task 继承自BaseTask,在super.configure之前加载自己重写的lint gradle 库,分为 打包发布插件,lint gradle 插件)
appplugin,libraryplugin
插件开发文档较少除了gradle官方文档剩下的就是读源码,结合androidbuild流程进行方案设计与开发
- 插桩
使用 Transform 与ASM 修改 .class文件
写过 打印方法耗时的demo,前置需要2个知识点,一个是插件开发,rigisterTransform,一个是会读字节码文件(学习jvm时掌握)
transform有class访问器跟 方法访问器,来命中目标方法,ASMified可以讲目标class的改写指令进行可视化,copy进行调试。
Flutter开发经验
去年为团队培养出了一个flutter中级开发,3个初级开发,制定阶梯式学习项目 ladder-flutter,亲自参与到有 native 通信,getX状态管理,多引擎管理,banner+信息流开发。搭建 flutter 网络框架,利用范型与分层架构提供快速的数据解析能力,与流式API
面试过程:主要是记录下回答得不好的地方
带了ipad,用于讲解时展示一些图片资料,与用画图的方式更清晰的方式回复面试问题
一面:基础技术(JVM,多线程偏多)
- 说一下JVM的结构
说了堆,方法区,线程栈三个块的介绍。这里漏掉了说太快漏掉了程序计数器跟本地方法栈,但在面试官特地的问的时候也正确回答了作用。
- volatile 的作用与实现原理
用于变量修改时在多线程场景下保持修改的可见性,但并不能完全解决多线程并发修改的问题。举例了两个线程访问 i++的例子。
- 那介绍一下为什么说 i++是两步操作
介绍了i++字节码指令执行顺序以及方法栈执行细节
- Volatile 修饰的变量在修改时具体如何实现可见性的
这一步我直接回复不知道了,没有特地看过 volatile 修饰的字节码,不瞎说。面试官便给我进行了简单的介绍,我当时就想着回来一定要自己也看一看,之前为啥没看,哎。
首先在字节码中 针对Volatile修饰的变量会有一个 ACC_VOLATILE 标志:
- 可见性:当前线程修改后其他线程堆修改后的值立即可见,线程修改值之后立即写入到主存区,不用等到线程出栈的时候才同步到主存区。(线程工作区内存中保存的值要等待线程出栈时才写回主存区,在此之前其他线程对修改是不可见的)
- 顺序性:即读写的顺序性,而不会出现 读的过程中写入,或写入过程中被读取
- 不保证原子性:比如i++
// 读-写顺序性,假设有一个被 ACC_VOLATILE 标志修饰的 volatile 字段 v
// 线程 1
getfield v // 读取字段 v 的值
iconst_2 // 将常量值 2 压入操作数栈
putfield v // 将操作数栈顶的值存入字段 v 中
// 线程 2
getfield v // 读取字段 v 的值
//写-读顺序性,假设有一个被 ACC_VOLATILE 标志修饰的 volatile 字段 v
// 线程 1
iconst_1 // 将常量值 1 压入操作数栈
putfield v // 将操作数栈顶的值存入字段 v 中
// 线程 2
getfield v // 读取字段 v 的值
- 那如何保证原子性
加锁跟使用Atomic类
- Atomic 是如何保证原子性的,或者说如何实现CAS的
这里太久没碰这块代码,听到CAS蒙了,问了一下原来是说CompareAndSet。不过这里依然是没准备,直接回答了未深入研究。
gpt:CAS底层采用CPU原子指令或锁机制来实现,多数情况采用cpu原子指令,通过硬件级别的操作来完成对一个内存位置的读写比较。
这个快确实深啊,而且这种信息不太容易记忆。作为一个了解性内容吧。并不会产生二次开发所以应用比原理要重要。
- 你刚讲到了堆,锁,那你了解过对象的markword吗,它里面有什么信息
markword有了解,但是没有特别深。记得比较清楚的是有age 用于垃圾回收判断,有锁的标记位。
- 那对于偏向锁是如何转到轻量锁的
坦诚了一下想不起来,这里我自己虽然学习过,但是没作为重点知识准备。
markword中32位中会有几位来标记锁信息,其中包含当前持锁的线程ID
分为 无锁状态(对象无锁),偏向锁(单线程访问有锁对象),轻量锁(多线程访问有锁对象),重量级锁(轻量级锁无法解决竞争问题时上升到重量级锁,借助操作系统完成锁机制)。这里又能展开,锁竞争原理,锁开销不同的原因。默认在竞争锁时,为获取到锁的线程会进行Spin(自旋,最大10次),在无阻塞情况下尝试获取锁,超过次数阈值后,膨胀为重量级锁,基于操作系统的锁机制,进行阻塞式等待锁的释放,减少自旋开销(开销具体是什么?不想挖了)
应用到代码里完成知识从理解到应用的闭环:
使用synchronized 修饰方法,类来设置轻量级锁
使用 object.lock()或者可重用锁,读写分离锁,都是重量级锁
- 说说 age在垃圾回收中如何应用
这里回答比较清晰,从垃圾回收分区到age增长到对象换内存区
- 另外还问了handler消息机制
这部分主要是讲了ThreadLocal的特性,以及结合它如何完成多线程通信的。包括messageQueue的消息处理方式。对于native层nativePollOnce机制直接回复了未深入。我也不打算深入,集中在应用层的使用上收益比较大。
- 问了app启动流程,与启动优化
- TLS/TCP的 部分里拥塞控制跟流量控制部分没有回答上来
传输数据时数据包是被切成小块的(减少重传次数),切多大则是根据下面的两个策略进行平衡的。
拥塞控制:这在接受数据方,这部分是因为在做面试准备的时候没有刻意看,导致面试的时候没有结构化的进行表述。整体可以总结为在做数据传输时,每一个tcp链接都有窗口大小平衡每个tcp的的传输速率(分配到的带宽窗口),窗口大小自然是动态的,通过控制窗口大小避免单个tcp占用过大带宽,导致传输拥塞。
流量控制:发送方会根据接收方允许的窗口大小,调整自己发送的数据包大小,避免拥塞,这一步则是流量控制。
日常开发中针对这个优化则是降低接口数据体量,做接口拆分,分批次请求等等。
- Retrofit用过吧,说下他动态代理的实现原理
这里确实很深,我简单说了下自己学习掌握的原理概论与一些API与使用 ,因为这个要获取运行时字节码才可以搞明白。
面试官为我慷慨讲解了一些细节,没太记清楚,但我自己对于字节码理解还行,所以相对的给了一些临场反馈,全当学习了。当然,非常感谢他与我分享。就冲这些,这波面试已经不算白来了。
二面:TL
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数HarmonyOS鸿蒙开发工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年HarmonyOS鸿蒙开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上HarmonyOS鸿蒙开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新
如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注鸿蒙获取)
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
正体系化!**
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新
如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注鸿蒙获取)
[外链图片转存中…(img-xfQcBaUT-1712646065373)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!