Java 基础模块自答

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/HardToFindName/article/details/102562935

一. Java 基础模块

1.JDK 和 JRE 有什么区别?

答:jdk时java开发工具集,其包含编译器javac、运行时环境jre,java试调工具和分析工具如:jconsole,
jre时java运行时环境,其包含java虚拟机、java基础类库,所以jre是jdk的一部分

如果只是需要运行java程序只要安装jre便可,如果是开发人员则需要安装jdk

2.== 和 equals 的区别是什么?

答:和equals都是用来进行比较操作的,前者是操作符,后者是方法,如果比较的双方是基本数据类型,使用操作符,
比较的是双方表面上的值,如果双方是引用类型,比较的是对象的地址,在没有重写equals方法的前提下,因为所有类默认都继承
Object类,都继承了Object的equals方法,其equals方法中使用的是==操作符进行比较,故他们比较的也是对象的地址。像String类
其重写了equals方法,比较的是两个String对象的值,需要注意的是,再重写了equals方法后,需要重写hashcode。

3.两个对象的 hashCode() 相同,则 equals() 也一定为 true,对吗?

答:这个是不一定的,根据java的规范,其中两条说明:
1、若重写equals方法,则必须重写hashcode方法以确保在equals返回true时,两个对象的的hashcode具有相同的返回值
2、若equals方法返回false,即两个对象”不相同“,并不要求这两个对象的hashcode返回不相等的值。

简单来说就是两个对象使用equals进行判断是否相同时,返回true则要求他们的hashcode方法返回的值也要相等,如果equals
返回false,不要求他们的hashcode方法返回值不同。

上面根据规范来只会成立equals为true,hashcode相同,但是hashcode相同equals并不为true。

hashcode是根据对象的内存地址计算返回的一个int数,并不代表对象的内存地址,就像hash取模运算那样,地址为一个数,
不同的地址hash取模后的值是可以相同的。

只是根据规范去编写有助于提高hashmap和hashset的性能

4.final 在 Java 中有什么作用?

答:final可以用于修饰类、方法和变量,被其修饰的类不能够被继承,被其修饰的方法不能被重写,被其修饰的变量赋值后不能够进行更改

5.Java 中的 Math. round(-1. 5) 等于多少?

答:等于-1,Math. round()方法是根据传入的值+0.5后向下取整,-1.5+0.5=-1.0,所以为-1
若是Math. round(-1. 7),-1.7+0.5=-1.2,向下取整,为-2,这里的向下取整是取最小的,-2比-1小,取-2

6.String 属于基础的数据类型吗?

答:不属于,String是引用数据类型,其内部使用一个被final修饰的char数组保存String的值,这就说明了String对象一旦创建,其
值是不可变的。内存中有两个地方保存String对象,堆和字符串常量池,有意思的是根据创建String对象的方式不同,返回给引用的
内存地址所在的区域是不同的,若使用""直接创建,返回时的字符串常量池所在的内存区域的地址,若使用new String(“xxx”);
的形式返回的时堆所在内存区域的地址。更有意思的是,在创建时,”“方式会先在字符串常量池中寻找是否有相同值的对象,若有,
直接返回该对象的地址,没有则先创建再返回创建后的对象的地址,new String(“xxx”);方式也会在字符串常量池中寻找是否有相同
值的对象,若有则直接在堆中创建对象,返回堆中对象的地址,若没有则先在池中创建对象,再到堆中创建对象,返回堆中的对象的
地址。

7.Java 中操作字符串都有哪些类?它们之间有什么区别?

答:有String、StringBuilder、StringBuffer。
String对象的值是不可修改的,为String引用重新赋值意味着创建了一个新的String对象,
StringBuilder和StringBuffer对象的值是可修改的,两者的方法大致一样,但是StringBuilder的方法不是线程同步的,
而StringBuffer的方法是线程同步的。

8.String str="i"与 String str=new String(“i”)一样吗?

答:在表面上,他们都创建了一个值为”i“的字符串,但是在创建的过程是不一样的,并且是两个不相同的对象。创建时,”“方式会先在字符串常量池中寻找是否有相同值的对象,若有,
直接返回该对象的地址,没有则先创建再返回创建后的对象的地址,new String(“xxx”);方式也会在字符串常量池中寻找是否有相同
值的对象,若有则直接在堆中创建对象,返回堆中对象的地址,若没有则先在池中创建对象,再到堆中创建对象,返回堆中的对象的
地址。

9.如何将字符串反转?

答:可以使用jdk自有的类中方法,如StringBuffer类的reverse()方法,或是自己重写,代码如下:

pubilc String reverse(String str){
	int len = str.length();
	StringBuffer string = new StringBuffer("");
	for(int i = len - 1;i >= 0;i--){
		string.append(str.charAt(i));
	}
	return string.toString();
}

10.String 类的常用方法都有那些?

答:有split(String regex) 根据指定字符串拆分字符串,
subString(…) 返回一个子串,
replace(…) 替换字符串中的字符,
length() 返回字符串长度,
charAt(…) 根据下标返回字符串中的字符,
valueOf(…) 将参数值转换为字符串,
trim() 剔除字符串前后空格后返回字符串的副本,
stratWith(…) 判断字符串前缀是否与参数相等
endWith(…) 判断字符串后缀是否与参数相等
equals() 判断两个字符串值是否相等
toLowerCase() 字符串转换为小写
toUpperCase() 字符串转换为大写
concat() 连接字符串

11.抽象类必须要有抽象方法吗?

答:非必须,但是含有抽象方法的类一定是抽象类,但含有抽象方法的可以是抽象类也可以是接口

12.普通类和抽象类有哪些区别?

答:普通类没有被abstract修饰,抽象类被abstract修饰
普通类不能含有抽象方法,抽象类可以含有抽象方法
普通类可以被实例化,抽象类不可以被实例化
普通子类继承普通父类时可以不重写父类的方法,普通子类继承抽象类必须实现其所有抽象方法,否则该子类要定义为抽象类
普通类的方法拥有任意的访问权限,但是抽象类的抽象方法的访问权限仅限于public和protected

13.抽象类能使用 final 修饰吗?

答:不能,被final修饰的类不能够被继承,而被abstract修饰的类需要被子类继承重写其抽象方法才能够使用其方法,方能
体现其存在的价值,两者的存在意义相互矛盾,无法相容,不能够同时修饰同一个类,若同时修饰,编译将无法通过。

14.接口和抽象类有什么区别?

答:jdk1.7中:
接口使用interface进行定义,抽象类使用abstract定义
接口只能含有抽象方法,抽象类中可以有抽象方法和普通方法
接口没有构造方法,抽象类有构造方法
接口中声明的变量都是静态常量,抽象类中的变量可以时任意类型
实现类使用implements声明实现接口,普通子类使用extends声明继承抽象类,两者都需要重写抽象方法
接口是多继承的,抽象类只能单继承
接口中方法的访问权限默认是public且仅为public,抽象类拥有所有的访问权限,但是抽象方法仅有public和protected
(在jdk1.8前,接口中只能含有抽象方法,jdk1.8后,接口允许含有一个非抽象方法,
且访问修饰符为default)

15.Java 中 IO 流分为几种?

答:有三种,BIO、NIO和AIO

16.BIO、NIO、AIO 有什么区别?

答:

  • BIO同步阻塞IO,其特点是一个连接一个线程,读写操作会产生阻塞,由于每当一个客户连接进服务端都会产生一个线程进行处理,在高并发场景下很容易因为线程过多导致系统崩溃。解决的办法是使用连接池去限制线程的数量,但是这样无法解决因为连接过多导致响应变慢的问题

  • NIO同步非阻塞IO,其特点是一个请求一个线程,其内部会将连接到服务端的连接注册到多路复用器上,同步过程中使用轮询的方式查看多路复用器中连接的状态,根据具体状态进行处理操作,这样一下便解决了BIO中开启线程过多的问题并一定程度缓解了响应速度慢的问题,但是如果处理操作中含有阻塞操作,如jdbc操作,很快会出现BIO同样的问题。解决办法是使用队列或资源池,将需要操作的数据以传参的形式放入队列或资源池立即得到返回结果,而阻塞操作对队列或资源池进行消费即可,这样变对操作进行了异步化,从而提升了响应速度。

  • AIO异步非阻塞IO,其特点是一个有效请求一个线程,读写操作不会发生阻塞,在应用读写读写数据前,系统OS会先对数据进行缓冲,当缓冲完成后会告知应用去读写,而应用程序只需要调用api的read和write的方法,方法会返回一个带回调函数的对象,当读取或写入操作完成后,直接调用回调函数。其充分使用了OS参与并发,性能要比BIO和NIO要好。

    应用场景:
    BIO:适用于连接数较小且固定的架构,这种方式对服务器的资源要求较高,并发局限于应用中,jdk1.4前的唯一选择,但是 优点程序简单直观易于理解。
    NIO:适用于连接数多且连接时长短的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,jdk1.4开始支持。
    AIO:适用于连接数多且连接时长较长的架构,比如相册服务器,充分调用os参与并发操作,编程比较复杂,jdk1.7开始支持,也称为NIO2.0。

17.Files的常用方法都有哪些?

答:exists()检测文件路径是否存在
createNewFile()创建文件
mkdirs()创建文件夹
read()读取文件
write()写入文件
isFile()检测是否是文件
isDirectory()检查是否是目录
getName()获取文件名
getPath()获取相对路径
list()列出路径下所有目录和文件名
listFiles()列出路径下所有目录和文件对象

猜你喜欢

转载自blog.csdn.net/HardToFindName/article/details/102562935