<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>java on 文的超级笔记</title>
    <link>/post/tech/%E5%85%AB%E8%82%A1/java/</link>
    <description>Recent content in java on 文的超级笔记</description>
    <generator>Hugo -- 0.152.2</generator>
    <language>zh</language>
    <lastBuildDate>Mon, 19 Oct 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="/post/tech/%E5%85%AB%E8%82%A1/java/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>spring 事务</title>
      <link>/post/tech/%E5%85%AB%E8%82%A1/java/spring-%E4%BA%8B%E5%8A%A1/</link>
      <pubDate>Mon, 19 Oct 2026 00:00:00 +0000</pubDate>
      <guid>/post/tech/%E5%85%AB%E8%82%A1/java/spring-%E4%BA%8B%E5%8A%A1/</guid>
      <description>&lt;h2 id=&#34;为什么需要-spring-事务管理&#34;&gt;为什么需要 Spring 事务管理？&lt;/h2&gt;
&lt;p&gt;数据库本身已经提供了事务机制，能够通过 &lt;code&gt;COMMIT&lt;/code&gt; 和 &lt;code&gt;ROLLBACK&lt;/code&gt; 等操作实现事务的提交与回滚。&lt;/p&gt;
&lt;p&gt;但是，在 Java 项目中，如果直接使用 JDBC 管理数据库事务，开发者通常需要手动控制事务的开启、提交和回滚。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;connection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;setAutoCommit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 创建订单&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 扣减库存&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 扣减余额&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;connection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;commit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;catch&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Exception&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;connection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;rollback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;throw&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RuntimeException&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;上述代码省略了数据库连接的获取、关闭等细节。&lt;/p&gt;
&lt;p&gt;这种方式虽然可以实现事务管理，但存在几个问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;重复代码较多&lt;/strong&gt;：不同业务方法都需要编写事务开启、提交、回滚等逻辑。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;业务逻辑与事务管理耦合&lt;/strong&gt;：开发者不仅需要关注具体业务，还需要处理事务的生命周期。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;事务管理容易出错&lt;/strong&gt;：如果遗漏回滚操作，或者异常处理不当，就可能导致事务行为不符合预期。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;因此，Spring 在底层事务能力之上提供了一套统一的事务管理机制，帮助开发者简化事务控制。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Spring 基础</title>
      <link>/post/tech/%E5%85%AB%E8%82%A1/java/spring-%E5%9F%BA%E7%A1%80/</link>
      <pubDate>Fri, 16 Oct 2026 00:00:00 +0000</pubDate>
      <guid>/post/tech/%E5%85%AB%E8%82%A1/java/spring-%E5%9F%BA%E7%A1%80/</guid>
      <description>&lt;h2 id=&#34;相关问题&#34;&gt;相关问题&lt;/h2&gt;
&lt;h3 id=&#34;一spring-ioc-与-bean-管理8-题&#34;&gt;一、Spring IoC 与 Bean 管理（8 题）&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Spring 框架主要解决了什么问题？什么是 IoC 和 DI？&lt;/li&gt;
&lt;li&gt;Spring IoC 容器是什么？BeanFactory 和 ApplicationContext 有什么区别？&lt;/li&gt;
&lt;li&gt;Spring 容器是如何发现、注册和管理 Bean 的？BeanDefinition 起什么作用？&lt;/li&gt;
&lt;li&gt;Spring Bean 的完整生命周期是什么？&lt;/li&gt;
&lt;li&gt;Spring 如何实现依赖注入？构造器注入、Setter 注入和字段注入有什么区别？&lt;/li&gt;
&lt;li&gt;Spring Bean 有哪些作用域？默认单例 Bean 是线程安全的吗？&lt;/li&gt;
&lt;li&gt;什么是循环依赖？Spring 为什么需要三级缓存来解决循环依赖？&lt;/li&gt;
&lt;li&gt;BeanPostProcessor 是什么？它在 Bean 生命周期中起什么作用？&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;二spring-aop-与动态代理5-题&#34;&gt;二、Spring AOP 与动态代理（5 题）&lt;/h3&gt;
&lt;ol start=&#34;9&#34;&gt;
&lt;li&gt;什么是 AOP？Spring 为什么需要 AOP？它和 IoC 有什么关系？&lt;/li&gt;
&lt;li&gt;什么是动态代理？JDK 动态代理和 CGLIB 有什么区别？&lt;/li&gt;
&lt;li&gt;Spring AOP 的核心概念有哪些？切面、切点、通知分别是什么？&lt;/li&gt;
&lt;li&gt;Spring AOP 的底层实现原理是什么？代理对象是如何创建和执行的？&lt;/li&gt;
&lt;li&gt;Spring AOP 在什么情况下会失效？为什么同类内部方法调用可能导致 AOP 失效？&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;spring-ioc&#34;&gt;Spring IoC&lt;/h2&gt;
&lt;p&gt;在传统的 Java 开发中，对象之间往往存在依赖关系。例如，一个 &lt;code&gt;UserService&lt;/code&gt; 需要调用 &lt;code&gt;UserDao&lt;/code&gt; 来完成数据库操作，最直接的方式就是在 &lt;code&gt;UserService&lt;/code&gt; 内部通过 &lt;code&gt;new&lt;/code&gt; 创建一个 &lt;code&gt;UserDao&lt;/code&gt; 对象。&lt;/p&gt;</description>
    </item>
    <item>
      <title>java基础</title>
      <link>/post/tech/%E5%85%AB%E8%82%A1/java/java%E5%9F%BA%E7%A1%80/</link>
      <pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate>
      <guid>/post/tech/%E5%85%AB%E8%82%A1/java/java%E5%9F%BA%E7%A1%80/</guid>
      <description>&lt;h3 id=&#34;相关问题&#34;&gt;相关问题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;==&lt;/code&gt; 和 &lt;code&gt;equals()&lt;/code&gt; 有什么区别？&lt;/li&gt;
&lt;li&gt;为什么重写 &lt;code&gt;equals()&lt;/code&gt; 通常也要重写 &lt;code&gt;hashCode()&lt;/code&gt;？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Object&lt;/code&gt; 类里常见的方法有哪些？&lt;/li&gt;
&lt;li&gt;Java 是值传递还是引用传递？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;String&lt;/code&gt; 为什么是不可变的？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;String&lt;/code&gt;、&lt;code&gt;StringBuilder&lt;/code&gt;、&lt;code&gt;StringBuffer&lt;/code&gt; 有什么区别？&lt;/li&gt;
&lt;li&gt;字符串常量池是什么？&lt;code&gt;new String(&amp;quot;abc&amp;quot;)&lt;/code&gt; 创建几个对象？&lt;/li&gt;
&lt;li&gt;Integer 缓存是什么？为什么 &lt;code&gt;Integer 127 == 127&lt;/code&gt; 可能为 true，而 128 不一定？&lt;/li&gt;
&lt;li&gt;自动装箱和拆箱是什么？&lt;/li&gt;
&lt;li&gt;重载和重写有什么区别？&lt;/li&gt;
&lt;li&gt;接口和抽象类有什么区别？&lt;/li&gt;
&lt;li&gt;Java 怎么实现多态？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;final&lt;/code&gt; 修饰类、方法、变量分别代表什么？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;this&lt;/code&gt; 和 &lt;code&gt;super&lt;/code&gt; 有什么区别？&lt;/li&gt;
&lt;li&gt;Java 的异常体系是怎样的？&lt;/li&gt;
&lt;li&gt;Checked Exception 和 RuntimeException 有什么区别？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;throw&lt;/code&gt; 和 &lt;code&gt;throws&lt;/code&gt; 有什么区别？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;try-catch-finally&lt;/code&gt; 的执行顺序是什么？finally 一定会执行吗？&lt;/li&gt;
&lt;li&gt;泛型是什么？为什么需要泛型？&lt;/li&gt;
&lt;li&gt;什么是泛型擦除？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;? extends&lt;/code&gt; 和 &lt;code&gt;? super&lt;/code&gt; 有什么区别？&lt;/li&gt;
&lt;li&gt;反射是什么？有哪些典型使用场景？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Class&lt;/code&gt; 对象怎么获取？&lt;/li&gt;
&lt;li&gt;反射为什么性能相对差？&lt;/li&gt;
&lt;li&gt;注解是什么？怎么自定义注解？&lt;/li&gt;
&lt;li&gt;注解是怎么被反射读取的？&lt;/li&gt;
&lt;li&gt;Java IO 里字节流和字符流有什么区别？&lt;/li&gt;
&lt;li&gt;BIO、NIO、AIO 有什么区别？&lt;/li&gt;
&lt;li&gt;NIO 里的 Buffer、Channel、Selector 分别是什么？&lt;/li&gt;
&lt;li&gt;什么是零拷贝？&lt;/li&gt;
&lt;li&gt;浅拷贝和深拷贝有什么区别？&lt;/li&gt;
&lt;li&gt;序列化是什么？&lt;code&gt;transient&lt;/code&gt; 有什么作用？&lt;/li&gt;
&lt;li&gt;枚举和普通常量相比有什么优势？&lt;/li&gt;
&lt;li&gt;Lambda 和匿名内部类有什么区别？&lt;/li&gt;
&lt;li&gt;Stream 是什么？中间操作和终止操作有什么区别？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;equals/hashCode → String → 面向对象 → 异常 → 泛型 → 反射/注解 → IO/NIO → 其他语言细节。&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>java集合</title>
      <link>/post/tech/%E5%85%AB%E8%82%A1/java/java%E9%9B%86%E5%90%88/</link>
      <pubDate>Tue, 06 Oct 2026 00:00:00 +0000</pubDate>
      <guid>/post/tech/%E5%85%AB%E8%82%A1/java/java%E9%9B%86%E5%90%88/</guid>
      <description>&lt;h3 id=&#34;相关问题&#34;&gt;相关问题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Java 集合体系有哪些？&lt;code&gt;Collection&lt;/code&gt; 和 &lt;code&gt;Map&lt;/code&gt; 有什么区别？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;List&lt;/code&gt;、&lt;code&gt;Set&lt;/code&gt;、&lt;code&gt;Queue&lt;/code&gt; 分别有什么特点？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ArrayList&lt;/code&gt; 和 &lt;code&gt;LinkedList&lt;/code&gt; 有什么区别？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ArrayList&lt;/code&gt; 底层是什么结构？扩容机制是怎样的？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ArrayList&lt;/code&gt; 为什么随机访问快、插入删除慢？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LinkedList&lt;/code&gt; 底层是什么结构？适合什么场景？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HashMap&lt;/code&gt; 底层数据结构是什么？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HashMap&lt;/code&gt; 的 put 流程是什么？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HashMap&lt;/code&gt; 怎么计算哈希和数组下标？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HashMap&lt;/code&gt; 怎么解决哈希冲突？&lt;/li&gt;
&lt;li&gt;为什么 JDK 8 以后链表过长会转成红黑树？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HashMap&lt;/code&gt; 什么时候扩容？为什么容量通常是 2 的幂？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HashMap&lt;/code&gt; 扩容时元素怎么迁移？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HashMap&lt;/code&gt; 为什么线程不安全？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HashMap&lt;/code&gt;、&lt;code&gt;Hashtable&lt;/code&gt;、&lt;code&gt;ConcurrentHashMap&lt;/code&gt; 有什么区别？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HashSet&lt;/code&gt; 底层是怎么实现的？为什么元素不能重复？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LinkedHashMap&lt;/code&gt; 是怎么保证插入顺序或访问顺序的？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TreeMap&lt;/code&gt; / &lt;code&gt;TreeSet&lt;/code&gt; 底层为什么用红黑树？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ArrayDeque&lt;/code&gt; 和 &lt;code&gt;LinkedList&lt;/code&gt; 作为队列有什么区别？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PriorityQueue&lt;/code&gt; 底层是什么结构？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ConcurrentHashMap&lt;/code&gt; JDK 7 和 JDK 8 的实现有什么区别？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ConcurrentHashMap&lt;/code&gt; 为什么比 &lt;code&gt;Hashtable&lt;/code&gt; 并发性能更好？&lt;/li&gt;
&lt;li&gt;JDK 8 的 &lt;code&gt;ConcurrentHashMap&lt;/code&gt; 怎么保证线程安全？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CopyOnWriteArrayList&lt;/code&gt; 的原理是什么？适合什么场景？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BlockingQueue&lt;/code&gt; 有哪些常见实现？线程池为什么常用它？&lt;/li&gt;
&lt;li&gt;什么是 fail-fast？为什么遍历集合时修改可能抛 &lt;code&gt;ConcurrentModificationException&lt;/code&gt;？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Iterator&lt;/code&gt; 和增强 for 的关系是什么？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Comparable&lt;/code&gt; 和 &lt;code&gt;Comparator&lt;/code&gt; 有什么区别？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;equals()&lt;/code&gt; 和 &lt;code&gt;hashCode()&lt;/code&gt; 为什么要一起重写？对 HashMap/HashSet 有什么影响？&lt;/li&gt;
&lt;li&gt;什么时候选 ArrayList、LinkedList、HashMap、TreeMap、ConcurrentHashMap？&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;集合体系&#34;&gt;集合体系&lt;/h3&gt;
&lt;p&gt;Java 集合大体可以分成两套体系：&lt;code&gt;Collection&lt;/code&gt; 和 &lt;code&gt;Map&lt;/code&gt;。&lt;/p&gt;</description>
    </item>
    <item>
      <title>类加载机制</title>
      <link>/post/tech/%E5%85%AB%E8%82%A1/java/%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6/</link>
      <pubDate>Mon, 05 Oct 2026 00:00:00 +0000</pubDate>
      <guid>/post/tech/%E5%85%AB%E8%82%A1/java/%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6/</guid>
      <description>&lt;h3 id=&#34;相关问题&#34;&gt;相关问题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Java 类从 &lt;code&gt;.class&lt;/code&gt; 文件到可以被 JVM 使用，中间经历哪些阶段？&lt;/li&gt;
&lt;li&gt;类加载的五个阶段分别做什么？
&lt;ul&gt;
&lt;li&gt;加载&lt;/li&gt;
&lt;li&gt;验证&lt;/li&gt;
&lt;li&gt;准备&lt;/li&gt;
&lt;li&gt;解析&lt;/li&gt;
&lt;li&gt;初始化&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;“准备”和“初始化”有什么区别？&lt;/li&gt;
&lt;li&gt;static 变量在准备阶段和初始化阶段分别会发生什么？&lt;/li&gt;
&lt;li&gt;类什么时候会触发初始化？&lt;/li&gt;
&lt;li&gt;哪些情况不会触发类初始化？&lt;/li&gt;
&lt;li&gt;JVM 中常见的类加载器有哪些？&lt;/li&gt;
&lt;li&gt;什么是双亲委派模型？&lt;/li&gt;
&lt;li&gt;双亲委派的完整加载流程是什么？&lt;/li&gt;
&lt;li&gt;为什么要使用双亲委派？&lt;/li&gt;
&lt;li&gt;双亲委派怎么避免核心类被重复加载或篡改？&lt;/li&gt;
&lt;li&gt;什么叫“同一个类”？只看类名一样就算同一个类吗？&lt;/li&gt;
&lt;li&gt;不同 ClassLoader 加载同一个 &lt;code&gt;.class&lt;/code&gt;，得到的 Class 是同一个吗？&lt;/li&gt;
&lt;li&gt;哪些场景会打破双亲委派？&lt;/li&gt;
&lt;li&gt;SPI 为什么会涉及打破双亲委派？&lt;/li&gt;
&lt;li&gt;Tomcat 为什么要自定义 ClassLoader？&lt;/li&gt;
&lt;li&gt;自定义 ClassLoader 一般怎么实现？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Class.forName()&lt;/code&gt; 和 &lt;code&gt;ClassLoader.loadClass()&lt;/code&gt; 有什么区别？&lt;/li&gt;
&lt;li&gt;类加载器和类卸载有什么关系？&lt;/li&gt;
&lt;li&gt;什么情况下类可以被卸载？&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;类加载流程&#34;&gt;类加载流程&lt;/h3&gt;
&lt;p&gt;一个 &lt;code&gt;.class&lt;/code&gt; 文件真正被 JVM 使用之前，通常会经历：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;加载
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;→ 验证
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;→ 准备
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;→ 解析
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;→ 初始化
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;加载&lt;/strong&gt;阶段就是把 &lt;code&gt;.class&lt;/code&gt; 文件读进 JVM。&lt;/p&gt;</description>
    </item>
    <item>
      <title>问题排查</title>
      <link>/post/tech/%E5%85%AB%E8%82%A1/java/%E9%97%AE%E9%A2%98%E6%8E%92%E6%9F%A5/</link>
      <pubDate>Mon, 05 Oct 2026 00:00:00 +0000</pubDate>
      <guid>/post/tech/%E5%85%AB%E8%82%A1/java/%E9%97%AE%E9%A2%98%E6%8E%92%E6%9F%A5/</guid>
      <description>&lt;h3 id=&#34;full-gc-频繁怎么排查&#34;&gt;Full GC 频繁怎么排查&lt;/h3&gt;
&lt;p&gt;Full GC 频繁通常说明老年代或者元空间压力比较大，也可能是代码或参数配置导致 GC 退化。&lt;/p&gt;
&lt;p&gt;排查时先看三个东西：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Full GC 发生频率
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;单次停顿时间
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Full GC 之后内存是否明显下降
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果 Full GC 之后老年代占用明显下降，比如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GC 前：90%
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GC 后：30%
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;说明对象大部分其实是可以回收的，更像是对象创建太快、堆太小，或者大量对象过早晋升到了老年代。&lt;/p&gt;
&lt;p&gt;这时可以继续看：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Young GC 是否过于频繁
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;对象晋升速度是否过快
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;新生代是否太小
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;是否存在大量大对象
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果 Full GC 之后老年代几乎不下降：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GC 前：90%
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GC 后：85%
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;而且后面还在持续上涨，就要重点怀疑：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;大量对象长期存活，甚至存在内存泄漏。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这时候通常需要导出 Heap Dump，分析：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;哪些对象占用内存最多
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;哪些对象数量异常
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;这些对象为什么一直被 GC Roots 引用
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;另外还要关注 Full GC 的触发原因，比如：&lt;/p&gt;</description>
    </item>
    <item>
      <title>GC</title>
      <link>/post/tech/%E5%85%AB%E8%82%A1/java/gc/</link>
      <pubDate>Sun, 04 Oct 2026 00:00:00 +0000</pubDate>
      <guid>/post/tech/%E5%85%AB%E8%82%A1/java/gc/</guid>
      <description>&lt;h3 id=&#34;相关问题&#34;&gt;相关问题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;什么是 GC？Java 为什么仍然可能发生内存泄漏？&lt;/li&gt;
&lt;li&gt;JVM 怎么判断一个对象是否可以回收？
&lt;ul&gt;
&lt;li&gt;引用计数法&lt;/li&gt;
&lt;li&gt;可达性分析&lt;/li&gt;
&lt;li&gt;GC Roots&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;常见的 GC Roots 有哪些？&lt;/li&gt;
&lt;li&gt;什么是三色标记法？并发标记为什么会有漏标和多标问题？&lt;/li&gt;
&lt;li&gt;Java 的强引用、软引用、弱引用、虚引用有什么区别？&lt;/li&gt;
&lt;li&gt;常见垃圾回收算法有哪些？
&lt;ul&gt;
&lt;li&gt;标记-清除&lt;/li&gt;
&lt;li&gt;复制&lt;/li&gt;
&lt;li&gt;标记-整理&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;为什么 JVM 要采用分代收集？&lt;/li&gt;
&lt;li&gt;新生代和老年代分别存什么对象？为什么适合不同的回收算法？&lt;/li&gt;
&lt;li&gt;Eden、Survivor 0、Survivor 1 是怎么配合工作的？&lt;/li&gt;
&lt;li&gt;对象什么时候会进入老年代？&lt;/li&gt;
&lt;li&gt;Young GC、Major GC、Full GC 有什么区别？&lt;/li&gt;
&lt;li&gt;哪些情况可能触发 Full GC？为什么 Full GC 通常比较慢？&lt;/li&gt;
&lt;li&gt;什么是 STW？为什么 GC 过程中需要暂停业务线程？&lt;/li&gt;
&lt;li&gt;什么是 Safepoint？它和 STW 有什么关系？&lt;/li&gt;
&lt;li&gt;什么是 Card Table / Remembered Set？为什么 Young GC 不能直接扫描整个老年代？&lt;/li&gt;
&lt;li&gt;CMS 的工作流程是什么？它有哪些优缺点？&lt;/li&gt;
&lt;li&gt;G1 的核心设计是什么？&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Region&lt;/li&gt;
&lt;li&gt;Young GC&lt;/li&gt;
&lt;li&gt;Mixed GC&lt;/li&gt;
&lt;li&gt;为什么叫 Garbage First&lt;/li&gt;
&lt;li&gt;为什么能控制停顿时间&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&#34;18&#34;&gt;
&lt;li&gt;ZGC 的核心特点是什么？为什么能做到低停顿？&lt;/li&gt;
&lt;li&gt;G1 和 ZGC 怎么选？&lt;/li&gt;
&lt;li&gt;线上 GC 问题怎么排查？&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Young GC 频繁&lt;/li&gt;
&lt;li&gt;Full GC 频繁&lt;/li&gt;
&lt;li&gt;GC 后内存降不下来&lt;/li&gt;
&lt;li&gt;Heap Dump&lt;/li&gt;
&lt;li&gt;常用工具和指标&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;jvm-怎么判断对象是否可以回收&#34;&gt;JVM 怎么判断对象是否可以回收&lt;/h3&gt;
&lt;p&gt;垃圾回收的第一步，是先判断哪些对象已经没有用了。&lt;/p&gt;</description>
    </item>
    <item>
      <title>jvm内存结构</title>
      <link>/post/tech/%E5%85%AB%E8%82%A1/java/jvm%E5%86%85%E5%AD%98%E7%BB%93%E6%9E%84/</link>
      <pubDate>Sat, 03 Oct 2026 00:00:00 +0000</pubDate>
      <guid>/post/tech/%E5%85%AB%E8%82%A1/java/jvm%E5%86%85%E5%AD%98%E7%BB%93%E6%9E%84/</guid>
      <description>&lt;h3 id=&#34;相关问题&#34;&gt;相关问题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;JVM 运行时数据区有哪些？&lt;/li&gt;
&lt;li&gt;哪些区域是线程私有，哪些是线程共享？&lt;/li&gt;
&lt;li&gt;程序计数器是干什么的？为什么它是线程私有的？&lt;/li&gt;
&lt;li&gt;虚拟机栈里存什么？&lt;/li&gt;
&lt;li&gt;一个方法调用时，栈帧里有哪些内容？&lt;/li&gt;
&lt;li&gt;本地方法栈是什么？和虚拟机栈有什么区别？&lt;/li&gt;
&lt;li&gt;Java 堆里主要存什么？&lt;/li&gt;
&lt;li&gt;栈和堆有什么区别？&lt;/li&gt;
&lt;li&gt;方法区主要存什么？&lt;/li&gt;
&lt;li&gt;元空间是什么？和永久代有什么区别？&lt;/li&gt;
&lt;li&gt;为什么 JDK 8 把永久代换成了元空间？&lt;/li&gt;
&lt;li&gt;运行时常量池是什么？放在哪里？&lt;/li&gt;
&lt;li&gt;字符串常量池放在哪里？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;static&lt;/code&gt; 变量放在哪里？&lt;/li&gt;
&lt;li&gt;一个 Java 对象创建以后通常存在哪里？&lt;/li&gt;
&lt;li&gt;对象引用和对象本身分别可能存在哪里？&lt;/li&gt;
&lt;li&gt;Java 对象在内存中的结构是什么？&lt;/li&gt;
&lt;li&gt;对象头里有哪些内容？Mark Word 是什么？&lt;/li&gt;
&lt;li&gt;什么情况下会出现 &lt;code&gt;StackOverflowError&lt;/code&gt;？&lt;/li&gt;
&lt;li&gt;哪些内存区域可能出现 &lt;code&gt;OutOfMemoryError&lt;/code&gt;？&lt;/li&gt;
&lt;li&gt;线程创建太多为什么可能导致 OOM？&lt;/li&gt;
&lt;li&gt;直接内存是什么？属于 JVM 运行时数据区吗？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ByteBuffer.allocateDirect()&lt;/code&gt; 为什么可能导致直接内存 OOM？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;内存结构：内存分哪几块、每块放什么。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GC：堆里的对象怎么分代、怎么判断垃圾、怎么回收。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;jvm整体内存结构&#34;&gt;JVM整体内存结构&lt;/h3&gt;
&lt;p&gt;JVM 在运行 Java 程序时，会把运行过程中需要使用的内存划分成几个不同的区域，每个区域负责保存不同类型的数据。&lt;/p&gt;
&lt;p&gt;从整体上看，可以先分成两类：&lt;strong&gt;线程私有区域&lt;/strong&gt;和&lt;strong&gt;线程共享区域&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;线程私有区域包括程序计数器、虚拟机栈和本地方法栈。每个线程都会有自己独立的一份，线程之间不会直接共用。&lt;/p&gt;
&lt;p&gt;线程共享区域主要包括堆和方法区，也就是后面常说的元空间相关内容，这些区域会被多个线程共同访问。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;JVM 内存
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── 线程私有
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── 程序计数器
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── 虚拟机栈
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── 本地方法栈
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└── 线程共享
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    ├── 堆
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    └── 方法区 / 元空间
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;程序计数器用来记录当前线程执行到哪一条字节码指令。因为线程可能随时被切换出去，之后重新获得 CPU 时，需要知道应该从哪里继续执行，所以每个线程都必须有自己独立的程序计数器。&lt;/p&gt;</description>
    </item>
    <item>
      <title>ThreadLocal</title>
      <link>/post/tech/%E5%85%AB%E8%82%A1/java/threadlocal/</link>
      <pubDate>Fri, 02 Oct 2026 00:00:00 +0000</pubDate>
      <guid>/post/tech/%E5%85%AB%E8%82%A1/java/threadlocal/</guid>
      <description>&lt;h3 id=&#34;相关问题&#34;&gt;相关问题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;ThreadLocal&lt;/code&gt; 是什么？它解决什么问题？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ThreadLocal&lt;/code&gt; 和加锁有什么区别？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ThreadLocal&lt;/code&gt; 的数据到底存在哪里？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ThreadLocalMap&lt;/code&gt; 是什么？为什么每个线程都有自己的 &lt;code&gt;ThreadLocalMap&lt;/code&gt;？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ThreadLocal.set()&lt;/code&gt; 的完整流程是什么？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ThreadLocal.get()&lt;/code&gt; 的完整流程是什么？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ThreadLocalMap&lt;/code&gt; 为什么不是普通的 &lt;code&gt;HashMap&lt;/code&gt;？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ThreadLocalMap&lt;/code&gt; 发生哈希冲突时怎么处理？&lt;/li&gt;
&lt;li&gt;为什么 &lt;code&gt;ThreadLocalMap&lt;/code&gt; 的 key 是弱引用？&lt;/li&gt;
&lt;li&gt;为什么 key 用弱引用以后，仍然可能发生内存泄漏？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ThreadLocal&lt;/code&gt; 内存泄漏到底泄漏的是什么？&lt;/li&gt;
&lt;li&gt;为什么使用完 &lt;code&gt;ThreadLocal&lt;/code&gt; 通常要调用 &lt;code&gt;remove()&lt;/code&gt;？&lt;/li&gt;
&lt;li&gt;在线程池里使用 &lt;code&gt;ThreadLocal&lt;/code&gt; 为什么风险更大？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ThreadLocal&lt;/code&gt; 的 key 被 GC 以后，value 是怎么被清理的？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ThreadLocalMap&lt;/code&gt; 什么时候会清理过期 Entry？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ThreadLocal&lt;/code&gt; 能实现父子线程之间的数据传递吗？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;InheritableThreadLocal&lt;/code&gt; 是怎么实现的？&lt;/li&gt;
&lt;li&gt;为什么在线程池里 &lt;code&gt;InheritableThreadLocal&lt;/code&gt; 也可能失效？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TransmittableThreadLocal&lt;/code&gt; 解决了什么问题？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ThreadLocal&lt;/code&gt; 的典型使用场景有哪些？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ThreadLocal&lt;/code&gt; 有哪些不适合使用的场景？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ThreadLocal&lt;/code&gt; 是线程安全的吗？为什么？&lt;/li&gt;
&lt;li&gt;一个线程可以有多个 &lt;code&gt;ThreadLocal&lt;/code&gt; 吗？它们的数据怎么区分？&lt;/li&gt;
&lt;li&gt;同一个 &lt;code&gt;ThreadLocal&lt;/code&gt; 被多个线程使用时，为什么不会互相覆盖？&lt;/li&gt;
&lt;li&gt;如果让你手写一个简化版 &lt;code&gt;ThreadLocal&lt;/code&gt;，核心结构会怎么设计？&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;threadlocal-的作用&#34;&gt;ThreadLocal 的作用&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ThreadLocal&lt;/code&gt; 用来为每个线程保存一份独立的数据。&lt;/p&gt;</description>
    </item>
    <item>
      <title>volatile&#43;CAS</title>
      <link>/post/tech/%E5%85%AB%E8%82%A1/java/volatile-cas/</link>
      <pubDate>Fri, 02 Oct 2026 00:00:00 +0000</pubDate>
      <guid>/post/tech/%E5%85%AB%E8%82%A1/java/volatile-cas/</guid>
      <description>&lt;h3 id=&#34;相关问题&#34;&gt;相关问题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;volatile&lt;/code&gt; 是什么？它主要解决什么问题？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;volatile&lt;/code&gt; 为什么能保证可见性？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;volatile&lt;/code&gt; 为什么能保证有序性？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;volatile&lt;/code&gt; 能保证原子性吗？为什么 &lt;code&gt;count++&lt;/code&gt; 仍然线程不安全？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;volatile&lt;/code&gt; 和 &lt;code&gt;synchronized&lt;/code&gt; 有什么区别？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;volatile&lt;/code&gt; 的典型使用场景有哪些？&lt;/li&gt;
&lt;li&gt;双重检查单例为什么一定要加 &lt;code&gt;volatile&lt;/code&gt;？&lt;/li&gt;
&lt;li&gt;什么是 happens-before？&lt;code&gt;volatile&lt;/code&gt; 的 happens-before 规则是什么？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;volatile&lt;/code&gt; 底层是怎么实现的？内存屏障起什么作用？&lt;/li&gt;
&lt;li&gt;CAS 是什么？Compare And Swap 比较和交换的三个值分别是什么？&lt;/li&gt;
&lt;li&gt;CAS 为什么能保证一次更新操作的原子性？&lt;/li&gt;
&lt;li&gt;CAS 和自旋是什么关系？&lt;/li&gt;
&lt;li&gt;CAS 为什么被称为无锁并发？&lt;/li&gt;
&lt;li&gt;CAS 失败以后会发生什么？为什么高竞争下会浪费 CPU？&lt;/li&gt;
&lt;li&gt;什么是 ABA 问题？&lt;/li&gt;
&lt;li&gt;ABA 为什么有时候会导致问题？&lt;/li&gt;
&lt;li&gt;ABA 怎么解决？版本号和 &lt;code&gt;AtomicStampedReference&lt;/code&gt; 是怎么做的？&lt;/li&gt;
&lt;li&gt;CAS 有哪些局限？
&lt;ul&gt;
&lt;li&gt;高竞争下自旋开销&lt;/li&gt;
&lt;li&gt;ABA&lt;/li&gt;
&lt;li&gt;单变量更新更合适&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AtomicInteger&lt;/code&gt; 为什么线程安全？底层和 CAS 有什么关系？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AtomicInteger.incrementAndGet()&lt;/code&gt; 大致是怎么实现的？&lt;/li&gt;
&lt;li&gt;CAS 和 &lt;code&gt;synchronized / ReentrantLock&lt;/code&gt; 有什么区别？&lt;/li&gt;
&lt;li&gt;CAS 适合什么场景，锁又适合什么场景？&lt;/li&gt;
&lt;li&gt;为什么 AQS、Atomic 类、轻量级锁里都会大量使用 CAS？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LongAdder&lt;/code&gt; 为什么在高并发下通常比 &lt;code&gt;AtomicLong&lt;/code&gt; 更合适？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LongAdder&lt;/code&gt; 为什么最终值不是每次更新时都集中写到一个变量上？&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;volatile-的作用&#34;&gt;volatile 的作用&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;volatile&lt;/code&gt; 是 Java 提供的一种轻量级同步机制，主要解决两个问题：&lt;strong&gt;可见性和有序性&lt;/strong&gt;。&lt;/p&gt;</description>
    </item>
    <item>
      <title>ReentrantLock</title>
      <link>/post/tech/%E5%85%AB%E8%82%A1/java/reentrantlock/</link>
      <pubDate>Mon, 28 Sep 2026 00:00:00 +0000</pubDate>
      <guid>/post/tech/%E5%85%AB%E8%82%A1/java/reentrantlock/</guid>
      <description>&lt;h3 id=&#34;问题&#34;&gt;问题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;ReentrantLock&lt;/code&gt; 是什么？为什么已经有 &lt;code&gt;synchronized&lt;/code&gt; 了还需要它？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ReentrantLock&lt;/code&gt; 和 &lt;code&gt;synchronized&lt;/code&gt; 有什么区别？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ReentrantLock&lt;/code&gt; 为什么叫“可重入锁”？可重入是怎么实现的？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ReentrantLock&lt;/code&gt; 底层是怎么实现的？
&lt;ul&gt;
&lt;li&gt;AQS 是什么&lt;/li&gt;
&lt;li&gt;&lt;code&gt;state&lt;/code&gt; 表示什么&lt;/li&gt;
&lt;li&gt;&lt;code&gt;exclusiveOwnerThread&lt;/code&gt; 表示什么&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;一个线程调用 &lt;code&gt;lock()&lt;/code&gt; 以后，完整的加锁流程是什么？
&lt;ul&gt;
&lt;li&gt;CAS 抢锁&lt;/li&gt;
&lt;li&gt;抢锁失败以后怎么办&lt;/li&gt;
&lt;li&gt;什么时候进入等待队列&lt;/li&gt;
&lt;li&gt;什么时候阻塞线程&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AQS 的等待队列是什么结构？
&lt;ul&gt;
&lt;li&gt;CLH 队列&lt;/li&gt;
&lt;li&gt;&lt;code&gt;head&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tail&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Node&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;等待线程是怎么被阻塞和唤醒的？
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;LockSupport.park()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LockSupport.unpark()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;unlock()&lt;/code&gt; 的完整流程是什么？
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;state&lt;/code&gt; 怎么减少&lt;/li&gt;
&lt;li&gt;什么时候真正释放锁&lt;/li&gt;
&lt;li&gt;怎么唤醒下一个线程&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ReentrantLock&lt;/code&gt; 是怎么实现可重入的？&lt;/li&gt;
&lt;li&gt;公平锁和非公平锁有什么区别？
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;new ReentrantLock(true)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;为什么默认是非公平锁&lt;/li&gt;
&lt;li&gt;非公平锁为什么吞吐量通常更高&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tryLock()&lt;/code&gt; 和 &lt;code&gt;lock()&lt;/code&gt; 有什么区别？
&lt;ul&gt;
&lt;li&gt;立即失败&lt;/li&gt;
&lt;li&gt;超时获取&lt;/li&gt;
&lt;li&gt;适合什么场景&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lockInterruptibly()&lt;/code&gt; 是什么？和 &lt;code&gt;lock()&lt;/code&gt; 有什么区别？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Condition&lt;/code&gt; 是什么？为什么有了 &lt;code&gt;wait/notify&lt;/code&gt; 还需要 &lt;code&gt;Condition&lt;/code&gt;？&lt;/li&gt;
&lt;li&gt;一个 &lt;code&gt;ReentrantLock&lt;/code&gt; 为什么可以创建多个 &lt;code&gt;Condition&lt;/code&gt;？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Condition.await()&lt;/code&gt; 和 &lt;code&gt;signal()&lt;/code&gt; 的底层流程是什么？
&lt;ul&gt;
&lt;li&gt;Condition Queue&lt;/li&gt;
&lt;li&gt;AQS Queue&lt;/li&gt;
&lt;li&gt;await 为什么会释放锁&lt;/li&gt;
&lt;li&gt;signal 为什么不是直接让线程继续执行&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ReentrantLock&lt;/code&gt; 使用时为什么必须在 &lt;code&gt;finally&lt;/code&gt; 里 &lt;code&gt;unlock()&lt;/code&gt;？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ReentrantLock&lt;/code&gt; 会发生死锁吗？常见死锁场景有哪些？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ReentrantLock&lt;/code&gt; 和 &lt;code&gt;synchronized&lt;/code&gt; 在性能上谁更好？&lt;/li&gt;
&lt;li&gt;实际业务中什么时候更适合用 &lt;code&gt;synchronized&lt;/code&gt;，什么时候更适合用 &lt;code&gt;ReentrantLock&lt;/code&gt;？&lt;/li&gt;
&lt;li&gt;如果让你手写一个简化版互斥锁，你会怎么基于 AQS 实现？&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;为什么已经有-synchronized-了还需要-reentrantlock&#34;&gt;为什么已经有 synchronized 了，还需要 ReentrantLock？&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ReentrantLock&lt;/code&gt; 本质上也是一种互斥锁，用来控制多个线程对共享资源的访问。&lt;/p&gt;</description>
    </item>
    <item>
      <title>synchronized</title>
      <link>/post/tech/%E5%85%AB%E8%82%A1/java/synchronized/</link>
      <pubDate>Mon, 28 Sep 2026 00:00:00 +0000</pubDate>
      <guid>/post/tech/%E5%85%AB%E8%82%A1/java/synchronized/</guid>
      <description>&lt;h3 id=&#34;相关问题&#34;&gt;相关问题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;synchronized 本质上解决什么问题？&lt;/li&gt;
&lt;li&gt;synchronized 除了互斥，还提供哪些内存语义？&lt;/li&gt;
&lt;li&gt;synchronized 修饰实例方法时，锁的是谁？&lt;/li&gt;
&lt;li&gt;synchronized 修饰静态方法时，锁的是谁？&lt;/li&gt;
&lt;li&gt;synchronized(obj) 锁的又是谁？&lt;/li&gt;
&lt;li&gt;两个不同对象分别调用同一个实例 synchronized 方法，会互相阻塞吗？为什么？&lt;/li&gt;
&lt;li&gt;static synchronized 方法通过类名调用和通过对象调用，有没有竞争关系？为什么？&lt;/li&gt;
&lt;li&gt;一个 static synchronized 方法和一个实例 synchronized 方法之间是否竞争？&lt;/li&gt;
&lt;li&gt;为什么 synchronized 是可重入锁？&lt;/li&gt;
&lt;li&gt;什么叫“可重入”？&lt;/li&gt;
&lt;li&gt;一个同步方法内部再调用另一个锁住同一对象的同步方法，会不会死锁？&lt;/li&gt;
&lt;li&gt;synchronized 代码块在字节码层面和什么指令有关？&lt;/li&gt;
&lt;li&gt;synchronized 方法又是如何标识的？&lt;/li&gt;
&lt;li&gt;synchronized 和对象头、Mark Word、Monitor 有什么关系？&lt;/li&gt;
&lt;li&gt;传统意义上的锁升级过程是什么？&lt;/li&gt;
&lt;li&gt;为什么现代 JDK 里不能再简单把偏向锁当成重点来讲？&lt;/li&gt;
&lt;li&gt;synchronized 在竞争激烈时为什么可能进入重量级 Monitor？&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;synchronized-的三种使用方式&#34;&gt;synchronized 的三种使用方式&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;synchronized&lt;/code&gt; 主要有三种使用方式：修饰实例方法、修饰静态方法、修饰代码块。三者最核心的区别就在于：&lt;strong&gt;锁对象不同。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;修饰实例方法时：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;synchronized&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;method&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;锁的是当前实例对象，也就是 &lt;code&gt;this&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;因此，如果两个线程操作的是同一个实例，它们会互斥；如果操作的是不同实例，因为锁对象不同，通常不会互相阻塞。&lt;/p&gt;
&lt;p&gt;修饰静态方法时：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;synchronized&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;method&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;锁的是当前类对应的 &lt;code&gt;Class&lt;/code&gt; 对象，也就是：&lt;/p&gt;</description>
    </item>
    <item>
      <title>线程池</title>
      <link>/post/tech/%E5%85%AB%E8%82%A1/java/%E7%BA%BF%E7%A8%8B%E6%B1%A0/</link>
      <pubDate>Mon, 28 Sep 2026 00:00:00 +0000</pubDate>
      <guid>/post/tech/%E5%85%AB%E8%82%A1/java/%E7%BA%BF%E7%A8%8B%E6%B1%A0/</guid>
      <description>&lt;h3 id=&#34;相关问题&#34;&gt;相关问题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;为什么需要线程池？直接 new Thread() 有什么问题？&lt;/li&gt;
&lt;li&gt;ThreadPoolExecutor 的核心参数有哪些？这些参数之间是什么关系？&lt;/li&gt;
&lt;li&gt;一个任务提交到线程池后，完整执行流程是什么？
&lt;ul&gt;
&lt;li&gt;什么时候创建核心线程&lt;/li&gt;
&lt;li&gt;什么时候进队列&lt;/li&gt;
&lt;li&gt;什么时候扩到最大线程数&lt;/li&gt;
&lt;li&gt;什么时候触发拒绝策略&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;为什么达到核心线程数以后，线程池选择先入队，而不是直接扩容线程？&lt;/li&gt;
&lt;li&gt;任务队列为什么通常推荐有界队列？无界队列会带来什么问题？
&lt;ul&gt;
&lt;li&gt;OOM&lt;/li&gt;
&lt;li&gt;延迟不断增加&lt;/li&gt;
&lt;li&gt;maximumPoolSize 很难生效&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;线程池的几种拒绝策略分别是什么？实际业务应该怎么选？
&lt;ul&gt;
&lt;li&gt;AbortPolicy&lt;/li&gt;
&lt;li&gt;CallerRunsPolicy&lt;/li&gt;
&lt;li&gt;DiscardPolicy&lt;/li&gt;
&lt;li&gt;DiscardOldestPolicy&lt;/li&gt;
&lt;li&gt;CallerRunsPolicy 为什么能形成反压&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CPU 密集型和 IO 密集型任务，线程数应该怎么配置？为什么？&lt;/li&gt;
&lt;li&gt;IO 密集型线程是不是越多越好？还要受哪些资源限制？
&lt;ul&gt;
&lt;li&gt;数据库连接池&lt;/li&gt;
&lt;li&gt;HTTP 连接池&lt;/li&gt;
&lt;li&gt;下游服务容量&lt;/li&gt;
&lt;li&gt;CPU 上下文切换&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;线程池里的空闲线程是怎么回收的？
&lt;ul&gt;
&lt;li&gt;keepAliveTime&lt;/li&gt;
&lt;li&gt;核心线程和非核心线程的区别&lt;/li&gt;
&lt;li&gt;allowCoreThreadTimeOut&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;为什么生产环境通常不建议直接使用 Executors.newFixedThreadPool() 和 newCachedThreadPool()？&lt;/li&gt;
&lt;li&gt;线程池实现异步和 MQ 实现异步有什么区别？什么时候用线程池，什么时候用消息队列？&lt;/li&gt;
&lt;li&gt;如果让你设计一个生产环境线程池，你会重点考虑哪些指标和参数？
&lt;ul&gt;
&lt;li&gt;核心线程数&lt;/li&gt;
&lt;li&gt;最大线程数&lt;/li&gt;
&lt;li&gt;队列大小&lt;/li&gt;
&lt;li&gt;拒绝策略&lt;/li&gt;
&lt;li&gt;任务耗时&lt;/li&gt;
&lt;li&gt;CPU 使用率&lt;/li&gt;
&lt;li&gt;活跃线程数&lt;/li&gt;
&lt;li&gt;队列长度&lt;/li&gt;
&lt;li&gt;下游承载能力&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;结构化八股&#34;&gt;结构化八股&lt;/h3&gt;
&lt;h4 id=&#34;为什么需要线程池&#34;&gt;为什么需要线程池&lt;/h4&gt;
&lt;p&gt;如果每个任务都直接 &lt;code&gt;new Thread()&lt;/code&gt;，高并发时线程数量会不断增长。线程的创建、销毁、内存占用以及上下文切换都有成本，线程过多反而会降低系统整体效率。&lt;/p&gt;
&lt;p&gt;因此线程池首先解决的是&lt;strong&gt;线程复用和并发控制&lt;/strong&gt;：提前维护一批线程，任务来了就交给这些线程执行，任务结束后线程不销毁，而是继续处理后续任务。&lt;/p&gt;
&lt;h4 id=&#34;固定线程不够怎么办&#34;&gt;固定线程不够怎么办&lt;/h4&gt;
&lt;p&gt;固定线程数虽然避免了线程无限增长，但如果任务突然增多，线程全部忙起来，剩余任务就需要有地方暂存。&lt;/p&gt;
&lt;p&gt;于是线程池引入了 &lt;code&gt;workQueue&lt;/code&gt;。当线程暂时处理不过来时，新任务先进入队列，等已有线程执行完当前任务后，再继续从队列中取任务。&lt;/p&gt;
&lt;h4 id=&#34;队列也不能无限增长&#34;&gt;队列也不能无限增长&lt;/h4&gt;
&lt;p&gt;任务队列解决了短时间流量突增的问题，但如果任务进入速度长期大于处理速度，队列就会不断积压。无界队列可能最终占满内存，即使没有 OOM，任务等待时间也会越来越长。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
