BIO、NIO、IO多路复用
一、BIO
即Blocking IO,同步阻塞通信,每次有新的链接与服务端链接后,服务端链接的线程会阻塞住,一直到通信完后才进行其他线程。
二、NIO
即Non-Blocking IO,同步非阻塞通信,这是基于Selector和Epoll来实现的,Selector代替了线程本身轮询IO事件,避免了阻塞同时减少了不必要的线程消耗。

即Blocking IO,同步阻塞通信,每次有新的链接与服务端链接后,服务端链接的线程会阻塞住,一直到通信完后才进行其他线程。
即Non-Blocking IO,同步非阻塞通信,这是基于Selector和Epoll来实现的,Selector代替了线程本身轮询IO事件,避免了阻塞同时减少了不必要的线程消耗。

SPI(Service Provider Interface)是Java提供的一种服务发现机制。它定义了一套接口规范,允许第三方提供具体实现,并通过标准方式让框架在运行时自动发现和加载这些实现。
API:框架定义,别人调用,框架提供接口和实现,调用方直接使用。
SPI:框架定义,别人实现,框架只定义接口规范,实现由第三方提供,框架在运行时动态发现和加载这些实现。
本质区别:API关注如何使用,SPI关注如何扩展。
核心思想:接口与实现分离 + 运行时动态发现。
一、泛型(Generics)
使用类型参数(如 T, K, V)创建可复用、类型安全的代码组件。T、K、V这种来作为泛型字符,可以用在类、方法、对象上,通过最终使用的时候传入的对象类型来确定最终是什么。一般单个泛型用T(比如说List),多个用<K,V>(比如说Map)。
声明位置:
类:class Box<T> { } // 泛型类
方法:public <T> T get(T t) { } // 泛型方法
接口:interface List<T> { } // 泛型接口
HashMap扩容时会扩为2倍,此外,当创建 HashMap 并指定一个初始容量(比如 new HashMap(10))时,HashMap 内部会也自动将这个容量调整为大于等于指定值的最小2的幂。
扩容采用2的幂次是为了优化哈希计算效率。具体原理如下:
先计算当前key的hash值,当 HashMap 容量为16时,计算槽位的方式为 hash & (16-1),即 hash & 15。由于15的二进制只有最后4位是1(0000 1111),因此计算结果的有效部分仅为哈希值的最后4位,这4位就决定了键值对存放的槽位索引。
注解本质上是一个实现了annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。通过反射获取注解时,返回的是Java运行时生成的动态代理对象。
// 定义注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "default";
int count() default 0;
}
// 编译后:注解本质是一个接口,继承自Annotation
public interface MyAnnotation extends java.lang.annotation.Annotation {
String value();
int count();
}
public class SingleInstance {
//volatile防止JVM指令重排
private static volatile SingleInstance singleInstance;
private SingleInstance() {
}
public static SingleInstance getSingleInstance() {
if (singleInstance == null) {
synchronized (SingleInstance.class) {
//doubleCheck
if (singleInstance == null) {
singleInstance = new SingleInstance();
}
}
}
return singleInstance;
}
}