目录
Java 面试题
1 什么是JDK ,JRE, JVM
1.1 基本概念
JDK (Java Development Kit):是Java的核心。它包括Java运行环境JRE(Java Runtime Envirnment) 和Java开发工具,如 javac(编译), java(解释), jdb(调试),javap(反汇编),javadoc(根据Java源码及说明语句生成HTML文档)等以及Java 基础的类库(Java API 包括 rt.jar)。rt.jar 可以理解为:Java 源码编译成的jar包。
关系:JDK包括JRE,JRE包括JVM。
JRE (Java Runtime Environment ,Java 运行环境),包含JVM的标准实现及Java核心类库。他的主要功能:
- 加载代码:由类加载器(classloader)完成
- 校验代码:有字节码校验器(bytecodeverifier)完成
- 执行代码:由运行时解释器(runtimeinterpreter)完成
JVM (Java Virtual Machine , Java虚拟机)。JVM可以看做是一台抽象的计算机 ,如同真实的计算机那样,他有着自己的指令集以及各种运行时的内存区域。他将字节码文件翻译成各个操作系统对应的机器码,确保字节码文件能在各个系统上正确的运行。这就是Java能够 “一次编译,到处运行的原因”
1.2 联系与区别
联系:
JVM 不能单独执行class文件,解释class的时候还需调用解释所需要的类库lib。在 JDK 下面的的 jre 目录里面有两个文件夹bin 和 lib,在这里可以认为 bin 里的就是 jvm,lib 中则是 jvm工作所需要的类库,所以 JVM+Lib=JRE。
区别:
JDK 和 JRE 区别:在bin文件夹下会发现,JDK 有javac.exe而 JRE 里面没有,javac指令是用来将java文件编译成class文件的,这是开发者需要的,而用户(只需要运行的人)是不需要的。JDK还有jar.exe, javadoc.exe等等用于开发的可执行指令文件。这也证实了一个是开发环境,一个是运行环境。
JRE 和 JVM 区别:JVM 并不代表就可以执行class了,JVM执行.class还需要JRE下的lib类库的支持,尤其是rt.jar。
2 Java 和 C++ 的区别
- 都是面向对象的编程语言,都支持封装,继承,多态
- Java 中不提供指针来直接访问内存,程序内存更加安全
- Java 中的类是单继承的,C++ 支持多继承。但是Java接口支持多继承
- Java 由自动内存管理的垃圾回收机制(GC),不需要程序员手动释放无用内存
- 在C /C++语言中,字符串或字符数组最后都会有一个额外的字符 ‘\0’ 来表示结束。但是Java中没有结束符这一概念。
3 String StringBuilder StringBuffer 的区别
3.1 基本概念
String:字符串常量,字符串长度不可变。用于存放字符的数组被声明为final,所以只能赋值一次,不可再更改。
/** The value is used for character storage. */
private final char value[];
/** The offset is the first index of the storage that is used. */
private final int offset;
/** The count is the number of characters in the String. */
private final int count;
StringBuffer(JDK 1.0):字符串变量(Synchronized,即线程安全)。它是线程安全的可变字符序列,在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。
常用方法:
- toString():可以将StringBuffer类型转换为String类型
- append():将字符添加至缓冲区末端
- insert():在指定的位置添加字符
StringBuilder(JDK 5.0):字符串变量(线程不安全),它是一个可变的字符序列,此类提供与StringBuffer兼容的API,但不保证同步。当在单个线程使用时,建议使用它,因为在多数情况下,它实现的更快,不需要考虑线程安全。
3.2 性能区别
String 是不可变的对象,因此在每次对String类型进行改变的时候,都会生成一个新的String对象,然后指针指向新的String对象。每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后,JVM的GC就会开始工作,性能就会降低。
StringBuffer类,每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象的引用。String对象的拼接其实是被编译成了StringBuffer对象的拼接,但在某些特殊情况下(拼接的字符串来自一个String对象),则编译器自动将其拼接在一起,此时,String生成对象的速度比StringBuffer 快。
4 重载与重写的区别
比较参数 | 重载(OverLoad) | 重写(Override) |
---|---|---|
方法名 | 必须相同 | 必须相同 |
参数列表 | 不同(个数或类型) | 必须相同 |
返回值类型 | 无关 | 必须相同 |
修饰符 | 无关 | 访问权限不能缩小 |
位置 | 同一个类 | 子父类 |
异常 | 无关 | 不能抛出更大的异常 |
5 抽象类和接口的区别
- 抽象类要被子类继承,接口要被类实现
- 接口只能声明抽象方法,抽象类中可以声明抽象方法,也可以写非抽象方法
- 接口中定义的变量必须被public static final 修饰,抽象类中不做要求
- 抽象类不能多继承,接口可以多继承,泪也可以实现多个接口
- 抽象类中可以包含static方法,但是接口中不允许(因为静态方法不能被重写)
- 接口没有构造方法,抽象类可以有构造方法