一、final关键字用法

说明:最终的,不可变的

  1. final修改的:不可被继承
  2. final修饰的方法:不可被重写
  3. final修饰的变量:不可重新赋值
  4. final修饰对象:该对象不能被重新指向
  5. final修饰的成员变量:必须手动初始化,不可采用系统的默认值)
  6. final修饰的实例变量:最好是用static修饰(存储在方法区),因为final修饰的变量本来就不可重新赋值
  7. static final 关键字修饰的变量称为常量

    二、什么不可变类?

  8. 所有基本类型的包装类都是不可变的

  9. String为什么是不可变的?

1)String 类是final关键字修饰的类
2)String 实际是由一个final 修饰的char[]数组存储数据的


三、==、equal有什么区别?

  1. “==” 既可以比较基本类型,也可以比较引用类型。对于基本类型的话比较的是数值,如果是引用类型的话**比较的是内存地址**
  2. “equal” 属于java.lang.Object类里面的方法,如果该方法没有被重写过,那么默认和 “==” 一样
  3. 我们可以看到String类中是重写了equal方法,而且String类日常开发中用的比较多,从而就有了equal是比较值的错误观点
  4. 通常重写equal方法可以用来比较对象中相应的属性是否相等

四、你知道运算符&和&&、|和||的区别吗?

& 按位与操作 (只有对应的两个二进制数为1的时候,结果为才为1)
1 & 1 = 1
1 & 0 = 0
7的2进制是:1 1 1
6的2进制是:1 1 0
结果: 1 1 0
| 按位或操作 (有一个为1时,结果为就为1)
1 | 0 = 1
0 | 1 = 1

&&& 区别
区别:&两边都要运算,而&&先运算左边,如果左边为flase则不再对右边进行运算,判断语句中使用&&效率更高
| || 区别
区别:| 要对两边的条件都进行运算而||只要左边的运算为true,就不在对右边的条件进行运算
注意:&& 和 || 称为短路运算符


五、用最有效率的方法计算2乘以8

答案: 2 << 3 (2 2的3次方)
原理:将第一个数左移n位,相当于乘以2的n次方,位运算是CPU直接支持的,所以效率更高
1.常见的JDK源码里面HashMap的默认容量是16,也是通过位运算计算的
2.ArrayList 在**扩容**的时候也是使用了位运算计算要扩容的大小*


六、传递两个⾮0的int数值进去,实现变量交换的⽅式,有⼏种⽅式?

异或运算 (⼀个数与另⼀个数异或两次是其本身, ⼀个数和⾃身异或结果是0 )

运算规则是:两个数转为二进制,然后从高位开始比较,如果相同则为0,不相同则为1。
比如:8^11 = 3
8转为二进制是1000,11转为二进制是1011.从高位开始比较得到的是:0011.然后二进制转为十进制,就是Integer.parseInt(“0011”,2)=3;

  1. // a=3 b=5
  2. public static void swap(int a, int b){
  3. a = a^b; // a1 = a^b
  4. b = b^a; // b = b^a^b = a
  5. a = a^b; // a = a^b^a = b
  6. System.out.printf("a=%d, b=%d",a,b); // final a=5 b=3
  7. }

七、String、StringBuffffer与StringBuilder的区别?分别在哪些场景下使⽤?

1)三者都是final关键字修饰的, 不允许被继承
2)在本质都是char[]字符数组实现
3)String是不可变对象,StringBuffer与StringBuilder是可变的
4)StringBuilder 效率更快,因为它不需要加锁,线程不安全
5)StringBuffer⾥⾯操作⽅法⽤synchronized ,效率相对更低,是线程安全的
使⽤场景:
1)操作少量的数据⽤String,但是常改变内容且操作数据多情况下最好不要⽤ String ,因为每次⽣成中间对象性能会降低
2)单线程下操作⼤量的字符串⽤StringBuilder,虽然线程不安全但是不影响
3)多线程下操作⼤量的字符串,且需要保证线程安全 则⽤StringBuffer

八、说下Vector和ArrayList、LinkedList联系和区别?分别的使⽤场景

ArrayList:底层是数组实现,线程不安全查询和修改⾮常快,但是增加和删除慢
LinkedList: 底层是双向链表线程不安全,查询和修改速度慢,但是增加和删除速度快
Vector: 底层是数组实现,线程安全的,操作的时候使⽤synchronized进⾏加锁