Java 基础知识面试题+答案

1.Java的基本数据类型

八种基本数据类型:byte、short、char、int、long、double、float、boolean
byte:字节型 占用1字节
short:短整型 占用2字节
char:字符型 占用2字节
int:整形 占用4字节
long:长整型 占用8字节
double:双精度浮点型 占用8字节
float:浮点型 占用4字节
boolean:布尔型 占用1字节/4字节(《Java虚拟机规范》给出了4个字节) 默认是 false

2.Java的三大特性和五大原则

三大特性:封装、继承、多态
五大原则:单一职责原则、开放封闭原则、虚心的白云交替原则、依赖倒置原则、接口分离原则

3.JDK、JRE、JVM三者有啥区别

JDK:全称是Java Development Kit ,它Java开发工具包,包含了JRE和JVM
JRE:全称是Java Runtime Environment ,它是Java运行时环境,里面包含了JVM
JVM:全称是Java Virtual Machine,是Java运行的虚拟机,核心操作是将class文件转成机器码(汇编语言)

4.数组和集合的区别

1.数组即可以存储基本数据类型,也可以存储引用数据类型。集合只能存储引用类型的对象,也能存基本类型,但是存储的时候会自动装箱。(JDK1.5新特性)
2.数组长度是固定的,集合长度是可以改变的。
3.定义时,数组必须指定元素类型,集合默认全部都是Object类型。
4.无法获取数组的元素个数,length只能返回数组长度。而集合的size方法可以返回元素个数。
5.集合是以类和接口的形式存在,具有Java的三大特性特征,提供很多方法和属性可以完成很复杂的操作。大大提高开发的效率。

5.List和Set区别

1.List、Set都继承自Collection接口;List的特点:元素有放入顺序,且可重复;Set的特点:元素无放入顺序,且不可重复(注意:元素虽然无放入顺序,但是元素在Set中的位置是由该元素的HashCode决定的,其位置是固定的)。List支持for循环,也就是通过下标来遍历,也可以用迭代器,但是Set只能用迭代器,因为他无序,无法使用下标取值;
2.List接口有三个实现类:LinkedList,ArrayList,Vector。Set接口有两个实现类:HashSet(底层由HashMap实现),LinkedHashSet
3.Set:检索元素效率低,删除和插入效率高,插入和删除不会引起元素位置改变。List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。

6.ArrayList 和Vector的区别是

相同点:都实现了List接口、都是有序的集合,允许重复,可以根据下标获取元素。都有初始容量。
不同点:ArrayList是线程不安全的,效率会高,Vector是线程安全的,效率低;ArrayList的扩容为原来的1.5倍,Vector为原来的2倍。

7.说说ArrayList 和Vector、LinkedList的存储性能和特性

ArrayList 和Vector使用数组方式存储数据,他们都允许直接按序号索引取值,但是插入数据涉及数组元素移动等内存操作,所以索引数据快,而插入数据慢,由于Vector使用了synchronized锁,所以性能上比ArrayList差一些。LinketList使用的是双向链表实现存储,按序号索引数据需要向前或向后遍历,但是插入数据只需要记录本项的前后项即可。所以插入数据快。

8.equals和==的区别

==:基本数据类型比较值,引用数据类型比较引用地址
equals:Object的equals底层是= =, String重写了equals方法,比较的是字符。

9.Java8的新特性有哪些

1.接口默认方法
2.Lambda表达式
3.Sream API
4.新的时间LocalDateTime类

10.HashMap内部的bucket数组长度为什么一直都是2的整数次幂

1.为了在进行位运算(key.hashCode()的时候)的时候快熟寻址
2.为了扩容后数据均匀的散列到新的桶(bucket)中去

11.Java 8中为什么要引进红黑树

为了避免hash性能急剧下降,引起HashMap性能急剧下降的场景。

12.HashMap如何处理key为null的键值对

放置在桶数组下标为0的位置上

13.Java中有哪些线程安全的时间类

Date是线程不安全的
DateTime的所有类都是现成安全的,必须通过工厂的方式创建,不能通过new的方式创建

14.Java包含你的哪些知识层面或者知识模块

在这里插入图片描述

15.Integer的IntegerCache

那么当我赋值 Integer a=128 的时候, a大于-128 但是不小于127 , 所以走 new Integer, 是个新对象
我再赋值一个 Integer b=128 进来也是这样的流程,也会new Integer 这时用== 他们两个对象地址都是new的 是个全新的, 所以是不相等。

所以Integer c=127 和Integer d=127 取得都是同一个对象的地址。因为127存在常量池中 所以两个==是比较值相等。

16.为什么重写equals方法还要重写hashCode方法?

hashCode方法:使用C语言编写。根据对象内存地址转换成整数类型。
定律:
1.如果两个对象的hashCode相等,equals不一定相等。
2.如果两个对象的equals相等,则hashCode一定相等。

如果重写了equals方法,使两个对象比较相等,但是没有重写hashCode方法,则两个对象的hashCode方法可能不一样,违反了上面的定律。
且在HashMap中,比较key值是使用了对象的equals方法和hash值比较是否相等。(包括set集合等)

17.HashMap如何避免内存泄露问题?

重写自定义对象的equals方法和hashCode方法。来保证hashMap的对象key不重复创建。

12/24更新

18.java中,final、finally、finalize的区别

在Java语言编程中,final、finally、finalize是三种具有不同含义和用途的关键字。
1.final:是一个修饰符,它可以修饰类、方法、变量,它的作用是限制某些对象或行为的改变。当修饰类的时候,表示类不能被继承;当修饰方法的时候,表示方法不能被重写;当修饰变量的时候,表示变量不能被修改;
2.finally:是一个关键字,一般结合try catch来使用,用于异常的处理。finally块中的代码无论是否发生异常都会执行。在这里需要确保某些资源需要被释放(如文件和网络连接等)。
3.finalize:是Object类中的一个方法。在Java中所有的类都隐式继承了Object类。finalize方法在垃圾回收器清理对象时被调用,用于执行对象的清理工作,一般情况下不建议重写finalize方法,因为其执行时间和调用次数是不确定的,而在Java9中的版本,finalize方法已经被标记为弃用。为了能更好的管理资源,可以使用try-with-resources语句或显式的关闭资源。
总结一下:final、finally、finalize在Java中具有不同的含义和用途。final用于修饰类、方法、变量,表示不可改变。finally用于异常处理,表示无论异常是否发生都会执行的代码;finalize是Object类的一个方法,用于垃圾回收器执行清理对象前调用,执行对象的清理工作,但在现代Java中不建议使用。

19.BIO、NIO、AIO有什么区别

在Java中BIO、NIO、AIO是三种不同的I/O处理模型,它们在处理输入和输出的时候有不同的特点和使用场景。
1.BIO(Blocking IO):BIO是传统的IO模型,也被称为同步阻塞IO。在这种模式当中,当线程执行IO操作时,该线程会被阻塞,直到操作完成。这种方式简单易用,但是在高并发场景下,性能较差。因为每个IO操作都需要一个线程,现成数量过多可能导致资源耗尽。
2.NIO(Non-Brocking IO):NIO是Java1.4引入的新模型,也被称为同步非阻塞IO。NIO提供了缓冲区(Buffer)和通道(Channel)的新IO抽象。NIO允许线程在等待某个IO完成时执行其他任务。从而提高IO的操作的并发性。NIO的主要特点包括:
使用缓冲区进行数据操作,提高数据处理效率。
通过Selector(选择器)实现多路复用,允许一个线程同时处理多个Chennel,提高并发性能。
支持非阻塞IO操作。减少线程的等待时间。NIO相比于BIO,在高并发场景下具有更好的性能表现。
3.AIO(Asynchronous IO) :AIO是Java1.7引入的异步非阻塞IO模型,也称为NIO2.0。AIO采用了事件驱动的方式进行IO操作,当一个IO操作完成时,会自动触发处理器进行处理。AIO的主要特点包括:
支持异步IO操作,允许线程在等待IO操作时执行其他任务。
通过ComplationHandler(完成处理器)实现事件驱动, 当IO操作完成时,会自动触发处理器进行处理。AIO在某些场景下(列如大文件传输、低延迟要求等)具有更好的性能表现。
总结一下:BIO、NIO、AIO是Java中三种不同的IO处理模型。BIO是传统的同步阻塞IO模型,适用于简单的场景。NIO是同步非阻塞IO模型,使用于高并发场景。AIO是异步非阻塞IO模型,使用于大文件传输和低延迟要求的场景。在实际应用中选择合适的IO处理模型很重要。

20.为什么Java里面只有值传递?

在Java中,方法传参是按照值传递的。这意味着我们将一个变量传递给方法时,实际上传的是变量的值,而不是变量本身。这里需要区分基本数据类型和引用数据类型的值传递。
1.基本数据类型:对于基本数据类型(如int、byte、char、double等),值传递意味着传递的是变量的实际值。
2.引用数据类型:对于引用数据类型(如对象、数组等),值传递意味着传递是对象的引用,而不是对象的本身。所以,在方法内部,我们可以改变对象的状态,而不能改变原始对象的引用。

21.Java中io流分为几种?

Java中的流可以按照数据类型和传输方向来区分,分别由四个抽象类来表示。Java中多种多样变化的流均由它们派生出来的。
按照数据类型分:分为字节流和字符流:
字节流:InputStream,OutputStream。字节流按照8位传输,可以处理任何类型的数据,包括二进制。
字符流:Writer,Reader。字符流按照16位传输,只能处理字符或者字符串,可以直接处理UniCode字符。
按照传输方向分:输入流和输出流
输入流:InputStream,Reader 输入流用于从数据源读取到内存中。
输出流:OutputStream,Writer 输出流用于从内存写出数据到目标位置。

22.Switch能否作用在byte、long、String上?

switch可以作用的数据类型:byte、char、int、short、enum。Java7开始支持String类型。
switch不支持long类型,因为超过了switch的处理范围。

23.Java7中的try-with-resources有使用过吗?

一般用于自动关闭资源。异常处理。多个资源处理。资源类需要实现AutoCloseable或Closeable接口。

24.Java中重载(Overload)和重写(Override)有什么区别?

在Java中重载(OverLoading)和重写(OverRiding)是完全两种不同的概念。它们有一下区别。
重载:1.方法重载是在同一个类中定义多个具有相同方法名但参数列表不同(参数类型、数量、顺序等不同)的方法。2.重载方法可以用来改变方法类型,但返回类型不能区分重载的方法。3.重载可以改变访问修饰符。4.重载方法可以声明更新更广的检查异常。
重写:重写是子类定义了一个与父类方法签名(方法名和参数列表)完全相同的方法。2.重写不能改变返回类型,但是从java5开始子类可以协变返回类型,返回父类方法返回类型的子类。3.重写方法不能改变修饰符,子类中的方法访问级别不能低于父类方法。4.重写方法不能声明新的或者更广的检查异常,只能声明更少,更窄的或者完全不声明。
总结一下:重载发生在一个类中,同名方法有不同的参数列表。而重写发生在父类和子类当中,子类有个与父类的方法签名完全相同或者兼容(协变的返回类型)的方法。

25.Oracle JDK 和Open JDK的区别?

1.Oracle JDK 每三年更新一次,Open JDK每三个月更新一次
2.Open JDK 是一个参考模型,并且是完全开源的,而Oracle JDK 是Open JDK 的一个实现,并不是完全开源的。
3.Oracle JDK 比Open JDK 更加稳定。Open JDK 和Oracle JDK 源码几乎相同,但是Oracle JDK 有更多的一些类和错误的修复。因此,想要开发企业/商业的软件,我建议您选择Oracle JDK ,因为它经过了彻底的测试和稳定。
4.在响应性和JVM性能方面,Oracle JDk 比 Open JDK提供更好的性能。
5.Oracle JDK 不会为即将发布的版本提供长期的支持,用户每次都必须通过更新到最新版本获得支持来获取最新的版本。
6.Oracle JDK 根据二进制代码许可协议获得许可,而OpenJDK 根据GPL v2获得许可。

26.抽象类和接口的区别?

接口:向上而下(先有接口在有实现类,不需要管如何实现)
抽象类:向下而上(是对子类的某些属性和行为的抽象,所以一般先有子类在有抽象类)
抽象类是用来捕获子类通用性的,接口是抽象方法的集合。
从设计成面上来说,抽象类是对类的抽象,是一种模版设计。接口是行为的抽象,是一种行为的规范。
相同点:
接口和抽象类都不能被实例化。
都位于继承的顶端,用于被其他类继承或实现。
都包含抽象方法,其子类都必须覆写这些抽象方法。

不同点:(个人总结)
声明类的关键字不同。interface和abstract
子类实现方式不同。extends和implements
抽象类可以有构造器接口不能有构造器。
访问修饰符:抽象类可以任意修饰符,接口不能private和protected
多继承:一个类自能继承一个抽象类,一个类可以实现多个接口。
字段声明:抽象类的字段可以声明任意的,接口的字段都是static 和 final的。

27.普通类和抽象类的区别

普通类不能包含抽象方法,抽象类可以包含抽象方法。
抽象类不能实例化,普通类可以直接实例化。

28.内部类有哪些?

成员内部类、局部内部类、匿名内部类、静态内部类

29.反射的实现

1获取Class对象
Class clazz = Class.forName(类的全限定名);
Class clazz = 对象.getClass();
Class clazz = 类名.class;
2.获取构造器
Constructor ctor = clazz.getDeclaredConstructor();
3.创建构造器
Object obj = ctor.newInstance();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值