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和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
观察者,抽象出一个观察者接口,所有需要接收事件并做出相应的类,都实现这个接口
被观察者:抽象类,拥有观察者列表,可注册和删除。
当事件发生时,会通知列表中所有的观察者。
具体类去继承被观察类,当被观察类做出动作后,可对观察者类发送通知。