一、Java 基础
1.JDK 和 JRE 有什么区别?
JDK:开发工具;
JRE:运行环境;
JVM:虚拟机;
2.== 和 equals 的区别是什么?
==:比较存储地址;
equals:比较值;
3.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
不一定;因为是hash的存储方式,code一致,值不一定相同;值相同,code也不一定相同;
4.final 在 java 中有什么作用?
-
final在java中是修饰符关键字
-
修饰类:表示类不可以被继承
-
修饰方法:表示方法不可被子类覆盖,但是可以重载
-
修饰变量:表示变量一旦被赋值就不可以改变它的值
如果修饰成员变量:在声明的时候就要赋值 或者静态代码块赋值
如果修饰局部变量:局部变量必须程序员显示初始化,使用之前必须赋值。
如果修饰的是基本数据类型:一旦初始化之后就不能更改
如果是引用类型变量:对其初始化之后便不能再让其指向另一个对象,但是引用的值是可以改变的。
5.java 中的 Math.round(-1.5) 等于多少?
加0.5再计算,-1;
6.String 属于基础的数据类型吗?
不是,是引用类;基础的只有byte,short,int,long,float,double,Boolean,char;
7.java 中操作字符串都有哪些类?它们之间有什么区别?
String、StringBuffer、StringBuilder
String : final修饰,String类的方法都是返回new String。即对String对象的任何改变都不影响到原对象,对字符串的修改操作都会生成新的对象。
StringBuffer : 对字符串的操作的方法都加了同步锁(synchronized),保证线程安全。
StringBuilder : 不保证线程安全,在方法体内需要进行字符串的修改操作,可以new StringBuilder对象,调用StringBuilder对象的append、replace、delete等方法修改字符串。
效率:
StringBuilder > StringBuffer > String
8.String str="i"与 String str=new String(“i”)一样吗?
不一样
因为内存的分配方式不一样。String str="i"的方式,Java 虚拟机会将其分配到常量池中;而 String str=new String(“i”)方式,则会被分到堆内存中。
解释: Java 虚拟机会将其分配到常量池中:常量池不会重复创建对象。 在String str1="i"中,把i值存在常量池,地址赋给str1。假设再写一个String str2=“i”,则会把i的地址赋给str2,但是i对象不会重新创建,他们引用的是同一个地址值,共享同一个i内存。
分到堆内存中:堆内存会创建新的对象。 假设再写一个String str3=new String(“i”),则会创建一个新的i对象,然后将新对象的地址值赋给str3。虽然str3和str1的值相同但是地址值不同。
9.如何将字符串反转?
使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。
public static String reverse4(String s) {
return new StringBuilder(s).reverse().toString();
}
10.String 类的常用方法都有那些?
(1).indexOf():返回指定字符的索引。
(2).charAt():返回指定索引处的字符。
(3).replace():字符串替换。
(4).trim():去除字符串两端空白。
(5).split():分割字符串,返回一个分割后的字符串数组。
(6).getBytes():返回字符串的 byte 类型数组。
(7).length():返回字符串长度。
(8).toLowerCase():将字符串转成小写字母。
(9).toUpperCase():将字符串转成大写字符。
(10).substring():截取字符串。
(11).equals():字符串比较。
11.抽象类必须要有抽象方法吗?
抽象类可以没有抽象方法,但是如果你的一个类已经声明成了抽象类,即使这个类中没有抽象方法,它也不能再实例化,即不能直接构造一个该类的对象。
如果一个类中有了一个抽象方法,那么这个类必须声明为抽象类,否则编译通不过。
12.普通类和抽象类有哪些区别?
普通类不能包含抽象方法,抽象类可以包含抽象方法。 抽象类不能直接实例化,普通类可以直接实例化。
抽象类的特点:
-
1.抽象类不能被实例化
-
2.抽象类可以有抽象方法,抽象方法只需申明,无需实现
-
3.含有抽象方法的类必须申明为抽象类
-
4.如果没有实现抽象基类中所有的抽象方法,则子类成为一个抽象子类;如果实现抽象类中所有抽象方法,他就是非抽象子类;
-
5.抽象方法不能被声明为静态static
-
6.抽象方法不能用private修饰
-
7.抽象方法不能用final修饰
13.抽象类能使用 final 修饰吗?
不能,抽象类是被用于继承的,而用final修饰的类,无法被继承。
14.接口和抽象类有什么区别?
他们都不能实例化对象,都可以包含抽象方法,而且抽象方法必须被继承的类全部实现。
区别:
1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
2、抽象类要被子类继承,接口要被类实现。
3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现
4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
6、抽象方法只能申明,不能实现,接口是设计的结果 ,抽象类是重构的结果
7、抽象类里可以没有抽象方法
8、如果一个类里有抽象方法,那么这个类只能是抽象类
9、抽象方法要被实现,所以不能是静态的,也不能是私有的。
10、接口可继承接口,并可多继承接口,但类只能单根继承。
接口的设计目的,是对类的行为进行约束(更准确的说是一种“有”约束,因为接口不能规定类不可以有什么行为),也就是提供一种机制,可以强制要求不同的类具有相同的行为。它只约束了行为的有无,但不对如何实现行为进行限制。对“接口为何是约束”的理解,我觉得配合泛型食用效果更佳。
而抽象类的设计目的,是代码复用。当不同的类具有某些相同的行为(记为行为集合A),且其中一部分行为的实现方式一致时(A的非真子集,记为B),可以让这些类都派生于一个抽象类。在这个抽象类中实现了B,避免让所有的子类来实现B,这就达到了代码复用的目的。而A减B的部分,留给各个子类自己实现。正是因为A-B在这里没有实现,所以抽象类不允许实例化出来(否则当调用到A-B时,无法执行)。
15.java 中 IO 流分为几种?
- 按照流的流向分,可以分为输入流和输出流;
- 按照操作单元划分,可以划分为字节流和字符流;
- 按照流的角色划分为节点流和处理流。
- https://blog.csdn.net/weixin_43643277/article/details/96282707
16.BIO、NIO、AIO 有什么区别?
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操作本身是同步的。查阅网上相关资料,我发现就目前来说 AIO 的应用还不是很广泛,Netty 之前也尝试使用过 AIO,不过又放弃了。
17.Files的常用方法都有哪些?
Files. exists():检测文件路径是否存在。
Files. createFile():创建文件。
Files. createDirectory():创建文件夹。
Files. delete():删除一个文件或目录。
Files. copy():复制文件。
Files. move():移动文件。
Files. size():查看文件个数。
Files. read():读取文件。
Files. write():写入文件。