Java 基础面试题(一)

118 阅读5分钟

1. JDK、JRE、JVM的区别

  • JDK:java development kit 开发工具
  • JRE:java Runtime environment 运行时环境
  • JVM:java Virtual Machine 虚拟机

image.png

2. == 和 equals() 的区别

  • ==对比的是栈中的值
  • 基本数据类型比较变量值
  • 引用类型是堆中的内存对象的地址
  • equals:object中默认采用==比较,通常会重写,对比字符串的内容
String str1 = "hello";             // 在栈中分配地址
String str2 = new String("hello"); // 在堆中分配地址
String str3 = str2;
System.out.println(str1 == str2); // false
System.out.println(str1 == str3); // false
// equals() 方法被 Object 重写了,比较的是字符串内容
System.out.println(str1.equals(str2)); // true
System.out.println(str1.equals(str3)); // true
System.out.println(str2.equals(str3)); // true

image.png

3. 简述 final 作用

  • final 修饰类:表示该类不可以被继承
  • final 修饰方法:表示该方法不能被子类覆盖,但可以重载
  • final 修饰变量(类似 const):变量变量一点赋值,不能被修改

4. String、StringBuffer、StringBuilder区别和使用场景

  • string是final修饰的,不可变,每次操作都会产生新的String对象
  • StringBuffer和StringBuilder都是在原对象上操作
  • StringBuffer是线程安全的,StringBuilder线程不安全的
  • StringBuffer方法都是synchronized修饰
  • 性能: StringBuilder > StringBuffer > String
  • 场景:经常需要改变字符串内容时使用后面两个
  • 优先使用StringBuilder,多线程使用共享变量时使用StringBuffer

5. 重载和重写的区别

  • 重载:发生在同一个类中,方法名必须相同,顺序不同,参数类型不同,个数不同,方法返回值和访问修饰符可以不同
  • 重写:发生在父子类中,方法名、参数列表必须一样,返回值范围小于等于父类,抛出的异常小于等于父类,访问修饰符大于等于父类,如果父类访问修饰符为private,那么子类就不能重写该方法

6. 接口和抽象类的区别

  • 抽象类只能单继承,接口可以多实现
  • 抽象类可以包含某些方法实现,而接口不允许
  • 抽象类中的成员变量可以是任意类型的,而接口中的成员变量只能是public、static、final类型的

7. List 和 Set 的区别

  • List:有序,按照对象进入顺序保存,可重复,允许多个null对象,可以用迭代器,也可以用for循环遍历
  • Set:无序不可重复,只能用iterator迭代器遍历

8. hashCode()介绍

  • hashCode:用来获取在堆中地址

9. ArrayList 和 LinkedList 区别

  • ArrayList:
    • 基于动态数组,连续内存存储,适合随机访问,适合查询
    • 扩容机制:数组长度固定,如果需要增加元素,非常麻烦
  • LinkedList:
    • 基于链表,随机分布在内存中,适合做数据插入,删除等,
    • 不适合查询

10. HashMap 和 HashTable 的区别?底层实现是什么?

  • HashMap
    • 线程不安全
    • 允许 key 和 value 为null
    • 底层实现:数组 + 链表,如果hash冲突,采用拉链法解决
    • jdk8 开始,链表高度到8,链表转变成红黑树,长度低于6,红黑树转为链表
  • HashTable
    • 线程安全,每个方法都加了synchronized关键字
    • 不允许 key 和 value 为 null

11. 请说出作用域public,private,protected,以及不写时的区别

image.png

12. 构造器是否可以被重写?

不可以被重写,因为构造器不能被继承,但是可以重载

13.final, finally, finalize的区别

  • final修饰属性,方法,类;分别表示属性不可变,方法不可覆盖,类不可继承
  • finally是异常中的关键字,始终要执行的代码放在finally块中
  • finalize是Object的一个方法,是垃圾回收机制,重写此方法可以回收其他资源,如文件关闭。JVM不保证此方法总被调用

14.比较throw和throws

  • throws是声明异常的关键字,作用于类,其后是一个异常类,比如throws IOException
  • throw是抛出异常的关键字,其后跟着一个异常对象,比如throw  new IOException()

15.垃圾回收的原理和优点

垃圾回收是一个低级别的线程运行,在不知情的情况下对堆内存中的闲置的或者长期没使用的对象进行回收。

  • 优点:
    • 1)不需要考虑内存管理;

    • 2)防止内存泄漏,有效的管理内存;

    • 3)对象不再有作用域的问题,只有对象的引用存在作用域;

    • 4)程序员不能实时的对某个对象或所有对象调用垃圾回收器

16.线程的基本概念、线程的基本状态以及状态之间的关系

线程是执行和调度的基本单位,是进程中一个执行过程,一个进程有多个线程,线程间共享内存,如果是单核CPU,那么CPU一会访问a线程,一会访问b线程,线程之间切换很快,给人的感觉是他们在同步执行。

  • 线程的基本状态分为:新生状态,就绪状态,运行状态,阻塞状态,死亡状态

  • 关系:调用start()方法线程转为就绪状态

  • 调用wait()方法线程转为就绪状态

  • 调用sleep()方法线程转为阻塞状态

  • 就绪,运行之间是相互转换的

17.sleep() 和 wait() 有什么区别? 

  • sleep是Thread类下的方法;wait是Object下的方法
  • sleep是使线程休眠,不释放锁;wait是使线程等待,释放锁

18.PreparedStatement与Statement的区别

  • PreparedStatement是预编译语句执行者,数据库对sql语句进行预编译
  • Statement是执行时对sql语句进行编译
  • Statement存在sql注入的问题,PreparedStatement解决了这个问题
  • PreparedStatement的执行效率比Statement高
  • PreparedStatement中使用?占位符,设置参数更方便

19.线程的sleep()方法和yield()方法有什么区别?

  • sleep()会给比它优先级低的线程机会,yield()方法只会给跟它同等级或比它优先级高的线程机会
  • 执行sleep后进入阻塞状态,执行yield后进入就绪
  • sleep方法声明抛出InterruptedException异常,yield没有声明抛出任何异常
  • sleep比yield方法具有更好的移植性