Android 一天一题

1、类的加载过程,Person person = new Person();为例进行说明

  1. 因为new用到了Person.class,所以会先找到Person.class,并加载到内存中
  2. 执行类中的static代码块,如果有的话给Person.class 进行初始化
  3. 在堆内存中开辟空间分配内存地址
  4. 在堆内存中建立对象的特有属性,并进行默认初始化
  5. 对属性进行显示初始化
  6. 对对象进行构造代码块初始化
  7. 对对象进行与之相对应的构造函数进行初始化
  8. 将内存地址赋给栈内存的p变量

2.集合框架,list,map,set都有哪些具体的实现类,区别都是什么

  1. list是有序存储,可放入重复的元素
  2. set是无序存储(是按照元素的Hashcode进行排序),不可放入重复的元素
  3. 在增删查三个方面,list查询比较快(list是数组结构)set删除和插入比较快
  4. Map适合储存键值对数据

3.ArrayList 和 Hashmap 简单说一些,区别,底层的数据结构

  1. ArrayList是基于动态数组的数据结构,数据地址是连续,数据的查询比较快,但是数据的插入,删除(除了最后一个数据)效率比较低
  2. Hashmap是基于哈希表实现的,使用的是动态数组加链表结构,先根据key值的hashCode值,确定数组的位置 然后在放在链表中。负载因子的作用是确定什么时候扩容,Hashmap默认数组长度16 负载因子默认0.75

4.Handler 消息机制

按照代码的习惯说一下流程
1. handler通过sendMessage()方法或者其他的setXXX()方法调用handler中的enqueueMessage()方法向MessageQueue插入一条消息同时会把本事的handler通过msg.target = this传入
2. Looper 是一个死循环,不断的读取MessageQueue中的消息,Looper会调用MessageQueue的next方法获取新消息,next是一个阻塞操作,当没有消息时next方法一直阻塞,导致Looper也一直阻塞
3. 当有消息时会回调handler的dispatchMessage()方法

5. 引起内存泄漏的场景

  1. 资源对象没关闭
  2. bitmap对象不在使用时调用recycle()释放
  3. 构造Adapter时没有使用convertView
  4. 注册没取消造成的内存泄漏(evenBus,service)
  5. 单例造成的内存泄漏
  6. 查找内存泄漏可以使用Android Studio自带的Android Profiler

6. 多线程的使用场景

  1. App中的耗时操作,比如网络请求,文件操作
  2. 为了加快App启动 可以把数据存储操作放在线程中

7.常见线程池

  1. FixThreadPool:只有核心线程,并且数量固定,也不会被回收,所有线程都活动时,新任务会等待执行,优点是响应速度快
  2. SingleThreadPool:只有一个核心线程,确保所有的任务都在同一线程中顺序操作,因此不需要处理线程同步的问题
  3. CachedThreadPool:只有非核心线程,最大数量非常大,所有线程都活动时,会为新任务创建新线程,否则会利用空闲线程(60s空闲线程会被回收,所以线程池中有0个线程的可能)处理任务
  4. ScheduledThreadPool:核心线程数固定,非核心线程(闲这的时候会被回收)数没有数量限制。优点:执行定时任务以及有固定周期重复任务

8. 知道哪些单例模式,写一个线程安全的单例,并分析为什么是线程安全的

  1. 有饿汉模式,懒汉模式,利用私有的内部工厂类,懒汉模式改良版,静态内部类单例模式
  2. public class Singleton{//懒汉模式
    private static Singleton singleton;

    private Singleton(){}
    
    public static synchronized Singleton getInstance(){
    if(singleton == null){
    singleton = new Singleton();
    }
    return singleton;
    
    }}
    

    `

    public class Singleton{//懒汉模式改良版 目的是为了减少同步开销

    private static volatile Singleton instance = null;

    private Singleton(){}

    public static Singleton getInstance(){
    if(instance == null){
    synchronized(Singleton.class){
    if(instance == null){
    instance = new Singleton();
    }
    }
    }
    return instance;
    }
    }
    `

`

public class Singleton{//静态内部类单例模式

private Singleton(){}

public synchronized Singleton getInstance(){
        return SingletonHolder.instance;
}

private static class SingletonHolder{
    private static final Singleton instance = new Singleton();
}

}`

3.线程安全 是因为有同步线程锁 synchronized;

9. 解释一下HashMap?底部的数据结构?散列表冲突的处理方法,散列表是一个什么样的数据结构?HashMap是采用什么方法处理冲突的?

  1. HashMap是由数组和链表组合而成的数据结构,存取时都会根据键值计算出“类别”(HashCode),在根据类别定位到数组中的位置并执行操作
  2. 开放地址法,再哈希法,链地址法,建立一个公共溢出区
  3. 是根据关键码值直接进行访问的数据结构
  4. 链地址法

10. 解释一下什么是MVP架构,画出图解,一句话解释MVP和MVC的区别?

  1. MVP架构是从MVC框架演化而来的 M指model负责业务逻辑和实体模型 V指View 对应于Activity P指presenter 负责View和model之间的交互
  2. MVC允许Model和View交互 而MVP中Model和View的交互必须由Presenter完成

11. 在使用Handler的时候要注意哪些东西,是否会引起内存泄漏?画一下Handler机制的图解?

  1. 在子线程使用Handler时必须先调用Looper.prepare()创建Looper;
  2. 在同一个线程中只能调用一次Looper.prepare()
  3. 不能再主线程中调用Looper.prepare()
  4. 当我们在子线程中使用Handler时,如果Handler不在需要发送和接受消息,那么一定要退出子线程的消息轮询。因为Looper.loop()是一个死循环,如果我们不主动结束他,那么它会一直运行,子线程也会一直运行不会结束。
  5. 会引起内存泄漏,Handler可能会持有外部对象Activity,当Activity关闭时,handler还没执行完,从而引起activity内存泄漏
  6. handler 引起泄漏的解决方法 使用mHandler.removeCallbacksAndMessages(null)及时清除。使用静态内部类和弱引用

12 采取了哪些措施进行性能优化

  1. 布局优化 就是尽量减少布局文件的层级
  2. 使用标签
  3. 自定义View的时候 绘制优化 尽量减少重复绘制
  4. 内存泄漏优化
  5. 响应速度优化 就是避免在主线程中进行耗时操作
  6. ListView BitMap(对图片进行采样)优化
  7. 线程优化 避免程序中存在大量的线程,可以采用线程池
  8. 适当使用弱引用和软引用
  9. 采用三级缓存

13.引起内存泄漏的原因是什么?以及你是怎么解决的

  1. 原因是程序向系统申请分配内存空间后 ,在使用完毕后空间未释放,导致一直占用该内存单元
  2. 回看问题5

14.关于并发理解多少?说几个并发的集合?

15.画图说明View 事件传递机制?并举一个例子阐述

  1. Activity中事件分发体系 Window -> ViewGroup -> View
  2. dispatchTouchEvent() onInterceptTouchEvent() onTouchEvent() 三个方法协助

16.intentService作用是什么

  1. 先说一下service 简单来说,如果用户希望业务出现在后台,而非主界面上,那么Activity肯定没办法满足需求,于是诞生了Service。Service解决了用户可以不在UI界面进行业务操作的问题,如当听音乐时,我们没有必要一直让界面停留在播放界面。在使用Service的时候,一定要注意Service虽然感觉在后台运行,但实际是依附主线程的
  2. 与service的不同 IntentService是线程处理任务的,自带队列,每个请求都会排队,任务完成自己会调用stopSelf结束,无需我们操心
  3. 与其他线程的区别,因为intentService是服务的原因,这导致它的优先级比单纯的线程高很多,所以intentService比较适合执行一些高优先级的后台任务,因为它优先等级高不容易被系统杀死

17.String-StringBuffer-StringBuilder区别

  1. String是字符串常量
  2. StringBuffer是字符串变量(线程安全)
  3. StringBuilder是字符串变量(非线程安全)

18.如何判断Activity是否在运行?

`

final Activity activity = progressDialog.getOwnerActivity();

    if (activity == null || activity.isDestroyed() || activity.isFinishing()) {
        return;
    }

`

19.修改SharedPreferences后两种提交方式有什么区别?

commit这种方式很常用,在比较早的SDK版本中就有了,这种提交修改的方式是同步的,会阻塞调用它的线程,并且这个方法会返回boolean值告知保存是否成功(如果不成功,可以做一些补救措施)。
而apply是异步的提交方式,目前Android Studio也会提示大家使用这种方式。

20.SharedPreferences多进程

http://blog.csdn.net/cjh94520/article/details/70880266

21谈一下你理解的AsyncTask

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值