面试题链接:
https://blog.csdn.net/huangqili1314/article/details/79448187
Java相关:
https://www.cnblogs.com/java1024/p/7685400.html
Java << >>(前面两个是带符号移动,最高位为0,为正数,1为负数) >>>(不带符号右移)
https://www.douban.com/group/topic/123219502/
字符串相关:
String s1 = "HelloWorld"; // 常量池
String s2 = "HelloWorld";// 常量池 s1== s2
String s3 = new String("HelloWorld");//在堆上分配对象,s1 != s3, s1.equals(s3) == true
String s4 = "Hello";
String s5 = "World";
String s8 = "Hello" + "World";// 编译器确定,等同于String s8 ="helloworld"
String s6 = "Hello" + s1; //相当于stringBuilder append
String s7 = s3 + s4;//相当于stringBuilder append
https://blog.csdn.net/HaydenYu/article/details/74061674
Java中&&和&的区别
Java中&&和&都是表示与的逻辑运算符,都表示逻辑运输符and,当两边的表达式都为true的时候,整个运算结果才为true,否则为false。
&&的短路功能,当第一个表达式的值为false的时候,则不再计算第二个表达式;&则两个表达式都执行。
&可以用作位运算符,当&两边的表达式不是Boolean类型的时候,&表示按位操作。
Java 面向对象的三大特征:
继承,封装,多态(体现在方法重载和继承关系中的重写,接口的不同实现)
Java多态总结
面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。这是我们最后一个概念,也是最重要的知识点。
1.定义:
多态:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
2.实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
3.作用:消除类型之间的耦合关系。
4.现实中,关于多态的例子不胜枚举。比方说按下 F1 键这个动作,如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;如果当前在 Word 下弹出的就是Word 帮助;在 Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。
5.下面是多态存在的三个必要条件,要求大家做梦时都能背出来!
多态存在的三个必要条件
一、要有继承;
二、要有重写;
三、父类引用指向子类对象。
6.多态的好处:
1)可替换性(substitutability):多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
2)可扩充性(extensibility):多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。
3)接口性(interface-ability):多 态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3 所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和 Sphere为了实现多态,完善或者覆盖这两个接口方法。
4)灵活性(flexibility):它在应用中体现了灵活多样的操作,提高了使用效率。
5)简化性(simplicity):多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。
7.Java中多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载。
1 Java 中访问权限
private 本类内部访问
public 所有类都可以访问
protected 可被本类,子类,同包类 访问
default 可被本类,同包类访问
2 private void test(final int a){ // 这个final的作用
new Thread(){
public void run(){
}
}.start()
}
Java 方法参数传递相关:
1 基本类型作为参数传递时,是传递值的拷贝,无论你怎么改变这个拷贝,原值是不会改变的
2 如果传递引用类型,则相当于拷贝一份引用指向同一个内存地址
3 如果方法中的内部类使用了传递的参数,那么这个参数需要使用final, 为什么呢?
内部类在编译为class文件后,会在内部类的构造方法中,创建一个新参数,指向外部类传递的参数,
如果内部类在执行时,外部类改变了这个参数的引用,则外部类和内部类指向了不同的地址,这在java中是不允许的。
简单理解就是,拷贝引用,为了避免引用值发生改变,例如被外部类的方法修改等,而导致内部类得到的值不一致,于是用final来让该引用不可改变。
故如果定义了一个匿名内部类,并且希望它使用一个其外部定义的参数,那么编译器会要求该参数引用是final的。
https://www.cnblogs.com/xiaorenwu702/p/5167997.html
https://www.cnblogs.com/hpyg/p/8005599.html
3 synchonized 和 static synchonized 的区分
https://blog.csdn.net/cs408/article/details/48930803
4 concurrenthashmap
5 ClassLoader 双亲委派
https://www.cnblogs.com/z00377750/p/9175549.html
https://blog.csdn.net/xiongyouqiang/article/details/79151903
https://www.cnblogs.com/doit8791/p/5820037.html
6 java类初始化
https://www.ibm.com/developerworks/cn/java/j-lo-clobj-init/
https://blog.csdn.net/yuxin6866/article/details/53107578
类初始化,先初始化父类,再初始化当前类, 初始化,
1. 父类中静态成员变量和静态代码块
2. 子类中静态成员变量和静态代码块
3. 父类中普通成员变量和代码块,父类的构造函数
4. 子类中普通成员变量和代码块,子类的构造函数
实例化:如果类没有初始化,先初始化类,然后初始化实例变量,实例代码快,然后构造函数中的初始化
public class Test{
int a = 10;
{
int b = 11;
}
int c = 12;
public Test(){
// 默认调用super()初始化
int d = 13;
}
}
初始化过程:1: a=10; 2: c = 12; 3: b = 11; 4: d = 13
如果通过SuperClass.staticVariable ,子类不会初始化
如果通过ChildClass.staticVariable ,先初始化SuperClass,再初始化ChildClass
Volatile原理:
1 可见性 ,
首先被volatile关键字修饰的共享变量在转换成汇编语言时,会加上一个以lock为前缀的指令,当CPU发现这个指令时,立即做两件事:
1.1将当前内核高速缓存行的数据立刻回写到内存;
1.2.使在其他内核里缓存了该内存地址的数据无效。
2 内存屏障 防止指令重排序:
https://www.cnblogs.com/xrq730/p/7048693.html
CAS 原理:指令级控制
CAS算法
CAS(Compare-And-Swap)算法保证数据操作的原子性。
CAS 算法是硬件对于并发操作共享数据的支持。
CAS 包含了三个操作数:
内存值 V
预估值 A
更新值 B
当且仅当 V == A 时,V 将被赋值为 B,否则循环着不断进行判断 V 与 A 是否相等。
底层通过cpu指令实现数据更新,更底层通过执行LOCK前缀指令实现总线上的互斥,保证同时只有一个cpu访问内存
https://blog.csdn.net/jek123456/article/details/73087431
https://www.jianshu.com/p/bd68ddf91240
Synchonized && ReetrantLock
https://www.jianshu.com/p/96c89e6e7e90
java 线程状态:
创建,就绪 (调用start),运行(获取到时间片),阻塞(没获取到锁),等待 (调用wait),销毁(线程执行完毕或者被中断)
https://www.cnblogs.com/trust-freedom/p/6606594.html
BlockingQueue:
https://blog.csdn.net/qq_42135428/article/details/80285737
ArrayMap: && SparseArray
https://www.jianshu.com/p/1a14fc87b935
Android 相关:
1 主线程Handler为什么阻塞,为什么不会anr
Looper 的loop() 内部是一个死循环,如果没有消息,当前线程会阻塞,休眠,知道有新的消息换起。
https://www.jianshu.com/p/7bc2b86c4d89
handler.postDelay()的消息一定会执行吗?、
判断消息是否执行是通过
final long now = SystemClock.uptimeMillis(); //手机休眠之后,SystemClock.uptimeMillis()不再更新
// do something if (msg != null) {
if (now < msg.when)
{ // Next message is not ready. Set a timeout to wake up when it is ready.
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE); } else { // Got a message. mBlocked = false; if (prevMsg != null) { prevMsg.next = msg.next; } else { mMessages = msg.next; } msg.next = null; if (DEBUG) Log.v(TAG, "Returning message: " + msg); msg.markInUse(); return msg; } }
https://www.jianshu.com/p/17d6f991a10a
2 Surfaceview 和 普通View的区别
https://www.jianshu.com/p/b037249e6d31
3 AsyncTask 原理
默认内部串行执行所有的任务,线程池是进程级的
4 android 新版本特性
https://blog.csdn.net/s13383754499/article/details/82736912
5 requestlayout 和 invalidate
requestlayout: 从当前view 开始 向顶层调用,设置自己的flag 为 PFLAG_LAYOUT_REQUIRED 和PFLAG_LAYOUT_REQUIRED,
一直到ViewRootImpl,然后执行Measure 和 Layout , 如果坐标发生变化,则调用draw,
measure的核心代码处必须满足3个条件之一,而他自己与他的父族view都会被设置为PFLAG_FORCE_LAYOUT,所以他们都必然会被重新measure,但是其他的view就不一定了,就看这3个条件是否会满足。
PFLAG_FORCE_LAYOUT: 决定了当前view或者viewGroup是否需要measure
protect void measure:
if ((mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ||
widthMeasureSpec != mOldWidthMeasureSpec ||
heightMeasureSpec != mOldHeightMeasureSpec) { // 大小变化或者设置了PFLAG_FORCE_LAYOUT
//....measure核心代码
}
mPrivateFlags |= PFLAG_LAYOUT_REQUIRED;//这个PFLAG_LAYOUT_REQUIRED决定了是否执行onlayout
}
}
在measure是,如果当前View 宽,靠发生变化,或者设置了PFLAG_LAYOUT_REQUIRED,才会调用onmearsure
public void layout(int l, int t, int r, int b) {
...
//判断标记位是否为PFLAG_LAYOUT_REQUIRED,如果有,则对该View进行布局
if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
onLayout(changed, l, t, r, b);
//onLayout方法完成后,清除PFLAG_LAYOUT_REQUIRED标记位
mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED;
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnLayoutChangeListeners != null) {
ArrayList<OnLayoutChangeListener> listenersCopy =
(ArrayList<OnLayoutChangeListener>)li.mOnLayoutChangeListeners.clone();
int numListeners = listenersCopy.size();
for (int i = 0; i < numListeners; ++i) {
listenersCopy.get(i).onLayoutChange(this, l, t, r, b, oldL, oldT, oldR, oldB);
}
}
}
//最后清除PFLAG_FORCE_LAYOUT标记位
mPrivateFlags &= ~PFLAG_FORCE_LAYOUT;
mPrivateFlags3 |= PFLAG3_IS_LAID_OUT;
}
invalidate: 从当前view向上调用invalidateChildInParent 一直到ViewRootImpl,因为没有设置PFLAG_LAYOUT_REQUIRED,所以不会调用onmeasure,onlayout
https://blog.csdn.net/litefish/article/details/52859300
6 Parcelable 和 Seriable 源码区别
https://segmentfault.com/a/1190000012522154
https://www.cnblogs.com/woshimrf/p/java-serialize.html
binder为什么要设置传输数据大小?
binder是为了通讯用的,不是为了传输大量数据,如果有大量数据,可以多次通讯来完成,默认大小限制1M
https://blog.csdn.net/happylishang/article/details/62234127
7 如何加载大图片,判断Bitmap大小
先只加载图片边界,这是bitmap没有分配内存, 计算宽高
bitmap大小计算: width * height * 每个像素字节
ARGB8888:分别用8个bit来记录每个像素的A、R、G、B数据,就是常说的32bit位图、256色位图(这个也可能是RGB888这种24bit位图) 一个像素点占4Byte
RGB565:分别用5个、6个和5个bit记录像素的R、G、B数据,其中G的6个bit中一个是无效保留的,32色位图 一个像素点占2Byte
ARGB4444:分别用4个bit来记录每个像素的A、R、G、B数据,16色位图 一个像素点占2Byte
https://www.jianshu.com/p/0f56f35068e2
网络相关:
1 http1 和 http2区别
http1 所有的请求都是串行的,传输的文本 ,比如hello world ,如果并行传输,不能保证数据的顺序,所以只能串行
http2 所有的请求并行,采用的二进制流的形式,将传输数据分为很多帧,每个帧带着数据,以及当前数据的client 请求id,以及在原始数据中的序号,服务端就可以针对每个请求的id,以及每一帧的序号 ,重新组合数据,从而达到并行
为了减少不必要的带宽,http2 将请求头通过gzip压缩,服务端解压缩获取请求头
HTTP 协议是没有状态,导致每次请求都必须附上所有信息。所以,请求的很多头字段都是重复的,比如 Cookie,一样的内容每次请求都必须附带,这会浪费很多带宽,也影响速度。对于相同的头部,不必再通过请求发送,只需发送一次;HTTP/2 对这一点做了优化,引入了头信息压缩机制;一方面,头信息使用 gzip 或 compress 压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,产生一个索引号,之后就不发送同样字段了,只需发送索引号
https://blog.csdn.net/qq_28709925/article/details/79880766
http://baijiahao.baidu.com/s?id=1603681423752117045&wfr=spider&for=pc
2 网络层模型
https://blog.csdn.net/qq_33624952/article/details/79212500
3 tcp三次握手和四次挥手
https://www.cnblogs.com/Andya/p/7272462.html
4 https ssl tsl 了解
https://www.cnblogs.com/digdeep/p/4832885.html
5 网络连接超时设置:
connectTimeout // 建立连接超时
readTimeout // 客户端等待从服务端读取数据超时
writeTimeout // 客户端向服务端写数据超时