Java基础常见面试题
1、JDK和JRE有什么区别?
JDK就是Java Development Kit 。JDK是面向开发人员使用的SDK,它提供了Java的开发环境和运行环境。SDK是Software Development Kit 一般指软件开发包,可以包括函数库、编译程序等。
JRE是Java Runtime Enviroment是指Java的运行环境,是面向Java程序的使用者,而不是开发者。
2、== 和 equals 的区别是什么?
(1)== : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象。
(基本数据类型 == 比较的是值,引用数据类型 == 比较的是内存地址)
(2)equals() : 它的作用也是判断两个对象是否相等。
但它一般有两种使用情况:
情况1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。
情况2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来两个对象的内容相等;若它们的内容相等,则返回 true (即,认为这两个对象相等)。
3、两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
如果两个对象相等,则hashcode一定也是相同的
两个对象相等,对两个对象分别调用equals方法都返回true
两个对象有相同的hashcode值,它们也不一定是相等的
因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖
hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)
4、final 在 java 中有什么作用?
用于修饰类、属性和方法;
被final修饰的类不可以被继承
被final修饰的方法不可以被重写
被final修饰的变量不可以被改变,被final修饰不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的
5、java 中的 Math.round(1.5) 等于多少? Math.round(-1.5) 等于多少?
Math.round(1.5)等于2,Math.round(-1.5)等于-1,四舍五入是在原来的基础上加上0.5向下取整。
6、说出以下代码的输出结果。
1 | public class A { |
1 | public class SubA extends A { |
1 | public class StaticTest { |
1 | 输出结果为: |
解释:
子类构造方法调用规则:
(1)如果子类的构造方法中没有通过 super 显式调用父类的有参构造方法,
也没有通过 this 显式调用自身的其他构造方法,则系统会默认先调用父类的无参构造方法。
这种情况下,写不写 super(); 语句,效果是一样的
(2)如果子类的构造方法中通过 super 显式调用父类的有参构造方法,
将执行父类相应的构造方法,不执行父类无参构造方法
(3)如果子类的构造方法中通过 this 显式调用自身的其他构造方法,将执行类中相应的构造方法
(4)如果存在多级继承关系,在创建一个子类对象时,以上规则会多次向更高一级父类应用,
一直到执行顶级父类 Object 类的无参构造方法为止
结论:
类的实例化方法调用顺序:
类加载器实例化时进行的操作步骤:加载 -> 连接 -> 初始化
(1)父类静态代变量
(2)父类静态代码块
(3)子类静态变量
(4)子类静态代码块
(5)父类非静态变量(父类实例成员变量)
(6)父类构造函数
(7)子类非静态变量(子类实例成员变量)
(8)子类构造函数
7、Java中,基本的数据类型有哪些?
基本数据类型有byte、short、int、long、float、double、char、boolean八种基本数据类型。
byte:1个字节,8位
short:2个字节,16位
int:4个字节,32位
long:8个字节,64位
float:4个字节,32位
double:8个字节,64位
boolean:逻辑上理解是占用 1位,但是实际中会考虑计算机高效存储因素
char:2个字节,16位
8、String 属于基础的数据类型吗?
不属于,Java中基本数据类型只有byte、short、int、long、float、double、char、boolean八种数据类型。
String在Java中属于对象,底层实现是char数组,使用final修饰。
9、switch 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String 上?
在Java5以前,switch(expr)中的expr只能是byte、char、short、int四种数据类型。从Java5以后引入了枚举,expr可以是enum类型,Java7开始,expr就可以支持String字符串了,但是目前还不能使用long类型的。
10、java 中操作字符串都有哪些类?它们之间有什么区别?
Java中操作字符串的类有String、StringBuffer、StringBuilder三个类。
三者的相同点:
(1)都可以存储和操作字符串;
(2)底层都使用了final修饰,不能被继承。
(3)提供了API相似。
三者的区别:
(1)String是不可变字符序列,String内容是不能被改变的;
(2)StringBuffer和StringBuilder是可变字符序列,他们都可以对字符串内容进行修改,
并且修改之后的内存地址不会发生改变;
(3)StringBuilder是JDK1.5的,效率高,但是它的线程不安全,
StringBuffer是JDK1.0的,效率低,但是它是线程安全的(方法加了Synchronized)。
对于三者使用的总结
如果要操作少量的数据用 = String
单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
11、String str=”i”与 String str=new String(“i”)一样吗?
不一样,因为内存的分配方式不一样,String str = “i”的方式,Java虚拟机会将其分配到常量池中;而String str = new String(“i”) 则会被分配到堆内存中。
提问:String s = new String(“abc”)创建了几个对象呢?
答案是两个对象,一个是静态区的”abc”,另外一个是用new创建在堆上的对象。
1 | String str1 = "hello"; //str1指向静态区 |
13、如何将字符串反转?
使用StringBuffer或者StringBuilder中的reverse()方法。
1 | // StringBuffer reverse |
14、String 类的常用方法都有那些?
(1)String 类的常用方法都有那些?
(2)indexOf():返回指定字符的索引。
(3)charAt():返回指定索引处的字符。
(4)replace():字符串替换。
(5)trim():去除字符串两端空白。
(6)split():分割字符串,返回一个分割后的字符串数组。
(7)getBytes():返回字符串的 byte 类型数组。
(8)length():返回字符串长度。
(9)toLowerCase():将字符串转成小写字母。
(10)toUpperCase():将字符串转成大写字符。
(11)substring():截取字符串。
(12)equals():字符串比较。
15、HashMap中使用String做key有什么好处?
HashMap内部实现是通过key的hashcode来确定value的存储位置,因为字符串是不可变的,并且使用字符串时会在字符串常量池中进行缓存,所以当创建字符串的时候,hashcode会被缓存下来,不需要再次计算,所以相比于其他对象来说快一些。
16、抽象类必须要有抽象方法吗?
抽象类不一定要有抽象方法,但是抽象方法必要要有抽象类。
17、普通类和抽象类有哪些区别?
(1)抽象类不能被实例化;
(2)抽象类可以有抽象方法,但是普通类没有;
(3)含有抽象方法的类必须是抽象类;
(4)抽象方法不能被声明为静态;
(5)抽象方法不能被private;
(6)抽象方法不能被final修饰。
18、抽象类能使用 final 修饰吗?
不能,因为被final修饰的类不能被继承,而定义抽象类就是为了让其他类去继承的,如果使用final修饰了就矛盾了,因此不能被final修饰。
19、接口和抽象类有什么区别?
(1)实现:抽象类的子类使用extends来继承,而接口就必须使用implements来实现接口;
(2)构造函数:抽象类可以有构造函数,但是接口没有;
(3)实现数量:类可以实现很多个接口,但是只能继承一个抽象类;
(4)访问修饰符:接口的方法默认使用的是public修饰,而抽象类中的方法可以是任意访问修饰符;
20、内部类有哪几种?详细说明一下。
内部类的定义:可以将一个类的定义放在另外一个类的定义内部;
内部类的种类:成员内部类、局部内部类、匿名内部类、静态内部类。
(1)静态内部类:定义在类内部的静态类。
1 | public class Outer { |
静态内部类可以访问外部类所有的静态变量,而不可访问外部类的非静态变量;静态内部类的创建方式,new 外部类.静态内部类(),如下:
1 | Outer.StaticInner inner = new Outer.StaticInner(); |
(2)成员内部类:定义在类内部,成员位置上的非静态类。
1 | public class Outer { |
成员内部类可以访问外部类所有的变量和方法,包括静态和非静态,私有和公有。成员内部类依赖于外部类的实例,它的创建方式外部类实例.new 内部类(),如下:
1 | Outer outer = new Outer(); |
(3)局部内部类:定义在方法的内部,就是局部内部类。
1 | public class Outer { |
定义在实例方法中的局部类可以访问外部类的所有变量和方法,定义在静态方法中的局部类只能访问外部类的静态变量和方法。局部内部类的创建方式,在对应方法内,new 内部类(),如下:
1 | public static void testStaticFunctionClass(){ |
(4)匿名内部类:没有名字的内部类,日常开发中使用的比较多。
1 | public class Outer { |
除了没有名字,匿名内部类还有以下特点:
A、匿名内部类必须继承一个抽象类或者实现一个接口。
B、匿名内部类不能定义任何静态成员和静态方法。
C、当所在的方法的形参需要被匿名内部类使用时,必须声明为 final。
D、匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
1 | 匿名内部类创建方式: |
21、内部类有哪些使用场景?你在哪些地方使用到了内部类?
(1)在设计模式中使用静态内部类实现单例模式;
1 | public class SingletonDemo03 { |
(2)其他的忘记了,,,等记得来的时候再补上0.0
22、Files的常用方法都有哪些?
(1)Files. exists():检测文件路径是否存在。
(2)Files. createFile():创建文件。
(3)Files. createDirectory():创建文件夹。
(4)Files. delete():删除一个文件或目录。
(5)Files. copy():复制文件。
(6)Files. move():移动文件。
(7)Files. size():查看文件个数。
(8)Files. read():读取文件。
(9)Files. write():写入文件。
23、Date类常用方法都有哪些?
1 | -----日期类型如何格式化? |
24、java 中 IO 流分为几种?
(1)按照流向可以分为输入流和输出流;
(2)按照操作单元划分可以分为字节流和字符流;
(3)按照流的角色划分可分为节点流和处理流;
25、BIO、NIO、AIO 有什么区别?
简答:
BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
NIO:Non IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。
详细回答:
BIO (Blocking I/O): 同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。在活动连接数不是特别高(小于单机1000)的情况下,这种模型是比较不错的,可以让每一个连接专注于自己的 I/O 并且编程模型简单,也不用过多考虑系统的过载、限流等问题。线程池本身就是一个天然的漏斗,可以缓冲一些系统处理不了的连接或请求。但是,当面对十万甚至百万级连接的时候,传统的 BIO 模型是无能为力的。因此,我们需要一种更高效的 I/O 处理模型来应对更高的并发量。
NIO (New I/O): NIO是一种同步非阻塞的I/O模型,在Java 1.4 中引入了NIO框架,对应 java.nio 包,提供了 Channel , Selector,Buffer等抽象。NIO中的N可以理解为Non-blocking,不单纯是New。它支持面向缓冲的,基于通道的I/O操作方法。 NIO提供了与传统BIO模型中的 Socket 和 ServerSocket 相对应的 SocketChannel 和 ServerSocketChannel 两种不同的套接字通道实现,两种通道都支持阻塞和非阻塞两种模式。阻塞模式使用就像传统中的支持一样,比较简单,但是性能和可靠性都不好;非阻塞模式正好与之相反。对于低负载、低并发的应用程序,可以使用同步阻塞I/O来提升开发速率和更好的维护性;对于高负载、高并发的(网络)应用,应使用 NIO 的非阻塞模式来开发。
AIO (Asynchronous I/O): AIO 也就是 NIO 2。在 Java 7 中引入了 NIO 的改进版 NIO 2,它是异步非阻塞的IO模型。异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。AIO 是异步IO的缩写,虽然 NIO 在网络操作中,提供了非阻塞的方法,但是 NIO 的 IO 行为还是同步的。对于 NIO 来说,我们的业务线程是在 IO 操作准备好时,得到通知,接着就由这个线程自行进行 IO 操作,IO操作本身是同步的。