面试篇(JavaSE):基础部分
对 Java 平台的理解?“Java 是解释执行”,这句话是正确的吗?
Java特性
面向对象(封装,继承,多态)
平台无关性(JVM运行.class文件,编译一次,到处运行)
语言(泛型,Lambda)
类库(集合,并发,网络,IO/NIO)
JRE(Java运行环境,JVM,类库)
JDK(Java开发工具,包括JRE,javac,诊断工具)
垃圾回收
Java 是解释执行?No
Java源代码首先通过javac编译成字节码(.class文件)
运行时,.class文件通过JVM解析或编译运行 解析:通过JVM内嵌的解释器将字节码解释成机器码;编译:JVM提供了JIT(Just In Time Compile 即时编译器)能够在运行时将经常运行的热点代码编译成与本地平台相关的机器码。这种情况下部分热点代码就属于编译执行,而不是解释执行。
AOT编译器: Java 9提供的直接将所有代码编译成机器码执行。
怎样理解面向对象 ?
面向对象是利于语言对现实事物进行抽象。
四大特征:
继承:继承是从已有类得到继承信息创建新类的过程
封装:通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。
多态性:多态性是指允许不同子类型的对象对同一消息作出不同的响应。
抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。
int 和Integer
Integer 是 int 的包装类,int 则是 java 的一种基本数据类型;
Integer 变量必须实例化后才能使用,而 int 变量不需要;
Integer 实际是对象的引用,当 new 一个 Integer 时,实际上是生成一个引用指向此对象;而 int 则是直接存储数据值;
Integer 的默认值是 null,int 的默认值是 0。
== 和 equals
==
如果比较的是基本数据类型,那么比较的是变量的值
如果比较的是引用数据类型,那么比较的是地址值(两个对象是否指向同一块内存)
equals
如果没重写 equals() 方法比较的是两个对象的地址值
如果重写了 equals() 方法后我们往往比较的是对象中的属性的内容
equals() 方法是从 Object 类中继承的,如果实现类没有重写 Object 类中 equals() 方法,默认的 实现就是使用==
eg
String x = "string";
String y = "string";
String z = new String("string");
System.out.println(x==y); // true
System.out.println(x==z); // false
System.out.println(x.equals(y)); // true
System.out.println(x.equals(z)); // true
final,finally,finalize
final
修饰符(关键字)有三种用法:修饰类、变量和方法。
修饰类时,意味着它不能再派生出新的子类,即不能被继承,因此它和 abstract 是反义词。
修饰变量时,该变量使用中不被改变,必须在声明时给定初值,在引用中只能读取不可修改,即为常量。
修饰方法时,也同样只能使用,不能在子类中被重写。匿名内部类访问局部变量时需要使用 final,因为 Innerclass 实际会 copy 一份局部变量,final 可以防止出现数据一致性问题。
finally
Java 保证重点代码一定要被执行的机制,例如我们可以用 try-finally 或者 try- catch-finally 来进行文件的关闭、JDBC的关闭等。除非在 finally 前执行了 System.exit()、 try 中死循环、线程被杀死,finally一定被执行
finalize
基础类 Object 的一个方法,当垃圾回收器将要回收对象所占内存时之前被调用(该对象 覆盖了finalize()方法),用来保证对象在被垃圾收集前完成特定的资源回收。由于 finalize 执行时间 不确定且可能造成程序死锁、拖慢垃圾收集等问题,Java 9 中将该方法废弃。
优化:使用 Cleaner 配合幻象引用。
接口与抽象类
构造函数
抽象类可以有构造函数,但不能被实例化(无论其内部是否有抽象方法,都不能实例化)
接口没有构造函数,不能实例化
成员变量
抽象类可以有普通成员变量;
接口中没有普通成员变量,但是可以有也只能有 public static final的静态常量,并必须赋予初值;
成员方法
抽象类中可以有非抽象的普通方法,也可以没有抽象方法;
JDK1.8之前,接口中只能有抽象方法(默认使用 public abstract 修饰,也只能使用这个修饰);
JDK1.8之后,接口中允许有普通方法,但是需要用 default 来定义,同时可以包含 static 方法;
实现方式
一个类可以实现多个接口,但只能继承一个抽象类
Java 类实现接口使用 implements 关键字,继承抽象
类则是使用 extends 关键字
重载(Overload)与重写(Override)
重载是同一个类中,方法名称相同,但是参数或个数不同。与返回值没有关系。
重写是在多个类中,产生继承关系,父类与子类的方法必须相同。
Object 中的方法
protected Object clone()--->创建并返回此对象的一个副本。
boolean equals(Object obj)--->指示某个其他对象是否与此对象“相等”。
protected void finalize()--->当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾 回收器调用此方法。
Class<? extendsObject> getClass()--->返回一个对象的运行时类。
int hashCode()--->返回该对象的哈希码值。
void notify()--->唤醒在此对象监视器上等待的单个线程。
void notifyAll()--->唤醒在此对象监视器上等待的所有线程。
String toString()--->返回该对象的字符串表示。
void wait()--->导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。
void wait(long timeout)--->导致当前的线程等待,直到其他线程调用此对象的 notify() 方 法或 notifyAll()方法,或者超过指定的时间量。
void wait(long timeout, int nanos)--->导致当前的线程等待,直到其他线程调用此对象的 notify()。
Java创建对象方式
使用new关键字创建
调用对象的clone()方法
利用反射,调用Class类或者Constructor类的newInstance()方法
利用反序列化,调用ObjectInputStream类的readObject()方法
JDK1.8的新特性
Lambda表达式
函数式接口
方法引用和构造器调用
Stream API
接口中的默认方法和静态方法
新时间日期API
参考资料:[JDK1.8 新特性]