Android高级进阶

真香定律,我就是从这里跳下去也不刷面试题!真香~

2019-12-27  本文已影响0人  小小小小怪兽_666

本文主要是整理了中高级安卓需要的(或者说面试被频繁问到的内容),主要作为参考大纲,之后会陆续更新每个详细部分,供大家参考,互相学习。

记得前几年看到一档综艺节目“我就是从这里跳下去,也不吃这碗炒饭~~~真香”王境泽的一句随口的话成了所谓的真香定律。记得前几年看到身边很多人都在刷面试题,那个时候也没怎么刷,后来却加入了真香定律的一员

之前吧很多面试题目整理在了GitHub上了,短短几周就有554多个star.由于个别原因删了原来的那个库(俗称删库跑路~手动滑稽)现在创建了新的大家可以点一点https://github.com/xiangjiana/Android-MS
以上所有的加上GitHub上面面试题都整理成一份新的PDF~希望这些对大家有所帮助和突破
(VX:mm14525201314)

有好的面试内容欢迎投稿我

一丶数据库的操作类型有哪些,如何导入外部数据库?

读懂题目。如果碰到问题比较模糊的时候可以适当问问面试官。
配合面试官来面试: 面试是一个相互了解的过程,要充分利用面试的题目和时间把自己的能力和技术展现出来,面试官能够看到你的真实技术。

1) 使用数据库的方式有哪些?

①.openOrCreateDatabase(String path);
② .继 承 SqliteOpenHelper 类 对 数 据 库 及 其 版 本 进 行 管 理(onCreate,onUpgrade)
当 在 程 序 当 中 调 用 这 个 类 的 方 法 getWritableDatabase()或者 getReadableDatabase();的时候才会打开数据库。如果当时没有数据库文件的时候,系统就会自动生成一个数据库。

2) 操作的类型:增删改查 CRUD

直接操作 SQL 语句: SQliteDatabase.execSQL(sql);
面 向 对 象 的 操 作 方 式:SQLiteDatabase.insert(table,nullColumnHack,ContentValues);

如何导入外部数据库?

一般外部数据库文件可能放在 SD 卡或者 res/raw 或者 assets 目录下面。写一个 DBManager 的类来管理,数据库文件搬家,先把数据库文件复制到”/data/data/包名/databases/”目录下面,然后通过db.openOrCreateDatabase(db 文件),打开数据库使用。我上一个项目就是这么做的,由于 app 上架之前就有一些初始数据需要内置,也会碰到数据的升级等问题,我是这么做的…… 同时我碰到最有意思的问题就是关于数据库并发操作的问题,
比如: 多线程操作数据库的时候,我采取的是封装使用互斥锁来解
决……

二丶是否使用过IntentService作用是什么,AIDL 解决了什么问题?

如果有一个任务,可以分成很多个子任务,需要按照顺序来完成,如果需要放到一个服务中完成,那么使用 IntentService 是最好的选择。一般我们所使用的 Service 是运行在主线程当中的,所以在 service 里面编写耗时的操作代码,则会卡主线程会 ANR。为了解决这样的问题,谷歌引入了 IntentService.

IntentService 的优点:

(1) 它创建一个独立的工作线程来处理所有一个一个 intent。
(2) 创建了一个工作队列,来逐个发送 intent 给 onHandleIntent()
(3) 不需要主动调用 stopSelf()来结束服务,因为源码里面自己实现了自动关闭。
(4) 默认实现了 onBind()返回的 null。
(5) 默认实现的 onStartCommand()的目的是将 intent 插入到工作队列。

总结: 使用IntentService 的好处有哪些。首先,省去了手动开线程的麻烦;第二,不用手动停止 service;第三,由于设计了工作队列,可以启动多次---startService(),但是只有一个 service 实例和一个工作线程。一个一个熟悉怒执行。

AIDL 解决了什么问题?

AIDL 的全称: Android Interface Definition Language,安卓接口定义语言。由于 Android 系统中的进程之间不能共享内存,所以需要提供一些机制在不同的进程之间进行数据通信。
远程过程调用: RPC—Remote Procedure Call。 安卓就是提供了一种 IDL 的解决方案来公开自己的服务接口。AIDL:可以理解为双方的一个协议合同。双方都要持有这份协议---文本协议 xxx.aidl 文件(安卓内部编译的时候会将 aidl 协议翻译生成一个xxx.java 文件---代理模式:Binder 驱动有关的,Linux 底层通讯有关的。)
在系统源码里面有大量用到 aidl,比如系统服务。
电视机顶盒系统开发。你的服务要暴露给别的开发者来使用。
讲解 Binder 机制。

三丶 fragment的特点?

fragment的特点?( 你用 fragment有没有领略到一些乐趣或者有没有踩过什么坑?)

fragment 的设计主要是把 Activity 界面包括其逻辑打碎成很多个独立的模块,这样便于模块的重用和更灵活地组装呈现多样的界面。

1) Fragment 可以作为 Activity 界面的一个部分组成;
2) 可以在一个 Activity 里面出现多个 Fragment,并且一个 fragment 可以在多个Activity 中使用;
3) 在 Activity 运行中,可以动态地添加、删除、替换 Fragment。
4) Fragment 有自己的生命周期的,可以响应输入事件。

踩过的坑:

1.重叠;

  1. 注解 newAPI(兼容包解决);
  2. Setarguement()初始化数据;
  3. 不能在 onsave()方法后,commit;
  4. 入栈出栈问题; --事务。像 Activity 跳转一样的效果,同时返回的时候还能回到之前的页面(fragment)并且状态都还在。replace(f1,f2)严重影响生命周期

四丶View绘制流程和优化自定义 view

Measure: 测量,测量自己。如果是 ViewGroup 就需要测量里面的所有 childview.测 量 的 结 果 怎 么 办 ? setMeasuredDimension(resolveSizeAndState(maxWidth,widthMeasureSpec, childState), heightSizeAndState);设置自己的大小。
Layout: 摆放,把自己摆放在哪个位置。如果是 ViewGroup 就需要发放里面的所有childview.
怎么去具体摆放呢?
Draw: 绘制

  /*
   * Draw traversal performs several drawing steps which must be executed
        in the appropriate order:
        Draw the background
          If necessary, save the canvas' layers to prepare for fading
        Draw view's content
        Draw children
           If necessary, draw the fading edges and restore layers
        Draw decorations (scrollbars for instance)
*/
优化自定义 view

1)减少在 onDraw 里面大量计算和对象创建和大量内存分配。
2)应该尽量少用 invalidate()次数。
3)view 里面耗时的操作 layout。减少 requestLayout()避免让 UI 系统重新遍历整棵树。Mearsure
4)如果你有一个很复杂的布局,不如将这个复杂的布局直接使用你自己的写的ViewGroup 来实现。减少了一个树的层次关系 全部都是自己测量和 layout,达到优化的目的。(Facebook 就经常这么干)

五丶 什么情况导致内存泄漏

内存溢出和内存泄漏有什么区别?

程序运行时所需的内存大于程序允许的最高内存,这时会出现内存溢出; 应该被回收的内存,由于各种原因回收不了,这就是内存泄漏。内存泄漏过多,就容易导致内存溢出。

1)什么是内存泄漏: 最好解释清楚 GC 垃圾回收机制以及概念 GC Root。
2)为什么会有内存泄漏:因为内存泄漏是属于人为的失误造成的。而且面向对象开发关系复杂、多线程的关系,很容易出现引用层级关系很深以及很混乱。

六丶Bitmap很容易造成OOM,一般有几种优化方式?什么情况导致OOM?

Bitmap很容易造成OOM,一般有几种优化方式?

1.使用缓存;
2.压缩图片;
3.及时回收;

什么情况导致oom:

OOM 产生的原因: 内存不足,android 系统为每一个应用程序都设置了一个硬性的条件:
DalvikHeapSize 最大阀值 64M/48M/24M.如果你的应用程序内存占用接近这个阀值,此时如果再尝试内存分配的时候就会造成 OOM

1)内存泄露多了就容易导致 OOM
2)大图的处理。压缩图片。平时开发就要注意对象的频繁创建和回收。
3)可以适当的检测: ActivityManager.getMemoryClass()可以用来查询当前应用的HeapSize阀值。可以通过命名 adb shellgetProp | grepdalvik.vm.heapxxxlimit 查看。

如何避免内存泄露:

1) 减小对象的内存占用:

①使用更加轻量级的数据结构:考虑适当的情况下替代 HashMap 等传统数据结构而使用安卓专门为手机研发的 数 据 结 构 类ArrayMap/SparseArray SparseLongMap/SparseIntMap/SparseBoolMap 更加高效HashMap.put(string,Object);Object o = map.get(string);会导致一些没必要的自动装箱和拆箱。
适当的避免在 android 中使用 Enum 枚举,替代使用普通的 static 常量。(一般还是提倡多用枚举---软件的架构设计方面;如果碰到这个枚举需要大量使用的时候就应该更加倾向于解决性能问题)
③较少 Bitmap 对象的内存占用:使用 inSampleSize:计算图片压缩比例进行图片压缩,可以避免大图加载造成OOM; decodeformat : 图 片 的 解 码 格 式 选 择 ,ARGB_8888/RGB_565/ARGB_4444/ALPHA_8,还可以使用 WebP。
④使用更小的图片:资源图片里面,是否存在还可以继续压缩的空间。

2) 内存对象的重复利用:

使用对象池技术,两种:

1.自己写;
2.利用系统既有的对象池机制。比如 LRU(Last Recently Use)算法
ListView/GridView 源 码 可 以 看 到 重 用 的 情 况 ConvertView 的 复 用 。RecyclerView 中 Recycler 源码。
Bitmap 的复用,Listview 等要显示大量图片。需要使用LRU 缓存机制来复用图片。
避免在 onDraw 方法里面执行对象的创建,要复用。避免内存抖动。
常见的 java 基础问题---StringBuilder
3) 避免对象的内存泄露
4) 使用一些内存的优化策略

七丶Android动画框架实现原理

传统的动画框架: View.startAnimation();
弊端: 移动后不能点击。原因?跟实现机制有关系。所有的透明度、旋转、平移、缩放动画,都是在 view 不断刷新调用 draw 的情况下实现的。调用的canvas.translate(xxx),canvas.scaleX(xxx)…. Xxx:matrix 像素矩阵来控制动画的数据。记得看源码,结合多只缩放的 demo 看源码。

补间动画分为哪几种形式:
补间动画可以分为四种形式,分别是alpha(淡入淡出),translate(位移),scale(缩放大小),rotate(旋转)。

Android 中的动画有哪几类:帧动画、补间动画、属性动画

八丶为什么要用Handler机制去更新UI呢

我们经常会在子线程去处理大量运算、网络请求、图片压缩等操作。当我们操作完,要通知主线程操作结果,可以进行下一步行动了。这时候又有一个问题,如果几个线程同时去通知主线程呢,那么必然会有并发问题,我们怎么避免这个问题又不会影响性能呢?(加同步锁会影响性能)

Google还是了解开发者意愿的,搬出来了Handler机制,内部有Looper MessageQueue两个重要角色,光看名字我们就知道这是一个消息队列,通过队列方式去对UI进行更新。很好解决了多个子线程的并发问题,还不影响性能。

handler机制
Binder通信机制
线程池是如何管理线程状态的
热修复原理
手写快速排序算法。

大厂比较看重思路与抽象的解决方案

顺手留下GitHub链接,需要获取相关面试等内容的可以自己去找
https://github.com/xiangjiana/Android-MS

PDF获取
上一篇下一篇

猜你喜欢

热点阅读