Android问题总结(1)

1.int和Integer的区别
https://blog.csdn.net/q5706503/article/details/83386365
总结:integer是包装类,而int是基本类型。
int–>编译器会自动装箱成integer类型。

Interger i = new Interger(1)-->堆中产生。
Interger j = 1 --->栈中指向

所以这两者不相等。

Interger i = 1
Interger j = 1
i == j -->true
i = 128
j = 128
i == j -->false

因为-128----127之外的数,实际上是new得到的。所在地址不同。 更深的理解请去理解JVM中的堆和栈,原理是因为这个,指向地址不同。

2.JVM的堆,栈,方法区,垃圾回收机制

栈:

每个线程都有自己的栈内存,每个方法运行也是在自己的栈内存里面,局部变量也是,私有。int i =1;理解,是看栈里面有没有某个内存地址有值为1的,如果有则赋予这个地址给它。没有则给某个地址值为1然后再将这个地址赋值给它。

堆:

(C:需要被申请内存才有的地址空间)提供所有实例和数组对象存储区域,被所有线程共享,只存放对象本身。

方法区:

跟堆一样,被所有线程共享,包含所有class和static.

垃圾回收

垃圾回收机制,最主要回收的是堆里面的内容。
根据某些算法标记然后清除掉部分内存。
(暂且理解到这里。)

3.HashMap,LinkedHasMap,HashTable
HashMap
HashMap—>有点类似于字典啦
原理:把关键字通过某个函数映射到实际存储地址,通过下表一次定位即可,这个函数称为Hash函数。
HashMap由数组+链表组成,Entry作为单元分散在一个数组当中,Entry.next是链表型的使用.当查找时,如果key经过hash计算后得到相同位置,则要遍历整个链表。找到对应的key。
初始长度为16.扩展要为2的幂.扩容时,是要将原本所有的Entry重新Hash到新的数组内,(JDK1.8后就增加的红黑树,解决性能,提高搜索效率,插入,删除等操作)
但扩容时会出现问题,因为是非线程安全的,当线程A,B都在线程进行扩容时,线程B进行到一半,被挂起,而线程A在无阻碍的情况下进行Rehash,会出现无限回环的情况。
(原因是次序翻转,)
HashMap高并发
HashMap过程
HashMap和Hashtable的区别:
HashMap 几乎等价Hashtable,但HashMap是非
synchronized的,而Hashtable是synchronized,是线程安全的。但HashTable单线程的环境下比HashMap慢一点。
HashMap和LinkHashMap的区别:
LinkHashMap是HashMap的一个子类,保存了记录的插入顺序,即,插入时顺序如何,取出时,也是顺序排序出来的。
4.ArrayList和LinkedList对比
https://blog.csdn.net/GBStyle/article/details/81538373
ArrayList和LinkedList都继承了List的类,所以都算是实现了List接口,两者区别就是具体实现方式不同。
ArrayList实现是用可变数组实现,LinkedList使用双向链表实现。
ArrayList增加是移动数据往后一格和扩容去实现的,但查询询址是比较容易的。
LinkedList增加则是指针增加的,但查询是要移动指针的。
ArrayLish适合频繁查找和修改,linkedList则适合需要频繁增删的环境。

5.okhhtp源码理解
流程:
https://blog.csdn.net/zxw136511485/article/details/52872724
https://blog.csdn.net/json_it/article/details/78404010
https://blog.csdn.net/u010302765/article/details/102286157
初始化Builder—>Builder.build创建构造对象okhttp.client----->创建对象构造请求request---->client建立Call对象,传入request,实现方法,enqueue(异步),execute(同步)。
Call不能被执行两次
execute方法用分发器把Call加入双端队列,获得response对象后,再讲双端队列移除本次Call。而获得对象getResponseWithInterceptorChain()方法,内部是各类拦截器组成一套拦截器链。
enqueue()方法,一样去检查是否被执行过,然后用分发器的enqueue(new AsyncCall(responseCallback))方法,而里面的AsyncCall实际上就是一个Runnable.复写了execute,execute里面有又有熟悉的getResponseWithInterceptorChain()方法,且最后有dispatcher.finished方法,里面会删除已经执行的异步请求,接着再调用promoteCalls().
而再看Dispatcher里面的enqueue方法,就是把这个Runnable放入线程池里面等待执行。

6.MVP,MVC理解异同。
https://blog.csdn.net/u011315960/article/details/82869206
https://blog.csdn.net/chunqiuwei/article/details/80460108
https://blog.csdn.net/lmj623565791/article/details/46596109
MVC:模型层(Model)+视图层(View)+控制层(Controller)
View层:Layout,xml文件。
Module层:数据处理层,请求数据等。
Controller:把特定功能逻辑抽离,作为控制层。对应Activity–Module和View是在交互的。
交互:直接暴力的使用方法
V与M会直接交互,V包含M的信息
MVP:模型层(Model)+视图层(View)+逻辑层(Presenter)
Model:数据处理层,主要负责网络请求,本地数据加载操
作,进一步简化Activity的代码。
Presenter:逻辑层,从Activity中抽离出功能逻辑,简化Activity的代码。
View:视图层,作为Activity.
交互:用接口的多
Android中,只让View单纯负责UI显示,把功能逻辑抽离变成Presenter层,数据相关提取成Model层,并且View和Model通过Presenter解耦,这样可以简化代码。
异:层之间的交互关系不同,职责不同,View层不同,
实现:
M层:定义接口,一个实现类实现接口。
V层:定义接口,Activity类实现接口。
P层:构造函数拿到M层和V层的实现类,在自定义方法中用M层的方法,然后在回调接口中用V层的方法。
个人理解

7.Handler消息机制的理解。
(1)能不能在ui线程创建。
(2)LOOP为何没有阻塞线程。
8.弱引用,各种引用
https://blog.csdn.net/qq_39037047/article/details/80532908
9.如何保证Servie不被杀死,保证进程不被杀死
(1)优先级。
提高优先级,互相唤醒,native保活

10.红黑树
https://zhuanlan.zhihu.com/p/139907457
11.volatile和synchronized
volatile:是保证变量线程可见性,即变量在线程之间有关系,加入这个关键词保证能立即更新到主内存去。变量不受线程的影响。但并不能保证其原子性。
synchronized:保证线程互斥的访问同步代码。对象锁,类锁。
设计模式:
3.工厂模式
https://www.jianshu.com/p/13 f80d27b7f2
(1)普通工厂模式
定义一个抽象类。
定义具体类去继承这个抽象类。
定义工厂类(抽象)

public abstract class Factory {
    public abstract <T extends NokiaPhone> T createNokia(Class<T> clz);
    //抽象的这个类,实现的方法是返回一个class extends NokiaPhone的。 且传入参数为一个类
}

定义具体某一个工厂继承这个工厂类

public class NokiaFactory extends Factory {
    @Override
    public <T extends NokiaPhone> T createNokia(Class<T> clz) {
        NokiaPhone nokiaPhone = null;
        try {
        //通过反射得到传入参数的整个类
            nokiaPhone = (NokiaPhone) Class.forName(clz.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        } 
        return (T) nokiaPhone;
    }
}

此时
NokiaFactory nokiaFactory = new NokiaFactory();
Nokia5200 nokia5200 = nokiaFactory.createNokia(Nokia5200.class);
NokiaN97 nokiaN97 = nokiaFactory.createNokia(NokiaN97.class);
这样就产生了两个类。再通过类就可以使用其中的方法
(2)抽象工厂模式
定义一个接口,里面又接口方法
定义产品类,继承这个接口
抽象定义出工厂类的方法

public abstract class Factory {
	//这个工厂抽象出来的是返回上面定义的接口
    public abstract component.CPU createCPU();
    public abstract component.Battery createBattery();
}

具体工厂的实现

public class IPhone6Factory extends Factory {
    @Override
    public component.CPU createCPU() {
        return new A9();
    }

    @Override
    public component.Battery createBattery() {
        return new Battery1000ma();
    }
}

public class Iphone7Factory extends Factory {
    @Override
    public component.CPU createCPU() {
        return new A10();
    }

    @Override
    public component.Battery createBattery() {
        return new Battery1200ma();
    }
}

创建的产品相同,但是抽象产品是同接口的不同子类实例。
4.生产者,消费者模式

pass
https://blog.csdn.net/a394268045/article/details/82979944?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-2
Handler也是这个模式操作的。
5.单例模式(类锁和对象锁)

双检锁:
第一次判空,看实例是否为空,如果不为空则返回,为空了线程才开始等待。
线程A/B都进入到synchonized.在第二层某个线程执行后,释放了锁,其它线程又进入了synchonized块
如果不判断则由又会被创建一次,所以这么写。

	private volatile static OkHttpUtil okHttpUtil;
   public static OkHttpUtil getInstance(Context context){
        if (okHttpUtil == null){
            synchronized (OkHttpUtil.class){//锁住整个类
                if (okHttpUtil == null){
                    okHttpUtil = new OkHttpUtil(context);
                }
            }
        }
        return okHttpUtil;
    }

6.观察者模式(EventBus?)
https://zhuanlan.zhihu.com/p/158537313
观察者,抽象出一个观察者接口,所有需要接收事件并做出相应的类,都实现这个接口
被观察者:抽象类,拥有观察者列表,可注册和删除。
当事件发生时,会通知列表中所有的观察者。
具体类去继承被观察类,当被观察类做出动作后,可对观察者类发送通知。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值