1.JDK和JRE有什么区别?
JDK:它是java开发运行环境,是程序员使用java语言编写java程序所需的开发工具包,是面向java程序的开发者。
JRE:它是java运行环境,包含了java虚拟机,java基础类库,是面向java程序的使用者。
包含关系:JDK包含JRE
2.== 和 equals 的区别是什么?
1. ==比较的是引用,比较的是引用的地址值 ,equals方法,是object中的方法,如果不进行重写的话,比较的也是引用的地址值,实际和==一样。
2. String类型:==比较的是内存地址,equals方法是已经重写过了,比较的是两个String对象对应的值。
3. 对于非String类(比如StringBuffer类)没有重写equals方法,所以不比较内容。==和equals都是比较的内存地址。
4. 对于基本数据类型:(byte,short,char,int,float,double,long,boolean),==和equals比较的是值,因为他们是作为常量在方法区中的常量池里面以HashSet策略存储起来的,在常量池中,一个常量只会对应一个地址。
3.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
答案肯定是不一定。同时反过来equals为true,hashCode也不一定相同。类的hashCode方法和equals方法都可以重写,返回的值完全在于自己定义。
关于hashCode和equals是方法是有一些常规协定 :
1. 两个对象用equals()比较返回true,那么两个对象的hashCode()方法必须返回相同的结果。
2. 两个对象用equals()比较返回false,不要求hashCode()方法也一定返回不同的值,但是最好返回不同值,以提高哈希表性能。
3. 重写equals()方法,必须重写hashCode()方法,以保证equals方法相等时两个对象hashcode返回相同的值。
4.final 在 java 中有什么作用?
final作为Java中的关键字可以用于三个地方。用于修饰类、类属性和类方法。
特征:凡是引用final关键字的地方皆不可修改!
1. 修饰类:表示该类不能被继承。
2. 修饰方法:表示方法不能被重写。
3. 修饰变量:表示变量只能一次赋值以后值不能被修改(常量)。
5.java 中的 Math.round(-1.5) 等于多少?
Math.round(-1.5)的返回值是-1。四舍五入的原理是在参数上加0.5然后做向下取整。
6.String 属于基础的数据类型吗?
String不是基本的数据类型,是final修饰的java类,java中的基本类型一共有8个,它们分别为:
1. 字符类型:byte,char
2. 基本整型:short,int,long
3. 浮点型:float,double
4. 布尔类型:boolean
7.java 中操作字符串都有哪些类?它们之间有什么区别?
String、StringBuffer、StringBuilder
1. String : final修饰,String类的方法都是返回new String。即对String对象的任何改变都不影响到原对象,对字符串的修改操作都会生成新的对象。
2. StringBuffer : 对字符串的操作的方法都加了synchronized,保证线程安全。
3. StringBuilder : 不保证线程安全,在方法体内需要进行字符串的修改操作,可以new StringBuilder对象,调用StringBuilder对象的append、replace、delete等方法修改字符串。
4. 在性能方面,由于 String 类的操作都是产生新的 String 对象,而 StringBuilder 和 StringBuffer 只是一个字符数组的再扩容而已,所以 String 类的操作要远慢于 StringBuffer 和 StringBuilder。
8.String str="i"与 String str=new String(“i”)一样吗?
不一样
因为内存的分配方式不一样。String str="i"的方式,Java 虚拟机会将其分配到常量池中;而 String str=new String(“i”)方式,则会被分到堆内存中。
9.如何将字符串反转?
1. 利用 StringBuffer 或 StringBuilder 的 reverse 成员方法。
2. 利用 String 的 toCharArray 方法先将字符串转化为 char 类型数组,然后将各个字符进行重新拼接。
// toCharArray
public static String reverse(String str) {
char[] chars = str.toCharArray();
String reverse = "";
for (int i = chars.length - 1; i >= 0; i--) {
reverse += chars[i];
}
return reverse;
}
3. 利用 String 的 CharAt 方法取出字符串中的各个字符。
// charAt
public static String reverse(String str) {
String reverse = "";
int length = str.length();
for (int i = 0; i < length; i++) {
reverse = str.charAt(i) + reverse;
}
return reverse;
}
10.String 类的常用方法都有那些?
1. 和长度有关:
返回类型 | 方法名 | 作用 |
int | length() | 得到一个字符串的字符个数 |
2、和数组有关:
返回类型 | 方法名 | 作用 |
byte[] | getByte() | 将一个字符串转换成字节数组 |
char[] | toCharArray() | 将一个字符串转换成字符数组 |
String | split(String) | 将一个字符串按照指定内容劈开 |
3、和判断有关:
返回类型 | 方法名 | 作用 |
boolean | equals() | 判断两个字符串的内容是否一样 |
boolean | equalsIsIgnoreCase(String) | 忽略太小写的比较两个字符串的内容是否一样 |
boolean | contains(String) | 判断一个字符串里面是否包含指定的内容 |
boolean | startsWith(String) | 判断一个字符串是否以指定的内容开头 |
boolean | endsWith(String) | 判断一个字符串是否以指定的内容结尾 |
4、和改变内容有关:
返回类型 | 方法名 | 作用 |
String | toUpperCase() | 将一个字符串全部转换成大写 |
String | toLowerCase() | 将一个字符串全部转换成小写 |
String | replace(String,String) | 将某个内容全部替换成指定内容 |
String | replaceAll(String,String) | 将某个内容全部替换成指定内容,支持正则 |
String | repalceFirst(String,String) | 将第一次出现的某个内容替换成指定的内容 |
String | substring(int) | 从指定下标开始一直截取到字符串的最后 |
String | substring(int,int) | 从下标x截取到下标y-1对应的元素 |
String | trim() | 去除一个字符串的前后空格 |
5、和位置有关:
返回类型 | 方法名 | 作用 |
char | charAt(int) | 得到指定下标位置对应的字符 |
int | indexOf(String) | 得到指定内容第一次出现的下标 |
int | lastIndexOf(String) | 得到指定内容最后一次出现的下标 |
11.抽象类必须要有抽象方法吗?
抽象类不一定有抽象方法;但是包含一个抽象方法的类一定是抽象类。
12.普通类和抽象类有哪些区别?
1. 抽象类不能被实例化。
2. 抽象类可以有抽象方法,抽象方法只需申明,无需实现。
3. 含有抽象方法的类必须申明为抽象类。
4. 抽象的子类必须实现抽象类中所有抽象方法,否则这个子类也是抽象类。
5. 抽象方法不能被声明为静态。
6. 抽象方法不能用private修饰。
7. 抽象方法不能用final修饰。
13.抽象类能使用 final 修饰吗?
不能,抽象类就是要子类继承然后实现内部方法的。但是final修饰的类是不能再被继承和修改的。所以不能用final修饰。
14.接口和抽象类有什么区别?
1. 实现不一样,抽象类的子类是使用extends关键字继承,接口是使用implements关键字实现的。
2. 构造函数不一样,抽象类是具有构造函数的,接口没有。
3. main方法,抽象类是可以有main方法的且可以运行,接口不可以有。
4. 实现的数量不一样,类是可以实现多个接口的,但是只能继承一个类。
5. 修饰符不一样,接口中的方法默认使用的是public修饰,而抽象类是任意访问修饰符。
15.java 中 IO 流分为几种?
1. 按照流的流向分,可以分为输入流和输出流。
2. 按照操作单元划分,可以划分为字节流和字符流。
3. 按照流的角色划分为节点流和处理流。
16.BIO、NIO、AIO 有什么区别?
1. BIO (Blocking I/O): 同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。在活动连接数不是特别高(小于单机1000)的情况下,这种模型是比较不错的,可以让每一个连接专注于自己的 I/O 并且编程模型简单,也不用过多考虑系统的过载、限流等问题。线程池本身就是一个天然的漏斗,可以缓冲一些系统处理不了的连接或请求。但是,当面对十万甚至百万级连接的时候,传统的 BIO 模型是无能为力的。因此,我们需要一种更高效的 I/O 处理模型来应对更高的并发量。
2. 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 的非阻塞模式来开发。
3. 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的常用方法都有哪些?
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() 写入文件。