1. 整体性能如何探测,有哪方面 什么指标,怎么保证更流畅
2. 讲讲架构这块,如何解耦,大项目逻辑多怎么办。
3. android的发展大事件和主要技术发展
4. avtivity(service)启动流程简述
5. 动态化的几种方案
6. 热修复的原理
7. 网络这块怎么优化
8. 数据库性能怎么保证
9. 线程安全怎么保证,异步并发这块你怎么做的
2. 讲讲架构这块,如何解耦,大项目逻辑多怎么办。
3. android的发展大事件和主要技术发展
4. avtivity(service)启动流程简述
5. 动态化的几种方案
6. 热修复的原理
7. 网络这块怎么优化
8. 数据库性能怎么保证
9. 线程安全怎么保证,异步并发这块你怎么做的
按投票排序
按时间排序
5 个回答
其实这几个问题是我根据自己的面试经历总结的,
@AndWang
帮分享出来,大家一起交流。
当前问题描述是“大公司面试这些问题最佳答案,需要各位大大的答案啊?”,其实不一定面试时才了解,当做一次交流蛮好的嘛,也并没有“最佳答案”吧,都是发表一下自己的研究或者观点~
很多方法或点一下子想不起来,需要具体做的时候再google一下,或者跟朋友沟通拓展一下,先做个简单的回答吧,请大家补充。
---
1. 整体性能如何探测,有哪些方面,什么指标,怎么保证更流畅?
性能可以根据帧率、内存、CPU、GPU等指标的数据和表现辅助判断,可以从/proc文件夹下读取文件获取cpu、内存等信息,也可以用dumpsys命令获取帧率等信息,也可以通过android API获取相关信息。
还有很多性能相关的分析工具,Heap Tool、Memory Monitor、Lint、HierarchyView、WireShark、TraceView等。
保证流畅有很多点可以去研究,比如布局、代码、缓存、网络、数据库、异步并发等方面的优化,设计很多的知识点,可以google下,有时间再细述。
2. 讲讲架构这块,如何解耦,大项目逻辑多怎么办。
适当参考我在知乎的一个回答 怎样搭高质量的Android项目框架,框架的结构具体描述? - 马天宇的回答 ,结合模块化、组件化思想去做,多实践一下mvp、mvvm等策略。
3. android的发展大事件和主要技术发展
额,挺多的,朋友们补充吧。
4. avtivity(service)启动流程简述
罗老师研究的好: Android应用程序启动过程源代码分析
5. 动态化的几种方案
早期的H5方案,通过js和java互通增强h5的能力。
还有DexClasssLoader结合反射代理的方案。
还有React Native方案,手淘的Weex框架。
还有Lua等脚本实现动态化方案。
6. 热修复的原理
Github上读一下AndFix这个项目的源码,还有xposed、dexposed。
大致原理就是将java方法通过c/c++修改属性变为public native方法,上下文携带到native层,然后根据上下文指向另一个java方法,从而“偷梁换柱”,如果是支持ART的手机,那么策略不一样,将bug method的关键信息(classloader、theadid等)保留,将修复过的方法的各种信息赋给bug method,完成“移花接木”。
另外,其实有挺多的策略改变运行时行为的,比如:
7. 网络这块怎么优化
尽量避免轮询,控制节奏和频率。
IP直连节省DNS解析时间。
尝试其他数据序列化比如protocol buffer。
采用SPDY方案(或HTTP2.0)来压缩header、多路复用、双向通信等。
服务器做优化,比如分布式、缓存之类的,减少API涉及的业务操作所需要的时间嘛。
API接口数据精简,多个请求是否可以合并,增量、缓存、GIP压缩啊什么的,等等。
8. 数据库性能怎么保证
尝试使用SQLiteStatement取代SQLiteDatabase对象完成操作,避免直接使用SQLiteDatabase提供的update、inset等方法。
索引和事务的充分理解和使用,批量操作使用事务极大提升速度,这个我是做过试验的,效果惊人。
SQL语句拼接和本身的优化,仅查询部分局部数据,使用延迟加载策略。
10万条数据插入比系统SQLiteDatabase操作快一倍,推荐我的LiteOrm数据库框架 GitHub - litesuits/android-lite-orm: LiteOrm is a fast, small, powerful ORM framework for Android. LiteOrm makes you do CRUD operarions on SQLite database with a sigle line of code efficiently.。
9. 线程安全怎么保证,异步并发这块你怎么做的
理解并使用ReentrantLock,Synchronized保护对象或过程,final来保护不可变对象,无状态和只读对象是安全的,合理使用一些 concurrent容器,比如ConcurrentHashmap等,重量级耗时任务考虑是否可以释放锁,多线程下实例化或延迟加载需要保护起来,保护多线程下关键数据访问的原子性,等等还有很多的。。。
推荐研究下Doug Lea主写和设计的java concurrent包,理解CountDownLatch、CyclicBarrier、Semaphore、FutureTask等对象。
具体开上,我使用自己写的SmartExecutor,直接继承ExecutorService,封装了一个公共线程池,全App保证只有一个线程池。源码在这个开源项目里: GitHub - litesuits/android-lite-http: LiteHttp is a simple, intelligent and flexible HTTP framework for Android. With LiteHttp you can make HTTP request with only one line of code! It could convert a java model to the parameter and rander the response JSON as a java model intelligently. 。
在一个 App 中 SmartExecutor 可以有多个实例,每个实例都有独立核心和等待线程数指标,每个实例都有独立的调度和满载处理策略,但它们 共享一个线程池。这种机制既满足不同木块对线程控制和任务调度的独立需求,又共享一个池资源。独立又共享,最大程度上节省资源,提升性能。
控制核心并发数,尽量和CPU核数保持一致(或者多两个)我认为吞吐量是最佳的,线程过多则调度线程消耗CPU和时间,过少则不能充分利用多核的能力。
控制排队策略和排队数量,是否考虑新任务先处理,过度超载丢掉最老的任务。
还有就是业务上,合理调度任务,优化业务逻辑,不要胡搞乱搞,不作恶。
最后我想推荐一下我的个人开源项目: http://litesuits.com?f=zh_perf,欢迎关注嘛。
当前问题描述是“大公司面试这些问题最佳答案,需要各位大大的答案啊?”,其实不一定面试时才了解,当做一次交流蛮好的嘛,也并没有“最佳答案”吧,都是发表一下自己的研究或者观点~
很多方法或点一下子想不起来,需要具体做的时候再google一下,或者跟朋友沟通拓展一下,先做个简单的回答吧,请大家补充。
---
1. 整体性能如何探测,有哪些方面,什么指标,怎么保证更流畅?
性能可以根据帧率、内存、CPU、GPU等指标的数据和表现辅助判断,可以从/proc文件夹下读取文件获取cpu、内存等信息,也可以用dumpsys命令获取帧率等信息,也可以通过android API获取相关信息。
还有很多性能相关的分析工具,Heap Tool、Memory Monitor、Lint、HierarchyView、WireShark、TraceView等。
保证流畅有很多点可以去研究,比如布局、代码、缓存、网络、数据库、异步并发等方面的优化,设计很多的知识点,可以google下,有时间再细述。
- 布局充分利用include、viewstub、meger等标签,控制层级,避免过度渲染(绘制)。
- 代码上尽量使用final、局部变量、系统函数如arraycoy等、位移操作是否可以代替乘除、for循环是否可以避免size计算和new对象等等。
- 缓存方面,线程、位图、视图、网络数据是否客户缓存或者IO用缓冲流,充分的重复利用。
- 网络方面,如尽量避免轮询,控制节奏和频率,IP直连,采用SPDY方案(或HTTP2.0)来实现压缩header、多路复用、双向通信等,API数据压缩,多个请求是否可以合并,数据压缩和尝试protocol buffer相关序列化方案。
- 数据库方面,尝用SQLiteStatement代替SQLiteDatabase完成操作,索引和事务的充分理解和使用,注意SQL语句语法和拼接,采用部分查询和延迟加载。
- 异步并发方面,全App只有一个线程池,控制核心并发数量,控制超载时排队数量和策略,合理调度任务,优化业务逻辑。
- 最后关于帧率,你看到的视觉卡顿,直接原因基本是“掉帧”。关于**帧率**,尽量保证主线程里做的事情,不会超过16毫秒(其实这挺难的),16毫秒大法好,具体可以去理解下CPU、GPU、屏幕三者如何配合完成渲染的,推荐老罗的博客。
2. 讲讲架构这块,如何解耦,大项目逻辑多怎么办。
适当参考我在知乎的一个回答 怎样搭高质量的Android项目框架,框架的结构具体描述? - 马天宇的回答 ,结合模块化、组件化思想去做,多实践一下mvp、mvvm等策略。
3. android的发展大事件和主要技术发展
额,挺多的,朋友们补充吧。
4. avtivity(service)启动流程简述
罗老师研究的好: Android应用程序启动过程源代码分析
5. 动态化的几种方案
早期的H5方案,通过js和java互通增强h5的能力。
还有DexClasssLoader结合反射代理的方案。
还有React Native方案,手淘的Weex框架。
还有Lua等脚本实现动态化方案。
6. 热修复的原理
Github上读一下AndFix这个项目的源码,还有xposed、dexposed。
大致原理就是将java方法通过c/c++修改属性变为public native方法,上下文携带到native层,然后根据上下文指向另一个java方法,从而“偷梁换柱”,如果是支持ART的手机,那么策略不一样,将bug method的关键信息(classloader、theadid等)保留,将修复过的方法的各种信息赋给bug method,完成“移花接木”。
另外,其实有挺多的策略改变运行时行为的,比如:
- JavaSisst:字节码修改类库,依赖字节码修改和DX类库,可以完成动态替换和切面编程。
- AspectJ:依赖字节码编织器,需要按照其语法来编写,需要一点“编织”时间。
- Xposed方案,简直是一个Bug,神器,没准以后会被Android修复呢,不仅可以改变自己的类行为还可以hook系统的方法,root过的机器还可以hook其他App和系统进程。
7. 网络这块怎么优化
尽量避免轮询,控制节奏和频率。
IP直连节省DNS解析时间。
尝试其他数据序列化比如protocol buffer。
采用SPDY方案(或HTTP2.0)来压缩header、多路复用、双向通信等。
服务器做优化,比如分布式、缓存之类的,减少API涉及的业务操作所需要的时间嘛。
API接口数据精简,多个请求是否可以合并,增量、缓存、GIP压缩啊什么的,等等。
8. 数据库性能怎么保证
尝试使用SQLiteStatement取代SQLiteDatabase对象完成操作,避免直接使用SQLiteDatabase提供的update、inset等方法。
索引和事务的充分理解和使用,批量操作使用事务极大提升速度,这个我是做过试验的,效果惊人。
SQL语句拼接和本身的优化,仅查询部分局部数据,使用延迟加载策略。
10万条数据插入比系统SQLiteDatabase操作快一倍,推荐我的LiteOrm数据库框架 GitHub - litesuits/android-lite-orm: LiteOrm is a fast, small, powerful ORM framework for Android. LiteOrm makes you do CRUD operarions on SQLite database with a sigle line of code efficiently.。
9. 线程安全怎么保证,异步并发这块你怎么做的
理解并使用ReentrantLock,Synchronized保护对象或过程,final来保护不可变对象,无状态和只读对象是安全的,合理使用一些 concurrent容器,比如ConcurrentHashmap等,重量级耗时任务考虑是否可以释放锁,多线程下实例化或延迟加载需要保护起来,保护多线程下关键数据访问的原子性,等等还有很多的。。。
推荐研究下Doug Lea主写和设计的java concurrent包,理解CountDownLatch、CyclicBarrier、Semaphore、FutureTask等对象。
具体开上,我使用自己写的SmartExecutor,直接继承ExecutorService,封装了一个公共线程池,全App保证只有一个线程池。源码在这个开源项目里: GitHub - litesuits/android-lite-http: LiteHttp is a simple, intelligent and flexible HTTP framework for Android. With LiteHttp you can make HTTP request with only one line of code! It could convert a java model to the parameter and rander the response JSON as a java model intelligently. 。
在一个 App 中 SmartExecutor 可以有多个实例,每个实例都有独立核心和等待线程数指标,每个实例都有独立的调度和满载处理策略,但它们 共享一个线程池。这种机制既满足不同木块对线程控制和任务调度的独立需求,又共享一个池资源。独立又共享,最大程度上节省资源,提升性能。
控制核心并发数,尽量和CPU核数保持一致(或者多两个)我认为吞吐量是最佳的,线程过多则调度线程消耗CPU和时间,过少则不能充分利用多核的能力。
控制排队策略和排队数量,是否考虑新任务先处理,过度超载丢掉最老的任务。
还有就是业务上,合理调度任务,优化业务逻辑,不要胡搞乱搞,不作恶。
最后我想推荐一下我的个人开源项目: http://litesuits.com?f=zh_perf,欢迎关注嘛。
试着回答一下有关
网络优化的吧,今天正好复习了一些:
1.使用 post的时候对body使用gzip压缩,http 2.0也支持对header压缩,顺便可以讲一下http 2.0有哪些优化(多路复用、双向通信等);
2.对数据进行 Prefetch(预取)。比如在一个预览页面里可以先请求将要访问的详情页的数据,打开详情页的时候就直接显示了,注意需要根据网络状况(2G、3G/4G、wifi等,也可进一步获取实际的网速)确定合理的Prefetch数据量,数据多了反而影响了速度、少了达不到效果;
3. 断点下载可以使用多线程方式,第一次请求完可以从response header里获取etag和last-modified字段,下次请求的时候带上,如果没有改变etag并且时间没到则返回304,直接使用缓存;
4. 减小返回数据量。一方面客户端获取API数据时可以使用gzip压缩;另一方面服务端可以根据设备尺寸、网络情况等返回不同分辨率图片,使用JSON、protobuf代替XML,WebP代替其他图片格式;
5. 设置合理的同步频率。对于一些需要经常同步数据的需求,不要过于频繁的请求数据。比如上一次请求后没有新数据的话,下一次请求间隔可以加倍,避免频繁的请求耗尽手机电量;另外在网络状况不好时可以采用Batch策略,即将请求放入一个队列里,等待网络状况好转时才一起去请求;
其他诸如IP直连、请求合并、连接复用(keep-alive)等也有人提到了,就不再说了。
希望大家都面试顺利~
1.使用 post的时候对body使用gzip压缩,http 2.0也支持对header压缩,顺便可以讲一下http 2.0有哪些优化(多路复用、双向通信等);
2.对数据进行 Prefetch(预取)。比如在一个预览页面里可以先请求将要访问的详情页的数据,打开详情页的时候就直接显示了,注意需要根据网络状况(2G、3G/4G、wifi等,也可进一步获取实际的网速)确定合理的Prefetch数据量,数据多了反而影响了速度、少了达不到效果;
3. 断点下载可以使用多线程方式,第一次请求完可以从response header里获取etag和last-modified字段,下次请求的时候带上,如果没有改变etag并且时间没到则返回304,直接使用缓存;
4. 减小返回数据量。一方面客户端获取API数据时可以使用gzip压缩;另一方面服务端可以根据设备尺寸、网络情况等返回不同分辨率图片,使用JSON、protobuf代替XML,WebP代替其他图片格式;
5. 设置合理的同步频率。对于一些需要经常同步数据的需求,不要过于频繁的请求数据。比如上一次请求后没有新数据的话,下一次请求间隔可以加倍,避免频繁的请求耗尽手机电量;另外在网络状况不好时可以采用Batch策略,即将请求放入一个队列里,等待网络状况好转时才一起去请求;
其他诸如IP直连、请求合并、连接复用(keep-alive)等也有人提到了,就不再说了。
希望大家都面试顺利~