一,java基础
1. JDK 和 JRE 有什么区别?
- JDK:Java Development Kit 的简称,java 开发工具包,提供了 java 的开发环境和运行环境。
- JRE:Java Runtime Environment 的简称,java 运行环境,为 java 的运行提供了所需环境
- JDK中包含JRE,JDK中有一个名为jre的目录,里面包含两个文件夹bin和lib,bin就是JVM,lib就是JVM工作所需要的类库。
2. == 和 equals 的区别是什么?
- 对于基本类型,==比较的是值;
- 对于引用类型,==比较的是地址;
- equals不能用于基本类型的比较;
- 如果没有重写equals,equals就相当于==;
- 如果重写了equals方法,equals比较的是对象的内容;
3、final 在 java 中有什么作用?
- 用来修饰一个引用
- 如果引用为基本数据类型,则该引用为常量,该值无法修改;
- 如果引用为引用数据类型,比如对象、数组,则该对象、数组本身可以修改,但指向该对象或数组的地址的引用不能修改。
- 如果引用时类的成员变量,则必须当场赋值,否则编译会报错。
- 用来修饰一个方法
- 当使用final修饰方法时,这个方法将成为最终方法,无法被子类重写。但是,该方法仍然可以被继承。
- 用来修饰类
- 当用final修改类时,该类成为最终类,无法被继承。
4、java 中的 Math.round(-1.5) 等于多少?
(1)ceil:向上取整;
System.out.println(Math.ceil(11.2));//12.0
System.out.println(Math.ceil(11.5));//12.0
System.out.println(Math.ceil(11.8));//12.0
System.out.println(Math.ceil(-11.2));//-11.0
System.out.println(Math.ceil(-11.5));//-11.0
System.out.println(Math.ceil(-11.8));//-11.0
(2)floor:向下取整;
System.out.println(Math.floor(11.2));//11
System.out.println(Math.floor(11.5));//11
System.out.println(Math.floor(11.8));//11
System.out.println(Math.floor(-11.2));//-12
System.out.println(Math.floor(-11.5));//-12
System.out.println(Math.floor(-11.8));//-12
(3)round:四舍五入;
加0.5然后向下取整。
System.out.println(Math.round(11.4));//11
System.out.println(Math.round(11.5));//12
System.out.println(Math.round(-11.3));//-11
System.out.println(Math.round(-11.5));//-11
System.out.println(Math.round(-11.8));//-12
5.java的八大基础类型
整型:int,long,short,byte
型:char
浮点型:float(单精度),double(双精度)
型:boolean
6.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的值相同但是地址值不同。
7、如何将字符串反转?
String as="abc def";
StringBuilder stringBuilder = new StringBuilder(as);
String string = stringBuilder.reverse().toString();
System.out.println(string);
-----------------------------------------------------------
编译结果为:
fed cba
Process finished with exit code 0
8.String中的长用方法有哪些?
length():获取字符串的长度
charAt(int index):获取指定位置的字符
indexOf(int ch):返回指定字符在此字符串第一次出现的索引
substring(int start):从指定位置开始截取字符,默认到末尾位置
equals(Object b):比较字符串的类容是否相同,区分大小写
toLowerCase():将字符串转换成小写
toUpperCase():将字符串转换为大写
concat():将字符串拼接起来
isEmpty():判断字符串为空
trim():去除字符串两端空白。
9.java中static的用法
用法1:修饰成员属性
说明:
给属性加了static关键字之后,对象就不再拥有该属性了,该属性会由类去管理,即多个对象只对应一个属性。
package com.example.a;
class Test{
public static String NAME = "Tony";
}
public class Demo {
public static void main(String[] args) {
System.out.println(Test.NAME);
}
}
用法2:修饰成员方法
说明:
方法本来就是存放在类的定义当中的。static修饰成员方法的作用是可以使用"类名.方法名"的方式操作方法,避免了先要new出对象的繁琐和资源消耗。
package com.example.a;
class Test{
public static void sayHello(String name) {
System.out.println("Hello," + name);
}
}
public class Demo {
public static void main(String[] args) {
Test.sayHello("Tony");
}
}
用法3:修饰代码块
static { }就是静态块,当类加载器载入类的时候,这一部分代码被执行,常用于对静态变量进行初始化工作。当其他代码用到这个类,类加载器才会将它载入。
代码只能执行一次,不能再调用。在静态块中,可以访问静态变量,调用静态方法。
如果去掉static,{ }中的代码则会在创建类对象的时候才执行,(相当于把这部分代码复制到各个构造函数中),这样可以实现块中的内容在多个构造函数中的复用。
package com.example.a;
class Test{
static {
System.out.println("This is static Block");
}
{
System.out.println("This is Block");
}
public Test(){
System.out.println("This is Test()");
}
public Test(String string){
System.out.println("This is Test(String string)");
}
}
public class Demo {
public static void main(String[] args) {
System.out.println("------------------------");
Test test1 = new Test();
System.out.println("------------------------");
Test test2 = new Test("Hello");
}
}
执行结果:
------------------------
This is static Block
This is Block
This is Test()
------------------------
This is Block
This is Test(String string)
10.普通类和抽象类有哪些区别?
- 抽象类不能被实例化;
- 抽象类可以有抽象方法,只需申明,无须实现;
- 有抽象方法的类一定是抽象类;
- 抽象类的子类必须实现抽象类中的所有抽象方法,否则子类仍然是抽象类;
- 抽象方法不能声明为静态、不能被static、final修饰。
11.接口和抽象类有什么区别?
(1)接口
接口使用interface修饰;
接口不能实例化;
类可以实现多个接口;
①java8之前,接口中的方法都是抽象方法,省略了public abstract。②java8之后;接口中可以定义静态方法,静态方法必须有方法体,普通方法没有方法体,需要被实现;
(2)抽象类
抽象类使用abstract修饰;
抽象类不能被实例化;
抽象类只能单继承;
抽象类中可以包含抽象方法和非抽象方法,非抽象方法需要有方法体;
如果一个类继承了抽象类,①如果实现了所有的抽象方法,子类可以不是抽象类;②如果没有实现所有的抽象方法,子类仍然是抽象类。
12.java 中 IO 流分为几种?
(1)按流划分,可以分为输入流和输出流;
(2)按单位划分,可以分为字节流和字符流;
字节流:inputStream、outputStream;
字符流:reader、writer;
13. BIO、NIO、AIO 有什么区别?
- BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
- NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
- AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。
14.Files的常用方法都有哪些?
exist
createFile
createDirectory
write
read
copy
size
delete
move
15.反射
反射的机制:java语言的一个重要的特性,允许程序在运行时获取自身信息,并可以动态的操作和修改类的行为。包括访问类的字段,方法,构造函数等信息,以及在运行时创建对象,调用方法,修改字段的的值等。
使用反射的例子:动态的创建对象是一个常见的例子,通过动态的获取目标类的Class对象,然后使用newInstance()方法来创建该类的实例。还可以动态加载类,调用方法和访问属性。
反射的应用场景:广泛的应用于框架和库中,如spring框架,ROM工具,插件系统,以及单元测试框架Junit等。
反射的弊端:
- 对封装造成一定的破坏:反射可以访问私有成员,导致封装性被破坏,违背了封装的设计原则。
- 绕过了泛型的类型检查:反射可以绕过泛型的检查,在运行时可能发生类型转换的错误。
- 可读性和维护性下降:滥用反射可能导致代码的可读性和维护性变差。
在使用反射的时需要注意的问题:
- 性能问题:反射相对于直接使用来说较慢,在性能要求高的场景下需要谨慎使用
- 安全问题:反射可以绕过访问控制,可能导致安全隐患
- 异常区里问题:由于反射是在运行时进行的可能会抛出NoSuchMethodException等异常。
16.什么是 java 序列化?什么情况下需要序列化?
序列化的核心目的是为了解决网络通信之间的一个对象传输问题,也就是说怎么样去哪当前Jvm进程里的一个对象跨网络传输到另外一个JVM进程中进行恢复。
序列化就是吧内存里面的对象转化为字节流以便用来实现存储和传输。
翻序列化就是根据从文件或者网络上获取到的对象的一个字节流,根据字节流里面保存的对象描述信息和状态重新构建一个新的对象。
序列化的前提是为了保证通信双方对于对象的一个可识别性,所以很多时候我们现将对象转化为通用的解析格式,然后再把他们转化为数据流进行网络传输从而去实现跨平台或者跨语言的这样一个可识别性
序列化是通过实现serializable接口,该接口没有需要实现的方法,implement Serializable只是为了标注该对象是可被序列化的,使用一个输出流(FileOutputStream)来构造一个ObjectOutputStream对象,接着使用ObjectOutputStream对象的writeObejct(Object object)方法就可以将参数的obj对象到磁盘,需要恢复的时候使用输入流。
如何实现序列化:实现Serializable接口,json序列化,xml序列化
17.throw 和 throws 的区别?
(1)throw
作用在方法内,表示抛出具体异常,由方法体内的语句处理;
一定抛出了异常;
(2)throws
作用在方法的声明上,表示抛出异常,由调用者来进行异常处理;
可能出现异常,不一定会发生异常;