来自 gpt 的摘要:
JVM 主要组成部分和作用
类加载器(ClassLoader)
运行时数据区(Runtime Data Area)
执行引擎(Execution Engine)
本地库接口(Native Interface)(JNI、native)

来自 gpt 的摘要:
类加载器(ClassLoader)
运行时数据区(Runtime Data Area)
执行引擎(Execution Engine)
本地库接口(Native Interface)(JNI、native)

本文依据 JDK8 源码进行编写
关于 native 修饰的方法不进行内部剖析
只对核心方法进行剖析
什么是 native 方法?官方给的说明是"A native method is a Java method whose implementation is provided by non-java code." 通俗的说,native 表示该方法的实现 java 本身并没有完成,而是有 c/c++来完成,放在.dll 动态库文件中。
来自 gpt 的摘要: 这篇文章介绍了AOP(面向切面编程)的概念、术语、实现方式及应用场景。AOP旨在将横切关注点(如日志、事务、权限等)从业务逻辑中分离,实现代码解耦和复用。核心术语包括切面(Aspect)、连接点(JoinPoint)、通知(Advice)、切点(Pointcut)和织入(Weaving)。AOP常通过Spring AOP的动态代理或AspectJ的字节码操作来实现。Spring AOP适合简单场景,基于代理技术,而AspectJ性能更高,适用于复杂情况。AOP广泛用于日志记录、性能统计、事务管理、权限控制、接口限流和缓存管理等领域。
来自 gpt 的摘要: 这篇文章系统介绍了Linux操作系统中与目录、文件、用户管理、系统状态和网络通信相关的常用命令及其用法。内容涵盖目录切换与操作、文件的创建、查看、修改与删除,以及文件压缩与传输。文章还涉及权限管理、用户和用户组的增删改、服务管理及进程控制。同时,它讲解了系统资源监控、内存与磁盘使用查看、网络连接测试等实用工具。整体内容侧重于命令的功能说明与实际示例,适用于初学者熟悉Linux日常操作和管理任务。
cd usr:切换到该目录下 usr 目录
cd ..(或cd../):切换到上一层目录
cd /:切换到系统根目录
cd ~:切换到用户主目录
cd -: 切换到上一个操作所在目录
来自 gpt 的摘要: 这篇文章解释了TCP协议中的三次握手和四次挥手,分别用于建立和断开可靠连接。三次握手确保客户端和服务端的收发能力正常,并通过同步序列号避免旧连接干扰。两次握手不足以防止历史连接的误触发,而四次握手则显得冗余。四次挥手则体现了TCP的全双工特性,允许双方独立决定何时结束数据传输,从而确保断开过程的完整性和安全性。
建立一个 TCP 连接需要“三次握手”,缺一不可:
一次握手:客户端发送带有 SYN(SEQ = x)标志的数据包 -> 服务端,然后客户端进入 SYN_SEND 状态,等待服务端的确认;
二次握手:服务端发送带有 SYN + ACK(SEQ = y,ACK = x + 1) 标志的数据包 –> 客户端,然后服务端进入 SYN_RECV 状态;
三次握手:客户端发送带有 ACK(ACK = y + 1) 标志的数据包 –> 服务端,然后客户端和服务端都进入ESTABLISHED 状态,完成 TCP 三次握手。
来自 gpt 的摘要: B+树是一种优化过的多路搜索树,常用于数据库系统。与 B 树类似,但在结构和性能上有所改进。B+树的叶子节点存储所有关键字和指向具体数据的指针,并按关键字大小有序链接,方便顺序遍历。非叶子节点仅作为索引部分,包含子树中的最大或最小关键字,用于加速查询。非叶子节点的关键字数量与其子节点的数量一致,这种结构使 B+树更紧凑,并提高缓存命中率。 B+树的底层是多路平衡查找树,在查询时自根节点开始,直至叶子节点找到目标键值。若索引不包含完整数据,可能需要回表查询。这种结构减少了树的高度,提高了查询效率。 MySQL 采用 B+树作为索引的核心数据结构,主要是因为它减少了 I/O 操作,并且查询更加稳定。B+树的中间节点仅存储索引,数据都保存在叶子节点,这使得树的层数较低,磁盘页能够容纳更多节点元素,从而减少磁盘 I/O。此外,B+树的叶子节点相互链接,方便区间查询,只需遍历链表即可快速找到范围内的数据。 B+树与 B 树的主要区别在于数据存储位置和查询方式。B+树的实际数据仅保存在叶子节点,所有索引都在叶子节点中出现,并且叶子节点之间构成有序链表。而 B 树的非叶子节点既存储索引也可能存储数据,这导致其查询路径不如 B+树一致。B+树的结构使得范围查询和批量读取更加高效,因此更适合数据库场景。
来自 gpt 的摘要: MySQL 提供了四种隔离级别,用于控制并发事务之间的数据可见性:READ-UNCOMMITTED 允许读取未提交的变更,可能导致脏读、不可重复读和幻读;READ-COMMITTED 仅能读取已提交的数据,避免脏读,但仍无法避免不可重复读和幻读;REPEATABLE-READ 确保同一事务中的多次读取结果一致,防止脏读和不可重复读,但幻读仍可能发生;SERIALIZABLE 是最高级别的隔离,所有事务串行执行,完全避免脏读、不可重复读和幻读,但性能较低。MySQL 默认采用 REPEATABLE-READ,在大多数情况下可以避免幻读,无需使用性能开销更大的串行化隔离级别。 这些隔离级别的实现依赖于 锁机制 和 MVCC(多版本并发控制)。高隔离级别如 SERIALIZABLE 主要依靠锁来控制并发,而 READ-COMMITTED 和 REPEATABLE-READ 通过 MVCC 实现。此外,REPEATABLE-READ 在当前读情况下需要使用锁来避免幻读。 MySQL 的事务确保数据库操作构成一个逻辑整体,符合 ACID 特性:原子性 保证事务内的操作不可分割;一致性 确保数据在事务前后保持一致;隔离性 使并发事务互不干扰;持久性 确保已提交的事务在故障后仍然有效。InnoDB 存储引擎通过 redo log 实现持久性,undo log 确保原子性,MVCC 和锁机制 实现隔离性,而一致性依赖其他三者的共同保障。
来自 gpt 的摘要: HashMap 是一种基于数组和链表(或红黑树)的数据结构,用于存储键值对。在插入元素时,通过键的 hashCode() 方法计算哈希值,并经过扰动函数确定元素在数组中的位置。Java 8 之前,HashMap 通过链表解决哈希碰撞问题,而在 Java 8 之后,当链表长度超过 8 时,链表会转换为红黑树,以提升效率。当 HashMap 的元素数量达到其容量的 75% 时,触发扩容,容量通常增加为原来的两倍。 HashMap 和 HashSet 的主要区别在于前者存储键值对,而后者仅存储对象。HashSet 的底层依赖于 HashMap,通过 HashMap 的键来存储对象。相比之下,HashMap 是非线程安全的,而 Hashtable 是线程安全的,但性能较低。此外,HashMap 允许 null 键和值,而 Hashtable 不允许。 HashMap 在多线程环境下可能不安全,尤其在插入和扩容操作时,可能导致数据不一致或死循环。要解决这个问题,可以使用 ConcurrentHashMap,它通过细粒度锁和 CAS(Compare-And-Swap)机制保证并发环境下的安全性。
来自 gpt 的摘要: TCP(Transmission Control Protocol)是传输层协议,提供可靠、面向连接的数据传输,适用于网页浏览、电子邮件等需要稳定传输的应用。它通过流量控制和拥塞控制等机制,保证数据传输过程中的完整性和顺序性。UDP(User Datagram Protocol)则是一种无连接、不可靠的传输协议,传输速度快,但可能丢包,适用于对实时性要求高的应用,如视频通话和直播。 TCP 和 UDP 的主要区别在于:TCP 是面向连接的,提供可靠的传输,保证数据不丢失、按序到达,同时需要维持状态,因此传输效率较低。UDP 不需要建立连接,也不保证数据的完整性,但传输效率更高。此外,TCP 是面向字节流的,UDP 是面向报文的,TCP 的首部开销大于 UDP,并且 TCP 只支持点对点通信,而 UDP 支持多种通信模式。 在应用选择上,TCP 适合文件传输、邮件等对传输准确性要求高的场景,而 UDP 更适合语音、视频等对实时性要求高的场景。运行在 TCP 协议上的应用包括 HTTP(3.0 之前)、HTTPS、FTP、SMTP、POP3/IMAP、Telnet、SSH 等;运行在 UDP 协议上的应用包括 HTTP/3.0、DHCP 和 DNS 等。
来自 gpt 的摘要: 线程池是管理线程的资源池,主要作用在于通过重复利用已创建的线程降低资源消耗、提高响应速度、以及管理线程的使用和分配。常见的线程池参数包括核心线程数、最大线程数、任务队列、线程存活时间等。线程池在任务执行时,首先创建核心线程处理任务,当任务量超过核心线程数时,进入阻塞队列,队列满时会根据最大线程数创建新线程,超出后根据预设的拒绝策略处理多余任务。线程池的选择可以通过 ThreadPoolExecutor 或 Executors 工具类创建,常用的线程池类型包括 SingleThreadExecutor、FixedThreadPool、CachedThreadPool 和 ScheduledThreadPool。根据任务的特性,线程池的线程数可以根据 CPU 密集型任务和 I/O 密集型任务来规划,CPU 密集型任务推荐使用等于 CPU 核心数的线程,I/O 密集型任务建议使用多倍于核心数的线程数。引入线程池能有效提高系统的性能,尤其适合 I/O 密集型任务,通过并发执行减少等待时间,从而提升整体计算效率。