Java基本类型(8种)
byte (8位)
short (16位)
int (32位)
long (64位)
float (32位)
double (64位)
char (16位)
boolean (8位)
final关键字的几种用法

修饰的类不能被继承

final类中的成员变量可以根据需要设为final

final类中的所有成员方法都会被隐式地指定为final方法

禁止该方法在子类中被覆盖

注:类的private方法会被隐式地指定为final方法

如果是基础类型的变量,一旦初始化后其值便不能更改

如果是引用类型的变量,对其初始化后并不能再让其指向另一个对象

注:当用final修饰类的成员变量时,必须在定义时或者构造器中进行初始化赋值;当用final修饰局部变量时,只需要保证在使用之前被初始化赋值即可。

为什么Java内部类要设计成静态和非静态两种?
java 内部类和静态内部类的区别
String为什么要设计成final
  1. 安全:

    String经常被用于HashMap或HashSet的键值,如果String可变,可能破坏HashSet键值的唯一性,所以千万不要用可变类型做HashMap和HashSet键值。

    在并发场景下,多个线程同时读一个资源,不可变对象不能被写,所以是线程安全的。

  2. 性能:支持字符串常量池数据共享,节省资源,提高效率(因为如果已经存在这个常量便不会再创建,直接拿来用)

注:类似的,Long, Double, Integer之类的全都是final的。

HashMap原理?为什么每次扩容都是扩大一倍为什么不是三倍四倍?

HashMap原理,注意不是取模运算,而是与运算(效率高),这也是扩容2倍的原因!

    /**
     * 返回数组下标
     */
    static int indexFor(int h, int length) {
        return h & (length-1);
    }

什么时候扩容: 当向容器添加元素的时候,会判断当前容器的元素个数,如果大于等于阈值—即当前数组的长度乘以加载因子的值的时候,就要自动扩容啦。

加载因子的参数,如果加载因子为0.75 ,如果你hashmap的 空间有 100 那么 当你插入了75个元素的时候 hashmap就需要扩容了,不然的话 会形成很长散列桶 , 对于查询和插入都会增加时间,因为 他要一个一个的equals。
但是你又不能让加载因子很小,0.01 这样是不合适的,因为 他会大大消耗你的 内存, 你一加入一个对象hashmap就扩容。 这时就存在着一个平衡,,jdk中默认是0.75 可以根据自己的实际情况进行调整

扩容(resize) 就是重新计算容量,向HashMap对象里不停的添加元素,而HashMap对象内部的数组无法装载更多的元素时,对象就需要扩大数组的长度,以便能装入更多的元素。当然Java里的数组是无法自动扩容的,方法是使用一个新的数组代替已有的容量小的数组,就像我们用一个小桶装水,如果想装更多的水,就得换大水桶。

扩容2倍原因

反射中Class.forName()和ClassLoader.loadClass()的区别

Java中Class.forName和classloader都可以用来对类进行加载。Class.forName除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。而classloader只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。Class.forName(name,initialize,loader)带参数也可控制是否加载static块。并且只有调用了newInstance()方法采用调用构造函数,创建类的对象。

java中的静态变量、静态方法与静态代码块详解与初始化顺序

静态变量 先于 静态代码块 初始化

Java 反射 使用总结
Java集合体系总结—Map、Set、List、Queue
描述一下ArrayList和LinkedList各自实现和区别

ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

Java中的队列都有哪些,有什么区别

阻塞队列与普通队列。区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来,如从队列中移除一个或者多个元素,或者完全清空队列.

详细信息

普通队列(非阻塞队列):LinkedList、PriorityQueue 和 ConcurrentLinkedQueue
阻塞队列:java.util.concurrent 中加入了 BlockingQueue 接口和五个阻塞队列类。它实质上就是一种带有一点扭曲的 FIFO 数据结构。不是立即从队列中添加或者删除元素,线程执行操作阻塞,直到有空间或者元素可用。

java5、java6、java7、java8的新特性
Java7语法新特性
JAVA8 十大新特性详解
Java 8 新特性
数组与链表
Java内存泄露的问题调查定位:jmap,jstack的使用等等

jmap (linux下特有,也是很常用的一个命令)
观察运行中的jvm物理内存的占用情况。
参数如下: -heap :打印jvm heap的情况
-histo: 打印jvm heap的直方图。其输出信息包括类名,对象数量,对象占用大小。
-histo:live : 同上,但是只答应存活对象的情况
-permstat: 打印permanent generation heap情况

jmap -heap 2083
可以观察到New Generation(Eden Space,From Space,To Space),tenured generation,Perm Generation的内存使用情况

输出内容:
jmap -histo 2083 | jmap -histo:live 2083

可以观察heap中所有对象的情况(heap中所有生存的对象的情况)。包括对象数量和所占空间大小。

写个脚本,可以很快把占用heap最大的对象找出来,对付内存泄漏特别有效。

jstack用法
Java中的String,StringBuilder,StringBuffer三者的区别

String,StringBuffer和StringBuilder对比

注:String是线程安全的,图中错误。

HashTable和HashMap的区别详解
Java 异常机制,异常的结构,运行时异常和非运行时异常

RunntimeException的子类:

多态中,可以使用Instanceof 判断,进行规避

进行if判断,如果除数为0,进行return

进行if判断,是否为null

使用数组length属性,避免越界

非运行时异常:

非运行时异常是RuntimeException以外的异常,类型上都属于Exception类及其子类。如IOException、SQLException等以及用户自定义的Exception异常。对于这种异常,JAVA编译器强制要求我们必需对出现的这些异常进行catch并处理,否则程序就不能编译通过。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆catch块去处理可能的异常。

String a= “abc” String b = “abc” String c = new String(“abc”) String d = “ab” + “c” .他们之间用 == 比较的结果
public class TestString {
    public static void main(String[] args) {
        String a = "abc";
        String b = "abc";
        String c = new String("abc");
        String d = "ab" + "c";

        System.out.println(a == b); // true
        System.out.println(a == c); // false
        System.out.println(a == d); // true
        System.out.println(c == d); // false
    }
}
String 类的常用方法
Java 的引用类型有哪几种

Java中的四种引用类型 Strong, Soft, Weak And Phantom
JAVA的四种引用类型
Java中四种引用类型详细介绍

接口和抽象类有什么区别
Hashtable,HashMap,ConcurrentHashMap 底层实现原理与线程安全问题(建议熟悉 jdk 源码,才能从容应答)

Hashtable,HashMap,ConcurrentHashMap 底层实现原理与线程安全问题

如果不让你用Java Jdk提供的工具,你自己实现一个Map,你怎么做。说了好久,说了HashMap源代码,如果我做,就会借鉴HashMap的原理,说了一通HashMap实现
Hash冲突怎么办?哪些解决散列冲突的方法?

java 解决Hash(散列)冲突的四种方法–开放定址法(线性探测,二次探测,伪随机探测)、链地址法、再哈希、建立公共溢出区

  1. 开放定址法(线性探测再散列,二次探测再散列,伪随机探测再散列)
  2. 再哈希法(当发生冲突时,使用第二个、第三个、哈希函数计算地址,直到无冲突时。缺点:计算时间增加。)
  3. 链地址法(Java hashmap就是这么做的)
  4. 建立一个公共溢出区(假设哈希函数的值域为[0,m-1],则设向量HashTable[0..m-1]为基本表,另外设立存储空间向量OverTable[0..v]用以存储发生冲突的记录。)
HashMap冲突很厉害,最差性能,你会怎么解决? 从O(n)提升到log(n)咯,用二叉排序树的思路说了一通???
  1. 修改hashCode计算方式
  2. 链表排序(初始化使用快排),新加节点使用插入排序,在查找插入删除过程中,可以使用二分查找
  3. 链表改为红黑树结构(自平衡二叉查找树)
HashMap rehash

当hash表中的负载因子达到负载极限的时候,hash表会自动成倍的增加容量(桶的数量),并将原有的对象重新的分配并加入新的桶内,这称为rehash,这个过程是十分好性能的。

扩容2倍,只需要比较扩容对应的最高位,最高位为0,保持不变,最高位为1,分配到对应的新的位置。

    /**
     * 返回数组下标
     */
    static int indexFor(int h, int length) {
        return h & (length-1);
    }
hashCode() 与 equals() 生成算法、方法怎么重写

equals和HashCode深入理解以及Hash算法原理

java什么叫线程安全?什么叫不安全?
ConcurrentHashMap原理分析
线程安全的CopyOnWriteArrayList介绍
JDK8新特性:接口的静态方法和默认方法