面试篇一:Java基础

  • String、StringBuffer、StringBuilder
String类是用的  final char[]  保存的字符串,故String对象是不可变的,用+拼接字符串,就是生成的一个新的String对象。
  String s1 = "abc"; 是放在字符串常量池中,如再创建一个String s2 = "abc";s1和s2都是abc,这时s1,s2指向的是同一个内存地址。
  String s3 = new String("abc"); 是在堆中创建一个对象,同时也会在字符串常量池中创建一个abc。
  String s4 = new String("abc"); 仍然会在堆中创建一个新的对象。
上述s1,s2,s3,s4都为abc,字符串常量池中只会存在一个abc,但堆中会存在两个地址分别存放abc。
  String s = "ab"; 
  String s5 = s + "c"; s5在堆中,s是一个变量,故s5实际上是先创建一个StringBuffer对象,通过append拼接后,再转换成String类型赋值给s5。
  String s6 = "ab" + "c";  s6在字符串常量池中
StringBuffer/StringBuilder是调用父类(AbstractStringBuilder)构造方法创建的,用的char[]保存字符串,是可变对象,可用append、insert方法拼接字符串。
在构造过程中,会先按默认大小申请一个字符数组,当超过默认大小后,会创建一个更大的数组,并且将原来的数组复制到新的数组,丢弃旧的数组。
StringBuilder是线程不安全的,
StringBuffer的底层有synchronize,是线程安全的。
 
怎么选择?
操作少量数据,使用String
单线程下操作大量数据,使用StringBuilder
多线程下操作数据,使用StringBuffer
  • 自动装箱和自动拆箱
装箱:将基本类型用引用类型包装起来。
  Integer i = 1;  自动装箱,实际上是调用的  Integer.valueOf(1); 
拆箱:将包装类型转换为基本类型。
  int ii = i;   自动拆箱,实际上是调用  i.intValue(); 
  • 重写@Override和重载Overload
重写:在父子类中,子类重写父类的方法。
   子父类中的方法名和参数列表一样。
   子类返回范围和抛出的异常不能大于父类的范围。
重载:发生在一个类中,方法名必须相同,参数类型、个数、顺序不同,方法返回值和修饰符不作要求。
  • 多态
多态就是同一个行为具有多个不同表现形式或形态的能力。
实现方式是同一个接口有不同的实现类,或者继承同一父类的各子类有不同的实现方式,各子类对象的引用指向父类或接口。
  • 接口和抽象类
接口:用interface修饰,方法默认是public的,方法不能有具体实现。接口中的实例变量默认是final的。一个类可以实现多个接口。实现一个接口,必须实现接口中的所有方法不能new,只能声明。
抽象类:用abstract修饰,抽象类可以有抽象方法和非抽象方法,一个类只能继承一个抽象类,可以new。
  • 异常
Throwable类有两个子类,Exception
Exception是程序本身可以处理的异常。如RuntimeException、NullPointException、
Error是程序无法处理的异常,表示运行过程中出现了严重的异常,如内存不够,报OutOfMemoryError。
 
异常分类:
逻辑异常:如检查不通过等的无法按照业务预期进行下去的异常,是用户造成的。
代码错误:程序bug造成的。
专有异常:出现意外情况,程序无法处理。
 
怎么处理异常?
使用try-catch-finally进行处理
把异常抛给上层框架统一处理
大多数时候,我们在业务处理时,如果发现无法处理直接抛出异常即可。
如果需要try-catch异常,看情况记录日志信息。
  • 反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性。
  • 泛型

Java泛型就是把类型明确的工作推迟到创建对象或调用方法的时候才去明确的特殊的类型。

写法:

(1)泛型类:把泛型定义在类上,在用户使用该类时,显式地明确是什么类型。

public class Redis<T> {

    private T obj;

    public T getObj() {
        return obj;
    }

    public void setObj(T obj) {
        this.obj = obj;
    }
}

(2)泛型方法:

    public <T> void method(T t) {
        System.out.println(t);
    }

怎么做?把类型当作是参数一样传递,<数据类型> 只能是引用类型。

为什么不用Object?获取的对象需强制转换,强制类型可错了,运行时才会报异常。

  泛型不需要强制转换,运行时不会出现ClassCastException异常,我们在固定场景使用时就明确了具体类型。

  • 代码更加简洁【不用强制转换】
  • 程序更加健壮【只要编译时期没有警告,那么运行时期就不会出现ClassCastException异常】
  • 可读性和稳定性【在编写集合的时候,就限定了类型】
  • 集合

(1)Java集合:List、Set、Map,参考https://www.cnblogs.com/scorpio-cat/p/12719137.html。

(2)HashMap、ConcurrentHashMap数据结构、底层原理、源码分析,参考https://www.cnblogs.com/scorpio-cat/p/12680487.html。

猜你喜欢

转载自www.cnblogs.com/scorpio-cat/p/12818498.html
今日推荐