Java IO 模型深度解析
Java IO 模型深度解析一、同步阻塞 IO (BIO)1.1 核心概念⭐首先解释什么是同步和阻塞。同步,调用线程必须等到操作完成,才能继续执行;阻塞,当条件不满足时,调用线程会被操作系统挂起(sleep),不占用 CPU。 ⭐然后解释为什么是同步阻塞的。同步阻塞 API ServerSocket.accept()、Socket.read()、Socket.write(),而这些 API 是同步阻塞的是因为最终依赖操作系统的阻塞式系统调用(如 accept/read/write) 1.2 底层实现原理⭐并介绍具体是怎么调用到的,介绍 JDK8 的 ServerSocket.accept() 的底层实现原理。通过策略模式(Debug 可以发现在 Windows 下 ServerSocket 内部使用的是 DualStackPlainSocketImpl 至少Vista(支持 IPv4 和 IPv6 同时处理) 或者 TwoStacksPlainSocketImpl 低于Vista),组合持有一个 SocketImpl 抽象类对象来实现的。ServerSocke...
Java HashMap 深度解析
Java HashMap 深度解析一、数据结构1.1 JDK 7 vs JDK 8JDK 7 采用的是数组加链表,没有红黑树 JDK 8 采用的是数组加链表加红黑树,红黑树的引入是为了解决链表过长的问题,提高查询效率 1.2 红黑树转换条件红黑树的升级条件 当链表长度大于等于 8 且数组长度大于等于 64 时,会将链表转换为红黑树 红黑树的退化条件 当链表长度小于等于 6 时,会将红黑树转换为链表 1.3 Entry 结构HashMap 的主干是一个 Entry 数组,Entry 其实就是一个有着键值对的链表节点,其中有 next 节点的指针,用于 Hash 冲突时形成链表,hash 字段是为了后面不用重复计算 hash 值,扩容直接 & 存在的 二、初始化2.1 默认参数HashMap 可以设置初始容量和负载因子: 默认的初始容量 initialCapacity 是 16 默认的负载因子 loadFactor 大小为 0.75 2.2 惰性初始化和 ArrayList 一样,都是惰性初始化,等到实际要用了才会真正构建 table 数组。在第一次 p...
Java ArrayList 深度解析
Java ArrayList 深度解析一、底层原理1.1 ⭐初始化无参构造会将 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 复制给 elementData 数组,这个很有用,便于确保无参构成函数创建的实例在添加第一个元素时,最小的容量是默认大小 10 有参集合构造,有参数值构造如果传递集合的大小或者传递的参数值为 0,会将 EMPTY_ELEMENTDATA 赋值给 elementData 数组,优化创建 ArrayList 空实例时产生不必要的空数组,使得所有 ArrayList 空实例都指向同一个空数组。当然,如果传递的大小不为零,参数值不为零,那么还是会正常构造的 1.2 ⭐扩容机制扩容触发流程add 函数每次添加元素的时候都会调用 ensureCapacityInternal 函数保证容量足够,容量足够才会继续将元素添加到 elementData 数组中 扩容详细过程如果调用 ensureCapacityInternal 函数之后发现容量不够了才会执行扩容逻辑,首先还是调用 ensureCapacityInternal 函数,然后 ensureCa...
Java 新特性深度解析
Java 新特性深度解析一、Java 8 新特性1.1 Optional用于解决空指针异常,使代码更健壮 1.2 Stream 流提供了一种处理集合数据的新方式,支持链式操作和函数式编程,提高代码可读性和效率 1.3 Lambda 表达式允许将函数作为方法参数,或将代码视为数据,简化匿名内部类,使代码更简洁、可读性更强 二、Java 17 新特性2.1 ⭐Record 不可变数据模型核心特性简化POJO类,自动生成构造器、Getter、equals、hashCode、toString 适用场景Record 非常适合 DTO / VO / Query,不适合 JPA Entity 2.2 ⭐Sealed 限制继承范围核心特性精确控制哪些类可以继承/实现,提升类型安全性,提升类型安全性和代码可维护性 与 enum 的对比enum 适合表达简单、无状态的枚举值,而 sealed 类可以看作是 enum 在类型系统层面的升级,适合表达可穷举但具有不同行为和结构的业务状态 适用场景Sealed 非常适合”受控的策略模式(Closed Strategy Set...
Java 扩展知识深度解析
Java 扩展知识深度解析一、BigDecimal1.1 ⭐底层原理精度丢失问题Double 是因为转换为二进制数的时候发生了截断,所以会产生精度丢失,如果涉及到金融方面的操作,建议使用没有精度丢失的 BigDecimal 其实如果没有用好 BigDecimal 其实还是会产生精度丢失,比如在阿里巴巴开发规范中就提到了我们 BigDecimal 的构造函数中传入 Double 基本类型的数据时,会有精度缺失问题,正确的使用方法应该是传入 String 对象 BigDecimal 实现原理原理的话,主要是将原来的小数扩大为整数,其中 intCompact 存储扩大后的整数,scale 存储小数点后的位数,precision 存储值的有效位数,而不是使用浮点型的科学计数法 总结double 产生精度丢失的根本原因是它采用 IEEE 754 的二进制浮点数表示,很多十进制小数在二进制中无法精确表示,只能近似存储,因此在运算过程中会产生精度误差。 在金融等精度敏感场景中通常使用 BigDecimal,因为 BigDecimal 使用的是十进制定点数模型,通过将小数放大为整数进行计算,内部...