可能不全,但是是个人感觉比较重要的 Java 基础知识。
1. 面向对象三大特性
1.1 封装
封装就是将对象的部分属性私有化(private),使用公用(public)方法供外界访问修改。
1.2 继承
就是新类继承父类,Java 不支持多继承,而 C++ 支持,继承有三点需要注意:
- 子类拥有父类的所有属性和方法,包括私有属性和私有方法,但是父类中的私有属性和私有方法子类无法访问,只是拥有;
- 子类可以拥有自己的属性和方法;
- 子类可以用自己的方法实现父类的方法(方法重载)。
1.3 多态
多态是同一个行为具有多个不同表现形式或形态的能力。
Java 中实现多态有两种方式:
- 继承:多个子类对同一个方法重写
- 接口:多个接口实现类覆盖接口中的同一种方法
接口与抽象类
| 接口 | 抽象类 | |
|---|---|---|
| 方法 | 默认是public方法,方法在接口中不能有实现(Java 8 中可以有默认实现) | 可以有public、protected和default方法,可以有默认实现,但是为了防止被重写不能使用private方法 |
| 变量 | 只能有static和final变量 | 都可以 |
| 继承 | 一个类可以实现多个接口,但是一个接口可以扩展多个接口 | 一个类只能实现一个抽象类 |
| 设计思路 | 对行为的抽象,行为规范 | 对类的抽象,模板设计 |
2. 关键字
2.1 static
该关键字有两个作用:
- 为某特定数据类型或对象分配存储空间,与创建的类无关;
- 实现某个方法或属性与类而不是对象关联在一起,即在不创建对象的情况下就可以通过类来直接使用类的方法或属性。
可以修饰以下元素:
- 变量:静态变量属于类而不属于对象,该类所有的实现对象共享同一个静态变量;
- 方法:静态方法可以不通过对象而通过类直接调用,静态方法只能访问本类中的静态变量;
- 代码块:静态代码块只能定义在类定义下(方法外),在类被加载时执行;
- 内部类:一旦内部类使用static修饰,那么此时这个内部类就升级为顶级类,可以在外部类不创建对象的情况下直接创建对象;静态内部类不能访问任何外围类的非静态变量和方法;
- 导入包:静态导入包能够导入指定的包下的所有静态变量。
2.2 final
可以用于修饰变量、方法和类,分别表示变量不可变、方法不可覆盖、类不可被继承:
- 变量:如果是基本数据类型,则初始化后数值就不可再改变;如果是引用类型的变量,则初始化后不能再让他指向另一个对象,即引用不可变;
- 方法:使得继承类无法对其进行修改,类中所有的 private 方法都隐式地指定为私有方法;
- 类:使得类无法被继承,final 类中所有的成员方法都被隐式地指定为 final 方法。
3. == 与 equals
3.1 ==
==在基本数据类型中比较的是值,在引用数据类型中是比较两个对象的地址是否相同,即判断被比较的二者是否是同一个对象
3.2 equals()
- 当被比较的类没有重写
equals()方法时,该方法相当于用==比较两个对象; - 当被比较的类覆盖了
equals()方法时,一般是将其重写为比较被比较类型的值,相等即返回true。
4. I/O
4.1 I/O分类
Java I/O 都是由InputStream 、Reader、OutputStream、Writer这四个基类派生出来的,可以按照以下分类方法进行分类。
按操作方式分类:
按操作对象分类:
4.2 BIO、NIO、AIO
- 同步、异步:客户端在请求数据的过程中,能否做其他事情。
- 阻塞、非阻塞:客户端与服务端是否从头到尾始终都有一个持续连接,以至于占用了通道,不让其他客户端成功连接。
4.2.1 BIO(Blocking I/O)同步阻塞
客户端在请求数据的过程中保持一个连接,不能做其他事。
在这一个连接中,服务端也需要一个线程来维护这个连接,由于服务端对应多个客户端,因此在阻塞过程中服务端压力更大。而且在等待过程中客户端做不了其他事,所以等待过程中其本身的性能也没得到充分释放。
BIO 的问题可以通过线程池解决,在活动连接数较低的情况下这种模型编程简单,可以让每一个连接专注于自己的I/O,不用考虑系统过载、限流等问题。但是这种模型无法应对高并发情况。
4.2.2 NIO(Non-blocking/New I/O)同步非阻塞
客户端在请求数据的过程中,不用保持一个连接,不能做其他事情。
客户端发送一个请求,并建立一个连接,服务端接收到了。如果服务端没有数据,就告知客户端“没有数据”;如果有数据,则返回数据。客户端接到了服务端回复的“没有数据”就断开连接,过了一段时间后,客户端重新问服务端是否有数据。服务器重复以上步骤。
客户端反复建立连接询问,如果没有数据则断开连接。这个过程称为轮询。NIO用轮询代替了始终保持一个连接。
Java 1.4 中引入了 NIO 模型,对应java.nio包,他与 BIO 模型存在对应关系:
| NIO | BIO |
|---|---|
SocketChannel | Socket |
ServerSocketChannel | ServerSocket |
NIO 的操作方法是基于通道、面向缓冲的,能够应对高负载、高并发的情况。
NIO 有三个实体,缓冲区 Buffer、通道 Channel、多路复用器 Selector
- Buffer 是客户端存放服务端信息的一个容器,服务端如果把数据准备好了,就会通过Channel往Buffer里面传。
- Channel 是客户端与服务端之间的双工连接通道。所以在请求的过程中,客户端与服务端中间的Channel就在不停的执行“连接、询问、断开”的过程。直到数据准备好,再通过Channel传回来。
- Selector 是服务端选择 Channel 的一个复用器。Selector 有两个核心任务:监控数据是否准备好,应答Channel。具体说来,多个 Channel 反复轮询时,Selector 就看该 Channel 所需的数据是否准备好了;如果准备好了,则将数据通过 Channel 返回给该客户端的 Buffer,该客户端再进行后续其他操作;如果没准备好,则告诉Channel还需要继续轮询;多个 Channel 反复询问Selector,Selector 为这些 Channel 一一解答。
4.2.3 AIO(Asynchronous I/O)异步非阻塞
客户端在请求数据的过程中,不用保持一个连接,能做其他事情。
客户端向服务端请求数据。服务端若有,则返回数据;若无,则告诉客户端“没有数据”。客户端收到“没有数据”的回复后,就做自己的其他事情。服务端有了数据之后,就主动通知客户端,并把数据返回去。
但是,服务端需要主动通知客户端,关于“通知”的业务逻辑肯定是需要消耗资源的。客户端本来在做别的事情,突然前面的事情又插过来要做了,必然引入了一个多线程的协调工作。
AIO 目前的实际应用仍然较少。