超详细的Java面试题总结之 -- JAVA基础

(一) 基本概念和常识

1. Java语言有什么特点?

  1. 简单易学(摒弃了指针和内存管理等容易发生错误的地方,而且有丰富的类库)
  2. 面向对象
  3. 移植性强(一次编译,随处运行)
  4. 支持多线程
  5. 健壮(Java是强类型语言,还提供了异常处理,垃圾回收等特性)

2. 说一说JDK、JRE、JVM的区别?

JVM是运行字节码的Java虚拟机(字节码就是.class文件,只面向虚拟机)。JVM针对不同的系统有不同的实现,使得Java代码编译一次,随处可以运行。

JRE是java的运行环境。它是运行已编译的java程序所需资源的集合,包括虚拟机JVM,Java类库,Java命令等组件。

JDK是Java开发工具包,提供了Java的开发环境和运行环境。它包括JRE,而且还有编译器javac和工具如javadoc。

如果只运行java程序,安装JRE即可。如果要编写、编译Java源代码,就得安装JDK。也有例外情况,例如运行一个含有JSP的Web程序,就需要JDK,因为将JSP转化成Servlet后需要用JDK编译。

3. 为什么说 Java 语言“编译与解释并存”?

因为Java源代码首先要经过javac编译步骤,变成字节码文件,然后再由JVM解释运行。所以编译与解释并存。

4. 什么是字节码?采用字节码的最大好处是什么?

字节码就是Java源代码经过javac编译后形成的.class文件,它不面向任何处理器,只面向JVM。

Java通过字节码的方式,一定程度上缓解了传统解释型语言执行速度慢的问题,同时保留了跨平台的特性,所以Java程序运行时比较高效,而且无须重新编译,即可在不同平台执行。

5. Oracle JDK 和 OpenJDK 有什么区别?

OpenJDK是一个参考模型,全部开源。Oracle JDK是OpenJDK的一个实现,部分开源。

Oracle JDK相对更稳定,而且性能好一点。

6. JAVA和C++有什么区别?

  1. C++是编译型语言,运行速度比Java快。Java是解释型语言,能跨平台。
  2. Java不提供指针来直接访问内存,更加安全。
  3. Java有自动内存管理机制,不需要像C++一样手动释放内存。
  4. Java的类只能是单继承,C++可以多继承。但是Java接口可以多继承,就是一个类可以实现多个接口。
  5. C++的字符数组或字符串需要用空字符结尾('\0'),Java的字符串不需要结束符。

7. JAVA语言采用何种编码方案?

Java采用Unicode编码标准,把世界上的各种语言的每一个字符都设定了唯一编码,实现跨语种、跨平台使用。

(二) 基础语法

1. Java的注释有几种?怎么表示?

有三种,分别为单行注释多行注释文档注释

分别为//, /* */, /** */

多行注释和文档注释不能嵌套使用

2. Java访问修饰符是什么?有哪几种?

访问修饰符可以修饰类、变量、方法,用来控制它们的访问权限。

修饰符当前类子类当前包其他包
private
默认(default)
protected
public

3. final, finally, finalize的区别?

final是用来修饰类、方法、变量的。如果修饰类,则表示该类无法被继承;如果修饰方法,则该方法无法被重写;如果修饰变量,则该变量是一个常量,无法被重新赋值。

finally出现在try-catch代码块中,无论是否出现异常,finally内的语句都会执行。

finalize是一个方法,属于Object类,该方法一般由垃圾回收器来调用。

4. this有什么作用?super呢?

this代表对象本身,是当前对象的引用。

this的作用主要有两个:形参和成员变量重名时,使用this来区分;引用本类的构造方法。

super为自己父类对象的应用。离自己最近的一个父类。

super的作用也有两个:调用父类的属性和方法;引用父类的构造方法。

5. ==和equals有什么区别?

**==**判断的是两个变量的值是否相等。如果是两个基本数据类型,那么就直接比较值。如果是两个对象,那么就比较地址的值。

equals判断两个对象是否相等,如果类中没有重写equals方法,那么就会使用Object中的equals方法,和==是一样的效果。如果类中重写了equals方法,那么就可以比较类中的内容是否相等。

6. 为什么重写equals()方法后还要重写hashCode()方法?

如果要以某个类为键创建散列表,那么就得使用hashCode()方法计算其下标,如果表中对应下标有元素的话,说明发生了冲突,会根据hashCode和equals方法判断键是否相同,如果相同,则直接覆盖值。如果不同,就插入红黑树或放到链表末尾。

如果仅仅重写了equals方法,那么两个相等的对象的hashCode很可能不等,导致哈希表保存重复的对象。而HashSet、HashMap这种是不允许出现重复元素的。所以要同时重写hashCode方法,保证两个对象如果equals()返回相等时,hashCode()应该是相同的结果

(三) 数据类型

1. Java有哪些基本数据类型,各占多少字节,取值范围是多少?

在这里插入图片描述

2. 谈谈自动装箱和拆箱?

自动装箱:自动将基本数据类型包装成引用类型。

自动拆箱:自动将包装类型拆成基本数据类型。

例如将一个常数赋值给Integer类型,就会进行自动装箱操作,将常数包装成Integer类型。如果将一个Integer类型和一个整数做加法,那么就会自动拆箱,将Integer拆正对于的整数。


Java中的大部分包装类型都实现了常量池技术,包括Byte、Short、Integer、Long、Char、Boolean。前四种默认创建了[-127, 128]的缓存数据,Char类型创建了[0, 127]的缓存数据,Boolean直接返回True或False。如果要装箱的基本类型在缓存池区间内,就直接返回对应的引用即可,如果不在区间内,就会创建新的对象

下列程序的输出结果是什么?

public class Main {
    public static void main(String[] args) {         
        Integer a = 1;
        Integer b = 2;
        Integer c = 3;
        Integer d = 3;
        Integer e = 321;
        Integer f = 321;
        Long g = 3L;
        Long h = 2L;
         
        System.out.println(c==d); // true
        System.out.println(e==f); // false
        System.out.println(c==(a+b)); // true
        System.out.println(c.equals(a+b)); // true
        System.out.println(g==(a+b)); // true
        System.out.println(g.equals(a+b)); // false
        System.out.println(g.equals(a+h)); // true
    }
}

3. Java中switch能支持哪些数据类型?

jdk1.5之前,能支持byte, short, int, char四种基础类型。

jdk1.5增加了枚举类和byte, short, int, char的包装类,支持包装类的原因是Java进行了自动拆箱操作,支持枚举类的原因是枚举类有一个ordinal方法,返回的是int类型的数值。

jdk1.7开始支持String类型,是因为String类型有一个HashCode方法返回int值。其余几种能不丢失精度的情况下向上转型为int,所以总的来说,switch支持的是int。

switch表达式中的值不能为null,不然会报NullPointerException。case中的值也不能为null,会编译错误。

(四) Java包

1. JDK 中常用的包有哪些?

  • java.lang,这个是java的基础包,在使用时不需要导包。
  • java.util,这个包含有各种集合类。
  • java.io,这个包含有读写文件相关操作。
  • java.sql,这个包是和数据库操作相关的。

2. import java和javax有什么区别?

javax刚开始作为一个拓展的API包来使用,但随着时间推移,javax发展成了java API的组成部分。但将javax包中的内容移动到java包中会破坏之前的代码。因此,javax包就成了标准的一部分。实际上java和javax没有区别,就是名字不同。

(五) String类

1. 什么是字符串常量池?

字符串常量池位于堆内存中,专门用来存放字符串常量。它的设计思想就是避免频繁地创建重复字符串,导致系统性能降低。

所以在创建字符串常量时,先判断字符串在不在常量池中,如果在,就直接返回引用。如果不在,就实例化字符串,并存放到常量池中。

2. String、StringBuffer、StringBuilder有什么异同点?

这三个都是使用字符数组保存字符串,而且都是final类,无法被继承。

可变性方面,String是不可变的,因为类中的字符数组被final修饰。StringBuffer和StringBuilder中的字符数组是可变的。

线程安全方面,String由于是不可变的,所以线程安全。StringBuffer也是线程安全的,因为大部分方法加了同步锁,可以实现对字符数组的互斥访问。而StringBuilder为了提高性能,就没有同步锁,所以线程不安全。

性能方面,String的性能最低,StringBuffer其次,StringBuilder最快。因为String类型进行字符串拼接、修改时,其实是每次都在创建了新的字符串,所以效率最慢。StringBuffer由于有同步锁,就会阻塞一些访问字符数组的进程,效率会慢些。StringBuilder不涉及到锁,所以速度最快。

如果只是定义个字符串,或进行少量的拼接操作,那么可以使用String。如果涉及大量字符串改动,而且是多线程操作,那么就应该使用StringBuffer。如果是单线程,那就可以用StringBuilder。

3. 使用HashMap时,使用String做Key有什么好处?

由于HashMap中根据HashCode来计算值的存放位置。String类型是不可变的,所以它的HashCode是固定的,可以被缓存下来,不用重复计算,所以效率很高。

4. String类可以被继承吗?

不能,String是final类,无法被继承。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值