<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Posts on Creat</title><link>https://creat.asia/post/</link><description>Recent content in Posts on Creat</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Fri, 08 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://creat.asia/post/index.xml" rel="self" type="application/rss+xml"/><item><title>基础知识拓展</title><link>https://creat.asia/post/00-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86%E6%8B%93%E5%B1%95/</link><pubDate>Tue, 03 Feb 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/00-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86%E6%8B%93%E5%B1%95/</guid><description/></item><item><title>基本语法</title><link>https://creat.asia/post/01-%E5%9F%BA%E6%9C%AC%E8%AF%AD%E6%B3%95/</link><pubDate>Tue, 03 Feb 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/01-%E5%9F%BA%E6%9C%AC%E8%AF%AD%E6%B3%95/</guid><description>&lt;h1 id="数组"&gt;数组
&lt;/h1&gt;&lt;h2 id="索引"&gt;索引
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; arr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {0, 1, 2, 3, 4};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(arr);&lt;span style="color:#75715e"&gt;//[I@f6f4d33&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="地址符"&gt;地址符:
&lt;/h2&gt;&lt;p&gt;[ :表示当前是一个数组&lt;br&gt;
I :表示当前数组里边的元素类型为int&lt;br&gt;
@ :表示一个间隔符号&lt;br&gt;
6f4d33 :16进制的数组 ‘地址值’&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;int len = arr.length; //获取数组长度
int[] arr = new int [3]; //格式：数据类型[] = new 数据类型[数组长度]
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="数组默认动态初始化值"&gt;数组默认动态初始化值：
&lt;/h2&gt;&lt;p&gt;整数类型: 0;&lt;br&gt;
浮点数类型: 0.0;&lt;br&gt;
字符类型: &amp;lsquo;/u000&amp;rsquo; (空格)&lt;br&gt;
布尔类型: false&lt;br&gt;
引用数据类型: none&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="java内存分配"&gt;Java内存分配
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;栈：方法运行时使用的内存，比如main方法运行，进入方法栈中运行。&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;堆：存储对象或数组，new来创建的，都存储在堆内存&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;方法区：存储可以运行的class文件&lt;/strong&gt;&lt;br&gt;
本地方法栈： JVM在使用操作系统的时候使用，和开发无关&lt;br&gt;
寄存器：给CPU使用，和开发无关&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当两个数组指向同一个小空间时，其中一个数组对小空间中的值发生了改变，那么其他数组再次询问的时候都是修改后的结果了。例如：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; arr1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {11.&lt;span style="color:#a6e22e"&gt;22&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; arr2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; arr1;&lt;span style="color:#75715e"&gt;//此时arr2与arr1共用一个内存&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	sout(arr1&lt;span style="color:#f92672"&gt;[&lt;/span&gt;0&lt;span style="color:#f92672"&gt;]&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//11&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	sout(arr2&lt;span style="color:#f92672"&gt;[&lt;/span&gt;0&lt;span style="color:#f92672"&gt;]&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//11&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	arr2&lt;span style="color:#f92672"&gt;[&lt;/span&gt;0&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 33;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	sout(arr1&lt;span style="color:#f92672"&gt;[&lt;/span&gt;0&lt;span style="color:#f92672"&gt;]&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//33&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	sout(arr2&lt;span style="color:#f92672"&gt;[&lt;/span&gt;0&lt;span style="color:#f92672"&gt;]&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//33&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="方法"&gt;方法
&lt;/h1&gt;&lt;h2 id="方法是程序运行的最小执行单元类似于c中的函数"&gt;方法是程序运行的最小执行单元(类似于c中的函数)
&lt;/h2&gt;&lt;p&gt;经典例题：
需求：定义一个方法copyOfRange(int[] arr, int from ,int to)&lt;br&gt;
功能：将数组arr从索引from(包含)开始,到索引to(不包含)的元素复制带一个新的数组中,将新数组返回&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; test;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; java.util.Arrays;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; java.util.Scanner;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;method_test&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Scanner sc &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Scanner(System.&lt;span style="color:#a6e22e"&gt;in&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; arr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {1,2,3,4,5};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; num &lt;span style="color:#f92672"&gt;=&lt;/span&gt; copyOfRange(arr,0,4);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//打印新数组num的元素&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(Arrays.&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;(num));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;copyOfRange&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; arr, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; from, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;to&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//设置数组长度为 from - to&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; num &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;to&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; from&lt;span style="color:#f92672"&gt;]&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; from; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;to&lt;/span&gt;; i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; num&lt;span style="color:#f92672"&gt;[&lt;/span&gt;i&lt;span style="color:#f92672"&gt;-&lt;/span&gt;from&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; arr&lt;span style="color:#f92672"&gt;[&lt;/span&gt;i&lt;span style="color:#f92672"&gt;]&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; num;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;传递基本数据类型时，传递的是真实的数据，形参的改变，不影响实际参数的值&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;method_test&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; num &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 100;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;调用change方法前&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; num); &lt;span style="color:#75715e"&gt;//100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; change(num);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;调用change方法后&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; num); &lt;span style="color:#75715e"&gt;//100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;change&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; num){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; num &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 200;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;上述代码并未改变number的值，因为方法change()与方法main()存储在栈内存中，两个num并不一样.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;传递引用数据类型时，传递的是地址，形参的该百年，影响实际参数的值&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;method_test&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; arr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {10, 20, 30};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;调用change方法前&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; arr&lt;span style="color:#f92672"&gt;[&lt;/span&gt;0&lt;span style="color:#f92672"&gt;]&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//10;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; change(arr);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;调用change方法后&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; arr&lt;span style="color:#f92672"&gt;[&lt;/span&gt;0&lt;span style="color:#f92672"&gt;]&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//1000;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;change&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; arr){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; arr&lt;span style="color:#f92672"&gt;[&lt;/span&gt;0&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 1000;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;上述代码中 arr 数组的值发生了改变，原因是数组属于引用数据类型，其引用(内存地址)存储在栈内存中，而实际数据存储在堆内存中。main 方法与 change 方法共享同一个数组引用(即指向堆内存中同一个数组对象)，因此在 change 方法中对数组内容的修改会影响到 main 方法中访问该数组时的结果&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>面向对象</title><link>https://creat.asia/post/02-%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/</link><pubDate>Tue, 03 Feb 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/02-%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/</guid><description>&lt;h1 id="面向对象"&gt;面向对象
&lt;/h1&gt;&lt;h2 id="类和对象"&gt;类和对象
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;类（设计图)：是对象共同特征的描述；&lt;/li&gt;
&lt;li&gt;对象：是真实存在的具体东西&lt;br&gt;
&lt;strong&gt;在Java中，必须先设计类，才能获得对象&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;类名&lt;/span&gt;{ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	1.&lt;span style="color:#a6e22e"&gt;成员变量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	2.&lt;span style="color:#a6e22e"&gt;成员方法&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	3.&lt;span style="color:#a6e22e"&gt;构造器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	4.&lt;span style="color:#a6e22e"&gt;代码块&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	5.&lt;span style="color:#a6e22e"&gt;内部类&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Phone&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//属性（成员变量）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String brand;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;double&lt;/span&gt; price;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//行为（方法）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;call&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;playGame&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;定义类的注意事项&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;类名首字母建议大写，需要见名知意&lt;/li&gt;
&lt;li&gt;一个Java文件中可以定义多个class类，且只能一个类是public修饰，而且public修饰的类名必须为代码文件名（实际开发中还是建议一个文件定义一个class类）&lt;/li&gt;
&lt;li&gt;成员变量完整定义格式是：修饰符 数据类型 变量名称 = 初始化值；一般无需指定初始化值，存在默认值&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="封装"&gt;封装
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;告诉我们如何正确设计对象的属性和方法&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对象代表什么，就得封装对应的数据，并提供对应的行为&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="private关键字"&gt;private关键字
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;是一个权限修饰符&lt;/li&gt;
&lt;li&gt;可以修饰成员（成员变量和成员方法）&lt;/li&gt;
&lt;li&gt;被private修饰的成员只能在本类中才能访问
&lt;strong&gt;以下代码并不安全&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;GirlFriend&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String name; &lt;span style="color:#75715e"&gt;//会出现负数等不合理的值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; age;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String gneder;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;修改为以下代码&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;GirlFriend&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//将类中的变量转换为私有&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; age;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// set 赋值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;setAge&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; a){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(a &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; 18 &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; a &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; 50){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			age &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		}&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;非法数据&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// get 获取&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getAge&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; age;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="就近原则和this关键字"&gt;就近原则和this关键字
&lt;/h2&gt;&lt;h3 id="成员变量和局部变量"&gt;成员变量和局部变量
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;GrilFriend&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; age;	&lt;span style="color:#75715e"&gt;//成员变量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;method&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; age &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 10;	&lt;span style="color:#75715e"&gt;//局部变量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(age);&lt;span style="color:#75715e"&gt;//输出 10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;修改为this后可以调用成员变量&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;GrilFriend&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; age;	&lt;span style="color:#75715e"&gt;//成员变量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;method&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; age &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 10;	&lt;span style="color:#75715e"&gt;//局部变量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;age&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="构造方法"&gt;构造方法
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;构造方法也叫做构造器，构造函数&lt;/strong&gt;
&lt;strong&gt;作用：在创建对象的时候给成员变量进行初始化（赋值）。&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Student&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	修饰符 类名&lt;span style="color:#960050;background-color:#1e0010"&gt;（&lt;/span&gt;参数&lt;span style="color:#960050;background-color:#1e0010"&gt;）&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		方法体;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;特点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;方法名与类名相同，大小写也要一致&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;没有返回值类型，连void也没有&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;没有具体的返回值（不能由return带回结果数据）
空参构造：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Student&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System,out.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;执行空参构造&amp;#34;&lt;/span&gt;)	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;空参调用：&lt;code&gt;Student s = new Student()&lt;/code&gt;&lt;/p&gt;
&lt;!--如果我们自己没有写任何的构造方法--&gt;
&lt;!--那么虚拟机会给我们加一个空参构造方法--&gt;
&lt;p&gt;带参构造：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Student&lt;/span&gt;(String name,&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; age){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;执行带参构造&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; name;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;age&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; age;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;带参调用：&lt;code&gt;Student s = new Student(&amp;quot;Jim&amp;quot;，18);&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;注意事项：
1.构造方法的定义&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果没有定义构造方法，系统将给出一个默认的无参数的构造方法&lt;/li&gt;
&lt;li&gt;如果定义了构造方法，系统将不再提供默认的构造方法&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2.构造方法的重载&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;带参构造方法和无参构造方法，方法名相同，但是参数不同，这叫构造方法的重载&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3.推荐使用方式&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;无论是否使用，都手动书写无参数构造方法和带全部参数的构造方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="标准javabean"&gt;标准JavaBean
&lt;/h2&gt;&lt;h3 id="标准的javabean类"&gt;标准的Javabean类
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;类名需要见名知意&lt;/li&gt;
&lt;li&gt;成员变量使用private修饰&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;
&lt;li&gt;成员方法
&lt;ul&gt;
&lt;li&gt;提供每一个成员变量对应的&lt;strong&gt;setXxx() / getXxx()&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;如果还有其他行为，也需要写上&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="java内存分配"&gt;Java内存分配
&lt;/h2&gt;&lt;p&gt;new 一个对象：
1.加载class文件
2.申明局部变量
3.在堆内存中开辟一个空间
4.默认初始化
5.显示初始化
6.构造方法初始化
7.将堆内存中的地址值赋值给左边的局部变量&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;this本质：代表方法调用者的地址值&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;this作用：区分局部变量和成员变量&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="一些实例"&gt;一些实例&amp;hellip;
&lt;/h1&gt;&lt;h2 id="键盘录入"&gt;键盘录入:
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;第一套体系&lt;/strong&gt; (遇到空格,制表符,回车就停止接收)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	nextInt(); 	 &lt;span style="color:#75715e"&gt;//接收整数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	nextDouble(); &lt;span style="color:#75715e"&gt;//接收小数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	next();		 &lt;span style="color:#75715e"&gt;//接收字符串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;第二套体系&lt;/strong&gt;(遇到回车停止接收)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	nextLine(); &lt;span style="color:#75715e"&gt;//接收字符串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>字符串</title><link>https://creat.asia/post/03-%E5%AD%97%E7%AC%A6%E4%B8%B2/</link><pubDate>Tue, 03 Feb 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/03-%E5%AD%97%E7%AC%A6%E4%B8%B2/</guid><description>&lt;h1 id="字符串"&gt;字符串
&lt;/h1&gt;&lt;h2 id="string"&gt;String
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;字符串在内存中存储的是地址&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="创建string对象的两种方式"&gt;创建String对象的两种方式
&lt;/h3&gt;&lt;p&gt;１．直接赋值
&lt;code&gt;String name = &amp;quot;MyString&amp;quot;&lt;/code&gt;&lt;br&gt;
2.使用new关键字构造&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//空参构造&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String s1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; String(); 		&lt;span style="color:#75715e"&gt;// 空&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//传递一个字符串，根据传递的字符串内容再创建一个新的字符串对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String s2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; String(&lt;span style="color:#e6db74"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;); 	&lt;span style="color:#75715e"&gt;//abc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//*传递一个字符数组，根据一个字符数组的内容，创建一个新的字符串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;char&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; ch &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {&lt;span style="color:#e6db74"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;b&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;c&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;d&amp;#39;&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String s3 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; String(ch);		&lt;span style="color:#75715e"&gt;//abcd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//*传递一个字节数组，根据一个字节数组的内容，创建一个新的字符串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; bytes &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {97,98,99,100}; &lt;span style="color:#75715e"&gt;//传递ASCII码&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String s4 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; String(bytes); &lt;span style="color:#75715e"&gt;//abcd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="字符串的比较"&gt;字符串的比较
&lt;/h3&gt;&lt;p&gt;​	先了解&amp;quot;==&amp;ldquo;比较的是什么，在&lt;del&gt;基本数据类型&lt;/del&gt;中&amp;rdquo;==&amp;ldquo;比较的是具体的&lt;strong&gt;数据值&lt;/strong&gt;，但是在&lt;del&gt;引用数据类型&lt;/del&gt;中，&amp;quot;==&amp;ldquo;比的是&lt;strong&gt;地址值&lt;/strong&gt;，所以在字符串的比较中不能用 &amp;ldquo;==&amp;quot;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String s1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String s2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	sout(s1 &lt;span style="color:#f92672"&gt;==&lt;/span&gt; s2); &lt;span style="color:#75715e"&gt;// true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String s1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; String(&lt;span style="color:#e6db74"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;);&lt;span style="color:#75715e"&gt;//记录堆里面的地址值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String s2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;;			 &lt;span style="color:#75715e"&gt;//记录串池中的地址值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	sout(s1 &lt;span style="color:#f92672"&gt;==&lt;/span&gt; s2); &lt;span style="color:#75715e"&gt;// false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="equals-与-equalsignorecase"&gt;equals 与 equalsIgnoreCase
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;boolean equals 方法：&lt;strong&gt;完全一样结果才是true&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;boolean equalsIgnoreCase方法：&lt;strong&gt;忽略大小写的比较&lt;/strong&gt;&lt;br&gt;
&lt;u&gt;（忽略大小写只能是英文状态下的）&lt;/u&gt;&lt;br&gt;
&lt;code&gt;	boolean bool = s1.equals(s2)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		Scanner sc &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Scanner(System.&lt;span style="color:#a6e22e"&gt;in&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		String str1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; sc.&lt;span style="color:#a6e22e"&gt;next&lt;/span&gt;(); &lt;span style="color:#75715e"&gt;//abc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		String str2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;;	&lt;span style="color:#75715e"&gt;//赋值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		Souy(str1 &lt;span style="color:#f92672"&gt;==&lt;/span&gt; str2) &lt;span style="color:#75715e"&gt;//false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]&lt;/p&gt;
&lt;p&gt;两者不一样，键盘录入得到的字符串其实是new出来的，两者的地址值不一样，因此一定要用equals比较字符串&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id="遍历字符串"&gt;遍历字符串
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;public charAt(int index)&lt;/code&gt; 根据索引返回字符&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;public int length()&lt;/code&gt; 	 返回此字符串的长度&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;String substring(int beginindex, int endlindex)&lt;/code&gt; 截取字符串&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
包头不包尾，包左不包右 ，对原字符拆没影响
重构：&lt;code&gt;String substring (int beginindex)&lt;/code&gt; 截取到末尾&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id="替换字符串"&gt;替换字符串
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;String replace(旧值，新值)&lt;/code&gt; 替换&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="stringbulider"&gt;StringBulider
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;提高字符串的操作效率&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="stringbuilder-常用方法"&gt;StringBuilder 常用方法
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;public StringBulider()&lt;/code&gt;
创建一个空白可变的字符串对象，不含有任何内容&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
&lt;em&gt;StringBuilder 是 Java 已经写好的类&lt;/em&gt;
&lt;em&gt;Java在底层对他做了一些特殊处理&lt;/em&gt;
&lt;em&gt;打印对象不是&lt;strong&gt;地址值&lt;/strong&gt;而是&lt;strong&gt;属性值&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;public StringBuilder append(任意类型)&lt;/code&gt;
添加数据，返回对象本身&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;public StringBuilder reverse()&lt;/code&gt;
反转容器中的内容&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;public int length()&lt;/code&gt;
返回长度（字符出现的个数）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;public String toString()&lt;/code&gt;
通过toString()就可以实现把 StringBuilder 转化为 String&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;del&gt;&lt;strong&gt;以下是对于StringBuilder 和 toString的演示&lt;/strong&gt;&lt;/del&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;// 此时并不是字符串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	StringBuilder sb &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; StringBuilder(&lt;span style="color:#e6db74"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sb.&lt;span style="color:#a6e22e"&gt;append&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;111&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sb.&lt;span style="color:#a6e22e"&gt;append&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;222&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//再将 StringBuilder 变回字符串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String str &lt;span style="color:#f92672"&gt;=&lt;/span&gt; sb.&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(str);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!TIP]
&lt;strong&gt;补充&lt;/strong&gt; 链式编程：当我们在调用一个方法的时候，不需要用变量接收他的结果，可以继续调用其他方法。&lt;/p&gt;
&lt;p&gt;例如：&lt;code&gt;int len getString().substring(1).replace(&amp;quot;A&amp;quot;,&amp;quot;Q&amp;quot;).length()&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="stringjoiner"&gt;StringJoiner
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;StringJoiner 跟 StringBuilder 一样，也可以看成是一个容器，创建之后里边的内容是可变的。&lt;/li&gt;
&lt;li&gt;作用：提高字符串的操作效率，而且代码编写特别简介，但是目前市场很少有人用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JDK8才出现&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="stringjoiner--的构造方法"&gt;StringJoiner 的构造方法
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;public StringJoiner(间隔符号)&lt;/code&gt; 创建一个StringJoiner对象,指定拼接时的&lt;strong&gt;间隔符号&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;public StringJoiner(间隔符号,开始符号,结束符号)&lt;/code&gt; 创建一个StringJoiner对象，指定拼接时的&lt;strong&gt;间隔符号,开始符号,结束符号&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="stringjoiner-的成员方法"&gt;StringJoiner 的成员方法
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;public StringJoiner add(添加的内容)&lt;/code&gt; 添加数据，并返回数据本身&lt;/li&gt;
&lt;li&gt;&lt;code&gt;public int length()&lt;/code&gt; 返回长度（字符出现的个数）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;public String toString()&lt;/code&gt; 返回一个字符串（该字符串就是拼接之后的效果）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="字符串原理"&gt;字符串原理
&lt;/h2&gt;&lt;p&gt;1.字符串存储的原理
- 直接赋值会复用字符串常量池中的
- new 出来的不会复用，而是开辟一个新的空间&lt;/p&gt;
&lt;p&gt;2.==号比较的到底是什么？
- 基本数据类型 &lt;strong&gt;比较数据值&lt;/strong&gt;
- 引用数据类型 &lt;strong&gt;比较地址值&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;3.字符串拼接的底层原理&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Test2&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String ss &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 记录串池中的地址值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String s &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;b&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;c&amp;#34;&lt;/span&gt;; &lt;span style="color:#75715e"&gt;//拼接时没有变量,会复用串池中的字符串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(s); &lt;span style="color:#75715e"&gt;//abc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
拼接的时候没有变量，都是字符串
触发字符串的优化机制
在编译的时候就已经是最终结果了。&lt;/p&gt;
&lt;p&gt;在编译的时候，就会将&amp;quot;a&amp;rdquo;+&amp;ldquo;b&amp;rdquo;+&amp;ldquo;c&amp;rdquo; 拼接为 &amp;ldquo;abc&amp;rdquo;&amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Test2&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String s1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String s2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; s1 &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;b&amp;#34;&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String s3 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; s2 &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;c&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(s3);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
相当于先创建了一个new StringBuilder 对象
做完一系列操作后在使用 toString 转化为字符串
new StringBuilder().append(s1).qppend(&amp;ldquo;b&amp;rdquo;).toString();&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Test2&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String s1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String s2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;b&amp;#34;&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String s3 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;c&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String s4 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; s1 &lt;span style="color:#f92672"&gt;+&lt;/span&gt; s2 &lt;span style="color:#f92672"&gt;+&lt;/span&gt; s3 ; &lt;span style="color:#75715e"&gt;//创建了四个SB对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(s3);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
JDK8 之前：每次以上的字符串相加都会创建两个SB对象
JDK8 及之后，编译器会对连续的字符串拼接操作进行优化，通过一个StringBuilder完成所有拼接，并预先计算和分配合适的容量，从而减少对象创建和数组扩容的开销。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;总结：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;如果没有变量参与，都是字符串直接相加，编译之后就是拼接的结果，会复用字符串池&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;如果有变量参与，每一行拼接的代码，都会在内存中创建新的字符串，浪费内存&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;4.StringBuilder 提高效率原理图&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;所有要拼接的内容都会往StringBuilder中放，不会创建很多无用空间，节约内存&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;5.StringBuilder 源码分析&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;默认创建一个长度为16的字节数组&lt;/li&gt;
&lt;li&gt;添加的内容长度小于16，直接存&lt;/li&gt;
&lt;li&gt;添加的内容大于16 会扩容（原来的容量*2+2）&lt;/li&gt;
&lt;li&gt;如果扩容后还不够，以实际长度为准&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="补充内容"&gt;补充内容
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;startsWith(&amp;quot;String&amp;quot;) 或 startsWith(&amp;quot;String&amp;quot;,begin,end)&lt;/code&gt;检测字符串（范围）开头&lt;/p&gt;</description></item><item><title>ArrList集合</title><link>https://creat.asia/post/04-arrlist%E9%9B%86%E5%90%88/</link><pubDate>Tue, 03 Feb 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/04-arrlist%E9%9B%86%E5%90%88/</guid><description>&lt;h1 id="集合"&gt;集合
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;类似于vector&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
集合的每个位置存储的是地址值&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="arraylist"&gt;ArrayList
&lt;/h2&gt;&lt;h3 id="成员方法增删改查"&gt;成员方法（增删改查）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;boolean add(E e)&lt;/code&gt; 添加元素，返回值表示是否添加成功
一般直接用&lt;code&gt;list.add(E e)&lt;/code&gt;，因为只要添加就会返回&lt;strong&gt;true&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;boolean add(E e)&lt;/code&gt; 删除指定元素，返回值代表是否删除成功
优先删除索引小的元素&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;E remove(int index&lt;/code&gt; 删除指定索引的元素，返回被删除的元素&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;E set(int index,E e)&lt;/code&gt; 修改指定索引下的元素，返回原来的元素&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;E get(int index)&lt;/code&gt; 获取指定索引的元素&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;int size()&lt;/code&gt; 集合的长度&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id="基本数据类型对应的包装类"&gt;基本数据类型对应的包装类
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;byte &amp;mdash;&amp;gt; Byte&lt;/li&gt;
&lt;li&gt;short &amp;mdash;&amp;gt; Short&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;char &amp;mdash;&amp;gt; Character&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;int &amp;mdash; &amp;gt; Integer&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;long &amp;mdash;&amp;gt; Long&lt;/li&gt;
&lt;li&gt;float &amp;mdash;&amp;gt; Float&lt;/li&gt;
&lt;li&gt;double &amp;mdash;&amp;gt; Double&lt;/li&gt;
&lt;li&gt;boolean &amp;mdash;&amp;gt; Boolean&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;</description></item><item><title>面向对象进阶</title><link>https://creat.asia/post/05-%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E8%BF%9B%E9%98%B6/</link><pubDate>Tue, 03 Feb 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/05-%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E8%BF%9B%E9%98%B6/</guid><description>&lt;h1 id="static静态"&gt;static（静态）
&lt;/h1&gt;&lt;h2 id="静态变量"&gt;静态变量
&lt;/h2&gt;&lt;p&gt;在JavaBean中，不加static只能供一个对象使用&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;被 static 修饰的变量属于类，所有实例共享同一个变量值&lt;/li&gt;
&lt;li&gt;在内存中只存在一份，当类被加载时初始化&lt;/li&gt;
&lt;li&gt;通常用于表示所有对象共有的属性&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Student&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 静态变量（类变量）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; String schoolName &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;阳光中学&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 实例变量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String name;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Student&lt;/span&gt;(String name) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; name;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 直接通过类名访问静态变量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(Student.&lt;span style="color:#a6e22e"&gt;schoolName&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 输出：阳光中学&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Student s1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Student(&lt;span style="color:#e6db74"&gt;&amp;#34;张三&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Student s2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Student(&lt;span style="color:#e6db74"&gt;&amp;#34;李四&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 也可以通过实例访问（不推荐）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(s1.&lt;span style="color:#a6e22e"&gt;schoolName&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 输出：阳光中学&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 修改静态变量，所有实例都会受到影响&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Student.&lt;span style="color:#a6e22e"&gt;schoolName&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;星光中学&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(s2.&lt;span style="color:#a6e22e"&gt;schoolName&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 输出：星光中学&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}	
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
JDK8之前，静态区处于方法区里面。
JDK7之后，静态区处于堆空间之中。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="静态方法"&gt;静态方法
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;多用在测试类和工具类当中&lt;/li&gt;
&lt;li&gt;JavaBean中很少用&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
JavaBean类：用来描述一类事物的类
测试类：用来检查其他类是否书写正确，带有main方法的类，是程序的入口
工具类：不是用来描述一类事物的，而是帮我们做一些事情的类&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="工具类"&gt;工具类
&lt;/h3&gt;&lt;p&gt;1.类名见名知意
2.私有化构造方法&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ArrUtil&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ArrUtil&lt;/span&gt;(){}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;private ArrayUtil() {} 是一个私有构造方法
由于构造方法被声明为 private（私有），这意味着在类的外部无法调		用这个构造方法，也就无法创建 ArrayUtil 类的对象实例。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;防止这个工具类被意外地实例化&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
如果不写这个私有构造方法，Java 会默认提供一个公共的无参构造方法
这样别人就可能误将其当作普通 JavaBean，写出new ArrayUtil()这样的代码（虽然创建了对象也没用，但不符合设计意图）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;3.方法定义/为静态&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="static的注意事项"&gt;static的注意事项
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;静态方法只能访问静态变量和静态方法&lt;/li&gt;
&lt;li&gt;非静态方法可以访问静态变量或静态方法，也可以访问非静态的成员变量和非静态的成员方法&lt;/li&gt;
&lt;li&gt;静态方法中没有this关键字&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Student&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String name;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; age;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; String teachername;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//this:表示当前方法调用者的地址值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//这个this:是由虚拟机赋值的&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;show1&lt;/span&gt;(Student &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;){&lt;span style="color:#75715e"&gt;//此处的this是虚拟机暗加的&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		sout(&lt;span style="color:#e6db74"&gt;&amp;#34;this:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;);&lt;span style="color:#75715e"&gt;//地址值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		sout(name&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;,&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;age&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;,&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;teachername);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//实际上是this.name和this.age和this.teachername&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		show2();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//实际上是this.show2();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//意思是当前show1调用的对象继续调用show2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;show2&lt;/span&gt;(){}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	poublic &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;method&lt;/span&gt;(){&lt;span style="color:#75715e"&gt;//此处的静态方法却不会有this关键字&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//不可调用非静态的成员变量和成员方法&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		sout(&lt;span style="color:#e6db74"&gt;&amp;#34;静态方法&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;StudentTest&lt;/span&gt;(){		
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		Student.&lt;span style="color:#a6e22e"&gt;teachername&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;老师姓名&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		Student s1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Student();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		sout(&lt;span style="color:#e6db74"&gt;&amp;#34;s1:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; s1);&lt;span style="color:#75715e"&gt;//地址值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		s1.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;张三&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		s1.&lt;span style="color:#a6e22e"&gt;age&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 23;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		s1.&lt;span style="color:#a6e22e"&gt;show1&lt;/span&gt;(); &lt;span style="color:#75715e"&gt;//此处的s1对应this&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		Student s2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Stduent();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sout(&lt;span style="color:#e6db74"&gt;&amp;#34;s2:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; s2);&lt;span style="color:#75715e"&gt;//地址值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		s2.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;李四&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		s2.&lt;span style="color:#a6e22e"&gt;age&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 24;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		s2.&lt;span style="color:#a6e22e"&gt;show1&lt;/span&gt;();&lt;span style="color:#75715e"&gt;//此处的s2对应this&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;打印后，s1与this的地址值相同，s2与this的地址相同。&lt;/p&gt;
&lt;h3 id="内存的加载"&gt;内存的加载
&lt;/h3&gt;&lt;p&gt;静态：随着类的加载而加载&lt;br&gt;
非静态：与对象有关&lt;/p&gt;
&lt;h3 id="main方法"&gt;main方法
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;HelloWorld&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#75715e"&gt;//[]：数组&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#75715e"&gt;//String:数据类型&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#75715e"&gt;//args：数组名&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			sout(&lt;span style="color:#e6db74"&gt;&amp;#34;HelloWorld&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;public：被JVM调用，访问权限足够大&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;static：被JVM调用，不用创建对象，直接类名访问。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;因为main方法是静态的，所以测试类中的其他方法也需要是静态的&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;void：被JVM调用，不需要给JVM返回值&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;main：一个通用的名称，不是关键字，但是被JVM识别&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;String[] args：以前用于接受键盘录入数据，现在没用&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="继承"&gt;继承
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Java中提供一个关键字extends，用这个关键字，我们可以让一个类和另一个类建立起 &lt;u&gt;继承关系&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;public class Student extends Person{}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Studet成为子类（派生类），Person称为父类（基类或超类）。&lt;/strong&gt;
使用继承的好处：
&lt;ul&gt;
&lt;li&gt;可以把多个子类中重复的代码抽取到父类中了，提高代码的复用性&lt;/li&gt;
&lt;li&gt;子类可以在父类的基础上，增加其他的功能，使子类更强大。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;？什么时候用继承：&lt;/strong&gt;
&lt;strong&gt;当类与类之间，存在相同（共性）的内容，并满足子类是父类的一种，就可以考虑用继承，来优化代码。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="继承特点"&gt;继承特点
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;Java只支持单继承，不支持多继承，但支持多层继承。&lt;/strong&gt;&lt;/p&gt;
&lt;ul&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;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
每一个类都直接或间接继承于Object&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;构造方法不可被继承&lt;/li&gt;
&lt;li&gt;成员变量私有和非私有都能被继承（私有不可直接使用）&lt;/li&gt;
&lt;li&gt;成员方法只有&lt;strong&gt;非私有非static非final&lt;/strong&gt;（能被加入虚方法表）能被继承&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h2 id="在继承中-成员变量的访问特点"&gt;在继承中 成员变量的访问特点
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;就近原则&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Fu&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Fu&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Zi&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; Fu{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Zi&amp;#34;&lt;/span&gt;;&lt;span style="color:#75715e"&gt;//若没有此语句会打印Fu&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ziShow&lt;/span&gt;(){		
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		String name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;ziShow&amp;#34;&lt;/span&gt;;&lt;span style="color:#75715e"&gt;//若没有此语句会打印Zi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		sout(name); &lt;span style="color:#75715e"&gt;//ziShow...依次向上找name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Fu&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Fu&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Zi&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; Fu{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Zi&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ziShow&lt;/span&gt;(){		
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		String name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;ziShow&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//局部-&amp;gt;本类-&amp;gt;父类&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		sout(name); &lt;span style="color:#75715e"&gt;//ziShow&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		sout(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;);&lt;span style="color:#75715e"&gt;//Zi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//this:本类&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		sout(&lt;span style="color:#66d9ef"&gt;super&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;);&lt;span style="color:#75715e"&gt;//Fu&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//super:父类&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;name：从局部位置开始往上找&amp;hellip; 局部 &amp;ndash;&amp;gt; 本类 &amp;ndash;&amp;gt; 父类&lt;/strong&gt;
&lt;strong&gt;this.name：从本类成员位置开始往上找&amp;hellip; 本类 &amp;ndash;&amp;gt; 父类&lt;/strong&gt;
&lt;strong&gt;super.name：从父类成员位置开始往上找&amp;hellip;父类&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="在继承中成员方法的访问特点"&gt;在继承中成员方法的访问特点
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;直接调用满足就近原则，super调用直接访问父类&lt;/strong&gt;
方法的重写：
&lt;u&gt;&lt;strong&gt;当父类的方法不能满足子类现在的需求时，需要进行方法重写&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;书写格式：
&lt;strong&gt;在继承体系中，子类出现了和父类中一模一样的方法声明，我们就称子类这个方法是重写的方法。&lt;/strong&gt;
@Override重写注解
&lt;strong&gt;@Override是放在重写后的方法上，校验子类重写时语法是否正确。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="方法重写的本质"&gt;方法重写的本质
&lt;/h3&gt;&lt;p&gt;A类&amp;mdash;&amp;mdash;-继承&amp;mdash;&amp;mdash;&amp;gt;B类&amp;mdash;继承&amp;mdash;&amp;gt;C类&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;strong&gt;子类覆盖了从父类继承下来的虚方法表里的方法&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;写入方法&lt;/th&gt;
					&lt;th&gt;A（method2）&lt;/th&gt;
					&lt;th&gt;B（method2）&lt;/th&gt;
					&lt;th&gt;C（method1，method2）&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;虚方法表&lt;/td&gt;
					&lt;td&gt;C：method1&lt;/td&gt;
					&lt;td&gt;C：method1&lt;/td&gt;
					&lt;td&gt;C：method1&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;A：method2（）重写&lt;/td&gt;
					&lt;td&gt;B：method2（重写）&lt;/td&gt;
					&lt;td&gt;C：method2&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
&lt;strong&gt;1.重写方法的名称、形参列表必须与父类中的一致&lt;/strong&gt;
&lt;strong&gt;2.子类重写父方法时.，访问权限子类必须大于等于父类（空 &amp;lt; protected &amp;lt; public）&lt;/strong&gt;
&lt;strong&gt;3.子类重写父类方法时，返回值类型必须小于等于父类&lt;/strong&gt;
&lt;u&gt;&lt;strong&gt;4.重写的方法尽量和父类保持一致&lt;/strong&gt;&lt;/u&gt;
&lt;strong&gt;5.只有被添加到虚方法表中的方法才能被重写&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="在继承中构造方法的访问特点"&gt;在继承中构造方法的访问特点
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;父类中的构造方法不会被子类继承，但是可以使用super调用。&lt;/li&gt;
&lt;li&gt;子类中所有的构造方法默认先访问父类中的无参构造，在执行自己。（子类构造方法第一句默认是super()，不写也存在，若想调用父类有参构造，则必须使用super）&lt;/li&gt;
&lt;li&gt;如果想要访问父类的有参构造，必须手动书写&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="this-与-super"&gt;this 与 super
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;this:理解为一个变量，表示当前方法调用者的地址值。&lt;/strong&gt;
&lt;strong&gt;super:代表父类存储空间。&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;关键字&lt;/th&gt;
					&lt;th&gt;访问成员变量&lt;/th&gt;
					&lt;th&gt;访问成员方法&lt;/th&gt;
					&lt;th&gt;访问构造方法&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;this&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;this.成员变量&amp;mdash;访问本类成员变量&lt;/td&gt;
					&lt;td&gt;this.成员方法&amp;mdash;访问本类成员方法&lt;/td&gt;
					&lt;td&gt;&lt;u&gt;this(&amp;hellip;)&amp;mdash;访问本类构造方法&lt;/u&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;super&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;super.成员变量&amp;mdash;访问父类成员变量&lt;/td&gt;
					&lt;td&gt;super.成员方法&amp;mdash;访问父类成员方法&lt;/td&gt;
					&lt;td&gt;super(&amp;hellip;)&amp;mdash;访问父类构造方法&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;this()：&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
在子类中可以直接快捷使用构造函数&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Student&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String name;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; age;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String school;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Student(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	&lt;span style="color:#75715e"&gt;//表示调用本类的其他构造方法&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	&lt;span style="color:#75715e"&gt;//虚拟机不会再添加super();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;,0,&lt;span style="color:#e6db74"&gt;&amp;#34;默认大学&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Student&lt;/span&gt;(String name, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; age, String school) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	&lt;span style="color:#75715e"&gt;//因为调用之后此处有一个super();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; name;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;age&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; age;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;school&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; school;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="多态"&gt;多态
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;同类型的对象，表现出不同的形态&lt;/strong&gt;
&lt;strong&gt;表现形式：&lt;/strong&gt;&lt;code&gt;父类类型 对象名称 = 子类对象;&lt;/code&gt;
前提：
&lt;strong&gt;1.有继承/实现关系&lt;br&gt;
2.有父类引用指向子类对象&lt;br&gt;
3.有方法重写&lt;/strong&gt;&lt;br&gt;
好处：使用父类型作为参数，可以接收所有子类对象，体现多态的扩展性与便利。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Test&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Student s &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Student(&lt;span style="color:#e6db74"&gt;&amp;#34;张三&amp;#34;&lt;/span&gt;,18);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Teacher t &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Teacher(&lt;span style="color:#e6db74"&gt;&amp;#34;王建国&amp;#34;&lt;/span&gt;,22);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Admin a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Admin(&lt;span style="color:#e6db74"&gt;&amp;#34;管理员&amp;#34;&lt;/span&gt;,20);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; register(s);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; register(t);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; register(a);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//接收老师，学生，管理员&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;register&lt;/span&gt;(Person p){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	&lt;span style="color:#75715e"&gt;//在每一个子类中都重写了show方法&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	&lt;span style="color:#75715e"&gt;//p.show()，会直接指向子类的方法&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p.&lt;span style="color:#a6e22e"&gt;show&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="多态调用成员变量的特点"&gt;多态调用成员变量的特点
&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;`父类类型 对象名称 = 子类对象;`
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;变量调用：编译看左边，运行也看左边&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//Animal 默认name为&amp;#34;动物&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//Dog 默认name为&amp;#34;狗&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Animal a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Dog();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//编译看左边：Javac编译代码的时候，会看左边的父类有没有这个变量，如果有，编译成功，反之失败&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//运行也看左边：Java运行代码的时候，实际获取的就是左边父类中成员变量的值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	sout(a.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;);&lt;span style="color:#75715e"&gt;//动物&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;方法调用：编译看左边，运行看右边&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Animal a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Dog();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//编译看左边：Javac编译代码的时候，会看左边的父类中有没有这个方法，如果有，编译成功，反之失败&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//运行看右边：Java运行代码的时候，实际上运行的是子类中的方法&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	a.&lt;span style="color:#a6e22e"&gt;show&lt;/span&gt;();&lt;span style="color:#75715e"&gt;//Dog---show方法&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
&lt;em&gt;&lt;em&gt;成员变量：在子类的对象中，会把父类的成员变量也继承下来。父：name，子：name&lt;/em&gt;（本质上时在内存中开辟了一个地址空间存储两个name）&lt;/em&gt;
&lt;strong&gt;成员方法：如果子类对方法进行了重写，那么在虚方法表中是会把父类的方法进行覆盖。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;优点：使用父类型作为参数，可以接收所有子类对象&lt;br&gt;
弊端：不能调用子类的特有功能（方法），但是可以通过强制转换解决&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Animal a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Dog();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Dog d &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (Dog)a;&lt;span style="color:#75715e"&gt;//大范围 -&amp;gt; 小范围	&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//判断对象是不是某一个类中的 instanceof&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(a &lt;span style="color:#66d9ef"&gt;instanceof&lt;/span&gt; Dog){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		Dog d &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (Dog)a;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		d.&lt;span style="color:#a6e22e"&gt;lookHome&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		Cat c &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (Dog)a;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		c.&lt;span style="color:#a6e22e"&gt;catchMouse&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		sout(&lt;span style="color:#e6db74"&gt;&amp;#34;没有这个类型，无法转换&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//新特性&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(a &lt;span style="color:#66d9ef"&gt;instanceof&lt;/span&gt; Dog d){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//		Dog d = (Dog)a;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		d.&lt;span style="color:#a6e22e"&gt;lookHome&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(a &lt;span style="color:#66d9ef"&gt;instanceof&lt;/span&gt; Cat c){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//		Cat c = (Dog)a;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		c.&lt;span style="color:#a6e22e"&gt;catchMouse&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		sout(&lt;span style="color:#e6db74"&gt;&amp;#34;没有这个类型，无法转换&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="包"&gt;包
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;包就是文件夹，用来管理不同类的Java类，方便后期代码维护&lt;/strong&gt;
&lt;del&gt;包名一般都用小写&lt;/del&gt;
使用其他类的规则：
1.使用同一个包中的类时，不需要导包&lt;br&gt;
2.使用Java.lang包中的类时，不需要导包&lt;br&gt;
3.其他情况都需要导报&lt;br&gt;
4.如果同时使用两个包的同名类，需要用 全类名&lt;/p&gt;
&lt;p&gt;全类名：包名 + 类名&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="final"&gt;final
&lt;/h1&gt;&lt;p&gt;方法：表明该方法时最终方法，不能被重写&lt;br&gt;
类：表明该类是最终类，不能被继承&lt;br&gt;
变量：叫做常量，只能被赋值一次 (c/c++中的const)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
常量的命名规范
单个单词：全部大写
多个单词：全部大写，单词之间用下划线隔开&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
final修饰的变量是基本类型：那么变量存储的&lt;strong&gt;数据值&lt;/strong&gt;不能发生改变&lt;br&gt;
final修饰的变量是引用类型：那么变量存储的&lt;strong&gt;地址值&lt;/strong&gt;不能发生改变，对象内部的可以改变（静态指针）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//记录的地址值不能发生改变&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; Student S &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Student(&lt;span style="color:#e6db74"&gt;&amp;#34;张三&amp;#34;&lt;/span&gt;,23);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//	S = new Student(); ！报错&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	S.&lt;span style="color:#a6e22e"&gt;setName&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;李四&amp;#34;&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 对象内部可以改变&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;u&gt;补充：字符串不可变的原因是&lt;strong&gt;String&lt;/strong&gt;是由&lt;strong&gt;final和private&lt;/strong&gt;存储的数组&lt;/u&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="权限修饰符"&gt;权限修饰符
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;控制一个成员能够被访问的范围&lt;/li&gt;
&lt;li&gt;可以修饰成员变量，方法，构造方法，内部类。&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;修饰符&lt;/th&gt;
					&lt;th&gt;同一个类中&lt;/th&gt;
					&lt;th&gt;同一个包中其他类&lt;/th&gt;
					&lt;th&gt;不同包下的子类&lt;/th&gt;
					&lt;th&gt;不同包下的无关类&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;private&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;√&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;空着不写（默认）&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;√&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;√&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;protected&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;√&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;√&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;√&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;public&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;√&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;√&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;√&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;√&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h1 id="代码块"&gt;代码块
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;构造代码块：从多个构造方法中抽取重复代码，而且会先于构造方法的执行&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="静态代码块"&gt;静态代码块
&lt;/h2&gt;&lt;p&gt;格式：&lt;code&gt;static{}&lt;/code&gt;
特点：需要static关键字修饰，随着类的加载而加载，并且自动触发，只执行一次。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;static&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		sout(&lt;span style="color:#e6db74"&gt;&amp;#34;执行静态代码块&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//随着类的加载而加载，并且只执行一次。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;应用：数据初始化&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//sattic里面只能用static&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Student&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;list &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;static&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		sout(&lt;span style="color:#e6db74"&gt;&amp;#34;初始化&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; staic &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="抽象类和抽象方法"&gt;抽象类和抽象方法
&lt;/h1&gt;&lt;p&gt;抽象类: 是一种不能被实例化的类，它主要用于定义其他类（子类）的共同接口和部分实现.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;抽象方法一定在抽象类中&lt;/li&gt;
&lt;li&gt;抽象类不一定含有抽象方法.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;抽象类的主要特点：
1.&lt;strong&gt;不能实例化&lt;/strong&gt;：抽象类本身不能创建对象，只能作为父类被继承&lt;br&gt;
2.&lt;strong&gt;可以包含抽象方法&lt;/strong&gt;：抽象方法只有声明，没有具体实现，必须由子类实现&lt;br&gt;
3.&lt;strong&gt;可以包含具体方法&lt;/strong&gt;：抽象类也可以有已实现的方法，供子类直接使用或重写&lt;br&gt;
4.&lt;strong&gt;子类必须实现所有抽象方法&lt;/strong&gt;：如果子类没有实现父类的所有抽象方法，那么子类也必须是抽象类&lt;/p&gt;
&lt;h1 id="接口"&gt;接口
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;接口用关键字**&lt;del&gt;interface&lt;/del&gt;**来定义&lt;br&gt;
&lt;code&gt;public interface 接口名{}&lt;/code&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;del&gt;implements&lt;/del&gt;**关键字表示&lt;br&gt;
&lt;code&gt;public class 类名 implement 接口名{}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;接口的子类（实现类）
要么重写接口中的所有抽象方法
要么是抽象类&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
1.接口和类的实现关系，可以&lt;strong&gt;单实现&lt;/strong&gt;，也可以&lt;strong&gt;多实现&lt;/strong&gt;。
&lt;code&gt;public class 类名 implements 接口名1，接口名2{}&lt;/code&gt;
2.实现类还可以在继承一个类的同时实现多个接口。
&lt;code&gt;public class 类名 extends 父类 inplements 接口名1，接口名2{}&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="成员特点和接口中的各种关系"&gt;成员特点和接口中的各种关系
&lt;/h2&gt;&lt;p&gt;接口中成员的特点&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;成员变量&lt;/p&gt;
&lt;p&gt;只能是常量
默认修饰符：public static final&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;构造方法：没有&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;成员方法
只能是抽象方法
默认修饰符：public abstract&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;JDK7以前&lt;/strong&gt;：接口中只能定义抽象方法&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;JDK8的新特性&lt;/strong&gt;：接口中可以定义有方法体的方法&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;JDK9的新特性&lt;/strong&gt;：接口中可以定义私有方法&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="接口和类的关系"&gt;接口和类的关系
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;类和类的关系&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;继承关系，只能单继承，不能多继承，但是可以多层继承&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;类和接口的关系&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;实现关系，可以单实现，也可以多实现，还可以在继承一个类同时实现多个接口&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;接口和接口的关系&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;继承关系，可以单继承，也可以多继承&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="接口中的默认方法"&gt;接口中的默认方法
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;格式：&lt;/strong&gt;
&lt;code&gt;public default 返回值类型 方法名（参数列表）{	}&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="接口中默认方法的注意事项"&gt;接口中默认方法的注意事项
&lt;/h3&gt;&lt;p&gt;1.默认方法不是抽象方法，&lt;strong&gt;所以不强制被重写&lt;/strong&gt;。但是如果被重写，&lt;strong&gt;重写的时候去掉default关键字&lt;/strong&gt;&lt;br&gt;
2.&lt;strong&gt;public&lt;/strong&gt;可以省略，default不能省略&lt;br&gt;
3.如果实现了多个接口，多个接口中存在相同名字的默认方法，子类就必须对该方法进行重写。&lt;/p&gt;
&lt;h2 id="接口中的静态方法"&gt;接口中的静态方法
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;JDK8以后 允许在接口中国定义静态方法，需要用static修饰&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;接口中静态方法的额定义格式 ：&lt;br&gt;
-　格式:	public static 返回值类型　方法名（参数列表）{ }&lt;br&gt;
-　范例:	public static void show(){ }&lt;/p&gt;
&lt;p&gt;注意事项：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;静态方法只能通过接口名调用，不能同故宫实现类名或者对象名调用&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;public可以省略，static 不可以省略&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;JDK9以后 接口中出现了私有方法&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;privbate 返回值类型 方法名（参数列表）{}
private void show(){ }&lt;/li&gt;
&lt;li&gt;private static 返回值类型 方法名（参数列表）{}
private static void method(){ }&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;InterA&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;show1&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;show1方法开始执行了&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; show3();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;show2&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;show2方法开始执行了&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; show3();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;show3&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	&lt;span style="color:#75715e"&gt;//必须是static&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	&lt;span style="color:#75715e"&gt;//若上述show1,show2是default，则不需要static&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;记录程序运行时的各种细节&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
静态的私有方法，为静态方法服务
普通的私有方法，为默认方法服务&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="接口的应用接口多态"&gt;接口的应用（接口多态）
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;接口类型 j = new 实现类对象();&lt;/code&gt;
&lt;strong&gt;编译看左，运行看右&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="适配器设计模式"&gt;适配器设计模式
&lt;/h2&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;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Inter&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;abstract&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;method1&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;abstract&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;method2&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;abstract&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;method10&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//在此创建父类来使InterImpl更加简洁&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;abstract&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;InterAdapter&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; Inter {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//abstract 不让外界创建对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;method1&lt;/span&gt;() {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;method2&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;method10&lt;/span&gt;() {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;InterImpl&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; InterAdapter{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//需要用到哪个方法就重写哪个方法&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;method5&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;第五个方法&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Inter定义了多个抽象方法，但是测试类只需要调用其中的一个方法method5()，于是添加一个类（作为测试类的父类）去重写所有方法，这样测试类就可以按需重写方法了。其中添加的这个类就是适配器&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="内部类"&gt;内部类
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;类的五大成员：属性，方法，构造方法，代码块，内部类&lt;/li&gt;
&lt;li&gt;内部类分为： 成员内部类，静态内部类，局部内部类，匿名内部类&lt;/li&gt;
&lt;li&gt;在A类的内部定义B类，B类就被成为内部类&lt;/li&gt;
&lt;li&gt;内部类表示的事物是外部类的一部分，内部类单独出现没有任何意义&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;访问特点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;内部类可以直接访问外部类的成员，包括&lt;strong&gt;私有private&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;外部类要访问内部类的成员，必须创建对象。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="成员内部类"&gt;成员内部类
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;写在成员位置的，属于外部内部类&lt;/li&gt;
&lt;li&gt;成员内部类可以被一些修饰符修饰，private、默认、protected、public、static等（用static修饰就是静态内部类了）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;获取成员内部类对象的两种方式：&lt;br&gt;
方式一：外部类编写方法，对外提供内部类对象&lt;br&gt;
方式二：直接创建&lt;br&gt;
格式 Outer.Inner oi = new Outer().new Inner();&lt;/p&gt;
&lt;p&gt;成员内部类获取外部类的成员变量&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Outer&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 10;&lt;span style="color:#75715e"&gt;//&amp;lt;----sout(Outer.this.a)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Inner&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 20;&lt;span style="color:#75715e"&gt;//&amp;lt;----sout(this.a)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;show&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 30;&lt;span style="color:#75715e"&gt;//&amp;lt;----sout(a)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(a);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(Outer.&lt;span style="color:#a6e22e"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;);&lt;span style="color:#75715e"&gt;//此处的Outer是类名&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="静态内部类"&gt;静态内部类
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;是用static修饰的成员内部类&lt;/li&gt;
&lt;li&gt;静态内部类只能访问外部类中的静态变量和静态方法，如果想要访问非静态的需要创建对象&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;创建静态内部类对象的格式：&lt;/strong&gt;
&lt;code&gt;外部类名.内部类名. 对象名 = new 外部类名.内部类名 (); &lt;/code&gt;&lt;br&gt;
&lt;code&gt;Outer.Inner oi = new Outer.Inner();&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;调用非静态方法的格式：&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;先创建对象，再对象调用&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;调用静态方法的格式：&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;外部类名.内部类名.方法名();&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="局部内部类了解"&gt;局部内部类（了解）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;1.将内部类定义在方法里面就叫做局部内部类，类似于方法里面的局部变量&lt;/li&gt;
&lt;li&gt;2.外界是无法直接使用，需要在方法内部创建对象使用&lt;/li&gt;
&lt;li&gt;3.该类可以直接访问外部类的成员，也可以访问方法内的局部变量&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="匿名内部类"&gt;匿名内部类**
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;匿名内部类本质上是隐藏了名字的内部类&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;	new 类名或接口名(){
		重写方法;
	};
	//注意有分号
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="接口实现关系"&gt;接口（实现关系）
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Student&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Swim&lt;/span&gt;(){	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;swim&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		sout(&lt;span style="color:#e6db74"&gt;&amp;#34;重写的swim方法&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//1.把前面的class去掉，剩余的内容变成了一个没有名字的类&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//2.这个没有名字的类想要实现Swim接口 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//把Swim写在了大括号的前面，表示这个没有名字的类实现了Swim接口，所以需要在类中重写接口里面的所有抽象方法。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Swim(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;swim&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			sout(&lt;span style="color:#e6db74"&gt;&amp;#34;重写的swim方法&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//这一部分(匿名内部类的对象)是没有名字的类(Student)，他来实现Swim接口&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="类名继承关系"&gt;类名（继承关系）
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Animal(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;eat&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			sout()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;应用/拓展&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Test&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//整体理解为Swim接口的实现类对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//接口多态：接口类型 j = new 实现类对象();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Swim s &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Swim(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;swim&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;重写之后的swim方法&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//编译看左边，运行看右边&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; s.&lt;span style="color:#a6e22e"&gt;swim&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Swim(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;swim&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;重写之后的swim方法&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }.&lt;span style="color:#a6e22e"&gt;swim&lt;/span&gt;();&lt;span style="color:#75715e"&gt;//自己调用自己&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;格式的细节：
&lt;code&gt;包含了继承或实现，方法重写，创建对象。整体就是一个类的子类对象或者接口的实现类对象&lt;/code&gt;
使用场景：
&lt;code&gt;当方法的参数是接口或者类时。 以接口为例，可以传递这个接口的实现类对象 如果实现类只要使用一次，就可以用匿名内部类简化代码&lt;/code&gt;&lt;/p&gt;</description></item><item><title>API</title><link>https://creat.asia/post/06-api/</link><pubDate>Tue, 03 Feb 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/06-api/</guid><description>&lt;h1 id="api"&gt;API
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;应用程序编程接口&lt;/strong&gt;&lt;br&gt;
API就是别人写好的东西，我们不需要自己编写，直接使用即可
例如：
&lt;code&gt;Random r = new Random();&lt;/code&gt;&lt;br&gt;
&lt;code&gt;Scanner sc = new Scanner();&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Java API：JDK中提供的各种功能的Java类&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="system"&gt;System
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;public static void exit(int status) 终止当前运行的Java虚拟机&lt;/code&gt;
&lt;code&gt;public static long currentTimeMillis() 返回当前系统的时间（毫秒）&lt;/code&gt;
&lt;code&gt;public static void arraycopy(数据源数组,起始索引,目的地数组,起始索引,拷贝个数) 数组拷贝 （地址值）&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="runtime"&gt;Runtime
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Runtime表示当前虚拟机的运行环境&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;public static		Runtime getRuntime() 当前系统的运行环境对象&lt;/code&gt;&lt;br&gt;
&lt;code&gt;public void 	exit(int status)	停止虚拟机&lt;/code&gt;&lt;br&gt;
&lt;code&gt;public int 	availableProcessors()	获取CPU线程数&lt;/code&gt;&lt;br&gt;
&lt;code&gt;public long 	maxMemory()	 JVM能从系统中获取总内存大小byte&lt;/code&gt;&lt;br&gt;
&lt;code&gt;public long	totalMemory()JVM已经从系统中获取总内存大小byte&lt;/code&gt;&lt;br&gt;
&lt;code&gt;public long 	freeMemory() JVM剩余内存大小byte&lt;/code&gt;
&lt;code&gt;public Process exec(String command)	运行cmd命令&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="object"&gt;Object
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;public boolean		equals(Objects obj) 比较地址值&lt;/code&gt;&lt;br&gt;
&lt;code&gt;public String 		toString() 返回对象的字符串表示形式&lt;/code&gt;&lt;br&gt;
&lt;code&gt;protected object clone(int a) 对象克隆&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		String s &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; StringBuilder sb &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; StringBuilder(&lt;span style="color:#e6db74"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(s.&lt;span style="color:#a6e22e"&gt;equals&lt;/span&gt;(sb));&lt;span style="color:#75715e"&gt;//false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;String中的equals方法会先判断参数是否为字符串&lt;span style="color:#f92672"&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;是字符串再比较内部属性&lt;span style="color:#f92672"&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(sb.&lt;span style="color:#a6e22e"&gt;equals&lt;/span&gt;(s));&lt;span style="color:#75715e"&gt;//false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;StringBuilder仅比较地址值&lt;span style="color:#f92672"&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (String)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;boolean&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;equals&lt;/span&gt;(Object anObject) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; anObject) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; (anObject &lt;span style="color:#66d9ef"&gt;instanceof&lt;/span&gt; String aString)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;COMPACT_STRINGS &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;coder&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; aString.&lt;span style="color:#a6e22e"&gt;coder&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; StringLatin1.&lt;span style="color:#a6e22e"&gt;equals&lt;/span&gt;(value, aString.&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (StringBuilder{Object的方法})
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;boolean&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;equals&lt;/span&gt;(Object obj) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; obj);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="克隆clone"&gt;克隆clone
&lt;/h3&gt;&lt;p&gt;对象克隆：把A对象的属性值完全拷贝给B对象，也叫对象拷贝，对象复制&lt;/p&gt;
&lt;h4 id="第一种克隆方式浅克隆"&gt;第一种克隆方式（浅克隆）
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;不管对象内部的属性是基本数据类型还是引用数据类型，都完全拷贝过来&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Cloneable&lt;/li&gt;
&lt;li&gt;如果一个接口里面没有抽象方法，表示当前的接口是一个可标记接口，现在Cloneable表示一旦实现了那么当前的对象就可以被克隆&lt;/li&gt;
&lt;li&gt;如果没有实现，当前类的对象就不能克隆&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; CloneNotSupportedException {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Student s1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Student(&lt;span style="color:#e6db74"&gt;&amp;#34;zhangsan&amp;#34;&lt;/span&gt;,18);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Object s2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (Student)s1.&lt;span style="color:#a6e22e"&gt;clone&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(s1);&lt;span style="color:#75715e"&gt;//@23fc625e&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(s2);&lt;span style="color:#75715e"&gt;//@3f99bd52&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(s1 &lt;span style="color:#f92672"&gt;==&lt;/span&gt; s2);&lt;span style="color:#75715e"&gt;//false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;（&lt;/span&gt;写在JavaBean中&lt;span style="color:#960050;background-color:#1e0010"&gt;）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;protected&lt;/span&gt; Object &lt;span style="color:#a6e22e"&gt;clone&lt;/span&gt;() &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; CloneNotSupportedException {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;super&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;clone&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;/*	1.重写Object中的clone方法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;		2.让JavaBean类实现Cloneable接口
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;		3.创建原对象调用clone	*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="https://creat.asia/post/image/06-1.png"
 loading="lazy"
 data-pending-gallery
 alt="浅克隆"
 &gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
浅克隆（引用数据类型）用的是相同的地址值，当其中一个对象修改该引用类型字段的内容时
另一个对象也会受到影响，可能导致数据不一致的问题。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="第二种克隆方式深克隆"&gt;第二种克隆方式（深克隆）
&lt;/h4&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;p&gt;&lt;img src="https://creat.asia/post/image/06-2.png"
 loading="lazy"
 data-pending-gallery
 alt="深克隆"
 &gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
基本数据类型 ： 直接克隆对象
引用数据类型 ： 创建一个新的对象
注：String 深克隆时用串池地址（原地址），只有在改变后才会创建新String对象，因为String本身不可变
&lt;strong&gt;此时的data记录新数据的地址值&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://creat.asia/post/image/06-3.png"
 loading="lazy"
 data-pending-gallery
 alt="深克隆与浅克隆"
 &gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="objects"&gt;Objects
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;public static boolean equals(Object a,Object b)&lt;/code&gt;&lt;strong&gt;先做非空判断&lt;/strong&gt;，比较两个对象&lt;/p&gt;
&lt;p&gt;&lt;code&gt;public static boolean isNull(Object obj)&lt;/code&gt;判断对象是否为null，null-&amp;gt;true&lt;/p&gt;
&lt;p&gt;&lt;code&gt;public static boolean nonNull(Object obj)&lt;/code&gt;判断对象是否为null，与isNull的结果相反&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; java.util.Objects; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;TestDemo&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; CloneNotSupportedException { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Student s1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; s2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Student(&lt;span style="color:#e6db74"&gt;&amp;#34;zhangsan&amp;#34;&lt;/span&gt;,23); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;boolean&lt;/span&gt; res &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Objects.&lt;span style="color:#a6e22e"&gt;equals&lt;/span&gt;(s1,s2); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(res); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//方法的底层会判断n1 ?= null，如果为null，直接返回false &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//如果s1不为null，那么就利用s1再次调用equals方法 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//此时s1是Student类型，所以最终还是会调用Student中的equals方法 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//未重写-&amp;gt;比较地址值 重写-&amp;gt;比较属性值 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="biginteger和bigdecimal"&gt;BigInteger和BigDecimal
&lt;/h2&gt;&lt;h3 id="biginteger的构造方法"&gt;BigInteger的构造方法
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;public BigInteger(int num,Random rnd)&lt;/code&gt;获取随机大整数，范围:[0~2的num次方-1]&lt;/p&gt;
&lt;p&gt;&lt;code&gt;public BigInteger(String val)&lt;/code&gt; 获取指定的大整数&lt;/p&gt;
&lt;p&gt;&lt;code&gt;public BigInteger(String val,int radix)&lt;/code&gt;获取指定进制的大整数&lt;/p&gt;
&lt;p&gt;&lt;code&gt;public static BigInteger valueOf(long val)&lt;/code&gt;静态方法获取BigInteger的对象，内部有优化(-1&lt;del&gt;16,1&lt;/del&gt;16)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
对象一旦创建，内部的数据不能发生改变&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BigInteger bd1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; BigInteger.&lt;span style="color:#a6e22e"&gt;valueOf&lt;/span&gt;(1);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BigInteger bd2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; BigInteger.&lt;span style="color:#a6e22e"&gt;valueOf&lt;/span&gt;(2);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BigInteger res &lt;span style="color:#f92672"&gt;=&lt;/span&gt; bd1.&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(bd2);&lt;span style="color:#75715e"&gt;//产生一个新对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//res = 3;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="https://creat.asia/post/image/06-4.png"
 loading="lazy"
 data-pending-gallery
 alt="BigInteger"
 &gt;&lt;/p&gt;
&lt;h3 id="biginteger的成员方法"&gt;BigInteger的成员方法
&lt;/h3&gt;&lt;p&gt;&lt;img src="https://creat.asia/post/image/06-5.png"
 loading="lazy"
 data-pending-gallery
 alt="成员方法"
 &gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="bigdemical"&gt;BigDemical
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;常用方法&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;表示的数字不大(没有超出double) -&amp;gt; 使用静态方法
&lt;code&gt;public static BigDecimal valueOf(double val)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;表示的数字比较大(超出double) -&amp;gt; 使用构造方法
&lt;code&gt;BigDecimal bd = new BigDecimal(String val)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
如果传递的是[0,10]之间的数，那么方法会返回已经创建好的对象（不会new）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://creat.asia/post/image/06-6.png"
 loading="lazy"
 data-pending-gallery
 alt="常用方法"
 &gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
注：divide除法方法必须除尽，否则会报错&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;舍入模式&lt;/th&gt;
					&lt;th style="text-align: left"&gt;说明&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;UP&lt;/td&gt;
					&lt;td style="text-align: left"&gt;远离&lt;strong&gt;0方向&lt;/strong&gt;舍入的舍入模式(&amp;lt;- -&amp;gt;)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;DOWN&lt;/td&gt;
					&lt;td style="text-align: left"&gt;靠近&lt;strong&gt;0方向&lt;/strong&gt;舍入的舍入模式(-&amp;gt; &amp;lt;-)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;CEILING&lt;/td&gt;
					&lt;td style="text-align: left"&gt;向&lt;strong&gt;正无穷大&lt;/strong&gt;方向舍入（ -&amp;gt; ）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;FLOOR&lt;/td&gt;
					&lt;td style="text-align: left"&gt;向&lt;strong&gt;负无穷大&lt;/strong&gt;方向舍入 ( &amp;lt;- )&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;HALF_UP&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;四舍五入&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="正则表达式regex"&gt;正则表达式（regex）
&lt;/h2&gt;&lt;p&gt;&lt;img src="https://creat.asia/post/image/06-7.png"
 loading="lazy"
 data-pending-gallery
 alt="regex"
 &gt;
&lt;img src="https://creat.asia/post/image/06-8.png"
 loading="lazy"
 data-pending-gallery
 alt="regex"
 &gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;(?i)abcd&lt;/code&gt;会忽略abcd的大小写&lt;/li&gt;
&lt;li&gt;&lt;code&gt;a(?i)bcd&lt;/code&gt;会忽略bcd的大小写&lt;/li&gt;
&lt;li&gt;&lt;code&gt;a((?i)b)cd&lt;/code&gt;会忽略b的大小写&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="date时间类"&gt;Date时间类
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//简单时间类&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Date d1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Date();&lt;span style="color:#75715e"&gt;//获取当前时间&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Date d2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Date(0L)&lt;span style="color:#75715e"&gt;//获取初始时间+0ms后的时间Thu Jan 01 08:00:00 CST 1970&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	d2.&lt;span style="color:#a6e22e"&gt;getTime&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;sout&lt;/span&gt;;&lt;span style="color:#75715e"&gt;//0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Date d3 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Date(1000L)&lt;span style="color:#75715e"&gt;//获取初始时间+1000ms后的时间Thu Jan 01 08:00:01 CST 1970&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	d3.&lt;span style="color:#a6e22e"&gt;getTime&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;sout&lt;/span&gt;;&lt;span style="color:#75715e"&gt;//1000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="simpledateformat类"&gt;SimpleDateFormat类
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;format格式化：把时间转换成指定格式&lt;/li&gt;
&lt;li&gt;parse解析：把字符串表示的时间变成Date对象&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="构造方法"&gt;构造方法
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;==&lt;code&gt;public SimpleDateFormat()&lt;/code&gt; 使用默认格式==&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	SimpleDateFormat sdf &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; SimpleDateFormat(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Date date &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Date(0L);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String str &lt;span style="color:#f92672"&gt;=&lt;/span&gt; sdf.&lt;span style="color:#a6e22e"&gt;format&lt;/span&gt;(date); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(str);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	默认格式&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;1970&lt;span style="color:#f92672"&gt;/&lt;/span&gt;1&lt;span style="color:#f92672"&gt;/&lt;/span&gt;1 08:00 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;==&lt;code&gt;public SimpleDateFormat(String Pattern)&lt;/code&gt; 使用指定格式==&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	SimpleDateFormat sdf &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; SimpleDateFormat(&lt;span style="color:#e6db74"&gt;&amp;#34;yyyy年MM月dd日 HH:mm:ss EEEE&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Date date &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Date(0L); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String str &lt;span style="color:#f92672"&gt;=&lt;/span&gt; sdf.&lt;span style="color:#a6e22e"&gt;format&lt;/span&gt;(date); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(str);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	指定格式&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;1970年01月01日 08:00:00 星期四
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;字母&lt;/th&gt;
					&lt;th&gt;描述 (Description)&lt;/th&gt;
					&lt;th&gt;示例 (Output)&lt;/th&gt;
					&lt;th&gt;备注 (Note)&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;G&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;年代标志 (Era)&lt;/td&gt;
					&lt;td&gt;AD (公元)&lt;/td&gt;
					&lt;td&gt;通常用于历史日期&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;y&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;年 (Year)&lt;/td&gt;
					&lt;td&gt;2026; 26&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;yy&lt;/code&gt; 是两位年，&lt;code&gt;yyyy&lt;/code&gt; 是四位年&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;u&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;纪元年 (Year)&lt;/td&gt;
					&lt;td&gt;2026&lt;/td&gt;
					&lt;td&gt;在 &lt;code&gt;java.time&lt;/code&gt; 中比 &lt;code&gt;y&lt;/code&gt; 更严谨&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;M&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;月份 (Month)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;07; Jul; July&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;大写&lt;/strong&gt;；&lt;code&gt;MM&lt;/code&gt; 为数字，&lt;code&gt;MMM&lt;/code&gt; 为缩写&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;L&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;独立月份 (Month)&lt;/td&gt;
					&lt;td&gt;7; July&lt;/td&gt;
					&lt;td&gt;常用于特定语言环境的格式化&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;d&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;月中天数 (Day)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;10; 05&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;小写&lt;/strong&gt;；该月中的第几天&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;D&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;年中天数 (Day)&lt;/td&gt;
					&lt;td&gt;189&lt;/td&gt;
					&lt;td&gt;该年中的第几天 (1-366)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;E&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;星期 (Day in week)&lt;/td&gt;
					&lt;td&gt;Tue; Tuesday&lt;/td&gt;
					&lt;td&gt;星期几的文本描述&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;e&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;星期数字 (Day of week)&lt;/td&gt;
					&lt;td&gt;2&lt;/td&gt;
					&lt;td&gt;1 (周一) 到 7 (周日)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;a&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;上下午标记 (AM/PM)&lt;/td&gt;
					&lt;td&gt;PM&lt;/td&gt;
					&lt;td&gt;上午或下午&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;H&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;24小时制小时&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;0-23&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;大写&lt;/strong&gt;；常用于服务器日志&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;h&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;12小时制小时&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;1-12&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;小写&lt;/strong&gt;；需配合 &lt;code&gt;a&lt;/code&gt; 使用&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;m&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;分钟 (Minute)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;30&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;小写&lt;/strong&gt;；不要和月份 &lt;code&gt;M&lt;/code&gt; 搞混&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;s&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;秒 (Second)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;55&lt;/td&gt;
					&lt;td&gt;秒数&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;S&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;毫秒 (Fraction)&lt;/td&gt;
					&lt;td&gt;978&lt;/td&gt;
					&lt;td&gt;毫秒或纳秒的零头&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;n&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;纳秒 (Nano)&lt;/td&gt;
					&lt;td&gt;500000&lt;/td&gt;
					&lt;td&gt;仅限 Java 8+ 的 &lt;code&gt;java.time&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;z&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;时区 (Time Zone)&lt;/td&gt;
					&lt;td&gt;CST; PST&lt;/td&gt;
					&lt;td&gt;通用时区名称&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Z&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;时区偏移 (Offset)&lt;/td&gt;
					&lt;td&gt;+0800&lt;/td&gt;
					&lt;td&gt;RFC 822 格式&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;ISO 8601 时区&lt;/td&gt;
					&lt;td&gt;Z; +08; +08:00&lt;/td&gt;
					&lt;td&gt;现代 API 推荐使用的时区格式&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="常用方法"&gt;常用方法
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;==&lt;code&gt;public final String format(Date date)&lt;/code&gt; 格式化（日期对象 -&amp;gt; 字符串)==&lt;/li&gt;
&lt;li&gt;==&lt;code&gt;public Date parse(String source)&lt;/code&gt; 解析（字符串 -&amp;gt; 日期对象）==&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="calendar类"&gt;Calendar类
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;Calendar代表了系统当前时间的日历对象，可以单独修改、获取事件中的年月日&lt;/li&gt;
&lt;li&gt;Calendar是一个抽象类，不能直接创建对象，需要通过一个静态方法获取到子类对象
&lt;img src="https://creat.asia/post/image/06-10.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="getsetadd方法"&gt;get/set/add方法
&lt;/h5&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Calandar c &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Calandar.&lt;span style="color:#a6e22e"&gt;getInstance&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	c.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(Calandar.&lt;span style="color:#a6e22e"&gt;YEAR&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	c.&lt;span style="color:#a6e22e"&gt;set&lt;/span&gt;(Calandar.&lt;span style="color:#a6e22e"&gt;YEAR&lt;/span&gt;,11)&lt;span style="color:#75715e"&gt;//实际为12月&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	c.&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(Calandar.&lt;span style="color:#a6e22e"&gt;YEAR&lt;/span&gt;,1)&lt;span style="color:#75715e"&gt;//实际为次年1月&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;数字&lt;/th&gt;
					&lt;th style="text-align: left"&gt;常量名&lt;/th&gt;
					&lt;th style="text-align: left"&gt;含义&lt;/th&gt;
					&lt;th style="text-align: left"&gt;注意事项&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;1&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Calendar.YEAR&lt;/td&gt;
					&lt;td style="text-align: left"&gt;年&lt;/td&gt;
					&lt;td style="text-align: left"&gt;-&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;2&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Calendar.MONTH&lt;/td&gt;
					&lt;td style="text-align: left"&gt;月&lt;/td&gt;
					&lt;td style="text-align: left"&gt;从 0 开始。0表示1月，11表示12月。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;5&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Calendar.DATE / DAY_OF_MONTH&lt;/td&gt;
					&lt;td style="text-align: left"&gt;日&lt;/td&gt;
					&lt;td style="text-align: left"&gt;两个常量效果一样。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;10&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Calendar.HOUR&lt;/td&gt;
					&lt;td style="text-align: left"&gt;小时&lt;/td&gt;
					&lt;td style="text-align: left"&gt;12小时制。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;11&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Calendar.HOUR_OF_DAY&lt;/td&gt;
					&lt;td style="text-align: left"&gt;小时&lt;/td&gt;
					&lt;td style="text-align: left"&gt;24小时制。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;12&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Calendar.MINUTE&lt;/td&gt;
					&lt;td style="text-align: left"&gt;分钟&lt;/td&gt;
					&lt;td style="text-align: left"&gt;-&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;13&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Calendar.SECOND&lt;/td&gt;
					&lt;td style="text-align: left"&gt;秒&lt;/td&gt;
					&lt;td style="text-align: left"&gt;-&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;7&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Calendar.DAY_OF_WEEK&lt;/td&gt;
					&lt;td style="text-align: left"&gt;星期&lt;/td&gt;
					&lt;td style="text-align: left"&gt;周日是1，周一是2，周六是7。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="包装类"&gt;包装类
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;基本数据类型所对应的对象&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="integer"&gt;Integer
&lt;/h3&gt;&lt;h4 id="integer缓存"&gt;Integer缓存
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;Java的Integer类内部实现了一个静态缓存池，用于存储特定范围内的整数值对应的Integer对象。&lt;/li&gt;
&lt;li&gt;默认情况下，这个范围时-128至127。当通过Integer.valueOf(int)方法创建一个在这个范围内的整数对象时，并不会每次都生成新的对象实例，而是&lt;strong&gt;复用缓存中的现有对象&lt;/strong&gt;，会直接从内存中取出，不需要新建一个对象。&lt;/li&gt;
&lt;li&gt;目的：节约内存&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="jdk5以后"&gt;JDK5以后
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;自动装箱、自动拆箱&lt;/li&gt;
&lt;li&gt;直接赋值获取对象&lt;/li&gt;
&lt;li&gt;计算时不需要new，不需要调用方法，直接赋值即可&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Integer i1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 10;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Integer i2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 20;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Integer i3 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; i1 &lt;span style="color:#f92672"&gt;+&lt;/span&gt; i2;&lt;span style="color:#75715e"&gt;//底层：先拆箱 -&amp;gt; 计算 -&amp;gt; 再装箱赋值给i3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="integer成员方法"&gt;Integer成员方法
&lt;/h4&gt;&lt;p&gt;&lt;img src="https://creat.asia/post/image/06-11.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="arrays"&gt;Arrays
&lt;/h2&gt;&lt;p&gt;&lt;img src="https://creat.asia/post/image/06-12.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h3 id="arraysbinarysearch"&gt;Arrays.binarySearch()
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;查找的元素存在，就返回真实的索引&lt;/li&gt;
&lt;li&gt;查找的元素不存在，就返回( -插入点 - 1 )&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {1,2,3,4,5,6,7,8,9,10};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Arrays.&lt;span style="color:#a6e22e"&gt;binarySearch&lt;/span&gt;(arr,10);&lt;span style="color:#75715e"&gt;//9&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Arrays.&lt;span style="color:#a6e22e"&gt;binarySearch&lt;/span&gt;(arr,100)&lt;span style="color:#75715e"&gt;//-11&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="arrrayscopyof"&gt;Arrrays.copyOf()
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;if(新数组len &amp;lt; 老数组len) 会部分拷贝&lt;/li&gt;
&lt;li&gt;if(新数组len = 老数组len) 会完全拷贝&lt;/li&gt;
&lt;li&gt;if(新数组len &amp;gt; 老数组len) 会补上默认初始值(int[] 补0)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {1,2,3,4,5,6,7,8,9,10};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; newa &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Arrays.&lt;span style="color:#a6e22e"&gt;copyOf&lt;/span&gt;(a);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="arrrayscopyofrange"&gt;Arrrays.copyOfRange()
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;包左不包右（左闭右开）&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {1,2,3,4,5,6,7,8,9,10};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; newa &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Arrays.&lt;span style="color:#a6e22e"&gt;copyOfRange&lt;/span&gt;(a,0,9);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//1 2 3 4 5 6 7 8 9&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="arraysfill"&gt;Arrays.fill()
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {1,2,3,4,5,6,7,8,9,10};	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Arrays.&lt;span style="color:#a6e22e"&gt;fill&lt;/span&gt;(a,100);&lt;span style="color:#75715e"&gt;//100 100 100 ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="arrayssort"&gt;Arrays.sort()
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;对基本类型快速排序&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Arrays.&lt;span style="color:#a6e22e"&gt;sort&lt;/span&gt;(a);&lt;span style="color:#75715e"&gt;//升序&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="重载"&gt;重载
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;只能对引用数据类型排序&lt;/li&gt;
&lt;li&gt;o1：表示在无序序列中，遍历得到的每一个元素&lt;/li&gt;
&lt;li&gt;o2：表示有序序列中的元素&lt;/li&gt;
&lt;li&gt;返回值
&lt;ul&gt;
&lt;li&gt;负数：表示当前要插入的元素是小的，放在前面&lt;/li&gt;
&lt;li&gt;正数：表示当前要插入的元素是大的，放在后面&lt;/li&gt;
&lt;li&gt;0 ：一样大，放在后面&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Integer&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {2,7,5,4,5,6,7,8,9,31}; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Arrays.&lt;span style="color:#a6e22e"&gt;sort&lt;/span&gt;(a,newComparator&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Integer&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;() { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;compare&lt;/span&gt;(Integer o1, Integer o2) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; o1&lt;span style="color:#f92672"&gt;-&lt;/span&gt;o2; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="lambda表达式"&gt;Lambda表达式
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;( )对应方法的形参&lt;/li&gt;
&lt;li&gt;-&amp;gt; 固定格式&lt;/li&gt;
&lt;li&gt;{ } 对应方法体&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Integer&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {2,7,5,4,5,6,7,8,9,31}; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Arrays.&lt;span style="color:#a6e22e"&gt;sort&lt;/span&gt;(a,(Integer o1, Integer o2) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; o1&lt;span style="color:#f92672"&gt;-&lt;/span&gt;o2; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;gt;[!NOTE]
&amp;gt;lambda 表达式可以用来简化匿名内部类的书写（不是所有）
&amp;gt;lambda 表达式只能简化函数式接口的匿名内部类写法
&amp;gt;
&amp;gt;函数式接口：
&amp;gt;- **有且仅有一个抽象方法的接口**，接口上方可以加@FunctionalInterface的注解

```Java
	Integer[] a = {2,7,5,4,5,6,7,8,9,31}; 
Arrays.sort(a,(Integer o1, Integer o2) -&amp;gt; { 
		return o1-o2; 
	} 
);
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; MyTestDemo2; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;TestDemo&lt;/span&gt;{ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; method(()&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;{ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;lambda:&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;swimming&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;method&lt;/span&gt;(swim s){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; s.&lt;span style="color:#a6e22e"&gt;swimming&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@FunctionalInterface&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;swim&lt;/span&gt;{ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;swimming&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="可推导可省略"&gt;可推导，可省略
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Integer&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {2,7,5,4,5,6,7,8,9,31}; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Arrays.&lt;span style="color:#a6e22e"&gt;sort&lt;/span&gt;(a,(o1,o2) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; o1&lt;span style="color:#f92672"&gt;-&lt;/span&gt;o2);&lt;span style="color:#75715e"&gt;//升序&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Arrays.&lt;span style="color:#a6e22e"&gt;sort&lt;/span&gt;(a,(o1,o2) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; o2&lt;span style="color:#f92672"&gt;-&lt;/span&gt;o1);&lt;span style="color:#75715e"&gt;//倒序&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>基本算法</title><link>https://creat.asia/post/07-%E5%9F%BA%E6%9C%AC%E7%AE%97%E6%B3%95/</link><pubDate>Tue, 03 Feb 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/07-%E5%9F%BA%E6%9C%AC%E7%AE%97%E6%B3%95/</guid><description>&lt;h1 id="插值查找"&gt;插值查找
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;前提是数据有顺序&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; list &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {7,23,79,81,103,127,131,147}; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; l &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; r &lt;span style="color:#f92672"&gt;=&lt;/span&gt; list.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; 1; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; sc.&lt;span style="color:#a6e22e"&gt;nextInt&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; mid;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (l &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; r &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; x &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; list&lt;span style="color:#f92672"&gt;[&lt;/span&gt;l&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; x &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; list&lt;span style="color:#f92672"&gt;[&lt;/span&gt;r&lt;span style="color:#f92672"&gt;]&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 先乘后除&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		mid &lt;span style="color:#f92672"&gt;=&lt;/span&gt; l &lt;span style="color:#f92672"&gt;+&lt;/span&gt; (x &lt;span style="color:#f92672"&gt;-&lt;/span&gt; list&lt;span style="color:#f92672"&gt;[&lt;/span&gt;l&lt;span style="color:#f92672"&gt;]&lt;/span&gt;) &lt;span style="color:#f92672"&gt;*&lt;/span&gt; (r &lt;span style="color:#f92672"&gt;-&lt;/span&gt; l) &lt;span style="color:#f92672"&gt;/&lt;/span&gt; (list&lt;span style="color:#f92672"&gt;[&lt;/span&gt;r&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; list&lt;span style="color:#f92672"&gt;[&lt;/span&gt;l&lt;span style="color:#f92672"&gt;]&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (x &lt;span style="color:#f92672"&gt;==&lt;/span&gt; list&lt;span style="color:#f92672"&gt;[&lt;/span&gt;mid&lt;span style="color:#f92672"&gt;]&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;找到了，索引为：&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; mid);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#66d9ef"&gt;break&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		} &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (x &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; list&lt;span style="color:#f92672"&gt;[&lt;/span&gt;mid&lt;span style="color:#f92672"&gt;]&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			l &lt;span style="color:#f92672"&gt;=&lt;/span&gt; mid &lt;span style="color:#f92672"&gt;+&lt;/span&gt; 1;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		} &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			r &lt;span style="color:#f92672"&gt;=&lt;/span&gt; mid &lt;span style="color:#f92672"&gt;-&lt;/span&gt; 1;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;插值查找优点&lt;/strong&gt;：对于&lt;strong&gt;均匀分布&lt;/strong&gt;的数组，速度极快（时间复杂度接近 $O(\log(\log n))$）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;插值查找缺点&lt;/strong&gt;：如果数据分布&lt;strong&gt;极不均匀&lt;/strong&gt;（比如：&lt;code&gt;{1, 2, 3, 100, 1000, 10000}&lt;/code&gt;），插值查找的性能可能还不如二分查找。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="冒泡排序"&gt;冒泡排序
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;相邻的数据两两比较&lt;/li&gt;
&lt;li&gt;&lt;code&gt;if(a[i] &amp;gt; [j]) swap(a[i],a[j])&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="选择排序"&gt;选择排序
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;从0索引开始，拿着每一个索引上的元素跟后面的元素一一比较，小的放前面，大的放后面。&lt;/li&gt;
&lt;li&gt;第一轮循环，确定确定了最小元素&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="插入排序"&gt;插入排序
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;分为有序组和无序组&lt;/li&gt;
&lt;li&gt;将无序组逐个插入有序组中&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;TestDemo&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; arr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {4,16,5,9,12,21,18, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 32,23,37,26,45,34, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 50,48,61,52,73,66}; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; startIndex &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;1; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; arr.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(arr&lt;span style="color:#f92672"&gt;[&lt;/span&gt;i&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; arr&lt;span style="color:#f92672"&gt;[&lt;/span&gt;i&lt;span style="color:#f92672"&gt;+&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt;){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; startIndex &lt;span style="color:#f92672"&gt;=&lt;/span&gt; i &lt;span style="color:#f92672"&gt;+&lt;/span&gt; 1; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;break&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(startIndex &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;1){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; ; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; startIndex; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; arr.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; j &lt;span style="color:#f92672"&gt;=&lt;/span&gt; i; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(j &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; 0 &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; arr&lt;span style="color:#f92672"&gt;[&lt;/span&gt;j&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; arr&lt;span style="color:#f92672"&gt;[&lt;/span&gt;j&lt;span style="color:#f92672"&gt;-&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt;) {&lt;span style="color:#75715e"&gt;//寻找正确的位置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; temp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; arr&lt;span style="color:#f92672"&gt;[&lt;/span&gt;j&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; arr&lt;span style="color:#f92672"&gt;[&lt;/span&gt;j&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; arr&lt;span style="color:#f92672"&gt;[&lt;/span&gt;j &lt;span style="color:#f92672"&gt;-&lt;/span&gt; 1&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; arr&lt;span style="color:#f92672"&gt;[&lt;/span&gt;j &lt;span style="color:#f92672"&gt;-&lt;/span&gt; 1&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; temp; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; j&lt;span style="color:#f92672"&gt;--&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="递归"&gt;递归
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;方法再次调用方法本身&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;递归一定要有出口，否则就会内存溢出&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="快速排序"&gt;快速排序
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;第一轮：将0索引数字作为基准数，确定基准数在数组中的正确位置&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 快速排序主方法：递归分治 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;quickSort&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; a, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; l, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; r) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(l &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; r){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; mid_index &lt;span style="color:#f92672"&gt;=&lt;/span&gt; find(a,l,r); &lt;span style="color:#75715e"&gt;// 分区，返回基准值的正确索引 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; quickSort(a,l,mid_index&lt;span style="color:#f92672"&gt;-&lt;/span&gt;1); &lt;span style="color:#75715e"&gt;// 排序左子数组（小于基准） &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; quickSort(a,mid_index&lt;span style="color:#f92672"&gt;+&lt;/span&gt;1,r); &lt;span style="color:#75715e"&gt;// 排序右子数组（大于基准） &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 分区函数：选a[l]为基准，返回基准值的最终索引 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;find&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; a, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; l, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; r) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; pivot &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a&lt;span style="color:#f92672"&gt;[&lt;/span&gt;l&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 基准值（保存副本，避免被修改） &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; left &lt;span style="color:#f92672"&gt;=&lt;/span&gt; l &lt;span style="color:#f92672"&gt;+&lt;/span&gt; 1; &lt;span style="color:#75715e"&gt;// 左指针：从基准下一位开始找大于pivot的元素 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; right &lt;span style="color:#f92672"&gt;=&lt;/span&gt; r; &lt;span style="color:#75715e"&gt;// 右指针：从右边界开始找小于pivot的元素 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 右指针找小于基准值的元素（left&amp;lt;=right 防止越界） &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (left &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; right &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; a&lt;span style="color:#f92672"&gt;[&lt;/span&gt;right&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; pivot) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; right&lt;span style="color:#f92672"&gt;--&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 左指针找大于基准值的元素（left&amp;lt;=right 防止越界） &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (left &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; right &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; a&lt;span style="color:#f92672"&gt;[&lt;/span&gt;left&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; pivot) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; left&lt;span style="color:#f92672"&gt;++&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 左指针超过右指针，分区结束 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (left &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; right) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;break&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 交换左右指针指向的元素（真正修改数组） &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; temp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a&lt;span style="color:#f92672"&gt;[&lt;/span&gt;left&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; a&lt;span style="color:#f92672"&gt;[&lt;/span&gt;left&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a&lt;span style="color:#f92672"&gt;[&lt;/span&gt;right&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; a&lt;span style="color:#f92672"&gt;[&lt;/span&gt;right&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; temp; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 把基准值放到正确位置（right是小于基准区域的最后一位） &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; temp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a&lt;span style="color:#f92672"&gt;[&lt;/span&gt;l&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; a&lt;span style="color:#f92672"&gt;[&lt;/span&gt;l&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a&lt;span style="color:#f92672"&gt;[&lt;/span&gt;right&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; a&lt;span style="color:#f92672"&gt;[&lt;/span&gt;right&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; temp; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; right; &lt;span style="color:#75715e"&gt;// 返回基准值的最终索引 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>集合进阶</title><link>https://creat.asia/post/08-%E9%9B%86%E5%90%88%E8%BF%9B%E9%98%B6/</link><pubDate>Tue, 03 Feb 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/08-%E9%9B%86%E5%90%88%E8%BF%9B%E9%98%B6/</guid><description>&lt;h1 id="collection-接口单列集合根接口"&gt;Collection 接口（单列集合根接口）
&lt;/h1&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;	├─ List 接口（有序、可重复）
	│ ├─ ArrayList（实现类）：动态数组，查询快、增删慢
	│ ├─ LinkedList（实现类）：双向链表，增删快、查询慢
	│ └─ Vector（实现类）：动态数组，线程安全、性能差
	└─ Set 接口（无序、不可重复）
	 ├─ HashSet（实现类）：哈希表，无序去重
	 ├─ TreeSet（实现类）：红黑树，排序去重
	 └─ LinkedHashSet（实现类）：哈希表+链表，有序去重
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="mermaid"&gt;
 flowchart TD
 A[Collection&amp;lt;br/&amp;gt;（单列集合根接口）] --&amp;gt; B[List&amp;lt;br/&amp;gt;（有序、可重复）]
 A --&amp;gt; C[Set&amp;lt;br/&amp;gt;（无序、不可重复）]
 
 B --&amp;gt; B1[ArrayList&amp;lt;br/&amp;gt;（动态数组）]
 B --&amp;gt; B2[LinkedList&amp;lt;br/&amp;gt;（双向链表）]
 B --&amp;gt; B3[Vector&amp;lt;br/&amp;gt;（线程安全数组）]
 
 C --&amp;gt; C1[HashSet&amp;lt;br/&amp;gt;（哈希表）]
 C --&amp;gt; C2[TreeSet&amp;lt;br/&amp;gt;（红黑树）]
 C1 --&amp;gt; C3[LinkedHashSet&amp;lt;br/&amp;gt;（哈希表+链表）]
 
 %% 样式优化
 A:::root
 B:::subInterface
 C:::subInterface
 B1:::impl
 B2:::impl
 B3:::impl
 C1:::impl
 C2:::impl
 C3:::impl
 classDef root fill:#f9f,stroke:#333,stroke-width:2px
 classDef subInterface fill:#9ff,stroke:#333,stroke-width:2px
 classDef impl fill:#ff9,stroke:#333,stroke-width:1px
&lt;/pre&gt;

&lt;h1 id="collection"&gt;Collection
&lt;/h1&gt;&lt;p&gt;&lt;img src="https://creat.asia/post/image/08-1.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Collection是单列集合的祖宗接口，它的功能是全部单列集合都可以继承使用的&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Collectio是一个接口，不能直接创建它的对象，只能创建实现类的对象&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
contains方法在底层依赖equals方法&lt;/p&gt;
&lt;p&gt;如果是自定义对象，那么必须在JavaBean重写equals方法&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="遍历"&gt;遍历
&lt;/h2&gt;&lt;h3 id="迭代器遍历"&gt;迭代器遍历
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Iterator&amp;lt;E&amp;gt; iterator()&lt;/code&gt; 返回迭代器对象，默认指向当前集合的0索引&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;boolean hasNext()&lt;/code&gt; 判断当前位置是否有元素&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;E next()&lt;/code&gt; 获取当前位置元素，并将迭代器对象移向下一个位置&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Iterator&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; it &lt;span style="color:#f92672"&gt;=&lt;/span&gt; list.&lt;span style="color:#a6e22e"&gt;iterator&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(it.&lt;span style="color:#a6e22e"&gt;hasNext&lt;/span&gt;()){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		String str &lt;span style="color:#f92672"&gt;=&lt;/span&gt; it.&lt;span style="color:#a6e22e"&gt;next&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(str);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;报错NoSuchElementException&lt;/li&gt;
&lt;li&gt;迭代器遍历完毕，指针不会复位（第二次遍历集合需重新获取iterator）&lt;/li&gt;
&lt;li&gt;迭代器遍历时，不能用集合的方法进行增加或者删除 ，只能用it.remove()&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id="增强for遍历"&gt;增强for遍历
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;底层就是一个迭代器&lt;/li&gt;
&lt;li&gt;修改增强for中的变量，不会改变集合中原本的数据&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Collection&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; coll &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(String s : coll){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(s);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="lambda表达式遍历"&gt;lambda表达式遍历
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	coll.&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;(s &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(s));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="list"&gt;List
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;元素有序，可重复，有索引&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://creat.asia/post/image/08-2.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h3 id="addremove"&gt;add/remove
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; L &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	L.&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;aaa&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	L.&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;bbb&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	L.&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;ccc&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	L.&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(1,&lt;span style="color:#e6db74"&gt;&amp;#34;ddd&amp;#34;&lt;/span&gt;);&lt;span style="color:#75715e"&gt;//在指定位置插入元素，原位置以后的元素依次往后移&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//aaa ddd bbb ccc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String remove &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L.&lt;span style="color:#a6e22e"&gt;remove&lt;/span&gt;(0);&lt;span style="color:#75715e"&gt;//aaa&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;boolean&lt;/span&gt; remove &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L.&lt;span style="color:#a6e22e"&gt;remove&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;aaa&amp;#34;&lt;/span&gt;);&lt;span style="color:#75715e"&gt;//true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
当List存储对象为Integer时，使用remove(1),会优先删除索引为1的元素
由于 &lt;code&gt;int&lt;/code&gt; 是基本数据类型，编译器会优先匹配参数类型最精确的方法&lt;/p&gt;
&lt;p&gt;解决方法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;手动装箱&lt;code&gt;list.remove(Integer.valueOf(1));&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;向上转型&lt;code&gt;list.remove((Object) 1);&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id="setget"&gt;set/get
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;set(int index,E element)&lt;/code&gt; 修改索引处的元素，返回修改前的元素&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;get(int index)&lt;/code&gt;返回索引上的元素&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="遍历方式"&gt;遍历方式
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;迭代器遍历&lt;/li&gt;
&lt;li&gt;增强for遍历&lt;/li&gt;
&lt;li&gt;lambda表达式遍历&lt;/li&gt;
&lt;li&gt;普通for循环遍历&lt;/li&gt;
&lt;li&gt;列表迭代器遍历&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="列表迭代器遍历"&gt;列表迭代器遍历
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ListIterator&amp;lt;E&amp;gt; extends Iterator&amp;lt;E&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="列表迭代器方法"&gt;列表迭代器方法
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;add&amp;lt;E e&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;hasNext()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;next()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;remove()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;hasPrevious()&lt;/code&gt;与&lt;code&gt;hasNext()&lt;/code&gt;相反&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;previous()&lt;/code&gt;与&lt;code&gt;next()&lt;/code&gt;相反&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在遍历的过程中可以添加元素&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ListIterator&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; it &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L.&lt;span style="color:#a6e22e"&gt;listIterator&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(it.&lt;span style="color:#a6e22e"&gt;hasNext&lt;/span&gt;()){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;aaa&amp;#34;&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;equals&lt;/span&gt;(it.&lt;span style="color:#a6e22e"&gt;next&lt;/span&gt;())){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; it.&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;qqq&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//aaa qqq bbb ccc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://creat.asia/post/image/08-3.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h3 id="arraylist底层原理"&gt;ArrayList底层原理
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;底层是数组结构的&lt;/li&gt;
&lt;li&gt;利用空参创建的集合，在底层创建一个默认长度为0得分数组&lt;/li&gt;
&lt;li&gt;添加第一个元素，底层会创建一个新的==长度为10==的数组（elementData），初始化为null&lt;/li&gt;
&lt;li&gt;存满时，会扩容==1.5倍==（向下取整）&lt;/li&gt;
&lt;li&gt;如果一次添加多个元素，1.5倍放不下，则新创建数组的长度以实际为准。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://creat.asia/post/image/08-4.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;boolean&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(E e) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; modCount&lt;span style="color:#f92672"&gt;++&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; add(e, elementData, size);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(E e, Object&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; elementData, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; s) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (s &lt;span style="color:#f92672"&gt;==&lt;/span&gt; elementData.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; elementData &lt;span style="color:#f92672"&gt;=&lt;/span&gt; grow(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; elementData&lt;span style="color:#f92672"&gt;[&lt;/span&gt;s&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; e; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; size &lt;span style="color:#f92672"&gt;=&lt;/span&gt; s &lt;span style="color:#f92672"&gt;+&lt;/span&gt; 1; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; Object&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;grow&lt;/span&gt;() { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; grow(size &lt;span style="color:#f92672"&gt;+&lt;/span&gt; 1); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对于&lt;code&gt;if (oldCapacity &amp;gt; 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;oldCapacity &amp;gt; 0&lt;/code&gt; 负责处理&lt;strong&gt;已经长大的数组&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA&lt;/code&gt; 负责处理&lt;strong&gt;被用户手动指定为 0 的数组&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;只有这两个条件都不满足（即：既是 0 又是默认空数组），才会触发“初始 10”的逻辑。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; Object&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;grow&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; minCapacity) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; oldCapacity &lt;span style="color:#f92672"&gt;=&lt;/span&gt; elementData.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (oldCapacity &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; 0 &lt;span style="color:#f92672"&gt;||&lt;/span&gt; elementData &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; newCapacity &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ArraysSupport.&lt;span style="color:#a6e22e"&gt;newLength&lt;/span&gt;(oldCapacity, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 minCapacity &lt;span style="color:#f92672"&gt;-&lt;/span&gt; oldCapacity, &lt;span style="color:#75715e"&gt;/* minimum growth */&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 oldCapacity &lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&lt;/span&gt; 1 &lt;span style="color:#75715e"&gt;/*默认新增容量*/&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; elementData &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Arrays.&lt;span style="color:#a6e22e"&gt;copyOf&lt;/span&gt;(elementData, newCapacity);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; elementData &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Object&lt;span style="color:#f92672"&gt;[&lt;/span&gt;Math.&lt;span style="color:#a6e22e"&gt;max&lt;/span&gt;(DEFAULT_CAPACITY, minCapacity)&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;newLength&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; oldLength, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; minGrowth, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; prefGrowth) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 由于内嵌原因未勾选前提条件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// assert oldLength &amp;gt;= 0 // assert minGrowth &amp;gt; 0 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; prefLength &lt;span style="color:#f92672"&gt;=&lt;/span&gt; oldLength &lt;span style="color:#f92672"&gt;+&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;max&lt;/span&gt;(minGrowth, prefGrowth); &lt;span style="color:#75715e"&gt;// 可能会溢出来 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (0 &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; prefLength &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; prefLength &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; SOFT_MAX_ARRAY_LENGTH) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; prefLength; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;// 用另一个方法冷处理代码&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; hugeLength(oldLength, minGrowth); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre class="mermaid"&gt;
 graph TD
 A[开始添加元素] --&amp;gt; B[modCount自增]
 B --&amp;gt; C{所需容量超过数组长度?}
 
 %% 扩容分支
 C -- 是 --&amp;gt; D[调用grow方法]
 D --&amp;gt; E[计算新容量：旧容量1.5倍]
 E --&amp;gt; F{新容量满足最小需求?}
 F -- 否 --&amp;gt; G[新容量设为最小需求]
 G --&amp;gt; H[检查是否超JVM限制]
 F -- 是 --&amp;gt; H
 H --&amp;gt; I[迁移数据到新数组]
 I --&amp;gt; J[更新elementData引用]
 
 %% 插入分支
 C -- 否 --&amp;gt; K[元素放入数组对应位置]
 J --&amp;gt; K
 K --&amp;gt; L[size自增]
 L --&amp;gt; M[返回true]
 M --&amp;gt; N[结束]
&lt;/pre&gt;

&lt;h3 id="linkedlist集合"&gt;LinkedList集合
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;底层数据结构是双链表，查询慢，增删快，但是如果操作的是首尾元素，速度也是极快
&lt;img src="https://creat.asia/post/image/08-5.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://creat.asia/post/image/08-6.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h3 id="iterator迭代器"&gt;Iterator迭代器
&lt;/h3&gt;&lt;p&gt;&lt;img src="https://creat.asia/post/image/08-7.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;modCount&lt;/code&gt; (Modification Count)&lt;/strong&gt;： 属于 &lt;code&gt;ArrayList&lt;/code&gt; 对象。只要列表结构发生变化（&lt;code&gt;add&lt;/code&gt;, &lt;code&gt;remove&lt;/code&gt;, &lt;code&gt;clear&lt;/code&gt; 等），这个计数器就会 &lt;strong&gt;+1&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;expectedModCount&lt;/code&gt;&lt;/strong&gt;： 属于 &lt;code&gt;Itr&lt;/code&gt;（迭代器）对象内部。在创建迭代器的那一刻，它会把当时的 &lt;code&gt;modCount&lt;/code&gt; “拍照”存下来：&lt;code&gt;expectedModCount = modCount&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="set"&gt;Set
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;添加的元素&lt;span style="color: #dc3545;"&gt;无序，不重复，无索引&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Set接口中的方法基本上与Collection一致（remove方法只能根据对象删除，不能根据索引删）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="hashset-哈希表"&gt;HashSet 哈希表
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;JDK8之前：数组+链表&lt;/li&gt;
&lt;li&gt;JDK8之后：数组+链表+红黑树&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="哈希值"&gt;哈希值
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;应该存入的位置 int index = (数组长度 - 1) &amp;amp; 哈希值&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;该方法定义在Object类中，所有对象都可以调用，默认使用地址值进行计算&lt;/li&gt;
&lt;li&gt;一般情况下，会重写hashCode方法，利用对象内部的属性值计算哈希值&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="对象哈希值的特点"&gt;对象哈希值的特点
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;如果没有重写hashCode方法，不同对象计算出的哈希值是不同的&lt;/li&gt;
&lt;li&gt;如果已经重写hashCode方法，不同对象只要属性值相同，计算出的哈希值就是一样的&lt;/li&gt;
&lt;li&gt;在小部分情况下，不同属性值或者不同的地址值计算出来的哈希值也有可能一样（哈希冲突）&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;hashCode&lt;/span&gt;()); &lt;span style="color:#75715e"&gt;//96354&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;acD&amp;#34;&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;hashCode&lt;/span&gt;()); &lt;span style="color:#75715e"&gt;//96354&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="底层原理"&gt;底层原理
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;先创建一个默认长度为16，默认 加载因子 为0.75的数组table&lt;/li&gt;
&lt;li&gt;加载因子：存入第 16 * 0.75 = 12 个元素时，会触发扩容&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;0.75&lt;/strong&gt; 是在频繁扩容的开销与查询延迟之间找到的黄金平衡点。&lt;/li&gt;
&lt;li&gt;根据元素的哈希值跟数组长度计算出应存入的位置&lt;/li&gt;
&lt;li&gt;&lt;span style="color: #dc3545;"&gt;判断当前的位置是否为null&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; 存入
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; 调用equals方法比较属性值
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; 不存
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; 存入数组&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;形成链表 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; JDK8以前&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;新元素存入数组&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;老元素挂在新元素下面
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; JDK8之后&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;新元素直接挂在老元素下面
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;JDK8以后，当链表长度超过8，而且数组长度大于等于64时，自动转换为红黑树&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如果集合中存储的是自定义对象，必须要重写hashCode () 和equals () 方法&lt;/strong&gt;(默认比较用的是地址值)&lt;/p&gt;
&lt;h4 id="hashset的三个特点"&gt;HashSet的三个特点
&lt;/h4&gt;&lt;h5 id="hashset为什么存和取的顺序不一样"&gt;HashSet为什么存和取的顺序不一样？
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;HashSet&lt;/code&gt; 存取顺序不一致，是因为它根据元素内容的 &lt;strong&gt;Hash 值&lt;/strong&gt;经计算后直接存放在内部数组的随机位置，而非按时间先后排队；&lt;/li&gt;
&lt;li&gt;读取时则是按数组下标从头到尾扫描，所以输出顺序取决于&lt;strong&gt;元素在内存中的分布位置&lt;/strong&gt;，而非&lt;strong&gt;输入顺序&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="hashset为什么没有索引"&gt;HashSet为什么没有索引？
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;HashSet&lt;/code&gt; 没有索引是因为它采用&lt;strong&gt;哈希表&lt;/strong&gt;结构，元素是根据内容计算出的哈希值“随机”散落在数组位置上的，中间存在大量空位且位置会随扩容改变，这种&lt;strong&gt;非连续、非固定&lt;/strong&gt;的存储方式使得通过物理位置（索引）定位元素变得毫无意义&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="hashset是利用什么机制保证数据去重的"&gt;HashSet是利用什么机制保证数据去重的？
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;HashSet&lt;/code&gt; 通过 &lt;strong&gt;&lt;code&gt;hashCode()&lt;/code&gt;&lt;/strong&gt; 快速定位存储位置，若位置冲突再利用 &lt;strong&gt;&lt;code&gt;equals()&lt;/code&gt;&lt;/strong&gt; 进行内容“肉搏”比对，只有当两个方法都判定相同时，才会触发去重机制拒绝存入。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="linkedhashset"&gt;LinkedHashSet
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style="color: #dc3545;"&gt;有序&lt;/span&gt;，不重复，无索引&lt;/li&gt;
&lt;li&gt;这里的有序指的是保证存储和去除的元素顺序一致&lt;/li&gt;
&lt;li&gt;原理：底层数据机构依然是哈希表，知识每个元素有额外多了一个==双链表==的机制记录存储的数据&lt;/li&gt;
&lt;li&gt;如果要求去重且存取有序，则选择LinkedHashSet&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="treeset"&gt;TreeSet
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style="color: #dc3545;"&gt;可排序&lt;/span&gt;，不重复，无索引&lt;/li&gt;
&lt;li&gt;可排序：按照元素的默认规则（由小到大）排序&lt;/li&gt;
&lt;li&gt;TreeSet集合底层是基于&lt;span style="color: #dc3545;"&gt;红黑树的数据结构&lt;/span&gt;实现排序的，增删改查性能都较好&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="treeset默认的规则"&gt;TreeSet默认的规则
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;对于数值类型：&lt;code&gt;Integer&lt;/code&gt;，&lt;code&gt;Double&lt;/code&gt;，默认按照从小到大的顺序进行排序&lt;/li&gt;
&lt;li&gt;对于字符、字符串类型：按照字符在ASCII码表中的数字升序进行排序&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;compareTo&lt;/span&gt;(Student o) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getAge&lt;/span&gt;()&lt;span style="color:#f92672"&gt;-&lt;/span&gt;o.&lt;span style="color:#a6e22e"&gt;getAge&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;:表示当前要添加的元素
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	o :表示已经在红黑树存在的元素
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;返回值&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	负数&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;认为要添加的元素是小的&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;存左边
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	正数&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;认为要添加的元素是大的&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;存右边
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	0&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;要添加的元素已存在&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;舍弃
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="treeset的两种比较方式"&gt;TreeSet的两种比较方式
&lt;/h4&gt;&lt;h5 id="方式一"&gt;方式一
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;默认排序/自然排序：JavaBean类实现Comparable接口指定比较规则&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="方式二"&gt;方式二
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;比较器排序：创建TreeSet对象的时候，传递比较器Comparator制定规则&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="使用规则"&gt;使用规则
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;默认使用第一种，如果第一种不能满足当前需求，就使用第二种&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="list与set的使用场景"&gt;List与Set的使用场景
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;如果想要集合中的元素*&lt;strong&gt;可重复&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用&lt;strong&gt;ArrayList&lt;/strong&gt;集合，==基于数组的==（用的最多）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果想要集合中的元素&lt;em&gt;&lt;strong&gt;可重复&lt;/strong&gt;&lt;/em&gt;，而且当前的&lt;span style="color: #dc3545;"&gt;增删操作明显多于查询&lt;/span&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用&lt;strong&gt;LinkedList&lt;/strong&gt;集合，==基于链表的==&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果想对集合中的&lt;em&gt;&lt;strong&gt;元素去重&lt;/strong&gt;&lt;/em&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用&lt;strong&gt;HashSet&lt;/strong&gt;，==基于哈希表的==（用的最多）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果相对集合的&lt;em&gt;&lt;strong&gt;元素去重&lt;/strong&gt;&lt;/em&gt;，而且&lt;span style="color: #dc3545;"&gt;保证存取顺序&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用&lt;strong&gt;LinkedHashList&lt;/strong&gt;集合，==基于哈希表和双链表，效率低于HashSet==&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="泛型"&gt;泛型
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;可以在编译阶段约束操作的数据类型，并进行检查&lt;/li&gt;
&lt;li&gt;格式：&amp;lt;数据类型&amp;gt;&lt;/li&gt;
&lt;li&gt;泛型只能支持引用数据类型&lt;/li&gt;
&lt;li&gt;==统一数据类型==，把运行时期的问题提前到了编译期间，避免了强制类型转化可能出现的异常&lt;/li&gt;
&lt;li&gt;==Java中的泛型是伪泛型==&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;注意！&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;泛型中不能写基本数据类型&lt;/li&gt;
&lt;li&gt;指定泛型的具体类型后，传递数据时，可以传入该类类型或者其&lt;strong&gt;子类类型&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;如果不写泛型，类型默认是Object&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="泛型类"&gt;泛型类
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;MyArrayList&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;E&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;{ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Object&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; obj &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Object&lt;span style="color:#f92672"&gt;[&lt;/span&gt;10&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; size; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;boolean&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(E e){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; obj&lt;span style="color:#f92672"&gt;[&lt;/span&gt;size&lt;span style="color:#f92672"&gt;++]&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; e; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; E &lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; index){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; (E)obj&lt;span style="color:#f92672"&gt;[&lt;/span&gt;index&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; &lt;span style="color:#75715e"&gt;//存入ArrayList的数据都会变成Object&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; String &lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;(){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Arrays.&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;(obj); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//此处的E可以理解为变量，但是不是用来记录数据的，是用来记录数据类型的,一般用：K、T、V、E&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="泛型方法"&gt;泛型方法
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;方法中形参不确定时
&lt;ul&gt;
&lt;li&gt;1.使用类名后面定义的泛型 -&amp;gt; 所有方法都能用&lt;/li&gt;
&lt;li&gt;2.在方法申明上定义自己的泛型 -&amp;gt; 只有本方法能用&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;T&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; boid &lt;span style="color:#a6e22e"&gt;show&lt;/span&gt;(T t){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;|&lt;/span&gt;此处的E可以理解为变量&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;但是不是用来记录数据的&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;是用来记录数据类型的,一般用&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;K&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;T&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;V&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;E&lt;span style="color:#f92672"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ListUtil&lt;/span&gt;{ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ListUtil&lt;/span&gt;() {} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 参数一：集合 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 参数二：要添加的元素 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * */&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;E&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;addAll&lt;/span&gt;(ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;E&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; list,E...&lt;span style="color:#a6e22e"&gt;e&lt;/span&gt;){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (E element : e) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; list.&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(element); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="泛型接口"&gt;泛型接口
&lt;/h2&gt;&lt;h3 id="实现类给出具体类型"&gt;实现类给出具体类型
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;MyArrayList&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="实现类延续泛型创建对象时再确定"&gt;实现类延续泛型，创建对象时再确定
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;MyArrayList&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;E&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;E&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="泛型的继承和通配符"&gt;泛型的继承和通配符
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;==泛型不具备继承性，但数据具备继承性==&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	通配符
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;?&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; E&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; 表示可以传递E或者E所有的子类类型
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;?&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;super&lt;/span&gt; E&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; 表示可以传递E或者E所有的父类类型
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="map"&gt;Map
&lt;/h1&gt;&lt;pre class="mermaid"&gt;
 flowchart TD
 A[Map&amp;lt;br/&amp;gt;（双列集合根接口）] --&amp;gt; B[HashMap&amp;lt;br/&amp;gt;（哈希表）]
 A --&amp;gt; C[TreeMap&amp;lt;br/&amp;gt;（红黑树）]
 A --&amp;gt; D[Hashtable&amp;lt;br/&amp;gt;（线程安全哈希表）]
 A --&amp;gt; E[LinkedHashMap&amp;lt;br/&amp;gt;（哈希表+链表）]
 
 D --&amp;gt; D1[Properties&amp;lt;br/&amp;gt;（属性集）]
 
 %% 保持和Collection流程图一致的样式
 A:::root
 B:::impl
 C:::impl
 D:::impl
 E:::impl
 D1:::impl
 classDef root fill:#f9f,stroke:#333,stroke-width:2px
 classDef subInterface fill:#9ff,stroke:#333,stroke-width:2px
 classDef impl fill:#ff9,stroke:#333,stroke-width:1px
&lt;/pre&gt;

&lt;h2 id="常见api"&gt;常见API
&lt;/h2&gt;&lt;p&gt;&lt;img src="https://creat.asia/post/image/08-%e9%9b%86%e5%90%88%e8%bf%9b%e9%98%b6.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h2 id="遍历-1"&gt;遍历
&lt;/h2&gt;&lt;h3 id="通过键k找值v"&gt;通过键k找值v
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Set&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; keys &lt;span style="color:#f92672"&gt;=&lt;/span&gt; map.&lt;span style="color:#a6e22e"&gt;keySet&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//遍历单列集合，得到每一个键&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (String key : keys) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(map.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(key)); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//迭代器遍历&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Iterator it &lt;span style="color:#f92672"&gt;=&lt;/span&gt; keys.&lt;span style="color:#a6e22e"&gt;iterator&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(it.&lt;span style="color:#a6e22e"&gt;hasNext&lt;/span&gt;()){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String key &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (String)it.&lt;span style="color:#a6e22e"&gt;next&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(key&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;:&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;map.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(key)); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//lambda表达式遍历&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	keys.&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;(key &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(map.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(key)));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="键值对对象遍历"&gt;键值对对象遍历
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//Set存储键值对&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Set&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Map.&lt;span style="color:#a6e22e"&gt;Entry&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String, String&lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&lt;/span&gt; es &lt;span style="color:#f92672"&gt;=&lt;/span&gt; map.&lt;span style="color:#a6e22e"&gt;entrySet&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//Entry是Map的内部接口&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//遍历每一个键值对对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (Map.&lt;span style="color:#a6e22e"&gt;Entry&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String, String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; e : es) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String key &lt;span style="color:#f92672"&gt;=&lt;/span&gt; e.&lt;span style="color:#a6e22e"&gt;getKey&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String value &lt;span style="color:#f92672"&gt;=&lt;/span&gt; e.&lt;span style="color:#a6e22e"&gt;getValue&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(key &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; value); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//遍历迭代器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Iterator &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Map.&lt;span style="color:#a6e22e"&gt;Entry&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String,String&lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&lt;/span&gt; it &lt;span style="color:#f92672"&gt;=&lt;/span&gt; es.&lt;span style="color:#a6e22e"&gt;iterator&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(it.&lt;span style="color:#a6e22e"&gt;hasNext&lt;/span&gt;()){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 Map.&lt;span style="color:#a6e22e"&gt;Entry&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String,String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; entry &lt;span style="color:#f92672"&gt;=&lt;/span&gt; it.&lt;span style="color:#a6e22e"&gt;next&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String key &lt;span style="color:#f92672"&gt;=&lt;/span&gt; entry.&lt;span style="color:#a6e22e"&gt;getKey&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String value &lt;span style="color:#f92672"&gt;=&lt;/span&gt; entry.&lt;span style="color:#a6e22e"&gt;getValue&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(key&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;:&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;value); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//lambda表达式&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	es.&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;(e &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(e.&lt;span style="color:#a6e22e"&gt;getKey&lt;/span&gt;()&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;:&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;e.&lt;span style="color:#a6e22e"&gt;getValue&lt;/span&gt;()));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="lambda表达式遍历-1"&gt;lambda表达式遍历
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	map.&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; BiConsumer&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String, String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;() { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;accept&lt;/span&gt;(String k, String v) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(k&lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt;v); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;-----------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	map.&lt;span style="color:#a6e22e"&gt;forEack&lt;/span&gt;((key,value) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(k&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;:&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;v));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="hashmap"&gt;HashMap
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;HashMap 是 Map 的一个实现类&lt;/li&gt;
&lt;li&gt;特点都是由键决定的：无序，不重复，无索引&lt;/li&gt;
&lt;li&gt;HashMap 与 HashSet 的底层原理是一样的，都是哈希表&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HashMap的键位置如果存储的是自定义对象，需要重写hashCode和equals&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="样例"&gt;样例
&lt;/h3&gt;&lt;p&gt;&lt;img src="https://creat.asia/post/image/08-%e9%9b%86%e5%90%88%e8%bf%9b%e9%98%b6-1.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	默认的hashCode和equals方法
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;boolean&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;equals&lt;/span&gt;(Object obj) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; obj) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(obj &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; getClass() &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; obj.&lt;span style="color:#a6e22e"&gt;getClass&lt;/span&gt;() ) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 Student student &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (Student)obj; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; name.&lt;span style="color:#a6e22e"&gt;equals&lt;/span&gt;(student.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;) &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; age &lt;span style="color:#f92672"&gt;==&lt;/span&gt; student.&lt;span style="color:#a6e22e"&gt;age&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;hashCode&lt;/span&gt;() { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Objects.&lt;span style="color:#a6e22e"&gt;hash&lt;/span&gt;(name,age); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="linkedhashmap"&gt;LinkedHashMap
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style="color: #dc3545;"&gt;由键决定：有序&lt;/span&gt;、不重复、无索引&lt;/li&gt;
&lt;li&gt;这里的有序值得是保证存储和去除的元素一致&lt;/li&gt;
&lt;li&gt;&lt;span style="color: #dc3545;"&gt;原理：&lt;/span&gt;底层数据结构依然是哈希表，只是每个键值对元素又额外多了一个双链表的机制记录存储的顺序&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="treemap"&gt;TreeMap
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;TreeMap跟TreeSet的底层原理一样，都是红黑树结构的&lt;/li&gt;
&lt;li&gt;由键决定特性：不重复，无索引，可排序&lt;/li&gt;
&lt;li&gt;可排序：**&lt;span style="color: #dc3545;font-weight: bold;"&gt;对键进行排序&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color: #dc3545;font-weight: bold;"&gt;注意：默认按照键的从小到大进行排序，也可以自己规定键的排序规则&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="代码两种书写排序规则"&gt;代码两种书写排序规则
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;创建Comparable接口，指定比较规则&lt;/li&gt;
&lt;li&gt;创建集合时传递Comparator比较器对象，指定比较规则&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		TreeMap&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Integer,String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; tm &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; TreeMap&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Comparator&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Integer&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;() { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;compare&lt;/span&gt;(Integer o1, Integer o2) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#75715e"&gt;//o1 : 当前要添加的元素 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#75715e"&gt;//o2 : 当前要添加的元素 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#75715e"&gt;//升序&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; o1 &lt;span style="color:#f92672"&gt;-&lt;/span&gt; o2;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="hashmap源码分析"&gt;HashMap源码分析
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;HashMap里面每一个对象包含以下内容&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;1.&lt;span style="color:#a6e22e"&gt;1链表中的键值对对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	包含&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; hash;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; K key;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			V value;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			Nodfe&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;K,V&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;1.&lt;span style="color:#a6e22e"&gt;2红黑树中的键值对对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	包含&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; hash;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; K key;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			V value;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			Node&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;K,V&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; right;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#66d9ef"&gt;boolean&lt;/span&gt; red;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2.&lt;span style="color:#a6e22e"&gt;添加元素&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	HashMap&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String,Integer&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; hm &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; HashMap&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	hm.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;aaa&amp;#34;&lt;/span&gt;,111);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	hm.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;bbb&amp;#34;&lt;/span&gt;,222);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;添加元素的时候至少考虑三种情况
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2.&lt;span style="color:#a6e22e"&gt;1&lt;/span&gt; 数组位置为null
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2.&lt;span style="color:#a6e22e"&gt;2&lt;/span&gt; 数组位置不为null&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;键重复&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;元素覆盖
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2.&lt;span style="color:#a6e22e"&gt;3&lt;/span&gt; 数组位置不为null&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;键不重复&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;挂在下面形成链表或者红黑树
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//参数一：键&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//参数二：值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//返回值：被覆盖元素的值，如果没有覆盖，返回value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; V &lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(K key, V value) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//参数一：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; putVal(hash(key), key, value, &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//利用键计算出对应的哈希值，再把哈希值进行一些处理&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;hash&lt;/span&gt;(Object key) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; h; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; (key &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) &lt;span style="color:#f92672"&gt;?&lt;/span&gt; 0 : (h &lt;span style="color:#f92672"&gt;=&lt;/span&gt; key.&lt;span style="color:#a6e22e"&gt;hashCode&lt;/span&gt;()) &lt;span style="color:#f92672"&gt;^&lt;/span&gt; (h &lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; 16); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//参数一：键的哈希值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//参数二：键&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//参数三：值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//参数四：如果键重复了是否保留 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// true-&amp;gt;表示老元素的值保留，不会覆盖 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// false-&amp;gt;表示老欧元素的值不会保留，会进行覆盖&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; V &lt;span style="color:#a6e22e"&gt;putVal&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; hash, K key, V value, &lt;span style="color:#66d9ef"&gt;boolean&lt;/span&gt; onlyIfAbsent,&lt;span style="color:#66d9ef"&gt;boolean&lt;/span&gt; evict) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Node&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;K,V&lt;span style="color:#f92672"&gt;&amp;gt;[]&lt;/span&gt; tab; &lt;span style="color:#75715e"&gt;//定义一个局部变量，用来记录哈希表数组的地址值，用于优化（方法在栈里，变量在堆里，直接在栈里找地址值） null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Node&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;K,V&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; p; &lt;span style="color:#75715e"&gt;//临时第三方变量，记录键值对对象的地址值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; n, i; &lt;span style="color:#75715e"&gt;//当前数组的的长度与索引&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//将哈希表中数组的地址值赋值给局部变量tab&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//将数组长度赋值给n&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; ((tab &lt;span style="color:#f92672"&gt;=&lt;/span&gt; table) &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; (n &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tab.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;) &lt;span style="color:#f92672"&gt;==&lt;/span&gt; 0) &lt;span style="color:#75715e"&gt;//true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//1.如果当前是第一次添加数据，底层会创建一个默认长度为16，加载因子为0.75的数组&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//2.如果不是第一次添加数据，会看数组中的元素是否达到了扩容条件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//如果没有达到扩容条件 -&amp;gt; 无操作&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//如果达到了 -&amp;gt; 底层会把数组扩容为原先的 两倍 ，并把数据全部转移到新的哈希表中&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		n &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (tab &lt;span style="color:#f92672"&gt;=&lt;/span&gt; resize()).&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//拿着数组的长度跟键的哈希值进行计算得到 -&amp;gt; 在数组中应存入的位置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//获取数组中对应元素的数据（第一次为null）	&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; ((p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tab&lt;span style="color:#f92672"&gt;[&lt;/span&gt;i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (n &lt;span style="color:#f92672"&gt;-&lt;/span&gt; 1) &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt; hash&lt;span style="color:#f92672"&gt;]&lt;/span&gt;) &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		添加第一个元素 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//底层会创建一个键值对对象，直接放到数组当中&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		tab&lt;span style="color:#f92672"&gt;[&lt;/span&gt;i&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; newNode(hash, key, value, &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		添加其他元素
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		Node&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;K,V&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; e; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		K k; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//p.hash:数组中键值对的哈希值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//hash:当前要添加键值对的哈希值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//如果键不一样，此时返回false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (p.&lt;span style="color:#a6e22e"&gt;hash&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; hash &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			((k &lt;span style="color:#f92672"&gt;=&lt;/span&gt; p.&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;) &lt;span style="color:#f92672"&gt;==&lt;/span&gt; key &lt;span style="color:#f92672"&gt;||&lt;/span&gt; (key &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; key.&lt;span style="color:#a6e22e"&gt;equals&lt;/span&gt;(k)))) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			e &lt;span style="color:#f92672"&gt;=&lt;/span&gt; p; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (p &lt;span style="color:#66d9ef"&gt;instanceof&lt;/span&gt; TreeNode) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#75715e"&gt;//判断数组中获取出来的键值对是不是红黑树的节点&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#75715e"&gt;//如果是，则调用putTreeVal，把当前的节点按照红黑树的规则添加到树当中&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			e &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ((TreeNode&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;K,V&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;)p).&lt;span style="color:#a6e22e"&gt;putTreeVal&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;, tab, hash, key, value); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#75715e"&gt;//如果数组中获取出来的键值对不是红黑树的节点&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#75715e"&gt;//表示此时下面挂的是链表 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; binCount &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0; ; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;binCount) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; ((e &lt;span style="color:#f92672"&gt;=&lt;/span&gt; p.&lt;span style="color:#a6e22e"&gt;next&lt;/span&gt;) &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) { &lt;span style="color:#75715e"&gt;//下一个元素为null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#75715e"&gt;//此时就会创建一个新的节点，挂在下面，形成链表&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					p.&lt;span style="color:#a6e22e"&gt;next&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; newNode(hash, key, value, &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#75715e"&gt;//判断当前链表长度是否超过8，如果超过，会调用treeifyBin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#75715e"&gt;//treeifyBin方法的底层还会继续判断，判断数组的长度是否大于等于64&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#75715e"&gt;//如果同时满足这两个条件，就会把这个链表转成红黑树&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (binCount &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; TREEIFY_THRESHOLD &lt;span style="color:#f92672"&gt;-&lt;/span&gt; 1) &lt;span style="color:#75715e"&gt;//7，插入后长度为8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;						treeifyBin(tab, hash); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#66d9ef"&gt;break&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (e.&lt;span style="color:#a6e22e"&gt;hash&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; hash &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					((k &lt;span style="color:#f92672"&gt;=&lt;/span&gt; e.&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;) &lt;span style="color:#f92672"&gt;==&lt;/span&gt; key &lt;span style="color:#f92672"&gt;||&lt;/span&gt; (key &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; key.&lt;span style="color:#a6e22e"&gt;equals&lt;/span&gt;(k)))) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#66d9ef"&gt;break&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; e; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//下一个节点不为空&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//如果e为null，表示当前不需要覆盖任何元素&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (e &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			V oldValue &lt;span style="color:#f92672"&gt;=&lt;/span&gt; e.&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;; &lt;span style="color:#75715e"&gt;//保存旧值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#75715e"&gt;//是否保留&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;onlyIfAbsent &lt;span style="color:#f92672"&gt;||&lt;/span&gt; oldValue &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#75715e"&gt;//当前要添加的值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				e.&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; value; &lt;span style="color:#75715e"&gt;//覆盖值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			afterNodeAccess(e); &lt;span style="color:#75715e"&gt;//后置处理&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; oldValue; &lt;span style="color:#75715e"&gt;//都返回旧值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;/*与并发修改异常有关，暂时忽略*/&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;modCount; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//threshold:记录数组的长度*0.75，哈希表的扩容时机&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;++&lt;/span&gt;size &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; threshold) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//扩容&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		resize(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;/*与LinkedHashMap有关，暂时忽略*/&lt;/span&gt;afterNodeInsertion(evict);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;; &lt;span style="color:#75715e"&gt;//表示当前没有覆盖任何元素，返回null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="哈希冲突处理逻辑"&gt;哈希冲突处理逻辑
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;1.&lt;span style="color:#a6e22e"&gt;hash不等&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; 绝对不是同一个Key
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2.&lt;span style="color:#a6e22e"&gt;hash相等&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; 可能是同一个&lt;span style="color:#960050;background-color:#1e0010"&gt;（&lt;/span&gt;冲突了&lt;span style="color:#960050;background-color:#1e0010"&gt;），&lt;/span&gt;继续比较 &lt;span style="color:#f92672"&gt;==&lt;/span&gt; 或 equals
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;3.&lt;span style="color:#a6e22e"&gt;equals相等&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; 确定是同一个元素&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;执行覆盖
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	因为冲突不可避免&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;所以 HashMap 才需要用 &lt;span style="color:#a6e22e"&gt;equals&lt;/span&gt;() 再次确认身份&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;并用链表&lt;span style="color:#f92672"&gt;/&lt;/span&gt;红黑树来安置多出来的&lt;span style="color:#960050;background-color:#1e0010"&gt;“&lt;/span&gt;鸽子&lt;span style="color:#960050;background-color:#1e0010"&gt;”。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;扩展&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;为什么 &lt;span style="color:#960050;background-color:#1e0010"&gt;`&lt;/span&gt;HashMap&lt;span style="color:#960050;background-color:#1e0010"&gt;`&lt;/span&gt; 里的 &lt;span style="color:#960050;background-color:#1e0010"&gt;`&lt;/span&gt;TREEIFY_THRESHOLD&lt;span style="color:#960050;background-color:#1e0010"&gt;`（&lt;/span&gt;树化阈值&lt;span style="color:#960050;background-color:#1e0010"&gt;）&lt;/span&gt;定为 8&lt;span style="color:#960050;background-color:#1e0010"&gt;？&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	根据泊松分布&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;在哈希函数设计合理的情况下&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;同一个桶位冲突达到 8 个的概率只有千万分之6
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="treemap源码分析"&gt;TreeMap源码分析
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;无哈希：完全不使用hashCode和equals，只看compare的结果&lt;/li&gt;
&lt;li&gt;强约束：Key必须实现Comparable或提供Comparator，且不能为null（因为要调用比较方法）&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Comparable&lt;span style="color:#f92672"&gt;&amp;lt;?&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;super&lt;/span&gt; K&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; k &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (Comparable&lt;span style="color:#f92672"&gt;&amp;lt;?&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;super&lt;/span&gt; K&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;) key;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//将键Key强转为Comparable接口类型&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//若无外部比较器，Key 必须实现Comparable接口，&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//否则在put时会报ClassCastException（强转失败）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="3"&gt;
&lt;li&gt;有序挂载：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	addEntry(key, value, parent, cmp &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; 0);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//true:左&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//false:右&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="4"&gt;
&lt;li&gt;自动平衡：插入后通过fixAfterInsertion（变色/旋转）维持红黑树平衡&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="可变参数"&gt;可变参数
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;本质上是一个&lt;strong&gt;数组&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;在方法的形参中只能写一个可变参数&lt;/li&gt;
&lt;li&gt;在方法当中，可变参数需要写到最后&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="collections集合工具类"&gt;Collections集合工具类
&lt;/h1&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;场景&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;核心方法（脑子里有个印象即可）&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;重点注意&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;排序/乱序&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;sort()&lt;/code&gt;, &lt;code&gt;reverse()&lt;/code&gt;, &lt;code&gt;shuffle()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;必须实现 &lt;code&gt;Comparable&lt;/code&gt; 或传 &lt;code&gt;Comparator&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;找最值&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;max()&lt;/code&gt;, &lt;code&gt;min()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;同样依赖比较逻辑&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;线程安全&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;synchronizedList()&lt;/code&gt;, &lt;code&gt;synchronizedMap()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;面试重点&lt;/strong&gt;：它是如何把非线程安全的集合变安全的？（包装了一层锁）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;不可变集合&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;unmodifiableList()&lt;/code&gt;，&lt;code&gt;unmodifiableMap()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;防止别人修改你的集合（保护数据）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;问：&lt;code&gt;synchronizedList&lt;/code&gt; 是如何把非线程安全集合变安全的？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;它是一个「包装类」（内部持有原集合的引用）&lt;/li&gt;
&lt;li&gt;重写了原集合的所有方法（add/get/iterator 等）&lt;/li&gt;
&lt;li&gt;在每个方法内部加 &lt;code&gt;synchronized (this)&lt;/code&gt; 锁，保证方法级别的线程安全&lt;/li&gt;
&lt;li&gt;注意：遍历（iterator）时需要手动加锁（因为 iterator 是迭代器方法，包装类没给迭代过程加锁）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="不可变集合"&gt;不可变集合
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;写法：&lt;/strong&gt;&lt;code&gt;List.of(),Set.of(),Map.of()&lt;/code&gt;(JDK9+)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;List&amp;lt;String&amp;gt; list = List.of(&amp;quot;1&amp;quot;,&amp;quot;2&amp;quot;);&lt;/code&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;code&gt;Set/Map&lt;/code&gt;里的元素不能重复；&lt;code&gt;of()不允许存null&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;价值：&lt;/strong&gt; 为了安全和并发性能&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>数据结构</title><link>https://creat.asia/post/09-%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/</link><pubDate>Tue, 03 Feb 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/09-%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/</guid><description>&lt;h1 id="栈stack"&gt;栈Stack
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;后进先出，先进后出&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;压栈/进栈：数据进入栈模型的过程&lt;/li&gt;
&lt;li&gt;弹栈/出栈：数据离开栈模型的过程&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="队列queue"&gt;队列Queue
&lt;/h1&gt;&lt;ul&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;/ul&gt;
&lt;h1 id="数组"&gt;数组
&lt;/h1&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;h1 id="链表"&gt;链表
&lt;/h1&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;hr&gt;
&lt;h1 id="树"&gt;树
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#f92672"&gt;[&lt;/span&gt;父节点地址值&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;值&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;左子节点地址值&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;右子节点地址值&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 度&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;每一个节点的 子节点 数量
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 树高&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;树的总层数
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 10 &lt;span style="color:#f92672"&gt;&amp;lt;--&lt;/span&gt; 根节点
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;/&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;\&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 5 15 &lt;span style="color:#f92672"&gt;&amp;lt;--&lt;/span&gt; 第二层
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;/&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;\&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;\&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 3 7 20 &lt;span style="color:#f92672"&gt;&amp;lt;--&lt;/span&gt; 第三层
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 6 &lt;span style="color:#f92672"&gt;&amp;lt;--&lt;/span&gt; 第四层
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="二叉树的遍历方式"&gt;二叉树的遍历方式
&lt;/h2&gt;&lt;h3 id="前序遍历"&gt;前序遍历
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;从根节点开始，按照当前节点，左子节点，右子节点的顺序遍历&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="中序遍历"&gt;中序遍历
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;从最左边的子节点开始，然后按照左子节点，当前节点，右子节点的顺序遍历&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="后序遍历"&gt;后序遍历
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;从最右边的子节点开始，然后按照左子节点，右子节点，当前节点的顺序遍历&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="层序遍历"&gt;层序遍历
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;从根节点开始一层一层遍历&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="二叉查找树"&gt;二叉查找树
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;每一个节点上最多有两个子节点&lt;/li&gt;
&lt;li&gt;任意节点左子树上的值都小于当前节点&lt;/li&gt;
&lt;li&gt;任意节点右子树上的值都大于当前节点
&lt;img src="https://creat.asia/post/image/09.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="添加节点"&gt;添加节点
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;小的存左边，大的存右边，一样的不存&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="弊端"&gt;弊端
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;左子树全部为空，从形式上看，更像一个==单链表==&lt;/li&gt;
&lt;li&gt;插入速度没有影响&lt;/li&gt;
&lt;li&gt;查询速度明显降低
&lt;img src="https://creat.asia/post/image/09-1.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="解决弊端平衡二叉树"&gt;解决弊端：平衡二叉树
&lt;/h3&gt;&lt;p&gt;平衡二叉树也叫 &lt;strong&gt;平衡二叉搜索树（Self-balancing binary search tree）&lt;/strong&gt;，又被称为 AVL 树，可以保证 &lt;strong&gt;查询效率较高&lt;/strong&gt;。它是解决 &lt;strong&gt;二叉排序&lt;/strong&gt; 可能出现的查询问题。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;二叉查找树&lt;/li&gt;
&lt;li&gt;规则：==&lt;strong&gt;任意&lt;/strong&gt;节点左右子树高度差不超过1==
&lt;img src="https://creat.asia/post/image/09-3.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="保持平衡的旋转机制"&gt;保持平衡的旋转机制
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;左旋&lt;/li&gt;
&lt;li&gt;右旋&lt;/li&gt;
&lt;li&gt;当添加一个节点时，该树不再是一颗平衡二叉树 -&amp;gt; 旋转&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="左旋"&gt;左旋
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;确定支点：从添加的节点开始，不断的往父节点找不平衡的节点&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;步骤：&lt;/p&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;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;img src="https://creat.asia/post/image/09-4.png"
 loading="lazy"
 data-pending-gallery
 alt="500"
 &gt;&lt;/th&gt;
					&lt;th&gt;&lt;img src="https://creat.asia/post/image/09-5.png"
 loading="lazy"
 data-pending-gallery
 alt="500"
 &gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&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;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;img src="https://creat.asia/post/image/09-6.png"
 loading="lazy"
 data-pending-gallery
 alt="500"
 &gt;&lt;/th&gt;
					&lt;th&gt;&lt;img src="https://creat.asia/post/image/09-7.png"
 loading="lazy"
 data-pending-gallery
 alt="500"
 &gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="需要旋转的四种情况"&gt;需要旋转的四种情况
&lt;/h4&gt;&lt;h5 id="左左ll"&gt;左左LL
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;当==根结点左子树的左子树==有节点插入，导致二叉树不平衡&lt;/li&gt;
&lt;li&gt;一次右旋&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="左右lr"&gt;左右LR
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;当==根结点左子树的右子树==有节点插入，导致二叉树不平衡&lt;/li&gt;
&lt;li&gt;先局部左旋 -&amp;gt; 左左LL&lt;/li&gt;
&lt;li&gt;再整体右旋&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="右右rr"&gt;右右RR
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;当==根结点右子树的右子树==有节点插入，导致二叉树不平衡&lt;/li&gt;
&lt;li&gt;一次左旋&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="右左rl"&gt;右左RL
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;当==根结点右子树的左子树==有节点插入，导致二叉树不平衡&lt;/li&gt;
&lt;li&gt;先局部右旋 -&amp;gt; 右右RR&lt;/li&gt;
&lt;li&gt;再整体左旋&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src="https://creat.asia/post/image/09-8.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="红黑树"&gt;红黑树
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;平衡二叉树的弊端：在添加节点的时候，旋转次数太多，造成添加节点的时间浪费&lt;/li&gt;
&lt;li&gt;红黑树刚开始被称为&lt;strong&gt;平衡二叉B树&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;是一种特殊的二叉查找树，红黑树的每一个节点上都有存储位表示节点的颜色&lt;/li&gt;
&lt;li&gt;&lt;span style="color: #dc3545;"&gt;每一个节点可以是红或者黑；红黑树不是高度平衡的，他的平衡是通过“红黑规则“进行实现的&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;是一个二叉查找树&lt;/li&gt;
&lt;li&gt;==但是不是高度平衡的==&lt;/li&gt;
&lt;li&gt;条件：特有的&lt;span style="color: #dc3545;"&gt;红黑规则&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="红黑规则"&gt;红黑规则
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;每一个节点是红色或黑色&lt;/li&gt;
&lt;li&gt;根节点必须是黑色的&lt;/li&gt;
&lt;li&gt;如果一个节点没有子节点或者父节点，则该节点相应的指针属性值为Nil，这些Nil被视为叶节点，每个叶节点 (Nil) 是黑色的&lt;/li&gt;
&lt;li&gt;如果某一个节点是红色的，那么它的子节点必须是黑色（不能出现两个红色节点相连的情况）&lt;/li&gt;
&lt;li&gt;对每一个节点，从该接待你到其所有后代叶节点的简单路径上，均包含相同数目的黑色节点&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="添加节点-1"&gt;添加节点
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;添加的节点默认是红色的（红色效率高）&lt;/li&gt;
&lt;li&gt;查找、插入、删除的时间复杂度最坏为O(log n)
&lt;img src="https://creat.asia/post/image/09-10.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Stream流与方法引用</title><link>https://creat.asia/post/10-stream%E6%B5%81%E4%B8%8E%E6%96%B9%E6%B3%95%E5%BC%95%E7%94%A8/</link><pubDate>Tue, 03 Feb 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/10-stream%E6%B5%81%E4%B8%8E%E6%96%B9%E6%B3%95%E5%BC%95%E7%94%A8/</guid><description>&lt;h1 id="stream流的思想和获取stream流"&gt;Stream流的思想和获取Stream流
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;比喻：&lt;/strong&gt; Stream 是流水线，不存数据&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;作用：&lt;/strong&gt; 结合Lambda表达式，简化集合、数组操作&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;类型&lt;/th&gt;
					&lt;th&gt;获取Stream流&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;List&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;.stream()&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Map&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;.entrySet().stream()&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;数组&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Arrays.stream(数组)&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Set&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;.stream()&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;零散数据（同种类型）&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Stream.of(数据)&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//List-------------------------//&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; list &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Collections.&lt;span style="color:#a6e22e"&gt;addAll&lt;/span&gt;(list, &lt;span style="color:#e6db74"&gt;&amp;#34;Java&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;Python&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;C++&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;JavaScript&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;Ruby&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	list.&lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt;() 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 .&lt;span style="color:#a6e22e"&gt;filter&lt;/span&gt;(s &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; s.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;() &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; 4) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 .&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;(System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;::println); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//Map--------------------------//&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	HashMap&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String, Integer&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; map &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; HashMap&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	map.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;aaa&amp;#34;&lt;/span&gt;, 111); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	map.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;bbb&amp;#34;&lt;/span&gt;, 222); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	map.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;ccc&amp;#34;&lt;/span&gt;, 333); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	map.&lt;span style="color:#a6e22e"&gt;entrySet&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt;() 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 .&lt;span style="color:#a6e22e"&gt;filter&lt;/span&gt;(e &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; e.&lt;span style="color:#a6e22e"&gt;getValue&lt;/span&gt;() &lt;span style="color:#f92672"&gt;==&lt;/span&gt; 333) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 .&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;(e &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(e.&lt;span style="color:#a6e22e"&gt;getKey&lt;/span&gt;() &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34; = &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; e.&lt;span style="color:#a6e22e"&gt;getValue&lt;/span&gt;())); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	map.&lt;span style="color:#a6e22e"&gt;keySet&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt;() 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;filter&lt;/span&gt;(k &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; map.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(k) &lt;span style="color:#f92672"&gt;==&lt;/span&gt; 333) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;(k &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(k &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34; = &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; map.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(k))); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//数组---------------------------//&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; arr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {1,2,3,4,5,6,7,8,9,10}; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Arrays.&lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt;(arr) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 .&lt;span style="color:#a6e22e"&gt;filter&lt;/span&gt;(n&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; n&lt;span style="color:#f92672"&gt;==&lt;/span&gt;1) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 .&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;(System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;::println);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//零散数据-----------------------//&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Stream.&lt;span style="color:#a6e22e"&gt;of&lt;/span&gt;(1,2,3,4,5,6,7,8,9,10) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;filter&lt;/span&gt;(n&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; n&lt;span style="color:#f92672"&gt;==&lt;/span&gt;1) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;(System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;::println);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;Stream.of&lt;/code&gt;的注意事项&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;数组必须是引用数据类型！！！&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; sArr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {&lt;span style="color:#e6db74"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;b&amp;#34;&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Stream.&lt;span style="color:#a6e22e"&gt;of&lt;/span&gt;(sArr); &lt;span style="color:#75715e"&gt;// 得到流 [a, b]，长度 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; iArr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {1, 2};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Stream.&lt;span style="color:#a6e22e"&gt;of&lt;/span&gt;(iArr); &lt;span style="color:#75715e"&gt;// 得到流 [[1, 2]]，长度 1！它把整个数组当成了一个元素&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="中间方法和终结方法"&gt;中间方法和终结方法
&lt;/h2&gt;&lt;h3 id="中间方法"&gt;中间方法
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;返回值&lt;strong&gt;还是 Stream&lt;/strong&gt;（可以继续 &lt;code&gt;.filter()&lt;/code&gt;、&lt;code&gt;.map()&lt;/code&gt; 下去）&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;常用方法&lt;/strong&gt;&lt;/th&gt;
					&lt;th style="text-align: center"&gt;&lt;strong&gt;功能&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;备注&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;filter&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: center"&gt;过滤&lt;/td&gt;
					&lt;td&gt;接收 &lt;code&gt;Predicate&lt;/code&gt;，返回 true 的留下。&lt;u&gt;修改Stream中的数据，不会影响原来的数据&lt;/u&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;map&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: center"&gt;类型转换&lt;/td&gt;
					&lt;td&gt;把一种对象换成另一种（如把 &lt;code&gt;Student&lt;/code&gt; 转成 &lt;code&gt;String&lt;/code&gt; 姓名）&lt;code&gt;.map(s -&amp;gt; Integer.parseInt(s.split(&amp;quot;-&amp;quot;)[1]))&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;distinct&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: center"&gt;去重&lt;/td&gt;
					&lt;td&gt;依赖对象的 &lt;code&gt;hashCode&lt;/code&gt; 和 &lt;code&gt;equals&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;limit(n)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: center"&gt;截取前 n 个`&lt;/td&gt;
					&lt;td&gt;获取前几个元素（短路）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;skip(n)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: center"&gt;跳过前 n 个&lt;/td&gt;
					&lt;td&gt;经常和 &lt;code&gt;limit&lt;/code&gt; 组合做&lt;strong&gt;分页&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;sorted&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: center"&gt;排序&lt;/td&gt;
					&lt;td&gt;自然排序或传 &lt;code&gt;Comparator&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;concat&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: center"&gt;合并&lt;/td&gt;
					&lt;td&gt;将a和b两个流合并成一个集 合。&lt;code&gt;Stream.concat(list1.stram(),list2.stream())&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="终结方法"&gt;终结方法
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;返回值&lt;strong&gt;不是 Stream&lt;/strong&gt;（变成 &lt;code&gt;void&lt;/code&gt;、&lt;code&gt;long&lt;/code&gt;、&lt;code&gt;List&lt;/code&gt;、&lt;code&gt;Optional&lt;/code&gt; 等），一旦调用，流彻底关闭&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;常用方法&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;功能&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;备注&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;forEach&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;遍历&lt;/td&gt;
					&lt;td&gt;打印或消费数据&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;.forEach()&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;count&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;统计个数&lt;/td&gt;
					&lt;td&gt;返回 &lt;code&gt;long&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;.count&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;collect&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;收集&lt;/strong&gt;转集合&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;最重要！&lt;/strong&gt; 把流转回 &lt;code&gt;List&lt;/code&gt;, &lt;code&gt;Set&lt;/code&gt;, &lt;code&gt;Map&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;.collect(Collectors.toList())&lt;/code&gt;&lt;br&gt;&lt;code&gt;.collect(Collectors.toSet())&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;toArray&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;收集&lt;/strong&gt;转数组&lt;/td&gt;
					&lt;td&gt;收集流中的数据，放到数组中&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;.toArray(n -&amp;gt; String[n])&lt;/code&gt;&lt;br&gt;&lt;code&gt;.toArray(String[]::new)&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;reduce&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;聚合&lt;/td&gt;
					&lt;td&gt;把所有数据累加/合成一个结果&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;anyMatch&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;匹配&lt;/td&gt;
					&lt;td&gt;只要有一个满足条件就返回 true&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="collect收集到map中"&gt;collect收集到Map中
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;/*
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;		toMap()：参数一表示键的生成规则
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;				 参数二表示值的生成规则
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;		
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;		Function：泛型一表示流中每一个数据的类型
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;				 泛型二表示Map集合中 键/值 的数据类型
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;				 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;		apply形参：依次表示流里面的每一个数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;			 方法体：生成 键/值 的代码
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;			 返回值：已经生成的 键/值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;	*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	例&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;数据格式为 name &lt;span style="color:#f92672"&gt;-&lt;/span&gt; gender &lt;span style="color:#f92672"&gt;-&lt;/span&gt; age
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Map&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String, Integer&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; map &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		list.&lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			.&lt;span style="color:#a6e22e"&gt;filter&lt;/span&gt;(s &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;男&amp;#34;&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;equals&lt;/span&gt;(s.&lt;span style="color:#a6e22e"&gt;spilt&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;-&amp;#34;&lt;/span&gt;)&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			.&lt;span style="color:#a6e22e"&gt;collect&lt;/span&gt;(Collectors.&lt;span style="color:#a6e22e"&gt;toMap&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Function&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;流的类型,键的类型&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; String &lt;span style="color:#a6e22e"&gt;apply&lt;/span&gt;(String s){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;						&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; s.&lt;span style="color:#a6e22e"&gt;split&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;-&amp;#34;&lt;/span&gt;)&lt;span style="color:#f92672"&gt;[&lt;/span&gt;0&lt;span style="color:#f92672"&gt;]&lt;/span&gt;;&lt;span style="color:#75715e"&gt;//name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;						&lt;span style="color:#75715e"&gt;//return null;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				},&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Function&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;流的类型,值的类型&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;						&lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;						&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Integer &lt;span style="color:#a6e22e"&gt;apply&lt;/span&gt;(String s){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;							&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Integer.&lt;span style="color:#a6e22e"&gt;parseInt&lt;/span&gt;(s.&lt;span style="color:#a6e22e"&gt;split&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;-&amp;#34;&lt;/span&gt;)&lt;span style="color:#f92672"&gt;[&lt;/span&gt;2&lt;span style="color:#f92672"&gt;]&lt;/span&gt;);&lt;span style="color:#75715e"&gt;//age&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;							&lt;span style="color:#75715e"&gt;//return null;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;						}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					}));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//----------lambda-----------//				&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Map&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String, Integer&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; map &lt;span style="color:#f92672"&gt;=&lt;/span&gt; list.&lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt;() 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;filter&lt;/span&gt;(s &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;男&amp;#34;&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;equals&lt;/span&gt;(s.&lt;span style="color:#a6e22e"&gt;split&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;-&amp;#34;&lt;/span&gt;)&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt;)) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;collect&lt;/span&gt;(Collectors.&lt;span style="color:#a6e22e"&gt;toMap&lt;/span&gt;(s&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;s.&lt;span style="color:#a6e22e"&gt;split&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;-&amp;#34;&lt;/span&gt;)&lt;span style="color:#f92672"&gt;[&lt;/span&gt;0&lt;span style="color:#f92672"&gt;]&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					s&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; Integer.&lt;span style="color:#a6e22e"&gt;parseInt&lt;/span&gt;(s.&lt;span style="color:#a6e22e"&gt;split&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;-&amp;#34;&lt;/span&gt;)&lt;span style="color:#f92672"&gt;[&lt;/span&gt;2&lt;span style="color:#f92672"&gt;]&lt;/span&gt;))); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
如果要收集到Map集合当中，&lt;strong&gt;&lt;u&gt;键不能重复&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h1 id="方法引用"&gt;方法引用
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;方法引用前提：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;接口对路&lt;/strong&gt;：必须是函数式接口。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;坑位对齐&lt;/strong&gt;：参数、返回值必须和接口方法一模一样。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;现成逻辑&lt;/strong&gt;：逻辑已存在(被引用方法满足当前需求),且 Lambda 内部&lt;strong&gt;只有&lt;/strong&gt;这一行调用。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;格式&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;例子 (Lambda -&amp;gt; 方法引用)&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;静态方法引用&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;类名::静态方法&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;s -&amp;gt; Integer.parseInt(s)&lt;/code&gt; $\rightarrow$ &lt;code&gt;Integer::parseInt&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;实例方法引用&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;对象名::成员方法&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;s -&amp;gt; System.out.println(s)&lt;/code&gt; $\rightarrow$ &lt;code&gt;System.out::println&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;特定类型实例方法&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;类名::成员方法&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;(s1, s2) -&amp;gt; s1.compareTo(s2)&lt;/code&gt; $\rightarrow$ &lt;code&gt;String::compareTo&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;构造方法引用&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;类名::new&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;name -&amp;gt; new Student(name)&lt;/code&gt; $\rightarrow$ &lt;code&gt;Student::new&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="引用成员方法的多种情况"&gt;引用成员方法的多种情况
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;其他类：&lt;/strong&gt; &lt;code&gt;其它类对象::方法名&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;本类：&lt;/strong&gt; &lt;code&gt;this::方法名&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;父类：&lt;/strong&gt; &lt;code&gt;super::方法名&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
当&lt;strong&gt;本类,父类&lt;/strong&gt;的引用处为静态方法时，不可用this/super，应当先创建本类对象&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Daily&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; list &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ArrayList(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Collections.&lt;span style="color:#a6e22e"&gt;addAll&lt;/span&gt;(list, &lt;span style="color:#e6db74"&gt;&amp;#34;张三&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;李四&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;王五&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;张六一&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;孙而七&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;//当方法在本类中，方法为static，创建本类对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; list.&lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;filter&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Daily()::stringJudge) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;(System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;::println); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;boolean&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;stringJudge&lt;/span&gt;(String s) {...} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Parent&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;boolean&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;stringJudge&lt;/span&gt;(String s) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; s.&lt;span style="color:#a6e22e"&gt;startsWith&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;张&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Daily&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; Parent { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;boolean&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;stringJudge&lt;/span&gt;(String s) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; s.&lt;span style="color:#a6e22e"&gt;startsWith&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;张&amp;#34;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; s.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;() &lt;span style="color:#f92672"&gt;==&lt;/span&gt; 3; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;test&lt;/span&gt;(List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; list) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 调子类重写后的方法 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 list.&lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;filter&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;::stringJudge)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 .&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;(System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;::println); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 强制调父类版本 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 list.&lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;filter&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;super&lt;/span&gt;::stringJudge)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 .&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;(System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;::println); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="构造方法的引用"&gt;构造方法的引用
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; list &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ArrayList(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Collections.&lt;span style="color:#a6e22e"&gt;addAll&lt;/span&gt;(list, &lt;span style="color:#e6db74"&gt;&amp;#34;张三,13&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;李四,46&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;王五,15&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Student&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; list1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		list.&lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt;() 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#75715e"&gt;//这里必须在Student中新建一个构造方法&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			.&lt;span style="color:#a6e22e"&gt;map&lt;/span&gt;(Student::&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			.&lt;span style="color:#a6e22e"&gt;collect&lt;/span&gt;(Collectors.&lt;span style="color:#a6e22e"&gt;toList&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/*在Student中
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;	* public Student(String s){ 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;	*	 this.name = s.split(&amp;#34;,&amp;#34;)[0]; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;	*	 this.age = Integer.parseInt(s.split(&amp;#34;,&amp;#34;)[1]);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;	*	 }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="其他调用方式"&gt;其他调用方式
&lt;/h2&gt;&lt;h3 id="类名引用成员方法-类名成员方法"&gt;类名引用成员方法 &lt;code&gt;类名::成员方法&lt;/code&gt;
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;独有的规则&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;被引用方法的形参，需要跟抽象方法的第二个形参到最后一个形参保持一致，返回值需要保持一致&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;抽象方法形参的详解：&lt;/strong&gt;
&lt;strong&gt;第一个参数：&lt;/strong&gt;
表示被引用方法的调用者，决定了可以引用那些类中的方法
在&lt;code&gt;Stream&lt;/code&gt;流当中，第一个参数一般都表示流里面的每一个数据
假设流里面的数据是字符串，那么使用这种方式进行方法引用，只能引用&lt;code&gt;String&lt;/code&gt;这个类中的方法&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二个参数到最后一个参数：&lt;/strong&gt;
跟被引用方法的形参保持一致，&lt;u&gt;如果没有第二个参数，说明被引用的方法需要时无参的成员方法&lt;/u&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;code&gt;String::substring(int beginIndex)&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;这个方法括号里只有 &lt;strong&gt;1 个&lt;/strong&gt; 参数。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;但它是一个成员方法，需要 &lt;strong&gt;1 个&lt;/strong&gt; 调用者。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;所以这个方法引用，要求 Lambda 必须提供 &lt;strong&gt;2 个&lt;/strong&gt; 参数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;第一个参数：必须是 &lt;code&gt;String&lt;/code&gt;（调用者）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第二个参数：必须是 &lt;code&gt;int&lt;/code&gt;（对应 &lt;code&gt;beginIndex&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Lambda 原型&lt;/strong&gt;：&lt;code&gt;(String s, int i) -&amp;gt; s.substring(i)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;总结：&lt;/strong&gt; “类名::成员方法”之所以看起来参数少了一个，是因为第一个参数被拿去“点”那个方法了。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; list &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ArrayList(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Collections.&lt;span style="color:#a6e22e"&gt;addAll&lt;/span&gt;(list, &lt;span style="color:#e6db74"&gt;&amp;#34;aaa&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;bbb&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;ccc&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;ddd&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	list.&lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt;() 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#75715e"&gt;//拿着流里面的每一个数据，去调用String类中的方法&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 .&lt;span style="color:#a6e22e"&gt;map&lt;/span&gt;(String::toUpperCase) &lt;span style="color:#75715e"&gt;//s -&amp;gt; s.toUpperCase()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 .&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;(System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;::println);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="引用数组的构造方法-数据类型new"&gt;引用数组的构造方法 &lt;code&gt;数据类型[]::new&lt;/code&gt;
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Integer&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; array &lt;span style="color:#f92672"&gt;=&lt;/span&gt; list.&lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		.&lt;span style="color:#a6e22e"&gt;toArray&lt;/span&gt;(Integer&lt;span style="color:#f92672"&gt;[]&lt;/span&gt;::&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt;);&lt;span style="color:#75715e"&gt;//v -&amp;gt; new Integer[v]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
数组的类型，需要跟流中数据一致&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="常犯错误"&gt;常犯错误
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Stream 中的参数分配法则：&lt;/strong&gt; 流里的数据总得有个去处。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;要么当&lt;strong&gt;参数&lt;/strong&gt;：喂给静态方法或构造器（如 &lt;code&gt;Student::new&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;要么当&lt;strong&gt;主人&lt;/strong&gt;：自己调用成员方法（如 &lt;code&gt;Student::getName&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;报错的原因&lt;/strong&gt;：通常是因为你既提供了一个主人（&lt;code&gt;new Student()&lt;/code&gt;），又想让流里的数据当参数，结果方法不收参数，数据就“没地方放”了。&lt;/p&gt;</description></item><item><title>异常和File</title><link>https://creat.asia/post/11-%E5%BC%82%E5%B8%B8%E5%92%8Cfile/</link><pubDate>Fri, 20 Mar 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/11-%E5%BC%82%E5%B8%B8%E5%92%8Cfile/</guid><description>&lt;h1 id="异常"&gt;异常
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Throwable（所有异常/错误的根类）
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;|
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├─ Error（系统级致命错误，程序无法恢复）
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├─ OutOfMemoryError（内存溢出，如创建超大对象/无限集合）
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └─ StackOverflowError（栈溢出，如无限递归调用）
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;└─ Exception（程序可处理的异常）运行时异常+编译时异常
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; |
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├─ RuntimeException（运行时异常/非检查型，编译器不强制捕获）
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; | |
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │ ├─ NullPointerException（空指针，调用null对象的方法/属性）
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │ ├─ IndexOutOfBoundsException（下标越界，如数组/集合下标超出范围）
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │ ├─ ClassCastException（类型转换异常，如String强转Integer）
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │ ├─ IllegalArgumentException（参数非法，如传入不符合规则的参数）
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │ └─ ArithmeticException（算术异常，如整数除以0）
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; |
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └─ CheckedException（检查型异常，编译器强制捕获/声明抛出）
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 |
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├─ IOException（IO操作异常）
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │ └─ FileNotFoundException（文件未找到，如读取不存在的文件）
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├─ SQLException（数据库操作异常，如SQL语法错误/连接失败）
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └─ InterruptedException（线程中断异常，如休眠线程被打断）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="捕获异常try-catch"&gt;捕获异常&lt;code&gt;try-catch&lt;/code&gt;
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; arr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {1,2,3}; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;try&lt;/span&gt;{ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//程序创建异常，与catch（）中的异常对比，可捕获 -&amp;gt; 执行catch{..}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//当catch{..}执行完毕，继续向下执行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(arr&lt;span style="color:#f92672"&gt;[&lt;/span&gt;10&lt;span style="color:#f92672"&gt;]&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}&lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (ArrayIndexOutOfBoundsException e){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;数组越界了&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;执行！&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="常见问题"&gt;常见问题
&lt;/h3&gt;&lt;h4 id="如果try中没有遇到问题怎么办"&gt;如果&lt;code&gt;try&lt;/code&gt;中没有遇到问题，怎么办？
&lt;/h4&gt;&lt;blockquote&gt;
&lt;p&gt;会把&lt;code&gt;try&lt;/code&gt;中的所有代码全部执行完毕，&lt;strong&gt;不会执行&lt;/strong&gt;&lt;code&gt;catch&lt;/code&gt;中的代码&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt; 只有出现了异常，才会执行&lt;code&gt;catch&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="如果try中可能遇到多个问题怎么办"&gt;如果&lt;code&gt;try&lt;/code&gt;中可能遇到多个问题，怎么办？
&lt;/h4&gt;&lt;blockquote&gt;
&lt;p&gt;写多个&lt;code&gt;catch&lt;/code&gt;与之对应&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt; 如果捕获多个异常，父类一定要写在下面&lt;/p&gt;
&lt;p&gt;JDK7以后，可以用&lt;code&gt;catch&lt;/code&gt;捕获多个异常，中间用&lt;code&gt;|&lt;/code&gt;隔开&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="如果try中遇到的问题没有被捕获怎么办"&gt;如果&lt;code&gt;try&lt;/code&gt;中遇到的问题没有被捕获，怎么办？
&lt;/h4&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;u&gt;JVM虚拟机默认处理异常&lt;/u&gt;，会停止程序&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="如果try中遇到了问题那么try下面的其他代码块还会执行吗"&gt;如果&lt;code&gt;try&lt;/code&gt;中遇到了问题，那么&lt;code&gt;try&lt;/code&gt;下面的其他代码块还会执行吗？
&lt;/h4&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;不会执行&lt;/strong&gt; ，会直接跳转到对应的&lt;code&gt;catch&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="常用方法"&gt;常用方法
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;方法名&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;e.getMessage()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;String&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;简报&lt;/strong&gt;：只告诉你最简单的错误原因（如 &amp;ldquo;By zero&amp;rdquo;）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;e.toString()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;String&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;中报&lt;/strong&gt;：异常类型 + 错误原因（如 &lt;code&gt;java.lang.ArithmeticException: / by zero&lt;/code&gt;）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;e.printStackTrace()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;详报&lt;/strong&gt;：在控制台打印完整的堆栈信息，&lt;strong&gt;最常用&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="抛出处理"&gt;抛出处理
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;关键字&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;位置&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;后面跟什么&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;throws&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;方法声明处&lt;/td&gt;
					&lt;td&gt;向上抛&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;异常类名&lt;/strong&gt;（可以跟多个）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;throw&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;方法体内&lt;/td&gt;
					&lt;td&gt;制造异常&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;异常对象&lt;/strong&gt;（只能跟一个）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;运行时异常不需要&lt;code&gt;throws&lt;/code&gt;声明&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="自定义异常"&gt;自定义异常
&lt;/h2&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;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;类型&lt;/th&gt;
					&lt;th&gt;继承 &lt;code&gt;Exception&lt;/code&gt;（检查型）&lt;/th&gt;
					&lt;th&gt;继承 &lt;code&gt;RuntimeException&lt;/code&gt;（非检查型）&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;强制要求&lt;/td&gt;
					&lt;td&gt;必须用 try-catch 捕获，或声明 throws&lt;/td&gt;
					&lt;td&gt;无需强制捕获，按需处理&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;适用场景&lt;/td&gt;
					&lt;td&gt;必须处理的严重业务异常（比如文件读写失败）&lt;/td&gt;
					&lt;td&gt;普通业务异常（比如余额不足、用户不存在）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;代码复杂度&lt;/td&gt;
					&lt;td&gt;高（到处加 try-catch）&lt;/td&gt;
					&lt;td&gt;低（只在需要处理的地方捕获）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h1 id="file"&gt;File
&lt;/h1&gt;&lt;h2 id="常用方法-1"&gt;常用方法
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;类别&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;方法名&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;核心功能&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;备注&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;获取&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;getName()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;String&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;获取文件或文件夹名称&lt;/td&gt;
					&lt;td&gt;带后缀名（如 &lt;code&gt;a.txt&lt;/code&gt;）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;length()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;long&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;获取文件大小，文件夹为&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;单位是&lt;strong&gt;字节 (Byte)&lt;/strong&gt;，UTF-8一个汉字三个字节&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;lastModified()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;long&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;最后修改时间&lt;/td&gt;
					&lt;td&gt;毫秒值，需转换日期&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;路径&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;getPath()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;String&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;获取构造时传入的路径&lt;/td&gt;
					&lt;td&gt;怎么 &lt;code&gt;new&lt;/code&gt;的就给什么&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;getAbsolutePath()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;String&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;获取&lt;strong&gt;绝对路径&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;从盘符开始的全路径&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;判断&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;exists()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;boolean&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;路径是否存在&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;最常用&lt;/strong&gt;，防报错必备&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;isFile()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;boolean&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;是否为文件&lt;/td&gt;
					&lt;td&gt;路径不存在则返回 false&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;isDirectory()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;boolean&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;是否为文件夹&lt;/td&gt;
					&lt;td&gt;路径不存在则返回 false&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;创建&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;createNewFile()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;boolean&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;创建新文件&lt;/td&gt;
					&lt;td&gt;文件夹不存在会创建失败&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;mkdirs()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;boolean&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;递归&lt;/strong&gt;创建文件夹&lt;/td&gt;
					&lt;td&gt;建议永远用带 s 的这个&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;删除&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;delete()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;boolean&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;删除文件/空文件夹&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;不走回收站&lt;/strong&gt;，直接消失&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;综合练习：&lt;/strong&gt; 统计各种文件的数量&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 递归方法：统计指定目录下所有文件的后缀名数量（包含子目录）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param src 要统计的目标目录File对象
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @return 后缀名-数量的HashMap，键为后缀名/无后缀，值为对应数量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; HashMap&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String,Integer&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getCount&lt;/span&gt;(File src){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	HashMap&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String,Integer&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;hm &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; HashMap&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	File&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; fs &lt;span style="color:#f92672"&gt;=&lt;/span&gt; src.&lt;span style="color:#a6e22e"&gt;listFiles&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 判空：避免目录为空/无访问权限导致空指针&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (fs &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (File f : fs) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (f.&lt;span style="color:#a6e22e"&gt;isFile&lt;/span&gt;()) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#75715e"&gt;// 按&amp;#34;.&amp;#34;分割文件名，用于提取后缀名（注意转义符\\.）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; split &lt;span style="color:#f92672"&gt;=&lt;/span&gt; f.&lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;split&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;\\.&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#75715e"&gt;// 分割后长度&amp;gt;=2说明有后缀名（如test.txt分割后是[test,txt]）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(split.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; 2){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#75715e"&gt;// 取分割数组最后一个元素作为后缀名&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					String endName &lt;span style="color:#f92672"&gt;=&lt;/span&gt; split&lt;span style="color:#f92672"&gt;[&lt;/span&gt;split.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#f92672"&gt;!&lt;/span&gt;hm.&lt;span style="color:#a6e22e"&gt;containsKey&lt;/span&gt;(endName))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;						hm.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(endName,1);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;						hm.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(endName,hm.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(endName)&lt;span style="color:#f92672"&gt;+&lt;/span&gt;1);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				}&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#75715e"&gt;// 分割后长度&amp;lt;2说明无后缀名（如readme、.gitignore）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#75715e"&gt;// 首次统计&amp;#34;无后缀&amp;#34;：初始化为1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#f92672"&gt;!&lt;/span&gt;hm.&lt;span style="color:#a6e22e"&gt;containsKey&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;无后缀&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;						hm.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;无后缀&amp;#34;&lt;/span&gt;,1);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;						hm.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;无后缀&amp;#34;&lt;/span&gt;,hm.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;无后缀&amp;#34;&lt;/span&gt;)&lt;span style="color:#f92672"&gt;+&lt;/span&gt;1);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			}&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#75715e"&gt;// 当前File是子目录：递归调用getCount统计子目录的后缀名&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				HashMap&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String,Integer&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; dfs &lt;span style="color:#f92672"&gt;=&lt;/span&gt; getCount(f);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#75715e"&gt;// 遍历子目录的统计结果，合并到当前目录的HashMap中&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (String k : dfs.&lt;span style="color:#a6e22e"&gt;keySet&lt;/span&gt;()){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#75715e"&gt;// 当前目录未统计过该后缀：直接赋值子目录的统计数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#f92672"&gt;!&lt;/span&gt;hm.&lt;span style="color:#a6e22e"&gt;containsKey&lt;/span&gt;(k))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;						hm.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(k,dfs.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(k));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#75715e"&gt;// 当前目录已统计过该后缀：累加子目录的统计数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;						hm.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(k,hm.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(k)&lt;span style="color:#f92672"&gt;+&lt;/span&gt;dfs.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(k));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 返回当前目录（含子目录）的最终统计结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; hm;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>IO流</title><link>https://creat.asia/post/12-io%E6%B5%81/</link><pubDate>Sat, 21 Mar 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/12-io%E6%B5%81/</guid><description>&lt;p&gt;&lt;strong&gt;程序是在“内存”里跑的，所以永远以内存为原点。&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;参照物：程序/内存&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Input (输入)&lt;/strong&gt;：数据从硬盘/网络 &lt;strong&gt;流进&lt;/strong&gt; 内存。—— &lt;strong&gt;读（Read）&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Output (输出)&lt;/strong&gt;：数据从内存 &lt;strong&gt;流出&lt;/strong&gt; 到硬盘/网络。—— &lt;strong&gt;写（Write）&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;字节流 (万能，图片/视频/文本)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;字符流 (仅限纯文本，自带编码)&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;输入 (Read)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;InputStream&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Reader&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;输出 (Write)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;OutputStream&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Writer&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="字节流"&gt;字节流
&lt;/h1&gt;&lt;h2 id="fileoutputstream"&gt;&lt;code&gt;FileOutputStream&lt;/code&gt;
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;操作本地文件的字节输出流，可以把程序中的数据写到本地文件中&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="核心步骤"&gt;核心步骤：
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;创建对象&lt;/strong&gt;：&lt;code&gt;FileOutputStream fos = new FileOutputStream(&amp;quot;a.txt&amp;quot;);&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;细节1：如果文件不存在，会自动创建，但是要保证父级路径是存在的。&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;细节2：如果文件存在，会清空原内容&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;写出数据&lt;/strong&gt;：&lt;code&gt;fos.write(97);&lt;/code&gt; // 写出的是 ASCII 码，文件中显示 &amp;lsquo;a&amp;rsquo;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;释放资源&lt;/strong&gt;：&lt;code&gt;fos.close();&lt;/code&gt; // &lt;strong&gt;极其重要！&lt;/strong&gt; 不关流，文件会被程序锁死。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="写出数据的三种方式"&gt;写出数据的三种方式
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;方法名&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;write(int b)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;一次写一个字节&lt;/td&gt;
					&lt;td&gt;极少用，效率太低&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;write(byte[] b)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;一次写一个字节数组&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;常用&lt;/strong&gt;，适合写出大量数据&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;write(byte[] b, off, len)&lt;/code&gt;&lt;/strong&gt; &lt;code&gt;off:offset&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;写出数组的一部分&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;最常用&lt;/strong&gt;，配合循环读取时能精确控制写出的量&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="fileoutputstream写数据的问题"&gt;&lt;code&gt;FileOutputStream&lt;/code&gt;写数据的问题
&lt;/h3&gt;&lt;h4 id="换行"&gt;换行
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Windows&lt;/strong&gt;: &lt;code&gt;\r\n 回车 + 换行，java在底层会补全&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Linux/Unix&lt;/strong&gt;: &lt;code&gt;\n&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mac&lt;/strong&gt;: &lt;code&gt;\r&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;System.lineSeparator() 获取操作系统的换行符&lt;/code&gt;&lt;/p&gt;
&lt;h4 id="续写"&gt;续写
&lt;/h4&gt;&lt;p&gt;&lt;code&gt;public FileOutputStream(File file, boolean append) true则续写&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="fileinputstream"&gt;&lt;code&gt;FileInputStream&lt;/code&gt;
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;功能&lt;/strong&gt;：硬盘 $\rightarrow$ 内存 (读取字节)。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;结束标志&lt;/strong&gt;：读取到 &lt;code&gt;-1&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;性能优化&lt;/strong&gt;：定义 &lt;code&gt;byte[]&lt;/code&gt; 数组作为缓冲区，一次读取多个字节。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：文件拷贝（图片、音视频）、不需要处理文本内容的场景。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="核心步骤-1"&gt;核心步骤：
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;创建对象&lt;/strong&gt;：&lt;code&gt;FileIutputStream fis = new FileIutputStream(&amp;quot;a.txt&amp;quot;);&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;细节1：如果文件不存在，会&lt;strong&gt;直接报错&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;读取数据&lt;/strong&gt;：&lt;code&gt;int b = fis.read(97);&lt;/code&gt; // 读出的是 ASCII 码，读出来显示 &amp;lsquo;a&amp;rsquo;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;细节1： 读到文件末尾，&lt;code&gt;read&lt;/code&gt;返回&lt;code&gt;-1&lt;/code&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;释放资源&lt;/strong&gt;：&lt;code&gt;fis.close();&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="读入数据的方法"&gt;读入数据的方法
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;方法名&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;返回值类型&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;含义&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;read()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;int&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;读取一个字节(效率低)，返回该字节的值；读完返回 &lt;strong&gt;-1&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;read(byte[] buffer)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;int&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;读取字节填充进数组，返回&lt;strong&gt;实际读取个数&lt;/strong&gt;；读完返回 &lt;strong&gt;-1&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;available()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;int&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;返回文件剩余的可读字节数（慎用，大文件会爆内存）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="文件拷贝"&gt;文件拷贝
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	FileInputStream fis &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileInputStream(PATH&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;b.txt&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	FileOutputStream fos &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileOutputStream(PATH&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;copy.txt&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; buffer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1024&lt;span style="color:#f92672"&gt;]&lt;/span&gt;;&lt;span style="color:#75715e"&gt;//1KB &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; len; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; ((len &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (fis.&lt;span style="color:#a6e22e"&gt;read&lt;/span&gt;(buffer))) &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;1) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 fos.&lt;span style="color:#a6e22e"&gt;write&lt;/span&gt;(buffer, 0, len); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	fos.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	fis.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
&lt;strong&gt;&lt;code&gt;close&lt;/code&gt;关闭顺序&lt;/strong&gt;：先开的后关，后开的先关&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="异常处理try-with-resources"&gt;异常处理&lt;code&gt;try-with-resources&lt;/code&gt;
&lt;/h2&gt;&lt;h3 id="try-catch-finally"&gt;&lt;code&gt;try-catch-finally&lt;/code&gt;
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;finally&lt;/code&gt;代码块一定会执行，除非虚拟机退出&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;当流对象实现了&lt;code&gt;AutoCloseable&lt;/code&gt;接口时，可以使用小括号&lt;/strong&gt;
&lt;img src="https://creat.asia/post/image/12-1.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h3 id="修正后的文件拷贝"&gt;修正后的文件拷贝
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	FileInputStream fis &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileInputStream(PATH &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;b.txt&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	FileOutputStream fos &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileOutputStream(PATH &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;copy.txt&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; (fis;fos){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; buffer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1024&lt;span style="color:#f92672"&gt;]&lt;/span&gt;;&lt;span style="color:#75715e"&gt;//1KB &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; len; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; ((len &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (fis.&lt;span style="color:#a6e22e"&gt;read&lt;/span&gt;(buffer))) &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;1) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 fos.&lt;span style="color:#a6e22e"&gt;write&lt;/span&gt;(buffer, 0, len); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	} &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (IOException e) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 e.&lt;span style="color:#a6e22e"&gt;printStackTrace&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="字符集"&gt;字符集
&lt;/h1&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;编码格式&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;中文占位&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;字节流读取过程&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;结果&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;GBK&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;2 字节&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;fis.read()&lt;/code&gt; 一次拿 1 字节&lt;/td&gt;
					&lt;td&gt;拿到了半个字 $\rightarrow$ &lt;strong&gt;乱码&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;UTF-8&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;3 字节&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;fis.read()&lt;/code&gt; 一次拿 1 字节&lt;/td&gt;
					&lt;td&gt;拿到了三分之一个字 $\rightarrow$ &lt;strong&gt;乱码&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="字符流--字节流--字符集"&gt;字符流 = 字节流 + 字符集
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;特性&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;字节流 (Stream)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;字符流 (Reader/Writer)&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;数据单位&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;字节 (8 bit)&lt;/td&gt;
					&lt;td&gt;字符 (16 bit)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;处理对象&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;所有文件&lt;/strong&gt;（图片、视频、文本）&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;仅限纯文本&lt;/strong&gt;（txt, java, html）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;读中文&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;会乱码&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;不会乱码&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;拷贝图片&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;完美拷贝&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;文件会损坏&lt;/strong&gt;（千万别用字符流拷图片）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="核心步骤-2"&gt;核心步骤：
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;创建对象&lt;/strong&gt;：&lt;code&gt;FileReader fr = new FileReader(&amp;quot;a.txt&amp;quot;);&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;_细节_1：&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;读取数据&lt;/strong&gt;：&lt;code&gt;while((ch = fr.read() )!= -1){}&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;细节1：按字节读取，遇到中文，&lt;strong&gt;一次会读多个字节&lt;/strong&gt;，读取后解码。返回整数&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;细节2：读到文件末尾返回&lt;code&gt;-1&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;read()&lt;/code&gt;的细节：&lt;/li&gt;
&lt;li&gt;&lt;em&gt;在读取之后，方法的底层还会进行解码并转成十进制，最终会把这个十进制作为返回值，这个十进制的数据也表示在字符集上的数字。&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;释放资源&lt;/strong&gt;：&lt;code&gt;fr.close();&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="缓冲流"&gt;缓冲流
&lt;/h1&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-plainext" data-lang="plainext"&gt;	IO流体系
	├─ 字节流
	│ ├─ InputStream（字节输入流）
	│ │ ├─ FileInputStream（基本字节输入流）
	│ │ └─ BufferedInputStream（字节缓冲输入流）
	│ └─ OutputStream（字节输出流）
	│ ├─ FileOutputStream（基本字节输出流）
	│ └─ BufferedOutputStream（字节缓冲输出流）
	└─ 字符流
	 ├─ Reader（字符输入流）
	 │ ├─ FileReader（基本字符输入流）
	 │ └─ BufferedReader（字符缓冲输入流）
	 └─ Writer（字符输出流）
	 ├─ FileWriter（基本字符输出流）
	 └─ BufferedWriter（字符缓冲输出流）
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="1为什么它快"&gt;1.为什么它快？
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;普通流&lt;/strong&gt;：每读写一个字节，就要调用一次操作系统的 API，直接操作硬盘。硬盘 IO 是计算机最慢的操作。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;缓冲流&lt;/strong&gt;：在内存中开辟了一个 &lt;strong&gt;8KB (8192 byte)&lt;/strong&gt; 的字节数组（缓冲区）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;输入缓冲&lt;/strong&gt;：一次性从硬盘读 8KB 进来，你调 &lt;code&gt;read()&lt;/code&gt; 时，它是从内存数组里拿。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;输出缓冲&lt;/strong&gt;：你调 &lt;code&gt;write()&lt;/code&gt; 时，数据先存在内存数组里，攒满 8KB 后，一次性“喷”向硬盘。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="2家族结构与包装模式"&gt;2.家族结构与包装模式
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;缓冲流属于&lt;strong&gt;装饰者模式&lt;/strong&gt;（Decorator Pattern），它不具备读写文件的能力，必须依托于“基本流”。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;语法模板：&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// “套娃”式创建：外层关了，内层自动关&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	BufferedInputStream bis &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; BufferedInputStream(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileInputStream(&lt;span style="color:#e6db74"&gt;&amp;#34;a.mp4&amp;#34;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;缓冲流名称&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;包装的基本流&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;字节输入&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;BufferedInputStream&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;FileInputStream&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;字节输出&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;BufferedOutputStream&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;FileOutputStream&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;字符输入&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;BufferedReader&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;FileReader&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;字符输出&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;BufferedWriter&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;FileWriter&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="字符缓冲流的特殊方法"&gt;字符缓冲流的特殊方法
&lt;/h2&gt;&lt;h3 id="-bufferedreader---readline"&gt;① &lt;code&gt;BufferedReader&lt;/code&gt; -&amp;gt; &lt;code&gt;readLine()&lt;/code&gt;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;功能&lt;/strong&gt;：读取一整行，直到遇到换行符（&lt;code&gt;\r&lt;/code&gt; 或 &lt;code&gt;\n&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;返回值&lt;/strong&gt;：返回 &lt;code&gt;String&lt;/code&gt;。&lt;strong&gt;注意：不包含换行符本身。&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;结束标志&lt;/strong&gt;：读到文件末尾返回 &lt;strong&gt;&lt;code&gt;null&lt;/code&gt;&lt;/strong&gt;（注意：不再是 -1）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="-bufferedwriter---newline"&gt;② &lt;code&gt;BufferedWriter&lt;/code&gt; -&amp;gt; &lt;code&gt;newLine()&lt;/code&gt;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;功能&lt;/strong&gt;：写出一个换行符。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优势&lt;/strong&gt;：&lt;strong&gt;跨平台性&lt;/strong&gt;。它会根据当前操作系统自动切换 &lt;code&gt;\r\n&lt;/code&gt; (Win) 或 &lt;code&gt;\n&lt;/code&gt; (Linux)。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="性能对比"&gt;性能对比
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;方式&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;性能&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;评价&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;基本流 + 单字节&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;极慢&lt;/td&gt;
					&lt;td&gt;可能需要几分钟&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;基本流 + 数组 (8KB)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;快&lt;/td&gt;
					&lt;td&gt;常用，性能已经很好了&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;缓冲流 + 单字节&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;快&lt;/td&gt;
					&lt;td&gt;缓冲流弥补了单字节的频繁 IO&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;缓冲流 + 数组 (8KB)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;极快&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;推荐使用&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;1.缓冲区溢出&lt;/strong&gt;：输出流写完后，如果程序突然崩溃且没关流，缓冲区里没满 8KB 的那部分数据会&lt;strong&gt;丢失&lt;/strong&gt;。所以必须 &lt;code&gt;close()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2.刷新缓冲区&lt;/strong&gt;：&lt;code&gt;flush()&lt;/code&gt; 只能清空缓冲区（强制写出），&lt;code&gt;close()&lt;/code&gt; 会先调 &lt;code&gt;flush()&lt;/code&gt; 再关流&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3.内存占用&lt;/strong&gt;：虽然缓冲流快，但每个流都会占 8KB 内存。如果同时开启几万个流，要注意内存溢出&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="带缓冲的字符流读取模板"&gt;带缓冲的字符流读取模板
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; (BufferedReader br &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; BufferedReader(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileReader(&lt;span style="color:#e6db74"&gt;&amp;#34;config.txt&amp;#34;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 BufferedWriter bw &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; BufferedWriter(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileWriter(&lt;span style="color:#e6db74"&gt;&amp;#34;copy.txt&amp;#34;&lt;/span&gt;))) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String line;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;// 1. 读一行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; ((line &lt;span style="color:#f92672"&gt;=&lt;/span&gt; br.&lt;span style="color:#a6e22e"&gt;readLine&lt;/span&gt;()) &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;// 2. 写一行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 bw.&lt;span style="color:#a6e22e"&gt;write&lt;/span&gt;(line);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;// 3. 必须手动补换行，因为 readLine 不读换行符&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 bw.&lt;span style="color:#a6e22e"&gt;newLine&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	} &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (IOException e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 e.&lt;span style="color:#a6e22e"&gt;printStackTrace&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="转换流"&gt;转换流
&lt;/h1&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;转换流名称&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;构造参数&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;作用方向&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;常用场景&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;InputStreamReader&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;InputStream&lt;/code&gt;, &lt;code&gt;Charset&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;字节 $\rightarrow$ 字符 (解码)&lt;/td&gt;
					&lt;td&gt;读取非 UTF-8 编码的文本文件&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;OutputStreamWriter&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;OutputStream&lt;/code&gt;, &lt;code&gt;Charset&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;字符 $\rightarrow$ 字节 (编码)&lt;/td&gt;
					&lt;td&gt;将文本以指定编码存入文件（如存为 GBK）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;JDK11&lt;/code&gt;以后&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 底层其实就是封装了转换流&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;FileReader fr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileReader(&lt;span style="color:#e6db74"&gt;&amp;#34;gbk_file.txt&amp;#34;&lt;/span&gt;, Charset.&lt;span style="color:#a6e22e"&gt;forName&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;GBK&amp;#34;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BufferedReader br &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; BufferedReader(fr);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;如何实现字节流读一整行不出现乱码？&lt;/strong&gt;
字节流 -&amp;gt; 字符流(可以指定编码) -&amp;gt; 字符缓冲流（可以读一整行）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//1. 创建文件字节输入流&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	FileInputStream fis &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileInputStream(PATH &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;d.txt&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 2. 将字节流包装为字符流（默认使用系统编码）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	InputStreamReader isr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; InputStreamReader(fis); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//3. 将字符流包装为缓冲字符流，可以按行读取提高效率&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	BufferedReader br &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; BufferedReader(isr); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(br.&lt;span style="color:#a6e22e"&gt;readLine&lt;/span&gt;()); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	br.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;();&lt;span style="color:#75715e"&gt;//关闭高级流&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="序列化流对象操作流"&gt;序列化流/对象操作流
&lt;/h1&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;ObjectOutputStream&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;ObjectInputStream&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;动作&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;序列化 (Serialization)&lt;/td&gt;
					&lt;td&gt;反序列化 (Deserialization)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;方向&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;内存 $\rightarrow$ 硬盘&lt;/td&gt;
					&lt;td&gt;硬盘 $\rightarrow$ 内存&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;构造方法&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;oos(OutputStream out)&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;ois(InputStream in)&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;方法&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;writeObject(Object obj)&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;readObject()&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;前提条件&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Javabean&lt;/code&gt;必须实现 &lt;code&gt;Serializable&lt;/code&gt;接口&lt;/td&gt;
					&lt;td&gt;类路径必须存在，ID 必须匹配&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//前提：实现Serializable（标记性）接口&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Student stu &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Student(&lt;span style="color:#e6db74"&gt;&amp;#34;张三&amp;#34;&lt;/span&gt;, 20); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ObjectOutputStream oos &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ObjectOutputStream(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileOutputStream(PATH&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;student.txt&amp;#34;&lt;/span&gt;)); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	oos.&lt;span style="color:#a6e22e"&gt;writeObject&lt;/span&gt;(stu); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	oos.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//--------------------------------------------//&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ObjectInputStream ois &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ObjectInputStream(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileInputStream(PATH&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;student.txt&amp;#34;&lt;/span&gt;)); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(ois.&lt;span style="color:#a6e22e"&gt;readObject&lt;/span&gt;()); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ois.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="细节一serialversionuid-版本号"&gt;细节一：&lt;code&gt;serialVersionUID&lt;/code&gt; (版本号)
&lt;/h2&gt;&lt;p&gt;当你序列化一个对象后，如果修改了类的代码（比如加了个字段），再进行反序列化就会报 &lt;code&gt;InvalidClassException&lt;/code&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;解决&lt;/strong&gt;：手动给类加一个固定的 ID。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;private static final long serialVersionUID = 1L;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;这样即使类改了，只要 ID 没变，Java 就会认为它们是同一个类。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="细节二transient-瞬态关键字"&gt;细节二：&lt;code&gt;transient&lt;/code&gt; (瞬态关键字)
&lt;/h2&gt;&lt;p&gt;如果你不希望某个成员变量被保存到硬盘（比如用户的&lt;strong&gt;密码&lt;/strong&gt;），只需在变量前加 &lt;code&gt;transient&lt;/code&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;private transient String password;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;反序列化回来后，该字段会变成默认值（如 &lt;code&gt;null&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="细节三"&gt;细节三：
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;序列化时写入什么类型，反序列化时就必须用什么类型接收，类型必须完全一致。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Student s1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Student(&lt;span style="color:#e6db74"&gt;&amp;#34;张三&amp;#34;&lt;/span&gt;,23,&lt;span style="color:#e6db74"&gt;&amp;#34;南京&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Student s2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Student(&lt;span style="color:#e6db74"&gt;&amp;#34;李四&amp;#34;&lt;/span&gt;,22,&lt;span style="color:#e6db74"&gt;&amp;#34;重庆&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Student s3 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Student(&lt;span style="color:#e6db74"&gt;&amp;#34;王五&amp;#34;&lt;/span&gt;,24,&lt;span style="color:#e6db74"&gt;&amp;#34;上海&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Student&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; list &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	list.&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(s1); list.&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(s2); list.&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(s3); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ObjectOutputStream oos &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ObjectOutputStream(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileOutputStream(PATH&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;student.txt&amp;#34;&lt;/span&gt;)); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//序列化使用Array List写入&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	oos.&lt;span style="color:#a6e22e"&gt;writeObject&lt;/span&gt;(list); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	oos.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//---------反序列化---------//&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ObjectInputStream ois &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ObjectInputStream(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileInputStream(PATH&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;student.txt&amp;#34;&lt;/span&gt;)); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//同样使用ArrayList反序列化&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Student&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; list &lt;span style="color:#f92672"&gt;=&lt;/span&gt;(ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Student&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;)ois.&lt;span style="color:#a6e22e"&gt;readObject&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (Student s : list) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(s); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ois.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="打印流"&gt;打印流
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;地位&lt;/strong&gt;：最方便的&lt;strong&gt;只写&lt;/strong&gt;流。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;三大招&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;println()&lt;/code&gt;：写啥都行，写完换行。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;printf()&lt;/code&gt;：格式化打印（如保留两位小数 &lt;code&gt;% .2f&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;System.setOut()&lt;/code&gt;：重定向输出。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;打印流只有输出，没有输入。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;它是对其他输出流的包装，可以配合缓冲流一起用：&lt;code&gt;new PrintWriter(new BufferedWriter(new FileWriter(&amp;quot;a.txt&amp;quot;)))&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;类别&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;名 称&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;对应家族&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;常用场景&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;字节打印流&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;PrintStream&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;OutputStream&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;标准输出（控制台）、日志记录&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;字符打印流&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;PrintWriter&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Writer&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;网页响应 (Servlet)、文本写入&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="字节打印流"&gt;字节打印流
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	PrintStream ps &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; PrintStream(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileOutputStream(PATH &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;c.txt&amp;#34;&lt;/span&gt;),&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,Charset.&lt;span style="color:#a6e22e"&gt;forName&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;UTF-8&amp;#34;&lt;/span&gt;)); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ps.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(97);&lt;span style="color:#75715e"&gt;//写出 + 自动刷新 + 自动换行 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ps.&lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;%s+%s = %s&amp;#34;&lt;/span&gt;,1,1,2); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ps.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="字符打印流"&gt;字符打印流
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	PrintWriter pw &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; PrintWriter(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileWriter(PATH&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;c.txt&amp;#34;&lt;/span&gt;), &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	pw.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;你好&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	pw.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="核心区别"&gt;核心区别
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;字节打印流 (PrintStream)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;字符打印流 (PrintWriter)&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;所属家族&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;OutputStream&lt;/code&gt; 的子类&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Writer&lt;/code&gt; 的子类&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;处理单位&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;字节&lt;/strong&gt;（即使你传的是字符，它也会先转成字节）&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;字符&lt;/strong&gt;（直接按字符处理）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;内部缓冲区&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;没有&lt;/strong&gt;（它直接调底层的 OutputStream）&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;有&lt;/strong&gt;（它内部维护了一个字符缓冲区）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;自动刷新 (AutoFlush)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;只要调了 &lt;code&gt;println&lt;/code&gt; 就会自动刷新&lt;/td&gt;
					&lt;td&gt;必须在构造器手动开启 &lt;code&gt;true&lt;/code&gt; 才会自动刷新&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;主要用途&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;标准输出 (&lt;code&gt;System.out&lt;/code&gt;)、&lt;strong&gt;写原始字节数据&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;写纯文本&lt;/strong&gt;、Web 开发 (Servlet 响应)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="标准输出流-systemout"&gt;标准输出流 (System.out)
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;本质&lt;/strong&gt;：一个预定义的 &lt;code&gt;PrintStream&lt;/code&gt; 对象。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;特点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;随 JVM 启动而产生，随 JVM 关闭而销毁。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;专门用于向控制台输出数据。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;核心功能&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;print()&lt;/code&gt; / &lt;code&gt;println()&lt;/code&gt;：万能打印。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;printf()&lt;/code&gt;：格式化打印（如 &lt;code&gt;%d&lt;/code&gt;, &lt;code&gt;%f&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;System.setOut(PrintStream)&lt;/code&gt;：修改输出目的地（常用于写简单的日志工具）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="解压缩流压缩流"&gt;解压缩流/压缩流
&lt;/h1&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-plainext" data-lang="plainext"&gt;	InputStream（字节输入流）-&amp;gt; 解压缩流
	OutputStream（字节输出流）-&amp;gt; 压缩流
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="解压"&gt;解压
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;什么是 ZipEntry？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;一个 ZIP 文件就像一个大包裹，里面的每个文件或文件夹都是一个 &lt;strong&gt;&lt;code&gt;ZipEntry&lt;/code&gt;&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;解压过程&lt;/strong&gt;：就是通过 &lt;code&gt;getNextEntry()&lt;/code&gt; 方法，一个一个地把包裹里的东西（Entry）拿出来，然后用普通的字节流（&lt;code&gt;FileOutputStream&lt;/code&gt;）把它们写到本地。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;unzip&lt;/span&gt;(File src,File dest) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; IOException { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ZipInputStream zip &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ZipInputStream(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileInputStream(src)); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ZipEntry entry; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; ((entry &lt;span style="color:#f92672"&gt;=&lt;/span&gt; zip.&lt;span style="color:#a6e22e"&gt;getNextEntry&lt;/span&gt;()) &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(entry.&lt;span style="color:#a6e22e"&gt;isDirectory&lt;/span&gt;()){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; File f &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; File(dest,entry.&lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;()); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; f.&lt;span style="color:#a6e22e"&gt;mkdirs&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; FileOutputStream fos &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileOutputStream(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; File(dest,entry.&lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;())); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; b; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;((b &lt;span style="color:#f92672"&gt;=&lt;/span&gt; zip.&lt;span style="color:#a6e22e"&gt;read&lt;/span&gt;()) &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;1){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fos.&lt;span style="color:#a6e22e"&gt;write&lt;/span&gt;(b); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fos.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; zip.&lt;span style="color:#a6e22e"&gt;closeEntry&lt;/span&gt;();&lt;span style="color:#75715e"&gt;//表示在压缩包中的一个文件处理完毕了 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; zip.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>多线程和JUC</title><link>https://creat.asia/post/13-%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%92%8Cjuc/</link><pubDate>Sun, 22 Mar 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/13-%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%92%8Cjuc/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-03-22&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="多线程"&gt;多线程
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;1.&lt;strong&gt;进程 (Process)&lt;/strong&gt;：运行中的程序（比如 IDEA、Chrome、QQ）。它是操作系统资源分配的最小单位。&lt;/p&gt;
&lt;p&gt;2.&lt;strong&gt;线程 (Thread)&lt;/strong&gt;：进程中的一个“执行路径”。一个进程可以包含多个线程（比如 Chrome 里一个线程下载文件，一个线程渲染网页）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="并发和并行"&gt;并发和并行
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;并发 (Concurrency)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;并行 (Parallelism)&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;核心特点&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;任务&lt;strong&gt;交替&lt;/strong&gt;执行&lt;/td&gt;
					&lt;td&gt;任务&lt;strong&gt;同时&lt;/strong&gt;执行&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;资源需求&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;单核 CPU 即可实现&lt;/td&gt;
					&lt;td&gt;必须&lt;strong&gt;多核 CPU&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;目的&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;提高 CPU 利用率，解决“阻塞”&lt;/td&gt;
					&lt;td&gt;提高计算速度，缩短处理时间&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;关系&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;并发不一定是并行&lt;/td&gt;
					&lt;td&gt;并行一定是并发的一种形式&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;img src="https://creat.asia/post/image/13-%e5%a4%9a%e7%ba%bf%e7%a8%8b%e5%92%8cJUC-1.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="实现方式"&gt;实现方式
&lt;/h2&gt;&lt;h3 id="继承thread类"&gt;继承&lt;code&gt;Thread&lt;/code&gt;类
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;MyThread&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; Thread {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;run&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; 100; i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(getName() &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34; 在运行: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; i);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 启动：new MyThread().start();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	优点:代码简单&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;直接 &lt;span style="color:#960050;background-color:#1e0010"&gt;`&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;`&lt;/span&gt; 就能获取线程名&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	缺点&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;Java 是单继承&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;继承了 Thread 就不能继承别的类了&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="实现runnable接口"&gt;实现&lt;code&gt;Runnable&lt;/code&gt;接口
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;MyRun&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; Runnable {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;run&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(Thread.&lt;span style="color:#a6e22e"&gt;currentThread&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;() &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34; 执行中&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 启动：new Thread(new MyRun()).start();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	优点&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;扩展性强&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;可以实现接口的同时继承别的类&lt;span style="color:#960050;background-color:#1e0010"&gt;；&lt;/span&gt;适合多个线程处理同一个资源&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="实现callable接口"&gt;实现&lt;code&gt;Callable&lt;/code&gt;接口
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;MyCallable&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; Callable&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Integer&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Integer &lt;span style="color:#a6e22e"&gt;call&lt;/span&gt;() &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; Exception {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; 100 &lt;span style="color:#f92672"&gt;+&lt;/span&gt; 200; &lt;span style="color:#75715e"&gt;// 返回计算结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 启动需配合 FutureTask&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	特点&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;可以获取线程执行后的结果&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;还能抛出异常&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="成员方法"&gt;成员方法
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;方法名&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;备注&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;setName(String name)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;设置线程名称&lt;/td&gt;
					&lt;td&gt;默认是 &lt;code&gt;Thread-0,Thread-1&lt;/code&gt; 等&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getName()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取线程名称&lt;/td&gt;
					&lt;td&gt;建议在构造时就起好名字&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getPriority()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取线程优先级&lt;/td&gt;
					&lt;td&gt;范围 1-10，默认 5&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;setPriority(int p)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;设置线程优先级&lt;/td&gt;
					&lt;td&gt;优先级越高，抢到 CPU 时间片的&lt;strong&gt;概率&lt;/strong&gt;越大&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;currentThread()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;静态方法&lt;/strong&gt;，获取当前线程&lt;/td&gt;
					&lt;td&gt;哪条线程执行这行代码，就返回谁&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;给线程设置名字：&lt;/strong&gt;
可以用&lt;code&gt;set&lt;/code&gt;也可以用构造方法&lt;/p&gt;
&lt;p&gt;&lt;code&gt;currentThread()&lt;/code&gt;:
当&lt;code&gt;JVM&lt;/code&gt;虚拟机启动之后，会自动启动多条线程，其中一条是&lt;code&gt;main&lt;/code&gt;线程，它的作用是调用&lt;code&gt;main&lt;/code&gt;方法，并执行里面的代码。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="状态控制方法"&gt;状态控制方法
&lt;/h3&gt;&lt;p&gt;这些方法直接影响线程的运行节奏，是多线程编程的核心。&lt;/p&gt;
&lt;h4 id="-sleeplong-ms线程休眠"&gt;① &lt;code&gt;sleep(long ms)&lt;/code&gt;：线程休眠
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;类型&lt;/strong&gt;：静态方法。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;：让当前线程进入“阻塞状态”指定的时间。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;特点&lt;/strong&gt;：&lt;strong&gt;不释放锁&lt;/strong&gt;（如果你拿着钥匙睡觉，别人依然进不来）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;应用&lt;/strong&gt;：在拼图游戏中，如果想制作一个“倒计时”或“动画间隔”，就用它。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="-yield线程让步"&gt;② &lt;code&gt;yield()&lt;/code&gt;：线程让步
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;类型&lt;/strong&gt;：静态方法。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;：暗示 CPU 当前线程愿意让出执行权。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;特点&lt;/strong&gt;：线程从“运行”回到“就绪”状态。CPU 可能会再次选中它，也可能选中别人。这是一种&lt;strong&gt;谦让&lt;/strong&gt;，不是强制停止。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="-join线程插队"&gt;③ &lt;code&gt;join()&lt;/code&gt;：线程插队
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;类型&lt;/strong&gt;：成员方法。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;：在 A 线程中调用 &lt;code&gt;B.join()&lt;/code&gt;，意味着 A 必须等 B 执行完，A 才能继续。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;类比&lt;/strong&gt;：你在排队买饭，突然一个 VIP（B 线程）插到了你前面，你必须等他买完。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="守护线程daemon-thread"&gt;守护线程&lt;code&gt;（Daemon Thread）&lt;/code&gt;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;方法&lt;/strong&gt;：&lt;code&gt;setDaemon(true)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;定义&lt;/strong&gt;：当进程中所有的“用户线程”都结束了，守护线程即便没运行完，也会&lt;strong&gt;被 JVM 强制杀掉&lt;/strong&gt;。(不是立马结束，而是 &lt;strong&gt;陆续结束&lt;/strong&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;比喻&lt;/strong&gt;：用户线程是“国王”，守护线程是“保镖”。国王死了，保镖也就没存在的意义了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;应用&lt;/strong&gt;：垃圾回收器（GC）就是一个经典的守护线程。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="生命周期"&gt;生命周期
&lt;/h2&gt;&lt;p&gt;&lt;img src="https://creat.asia/post/image/13-%e5%a4%9a%e7%ba%bf%e7%a8%8b%e5%92%8cJUC-2.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h2 id="线程安全"&gt;线程安全
&lt;/h2&gt;&lt;h3 id="三大特性"&gt;三大特性
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;原子性 (Atomicity)&lt;/strong&gt;：一个操作要么全部执行成功，要么全部失败，中间不能被中断。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;可见性 (Visibility)&lt;/strong&gt;：一个线程修改了共享变量的值，其他线程能够立即看到。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;有序性 (Ordering)&lt;/strong&gt;：程序执行的顺序按照代码的先后顺序执行（防止指令重排）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="为什么会出现线程不安全"&gt;为什么会出现线程不安全？
&lt;/h3&gt;&lt;p&gt;线程安全问题发生的&lt;strong&gt;三个必要条件&lt;/strong&gt;（缺一不可）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;多线程环境&lt;/strong&gt;：至少有两个线程在跑。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;共享资源&lt;/strong&gt;：多个线程访问同一个变量（如成员变量、静态变量）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;写操作&lt;/strong&gt;：至少有一个线程在修改这个变量。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="解决方案1-同步代码块-synchronized"&gt;解决方案1: 同步代码块 &lt;code&gt;(synchronized)&lt;/code&gt;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;在实例方法中，通常用 &lt;code&gt;this&lt;/code&gt;；在静态方法中，通常用 &lt;code&gt;类名.class&lt;/code&gt;。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;MyThread&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; Thread { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; sum &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//锁对象，一定要是唯一的&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; Object obj &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Object(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;run&lt;/span&gt;() { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;synchronized&lt;/span&gt; (obj) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 核心：在锁内部再次判断，保证原子性 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (sum &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; 100) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Thread.&lt;span style="color:#a6e22e"&gt;sleep&lt;/span&gt;(100); &lt;span style="color:#75715e"&gt;// 模拟网络延迟或出票时间 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (InterruptedException e) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; e.&lt;span style="color:#a6e22e"&gt;printStackTrace&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sum&lt;span style="color:#f92672"&gt;++&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(getName()&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;正在卖第&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;sum&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;张票!&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 票卖完了，跳出死循环 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;break&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="-卖票案例避坑指南"&gt;🛠️ 卖票案例避坑指南
&lt;/h4&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;锁的唯一性&lt;/strong&gt;：用了 &lt;code&gt;static final Object obj&lt;/code&gt;，这确保了无论创建多少个 &lt;code&gt;MyThread&lt;/code&gt; 对象，它们抢的都是同一把锁。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;判断逻辑的位置&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;如果判断在 &lt;code&gt;synchronized&lt;/code&gt; 外面，会有“判断通过但由于抢锁延迟导致数据过期”的风险。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;金律&lt;/strong&gt;：对共享变量的&lt;strong&gt;判断&lt;/strong&gt;和&lt;strong&gt;修改&lt;/strong&gt;，必须包裹在同一个 &lt;code&gt;synchronized&lt;/code&gt; 块内。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sleep 的位置&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;sleep&lt;/code&gt; 放在同步块里会**“抱着锁睡觉”**，其他线程只能干等，效率低。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在这个练习中，它是为了放大问题。在实际开发中，应尽量缩短同步块的代码量。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="解决方案2-同步方法"&gt;解决方案2: 同步方法
&lt;/h3&gt;&lt;h4 id="同步方法的分类与锁对象"&gt;同步方法的分类与锁对象
&lt;/h4&gt;&lt;blockquote&gt;
&lt;p&gt;同步方法分为两种，它们的锁对象是 Java 自动指定的，不需要手动创建 &lt;code&gt;obj&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h5 id="-同步实例方法非静态"&gt;① 同步实例方法（非静态）
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;格式&lt;/strong&gt;：&lt;code&gt;public synchronized void method() { ... }&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;锁对象&lt;/strong&gt;：&lt;strong&gt;&lt;code&gt;this&lt;/code&gt;&lt;/strong&gt;（当前调用该方法的对象）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：多个线程操作同一个对象的成员变量。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="-同步静态方法"&gt;② 同步静态方法
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;格式&lt;/strong&gt;：&lt;code&gt;public static synchronized void method() { ... }&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;锁对象&lt;/strong&gt;：&lt;strong&gt;&lt;code&gt;类名.class&lt;/code&gt;&lt;/strong&gt;（当前类的字节码文件对象）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：多个线程操作类的静态变量（比如你代码里的 &lt;code&gt;static int sum&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;code&gt;StringBuffer&lt;/code&gt;、&lt;code&gt;Vector&lt;/code&gt;、&lt;code&gt;Hashtable&lt;/code&gt; 内部都是通过同步方法实现线程安全的，所以它们效率比 &lt;code&gt;StringBuilder&lt;/code&gt;、&lt;code&gt;ArrayList&lt;/code&gt;、&lt;code&gt;HashMap&lt;/code&gt; 低&lt;/p&gt;
&lt;p&gt;单线程用&lt;code&gt;StringBuilder&lt;/code&gt;，多线程要&lt;strong&gt;考虑线程安全&lt;/strong&gt;用&lt;code&gt;StringBuffer&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="lock锁接口"&gt;&lt;code&gt;Lock&lt;/code&gt;锁(接口)
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;1.Static 关键字&lt;/strong&gt;：因为是 &lt;code&gt;extends Thread&lt;/code&gt;，所以 &lt;code&gt;Lock&lt;/code&gt; 必须加 &lt;code&gt;static&lt;/code&gt;。否则每个线程对象都有一把自己的锁，根本锁不住！&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2.Lock 的位置&lt;/strong&gt;：放在 &lt;code&gt;try&lt;/code&gt; 块上方。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3.Unlock 的位置&lt;/strong&gt;：必须在 &lt;code&gt;finally&lt;/code&gt; 第一行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4.死循环出口&lt;/strong&gt;：在 &lt;code&gt;break&lt;/code&gt; 之前，务必确保 &lt;code&gt;finally&lt;/code&gt; 能被触发（Java 默认支持，不用担心）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;MyThread&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; Thread {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; sum &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; Lock lock &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ReentrantLock();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;run&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 1. 锁放在 try 外面&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; lock.&lt;span style="color:#a6e22e"&gt;lock&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (sum &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; 100) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Thread.&lt;span style="color:#a6e22e"&gt;sleep&lt;/span&gt;(10); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sum&lt;span style="color:#f92672"&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;					sout(getName() &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;正在卖第&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; sum &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;张票!&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 2. 票卖完了，跳出循环&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;break&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (InterruptedException e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; e.&lt;span style="color:#a6e22e"&gt;printStackTrace&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;finally&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 3. 无论如何都会还锁&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; lock.&lt;span style="color:#a6e22e"&gt;unlock&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="锁的权衡-trade-off"&gt;锁的权衡 (Trade-off)
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;synchronized&lt;/code&gt;&lt;/strong&gt;：&lt;strong&gt;自动挡&lt;/strong&gt;。适合 80% 的日常业务场景，JVM 帮你管，安全、省心。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Lock&lt;/code&gt;&lt;/strong&gt;：&lt;strong&gt;手动挡&lt;/strong&gt;。适合 20% 的高并发、高性能、复杂调度场景。能漂移、能极速，但操作不当容易熄火（死锁）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;结论&lt;/strong&gt;：&lt;strong&gt;优先使用 &lt;code&gt;synchronized&lt;/code&gt;&lt;/strong&gt;，直到你发现它实现不了你的某个高级需求（如公平性、超时、尝试获取）时，再重构为 &lt;code&gt;Lock&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="等待唤醒机制"&gt;等待唤醒机制
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;生产者 (Producer)&lt;/strong&gt;：负责准备数据（比如从网络下载图片、计算游戏解法）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;消费者 (Consumer)&lt;/strong&gt;：负责使用数据（比如把图片渲染到屏幕、执行步数）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;仓库 (Buffer)&lt;/strong&gt;：中间存储数据的变量或容器。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;方法名&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;状态切换&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;wait()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;让当前线程释放锁，进入等待池，直到被唤醒&lt;/td&gt;
					&lt;td&gt;运行 -&amp;gt; 等待&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;notify()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;随机唤醒&lt;strong&gt;一个&lt;/strong&gt;在该锁上等待的线程&lt;/td&gt;
					&lt;td&gt;等待 -&amp;gt; 就绪&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;notifyAll()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;唤醒在&lt;strong&gt;这把锁&lt;/strong&gt;上等待的&lt;strong&gt;所有&lt;/strong&gt;线程（更安全）&lt;/td&gt;
					&lt;td&gt;等待 -&amp;gt; 就绪&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//定义中间控制类（Buffer）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Desk&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 0: 没有饭, 1: 有饭&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; foodFlag &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 锁对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; Object lock &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Object();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//消费者&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;run&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;synchronized&lt;/span&gt; (Desk.&lt;span style="color:#a6e22e"&gt;lock&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (Desk.&lt;span style="color:#a6e22e"&gt;foodFlag&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; 0) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; { Desk.&lt;span style="color:#a6e22e"&gt;lock&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;wait&lt;/span&gt;(); } &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (Exception e) {} &lt;span style="color:#75715e"&gt;// 没饭就等&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;吃货：开炫！&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Desk.&lt;span style="color:#a6e22e"&gt;foodFlag&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0; &lt;span style="color:#75715e"&gt;// 吃完了&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Desk.&lt;span style="color:#a6e22e"&gt;lock&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;notifyAll&lt;/span&gt;(); &lt;span style="color:#75715e"&gt;// 叫醒厨师再做点&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//生产者&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;run&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;synchronized&lt;/span&gt; (Desk.&lt;span style="color:#a6e22e"&gt;lock&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (Desk.&lt;span style="color:#a6e22e"&gt;foodFlag&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; 1) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; { Desk.&lt;span style="color:#a6e22e"&gt;lock&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;wait&lt;/span&gt;(); } &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (Exception e) {} &lt;span style="color:#75715e"&gt;// 有饭就歇着&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;厨师：出锅一份回锅肉！&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Desk.&lt;span style="color:#a6e22e"&gt;foodFlag&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 1; &lt;span style="color:#75715e"&gt;// 饭好了&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Desk.&lt;span style="color:#a6e22e"&gt;lock&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;notifyAll&lt;/span&gt;(); &lt;span style="color:#75715e"&gt;// 叫醒吃货开饭&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="阻塞队列"&gt;阻塞队列
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;实现类&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;特点&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;ArrayBlockingQueue&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;有界&lt;/strong&gt;，底层是数组&lt;/td&gt;
					&lt;td&gt;必须指定大小，性能稳定，最常用。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;LinkedBlockingQueue&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;可选界&lt;/strong&gt;，底层是链表&lt;/td&gt;
					&lt;td&gt;默认大小是 &lt;code&gt;Integer.MAX_VALUE&lt;/code&gt;（接近无限），容易 OOM。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//生产者&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Cook&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; Thread {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; BlockingQueue&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; queue;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Cook&lt;/span&gt;(BlockingQueue&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; queue) { &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;queue&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; queue; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;run&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// put 方法自带阻塞逻辑：如果队列满了，就在这儿等&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; queue.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;回锅肉&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;厨师放了一份回锅肉，当前库存：&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; queue.&lt;span style="color:#a6e22e"&gt;size&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (InterruptedException e) { e.&lt;span style="color:#a6e22e"&gt;printStackTrace&lt;/span&gt;(); }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//消费者&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Foodie&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; Thread {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; BlockingQueue&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; queue;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Foodie&lt;/span&gt;(BlockingQueue&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; queue) { &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;queue&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; queue; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;run&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// take 方法自带阻塞逻辑：如果队列空了，就在这儿等&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String food &lt;span style="color:#f92672"&gt;=&lt;/span&gt; queue.&lt;span style="color:#a6e22e"&gt;take&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;吃货炫了一份：&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; food);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (InterruptedException e) { e.&lt;span style="color:#a6e22e"&gt;printStackTrace&lt;/span&gt;(); }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//测试类（连接两者）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 创建一个只能装 1 份饭的阻塞队列&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BlockingQueue&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; queue &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ArrayBlockingQueue&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;(1);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Cook(queue).&lt;span style="color:#a6e22e"&gt;start&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Foodie(queue).&lt;span style="color:#a6e22e"&gt;start&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;操作类型&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;抛出异常&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;返回特殊值&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;阻塞（推荐）&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;超时退出&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;插入&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;add(e)&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;offer(e)&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;put(e)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;offer(e, time, unit)&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;移除&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;remove()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;poll()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;take()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;poll(time, unit)&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;检查&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;element()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;peek()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;无&lt;/td&gt;
					&lt;td&gt;无&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="线程池"&gt;线程池
&lt;/h2&gt;&lt;h3 id="线程池的优点"&gt;线程池的优点
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;降低资源消耗&lt;/strong&gt;：通过重复利用已创建的线程，降低线程创建和销毁造成的开销。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;提高响应速度&lt;/strong&gt;：任务到达时，不需要等待线程创建就能立即执行。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;提高线程的可管理性&lt;/strong&gt;：线程是稀缺资源，如果无限制地创建，会降低系统稳定性。线程池可以进行统一分配、调优和监控。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;API&lt;/th&gt;
					&lt;th&gt;问题&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Executors.newFixedThreadPool()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;使用无界队列，可能导致 OOM&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Executors.newCachedThreadPool()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;最大线程数为 Integer.MAX_VALUE，可能瞬间创建几十万线程&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Executors.newScheduledThreadPool()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;核心线程不会回收&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="核心元素"&gt;核心元素
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;参数&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;对应比喻&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;官方定义&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;corePoolSize&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;正式员工&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;核心线程数（常驻线程）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;maximumPoolSize&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;全部员工&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;最大线程数（核心 + 临时）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;keepAliveTime&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;解雇等待期&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;临时线程闲置多久后被销毁。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;unit&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;时间单位&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;对应上面的时间单位（秒、分钟等）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;workQueue&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;等候区&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;任务阻塞队列（放不下的活先排队）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;threadFactory&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;HR/招聘&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;线程工厂（给线程起名、设优先级）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;handler&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;拒单策略&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;拒绝策略（活太多实在干不完怎么办）。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="具体实现"&gt;具体实现
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ThreadPoolExecutor pool &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ThreadPoolExecutor( 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 3, &lt;span style="color:#75715e"&gt;//核心线程数量 不能小于0 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 6, &lt;span style="color:#75715e"&gt;//最大线程数量 不能小于0 且&amp;gt;=核心线程数量 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 60, &lt;span style="color:#75715e"&gt;//空闲线程最大存活时间 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TimeUnit.&lt;span style="color:#a6e22e"&gt;SECONDS&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//空闲线程最大存活时间的单位 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ArrayBlockingQueue&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;(3),&lt;span style="color:#75715e"&gt;//任务队列 不能为null &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Executors.&lt;span style="color:#a6e22e"&gt;defaultThreadFactory&lt;/span&gt;(),&lt;span style="color:#75715e"&gt;//线程工厂 不能为null &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ThreadPoolExecutor.&lt;span style="color:#a6e22e"&gt;AbortPolicy&lt;/span&gt;()&lt;span style="color:#75715e"&gt;//拒绝策略 不能为null &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	任务 1&lt;span style="color:#f92672"&gt;~&lt;/span&gt;3&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;直接创建 3 个核心线程&lt;span style="color:#960050;background-color:#1e0010"&gt;（&lt;/span&gt;正式工&lt;span style="color:#960050;background-color:#1e0010"&gt;）&lt;/span&gt;开始干活
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	任务 4&lt;span style="color:#f92672"&gt;~&lt;/span&gt;6&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;核心线程已满&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;3 个任务进入 ArrayBlockingQueue&lt;span style="color:#960050;background-color:#1e0010"&gt;（&lt;/span&gt;等候区&lt;span style="color:#960050;background-color:#1e0010"&gt;）&lt;/span&gt;排队
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	任务 7&lt;span style="color:#f92672"&gt;~&lt;/span&gt;9&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;等候区已满&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;线程池开启 3 个临时线程&lt;span style="color:#960050;background-color:#1e0010"&gt;（&lt;/span&gt;临时工&lt;span style="color:#960050;background-color:#1e0010"&gt;），&lt;/span&gt;总线程数达到 maximumPoolSize 6 个并开始干活
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	任务 10&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;核心线程&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;队列&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;临时线程均已满&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;触发 AbortPolicy 拒绝策略&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;程序抛出 RejectedExecutionException 异常
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>网络编程</title><link>https://creat.asia/post/14-%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/14-%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-03-26&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="常见架构"&gt;常见架构
&lt;/h1&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;C/S (客户端模式)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;B/S (浏览器模式)&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;硬件要求&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;较高（利用本地资源）&lt;/td&gt;
					&lt;td&gt;较低（主要靠服务器）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;部署难度&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;困难（需逐个安装）&lt;/td&gt;
					&lt;td&gt;极易（地址一输即用）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;升级维护&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;整体升级，成本高&lt;/td&gt;
					&lt;td&gt;无缝升级，用户无感&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;网络要求&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;部分功能可离线运行&lt;/td&gt;
					&lt;td&gt;必须全程联网&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;典型案例&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;英雄联盟、Photoshop&lt;/td&gt;
					&lt;td&gt;知乎、GitHub、1Panel&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="网络编程三要素"&gt;网络编程三要素
&lt;/h1&gt;&lt;h2 id="1-ip-地址-internet-protocol-address--收货地址"&gt;1. IP 地址 (Internet Protocol Address) —— &lt;strong&gt;“收货地址”&lt;/strong&gt;
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;设备在网络中的唯一标识。&lt;/strong&gt; 如果没有 IP 地址，数据包就不知道该发给哪台电脑。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;IPv4&lt;/strong&gt;：目前主流，如 &lt;code&gt;192.168.1.1&lt;/code&gt;。它是 32 位地址，通常用“点分十进制”表fff示。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;IPv6&lt;/strong&gt;：为了解决 IPv4 地址枯竭问题，位数为 128 位，采用“冒分十六进制”。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;特殊地址&lt;/strong&gt;：&lt;code&gt;127.0.0.1&lt;/code&gt; 或 &lt;code&gt;localhost&lt;/code&gt;（回环地址，代表本机）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;方法名&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;返回值示例&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getHostName()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取主机名&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;www.baidu.com&lt;/code&gt; 或 &lt;code&gt;LAPTOP-XXXX&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getHostAddress()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取字符串格式的 IP 地址&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;110.242.68.4&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;isReachable(int timeout)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;测试在指定时间内是否能连接上该地址&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;true&lt;/code&gt; / &lt;code&gt;false&lt;/code&gt;（类似 ping）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="2-端口-port--收货人姓名房间号"&gt;2. 端口 (Port) —— &lt;strong&gt;“收货人姓名/房间号”&lt;/strong&gt;
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;应用程序在设备中的唯一标识。&lt;/strong&gt; 一台电脑上同时运行着微信、IDEA、拼图游戏和浏览器，IP 只能找电脑，而端口负责找到对应的&lt;strong&gt;程序&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;范围&lt;/strong&gt;：0 ~ 65535。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;分类&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;周知端口 (0~1023)&lt;/strong&gt;：被系统协议占用，如 HTTP (80)、HTTPS (443)、FTP (21)。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;注册端口 (1024~49151)&lt;/strong&gt;：常用软件占用，如 MySQL (3306)、Tomcat (8080)、Redis (6379)。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;动态端口 (49152~65535)&lt;/strong&gt;：系统自动分配。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：同一个端口在同一时刻不能被两个程序同时占用。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="3-协议-protocol--语言交通规则"&gt;3. 协议 (Protocol) —— &lt;strong&gt;“语言/交通规则”&lt;/strong&gt;
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;数据传输的规则。&lt;/strong&gt; 通信双方必须遵守相同的约定（如数据格式、重传机制），才能听懂对方在说什么。&lt;/p&gt;
&lt;p&gt;在 Java 基础开发中，最核心的是 &lt;strong&gt;传输层&lt;/strong&gt; 的两大协议：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;协议&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;UDP (用户数据报协议)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;TCP (传输控制协议)&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;连接性&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;面向无连接&lt;/strong&gt;（直接发，不管对方在不在）&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;面向连接&lt;/strong&gt;（必须先握手建立连接）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;可靠性&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;不可靠（可能丢包、乱序）&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;可靠&lt;/strong&gt;（保证数据准确、有序）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;传输效率&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;极高（没有确认机制）&lt;/td&gt;
					&lt;td&gt;相对较低&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;传输限制&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;每个数据包限 64KB&lt;/td&gt;
					&lt;td&gt;无限制（流式传输）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;典型应用&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;视频会议、直播、语音通话&lt;/td&gt;
					&lt;td&gt;浏览器网页 (HTTP)、文件传输、邮件&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="tcpip协议"&gt;TCP/IP协议
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;层级&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;层名称&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;核心职责 (快递比喻)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;常见协议&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;4&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;应用层 (Application)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;内容制作&lt;/strong&gt;：决定快递寄什么（信件、包裹、视频）。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;HTTP, FTP, DNS, SMTP&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;传输层 (Transport)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;运输方式&lt;/strong&gt;：平邮（UDP）还是挂号信（TCP）。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;TCP, UDP&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;网络层 (Internet)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;地址路由&lt;/strong&gt;：规划从上海到北京的最优路线。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;IP, ICMP, ARP&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;网络接口层 (Link)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;物理运输&lt;/strong&gt;：实际上是走铁路、公路还是空运。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Ethernet (以太网), Wi-Fi&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="udp发送数据"&gt;UDP发送数据
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;具体流程&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;找邮局&lt;/strong&gt;：创建 &lt;code&gt;DatagramSocket&lt;/code&gt; 对象（码头/发送端）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;装包裹&lt;/strong&gt;：创建 &lt;code&gt;DatagramPacket&lt;/code&gt; 对象，并打包数据、指定接收端 IP 和端口。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;发快递&lt;/strong&gt;：调用 &lt;code&gt;send()&lt;/code&gt; 方法发送包裹。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;关门走人&lt;/strong&gt;：释放资源（&lt;code&gt;close()&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	DatagramSocket ds &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; DatagramSocket(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String s &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;你好&amp;#34;&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; bytes &lt;span style="color:#f92672"&gt;=&lt;/span&gt; s.&lt;span style="color:#a6e22e"&gt;getBytes&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	InetAddress address &lt;span style="color:#f92672"&gt;=&lt;/span&gt; InetAddress.&lt;span style="color:#a6e22e"&gt;getLocalHost&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 10086; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	DatagramPacket dp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; DatagramPacket(bytes, bytes.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;, address, port); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ds.&lt;span style="color:#a6e22e"&gt;send&lt;/span&gt;(dp); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ds.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="udp接收数据"&gt;UDP接收数据
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;具体流程&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;设信箱&lt;/strong&gt;：创建 &lt;code&gt;DatagramSocket&lt;/code&gt; 对象，并&lt;strong&gt;明确指定端口&lt;/strong&gt;（必须和发送端指向的端口一致）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;准备空盘子&lt;/strong&gt;：创建一个字节数组，用来存放接收到的数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;造空包裹&lt;/strong&gt;：创建 &lt;code&gt;DatagramPacket&lt;/code&gt; 对象，作为接收数据的容器。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;等快递&lt;/strong&gt;：调用 &lt;code&gt;receive()&lt;/code&gt; 方法。&lt;strong&gt;注意：这个方法是阻塞的&lt;/strong&gt;，没收到货之前程序会一直停在这儿。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	DatagramSocket ds &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; DatagramSocket(10086); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; bytes &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1024&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	DatagramPacket dp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; DatagramPacket(bytes, bytes.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//receive是阻塞的&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ds.&lt;span style="color:#a6e22e"&gt;receive&lt;/span&gt;(dp); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; dp.&lt;span style="color:#a6e22e"&gt;getData&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; len &lt;span style="color:#f92672"&gt;=&lt;/span&gt; dp.&lt;span style="color:#a6e22e"&gt;getLength&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	InetAddress address &lt;span style="color:#f92672"&gt;=&lt;/span&gt; dp.&lt;span style="color:#a6e22e"&gt;getAddress&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; dp.&lt;span style="color:#a6e22e"&gt;getPort&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;接收到了来自&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; address &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; port &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;的数据:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; String(data, 0, len));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="udp的三种通信方式"&gt;UDP的三种通信方式
&lt;/h1&gt;&lt;h2 id="单播"&gt;单播
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;这是最常见的通信方式。发送端明确指定接收端的 &lt;strong&gt;IP 地址&lt;/strong&gt; 和 &lt;strong&gt;端口号&lt;/strong&gt;。只有目标主机能收到数据包。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;特点&lt;/strong&gt;：点对点，不会给其他不相关的机器造成负担。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Java 实现&lt;/strong&gt;：使用常规的 &lt;code&gt;InetAddress.getByName(&amp;quot;192.168.1.100&amp;quot;)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="广播"&gt;广播
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;发送端向局域网（LAN）内的&lt;strong&gt;所有&lt;/strong&gt;主机发送数据。无论对方想不想听，数据都会送到他们的门口。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;广播地址&lt;/strong&gt;：固定为 &lt;code&gt;255.255.255.255&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;特点&lt;/strong&gt;：范围限制在当前局域网内，路由器通常不会转发广播包（防止垃圾信息塞满互联网）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Java 实现&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 发送到广播地址&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	InetAddress address &lt;span style="color:#f92672"&gt;=&lt;/span&gt; InetAddress.&lt;span style="color:#a6e22e"&gt;getByName&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;255.255.255.255&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	DatagramPacket dp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; DatagramPacket(bytes, bytes.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;, address, 10086);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="组播"&gt;组播
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;组播是介于单播和广播之间的一种高效方式。发送端向一个特定的&lt;strong&gt;组播地址&lt;/strong&gt;发消息，只有“加入”了这个组的主机才能收到。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;组播地址范围&lt;/strong&gt;：D 类地址（&lt;code&gt;224.0.0.0&lt;/code&gt; ~ &lt;code&gt;239.255.255.255&lt;/code&gt;）。其中 &lt;code&gt;224.0.0.0&lt;/code&gt; ~ &lt;code&gt;224.0.0.255&lt;/code&gt; 为预留。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;特点&lt;/strong&gt;：比广播更节省资源，只有感兴趣的主机才会处理数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Java 实现（特殊类）&lt;/strong&gt;：接收端需要使用 &lt;code&gt;MulticastSocket&lt;/code&gt; 并调用 &lt;code&gt;joinGroup()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="tcp发送和接收数据"&gt;TCP发送和接收数据
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;客户端 (Socket)&lt;/strong&gt;：主动拨号的人（请求连接）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;服务端 (ServerSocket)&lt;/strong&gt;：接电话的人（等待连接）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//TCP发送数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 1. 创建客户端 Socket 对象，并连接服务端&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 这一步会自动完成“三次握手”&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Socket socket &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Socket(&lt;span style="color:#e6db74"&gt;&amp;#34;127.0.0.1&amp;#34;&lt;/span&gt;, 10086);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 2. 获取输出流，准备往服务器写数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	OutputStream os &lt;span style="color:#f92672"&gt;=&lt;/span&gt; socket.&lt;span style="color:#a6e22e"&gt;getOutputStream&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 3. 写出数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	os.&lt;span style="color:#a6e22e"&gt;write&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;你好，TCP服务端！我是客户端&amp;#34;&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getBytes&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 4. 释放资源&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	os.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	socket.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//TCP接收数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 1. 创建服务端的 ServerSocket，并指定端口&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ServerSocket ss &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ServerSocket(10086);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 2. 等待客户端连接（阻塞式）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 只有客户端拨通了，这行代码才会往下走，并返回一个 Socket 对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;服务端已启动，等待连接...&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Socket socket &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ss.&lt;span style="color:#a6e22e"&gt;accept&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 3. 获取输入流，读取客户端发来的数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	InputStream is &lt;span style="color:#f92672"&gt;=&lt;/span&gt; socket.&lt;span style="color:#a6e22e"&gt;getInputStream&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; bytes &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1024&lt;span style="color:#f92672"&gt;]&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; len &lt;span style="color:#f92672"&gt;=&lt;/span&gt; is.&lt;span style="color:#a6e22e"&gt;read&lt;/span&gt;(bytes); &lt;span style="color:#75715e"&gt;// 读取数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 4. 解析并打印&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String msg &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; String(bytes, 0, len);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;收到消息：&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; msg);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 5. 释放资源&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	socket.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ss.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="三次握手-three-way-handshake--建立连接"&gt;三次握手 (Three-way Handshake) —— 建立连接
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;核心目的&lt;/strong&gt;：确认双方的&lt;strong&gt;收、发能力&lt;/strong&gt;都是正常的，并同步序列号。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;第一次握手&lt;/strong&gt;：客户端发送一个 &lt;code&gt;SYN&lt;/code&gt; 包给服务端。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;潜台词&lt;/em&gt;：“喂，你能听到我说话吗？”（客户端：确认自己能发；服务端：确认自己能收，对方能发）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;第二次握手&lt;/strong&gt;：服务端收到后，回传一个 &lt;code&gt;SYN + ACK&lt;/code&gt; 包。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;潜台词&lt;/em&gt;：“我能听到！你能听到我说话吗？”（服务端：确认自己能发；客户端：确认自己能收，对方能发/收都正常）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;第三次握手&lt;/strong&gt;：客户端收到后，再回传一个 &lt;code&gt;ACK&lt;/code&gt; 包。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;潜台词&lt;/em&gt;：“我也能听到。那我们要开始传数据了。”（服务端：确认对方收/发都正常）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="四次挥手-four-way-wave--释放连接"&gt;四次挥手 (Four-way Wave) —— 释放连接
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;核心目的&lt;/strong&gt;：确保双方都发送完了数据，并优雅地关闭双向通道。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;第一次挥手&lt;/strong&gt;：客户端发一个 &lt;code&gt;FIN&lt;/code&gt; 包。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;潜台词&lt;/em&gt;：“我的数据传完了，我要挂了。”（此时客户端进入半关闭状态）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;第二次挥手&lt;/strong&gt;：服务端回一个 &lt;code&gt;ACK&lt;/code&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;潜台词&lt;/em&gt;：“我知道你要挂了，但我这儿还有点活没干完，你等会儿。”（此时服务端可能还在发最后的数据）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;第三次挥手&lt;/strong&gt;：服务端干完活了，发一个 &lt;code&gt;FIN&lt;/code&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;潜台词&lt;/em&gt;：“好了，我也干完了，挂吧。”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;第四次挥手&lt;/strong&gt;：客户端回一个 &lt;code&gt;ACK&lt;/code&gt;，并进入 &lt;code&gt;TIME_WAIT&lt;/code&gt; 状态。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;潜台词&lt;/em&gt;：“收到，拜拜！”（客户端会等一会儿确保服务端收到了这个 ACK，然后彻底消失）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="为什么握手是-3-次挥手要-4-次"&gt;为什么握手是 3 次，挥手要 4 次？
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;为什么不是 2 次？&lt;/strong&gt; * 防止“失效的连接请求”突然到达服务端。如果只有 2 次，服务端一回应就建立连接，但客户端其实已经走掉了，这会浪费服务端资源。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;为什么挥手多一次？&lt;/strong&gt; * &lt;strong&gt;核心原因：半关闭状态&lt;/strong&gt;。当客户端说“我不发了”时（第一次挥手），服务端可能还有数据没发完。服务端必须先回一个 ACK 告诉客户端“我收到你的请求了”，等自己发完最后的数据，再发 FIN（第三次挥手）。&lt;strong&gt;中间这两步不能合并&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>反射与动态代理</title><link>https://creat.asia/post/15-%E5%8F%8D%E5%B0%84%E4%B8%8E%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86/</link><pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/15-%E5%8F%8D%E5%B0%84%E4%B8%8E%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-03-26&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="反射"&gt;反射
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;原定义：允许对封装类的字段，方法，和构造函数的信息进行编程式访问&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;反射&lt;/strong&gt; 允许程序在&lt;strong&gt;运行状态&lt;/strong&gt;中，对于任意一个类，都能知道这个类的所有属性和方法；对于任意一个对象，都能调用它的任意方法和属性。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;正常方式&lt;/strong&gt;：引入包 $\rightarrow$ &lt;code&gt;new&lt;/code&gt; 对象 $\rightarrow$ 调用方法。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;反射方式&lt;/strong&gt;：获取 &lt;code&gt;Class&lt;/code&gt; 对象 $\rightarrow$ 解剖类内容 $\rightarrow$ 操作成员。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="获取-class-对象的三种方式"&gt;获取 Class 对象的三种方式
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;类名.class&lt;/strong&gt;（最安全，性能最高）：
&lt;code&gt;Class clazz = Student.class;&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一般当作参数进行传递&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;对象.getClass()&lt;/strong&gt;（已有对象时使用）：
&lt;code&gt;Student s = new Student(); Class clazz = s.getClass();&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Class.forName(&amp;ldquo;全类名&amp;rdquo;)&lt;/strong&gt;（&lt;strong&gt;最常用&lt;/strong&gt;，配置文件加载）：
&lt;code&gt;Class clazz = Class.forName(&amp;quot;com.mysql.cj.jdbc.Driver&amp;quot;);&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="核心api"&gt;核心API
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;操作目标&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;对应类&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;核心方法&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;构造方法&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Constructor&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;newInstance(参数)&lt;/code&gt; ：创建对象&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;成员变量&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Field&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;set(对象, 值)&lt;/code&gt; / &lt;code&gt;get(对象)&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;成员方法&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Method&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;invoke(对象, 参数)&lt;/code&gt; ：运行方法&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="反射获取构造方法"&gt;反射获取构造方法
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;方法名&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;备注&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getConstructors()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取所有 &lt;strong&gt;public&lt;/strong&gt; 构造&lt;/td&gt;
					&lt;td&gt;只能拿到公有的。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getDeclaredConstructors()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取 &lt;strong&gt;所有&lt;/strong&gt; 构造&lt;/td&gt;
					&lt;td&gt;包含私有、受保护的。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getConstructor(Class...)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取指定的 &lt;strong&gt;public&lt;/strong&gt; 构造&lt;/td&gt;
					&lt;td&gt;需传入参数类型的字节码。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getDeclaredConstructor(Class...)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取指定的构造&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;最常用&lt;/strong&gt;，可以获取私有构造。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="反射获取成员变量"&gt;反射获取成员变量
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;方法名&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;备注&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getFields()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取所有 &lt;strong&gt;public&lt;/strong&gt; 变量&lt;/td&gt;
					&lt;td&gt;包含从父类继承的公有变量。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getDeclaredFields()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取 &lt;strong&gt;所有&lt;/strong&gt; 变量&lt;/td&gt;
					&lt;td&gt;仅限本类定义的（含私有）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getField(String name)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取指定的 &lt;strong&gt;public&lt;/strong&gt; 变量&lt;/td&gt;
					&lt;td&gt;根据变量名获取。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getDeclaredField(String name)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取指定的变量&lt;/td&gt;
					&lt;td&gt;可以获取私有变量。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;当变量为private时，可以通过&lt;code&gt;setAccessible(true)&lt;/code&gt;设置为可访问&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Class clazz &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Class.&lt;span style="color:#a6e22e"&gt;forName&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;asia.creat.demo2.Student&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Field name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; clazz.&lt;span style="color:#a6e22e"&gt;getDeclaredField&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Student s &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Student(&lt;span style="color:#e6db74"&gt;&amp;#34;张三&amp;#34;&lt;/span&gt;,23,&lt;span style="color:#e6db74"&gt;&amp;#34;男&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	name.&lt;span style="color:#a6e22e"&gt;setAccessible&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Object value &lt;span style="color:#f92672"&gt;=&lt;/span&gt; name.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(s); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(value); 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="反射获取成员方法"&gt;反射获取成员方法
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;方法名&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;备注&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getMethods()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取所有 &lt;strong&gt;public&lt;/strong&gt; 方法&lt;/td&gt;
					&lt;td&gt;包含本类及父类继承的所有公有方法。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getDeclaredMethods()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取 &lt;strong&gt;所有&lt;/strong&gt; 方法&lt;/td&gt;
					&lt;td&gt;仅限本类定义的（含私有）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getMethod(String, Class...)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取指定的 &lt;strong&gt;public&lt;/strong&gt; 方法&lt;/td&gt;
					&lt;td&gt;需指定方法名和参数类型。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getDeclaredMethod(String, Class...)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取指定的方法&lt;/td&gt;
					&lt;td&gt;用于精确锁定本类某个方法。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="总结反射的三步"&gt;总结：反射的三步
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;获取 Class 对象&lt;/strong&gt;：&lt;code&gt;Class clazz = Class.forName(&amp;quot;全类名&amp;quot;);&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;获取成员对象&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;找构造：&lt;code&gt;getDeclaredConstructor()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;找属性：&lt;code&gt;getDeclaredField(&amp;quot;变量名&amp;quot;)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;找方法：&lt;code&gt;getDeclaredMethod(&amp;quot;方法名&amp;quot;, 参数.class)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;暴力拆解（针对 private）&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;执行 &lt;code&gt;setAccessible(true);&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;实际操作&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;构造 $\rightarrow$ &lt;code&gt;newInstance()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;属性 $\rightarrow$ &lt;code&gt;set() / get()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;方法 $\rightarrow$ &lt;code&gt;invoke()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="动态代理"&gt;动态代理
&lt;/h1&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;无侵入性&lt;/strong&gt;：不需要修改 &lt;code&gt;BigStar&lt;/code&gt; 的任何代码，就能给它增加功能。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;JDK 代理限制&lt;/strong&gt;：只能代理&lt;strong&gt;实现了接口&lt;/strong&gt;的类。如果一个类没接口，需要使用 &lt;strong&gt;CGLIB&lt;/strong&gt;（通过继承实现代理）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;应用场景&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;日志记录&lt;/strong&gt;：每个方法执行前打印参数，执行后打印耗时。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;权限校验&lt;/strong&gt;：执行方法前检查用户是否登录。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;事务管理&lt;/strong&gt;：Spring 在方法开始前开启事务，结束后提交或回滚。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 1. 定义接口（明星的功能清单）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Star&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String &lt;span style="color:#a6e22e"&gt;sing&lt;/span&gt;(String name);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dance&lt;/span&gt;(String name);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 2. 定义实现类（真正的明星：被代理对象）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;BigStar&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; Star {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String name;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;BigStar&lt;/span&gt;(String name) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; name;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; String &lt;span style="color:#a6e22e"&gt;sing&lt;/span&gt;(String name) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;正在唱歌: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; name);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;谢谢&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dance&lt;/span&gt;(String name) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;正在跳舞: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; name);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Getter &amp;amp; Setter ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; String &lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;() { &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; name; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;setName&lt;/span&gt;(String name) { &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; name; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 3. 创建代理工具类（经纪人生成器）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; java.lang.reflect.Proxy;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ProxyUtil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; Star &lt;span style="color:#a6e22e"&gt;creatProxy&lt;/span&gt;(BigStar bs) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/*
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * Proxy.newProxyInstance 参数说明：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 1. 类加载器：用于加载生成的代理类
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 2. 接口数组：告诉代理类要实现哪些方法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 3. 处理器(InvocationHandler)：定义代理对象要额外做的“杂事”
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Star s &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (Star) Proxy.&lt;span style="color:#a6e22e"&gt;newProxyInstance&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ProxyUtil.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getClassLoader&lt;/span&gt;(),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Class&lt;span style="color:#f92672"&gt;[]&lt;/span&gt;{Star.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;},
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (proxy, method, args) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 这里就是“增强”逻辑（插队干活）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#e6db74"&gt;&amp;#34;sing&amp;#34;&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;equals&lt;/span&gt;(method.&lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;())) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;【准备】准备话筒，收钱&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#e6db74"&gt;&amp;#34;dance&amp;#34;&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;equals&lt;/span&gt;(method.&lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;())) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;【准备】准备场地，收钱&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 核心步骤：通过反射调用被代理对象（明星）的真实方法&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; method.&lt;span style="color:#a6e22e"&gt;invoke&lt;/span&gt;(bs, args);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; s;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 4. 测试类（外部调用）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ReflectDemo&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 1. 创建真实的对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BigStar bs &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; BigStar(&lt;span style="color:#e6db74"&gt;&amp;#34;张三&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 2. 获取代理对象（请经纪人）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Star proxy &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ProxyUtil.&lt;span style="color:#a6e22e"&gt;creatProxy&lt;/span&gt;(bs);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 3. 通过代理对象调用方法&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String result &lt;span style="color:#f92672"&gt;=&lt;/span&gt; proxy.&lt;span style="color:#a6e22e"&gt;sing&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;《千里之外》&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;返回值: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; result);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;--------------------&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy.&lt;span style="color:#a6e22e"&gt;dance&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;太空步&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>PTA临时</title><link>https://creat.asia/post/pta%E4%B8%B4%E6%97%B6/</link><pubDate>Fri, 08 May 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/pta%E4%B8%B4%E6%97%B6/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-05-08&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="顺序查找数组作形参"&gt;顺序查找（数组作形参）
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;search&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; arr[],&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; n,&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; n; i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(arr[i] &lt;span style="color:#f92672"&gt;==&lt;/span&gt; x) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; i;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;设置循环变量 &lt;code&gt;i&lt;/code&gt;，从 &lt;code&gt;0&lt;/code&gt; 开始遍历数组。&lt;/li&gt;
&lt;li&gt;每遍历一个元素，与目标值 &lt;code&gt;x&lt;/code&gt; 进行比较。&lt;/li&gt;
&lt;li&gt;若相等，直接返回当前下标 &lt;code&gt;i&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;循环结束仍未找到，返回 &lt;code&gt;-1&lt;/code&gt; 表示查找失败。&lt;/li&gt;
&lt;li&gt;时间复杂度：O(n)。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="顺序查找顺序表作形参"&gt;顺序查找（顺序表作形参）
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;searchSq&lt;/span&gt;(SqList L,ElemType x){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; L.len; i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(L.data[i] &lt;span style="color:#f92672"&gt;==&lt;/span&gt; x) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; i;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;顺序查找的核心思路与数组版本完全相同。&lt;/li&gt;
&lt;li&gt;区别在于数组边界由 &lt;code&gt;SqList&lt;/code&gt; 结构体的 &lt;code&gt;L.len&lt;/code&gt; 控制。&lt;/li&gt;
&lt;li&gt;从 &lt;code&gt;0&lt;/code&gt; 到 &lt;code&gt;L.len-1&lt;/code&gt; 依次遍历 &lt;code&gt;L.data[]&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;找到则返回下标，未找到返回 &lt;code&gt;-1&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="有序表的插入数组作形参"&gt;有序表的插入（数组作形参）
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;insert&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; a[], &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;n, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;n &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (i &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; a[i] &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; x) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; a[i &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a[i];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; i&lt;span style="color:#f92672"&gt;--&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; a[i &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; x;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#f92672"&gt;*&lt;/span&gt;n)&lt;span style="color:#f92672"&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;初始化 &lt;code&gt;i = n - 1&lt;/code&gt;，指向当前数组的最后一个元素。&lt;/li&gt;
&lt;li&gt;从后向前寻找插入位置，只要 &lt;code&gt;a[i] &amp;gt; x&lt;/code&gt;，说明 &lt;code&gt;x&lt;/code&gt; 应插在这些元素之前。&lt;/li&gt;
&lt;li&gt;因此将 &lt;code&gt;a[i]&lt;/code&gt; 后移一位到 &lt;code&gt;a[i+1]&lt;/code&gt;，腾出空位。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;i&lt;/code&gt; 递减，继续向前比较。&lt;/li&gt;
&lt;li&gt;循环结束后，&lt;code&gt;i+1&lt;/code&gt; 就是 &lt;code&gt;x&lt;/code&gt; 应该插入的位置。&lt;/li&gt;
&lt;li&gt;将 &lt;code&gt;x&lt;/code&gt; 写入 &lt;code&gt;a[i+1]&lt;/code&gt;，数组长度 &lt;code&gt;n&lt;/code&gt; 加一。&lt;/li&gt;
&lt;li&gt;由于数组有序，插入后仍然保持有序。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="有序表的插入顺序表作形参"&gt;有序表的插入（顺序表作形参）
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ListInsertByOrder&lt;/span&gt;(SqList L, ElemType x){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; len &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;length;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(len &lt;span style="color:#f92672"&gt;==&lt;/span&gt; LISTSIZE){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;顺序表已满，无法进行插入操作！&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; len &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(i&lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;elem[i] &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; x){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;elem[i&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;elem[i];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; i&lt;span style="color:#f92672"&gt;--&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;elem[i&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; x;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;length&lt;span style="color:#f92672"&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&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;code&gt;len&lt;/code&gt;，从 &lt;code&gt;len-1&lt;/code&gt; 位置开始向前查找插入位置。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：将所有大于 &lt;code&gt;x&lt;/code&gt; 的元素依次后移，腾出插入位置。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤四&lt;/strong&gt;：循环结束后，在 &lt;code&gt;i+1&lt;/code&gt; 处写入 &lt;code&gt;x&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤五&lt;/strong&gt;：顺序表长度加一，插入完成。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="有序表的插入单链表作形参"&gt;有序表的插入（单链表作形参）
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;LinkList &lt;span style="color:#a6e22e"&gt;InsertList&lt;/span&gt;(LinkList L, EType X){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; LNode&lt;span style="color:#f92672"&gt;*&lt;/span&gt; x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (LNode&lt;span style="color:#f92672"&gt;*&lt;/span&gt;)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(LNode));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; x&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; X;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; LNode&lt;span style="color:#f92672"&gt;*&lt;/span&gt; pre &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (LinkList)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(LNode));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pre &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(pre&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; NULL &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pre&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;data &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; X){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pre &lt;span style="color:#f92672"&gt;=&lt;/span&gt; pre &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; x&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; pre&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pre &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; x;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; L;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：为新值 &lt;code&gt;X&lt;/code&gt; 创建一个新节点 &lt;code&gt;x&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：初始化前驱指针 &lt;code&gt;pre&lt;/code&gt; 指向链表头 &lt;code&gt;L&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：向后遍历链表，找到第一个大于 &lt;code&gt;X&lt;/code&gt; 的节点的前驱 &lt;code&gt;pre&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤四&lt;/strong&gt;：将新节点接入链表：&lt;code&gt;x-&amp;gt;next = pre-&amp;gt;next&lt;/code&gt;，&lt;code&gt;pre-&amp;gt;next = x&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;由于链表有序，插入后链表仍然有序。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="合并两个有序数组数组作形参"&gt;合并两个有序数组（数组作形参）
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;merge&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt; a, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; m, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt; b, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; n, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt; c){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,j &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, k &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(i&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;m &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; j&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;n){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(a[i] &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; b[j]){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; c[k&lt;span style="color:#f92672"&gt;++&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a[i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(a[i] &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; b[j]){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; c[k&lt;span style="color:#f92672"&gt;++&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; b[j&lt;span style="color:#f92672"&gt;++&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; c[k&lt;span style="color:#f92672"&gt;++&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a[i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; c[k&lt;span style="color:#f92672"&gt;++&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; b[j&lt;span style="color:#f92672"&gt;++&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(i&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;m) c[k&lt;span style="color:#f92672"&gt;++&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a[i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(j&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;n) c[k&lt;span style="color:#f92672"&gt;++&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; b[j&lt;span style="color:#f92672"&gt;++&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：设置三个指针——&lt;code&gt;i&lt;/code&gt; 指向数组 &lt;code&gt;a&lt;/code&gt;，&lt;code&gt;j&lt;/code&gt; 指向数组 &lt;code&gt;b&lt;/code&gt;，&lt;code&gt;k&lt;/code&gt; 指向结果数组 &lt;code&gt;c&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：双指针同时遍历两数组，每次将较小的元素放入 &lt;code&gt;c&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：若两元素相等（&lt;code&gt;==&lt;/code&gt;），则两个都放入 &lt;code&gt;c&lt;/code&gt;，允许重复值存在。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤四&lt;/strong&gt;：当其中一个数组遍历完成后，将另一个数组的剩余元素全部复制到 &lt;code&gt;c&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;此为经典的&lt;strong&gt;二路归并&lt;/strong&gt;算法，时间复杂度 O(m+n)。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="合并两个有序表顺序表作形参"&gt;合并两个有序表（顺序表作形参）
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SqList &lt;span style="color:#a6e22e"&gt;MergeList_Sq&lt;/span&gt;(SqList La, SqList Lb){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; SqList Lc &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;InitList&lt;/span&gt;(MAXSIZE);;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,j &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,k &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; iLen &lt;span style="color:#f92672"&gt;=&lt;/span&gt; La&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;length,jLen &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Lb&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;length;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(i&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;iLen &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; j&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;jLen){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(La&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;elem[i] &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; Lb&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;elem[j]){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Lc&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;elem[k&lt;span style="color:#f92672"&gt;++&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; La&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;elem[i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Lc&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;elem[k&lt;span style="color:#f92672"&gt;++&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Lb&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;elem[j&lt;span style="color:#f92672"&gt;++&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(i&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;iLen) Lc&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;elem[k&lt;span style="color:#f92672"&gt;++&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; La&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;elem[i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(j&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;jLen) Lc&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;elem[k&lt;span style="color:#f92672"&gt;++&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Lb&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;elem[j&lt;span style="color:#f92672"&gt;++&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Lc &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; length &lt;span style="color:#f92672"&gt;=&lt;/span&gt; iLen &lt;span style="color:#f92672"&gt;+&lt;/span&gt; jLen;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Lc;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：初始化一个新的顺序表 &lt;code&gt;Lc&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：用三个指针 &lt;code&gt;i、j、k&lt;/code&gt; 分别遍历 &lt;code&gt;La&lt;/code&gt;、&lt;code&gt;Lb&lt;/code&gt;、&lt;code&gt;Lc&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：比较两表中当前元素，较小的复制到 &lt;code&gt;Lc&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤四&lt;/strong&gt;：任一表遍历完后，将另一表的剩余元素全部接入 &lt;code&gt;Lc&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤五&lt;/strong&gt;：设置 &lt;code&gt;Lc&lt;/code&gt; 的长度为两表长度之和，返回 &lt;code&gt;Lc&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="线性表元素的区间删除"&gt;线性表元素的区间删除
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;List &lt;span style="color:#a6e22e"&gt;Delete&lt;/span&gt;( List L, ElementType minD, ElementType maxD ){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; j &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; i &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Last; i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ElementType ele &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Data[i];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ElementType jele &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Data[j];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(ele&lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt;minD &lt;span style="color:#f92672"&gt;||&lt;/span&gt; ele&lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt;maxD){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Data[j] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ele;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; j&lt;span style="color:#f92672"&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Last &lt;span style="color:#f92672"&gt;=&lt;/span&gt; j&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; L;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：设置双指针——&lt;code&gt;i&lt;/code&gt; 用于遍历整个顺序表，&lt;code&gt;j&lt;/code&gt; 用于标记保留下来的元素应放置的位置。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：遍历每个元素 &lt;code&gt;ele&lt;/code&gt;，判断是否在开区间 &lt;code&gt;(minD, maxD)&lt;/code&gt; 之内。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：若 &lt;code&gt;ele &amp;lt;= minD&lt;/code&gt; 或 &lt;code&gt;ele &amp;gt;= maxD&lt;/code&gt;（即不在区间内），则保留。将 &lt;code&gt;ele&lt;/code&gt; 写入 &lt;code&gt;L-&amp;gt;Data[j]&lt;/code&gt;，&lt;code&gt;j&lt;/code&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;code&gt;L-&amp;gt;Last = j-1&lt;/code&gt;，即新的最后元素下标。&lt;/li&gt;
&lt;li&gt;此为&lt;strong&gt;原地压缩&lt;/strong&gt;算法，空间复杂度 O(1)。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="单链表遍历"&gt;单链表遍历
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Traverse&lt;/span&gt;(LinkList L){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; L &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(L &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; NULL){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;%d &amp;#34;&lt;/span&gt;,L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;data);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; L &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：由于链表可能带头结点，先将 &lt;code&gt;L&lt;/code&gt; 跳过头结点，指向第一个数据节点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：进入循环，只要 &lt;code&gt;L != NULL&lt;/code&gt; 就继续遍历。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：打印当前节点的 &lt;code&gt;data&lt;/code&gt; 值。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤四&lt;/strong&gt;：将 &lt;code&gt;L&lt;/code&gt; 指向下一个节点，继续循环。&lt;/li&gt;
&lt;li&gt;循环终止条件为 &lt;code&gt;L == NULL&lt;/code&gt;（到达链表末尾）。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="链式表的按序号查找"&gt;链式表的按序号查找
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ElementType &lt;span style="color:#a6e22e"&gt;FindKth&lt;/span&gt;( List L, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; K ){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; K&lt;span style="color:#f92672"&gt;--&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; index &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(p &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; NULL){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(index &lt;span style="color:#f92672"&gt;==&lt;/span&gt; K){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Data;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; index&lt;span style="color:#f92672"&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：将目标序号 &lt;code&gt;K&lt;/code&gt; 减一，因为链表下标从 0 开始计数（序号1对应下标0）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：从链表头开始遍历，设置 &lt;code&gt;index = 0&lt;/code&gt; 记录当前下标。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：每经过一个节点，&lt;code&gt;index++&lt;/code&gt;，当 &lt;code&gt;index == K&lt;/code&gt; 时返回该节点数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤四&lt;/strong&gt;：若遍历完链表仍未找到，返回 &lt;code&gt;-1&lt;/code&gt; 表示错误。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="单链表的建立头插法-逆序建立"&gt;单链表的建立（头插法-逆序建立）
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; ListNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;createlist&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; ListNode&lt;span style="color:#f92672"&gt;*&lt;/span&gt; newNode &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; data;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;scanf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;%d&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;data) &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(data &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)&lt;span style="color:#66d9ef"&gt;break&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; ListNode&lt;span style="color:#f92672"&gt;*&lt;/span&gt; L &lt;span style="color:#f92672"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; ListNode&lt;span style="color:#f92672"&gt;*&lt;/span&gt;)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; ListNode));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; data;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; newNode;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; newNode &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; newNode;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：初始化 &lt;code&gt;newNode = NULL&lt;/code&gt;，作为当前链表的起始。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：循环读入整数，读到 &lt;code&gt;-1&lt;/code&gt; 时结束输入。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：每读入一个数，创建新节点 &lt;code&gt;L&lt;/code&gt;，将 &lt;code&gt;L-&amp;gt;data&lt;/code&gt; 设为读入的值。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤四&lt;/strong&gt;：将新节点插入到链表头部——&lt;code&gt;L-&amp;gt;next = newNode&lt;/code&gt;，&lt;code&gt;newNode = L&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤五&lt;/strong&gt;：先读入的数据位于链表尾部，后读入的位于链表头部，最终链表与输入顺序&lt;strong&gt;相反&lt;/strong&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="单链表的建立尾插法-顺序建立"&gt;单链表的建立（尾插法-顺序建立）
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;LinkList &lt;span style="color:#a6e22e"&gt;Create&lt;/span&gt; (){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; LinkList L &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (LinkList)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(LinkList));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; LinkList head &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; head&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; data;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;scanf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;%d&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;data) &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(data &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;break&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; LinkList newNode &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (LinkList)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(LinkList));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; newNode&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; data;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; newNode&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; newNode;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; L &lt;span style="color:#f92672"&gt;=&lt;/span&gt; newNode;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; head;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：创建头结点 &lt;code&gt;head&lt;/code&gt;（或第一个节点），用指针 &lt;code&gt;L&lt;/code&gt; 记录当前尾节点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：循环读入整数，读到 &lt;code&gt;-1&lt;/code&gt; 时结束。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：每读入一个数，创建新节点 &lt;code&gt;newNode&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤四&lt;/strong&gt;：将新节点接入链表尾部——&lt;code&gt;L-&amp;gt;next = newNode&lt;/code&gt;，然后 &lt;code&gt;L = newNode&lt;/code&gt; 更新尾指针。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤五&lt;/strong&gt;：先读入的数据位于链表头部，最终链表与输入顺序&lt;strong&gt;一致&lt;/strong&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="单链表的按值删除"&gt;单链表的按值删除
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;DelNode&lt;/span&gt;(LinkList head, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; deldata){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; flag &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; LinkList p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; head;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; NULL) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;data &lt;span style="color:#f92672"&gt;==&lt;/span&gt; deldata) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; flag &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; LinkList temp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; temp&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;free&lt;/span&gt;(temp);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; flag;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：设置指针 &lt;code&gt;p&lt;/code&gt; 指向待比较节点的前驱节点（初始为 &lt;code&gt;head&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：遍历链表，判断 &lt;code&gt;p-&amp;gt;next-&amp;gt;data&lt;/code&gt; 是否等于目标值 &lt;code&gt;deldata&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：若相等，说明找到了待删除节点。用临时指针 &lt;code&gt;temp&lt;/code&gt; 保存该节点，&lt;code&gt;p-&amp;gt;next = temp-&amp;gt;next&lt;/code&gt; 绕过它，然后 &lt;code&gt;free(temp)&lt;/code&gt; 释放内存。&lt;code&gt;p&lt;/code&gt; 不移动，继续检查。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤四&lt;/strong&gt;：若不相等，&lt;code&gt;p&lt;/code&gt; 后移到下一个节点，继续遍历。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤五&lt;/strong&gt;：找到并删除则 &lt;code&gt;flag = 1&lt;/code&gt;，返回删除结果。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="单链表的按值查找"&gt;单链表的按值查找
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;LinkList &lt;span style="color:#a6e22e"&gt;Locate_LinkList&lt;/span&gt;(LinkList L, datatype x){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(L &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; NULL &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;data &lt;span style="color:#f92672"&gt;!=&lt;/span&gt;x)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; L &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; L;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&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;code&gt;L-&amp;gt;data&lt;/code&gt; 与目标值 &lt;code&gt;x&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：若相等，返回该节点指针；若遍历完仍未找到，&lt;code&gt;L == NULL&lt;/code&gt;，返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="单链表的按位置查找"&gt;单链表的按位置查找
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;LinkList &lt;span style="color:#a6e22e"&gt;Findk&lt;/span&gt;(LinkList L, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; k) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (k &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; count &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; LinkList p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (p &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; NULL &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; count &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; k) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; count&lt;span style="color:#f92672"&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; p;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：先检查 &lt;code&gt;k &amp;lt;= 0&lt;/code&gt;，非法输入直接返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：从链表头部开始，设置计数器 &lt;code&gt;count = 0&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：向后移动指针 &lt;code&gt;k&lt;/code&gt; 次，每移动一次 &lt;code&gt;count++&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤四&lt;/strong&gt;：若移动过程中到达 &lt;code&gt;NULL&lt;/code&gt;（节点数不足 &lt;code&gt;k&lt;/code&gt;），返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤五&lt;/strong&gt;：若成功移动 &lt;code&gt;k&lt;/code&gt; 步，返回当前节点 &lt;code&gt;p&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="带头结点的链式表操作集"&gt;带头结点的链式表操作集
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;List &lt;span style="color:#a6e22e"&gt;MakeEmpty&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; LNode&lt;span style="color:#f92672"&gt;*&lt;/span&gt; head &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; LNode&lt;span style="color:#f92672"&gt;*&lt;/span&gt;)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; LNode));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; head&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Data&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; head&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next&lt;span style="color:#f92672"&gt;=&lt;/span&gt;NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; head;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Position &lt;span style="color:#a6e22e"&gt;Find&lt;/span&gt;(List L, ElementType X ){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; LNode&lt;span style="color:#f92672"&gt;*&lt;/span&gt; p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(p&lt;span style="color:#f92672"&gt;!=&lt;/span&gt;NULL){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Data &lt;span style="color:#f92672"&gt;==&lt;/span&gt; X){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; p;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p&lt;span style="color:#f92672"&gt;=&lt;/span&gt;p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; ERROR;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Insert&lt;/span&gt;( List L, ElementType X, Position P ){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; LNode&lt;span style="color:#f92672"&gt;*&lt;/span&gt; p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(p&lt;span style="color:#f92672"&gt;!=&lt;/span&gt;NULL &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; P){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p&lt;span style="color:#f92672"&gt;=&lt;/span&gt;p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(p &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Wrong Position for Insertion&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; false;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; LNode&lt;span style="color:#f92672"&gt;*&lt;/span&gt; temp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; LNode&lt;span style="color:#f92672"&gt;*&lt;/span&gt;)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; LNode));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; temp&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; X;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; temp&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; temp;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; true;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Delete&lt;/span&gt;( List L, Position P ){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; LNode&lt;span style="color:#f92672"&gt;*&lt;/span&gt; p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(p&lt;span style="color:#f92672"&gt;!=&lt;/span&gt;NULL &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; P){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p&lt;span style="color:#f92672"&gt;=&lt;/span&gt;p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(p&lt;span style="color:#f92672"&gt;==&lt;/span&gt;NULL){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Wrong Position for Deletion&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; false;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; P&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;free&lt;/span&gt;(P);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; true;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;MakeEmpty&lt;/strong&gt;：创建头结点，初始化数据为0，&lt;code&gt;Next&lt;/code&gt; 指向 &lt;code&gt;NULL&lt;/code&gt;，返回链表指针。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Find&lt;/strong&gt;：从头结点遍历，依次比较每个节点的 &lt;code&gt;Data&lt;/code&gt; 是否等于 &lt;code&gt;X&lt;/code&gt;，找到则返回该节点指针。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Insert&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;步骤一：先遍历找到 &lt;code&gt;P&lt;/code&gt; 的前驱节点 &lt;code&gt;p&lt;/code&gt;（条件 &lt;code&gt;p-&amp;gt;Next == P&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;步骤二：若未找到前驱（&lt;code&gt;p == NULL&lt;/code&gt;），说明 &lt;code&gt;P&lt;/code&gt; 不在链表中，报错并返回 &lt;code&gt;false&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;步骤三：创建新节点 &lt;code&gt;temp&lt;/code&gt;，将其插入到 &lt;code&gt;p&lt;/code&gt; 之后——&lt;code&gt;temp-&amp;gt;Next = p-&amp;gt;Next&lt;/code&gt;，&lt;code&gt;p-&amp;gt;Next = temp&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Delete&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;步骤一：同样先找到待删除节点 &lt;code&gt;P&lt;/code&gt; 的前驱 &lt;code&gt;p&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;步骤二：若未找到前驱，报错并返回 &lt;code&gt;false&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;步骤三：&lt;code&gt;p-&amp;gt;Next = P-&amp;gt;Next&lt;/code&gt; 绕过 &lt;code&gt;P&lt;/code&gt;，然后 &lt;code&gt;free(P)&lt;/code&gt; 释放内存。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="删除单链表偶数节点"&gt;删除单链表偶数节点
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; ListNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;createlist&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; ListNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;head &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL, &lt;span style="color:#f92672"&gt;*&lt;/span&gt;tail &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; data;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;scanf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;%d&amp;#34;&lt;/span&gt;, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;data) &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; data &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; ListNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;newNode &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; ListNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; ListNode));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; newNode&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; data;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; newNode&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (head &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; head &lt;span style="color:#f92672"&gt;=&lt;/span&gt; newNode;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tail &lt;span style="color:#f92672"&gt;=&lt;/span&gt; head;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tail&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; newNode;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tail &lt;span style="color:#f92672"&gt;=&lt;/span&gt; newNode;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; head;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; ListNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;deleteeven&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; ListNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;head) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 步骤一：处理头部连续的偶数节点
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (head &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; NULL &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; head&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;data &lt;span style="color:#f92672"&gt;%&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; ListNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;temp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; head;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; head &lt;span style="color:#f92672"&gt;=&lt;/span&gt; head&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;free&lt;/span&gt;(temp);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 步骤二：若链表已空，直接返回
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (head &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 步骤三：处理后续节点中的偶数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; ListNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; head;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; NULL) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;data &lt;span style="color:#f92672"&gt;%&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; ListNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;temp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; temp&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;free&lt;/span&gt;(temp);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; head;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;createlist&lt;/strong&gt;：尾插法建立链表，读到 &lt;code&gt;-1&lt;/code&gt; 结束，过程同前文&amp;quot;单链表的建立（尾插法）&amp;quot;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;deleteeven&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：处理头部连续出现的偶数节点——只要 &lt;code&gt;head&lt;/code&gt; 为偶数，就头指针后移并释放原头节点。此过程可能连续删除多个偶数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：若链表已删空（&lt;code&gt;head == NULL&lt;/code&gt;），直接返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：此时头节点必为奇数。用 &lt;code&gt;p&lt;/code&gt; 记录待检查节点的前驱，遍历剩余链表。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤四&lt;/strong&gt;：若 &lt;code&gt;p-&amp;gt;next&lt;/code&gt; 为偶数，则绕过它并释放；若为奇数，则 &lt;code&gt;p&lt;/code&gt; 后移继续检查。&lt;/li&gt;
&lt;li&gt;注意：删除偶数节点后 &lt;code&gt;p&lt;/code&gt; &lt;strong&gt;不移动&lt;/strong&gt;，因为新顶替上来的 &lt;code&gt;p-&amp;gt;next&lt;/code&gt; 还需要检查。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="两个有序链表序列的合并"&gt;两个有序链表序列的合并
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;List &lt;span style="color:#a6e22e"&gt;Merge&lt;/span&gt;(List L1,List L2){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List dummy &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (List)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; Node));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dummy&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List list1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List list2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List curr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; dummy;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(list1&lt;span style="color:#f92672"&gt;!=&lt;/span&gt;NULL &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; list2&lt;span style="color:#f92672"&gt;!=&lt;/span&gt;NULL){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(list1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Data &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; list2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Data){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; curr&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; list2;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; curr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; list2;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; list2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; list2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; curr&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; list1;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; curr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; list1;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; list1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; list1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; curr&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (list1 &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; NULL) &lt;span style="color:#f92672"&gt;?&lt;/span&gt; list1 : list2;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; L1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; L2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; dummy;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：创建一个虚拟头结点 &lt;code&gt;dummy&lt;/code&gt;，用它简化边界处理，&lt;code&gt;curr&lt;/code&gt; 指向结果链表当前尾节点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：跳过两链表的头结点，分别用 &lt;code&gt;list1&lt;/code&gt; 和 &lt;code&gt;list2&lt;/code&gt; 指向第一个数据节点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：同时遍历两链表，每次比较 &lt;code&gt;list1&lt;/code&gt; 和 &lt;code&gt;list2&lt;/code&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;code&gt;L1-&amp;gt;Next = NULL&lt;/code&gt;，&lt;code&gt;L2-&amp;gt;Next = NULL&lt;/code&gt;），返回 &lt;code&gt;dummy-&amp;gt;Next&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="递增的整数序列链表的插入"&gt;递增的整数序列链表的插入
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;List &lt;span style="color:#a6e22e"&gt;Insert&lt;/span&gt;( List L, ElementType X ){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; NULL &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Data &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; X) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List newNode &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (List)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; Node));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; newNode&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; X;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; newNode&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; newNode;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; L;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：链表带头结点，用 &lt;code&gt;p&lt;/code&gt; 从头结点开始向后遍历。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：循环条件 &lt;code&gt;p-&amp;gt;Next != NULL &amp;amp;&amp;amp; p-&amp;gt;Next-&amp;gt;Data &amp;lt; X&lt;/code&gt;，即向后移动直到 &lt;code&gt;p-&amp;gt;Next&lt;/code&gt; 是第一个 &lt;strong&gt;大于等于&lt;/strong&gt; &lt;code&gt;X&lt;/code&gt; 的节点的前驱。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：找到位置后，创建新节点 &lt;code&gt;newNode&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤四&lt;/strong&gt;：将新节点接入——&lt;code&gt;newNode-&amp;gt;Next = p-&amp;gt;Next&lt;/code&gt;，&lt;code&gt;p-&amp;gt;Next = newNode&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;由于链表有序，插入后仍保持递增。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="单链表逆转"&gt;单链表逆转
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;List &lt;span style="color:#a6e22e"&gt;Reverse&lt;/span&gt;( List L ){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (L &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL &lt;span style="color:#f92672"&gt;||&lt;/span&gt; L&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; L;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; Node&lt;span style="color:#f92672"&gt;*&lt;/span&gt; pre &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; Node&lt;span style="color:#f92672"&gt;*&lt;/span&gt; curr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; Node&lt;span style="color:#f92672"&gt;*&lt;/span&gt; next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(curr&lt;span style="color:#f92672"&gt;!=&lt;/span&gt;NULL){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; curr&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; curr&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; pre;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pre &lt;span style="color:#f92672"&gt;=&lt;/span&gt; curr;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; curr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; pre;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&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;code&gt;pre = NULL&lt;/code&gt;（最终成为新头），&lt;code&gt;curr = L&lt;/code&gt;（当前处理节点），&lt;code&gt;next&lt;/code&gt; 用于暂存 &lt;code&gt;curr-&amp;gt;next&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：进入循环，每次处理一个节点的指向反转：
&lt;ul&gt;
&lt;li&gt;保存 &lt;code&gt;next = curr-&amp;gt;Next&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;将 &lt;code&gt;curr-&amp;gt;Next&lt;/code&gt; 指向 &lt;code&gt;pre&lt;/code&gt;（完成反转）；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pre&lt;/code&gt; 后移到 &lt;code&gt;curr&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;curr&lt;/code&gt; 后移到 &lt;code&gt;next&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤四&lt;/strong&gt;：当 &lt;code&gt;curr == NULL&lt;/code&gt; 时循环结束，&lt;code&gt;pre&lt;/code&gt; 指向原链表最后一个节点，即新链表的头结点。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="单链表分段逆转"&gt;单链表分段逆转
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;K_Reverse&lt;/span&gt;( List list, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; k ){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (k &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; list &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL &lt;span style="color:#f92672"&gt;||&lt;/span&gt; list&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;length &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; k)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Position pre &lt;span style="color:#f92672"&gt;=&lt;/span&gt; list&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;head;&lt;span style="color:#75715e"&gt;//待转部分的前驱节点
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Position start &lt;span style="color:#f92672"&gt;=&lt;/span&gt; pre&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;&lt;span style="color:#75715e"&gt;//待转部分的第一个节点
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; rest &lt;span style="color:#f92672"&gt;=&lt;/span&gt; list&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;length;&lt;span style="color:#75715e"&gt;//剩余节点数量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(rest &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; k){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//正常反转链表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Position prev &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Position curr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; start;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Position next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;i&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;k;i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; curr&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; curr&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; prev;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; prev &lt;span style="color:#f92672"&gt;=&lt;/span&gt; curr;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; curr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//将上一段末尾 接 这一段的头prev
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pre&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; prev;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//将这一段末尾 接 下一段开头
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; start&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; curr;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//移动pre
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pre &lt;span style="color:#f92672"&gt;=&lt;/span&gt; start;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//移动start
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; start &lt;span style="color:#f92672"&gt;=&lt;/span&gt; curr;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; rest &lt;span style="color:#f92672"&gt;-=&lt;/span&gt;k;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：检查边界——&lt;code&gt;k &amp;lt;= 1&lt;/code&gt; 或节点数不足 &lt;code&gt;k&lt;/code&gt; 时直接返回。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：&lt;code&gt;pre&lt;/code&gt; 指向待反转段的前驱节点，&lt;code&gt;start&lt;/code&gt; 指向待反转段的第一个节点，&lt;code&gt;rest&lt;/code&gt; 记录剩余节点数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：进入大循环，只要剩余节点数 &lt;code&gt;&amp;gt;= k&lt;/code&gt;，就处理一段。
&lt;ul&gt;
&lt;li&gt;用三指针法反转 &lt;code&gt;k&lt;/code&gt; 个节点，得到新头 &lt;code&gt;prev&lt;/code&gt;，新尾 &lt;code&gt;curr&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pre-&amp;gt;next = prev&lt;/code&gt;：将上一段末尾接上反转后的新头。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;start-&amp;gt;next = curr&lt;/code&gt;：将反转段的新尾接上下一段的原始头。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pre = start&lt;/code&gt;：前驱指针后移到反转段的原末尾（现为下一段的前驱）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;start = curr&lt;/code&gt;：待反转段的起始指针后移。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rest -= k&lt;/code&gt;：剩余节点数减少 &lt;code&gt;k&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤四&lt;/strong&gt;：当剩余节点不足 &lt;code&gt;k&lt;/code&gt; 时退出，完成所有段的逆转。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="求链表的倒数第m个元素"&gt;求链表的倒数第m个元素
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ElementType &lt;span style="color:#a6e22e"&gt;Find&lt;/span&gt;( List L, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; m ){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(L &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; ERROR;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List fast &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List slow &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(m&lt;span style="color:#f92672"&gt;--&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; fast&lt;span style="color:#f92672"&gt;!=&lt;/span&gt;NULL) fast &lt;span style="color:#f92672"&gt;=&lt;/span&gt; fast&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(fast &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; ERROR;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(fast&lt;span style="color:#f92672"&gt;!=&lt;/span&gt;NULL){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fast &lt;span style="color:#f92672"&gt;=&lt;/span&gt; fast&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; slow &lt;span style="color:#f92672"&gt;=&lt;/span&gt; slow&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; slow&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Data;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&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;code&gt;fast&lt;/code&gt; 和 &lt;code&gt;slow&lt;/code&gt; 都指向链表头。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：&lt;code&gt;fast&lt;/code&gt; 先向前移动 &lt;code&gt;m&lt;/code&gt; 步。若移动过程中到达 &lt;code&gt;NULL&lt;/code&gt;，说明链表节点数不足 &lt;code&gt;m&lt;/code&gt;，返回错误。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤四&lt;/strong&gt;：&lt;code&gt;fast&lt;/code&gt; 和 &lt;code&gt;slow&lt;/code&gt; 同时向后移动，直到 &lt;code&gt;fast&lt;/code&gt; 到达链表末尾。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤五&lt;/strong&gt;：此时 &lt;code&gt;slow&lt;/code&gt; 正好指向倒数第 &lt;code&gt;m&lt;/code&gt; 个节点，返回其数据。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="学生成绩链表处理"&gt;学生成绩链表处理
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; stud_node &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;createlist&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; stud_node&lt;span style="color:#f92672"&gt;*&lt;/span&gt; head &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL,&lt;span style="color:#f92672"&gt;*&lt;/span&gt;tail &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; num,score;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; name[&lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;scanf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;%d&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;num);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(num &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;break&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;scanf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;%s&amp;#34;&lt;/span&gt;,name);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;scanf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;%d&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;score);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//创建学生节点
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; stud_node&lt;span style="color:#f92672"&gt;*&lt;/span&gt; stu &lt;span style="color:#f92672"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; stud_node&lt;span style="color:#f92672"&gt;*&lt;/span&gt;)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; stud_node));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; stu&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;num &lt;span style="color:#f92672"&gt;=&lt;/span&gt; num;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(i&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; name[i]&lt;span style="color:#f92672"&gt;!=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;\0&amp;#39;&lt;/span&gt;; i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; stu&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;name[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; name[i];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; stu&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;name[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;\0&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; stu&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;score &lt;span style="color:#f92672"&gt;=&lt;/span&gt; score;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//尾插法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (head &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; head &lt;span style="color:#f92672"&gt;=&lt;/span&gt; stu;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tail &lt;span style="color:#f92672"&gt;=&lt;/span&gt; stu;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tail&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; stu;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tail &lt;span style="color:#f92672"&gt;=&lt;/span&gt; stu;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; head;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; stud_node &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;deletelist&lt;/span&gt;( &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; stud_node &lt;span style="color:#f92672"&gt;*&lt;/span&gt;head, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; min_score ){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; stud_node &lt;span style="color:#f92672"&gt;*&lt;/span&gt;p, &lt;span style="color:#f92672"&gt;*&lt;/span&gt;temp;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (head &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; NULL &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; head&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;score &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; min_score) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; temp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; head;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; head &lt;span style="color:#f92672"&gt;=&lt;/span&gt; head&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;free&lt;/span&gt;(temp);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(head &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL)&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; head;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next&lt;span style="color:#f92672"&gt;!=&lt;/span&gt;NULL){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;score &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; min_score){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; temp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; temp&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;free&lt;/span&gt;(temp);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; head;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;createlist 部分：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：循环读入学号 &lt;code&gt;num&lt;/code&gt;，若 &lt;code&gt;num == 0&lt;/code&gt; 则结束输入。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：读入姓名 &lt;code&gt;name&lt;/code&gt; 和成绩 &lt;code&gt;score&lt;/code&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;code&gt;head&lt;/code&gt; 和 &lt;code&gt;tail&lt;/code&gt;，后续节点接在 &lt;code&gt;tail&lt;/code&gt; 后并更新 &lt;code&gt;tail&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤五&lt;/strong&gt;：返回链表头指针。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;deletelist 部分：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：处理头部连续的不及格节点——只要 &lt;code&gt;head-&amp;gt;score &amp;lt; min_score&lt;/code&gt;，就头指针后移并释放原头节点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：若链表已删空（&lt;code&gt;head == NULL&lt;/code&gt;），直接返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：此时头节点必符合要求。用 &lt;code&gt;p&lt;/code&gt; 从头开始向后遍历。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤四&lt;/strong&gt;：若 &lt;code&gt;p-&amp;gt;next-&amp;gt;score &amp;lt; min_score&lt;/code&gt;，绕过并释放该节点，&lt;code&gt;p&lt;/code&gt; 不移动（继续检查新顶替上来的节点）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤五&lt;/strong&gt;：若 &lt;code&gt;p-&amp;gt;next&lt;/code&gt; 符合要求，&lt;code&gt;p&lt;/code&gt; 后移继续检查。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤六&lt;/strong&gt;：返回处理后的链表头。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="前中后缀表达式"&gt;前/中/后缀表达式
&lt;/h1&gt;&lt;p&gt;只需更换printf的位置即可&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Prefix&lt;/span&gt;(BiTree T){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(T){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;%c &amp;#34;&lt;/span&gt;,T&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;data);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Prefix&lt;/span&gt;(T&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;lchild);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//printf(&amp;#34;%c &amp;#34;,T-&amp;gt;data);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Prefix&lt;/span&gt;(T&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;rchild);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//printf(&amp;#34;%c &amp;#34;,T-&amp;gt;data);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; ;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="求二叉树高度"&gt;求二叉树高度
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;GetHeight&lt;/span&gt;( BiTree BT ){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#f92672"&gt;!&lt;/span&gt;BT) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; l &lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;GetHeight&lt;/span&gt;(BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;lchild);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; r &lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;GetHeight&lt;/span&gt;(BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;rchild);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; (l&lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt;r&lt;span style="color:#f92672"&gt;?&lt;/span&gt;l:r)&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="统计二叉树叶子结点个数"&gt;统计二叉树叶子结点个数
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;LeafCount&lt;/span&gt; ( BiTree T){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#f92672"&gt;!&lt;/span&gt;T) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#f92672"&gt;!&lt;/span&gt;T&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;lchild &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;!&lt;/span&gt;T&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;rchild) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;LeafCount&lt;/span&gt;(T&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;lchild) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;LeafCount&lt;/span&gt;(T&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;rchild);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="先序遍历输出二叉树的叶结点"&gt;先序遍历输出二叉树的叶结点
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;PreorderPrintLeaves&lt;/span&gt;( BiTree BT ){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(BT &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;lchild &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;rchild &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34; %c&amp;#34;&lt;/span&gt;,BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;data);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; ;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;PreorderPrintLeaves&lt;/span&gt;(BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;lchild);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;PreorderPrintLeaves&lt;/span&gt;(BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;rchild);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="二叉树的节点数"&gt;二叉树的节点数
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;count_n&lt;/span&gt;(BinTree T){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(T &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;count_n&lt;/span&gt;(T&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Left) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;count_n&lt;/span&gt;(T&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Right) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="二叉树的建立"&gt;二叉树的建立
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BiTree &lt;span style="color:#a6e22e"&gt;CreatBiTree&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TElemType ch;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;scanf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;%c&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;ch);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(ch &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;#&amp;#39;&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BiTree node &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (BiTree)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(BiTNode));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; node&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ch;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; node&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;lchild &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CreatBiTree&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; node&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;rchild &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CreatBiTree&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; node;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="二叉树的层次遍历"&gt;二叉树的层次遍历
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Levelorder&lt;/span&gt;(BiTree T) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (T &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BiTree queue[&lt;span style="color:#ae81ff"&gt;1001&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; head&lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; rear &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; queue[rear&lt;span style="color:#f92672"&gt;++&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; T;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(head &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; rear){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BiTree p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; queue[head&lt;span style="color:#f92672"&gt;++&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34; %c&amp;#34;&lt;/span&gt;,p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;data);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;lchild &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; NULL){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; queue[rear&lt;span style="color:#f92672"&gt;++&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;lchild;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;rchild &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; NULL){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; queue[rear&lt;span style="color:#f92672"&gt;++&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; p&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;rchild;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="二叉树的非递归遍历"&gt;二叉树的非递归遍历
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;InorderTraversal&lt;/span&gt;( BinTree BT ) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Stack s &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CreateStack&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (BT &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;IsEmpty&lt;/span&gt;(s)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (BT) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Push&lt;/span&gt;(s, BT);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BT &lt;span style="color:#f92672"&gt;=&lt;/span&gt; BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Left;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BT &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Pop&lt;/span&gt;(s);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34; %c&amp;#34;&lt;/span&gt;, BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Data); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BT &lt;span style="color:#f92672"&gt;=&lt;/span&gt; BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Right;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;PreorderTraversal&lt;/span&gt;( BinTree BT ){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Stack s &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CreateStack&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (BT &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;IsEmpty&lt;/span&gt;(s)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (BT) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34; %c&amp;#34;&lt;/span&gt;, BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Data); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Push&lt;/span&gt;(s, BT);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BT &lt;span style="color:#f92672"&gt;=&lt;/span&gt; BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Left;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BT &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Pop&lt;/span&gt;(s);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BT &lt;span style="color:#f92672"&gt;=&lt;/span&gt; BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Right;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;PostorderTraversal&lt;/span&gt;( BinTree BT ){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Stack s &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CreateStack&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (BT &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;IsEmpty&lt;/span&gt;(s)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (BT) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;flag &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#75715e"&gt;//标记
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Push&lt;/span&gt;(s, BT);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BT &lt;span style="color:#f92672"&gt;=&lt;/span&gt; BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Left;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BT &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Peek&lt;/span&gt;(s);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;flag &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//第一次回到这个节点
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;flag &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; ;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BT &lt;span style="color:#f92672"&gt;=&lt;/span&gt; BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; Right;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//第二次回到节点
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Pop&lt;/span&gt;(s);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34; %c&amp;#34;&lt;/span&gt;,BT&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Data);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="哈夫曼树的构造"&gt;哈夫曼树的构造
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;HFTree &lt;span style="color:#a6e22e"&gt;MakeHFTree&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; data[], &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; weight[], &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; n){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(n &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Heap&lt;span style="color:#f92672"&gt;*&lt;/span&gt; heap &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;InitHeap&lt;/span&gt;(n);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; data[i] &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; HFTree node &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (HFTree)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(HTNode));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; node&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; data[i];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; node&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;weight &lt;span style="color:#f92672"&gt;=&lt;/span&gt; weight[i];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; node&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;lchild &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; node&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;rchild &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Insert&lt;/span&gt;(heap,node);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(heap&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;size &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; HFTree node1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;DelTop&lt;/span&gt;(heap);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; HFTree node2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;DelTop&lt;/span&gt;(heap);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; HFTree node &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (HFTree)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(HTNode));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; node&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;\0&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; node&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;weight &lt;span style="color:#f92672"&gt;=&lt;/span&gt; node1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;weight &lt;span style="color:#f92672"&gt;+&lt;/span&gt; node2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;weight;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; node&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;rchild &lt;span style="color:#f92672"&gt;=&lt;/span&gt; node1;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; node&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;lchild &lt;span style="color:#f92672"&gt;=&lt;/span&gt; node2;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Insert&lt;/span&gt;(heap,node);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; HFTree root &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;DelTop&lt;/span&gt;(heap);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; root;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="哈夫曼编码实现"&gt;哈夫曼编码实现
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dfs&lt;/span&gt;(HFTree node,&lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; path[],&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; depth,&lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; data[],&lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; codes[][&lt;span style="color:#ae81ff"&gt;1001&lt;/span&gt;]){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(node &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(node&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;lchild &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; node&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;rchild &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; path[depth] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;\0&amp;#39;&lt;/span&gt;;&lt;span style="color:#75715e"&gt;//结束
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(i&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; data[i]&lt;span style="color:#f92672"&gt;!=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;\0&amp;#39;&lt;/span&gt;;i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(data[i] &lt;span style="color:#f92672"&gt;==&lt;/span&gt; node&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;data){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;break&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;strcpy&lt;/span&gt;(codes[i],path);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; ;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; path[depth] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;0&amp;#39;&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;dfs&lt;/span&gt;(node&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;lchild,path,depth&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,data,codes);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; path[depth] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;1&amp;#39;&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;dfs&lt;/span&gt;(node&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;rchild,path,depth&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,data,codes);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Show_HFcoding&lt;/span&gt;(HFTree root, &lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; data[], &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; n){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; codes[&lt;span style="color:#ae81ff"&gt;1001&lt;/span&gt;][&lt;span style="color:#ae81ff"&gt;1001&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; path[&lt;span style="color:#ae81ff"&gt;1001&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dfs&lt;/span&gt;(root,path,&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,data,codes);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;i&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;n;i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;%c:%s&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;,data[i],codes[i]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="编程题"&gt;编程题
&lt;/h1&gt;&lt;h2 id="7-1-一元多项式的乘法与加法运算"&gt;7-1 一元多项式的乘法与加法运算
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;数组映射法&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;using namespace std;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; poly1[&lt;span style="color:#ae81ff"&gt;1001&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;}; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; ans_sum[&lt;span style="color:#ae81ff"&gt;1001&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; ans_mul[&lt;span style="color:#ae81ff"&gt;2001&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 打印多项式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;print_poly&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; arr[], &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; max_expon) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; first &lt;span style="color:#f92672"&gt;=&lt;/span&gt; true;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 从高次到低次输出
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; max_expon; i &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#f92672"&gt;--&lt;/span&gt;i) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (arr[i] &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;first) cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34; &amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; arr[i] &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; i;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; first &lt;span style="color:#f92672"&gt;=&lt;/span&gt; false;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 空多项式输出 0 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (first) cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;0 0&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; n1, n2, c, e;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 读取第一个多项式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cin &lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&lt;/span&gt; n1;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; a_c[&lt;span style="color:#ae81ff"&gt;1001&lt;/span&gt;], a_e[&lt;span style="color:#ae81ff"&gt;1001&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; n1; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;i) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cin &lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&lt;/span&gt; c &lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&lt;/span&gt; e;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; a_c[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; c;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; a_e[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; e;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ans_sum[e] &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; c;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 读取第二个多项式，同时计算加法与乘法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cin &lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&lt;/span&gt; n2;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; n2; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;i) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cin &lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&lt;/span&gt; c &lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&lt;/span&gt; e;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ans_sum[e] &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; c;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 乘法：逐项相乘累加
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; j &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; j &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; n1; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;j) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ans_mul[e &lt;span style="color:#f92672"&gt;+&lt;/span&gt; a_e[j]] &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; c &lt;span style="color:#f92672"&gt;*&lt;/span&gt; a_c[j];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 输出：先乘法 后加法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;print_poly&lt;/span&gt;(ans_mul, &lt;span style="color:#ae81ff"&gt;2000&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;print_poly&lt;/span&gt;(ans_sum, &lt;span style="color:#ae81ff"&gt;1000&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路（数组映射法）：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：创建三个整型数组——&lt;code&gt;poly1[]&lt;/code&gt; 存第一个多项式，&lt;code&gt;ans_sum[]&lt;/code&gt; 存加法结果，&lt;code&gt;ans_mul[]&lt;/code&gt; 存乘法结果。数组下标对应指数，下标处的值对应系数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：读入第一个多项式的 &lt;code&gt;n1&lt;/code&gt; 项，将每项系数累加到 &lt;code&gt;ans_sum[指数]&lt;/code&gt; 和 &lt;code&gt;poly1[指数]&lt;/code&gt; 中（&lt;code&gt;poly1&lt;/code&gt; 备份以便后续乘法使用）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：读入第二个多项式的 &lt;code&gt;n2&lt;/code&gt; 项，做两件事：
&lt;ul&gt;
&lt;li&gt;加法：直接累加到 &lt;code&gt;ans_sum[指数]&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;乘法：遍历第一个多项式的每一项，将 &lt;code&gt;c * a_c[j]&lt;/code&gt; 累加到 &lt;code&gt;ans_mul[e + a_e[j]]&lt;/code&gt;（指数相加，系数相乘）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤四&lt;/strong&gt;：按指数从高到低遍历数组，输出所有系数非零项（&lt;code&gt;ans_mul&lt;/code&gt; 先输出，&lt;code&gt;ans_sum&lt;/code&gt; 后输出）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤五&lt;/strong&gt;：若没有任何非零项，输出 &lt;code&gt;0 0&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;正常链表解决&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 定义多项式节点
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; PolyNode {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; coef; &lt;span style="color:#75715e"&gt;// 系数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; expon; &lt;span style="color:#75715e"&gt;// 指数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; PolyNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;typedef&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; PolyNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;Polynomial;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 辅助函数：将新项接到链表尾部
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Attach&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; c, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; e, Polynomial &lt;span style="color:#f92672"&gt;*&lt;/span&gt;pRear) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial P &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (Polynomial)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; PolyNode));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; P&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;coef &lt;span style="color:#f92672"&gt;=&lt;/span&gt; c;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; P&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;expon &lt;span style="color:#f92672"&gt;=&lt;/span&gt; e;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; P&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#f92672"&gt;*&lt;/span&gt;pRear)&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; P;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;pRear &lt;span style="color:#f92672"&gt;=&lt;/span&gt; P; &lt;span style="color:#75715e"&gt;// 更新尾指针
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 读入多项式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Polynomial &lt;span style="color:#a6e22e"&gt;ReadPoly&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; N, c, e;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;scanf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;%d&amp;#34;&lt;/span&gt;, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;N);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial head &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (Polynomial)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; PolyNode));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; head&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial rear &lt;span style="color:#f92672"&gt;=&lt;/span&gt; head;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (N&lt;span style="color:#f92672"&gt;--&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;scanf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;%d %d&amp;#34;&lt;/span&gt;, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;c, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;e);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Attach&lt;/span&gt;(c, e, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;rear);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; head;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 两个多项式相加
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Polynomial &lt;span style="color:#a6e22e"&gt;Add&lt;/span&gt;(Polynomial P1, Polynomial P2) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial t1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; P1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial t2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; P2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial head &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (Polynomial)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; PolyNode));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; head&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial rear &lt;span style="color:#f92672"&gt;=&lt;/span&gt; head;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (t1 &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; t2) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (t1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;expon &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; t2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;expon) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Attach&lt;/span&gt;(t1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;coef, t1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;expon, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;rear);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; t1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; t1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (t1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;expon &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; t2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;expon) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Attach&lt;/span&gt;(t2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;coef, t2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;expon, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;rear);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; t2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; t2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; sum &lt;span style="color:#f92672"&gt;=&lt;/span&gt; t1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;coef &lt;span style="color:#f92672"&gt;+&lt;/span&gt; t2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;coef;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (sum &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;Attach&lt;/span&gt;(sum, t1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;expon, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;rear);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; t1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; t1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; t2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; t2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (t1) { &lt;span style="color:#a6e22e"&gt;Attach&lt;/span&gt;(t1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;coef, t1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;expon, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;rear); t1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; t1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (t2) { &lt;span style="color:#a6e22e"&gt;Attach&lt;/span&gt;(t2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;coef, t2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;expon, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;rear); t2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; t2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; head;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 两个多项式相乘
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Polynomial &lt;span style="color:#a6e22e"&gt;Mult&lt;/span&gt;(Polynomial P1, Polynomial P2) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial t1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; P1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial t2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; P2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;t1 &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#f92672"&gt;!&lt;/span&gt;t2) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial head &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (Polynomial)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; PolyNode));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; head&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 用 P1 的每一项去乘 P2 的每一项
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (t1) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial tempHead &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (Polynomial)&lt;span style="color:#a6e22e"&gt;malloc&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; PolyNode));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tempHead&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial tempRear &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tempHead;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial p2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; t2;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (p2) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Attach&lt;/span&gt;(t1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;coef &lt;span style="color:#f92672"&gt;*&lt;/span&gt; p2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;coef, t1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;expon &lt;span style="color:#f92672"&gt;+&lt;/span&gt; p2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;expon, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;tempRear);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; p2&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 将乘出来的这一行加到总结果里
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial oldRes &lt;span style="color:#f92672"&gt;=&lt;/span&gt; head;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; head &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Add&lt;/span&gt;(head, tempHead);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 释放临时链表空间（此处略，考试时可不写，但在工程中很重要）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; t1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; t1&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; head;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 打印多项式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;PrintPoly&lt;/span&gt;(Polynomial P) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;P &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#f92672"&gt;!&lt;/span&gt;P&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;0 0&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial t &lt;span style="color:#f92672"&gt;=&lt;/span&gt; P&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; first &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (t) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;first) &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34; &amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;%d %d&amp;#34;&lt;/span&gt;, t&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;coef, t&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;expon);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; first &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; t &lt;span style="color:#f92672"&gt;=&lt;/span&gt; t&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial P1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ReadPoly&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial P2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ReadPoly&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial PP &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Mult&lt;/span&gt;(P1, P2);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;PrintPoly&lt;/span&gt;(PP);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Polynomial PS &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Add&lt;/span&gt;(P1, P2);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;PrintPoly&lt;/span&gt;(PS);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;思路（链表法）：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ReadPoly 部分：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：读取项数 &lt;code&gt;N&lt;/code&gt;，创建带头结点的空链表 &lt;code&gt;head&lt;/code&gt;，尾指针 &lt;code&gt;rear&lt;/code&gt; 初始指向 &lt;code&gt;head&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：循环读取 &lt;code&gt;N&lt;/code&gt; 次系数 &lt;code&gt;c&lt;/code&gt; 和指数 &lt;code&gt;e&lt;/code&gt;，调用 &lt;code&gt;Attach(c, e, &amp;amp;rear)&lt;/code&gt; 将新节点接到链表尾部。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：返回链表头指针 &lt;code&gt;head&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Add 部分：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：用 &lt;code&gt;t1&lt;/code&gt;、&lt;code&gt;t2&lt;/code&gt; 分别指向两链表的第一个数据节点（跳过头结点）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：同时遍历两链表，按指数大小分情况处理：
&lt;ul&gt;
&lt;li&gt;若 &lt;code&gt;t1-&amp;gt;expon &amp;gt; t2-&amp;gt;expon&lt;/code&gt;，将 &lt;code&gt;t1&lt;/code&gt; 接入结果链表，&lt;code&gt;t1&lt;/code&gt; 后移；&lt;/li&gt;
&lt;li&gt;若 &lt;code&gt;t1-&amp;gt;expon &amp;lt; t2-&amp;gt;expon&lt;/code&gt;，将 &lt;code&gt;t2&lt;/code&gt; 接入结果链表，&lt;code&gt;t2&lt;/code&gt; 后移；&lt;/li&gt;
&lt;li&gt;若指数相等，系数相加后若非零则接入，&lt;code&gt;t1&lt;/code&gt;、&lt;code&gt;t2&lt;/code&gt; 同时后移。&lt;/li&gt;
&lt;/ul&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;&lt;strong&gt;Mult 部分：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：处理边界情况——任一多项式为空则返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：用 &lt;code&gt;t1&lt;/code&gt; 遍历第一个多项式的每一项，对每一项：
&lt;ul&gt;
&lt;li&gt;步骤二.1：用 &lt;code&gt;t2&lt;/code&gt; 遍历第二个多项式的每一项，调用 &lt;code&gt;Attach&lt;/code&gt; 生成 &lt;code&gt;t1-&amp;gt;coef * t2-&amp;gt;coef&lt;/code&gt;、&lt;code&gt;t1-&amp;gt;expon + t2-&amp;gt;expon&lt;/code&gt; 的节点，构成临时结果链表 &lt;code&gt;tempHead&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;步骤二.2：将 &lt;code&gt;tempHead&lt;/code&gt; 与已有的 &lt;code&gt;head&lt;/code&gt; 通过 &lt;code&gt;Add&lt;/code&gt; 函数合并，更新 &lt;code&gt;head&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：&lt;code&gt;t1&lt;/code&gt; 后移，重复以上过程直到 &lt;code&gt;P1&lt;/code&gt; 所有项遍历完毕。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;PrintPoly 部分：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;步骤一&lt;/strong&gt;：检查链表是否为空或只有头结点，若是则输出 &lt;code&gt;0 0&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤二&lt;/strong&gt;：从第一个数据节点开始遍历，用 &lt;code&gt;first&lt;/code&gt; 标记控制空格输出格式，逐个打印系数和指数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步骤三&lt;/strong&gt;：遍历完毕换行。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="7-2-银行业务队列简单模拟"&gt;7-2 银行业务队列简单模拟
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C" data-lang="C"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;bits/stdc++.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;using namespace std;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; n;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cin &lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&lt;/span&gt; n;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; queue&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;a,b;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;i&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;n;i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cin &lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&lt;/span&gt; x;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(x&lt;span style="color:#f92672"&gt;%&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;) a.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;(x);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; b.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;(x);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(n &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; x ;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a.&lt;span style="color:#a6e22e"&gt;front&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; x;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		a.&lt;span style="color:#a6e22e"&gt;pop&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a.&lt;span style="color:#a6e22e"&gt;front&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; x;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		a.&lt;span style="color:#a6e22e"&gt;pop&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(&lt;span style="color:#f92672"&gt;!&lt;/span&gt;a.&lt;span style="color:#a6e22e"&gt;empty&lt;/span&gt;() &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#f92672"&gt;!&lt;/span&gt;b.&lt;span style="color:#a6e22e"&gt;empty&lt;/span&gt;()){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//B
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; b.&lt;span style="color:#a6e22e"&gt;front&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; x; b.&lt;span style="color:#a6e22e"&gt;pop&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//A
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a.&lt;span style="color:#a6e22e"&gt;front&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; x; a.&lt;span style="color:#a6e22e"&gt;pop&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#f92672"&gt;!&lt;/span&gt;a.&lt;span style="color:#a6e22e"&gt;empty&lt;/span&gt;()){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a.&lt;span style="color:#a6e22e"&gt;front&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; x; a.&lt;span style="color:#a6e22e"&gt;pop&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;a.&lt;span style="color:#a6e22e"&gt;empty&lt;/span&gt;()) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a.&lt;span style="color:#a6e22e"&gt;front&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; x;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			a.&lt;span style="color:#a6e22e"&gt;pop&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;b.&lt;span style="color:#a6e22e"&gt;empty&lt;/span&gt;()) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; b.&lt;span style="color:#a6e22e"&gt;front&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; x;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			b.&lt;span style="color:#a6e22e"&gt;pop&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;</description></item><item><title>web后端实战</title><link>https://creat.asia/post/web%E5%90%8E%E7%AB%AF%E5%AE%9E%E6%88%98/</link><pubDate>Thu, 16 Apr 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/web%E5%90%8E%E7%AB%AF%E5%AE%9E%E6%88%98/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-16&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="restful"&gt;Restful
&lt;/h1&gt;&lt;p&gt;REST(REpresentational state Transfer)，表述性状态转换，它是一种软件架构风格。
❗它并不是一种标准或协议，而是一组设计原则，旨在让网络服务更加简洁、高效且易于扩展。&lt;/p&gt;
&lt;h2 id="具体请求url"&gt;具体请求url
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;动作&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;完整的 URL 示例&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;语义&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;查询全部&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;GET localhost:8080/books&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;查列表&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;查询单个&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;GET localhost:8080/books/{id}&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;查详情&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;新增&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;POST localhost:8080/books&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;存入新数据&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;更新&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;PUT localhost:8080/books/{id}&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;覆盖旧数据&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;删除&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;DELETE localhost:8080/books/{id}&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;移除数据&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="对应的注解"&gt;对应的注解
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;注解&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;对应的 HTTP 方法&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;REST 语义&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;典型应用场景&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;@GetMapping&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;GET&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;查&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取列表、查看详情、条件搜索。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;@PostMapping&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;POST&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;增&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;提交表单、上传文件、新增部门/员工。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;@PutMapping&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;PUT&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;改（整）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;修改整个对象的信息（如修改员工的所有资料）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;@PatchMapping&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;PATCH&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;改（部）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;修改部分信息（如只修改状态、只重置密码）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;@DeleteMapping&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;DELETE&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;删&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;删除单个或批量删除资源。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;特性&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;POST&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;PUT&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;语义&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;创建 (Create)&lt;/strong&gt;：用于创建子资源。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;更新/替换 (Update/Replace)&lt;/strong&gt;：用于更新或替换指定资源。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;资源标识&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;资源 ID 通常由&lt;strong&gt;服务器&lt;/strong&gt;生成。&lt;/td&gt;
					&lt;td&gt;资源 ID 通常由&lt;strong&gt;客户端&lt;/strong&gt;指定。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;对应 SQL&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;类似于 &lt;code&gt;INSERT&lt;/code&gt;。&lt;/td&gt;
					&lt;td&gt;类似于 &lt;code&gt;UPDATE&lt;/code&gt; (全量) 或 &lt;code&gt;REPLACE INTO&lt;/code&gt;。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;幂等性&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;不幂等&lt;/strong&gt;。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;幂等&lt;/strong&gt;。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@GetMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/depts&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//指定请求方式 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;list&lt;/span&gt;(){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;查询全部部门数据&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Dept&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; deptList &lt;span style="color:#f92672"&gt;=&lt;/span&gt; deptService.&lt;span style="color:#a6e22e"&gt;findAll&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(deptList); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="优点"&gt;优点
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;轻量级:&lt;/strong&gt; 相比早期的 SOAP 协议，REST 传输的数据量更小。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;易于理解:&lt;/strong&gt; 直接利用 HTTP 语义，开发者上手极快。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;高兼容性:&lt;/strong&gt; 只要支持 HTTP 协议的平台（浏览器、移动端、IoT）都能轻松调用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;利于缓存:&lt;/strong&gt; 良好的 RESTful 设计可以充分利用 HTTP 缓存机制，提升性能。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="数据封装"&gt;数据封装
&lt;/h1&gt;&lt;p&gt;在 MyBatis 中，如果&lt;strong&gt;实体类属性名&lt;/strong&gt;（比如 &lt;code&gt;deptName&lt;/code&gt;）和&lt;strong&gt;数据库字段名&lt;/strong&gt;（比如 &lt;code&gt;name&lt;/code&gt;）对不上，MyBatis 找不到对应关系，封装出来的结果就会是 &lt;code&gt;null&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="手动结果映射results-result"&gt;手动结果映射&lt;code&gt;@Results @Result&lt;/code&gt;
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Mapper&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;DeptMapper&lt;/span&gt;{ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Results&lt;/span&gt;({ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Result&lt;/span&gt;(column &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;create_time&amp;#34;&lt;/span&gt;, property &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;createTime&amp;#34;&lt;/span&gt;), 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Result&lt;/span&gt;(column &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;update_time&amp;#34;&lt;/span&gt;, property &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;updateTime&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Select&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;SELECT id, name, create_time, update_time FROM dept ORDER BY update_time DESC&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Dept&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;findAll&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="起别名"&gt;起别名
&lt;/h3&gt;&lt;p&gt;在写 SQL 语句时，利用 SQL 的 &lt;code&gt;AS&lt;/code&gt; 关键字，手动将数据库字段名改成和实体类属性名一致。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优点：&lt;/strong&gt; 简单直接。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;缺点：&lt;/strong&gt; 如果字段很多，SQL 语句会变得非常臃肿，且每个查询都要写一遍。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Mysql" data-lang="Mysql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 id, name, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 dept_name &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; deptName, &lt;span style="color:#75715e"&gt;-- 数据库是 dept_name，实体类是 deptName
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 create_time &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; createTime 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; dept;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="开启驼峰命名自动转换-最推荐"&gt;开启驼峰命名自动转换 (最推荐)
&lt;/h3&gt;&lt;p&gt;这是目前最常用的方案。大部分开发规范中，数据库字段用下划线（&lt;code&gt;dept_name&lt;/code&gt;），Java 属性用小驼峰（&lt;code&gt;deptName&lt;/code&gt;）。&lt;/p&gt;
&lt;p&gt;只需要在 Spring Boot 的配置文件 &lt;code&gt;application.yml&lt;/code&gt;（或 &lt;code&gt;properties&lt;/code&gt;）中开启一个开关，MyBatis 就会自动帮你转换。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;配置文件设置：&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-YAML" data-lang="YAML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;mybatis&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;configuration&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 开启驼峰命名自动映射：a_column -&amp;gt; aColumn&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;map-underscore-to-camel-case&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;效果：&lt;/strong&gt; 开启后，&lt;code&gt;dept_name&lt;/code&gt; 会自动映射到 &lt;code&gt;deptName&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="使用-resultmap-最强大最灵活"&gt;使用 ResultMap (最强大、最灵活)
&lt;/h3&gt;&lt;p&gt;如果命名完全不规则（比如数据库叫 &lt;code&gt;d_n&lt;/code&gt;，实体类叫 &lt;code&gt;deptName&lt;/code&gt;），或者需要处理复杂的关联查询，就需要手动定义映射规则。&lt;/p&gt;
&lt;p&gt;在 Mapper 的 XML 文件中定义 &lt;code&gt;&amp;lt;resultMap&amp;gt;&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;resultMap&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;DeptResultMap&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;com.example.pojo.Dept&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#f92672"&gt;&amp;lt;id&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;deptName&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;c_time&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;createTime&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;/resultMap&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;select&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;findAll&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;resultMap=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;DeptResultMap&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 SELECT id, name, c_time FROM dept
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;ResultMap (Join)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;分开查询 (Service组装)&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;开发效率&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;高 (MyBatis 自动化)&lt;/td&gt;
					&lt;td&gt;中 (需要写 Java 逻辑)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;SQL 复杂度&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;高 (涉及多表关联)&lt;/td&gt;
					&lt;td&gt;低 (全是单表操作)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;传输压力&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;较大 (存在冗余字段)&lt;/td&gt;
					&lt;td&gt;小 (按需取数据)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;缓存灵活性&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;差&lt;/td&gt;
					&lt;td&gt;好&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!--自定义结果集--&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;resultMap&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;empResultMap&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;asia.creat.pojo.Emp&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;id&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;username&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;username&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;gender&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;gender&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;phone&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;phone&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;job&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;job&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;salary&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;salary&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;image&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;image&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;entry_date&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;entryDate&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;dept_id&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;deptId&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;create_time&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;createTime&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;update_time&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;updateTime&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;!--封装exprList--&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;collection&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;exprList&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ofType=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;asia.creat.pojo.EmpExpr&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;id&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ee_Id&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ee_company&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;company&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ee_job&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;job&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ee_begin&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;begin&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ee_end&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;end&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ee_emp_id&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;empId&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/collection&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/resultMap&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="nginx"&gt;Nginx
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-nginx" data-lang="nginx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;server{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#e6db74"&gt;listen&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;90&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;# 省略......
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;# ......
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;location&lt;/span&gt; &lt;span style="color:#e6db74"&gt;^~&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/api/&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;# 只要URL 是以 /api/ 开头的请求
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#f92672"&gt;rewrite&lt;/span&gt; &lt;span style="color:#e6db74"&gt;^~/api/(.*)&lt;/span&gt;$ &lt;span style="color:#e6db74"&gt;/&lt;/span&gt;$1 &lt;span style="color:#e6db74"&gt;break&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#f92672"&gt;proxy_pass&lt;/span&gt; &lt;span style="color:#e6db74"&gt;http://localhost:8080&lt;/span&gt;; &lt;span style="color:#75715e"&gt;# 代理转发
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="各种注解"&gt;各种注解
&lt;/h1&gt;&lt;h2 id="httpservletrequest"&gt;HttpServletRequest
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;	* 基于HttpServetRequest接收前端请求参数，删除部门数据 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;	* */&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@DeleteMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/depts&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;deleteById&lt;/span&gt;(HttpServletRequest request){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String idStr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; request.&lt;span style="color:#a6e22e"&gt;getParameter&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Integer.&lt;span style="color:#a6e22e"&gt;parseInt&lt;/span&gt;(idStr); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;根据ID删除部门:&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;id); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="requestparam"&gt;@RequestParam
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@DeleteMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/depts&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;deleteById&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;@RequestParam&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;) Integer deptId){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;根据ID删除部门:&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;deptId); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@DeleteMapping(&amp;quot;/depts&amp;quot;)&lt;/code&gt;&lt;/strong&gt;: 指定该方法处理发送到 &lt;code&gt;/depts&lt;/code&gt; 路径的 &lt;strong&gt;DELETE&lt;/strong&gt; 类型请求。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@RequestParam(&amp;quot;id&amp;quot;)&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;❗明确映射&lt;/strong&gt;：&lt;strong&gt;强制要求&lt;/strong&gt;前端必须传递一个名为 &lt;code&gt;id&lt;/code&gt; 的参数，否则报错&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;默认Request 为 true，设为false 则不传递不会报错&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自动转换&lt;/strong&gt;：Spring 会自动将前端传来的字符串（如 &lt;code&gt;&amp;quot;1&amp;quot;&lt;/code&gt;）转换为 Java 的 &lt;code&gt;Integer&lt;/code&gt; 类型。如果前端传了非数字字符，Spring 会直接抛出 &lt;code&gt;400 Bad Request&lt;/code&gt; 错误，无需你手动编写 &lt;code&gt;Integer.parseInt&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Integer deptId&lt;/code&gt;&lt;/strong&gt;: 这里的变量名可以叫 &lt;code&gt;deptId&lt;/code&gt;，因为在注解中明确指定了匹配前端的 &lt;code&gt;id&lt;/code&gt; 字段&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="省略requestparam"&gt;省略@RequestParam
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;如果请求参数名与形参变量名相同，直接定义方法形参即可接收&lt;/strong&gt;
但是此时的形参只能为&lt;strong&gt;前端请求参数名&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@DeleteMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/depts&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;deleteById&lt;/span&gt;(Integer id){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;根据ID删除部门:&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;id); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="指定默认值"&gt;指定默认值
&lt;/h3&gt;&lt;p&gt;使用defaultValue设置默认值&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;	* 分页查询 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;	* */&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@GetMapping&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;page&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;@RequestParam&lt;/span&gt;(defaultValue &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;) Integer page, Integer pageSize){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 log.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;分页查询{},{}&amp;#34;&lt;/span&gt;,page,pageSize); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 PageResult&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Emp&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; pageResult &lt;span style="color:#f92672"&gt;=&lt;/span&gt; empService.&lt;span style="color:#a6e22e"&gt;page&lt;/span&gt;(page, pageSize); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(pageResult); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="requestbody"&gt;@RequestBody
&lt;/h2&gt;&lt;p&gt;当请求进入后端时，&lt;code&gt;@RequestBody&lt;/code&gt; 会告诉 Spring：“不要去 URL 路径或查询参数里找数据，去请求体（HTTP Body）里找。把那段 JSON 字符串拿出来，转换成我定义的这个 Java 对象。”&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Controller:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@PostMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/depts&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;@RequestBody&lt;/span&gt; Dept dept){ &lt;span style="color:#75715e"&gt;//将json数据封装到对象 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;新增部门&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;dept); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 deptService.&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(dept);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Service:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(Dept dept) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 dept.&lt;span style="color:#a6e22e"&gt;setCreateTime&lt;/span&gt;(LocalDateTime.&lt;span style="color:#a6e22e"&gt;now&lt;/span&gt;()); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 dept.&lt;span style="color:#a6e22e"&gt;setUpdateTime&lt;/span&gt;(LocalDateTime.&lt;span style="color:#a6e22e"&gt;now&lt;/span&gt;()); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 deptMapper.&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(dept); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mapper:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Insert&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;INSERT INTO dept (name,create_time,update_time)VALUES (#{name},#{creatTime},#{updateTime})&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#960050;background-color:#1e0010"&gt;❗❗❗&lt;/span&gt;注意&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;VALUES后用的是属性名(驼峰命名)而不是字段名(下划线)&lt;span style="color:#960050;background-color:#1e0010"&gt;❗❗❗&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(Dept dept);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="使用前提"&gt;使用前提
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;请求方式&lt;/strong&gt;：通常用于 &lt;code&gt;POST&lt;/code&gt;、&lt;code&gt;PUT&lt;/code&gt; 或 &lt;code&gt;PATCH&lt;/code&gt;。&lt;code&gt;GET&lt;/code&gt; 请求没有请求体，所以不能使用&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Content-Type&lt;/strong&gt;：前端发送请求时，Header 中必须包含 &lt;code&gt;Content-Type: application/json&lt;/code&gt;。否则后端会报 &lt;code&gt;415 Unsupported Media Type&lt;/code&gt; 错误&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;属性匹配&lt;/strong&gt;：JSON 中的键名（Key）必须与 Java 实体类中的属性名完全一致，且实体类必须提供 &lt;strong&gt;Setter 方法&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="pathvariable"&gt;@PathVariable
&lt;/h2&gt;&lt;p&gt;REST 风格提倡“URL 代表资源”。例如，你想访问 ID 为 5 的部门，URL 应该是 &lt;code&gt;.../depts/5&lt;/code&gt;，而不是传统的 &lt;code&gt;.../depts?id=5&lt;/code&gt;。这里的 &lt;code&gt;5&lt;/code&gt; 就是一个路径变量
要让 &lt;code&gt;@PathVariable&lt;/code&gt; 生效，需要两个步骤的配合：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;在路径中使用占位符&lt;/strong&gt;：用 &lt;code&gt;{变量名}&lt;/code&gt; 标注。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;在参数前加注解&lt;/strong&gt;：将占位符的值映射到 Java 变量。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@GetMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/depts/{id}&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;getInfo&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;@PathVariable&lt;/span&gt; Integer id){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#960050;background-color:#1e0010"&gt;❗❗❗&lt;/span&gt; 如果占位符名称 {id} 和方法参数名 id 一致&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;可以直接映射&lt;span style="color:#960050;background-color:#1e0010"&gt;❗❗❗&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;根据ID查询部门：&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt; id); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
在URL中可以携带多个路径参数 如 &amp;ldquo;/depts/1/0&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="datetimeformat"&gt;@DateTimeFormat
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;@DateTimeFormat&lt;/code&gt; 是一个非常实用的注解，主要用于 &lt;strong&gt;格式化请求参数&lt;/strong&gt;（也就是从前端传到后端的日期字符串）&lt;/p&gt;
&lt;h3 id="在实体类中使用处理搜索条件"&gt;在实体类中使用（处理搜索条件）
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Data&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;EmpQueryDTO&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String name;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 接收类似 &amp;#34;2024-01-01&amp;#34; 的字符串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@DateTimeFormat&lt;/span&gt;(pattern &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;yyyy-MM-dd&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; LocalDate beginDate;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@DateTimeFormat&lt;/span&gt;(pattern &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;yyyy-MM-dd&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; LocalDate endDate;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="直接在-controller-参数中使用"&gt;直接在 Controller 参数中使用
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@GetMapping&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;pageByCondition&lt;/span&gt;(String name, Integer gender, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#a6e22e"&gt;@DateTimeFormat&lt;/span&gt;(pattern &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;yyyy-MM-dd&amp;#34;&lt;/span&gt;) LocalDate begin, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#a6e22e"&gt;@DateTimeFormat&lt;/span&gt;(pattern &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;yyyy-MM-dd&amp;#34;&lt;/span&gt;) LocalDate end, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(result); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
如果是普通 GET 请求的参数，用 &lt;code&gt;@DateTimeFormat&lt;/code&gt;；如果是 &lt;code&gt;@RequestBody&lt;/code&gt; 接收的 JSON 数据，用 &lt;code&gt;@JsonFormat&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="options"&gt;@Options
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;@Options&lt;/code&gt; 注解主要用于在使用 &lt;strong&gt;注解开发&lt;/strong&gt;（即直接在 Mapper 接口方法上写 &lt;code&gt;@Insert&lt;/code&gt; 或 &lt;code&gt;@Update&lt;/code&gt;）时，配置一些额外的开关和属性。最常见的用法是 &lt;strong&gt;获取自增主键&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Options&lt;/span&gt;(useGeneratedKeys &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,keyProperty &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//获取到生成的主键 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Insert&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;...插入语句...&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;insertEmp&lt;/span&gt;(Emp emp);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;useGeneratedKeys = true&lt;/code&gt;&lt;/strong&gt;：告诉 MyBatis 使用数据库生成的自增主键&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;keyProperty = &amp;quot;id&amp;quot;&lt;/code&gt;&lt;/strong&gt;：告诉 MyBatis 把拿到的主键值，设置到 &lt;code&gt;emp&lt;/code&gt; 对象的哪个属性中
执行后的效果：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	empService.&lt;span style="color:#a6e22e"&gt;insertEmp&lt;/span&gt;(emp); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(emp.&lt;span style="color:#a6e22e"&gt;getId&lt;/span&gt;()); &lt;span style="color:#75715e"&gt;// 这里就能打印出数据库生成的那个新 ID 了&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;除了获取主键，&lt;code&gt;@Options&lt;/code&gt; 还可以配置以下内容：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;属性&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;timeout&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;设置这条 SQL 执行的超时时间（单位：秒）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;flushCache&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;设置为 &lt;code&gt;true&lt;/code&gt; 时，只要语句被调用，就会清空一级和二级缓存&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;useCache&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;是否将该查询结果放入二级缓存（默认为 true）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;statementType&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;设置 SQL 执行方式（默认为 &lt;code&gt;PREPARED&lt;/code&gt;，即预编译）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="xml形式的等价写法"&gt;XML形式的等价写法
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;insert id&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;insert&amp;#34;&lt;/span&gt; useGeneratedKeys&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;true&amp;#34;&lt;/span&gt; keyProperty&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 insert into &lt;span style="color:#a6e22e"&gt;emp&lt;/span&gt;(...) values(...)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;/&lt;/span&gt;insert&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="将多个参数提取到实体类"&gt;将多个参数提取到实体类
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;代码整洁&lt;/strong&gt;：方法参数由 10 个变成 1 个。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;高复用性&lt;/strong&gt;：这个实体类可以在 Controller、Service、Mapper 之间直接传递。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自动封装&lt;/strong&gt;：Spring MVC 会自动根据请求参数的名称（Query Params）与实体类的属性名进行匹配并赋值&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Data&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;EmpQueryParam&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; Integer page &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 1; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; Integer pageSize &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 10; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String name; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; Integer gender; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@DateTimeFormat&lt;/span&gt;(pattern &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;yyyy-MM-dd&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String begin; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@DateTimeFormat&lt;/span&gt;(pattern &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;yyyy-MM-dd&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String end; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="注意事项"&gt;注意事项
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;不要加 &lt;code&gt;@RequestBody&lt;/code&gt;&lt;/strong&gt;：&lt;code&gt;@RequestBody&lt;/code&gt; 是用来解析 POST 请求里的 JSON 体的。对于 GET 请求的 URL 参数映射到对象，&lt;strong&gt;直接写参数&lt;/strong&gt;即可。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;默认值处理&lt;/strong&gt;：在实体类中直接为 &lt;code&gt;page&lt;/code&gt; 和 &lt;code&gt;pageSize&lt;/code&gt; 赋初值，可以省去 Controller 里的 &lt;code&gt;@RequestParam(defaultValue = &amp;quot;...&amp;quot;)&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;日期处理&lt;/strong&gt;：记得给日期属性加上 &lt;code&gt;@DateTimeFormat&lt;/code&gt;，否则当前端传 &lt;code&gt;2026-05-20&lt;/code&gt; 时，后端会因为无法转换为 &lt;code&gt;LocalDate&lt;/code&gt; 而报错。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="路径抽取"&gt;路径抽取
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;修改前&lt;/strong&gt;：每个方法（如查询、删除、新增）都要在注解里写 &lt;code&gt;@GetMapping(&amp;quot;/depts&amp;quot;)&lt;/code&gt; 或 &lt;code&gt;@DeleteMapping(&amp;quot;/depts/{id}&amp;quot;)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;修改后&lt;/strong&gt;：在 &lt;code&gt;public class DeptController&lt;/code&gt; 顶部添加 &lt;strong&gt;&lt;code&gt;@RequestMapping(&amp;quot;/depts&amp;quot;)&lt;/code&gt;&lt;/strong&gt;。这样下方的方法注解就可以简化，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;查询全部简写为：&lt;code&gt;@GetMapping&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;根据 ID 查询简写为：&lt;code&gt;@GetMapping(&amp;quot;/{id}&amp;quot;)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@RequestMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/depts&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//指定请求路径前缀 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;DeptController&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Autowired&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; DeptService deptService; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@RequestMapping&lt;/span&gt;(value &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/depts&amp;#34;&lt;/span&gt;,method &lt;span style="color:#f92672"&gt;=&lt;/span&gt; RequestMethod.&lt;span style="color:#a6e22e"&gt;GET&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@GetMapping&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//指定请求方式 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;list&lt;/span&gt;(){...} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@PostMapping&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;@RequestBody&lt;/span&gt; Dept dept){...} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@DeleteMapping&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;deleteById&lt;/span&gt;(Integer id){...} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@GetMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/{id}&amp;#34;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;--&amp;gt;&lt;/span&gt; 即为 &lt;span style="color:#e6db74"&gt;&amp;#34;/depts/{id}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;getInfo&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;@PathVariable&lt;/span&gt; Integer id){...} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@PutMapping&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;update&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;@RequestBody&lt;/span&gt; Dept dept){...} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="日志logback"&gt;日志Logback
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;JUL (java.util.logging)&lt;/strong&gt;：Java 原生日志框架，虽然配置简单但灵活性和性能较差&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Log4j&lt;/strong&gt;：早期非常流行的第三方日志框架，配置灵活&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Logback&lt;/strong&gt;：由 Log4j 作者开发的升级版，性能更优，也是目前 Spring Boot 默认集成的日志实现&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Slf4j (Simple Logging Facade for Java)&lt;/strong&gt;：重点强调的“&lt;strong&gt;简单日志门面&lt;/strong&gt;”，它不是真正的日志实现，而是一套标准接口，允许你在不修改代码的情况下切换底层的日志框架（如从 Log4j 切换到 Logback）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//logger 来自 SLF4j包&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; Logger log &lt;span style="color:#f92672"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 org.&lt;span style="color:#a6e22e"&gt;slf4j&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;LoggerFactory&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getLogger&lt;/span&gt;(LogTest.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;可替换为注解：@Slf4j&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="日志级别"&gt;日志级别
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;日志级别&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;记录方式&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;trace&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;追踪，记录程序运行轨迹，使用很少&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;log.trace(&amp;quot;...&amp;quot;)&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;debug&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;调试，记录调试过程中的信息，实际应用中通常视为最低级别&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;log.debug(&amp;quot;...&amp;quot;)&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;info&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;记录一般信息，描述运行关键事件（如网络连接、IO 操作），使用较多&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;log.info(&amp;quot;...&amp;quot;)&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;warn&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;警告信息，记录潜在有害情况，使用较多&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;log.warn(&amp;quot;...&amp;quot;)&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;error&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;错误信息，使用较多&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;log.error(&amp;quot;...&amp;quot;)&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;只有&lt;strong&gt;大于等于&lt;/strong&gt;设定级别的日志才会被输出。&lt;/li&gt;
&lt;li&gt;如果将 &lt;code&gt;root&lt;/code&gt; 级别设为 &lt;strong&gt;&lt;code&gt;info&lt;/code&gt;&lt;/strong&gt;，那么 &lt;code&gt;trace&lt;/code&gt; 和 &lt;code&gt;debug&lt;/code&gt; 级别的日志将&lt;strong&gt;不会&lt;/strong&gt;被记录或显示&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;root&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;level=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#f92672"&gt;&amp;lt;appender-ref&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ref=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;STDOUT&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#f92672"&gt;&amp;lt;appender-ref&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ref=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;FILE&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;/root&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="pagehelper分页查询"&gt;PageHelper分页查询
&lt;/h1&gt;&lt;h2 id="原理"&gt;原理
&lt;/h2&gt;&lt;p&gt;PageHelper 利用了 MyBatis 的 &lt;strong&gt;拦截器（Interceptor）&lt;/strong&gt; 机制。它的工作流程如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;拦截&lt;/strong&gt;：当你调用 Mapper 方法前，PageHelper 会拦截到即将执行的 SQL&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;解析&lt;/strong&gt;：自动检测你当前使用的数据库类型（MySQL, Oracle, MariaDB 等）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;改写&lt;/strong&gt;：根据你设置的页码（pageNum）和每页数量（pageSize），动态地在原始 SQL 后面拼接分页子句&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自动 Count&lt;/strong&gt;：它还会额外执行一条 &lt;code&gt;SELECT COUNT(0)&lt;/code&gt; 来获取总记录数，方便前端显示总页数&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;❗SQL语句结尾不能加分号；&lt;/strong&gt;(PageHelper会追加limit语句)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;❗&lt;strong&gt;PageHelper仅仅能对紧跟在其后的第一个查询语句进行分页处理&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="使用"&gt;使用
&lt;/h2&gt;&lt;p&gt;原始Service层&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; PageResult&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Emp&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;page&lt;/span&gt;(Integer page, Integer pageSize) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 Long total &lt;span style="color:#f92672"&gt;=&lt;/span&gt; empMapper.&lt;span style="color:#a6e22e"&gt;count&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Emp&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; rows &lt;span style="color:#f92672"&gt;=&lt;/span&gt; empMapper.&lt;span style="color:#a6e22e"&gt;page&lt;/span&gt;((page &lt;span style="color:#f92672"&gt;-&lt;/span&gt;1)&lt;span style="color:#f92672"&gt;*&lt;/span&gt;pageSize, pageSize); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; PageResult&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Emp&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;(total,rows); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;使用后&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; PageResult&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Emp&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;page&lt;/span&gt;(Integer page, Integer pageSize) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;//设置分页参数PageHelper &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 PageHelper.&lt;span style="color:#a6e22e"&gt;startPage&lt;/span&gt;(page, pageSize); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;//执行查询 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Emp&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; emp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; empMapper.&lt;span style="color:#a6e22e"&gt;list&lt;/span&gt;(page, pageSize); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;//解析查询结果并封装数据 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 Page&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Emp&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (Page&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Emp&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;) emp; &lt;span style="color:#75715e"&gt;//多态的实现&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; PageResult&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Emp&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;(p.&lt;span style="color:#a6e22e"&gt;getTotal&lt;/span&gt;(), p.&lt;span style="color:#a6e22e"&gt;getResult&lt;/span&gt;()); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="web%e5%90%8e%e7%ab%af%e5%ae%9e%e6%88%98-1.png"
 loading="lazy"
 data-pending-gallery
 alt="644"
 &gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="spring事务管理"&gt;Spring&lt;a class="link" href="https://creat.asia/MySQL/%e4%ba%8b%e5%8a%a1" &gt;事务管理&lt;/a&gt;
&lt;/h1&gt;&lt;p&gt;Spring 事务的本质是利用 &lt;strong&gt;AOP（面向切面编程）&lt;/strong&gt;。当你给一个方法加上事务注解时，Spring 会为该类创建一个代理对象。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;开启&lt;/strong&gt;：在方法执行前，代理对象关闭自动提交，开启事务。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;提交&lt;/strong&gt;：如果方法正常执行完毕，代理对象提交事务。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;回滚&lt;/strong&gt;：如果方法执行过程中抛出异常，代理对象捕获异常并回滚数据。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="transactional"&gt;@Transactional
&lt;/h2&gt;&lt;p&gt;这是开发中最常用的方式，通过注解直接管理事务，代码零侵入&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;EmpServiceImpl&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; EmpService {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Autowired&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; EmpMapper empMapper;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Autowired&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; DeptMapper deptMapper;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Transactional&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 开启事务&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;deleteDept&lt;/span&gt;(Integer id) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 1. 删除部门&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; deptMapper.&lt;span style="color:#a6e22e"&gt;deleteById&lt;/span&gt;(id);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 模拟异常：一旦报错，上面的删除操作也会撤销&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// int i = 1/0; &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 2. 删除该部门下的所有员工&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; empMapper.&lt;span style="color:#a6e22e"&gt;deleteByDeptId&lt;/span&gt;(id);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;属性&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;描述&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;rollbackFor&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;指定哪些异常触发回滚。默认只回滚 &lt;code&gt;RuntimeException&lt;/code&gt;。建议设置为 &lt;code&gt;Exception.class&lt;/code&gt; 以涵盖所有异常。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;propagation&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;事务传播行为&lt;/strong&gt;：定义当一个事务方法调用另一个事务方法时，事务如何传递。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;readOnly&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;是否为只读事务。查询操作建议设为 &lt;code&gt;true&lt;/code&gt;，可以优化数据库性能。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="rollbackfor"&gt;rollbackFor
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Transactional&lt;/span&gt;&lt;span style="color:#75715e"&gt;//默认出现运行时异常RuntimeException才会回滚&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Transactional&lt;/span&gt;(rollbackFor &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {Exception.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;})&lt;span style="color:#75715e"&gt;//指定所有异常都会回滚&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="propagation"&gt;propagation
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;属性值&lt;/th&gt;
					&lt;th&gt;含义&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;REQUIRED&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;【默认值】需要事务，有则加入，无则创建新事务&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;REQUIRES_NEW&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;需要新事务，无论有无，总是创建新事务&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;SUPPORTS&lt;/td&gt;
					&lt;td&gt;支持事务，有则加入，无则在无事务状态中运行&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;NOT_SUPPORTED&lt;/td&gt;
					&lt;td&gt;不支持事务，在无事务状态下运行；如果当前存在已有事务，则挂起当前事务&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;MANDATORY&lt;/td&gt;
					&lt;td&gt;必须有事务，否则抛异常&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;NEVER&lt;/td&gt;
					&lt;td&gt;必须没事务，否则抛异常&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="readonly"&gt;readOnly
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Transactional&lt;/span&gt;(readOnly &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; User &lt;span style="color:#a6e22e"&gt;getUserById&lt;/span&gt;(Long id) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; userRepository.&lt;span style="color:#a6e22e"&gt;findById&lt;/span&gt;(id);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;：告诉数据库这是一个只读事务。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;好处&lt;/strong&gt;：数据库可以针对只读操作进行优化（例如在 MySQL 中不分配回滚段），提高查询效率&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;它能防止修改吗？&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;不一定&lt;/strong&gt;。这取决于数据库和驱动。虽然 Hibernate 会跳过脏检查，但如果你在只读事务中强行执行原生 SQL 的 &lt;code&gt;UPDATE&lt;/code&gt;，某些数据库可能仍然允许执行（虽然这会导致语义混乱）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;主从架构（Read/Write Splitting）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;这是 &lt;code&gt;readOnly&lt;/code&gt; 的&lt;strong&gt;关键应用场景&lt;/strong&gt;。通过 AOP 拦截 &lt;code&gt;readOnly=true&lt;/code&gt; 的方法，可以将请求路由到从库（Read Node），而将其他的路由到主库。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;性能损耗&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;虽然它能优化内存，但开启事务本身也是有开销的（获取连接、上下文切换）。对于极其简单的单条查询，有时不加 &lt;code&gt;@Transactional&lt;/code&gt; 反而更快。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="失效场景"&gt;失效场景
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;非 public 方法&lt;/strong&gt;：&lt;code&gt;@Transactional&lt;/code&gt; 只能用于 &lt;code&gt;public&lt;/code&gt; 方法。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;方法内部调用&lt;/strong&gt;：同一个类中，A 方法调用 B 方法，即使 B 加了注解也不会生效（因为绕过了 AOP 代理）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;异常被捕获&lt;/strong&gt;：如果你在代码里 &lt;code&gt;try...catch&lt;/code&gt; 了异常且没有抛出，Spring 无法感知到报错，就不会回滚。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;数据库不支持&lt;/strong&gt;：比如 MySQL 的 MyISAM 引擎不支持事务，必须使用 &lt;strong&gt;InnoDB&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tips"&gt;⭐Tips
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;加在 Service 层&lt;/strong&gt;：不要加在 Controller 层，确保业务逻辑的完整性。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;显式指定回滚范围&lt;/strong&gt;：推荐使用 &lt;code&gt;@Transactional(rollbackFor = Exception.class)&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;保持方法短小&lt;/strong&gt;：事务会占用数据库连接，尽量不要在事务方法中进行远程接口调用或耗时操作，防止连接池耗尽&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
&lt;code&gt;@Transactional&lt;/code&gt; 可以加在&lt;strong&gt;方法上、类上、接口&lt;/strong&gt;上
※ 推荐加在方法上 ※&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h1 id="文件上传"&gt;文件上传
&lt;/h1&gt;&lt;h1 id="multipartfile"&gt;MultipartFile
&lt;/h1&gt;&lt;p&gt;&lt;code&gt;MultipartFile&lt;/code&gt; 是处理文件上传的核心接口。它代表了 HTML 表单中 &lt;code&gt;multipart/form-data&lt;/code&gt; 类型的文件内容。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@PostMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/upload&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;upload&lt;/span&gt;(String name, Integer age, MultipartFile file){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 log.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;接收参数：{},{},{}&amp;#34;&lt;/span&gt;,name,age,file); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;方法&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getName()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取表单中文件参数的名称（如上面例子中的 &amp;ldquo;file&amp;rdquo;）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getOriginalFilename()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取客户端文件系统的原始文件名。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;getContentType()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;获取内容类型（如 &lt;code&gt;image/png&lt;/code&gt;）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;isEmpty()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;判断文件是否为空（没有内容或未选择文件）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;getSize()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;返回文件大小（单位：字节）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;getBytes()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;以字节数组形式读取文件内容。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;getInputStream()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;获取输入流，用于流式读取（适合大文件处理）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;transferTo(File dest)&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;最常用&lt;/strong&gt;：将上传的文件直接保存到目标文件。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="问题及注意事项"&gt;问题及注意事项
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;多文件上传&lt;/strong&gt;： 如果你需要一次上传多个文件，将参数改为数组或列表即可： &lt;code&gt;public String upload(@RequestParam(&amp;quot;files&amp;quot;) MultipartFile[] files)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;文件名冲突&lt;/strong&gt;： 直接使用 &lt;code&gt;getOriginalFilename()&lt;/code&gt; 可能导致重名覆盖。建议使用 &lt;strong&gt;UUID&lt;/strong&gt; 或 &lt;strong&gt;时间戳&lt;/strong&gt; 重命名文件。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;临时存储&lt;/strong&gt;： &lt;code&gt;MultipartFile&lt;/code&gt; 在处理时会产生临时文件（存储在操作系统的 &lt;code&gt;tmp&lt;/code&gt; 目录）。一旦请求处理完成，这些临时文件会被自动删除。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;安全性&lt;/strong&gt;： 务必校验文件后缀名和文件头（Magic Number），防止用户上传恶意的 &lt;code&gt;.exe&lt;/code&gt; 或 &lt;code&gt;.sh&lt;/code&gt; 脚本文件。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="存储在本地"&gt;存储在本地
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@PostMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/upload&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;upload&lt;/span&gt;(String name, Integer age, MultipartFile file) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; IOException { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 log.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;接收参数：{},{},{}&amp;#34;&lt;/span&gt;,name,age,file); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;//原始文件名 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String fof &lt;span style="color:#f92672"&gt;=&lt;/span&gt; file.&lt;span style="color:#a6e22e"&gt;getOriginalFilename&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;//新文件名 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String extension &lt;span style="color:#f92672"&gt;=&lt;/span&gt; fof.&lt;span style="color:#a6e22e"&gt;substring&lt;/span&gt;(fof.&lt;span style="color:#a6e22e"&gt;lastIndexOf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;.&amp;#34;&lt;/span&gt;)); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String newName &lt;span style="color:#f92672"&gt;=&lt;/span&gt; UUID.&lt;span style="color:#a6e22e"&gt;randomUUID&lt;/span&gt;() &lt;span style="color:#f92672"&gt;+&lt;/span&gt; extension; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;//保存文件 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 file.&lt;span style="color:#a6e22e"&gt;transferTo&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; File(&lt;span style="color:#e6db74"&gt;&amp;#34;F:/images/&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt; newName)); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Spring中默认上传文件最大大小为1MB，超过大小需要在配置文件中配置&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-YML" data-lang="YML"&gt;# 文件上传
Spring:
	servlet: 
	 multipart: 
	 # 最大单个文件大小 
	 max-file-size: 10MB 
	 # 最大请求大小（包含所有文件和表单数据） 
	 max-request-size: 100MB
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id="oss"&gt;OSS
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Value&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;${aliyun.oss.endpoint}&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String endpoint; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Value&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;${aliyun.oss.bucketName}&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String bucketName; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Value&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;${aliyun.oss.region}&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String region;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-YML" data-lang="YML"&gt;# 阿里云 OSS配置 
aliyun: 
 oss: 
 endpoint: https://oss-cn-beijing.aliyuncs.com 
 bucketName: creat-spring-oss 
 region: cn-beijing
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="批量注入值configurationproperties"&gt;批量注入值@ConfigurationProperties
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Component&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AliyunOSSOperator&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Autowired&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; AliyunOSSProperties aliyunOSSProperties; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; String &lt;span style="color:#a6e22e"&gt;upload&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; content, String originalFilename) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; ClientException {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String endpoint &lt;span style="color:#f92672"&gt;=&lt;/span&gt; aliyunOSSProperties.&lt;span style="color:#a6e22e"&gt;getEndpoint&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String bucketName &lt;span style="color:#f92672"&gt;=&lt;/span&gt; aliyunOSSProperties.&lt;span style="color:#a6e22e"&gt;getBucketName&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String region &lt;span style="color:#f92672"&gt;=&lt;/span&gt; aliyunOSSProperties.&lt;span style="color:#a6e22e"&gt;getRegion&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 ......
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Data&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Component&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@ConfigurationProperties&lt;/span&gt;(prefix &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;aliyun.oss&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AliyunOSSProperties&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String endpoint; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String bucketName; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String region; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="全局异常处理器"&gt;全局异常处理器
&lt;/h1&gt;&lt;p&gt;无论程序在哪里抛出了异常，都能被这个处理器统一拦截，并返回一个优雅、格式统一的错误信息给前端或客户端&lt;/p&gt;
&lt;h2 id="注解"&gt;注解
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@RestControllerAdvice&lt;/code&gt;&lt;/strong&gt;：标记这是一个增强版的控制器，专门处理全局层面的逻辑&lt;code&gt;(@ControllerAdvice + @ResponseBody)&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@ExceptionHandler&lt;/code&gt;&lt;/strong&gt;：指定具体的异常类型，当这种异常发生时，执行对应的方法。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="核心流程"&gt;核心流程：
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;异常发生&lt;/strong&gt;：Controller 或 Service 层抛出一个异常（如 &lt;code&gt;UserNotFoundException&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自动捕获&lt;/strong&gt;：Spring 发现该异常未被内部 &lt;code&gt;try-catch&lt;/code&gt;，于是将其向上抛给全局处理器。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;匹配处理&lt;/strong&gt;：处理器根据异常类型找到对应的处理方法。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;返回结果&lt;/strong&gt;：处理器将异常包装成一个通用的 &lt;code&gt;Result&lt;/code&gt; 对象（包含错误码、错误消息），转换成 JSON 返回。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@RestControllerAdvice&lt;/span&gt; &lt;span style="color:#75715e"&gt;// = @ControllerAdvice + @ResponseBody&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;GlobalExceptionHandler&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 处理自定义业务异常&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@ExceptionHandler&lt;/span&gt;(BusinessException.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;handleBusinessException&lt;/span&gt;(BusinessException e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(e.&lt;span style="color:#a6e22e"&gt;getCode&lt;/span&gt;(), e.&lt;span style="color:#a6e22e"&gt;getMessage&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 处理参数验证异常 (如 @Valid 校验失败)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@ExceptionHandler&lt;/span&gt;(MethodArgumentNotValidException.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;handleValidationException&lt;/span&gt;(MethodArgumentNotValidException e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String msg &lt;span style="color:#f92672"&gt;=&lt;/span&gt; e.&lt;span style="color:#a6e22e"&gt;getBindingResult&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;getFieldError&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;getDefaultMessage&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(400, msg);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 兜底：处理所有未知的运行异常&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@ExceptionHandler&lt;/span&gt;(Exception.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;handleException&lt;/span&gt;(Exception e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; log.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;系统崩溃了，救命！&amp;#34;&lt;/span&gt;, e); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(500, &lt;span style="color:#e6db74"&gt;&amp;#34;服务器开小差了，请稍后再试&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;---------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@ExceptionHandler&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;handleException&lt;/span&gt;(Exception e) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 log.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;发生异常: &amp;#34;&lt;/span&gt;, e); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;服务器发生异常，请稍后再试&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@ExceptionHandler&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;handleDuplicateKeyException&lt;/span&gt;(DuplicateKeyException e) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 log.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;发生异常: &amp;#34;&lt;/span&gt;, e); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String msg &lt;span style="color:#f92672"&gt;=&lt;/span&gt; e.&lt;span style="color:#a6e22e"&gt;getMessage&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; msg.&lt;span style="color:#a6e22e"&gt;indexOf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Duplicate entry&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String errMsg &lt;span style="color:#f92672"&gt;=&lt;/span&gt; msg.&lt;span style="color:#a6e22e"&gt;substring&lt;/span&gt;(i); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; arr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; errMsg.&lt;span style="color:#a6e22e"&gt;split&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34; &amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#39;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; arr&lt;span style="color:#f92672"&gt;[&lt;/span&gt;2&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#39; 已存在，请检查数据&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="会话技术"&gt;会话技术
&lt;/h1&gt;&lt;h2 id="cookie"&gt;Cookie
&lt;/h2&gt;&lt;h3 id="工作流程"&gt;工作流程
&lt;/h3&gt;&lt;p&gt;Cookie 的本质是通过 HTTP 响应头和请求头在外部交换数据：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;设置阶段&lt;/strong&gt;：服务器在响应（Response）中加入 &lt;code&gt;Set-Cookie&lt;/code&gt; 头部字段。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;存储阶段&lt;/strong&gt;：浏览器收到响应后，将 Cookie 内容保存在本地（内存或硬盘）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;携带阶段&lt;/strong&gt;：下次请求同一个域名时，浏览器会自动在请求（Request）头中加入 &lt;code&gt;Cookie&lt;/code&gt; 字段。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="缺点"&gt;缺点
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;缺点&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;存储能力&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;容量小&lt;/td&gt;
					&lt;td&gt;单个 Cookie 最大限制约为 &lt;strong&gt;4KB&lt;/strong&gt;，不适合存大数据。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;用户控制&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;可被禁用&lt;/td&gt;
					&lt;td&gt;用户可以在浏览器设置中完全禁止接收 Cookie，导致功能失效。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;安全性&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;不安全&lt;/td&gt;
					&lt;td&gt;默认明文存储在客户端，极易受到 &lt;strong&gt;XSS 攻击&lt;/strong&gt; 窃取或中间人篡改。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;访问限制&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;跨域限制&lt;/td&gt;
					&lt;td&gt;受到同源策略限制，Cookie 无法在不同的一级域名间直接共享。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;网络性能&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;占用带宽&lt;/td&gt;
					&lt;td&gt;每次 HTTP 请求都会自动携带相关 Cookie，增加了请求头体积，浪费流量。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;合规隐私&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;隐私问题&lt;/td&gt;
					&lt;td&gt;常用于行为追踪，可能触犯 GDPR 等隐私法规，令用户反感。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;生命周期&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;时效性&lt;/td&gt;
					&lt;td&gt;默认为会话级别（关闭浏览器即消失），除非开发者手动设置 &lt;code&gt;Max-Age&lt;/code&gt;。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;物理限制&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;无法跨设备&lt;/td&gt;
					&lt;td&gt;数据绑定在特定设备的特定浏览器上，无法实现手机/电脑端同步。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="典型场景与规避方案"&gt;典型场景与规避方案
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;敏感信息处理&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;原则&lt;/strong&gt;：绝不在 Cookie 中存储密码、身份证号等敏感数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;方案&lt;/strong&gt;：仅存储加密后的 Token，并设置 &lt;code&gt;HttpOnly&lt;/code&gt; 属性以防止 JS 脚本读取。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;移动端开发&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;痛点&lt;/strong&gt;：部分原生 App 内置浏览器或某些移动端环境对 Cookie 支持不佳。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;方案&lt;/strong&gt;：在移动端或前后端分离架构中，优先考虑使用 &lt;strong&gt;JWT (JSON Web Token)&lt;/strong&gt; 并通过自定义 Header 传输。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;分布式/集群环境&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;痛点&lt;/strong&gt;：多台服务器之间无法直接共享保存在各自内存或浏览器关联的传统 Session。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;方案&lt;/strong&gt;：采用 &lt;strong&gt;分布式会话&lt;/strong&gt;（如 &lt;code&gt;Spring Session + Redis&lt;/code&gt;），将状态数据统一托管在外部缓存中。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="session"&gt;Session
&lt;/h2&gt;&lt;h3 id="工作原理"&gt;工作原理
&lt;/h3&gt;&lt;p&gt;Session 的核心在于服务器与浏览器之间的一个“约定”。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;创建：&lt;/strong&gt; 当用户第一次访问服务器时，服务器会为该用户创建一个唯一的 &lt;strong&gt;HttpSession&lt;/strong&gt; 对象，并生成一个唯一的 ID（通常称为 &lt;code&gt;JSESSIONID&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;传递：&lt;/strong&gt; 服务器通过 HTTP 响应头，将这个 &lt;code&gt;JSESSIONID&lt;/code&gt; 以 &lt;strong&gt;Cookie&lt;/strong&gt; 的形式发送给浏览器。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;识别：&lt;/strong&gt; 当浏览器再次请求该服务器时，会自动在请求头中携带这个 &lt;code&gt;JSESSIONID&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检索：&lt;/strong&gt; 服务器根据收到的 ID，在内存中找到对应的 Session 对象&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="生命周期"&gt;生命周期
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;开始：&lt;/strong&gt; 用户第一次调用 &lt;code&gt;request.getSession()&lt;/code&gt; 时。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;超时：&lt;/strong&gt; 为了节省服务器内存，Session 不会永久存在。如果用户在一段时间内（默认通常是 30 分钟）没有任何操作，Session 会自动销毁。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="缺点-1"&gt;缺点
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;优势&lt;/th&gt;
					&lt;th&gt;劣势&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;开发难度&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;简单易用&lt;/strong&gt;：Java 原生支持，直接调用 &lt;code&gt;getAttribute&lt;/code&gt; 即可，逻辑清晰。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;依赖 Cookie&lt;/strong&gt;：如果客户端禁用了 Cookie，Session 就会失效（需额外处理 URL 重写）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;数据安全&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;安全性高&lt;/strong&gt;：敏感数据留在服务器，客户端只拿一个加密 ID，不容易被篡改。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;会话劫持&lt;/strong&gt;：如果 ID 被窃取，攻击者可以完全冒充用户身份（需 HTTPS 配合）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;性能表现&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;读写极快&lt;/strong&gt;：数据就在本地内存中，无需网络开销，适合单机小型应用。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;内存消耗&lt;/strong&gt;：用户多了会占满服务器内存。用户关浏览器不点退出，数据会白白占用内存直到超时。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;架构扩展&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;无需额外中间件&lt;/strong&gt;：单机部署时非常方便，不需要安装 Redis 等数据库。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;分布式困境&lt;/strong&gt;：多台服务器环境下，Session 不共享，会导致用户登录状态频繁丢失。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;数据类型&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;灵活&lt;/strong&gt;：可以存储复杂的 Java 对象，不需要像 Token 那样进行频繁的序列化转换。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;存储限制&lt;/strong&gt;：不能存太大的东西（如大列表、大图片），否则严重拖慢服务器性能。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="对比cookie"&gt;对比Cookie
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;特性&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;Cookie&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;Session&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;存储位置&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;客户端（浏览器）&lt;/td&gt;
					&lt;td&gt;服务器端&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;安全性&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;较低（易被伪造或窃取）&lt;/td&gt;
					&lt;td&gt;较高（敏感数据不发送给客户端）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;存储容量&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;较小（通常单个 4KB）&lt;/td&gt;
					&lt;td&gt;较大（取决于服务器内存）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;数据类型&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;只能存储字符串&lt;/td&gt;
					&lt;td&gt;可以存储任意 Java 对象&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;性能影响&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;几乎不占用服务器资源&lt;/td&gt;
					&lt;td&gt;占用服务器内存，用户多时压力大&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="token令牌主流"&gt;⭐Token令牌（主流）
&lt;/h2&gt;&lt;h3 id="工作原理-1"&gt;工作原理
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;1. 签发：&lt;/strong&gt; 当用户通过用户名和密码登录成功后，服务器会根据用户信息（如用户 ID）和一段只有服务器知道的“秘钥”，生成一个加密的字符串（即 Token）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. 传输：&lt;/strong&gt; 服务器将这个 Token 作为响应体的一部分发送给浏览器。与 Session 不同，服务器此时&lt;strong&gt;不会&lt;/strong&gt;在自己的内存或数据库中保存这个 Token。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. 存储：&lt;/strong&gt; 浏览器接收到 Token 后，通常将其存储在 &lt;code&gt;localStorage&lt;/code&gt;、&lt;code&gt;sessionStorage&lt;/code&gt; 或 &lt;code&gt;Cookie&lt;/code&gt; 中。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. 携带：&lt;/strong&gt; 当浏览器后续请求受保护的资源（如获取订单列表）时，会手动将 Token 放入 HTTP 请求头中（通常放在 &lt;code&gt;Authorization: Bearer &amp;lt;Token&amp;gt;&lt;/code&gt; 字段）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. 校验：&lt;/strong&gt; 服务器接收到请求后，不再去查找数据库或内存，而是直接使用存储在服务器本地的“秘钥”对该 Token 进行解密和签名校验。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. 提取：&lt;/strong&gt; 如果校验通过，服务器就认为该请求是合法的，并直接从 Token 内部解密出用户信息（如该用户是“张三”），从而完成业务处理。&lt;/p&gt;
&lt;h3 id="jwt组成"&gt;JWT组成
&lt;/h3&gt;&lt;h4 id="header头部-说明书"&gt;Header（头部）—— “说明书”
&lt;/h4&gt;&lt;p&gt;这部分用于描述 JWT 的元数据，告诉服务器如何处理这个令牌。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;内容：&lt;/strong&gt; 通常包含令牌的类型（&lt;code&gt;typ&lt;/code&gt;: &amp;ldquo;JWT&amp;rdquo;）和所使用的加密算法（&lt;code&gt;alg&lt;/code&gt;: 如 &amp;ldquo;HS256&amp;rdquo; 或 &amp;ldquo;RS256&amp;rdquo;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;编码：&lt;/strong&gt; 使用 &lt;strong&gt;Base64URL&lt;/strong&gt; 算法进行编码。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	{ &lt;span style="color:#e6db74"&gt;&amp;#34;alg&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;HS256&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;typ&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;JWT&amp;#34;&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="payload有效载荷-货物"&gt;Payload（有效载荷）—— “货物”
&lt;/h4&gt;&lt;p&gt;这是 JWT 的核心部分，包含了实际要传递的用户信息（Claims）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;标准字段：&lt;/strong&gt; 如签发人（&lt;code&gt;iss&lt;/code&gt;）、过期时间（&lt;code&gt;exp&lt;/code&gt;）、用户 ID（&lt;code&gt;sub&lt;/code&gt;）等。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自定义字段：&lt;/strong&gt; 你可以放入用户的角色、权限、姓名等（例如：&lt;code&gt;&amp;quot;role&amp;quot;: &amp;quot;admin&amp;quot;&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;编码：&lt;/strong&gt; 同样使用 &lt;strong&gt;Base64URL&lt;/strong&gt; 编码。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt; 这里的内容只是编码，并不是加密。&lt;strong&gt;绝对不要在此处存放密码或敏感信息&lt;/strong&gt;，因为任何人拿到 Token 都能通过解码看到里面的内容。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	{ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#e6db74"&gt;&amp;#34;sub&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;ZhangSan&amp;#34;&lt;/span&gt;, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#e6db74"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Java-Dev&amp;#34;&lt;/span&gt;, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#e6db74"&gt;&amp;#34;exp&amp;#34;&lt;/span&gt;: 1746144000 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="signature签名-防伪封条"&gt;Signature（签名）—— “防伪封条”
&lt;/h4&gt;&lt;p&gt;这是保证安全的关键。它用于验证 Token 在传输过程中是否被篡改。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;生成原理：&lt;/strong&gt; 服务器将编码后的 &lt;code&gt;Header&lt;/code&gt; 和 &lt;code&gt;Payload&lt;/code&gt; 用点拼接起来，再加上一个只有服务器知道的&lt;strong&gt;密钥（Secret）&lt;/strong&gt;，按照 Header 中指定的算法进行哈希计算。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt; 如果有人修改了 Payload 里的用户权限（比如把 &lt;code&gt;user&lt;/code&gt; 改成 &lt;code&gt;admin&lt;/code&gt;），由于他没有服务器的密钥，生成的签名就会和原来的不匹配。服务器校验失败，该 Token 立即失效。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-Secret" data-lang="Secret"&gt;	a-string-secret-at-least-256-bits-long
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="总结外观"&gt;总结外观
&lt;/h4&gt;&lt;p&gt;一个完整的 JWT 看起来像这样：
&lt;code&gt;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.&lt;/code&gt;
&lt;code&gt;eyJzdWIiOiJaaGFuZ3NhbiIsInJvbGUiOiJKYXZhLURldiIsImV4cCI6MTc0NjE0NDAwMH0.&lt;/code&gt;
&lt;code&gt;MJSEga1Hm1wHRnaCKpjSzXcr7DpI3TlhDQoGcIWnXDA&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;xxxxx.yyyyy.zzzzz&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;红色部分 (xxxxx):&lt;/strong&gt; 头部，声明算法。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;蓝色部分 (yyyyy):&lt;/strong&gt; 负载，存放用户信息。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;绿色部分 (zzzzz):&lt;/strong&gt; 签名，由前两部分加盐哈希而成&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="jwr生成解析"&gt;JWR生成/解析
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; String SECRET &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;基于base64的字符串（字节数必须大于32）&amp;#34;&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; SecretKey KEY &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Keys.&lt;span style="color:#a6e22e"&gt;hmacShaKeyFor&lt;/span&gt;(SECRET.&lt;span style="color:#a6e22e"&gt;getBytes&lt;/span&gt;(StandardCharsets.&lt;span style="color:#a6e22e"&gt;UTF_8&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Test&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;testGenerateJwt&lt;/span&gt;() { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Map&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String, Object&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; dataMap &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; HashMap&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dataMap.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;userId&amp;#34;&lt;/span&gt;, 1); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dataMap.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;username&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;admin&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String token &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Jwts.&lt;span style="color:#a6e22e"&gt;builder&lt;/span&gt;() 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;claims&lt;/span&gt;(dataMap) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;expiration&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Date(System.&lt;span style="color:#a6e22e"&gt;currentTimeMillis&lt;/span&gt;() &lt;span style="color:#f92672"&gt;+&lt;/span&gt; 3600 &lt;span style="color:#f92672"&gt;*&lt;/span&gt; 1000)) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;signWith&lt;/span&gt;(KEY) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;compact&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(token); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Test&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;testParseJwt&lt;/span&gt;() { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String token &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;JWT得到的Token&amp;#34;&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Claims claims &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Jwts.&lt;span style="color:#a6e22e"&gt;parser&lt;/span&gt;() 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;verifyWith&lt;/span&gt;(KEY) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;build&lt;/span&gt;() 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;parseSignedClaims&lt;/span&gt;(token) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;getPayload&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(claims); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="cookiesessiontoken对比"&gt;&lt;code&gt;Cookie,Session,Token&lt;/code&gt;对比
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;Cookie&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;Session&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;Token (JWT)&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;定义&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;存储在浏览器端的一段文本。&lt;/td&gt;
					&lt;td&gt;服务器端的一种会话记录机制。&lt;/td&gt;
					&lt;td&gt;一段经过加密/签名的凭证字符串。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;核心位置&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;客户端&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;服务器&lt;/strong&gt;（内存/数据库/Redis）&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;客户端&lt;/strong&gt;（服务器不存储）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;工作逻辑&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;浏览器自动携带。&lt;/td&gt;
					&lt;td&gt;依赖 Session ID 匹配服务器记录。&lt;/td&gt;
					&lt;td&gt;客户端手动放入 Header，服务器解密。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;安全性&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;较低，容易被拦截或伪造。&lt;/td&gt;
					&lt;td&gt;较高，敏感信息存在服务器。&lt;/td&gt;
					&lt;td&gt;高，有签名校验，防篡改。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;扩展性&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;无。&lt;/td&gt;
					&lt;td&gt;差，多台服务器需做数据同步。&lt;/td&gt;
					&lt;td&gt;极佳，天然支持跨服务器、跨域。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;存储压力&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;无（存在用户本地）。&lt;/td&gt;
					&lt;td&gt;较大，用户多时会消耗大量服务器内存。&lt;/td&gt;
					&lt;td&gt;无（存在用户本地）。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src="web%e5%90%8e%e7%ab%af%e5%ae%9e%e6%88%98-2.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h3 id="优点对比"&gt;优点对比
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;Cookie (客户端存储)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;Session (服务端存储)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;Token (无状态令牌/JWT)&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;最大优势&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;减轻服务器压力&lt;/strong&gt;：数据存用户本地，服务器不占内存。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;数据最安全&lt;/strong&gt;：敏感信息不发给客户端，只在服务器内部。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;极易水平扩展&lt;/strong&gt;：服务器不存任何数据，非常适合微服务/集群。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;生命周期&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;持久性好&lt;/strong&gt;：可以设置长达数天的有效期，甚至关机后再开也存在。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;控制力强&lt;/strong&gt;：服务器可以随时主动让某个特定用户下线。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;性能均衡&lt;/strong&gt;：不需要查数据库或缓存，服务器解析 Token 即可校验身份。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;开发难度&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;最简单&lt;/strong&gt;：浏览器原生支持，几乎不需要写代码逻辑。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;非常简单&lt;/strong&gt;：成熟的框架（如 Spring）自动处理 ID 传递。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;跨域支持完美&lt;/strong&gt;：不受浏览器跨域限制，App、小程序、H5 通用。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;存储能力&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;随用随取&lt;/strong&gt;：适合存偏好设置（如主题颜色、语言）。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;类型多样&lt;/strong&gt;：可以存复杂的 Java 对象（用户角色、权限列表）。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;自包含&lt;/strong&gt;：Token 内部可以携带用户信息，减少后端查询次数。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h1 id="过滤器filter"&gt;过滤器Filter
&lt;/h1&gt;&lt;h2 id="核心作用"&gt;核心作用
&lt;/h2&gt;&lt;p&gt;过滤器主要用于处理一些&lt;strong&gt;通用性&lt;/strong&gt;的横切关注点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;权限校验&lt;/strong&gt;：检查请求头中是否携带有效的 JWT Token。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;字符编码转换&lt;/strong&gt;：统一设置 &lt;code&gt;request&lt;/code&gt; 和 &lt;code&gt;response&lt;/code&gt; 的编码（如 UTF-8）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;日志记录&lt;/strong&gt;：统计接口的访问耗时、记录请求来源 IP。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;敏感词过滤&lt;/strong&gt;：对用户提交的内容进行安全扫描。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="工作原理责任链模式"&gt;工作原理：责任链模式
&lt;/h2&gt;&lt;p&gt;过滤器并不是独立存在的，它们通常组成一个&lt;strong&gt;过滤器链 (FilterChain)&lt;/strong&gt;。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;执行前处理&lt;/strong&gt;：请求进入时，过滤器先执行 &lt;code&gt;doFilter&lt;/code&gt; 方法中 &lt;code&gt;chain.doFilter()&lt;/code&gt; 之前的代码。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;放行（传递）&lt;/strong&gt;：调用 &lt;code&gt;chain.doFilter(request, response)&lt;/code&gt;。如果有下一个过滤器，就传给下一个；如果没有，就传给 Servlet（或 Controller）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;执行后处理&lt;/strong&gt;：当核心业务处理完返回响应时，代码会回到 &lt;code&gt;chain.doFilter()&lt;/code&gt; 之后，执行后续逻辑。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="执行顺序"&gt;执行顺序
&lt;/h2&gt;&lt;pre&gt;
$$Filter \rightarrow Controller \rightarrow Service \rightarrow Mapper \rightarrow DB$$
$$\uparrow \quad \quad \quad \quad \quad \quad \quad \quad \quad \quad \quad \quad \quad \quad \downarrow$$
$$Filter(回程) \leftarrow Controller \leftarrow Service \leftarrow Mapper$$
&lt;/pre&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#f92672"&gt;[&lt;/span&gt;浏览器请求&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;┌──────&lt;/span&gt; Filter (去程&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;校验Token&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;记录时间) &lt;span style="color:#960050;background-color:#1e0010"&gt;──────┐&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;┌────&lt;/span&gt; Controller (解析请求&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;参数校验) &lt;span style="color:#960050;background-color:#1e0010"&gt;────┐&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;┌──&lt;/span&gt; Service (业务逻辑处理) &lt;span style="color:#960050;background-color:#1e0010"&gt;────────┐&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;┌&lt;/span&gt; Mapper (SQL执行) &lt;span style="color:#960050;background-color:#1e0010"&gt;──┐&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt; 数据库 DB &lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;────┘&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; (返回结果) &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└────────────────────────────┘&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└──&lt;/span&gt; Service (业务结果组装) &lt;span style="color:#960050;background-color:#1e0010"&gt;────────┘&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└────&lt;/span&gt; Controller (封装结果对象) &lt;span style="color:#960050;background-color:#1e0010"&gt;─────────┘&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;└──────&lt;/span&gt; Filter (回程&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;清理ThreadLocal&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;日志打印) &lt;span style="color:#960050;background-color:#1e0010"&gt;┘&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#f92672"&gt;[&lt;/span&gt;返回响应&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//-- 这种图强调了 Filter 是最外层，它包裹着所有的内部组件：--&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		( ( ( ( &lt;span style="color:#f92672"&gt;[&lt;/span&gt; 数据库 DB &lt;span style="color:#f92672"&gt;]&lt;/span&gt; ) ) ) )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▲&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▲&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▲&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▲&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▲&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└─────┴───┘&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└────&lt;/span&gt; Mapper &lt;span style="color:#960050;background-color:#1e0010"&gt;─────┘&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└───────&lt;/span&gt; Service &lt;span style="color:#960050;background-color:#1e0010"&gt;─────────┘&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└──────────&lt;/span&gt; Controller &lt;span style="color:#960050;background-color:#1e0010"&gt;───────────┘&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└─────────────&lt;/span&gt; Filter &lt;span style="color:#960050;background-color:#1e0010"&gt;──────────────────┘&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;请求进入&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;响应返回&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;去程：&lt;/strong&gt; &lt;code&gt;Client&lt;/code&gt; $\rightarrow$ &lt;code&gt;Filter&lt;/code&gt; $\rightarrow$ &lt;code&gt;Controller&lt;/code&gt; $\rightarrow$ &lt;code&gt;Service&lt;/code&gt; $\rightarrow$ &lt;code&gt;Mapper&lt;/code&gt; $\rightarrow$ &lt;code&gt;DB&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心：&lt;/strong&gt; 数据库执行查询/更新&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;回程：&lt;/strong&gt; &lt;code&gt;DB&lt;/code&gt; $\rightarrow$ &lt;code&gt;Mapper&lt;/code&gt; $\rightarrow$ &lt;code&gt;Service&lt;/code&gt; $\rightarrow$ &lt;code&gt;Controller&lt;/code&gt; $\rightarrow$ &lt;code&gt;Filter&lt;/code&gt; $\rightarrow$ &lt;code&gt;Client&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&amp;mdash;页尾&amp;mdash;&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="注意事项-1"&gt;注意事项
&lt;/h1&gt;&lt;h2 id="pathvariable与requestparam"&gt;@PathVariable与@RequestParam
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;方式&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;前端URL&lt;/th&gt;
					&lt;th&gt;后端请求&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;什么时候用？&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;精准定位&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/clazzs/5&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/{id}&lt;/code&gt; + &lt;code&gt;@PathVariable&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;删除单个 ID&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;带清单操作&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/clazzs?ids=1,2,3&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;(无路径)&lt;/code&gt; + &lt;code&gt;@RequestParam&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;批量删除&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;路径串烧&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/clazzs/1,2,3&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/{ids}&lt;/code&gt; + &lt;code&gt;@PathVariable&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;极少用，除非有特殊设计需求&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="xml的更新语句"&gt;&lt;code&gt;xml&lt;/code&gt;的更新语句
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;字段类型&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;业务要求&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;&lt;if&gt; 判定表达式&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;避坑指南&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;String&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;必填&lt;/strong&gt; (非空且非空串)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;test=&amp;quot;name != null and name != ''&amp;quot;&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;这样可以防止前端传个空字符串 &lt;code&gt;&amp;quot;&amp;quot;&lt;/code&gt; 导致数据库存入无意义数据。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;String&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;允许置空&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;test=&amp;quot;address != null&amp;quot;&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;注意：&lt;/strong&gt; 这样如果传 &lt;code&gt;&amp;quot;&amp;quot;&lt;/code&gt;，它会判定为非 null，从而把空串插入数据库。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Integer / 数字&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;必填&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;test=&amp;quot;id != null&amp;quot;&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;绝对不要加&lt;/strong&gt; &lt;code&gt;and id != ''&lt;/code&gt;！如果 id 为 0，MyBatis 可能会误判它等于空串，导致 0 存不进去。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Integer / 数字&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;允许置空&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;test=&amp;quot;degree != null&amp;quot;&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;同上，只判断 null 即可。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;操作类型&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;字段类型&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;推荐写法&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;理由&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;SELECT&lt;/strong&gt; (搜索)&lt;/td&gt;
					&lt;td&gt;任何类型&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;!= null and != ''&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;防前端传空搜索框&lt;/strong&gt;导致的“查无数据”。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;UPDATE&lt;/strong&gt; (更新)&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;String&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;!= null and != ''&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;过滤无效空串，保证数据严谨。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;UPDATE&lt;/strong&gt; (更新)&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Integer&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;!= null&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;最安全&lt;/strong&gt;，防止 &lt;code&gt;0&lt;/code&gt; 值无法更新。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;INSERT&lt;/strong&gt; (插入)&lt;/td&gt;
					&lt;td&gt;任何类型&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;!= null&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;通常只为了防止 null 值覆盖数据库默认值。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;</description></item><item><title>Web</title><link>https://creat.asia/post/web/</link><pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/web/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-11&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="springbootweb基础"&gt;SpringBootWeb基础
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;* 请求处理类 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;* */&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;HelloController&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 响应返回值 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * */&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;@RequestMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/Hello&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; String &lt;span style="color:#a6e22e"&gt;Hello&lt;/span&gt;(String name){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;name:&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;name); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; name &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;~&amp;#34;&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="http协议"&gt;&lt;a class="link" href="%e5%9f%ba%e7%a1%80#HTTP" &gt;HTTP协议&lt;/a&gt;
&lt;/h1&gt;&lt;p&gt;概念:&lt;code&gt;Hyper Text Transfer Protocol&lt;/code&gt;，超文本传输协议，规定了浏览器和服务器之间数据传输的规则&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特点:&lt;/strong&gt;
&lt;ol&gt;
&lt;li&gt;基于TCP协议：面向连接，安全&lt;/li&gt;
&lt;li&gt;基于请求-响应模型的：一次请求对应一次响应&lt;/li&gt;
&lt;li&gt;HTTP协议是&lt;strong&gt;无状态&lt;/strong&gt;的协议：对于事务处理没有记忆能力。每次请求-响应都是独立的。&lt;/li&gt;
&lt;/ol&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;/ul&gt;
&lt;h2 id="请求协议"&gt;请求协议
&lt;/h2&gt;&lt;h3 id="请求数据格式"&gt;请求数据格式
&lt;/h3&gt;&lt;p&gt;&lt;img src="Web-1.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h4 id="请求行-request-line"&gt;请求行 (Request Line)
&lt;/h4&gt;&lt;p&gt;包含三个核心信息：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;请求方法&lt;/strong&gt;：&lt;code&gt;GET&lt;/code&gt;、&lt;code&gt;POST&lt;/code&gt;、&lt;code&gt;PUT&lt;/code&gt;、&lt;code&gt;DELETE&lt;/code&gt; 等。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;资源路径&lt;/strong&gt;：例如 &lt;code&gt;/api/v1/users&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;协议版本&lt;/strong&gt;：通常是 &lt;code&gt;HTTP/1.1&lt;/code&gt; 或 &lt;code&gt;HTTP/2&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;示例：&lt;code&gt;POST /login HTTP/1.1&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="请求头-request-headers"&gt;请求头 (Request Headers)
&lt;/h4&gt;&lt;p&gt;用键值对（&lt;code&gt;Key: Value&lt;/code&gt;）的形式告知服务器客户端的环境、权限以及&lt;strong&gt;数据格式&lt;/strong&gt;。常见头信息：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Host&lt;/code&gt;&lt;/strong&gt;: 服务器域名。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;User-Agent&lt;/code&gt;&lt;/strong&gt;: 客户端浏览器或系统信息。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Content-Type&lt;/code&gt;&lt;/strong&gt;: &lt;strong&gt;最重要的字段&lt;/strong&gt;，告诉服务器请求体里装的是什么格式的数据（如 JSON 或表单）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Authorization&lt;/code&gt;&lt;/strong&gt;: 携带 Token 进行登录校验。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="空行-empty-line"&gt;空行 (Empty Line)
&lt;/h4&gt;&lt;p&gt;必须存在的一行空行，用于分隔“报头”和“数据体”。&lt;/p&gt;
&lt;h4 id="请求体-request-body"&gt;请求体 (Request Body)
&lt;/h4&gt;&lt;p&gt;真正传输的数据。注意：&lt;code&gt;GET&lt;/code&gt; 请求通常没有请求体（参数放在 URL 后），而 &lt;code&gt;POST&lt;/code&gt;、&lt;code&gt;PUT&lt;/code&gt; 请求通常将数据放在这里。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="请求数据获取"&gt;请求数据获取
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;RequestController&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@RequestMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/request&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; String &lt;span style="color:#a6e22e"&gt;request&lt;/span&gt;(HttpServletRequest request) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//获取请求方式 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String method &lt;span style="color:#f92672"&gt;=&lt;/span&gt; request.&lt;span style="color:#a6e22e"&gt;getMethod&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;请求方式:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; method); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//获取请求url地址 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String url &lt;span style="color:#f92672"&gt;=&lt;/span&gt; request.&lt;span style="color:#a6e22e"&gt;getRequestURL&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//http://localhost:8080/request &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;请求url地址:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; url); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String uri &lt;span style="color:#f92672"&gt;=&lt;/span&gt; request.&lt;span style="color:#a6e22e"&gt;getRequestURI&lt;/span&gt;();&lt;span style="color:#75715e"&gt;//request &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;请求uri地址:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; uri); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//获取请求协议 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String protocol &lt;span style="color:#f92672"&gt;=&lt;/span&gt; request.&lt;span style="color:#a6e22e"&gt;getProtocol&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;请求协议:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; protocol); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//获取请求参数 - name &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; request.&lt;span style="color:#a6e22e"&gt;getParameter&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String age &lt;span style="color:#f92672"&gt;=&lt;/span&gt; request.&lt;span style="color:#a6e22e"&gt;getParameter&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;age&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;请求参数name:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; name &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;,age:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; age); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//获取请求头 - Accept &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String accept &lt;span style="color:#f92672"&gt;=&lt;/span&gt; request.&lt;span style="color:#a6e22e"&gt;getHeader&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;请求头Accept:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; accept); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;OKK&amp;#34;&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;URL (Uniform Resource Locator)&lt;/strong&gt;：资源的&lt;strong&gt;路径&lt;/strong&gt;。它像家庭住址：&lt;code&gt;http://localhost:8080/request&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;URI (Uniform Resource Identifier)&lt;/strong&gt;：资源的&lt;strong&gt;身份证&lt;/strong&gt;。它只关心资源本身：&lt;code&gt;/request&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;面试题：&lt;/strong&gt; 所有的 URL 都是 URI，但不是所有的 URI 都是 URL&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="响应协议"&gt;响应协议
&lt;/h2&gt;&lt;h3 id="响应数据格式"&gt;响应数据格式
&lt;/h3&gt;&lt;p&gt;&lt;img src="Web-2.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h4 id="响应行"&gt;响应行
&lt;/h4&gt;&lt;p&gt;协议版本 + 状态码 + 状态描述&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;例如：&lt;code&gt;HTTP/1.1 200 OK&lt;/code&gt; 或 &lt;code&gt;HTTP/1.1 404 Not Found&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="响应头"&gt;响应头
&lt;/h4&gt;&lt;p&gt;服务器告知客户端的数据元信息。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Content-Type&lt;/code&gt;&lt;/strong&gt;: &lt;strong&gt;最关键&lt;/strong&gt;。告知浏览器数据格式（如 &lt;code&gt;application/json&lt;/code&gt; 或 &lt;code&gt;text/html&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Set-Cookie&lt;/code&gt;&lt;/strong&gt;: 服务器给客户端种下的“小饼干”。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="空行"&gt;&lt;strong&gt;空行&lt;/strong&gt;
&lt;/h4&gt;&lt;p&gt;分隔头部与内容。&lt;/p&gt;
&lt;h4 id="响应体"&gt;响应体
&lt;/h4&gt;&lt;p&gt;真正传回给前端的数据（HTML、JSON、图片字节流等）&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;HTTP 状态码&lt;/th&gt;
					&lt;th&gt;含义说明&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;1xx&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;响应中 - 临时状态码，表示请求已经接收，告诉客户端应该继续请求或者如果它已经完成则忽略它。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;2xx&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;成功 - 表示请求已经被成功接收，处理已完成。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;3xx&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;重定向 - 重定向到其他地方；让客户端再发起一次请求以完成整个处理。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;4xx&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;客户端错误 - 处理发生错误，责任在客户端。如：请求了不存在的资源、客户端未被授权、禁止访问等。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;5xx&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;服务器错误 - 处理发生错误，责任在服务端。如：程序抛出异常等。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;最常见状态码：&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;状态码&lt;/th&gt;
					&lt;th&gt;英文描述&lt;/th&gt;
					&lt;th&gt;解释&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;200&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;OK&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;请求成功，服务器正常处理并返回资源&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;404&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Not Found&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;请求的资源不存在&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;500&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Internal Server Error&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;服务器内部错误，无法完成请求&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;字段解释：&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;响应头字段&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;含义说明&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Content-Type&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;表示该响应内容的类型，例如&lt;code&gt;text/html&lt;/code&gt;, &lt;code&gt;application/json&lt;/code&gt;。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Content-Length&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;表示该响应内容的长度（字节数）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Content-Encoding&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;表示该响应压缩算法，例如&lt;code&gt;gzip&lt;/code&gt;。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Cache-Control&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;指示客户端应如何缓存，例如&lt;code&gt;max-age=300&lt;/code&gt;表示可以最多缓存 300 秒。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Set-Cookie&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;告诉浏览器为当前页面所在的域设置 cookie。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="响应数据设置"&gt;响应数据设置
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ResponseController&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@RequestMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/response&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;response&lt;/span&gt;(HttpServletResponse response) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; IOException { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//设置响应状态码 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; response.&lt;span style="color:#a6e22e"&gt;setStatus&lt;/span&gt;(401); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//设置响应头 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; response.&lt;span style="color:#a6e22e"&gt;setHeader&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;itcast&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//设置响应体 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; response.&lt;span style="color:#a6e22e"&gt;getWriter&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;write&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;h1&amp;gt;Hello Response&amp;lt;/h1&amp;gt;&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 方法二 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 基于ResponseEntity构建响应对象 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * */&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;@RequestMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/response2&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; ResponseEntity&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;response2&lt;/span&gt;(){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; ResponseEntity 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;status&lt;/span&gt;(401) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;header&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;javaweb&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;h1&amp;gt;Hello ResponseEntity&amp;lt;/h1&amp;gt;&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="案例"&gt;案例
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//UserController&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 用户信息Controller 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * */&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserController&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@RequestMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/list&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;User&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;list&lt;/span&gt;() &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; FileNotFoundException { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//加载并读取user.txt &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; InputStream in &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getClass&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;getClassLoader&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;getResourceAsStream&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;user.txt&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; lines &lt;span style="color:#f92672"&gt;=&lt;/span&gt; IoUtil.&lt;span style="color:#a6e22e"&gt;readLines&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (in, StandardCharsets.&lt;span style="color:#a6e22e"&gt;UTF_8&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;()); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//解析用户信息，封装为User对象，list集合 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;User&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; userList &lt;span style="color:#f92672"&gt;=&lt;/span&gt; lines.&lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;map&lt;/span&gt;(line &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; parts &lt;span style="color:#f92672"&gt;=&lt;/span&gt; line.&lt;span style="color:#a6e22e"&gt;split&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;,&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Integer id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Integer.&lt;span style="color:#a6e22e"&gt;parseInt&lt;/span&gt;(parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;0&lt;span style="color:#f92672"&gt;]&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String username &lt;span style="color:#f92672"&gt;=&lt;/span&gt; parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String password &lt;span style="color:#f92672"&gt;=&lt;/span&gt; parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;2&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;3&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Integer age &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Integer.&lt;span style="color:#a6e22e"&gt;parseInt&lt;/span&gt;(parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;4&lt;span style="color:#f92672"&gt;]&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; LocalDateTime updateTime &lt;span style="color:#f92672"&gt;=&lt;/span&gt; LocalDateTime.&lt;span style="color:#a6e22e"&gt;parse&lt;/span&gt;(parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;5&lt;span style="color:#f92672"&gt;]&lt;/span&gt;, DateTimeFormatter.&lt;span style="color:#a6e22e"&gt;ofPattern&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;yyyy-MM-dd HH:mm:ss&amp;#34;&lt;/span&gt;)); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; User(id, username, password, name, age, updateTime); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }).&lt;span style="color:#a6e22e"&gt;toList&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//返回数据json &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; userList; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//User&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Data&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@NoArgsConstructor&lt;/span&gt; &lt;span style="color:#75715e"&gt;// &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@AllArgsConstructor&lt;/span&gt; &lt;span style="color:#75715e"&gt;//全参 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;User&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; Integer id; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String username; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String password; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String name; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; Integer age; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; LocalDateTime updateTime; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;1.静态资源文件存放位置&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;resources/static&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2.@ResponseBody 注解的作用&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;将 controller 方法的返回值直接写入 HTTP 响应体&lt;/li&gt;
&lt;li&gt;如果是对象或集合，会先转为 json，再响应&lt;/li&gt;
&lt;li&gt;@RestController = @Controller + @ResponseBody&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h1 id="分层解耦"&gt;分层解耦
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;耦合:&lt;/strong&gt; 衡量软件中各个层/各个模块的依赖关联程度。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;内聚:&lt;/strong&gt; 软件中各个功能模块内部的功能联系。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;设计原则： 高内聚低耦合&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="三层架构"&gt;三层架构
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;层次名称&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;对应英文&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;核心注解&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;职责描述（通俗理解）&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;控制层&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Controller&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;@RestController&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;门面&lt;/strong&gt;。负责接收请求、校验参数，并把结果响应给前端。它不负责处理业务。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;业务逻辑层&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Service&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;@Service&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;大脑&lt;/strong&gt;。负责所有的计算、逻辑判断、事务管理。它是系统最核心的部分。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;数据访问层&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;dao&lt;/strong&gt;(Data Access Object)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;@Repository&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;搬运工&lt;/strong&gt;。负责与数据库打交道，进行增删改查（CRUD）。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="controller"&gt;Controller
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 用户信息Controller 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * */&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserController&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; UserService userService &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; UserServiceImpl(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;多态的实现&lt;span style="color:#f92672"&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@RequestMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/list&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;User&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;list&lt;/span&gt;() &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; FileNotFoundException { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;User&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; list &lt;span style="color:#f92672"&gt;=&lt;/span&gt; userService.&lt;span style="color:#a6e22e"&gt;findAll&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;多态的实现&lt;span style="color:#f92672"&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; list; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="service"&gt;Service
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//接口&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserService&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; *查询所有用户信息 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * */&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;User&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;findAll&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//实现类&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//带impl就是一个实现类 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserServiceImpl&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; UserService { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; UserDao userDao &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; UserDaoImpl(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;*&lt;/span&gt;多态的实现&lt;span style="color:#f92672"&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;User&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;findAll&lt;/span&gt;() { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; lines &lt;span style="color:#f92672"&gt;=&lt;/span&gt; userDao.&lt;span style="color:#a6e22e"&gt;findAll&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;多态的实现&lt;span style="color:#f92672"&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;User&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; userList &lt;span style="color:#f92672"&gt;=&lt;/span&gt; lines.&lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;map&lt;/span&gt;(line &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; parts &lt;span style="color:#f92672"&gt;=&lt;/span&gt; line.&lt;span style="color:#a6e22e"&gt;split&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;,&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Integer id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Integer.&lt;span style="color:#a6e22e"&gt;parseInt&lt;/span&gt;(parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;0&lt;span style="color:#f92672"&gt;]&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String username &lt;span style="color:#f92672"&gt;=&lt;/span&gt; parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String password &lt;span style="color:#f92672"&gt;=&lt;/span&gt; parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;2&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;3&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Integer age &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Integer.&lt;span style="color:#a6e22e"&gt;parseInt&lt;/span&gt;(parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;4&lt;span style="color:#f92672"&gt;]&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; LocalDateTime updateTime &lt;span style="color:#f92672"&gt;=&lt;/span&gt; LocalDateTime.&lt;span style="color:#a6e22e"&gt;parse&lt;/span&gt;(parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;5&lt;span style="color:#f92672"&gt;]&lt;/span&gt;, DateTimeFormatter.&lt;span style="color:#a6e22e"&gt;ofPattern&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;yyyy-MM-dd HH:mm:ss&amp;#34;&lt;/span&gt;)); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; User(id, username, password, name, age, updateTime); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }).&lt;span style="color:#a6e22e"&gt;toList&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; userList; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="dao"&gt;Dao
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//接口&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserDao&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 加载用户数据 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * */&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;findAll&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//实现类&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserDaoImpl&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; UserDao { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;findAll&lt;/span&gt;() { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; InputStream in &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getClass&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;getClassLoader&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;getResourceAsStream&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;user.txt&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; lines &lt;span style="color:#f92672"&gt;=&lt;/span&gt; IoUtil.&lt;span style="color:#a6e22e"&gt;readLines&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (in, StandardCharsets.&lt;span style="color:#a6e22e"&gt;UTF_8&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;()); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; lines; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="Web-3.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;
&lt;img src="Web-4.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h2 id="控制反转ioc-依赖注入di-bean对象"&gt;控制反转（IOC）&amp;amp; 依赖注入（DI）&amp;amp; Bean对象
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;对象的创建控制权由程序自身转移到外部(容器)，这种思想称为控制反转&lt;/li&gt;
&lt;li&gt;容器为应用程序提供运行时，所依赖的资源，称之为依赖注入&lt;/li&gt;
&lt;li&gt;IOC容器中创建、管理的对象，称之为Bean
&lt;img src="Web-5.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;
&lt;img src="Web-6.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ioc详解"&gt;IOC详解
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;如何将一个类交给 IOC 容器管理？&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@Component&lt;/code&gt;（注意：是加在实现类上，而非接口上）&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;如何从 IOC 容器中找到该类型的 bean，然后完成依赖注入？&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@Autowired&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;@Component时声明bean的基础注解
其他三个是@Component的衍生注解&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;注解&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;适用层级&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;语义描述&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;@Component&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;通用组件&lt;/td&gt;
					&lt;td&gt;不属于以下三类时，用此注解（如工具类、配置类）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;@Controller&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;标注在&lt;strong&gt;控制层类&lt;/strong&gt; (Web)&lt;/td&gt;
					&lt;td&gt;负责处理 HTTP 请求，分发数据。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;@Service&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;标注在&lt;strong&gt;业务逻辑层类&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;负责核心业务逻辑处理、事务管理。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;@Repository&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;标注在&lt;strong&gt;数据访问层类&lt;/strong&gt; (Dao)&lt;/td&gt;
					&lt;td&gt;负责数据库的增删改查，并能将原生数据库异常转为 Spring 异常。（由于与&lt;a class="link" href="MySQL/JDBC%20&amp;amp;%20Mybatis.md#Mybatis" &gt;mybatis&lt;/a&gt;整合，用的少）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;[!warning]
❗：@RestController 注解内部已经包含 @Controller&lt;/p&gt;
&lt;p&gt;❗：声明bean的时候，可以通过注解的value属性指定bean的名字，如果没有指定，默认为类名首字母小写&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="Web-7.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h3 id="di详解"&gt;DI详解
&lt;/h3&gt;&lt;h4 id="基于autowired进行依赖注入的常见方式"&gt;基于@Autowired进行依赖注入的常见方式
&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;①.属性注入&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;这是最常见、最简洁的方式。直接在成员变量上加上 &lt;code&gt;@Autowired&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserController&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	&lt;span style="color:#a6e22e"&gt;@Autowired&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; UserService userService; &lt;span style="color:#75715e"&gt;// 直接注入&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：代码极其简洁，可读性好。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;缺点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;不能使用 &lt;code&gt;final&lt;/code&gt; 修饰变量&lt;/strong&gt;（因为变量必须在对象实例化后通过反射注入）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;隐藏依赖关系&lt;/strong&gt;：外部不通过反射很难看到这个类到底依赖了谁。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;违背单一职责原则&lt;/strong&gt;：因为写起来太简单，容易导致一个类注入了过多的依赖。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;②.构造器注入&lt;/strong&gt;—Spring官方推荐&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;通过类的构造函数来完成注入。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Service&lt;/span&gt; &lt;span style="color:#75715e"&gt;//将当前类给IOC容器管理 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserServiceImpl&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; UserService { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; UserDao userDao; &lt;span style="color:#75715e"&gt;//可以是final&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Autowired&lt;/span&gt; &lt;span style="color:#75715e"&gt;//可省略！&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserServiceImpl&lt;/span&gt;(UserDao userDao) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;userDao&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; userDao; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;支持 &lt;code&gt;final&lt;/code&gt; 关键字&lt;/strong&gt;：保证了依赖在对象创建后不可变，更加安全。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;完全初始化&lt;/strong&gt;：确保对象在被调用前，所有依赖都已就绪。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;易于测试&lt;/strong&gt;：在写单元测试时，可以直接通过 &lt;code&gt;new&lt;/code&gt; 一个对象并传入 Mock 依赖，不需要启动整个 Spring 容器。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：如果类中只有一个构造函数，Spring 4.3 以后可以省略 &lt;code&gt;@Autowired&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;③.Setter方法注入&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;通过对应的 &lt;code&gt;setXxx&lt;/code&gt; 方法来注入依赖。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserController&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; UserService userService; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Autowired&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;setUserService&lt;/span&gt;(UserService userService) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;userService&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; userService; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：允许依赖在之后被修改（灵活性高）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;缺点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;不能使用 &lt;code&gt;final&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;对象在被使用时可能处于“未完全初始化”的状态（如果没调用 set 方法）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;对比：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;注入方式&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;是否推荐&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;支持 final&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;优点&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;缺点&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;属性注入&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;慎用&lt;/td&gt;
					&lt;td&gt;否&lt;/td&gt;
					&lt;td&gt;简单、快&lt;/td&gt;
					&lt;td&gt;依赖关系不透明，不方便单元测试&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;构造器注入&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;强烈推荐&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;是&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;安全、强制初始化、方便测试&lt;/td&gt;
					&lt;td&gt;代码略显冗长&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Setter 注入&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;可选&lt;/td&gt;
					&lt;td&gt;否&lt;/td&gt;
					&lt;td&gt;灵活，可按需注入&lt;/td&gt;
					&lt;td&gt;无法保证对象完整性&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h4 id="当出现多个相同类型的bean就会报错如何解决"&gt;当出现多个相同类型的Bean就会报错，如何解决？
&lt;/h4&gt;&lt;p&gt;&lt;img src="Web-8.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;
&lt;strong&gt;①使用 @Primary&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果你希望在大多数情况下都使用某个特定的实现类，可以在该类上加上 &lt;code&gt;@Primary&lt;/code&gt; 注解。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;效果&lt;/strong&gt;：当存在多个候选 Bean 时，Spring 会优先注入标注了 &lt;code&gt;@Primary&lt;/code&gt; 的那一个&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-JAVA" data-lang="JAVA"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Primary&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserServiceImpl1&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; UserService { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// ... &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserServiceImpl2&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; UserService { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// ... &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;②使用@Qualifier(指定具体的名称)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果你想在不同的地方注入不同的实现，可以配合 &lt;code&gt;@Autowired&lt;/code&gt; 使用 &lt;code&gt;@Qualifier&lt;/code&gt;，并指定 Bean 的名称。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;注意&lt;/strong&gt;：Bean 的默认名称是&lt;strong&gt;类名首字母小写&lt;/strong&gt;（如 &lt;code&gt;userServiceImpl1&lt;/code&gt;），你也可以在注解中手动指定名称，如 &lt;code&gt;@Service(&amp;quot;userService2&amp;quot;)&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserController&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Autowired&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Qualifier&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;userServiceImpl1&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// 明确告诉 Spring：我要这一个&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; UserService userService;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;③使用@Resource(直接按名称查找)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;@Resource&lt;/code&gt; 是 JDK 提供的注解（Spring 也支持）。
它与 &lt;code&gt;@Autowired&lt;/code&gt; 的最大区别在于&lt;strong&gt;查找顺序&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@Autowired&lt;/code&gt;&lt;/strong&gt;：先按&lt;strong&gt;类型&lt;/strong&gt;找，如果类型有多个，再按名称找。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@Resource&lt;/code&gt;&lt;/strong&gt;：先按&lt;strong&gt;名称&lt;/strong&gt;找，如果名称找不到，再按类型找。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserController&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Resource&lt;/span&gt;(name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;userServiceImpl2&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// 直接通过名字“精准定位”&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; UserService userService;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;解决方案&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;核心原理&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;@Primary&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;权重优先&lt;/td&gt;
					&lt;td&gt;存在一个“绝对主流”的实现类时。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;@Qualifier&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;类型&lt;/strong&gt; + 名称辅助&lt;/td&gt;
					&lt;td&gt;需要在不同类中灵活切换不同实现时。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;@Resource&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;名称&lt;/strong&gt;优先&lt;/td&gt;
					&lt;td&gt;想减少对 Spring 注解的依赖，或更倾向于按名字查找时。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="问题"&gt;问题
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;问：“既然没有代码显式调用构造函数，Spring 是如何实现注入的？”&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这是通过 &lt;strong&gt;IoC 容器&lt;/strong&gt; 的生命周期管理实现的。Spring 启动时会解析 &lt;strong&gt;BeanDefinition&lt;/strong&gt;（Bean 的定义信息）。如果发现是构造器注入，Spring 会通过 &lt;strong&gt;反射&lt;/strong&gt; 查找匹配的参数 Bean，并利用 &lt;code&gt;Constructor.newInstance()&lt;/code&gt; 方法完成实例化。这种方式将对象的创建权交给了容器，实现了真正的控制反转。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;问：“如果你在代码里同时用了 &lt;code&gt;@Primary&lt;/code&gt; 和 &lt;code&gt;@Qualifier&lt;/code&gt;，谁会生效？”&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“&lt;strong&gt;&lt;code&gt;@Qualifier&lt;/code&gt; 的优先级更高&lt;/strong&gt;。因为 &lt;code&gt;@Primary&lt;/code&gt; 定义的是默认的首选 Bean，而 &lt;code&gt;@Qualifier&lt;/code&gt; 是在注入点进行的‘精准指名’。这就好比食堂默认提供大米饭（Primary），但你明确跟打饭阿姨说你要面条（Qualifier），阿姨肯定会给你面条。”&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="附录"&gt;附录
&lt;/h1&gt;&lt;h2 id="状态码大全"&gt;&lt;a class="link" href="https://cloud.tencent.com/developer/article/2138076" target="_blank" rel="noopener"
 &gt;状态码大全&lt;/a&gt;
&lt;/h2&gt;</description></item><item><title>Maven</title><link>https://creat.asia/post/maven/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/maven/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-10&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;用于管理和构建Java项目的工具&lt;/li&gt;
&lt;li&gt;拥有本地仓库，中央仓库，远程仓库（私服）&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="-生命周期"&gt;* 生命周期
&lt;/h1&gt;&lt;p&gt;Maven 的工作是有固定逻辑顺序的
&lt;strong&gt;只需要执行一个命令，它会自动执行之前的所有步骤&lt;/strong&gt;：（前提：同一生命周期）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;clean&lt;/strong&gt;：清理旧的编译文件（删掉 &lt;code&gt;target&lt;/code&gt; 目录）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;compile&lt;/strong&gt;：编译源代码&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;test&lt;/strong&gt;：运行单元测试&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;package&lt;/strong&gt;：打包（生成可执行的 Jar 包）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;install&lt;/strong&gt;：把打好的包安装到&lt;strong&gt;本地仓库&lt;/strong&gt;，让其他项目也能引用它&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="坐标"&gt;坐标
&lt;/h1&gt;&lt;p&gt;在 Maven 中，&lt;strong&gt;坐标（Coordinates）&lt;/strong&gt; 是用来唯一标识一个 Jar 包（插件或项目）的地址&lt;/p&gt;
&lt;h2 id="坐标的核心组成gav"&gt;坐标的核心组成（GAV）
&lt;/h2&gt;&lt;p&gt;一个最基本的坐标由三个核心部分组成，简称 &lt;strong&gt;GAV&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;groupId&lt;/code&gt; (团体/组织 ID)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;含义&lt;/strong&gt;：定义当前项目隶属的实际项目或组织。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;命名习惯&lt;/strong&gt;：通常是公司域名的倒写。例如：&lt;code&gt;com.google&lt;/code&gt;、&lt;code&gt;org.apache&lt;/code&gt;、&lt;code&gt;com.alibaba&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;artifactId&lt;/code&gt; (项目 ID)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;含义&lt;/strong&gt;：该组织下的某个具体模块或项目的名称。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;命名习惯&lt;/strong&gt;：通常是项目名。例如：&lt;code&gt;spring-boot-starter-web&lt;/code&gt;、&lt;code&gt;mysql-connector-java&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;version&lt;/code&gt; (版本)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;含义&lt;/strong&gt;：当前项目的版本号。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;常见格式&lt;/strong&gt;：&lt;code&gt;1.0.0-RELEASE&lt;/code&gt;（正式版）或 &lt;code&gt;2.1.5-SNAPSHOT&lt;/code&gt;（开发快照版）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="在pomxml中的样子"&gt;在&lt;code&gt;pom.xml&lt;/code&gt;中的样子
&lt;/h2&gt;&lt;p&gt;当你去 &lt;strong&gt;Maven 中央仓库&lt;/strong&gt; 搜到一个依赖时，它会给你这样一段坐标代码，你只需把它复制到 &lt;code&gt;dependencies&lt;/code&gt; 标签里：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#f92672"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.mybatis&lt;span style="color:#f92672"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#f92672"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;mybatis&lt;span style="color:#f92672"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#f92672"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.5.13&lt;span style="color:#f92672"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="坐标与目录结构的逻辑顺序"&gt;坐标与目录结构的逻辑顺序
&lt;/h2&gt;&lt;p&gt;坐标不仅仅是几个字母，它直接决定了 Jar 包在&lt;strong&gt;本地仓库&lt;/strong&gt;中的&lt;strong&gt;物理存放路径&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;如果本地仓库路径是 &lt;code&gt;D:\maven_repo&lt;/code&gt;，那么上面 MyBatis 的 Jar 包会被存放在：
&lt;code&gt;D:\maven_repo \ org \ mybatis \ mybatis \ 3.5.13 \ mybatis-3.5.13.jar&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;groupId&lt;/code&gt;&lt;/strong&gt;：中的点（&lt;code&gt;.&lt;/code&gt;）会被转换成文件夹斜杠（&lt;code&gt;\&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;artifactId&lt;/code&gt;&lt;/strong&gt;：是下一级文件夹。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;version&lt;/code&gt;&lt;/strong&gt;：是再下一级文件夹。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="依赖配置"&gt;依赖配置
&lt;/h1&gt;&lt;p&gt;在 Maven 项目中，&lt;strong&gt;依赖配置（Dependency Configuration）&lt;/strong&gt; 是通过 &lt;code&gt;pom.xml&lt;/code&gt; 文件来声明项目运行所需的外部库&lt;/p&gt;
&lt;h2 id="依赖传递与排除-exclusions"&gt;依赖传递与排除 (Exclusions)
&lt;/h2&gt;&lt;p&gt;这是 Maven 解决复用性的核心逻辑：如果引入了 A，而 A 依赖了 B，Maven 会自动把 B 也下载下来。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题&lt;/strong&gt;：如果 A 引入的 B 版本太旧，导致项目报错怎么办？
&lt;strong&gt;解决&lt;/strong&gt;：使用 &lt;code&gt;&amp;lt;exclusions&amp;gt;&lt;/code&gt; 手动切断传递&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.example&lt;span style="color:#f92672"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;library-a&lt;span style="color:#f92672"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.0&lt;span style="color:#f92672"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;exclusions&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;exclusion&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.slf4j&lt;span style="color:#f92672"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;slf4j-log4j12&lt;span style="color:#f92672"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/exclusion&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/exclusions&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="常见配置逻辑顺"&gt;常见配置逻辑顺
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;确定需求&lt;/strong&gt;：比如需要连接 MySQL。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查找坐标&lt;/strong&gt;：在 &lt;a class="link" href="https://mvnrepository.com/" target="_blank" rel="noopener"
 &gt;MVNrepository&lt;/a&gt; 搜索 &lt;code&gt;mysql-connector-java&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;粘贴配置&lt;/strong&gt;：将代码放入 &lt;code&gt;pom.xml&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;刷新 Maven&lt;/strong&gt;：在 IDEA 中点击刷新图标&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查冲突&lt;/strong&gt;：在 IDEA 右侧 Maven 面板查看 &lt;code&gt;Dependencies&lt;/code&gt; 树，确认没有红色的冲突标识&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING] 警告&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果依赖配置变更了，必须要刷新/重新加载&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h1 id="单元测试"&gt;单元测试
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;单元测试 (Unit Testing)&lt;/strong&gt; 是指对软件中的最小可测试单元（在 Java 中通常是一个&lt;strong&gt;类&lt;/strong&gt;或一个&lt;strong&gt;方法&lt;/strong&gt;）进行检查和验证
&lt;img src="Maven-1.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h2 id="为什么要写单元测试"&gt;为什么要写单元测试？
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;快速反馈&lt;/strong&gt;：改完代码秒知对错，不用等启动整个项目或手动点浏览器。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;防止回滚&lt;/strong&gt;：当你重构（修改）旧代码时，单元测试能确保你没有改坏原本正常的功能。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;文档作用&lt;/strong&gt;：好的测试代码本身就是最好的“功能说明书”。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]&lt;/p&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;/blockquote&gt;
&lt;h2 id="junit"&gt;JUnit
&lt;/h2&gt;&lt;h3 id="测试类要求"&gt;测试类要求
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;要求标准&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;存放路径&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;src/test/java&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;必须与业务代码（&lt;code&gt;src/main/java&lt;/code&gt;）分开存放。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;包名结构&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;与被测类包名一致&lt;/td&gt;
					&lt;td&gt;例如被测类在 &lt;code&gt;com.demo.service&lt;/code&gt;，测试类也应在此包下。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;类名规范&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;以 &lt;code&gt;Test&lt;/code&gt; 结尾&lt;/td&gt;
					&lt;td&gt;例如：&lt;code&gt;UserServiceTest.java&lt;/code&gt;（Surefire 插件默认识别规则）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;依赖配置&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;scope&lt;/code&gt; 设为 &lt;code&gt;test&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;确保测试相关的 Jar 包（如 JUnit）不会被打包到生产环境。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="断言assert"&gt;断言&lt;code&gt;assert&lt;/code&gt;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;本质&lt;/strong&gt;：测试逻辑的“裁判”。它对比 &lt;strong&gt;预期值 (Expected)&lt;/strong&gt; 与 &lt;strong&gt;实际值 (Actual)&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;逻辑流&lt;/strong&gt;：&lt;code&gt;执行业务逻辑 -&amp;gt; 获取结果 -&amp;gt; 调用断言方法 -&amp;gt; 判定测试通过/失败&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Test&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;testGenderWithAssert&lt;/span&gt;(){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 UserService userService &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; UserService(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String gender &lt;span style="color:#f92672"&gt;=&lt;/span&gt; userService.&lt;span style="color:#a6e22e"&gt;getGenderByIdCard&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;100000200010011011&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 Assertions.&lt;span style="color:#a6e22e"&gt;assertEquals&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;男&amp;#34;&lt;/span&gt;, gender,&lt;span style="color:#e6db74"&gt;&amp;#34;性别获取逻辑有问题&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;//会检测与结果是否一致&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!PROBLEM]
测试代码中，通常会极力避免手动写 &lt;code&gt;try-catch&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;断言方法&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;assertEquals(exp, act)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;判断两个值是否相等&lt;/td&gt;
					&lt;td&gt;验证计算结果、字符串内容、对象相等。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;assertNotEquals(exp, act)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;判断两个值是否&lt;strong&gt;不&lt;/strong&gt;相等&lt;/td&gt;
					&lt;td&gt;验证更新后的值确实变了。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;assertTrue(condition)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;判断条件是否为 &lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;验证布尔逻辑（如：&lt;code&gt;canAfford&lt;/code&gt; 方法）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;assertFalse(condition)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;判断条件是否为 &lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;验证否定逻辑（如：用户是否未登录）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;assertNull(obj)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;判断对象是否为空&lt;/td&gt;
					&lt;td&gt;验证查询不到数据时的返回。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;assertNotNull(obj)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;判断对象是否不为空&lt;/td&gt;
					&lt;td&gt;验证对象是否成功创建或查询到。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;assertArrayEquals(exp, act)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;判断两个数组是否相等&lt;/td&gt;
					&lt;td&gt;验证列表排序或批量处理后的数组。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Test&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;testGenderWithAssert2&lt;/span&gt;(){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 UserService userService &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; UserService(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String gender &lt;span style="color:#f92672"&gt;=&lt;/span&gt; userService.&lt;span style="color:#a6e22e"&gt;getGenderByIdCard&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;100000200010011011&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//当异常发生的时候 测试能否抛出正确的异常&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 Assertions.&lt;span style="color:#a6e22e"&gt;assertThrows&lt;/span&gt;(IllegalArgumentException.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;,()&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 userService.&lt;span style="color:#a6e22e"&gt;getGenderByIdCard&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;)); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="组合断言"&gt;组合断言
&lt;/h4&gt;&lt;p&gt;当一个测试方法里有多个断言时：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;普通逻辑&lt;/strong&gt;：第一个断言挂了，后面都不跑了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;assertAll 逻辑&lt;/strong&gt;：所有断言都会跑完，最后统一输出哪些挂了。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 笔记示例：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	assertAll(&lt;span style="color:#e6db74"&gt;&amp;#34;用户信息校验&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 () &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; assertEquals(&lt;span style="color:#e6db74"&gt;&amp;#34;男&amp;#34;&lt;/span&gt;, gender),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 () &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; assertEquals(36, age)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="注解annotation"&gt;注解&lt;code&gt;Annotation&lt;/code&gt;
&lt;/h3&gt;&lt;h4 id="生命周期钩子"&gt;生命周期钩子
&lt;/h4&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;注解&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;执行时机&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;强制要求&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;典型用途&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;@BeforeAll&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;所有测试开始前，&lt;strong&gt;只执行一次&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;必须是 &lt;code&gt;static&lt;/code&gt; 方法&lt;/td&gt;
					&lt;td&gt;初始化数据库连接池、启动 Redis 容器。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;@BeforeEach&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;每个&lt;/strong&gt;测试方法执行前都跑一次&lt;/td&gt;
					&lt;td&gt;普通方法&lt;/td&gt;
					&lt;td&gt;重置对象状态、准备 Mock 数据。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;@AfterEach&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;每个&lt;/strong&gt;测试方法执行后都跑一次&lt;/td&gt;
					&lt;td&gt;普通方法&lt;/td&gt;
					&lt;td&gt;清理临时文件、撤销数据库更改。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;@AfterAll&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;所有测试结束后，&lt;strong&gt;只执行一次&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;必须是 &lt;code&gt;static&lt;/code&gt; 方法&lt;/td&gt;
					&lt;td&gt;关闭数据库连接、释放系统资源。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;执行顺序逻辑：&lt;/strong&gt; &lt;code&gt;@BeforeAll&lt;/code&gt; $\rightarrow$ (&lt;code&gt;@BeforeEach&lt;/code&gt; $\rightarrow$ &lt;code&gt;@Test&lt;/code&gt; $\rightarrow$ &lt;code&gt;@AfterEach&lt;/code&gt;) $\times$ N次 $\rightarrow$ &lt;code&gt;@AfterAll&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	before All
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	before each
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	after each
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	before each
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	男
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	after each
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	before each
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#ae81ff"&gt;26&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	after each
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	before each
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	after each
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	after All
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	进程已结束，退出代码为 &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="核心测试与显示"&gt;核心测试与显示
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@Test&lt;/code&gt;&lt;/strong&gt;：最基础的标签，告诉 Maven 这是一个标准的单元测试。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@DisplayName(&amp;quot;描述内容&amp;quot;)&lt;/code&gt;&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;：在 IDEA 的运行面板或测试报告中，显示中文或易读的描述，而不是枯燥的方法名。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;复用性&lt;/strong&gt;：让非技术人员（或一个月后的你）一眼看懂这个测试在测什么&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="参数化测试"&gt;参数化测试
&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;@ParameterizedTest&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;：声明这个方法是一个“参数化测试”，它会多次运行，每次注入不同的值。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;逻辑&lt;/strong&gt;：它必须配合“数据源”注解使用。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@ValueSource&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;/strong&gt;：最简单的&lt;strong&gt;数据源&lt;/strong&gt;，提供一组基本类型的值（如 Strings, Ints）&lt;/li&gt;
&lt;li&gt;身份证性别测试：&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@ParameterizedTest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@ValueSource&lt;/span&gt;(strings &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 				{&lt;span style="color:#e6db74"&gt;&amp;#34;100000200010011021&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 				&lt;span style="color:#e6db74"&gt;&amp;#34;100000200010011032&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 				&lt;span style="color:#e6db74"&gt;&amp;#34;100000200010011051&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 			})
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@DisplayName&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;验证多个男性身份证的识别&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;testGenderWithAssert2&lt;/span&gt;(String idCard){&lt;span style="color:#75715e"&gt;//strings传入idCard&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; UserService userService &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; UserService(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String gender &lt;span style="color:#f92672"&gt;=&lt;/span&gt; userService.&lt;span style="color:#a6e22e"&gt;getGenderByIdCard&lt;/span&gt;(idCard); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Assertions.&lt;span style="color:#a6e22e"&gt;assertEquals&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;男&amp;#34;&lt;/span&gt;,gender); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="总结"&gt;总结
&lt;/h4&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;注解分类&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;注解名称&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;记忆关键词&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;控制流&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;@Before...&lt;/code&gt; / &lt;code&gt;@After...&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;时机控制&lt;/strong&gt;（前置/后置）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;基础&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;@Test&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;入场券&lt;/strong&gt;（标记测试）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;美化&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;@DisplayName&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;别名&lt;/strong&gt;（中文描述）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;高级&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;@ParameterizedTest&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;分身术&lt;/strong&gt;（一法多测）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;数据源&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;@ValueSource&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;数据池&lt;/strong&gt;（提供参数）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;静态限制&lt;/strong&gt;：记住 &lt;code&gt;@BeforeAll&lt;/code&gt; 和 &lt;code&gt;@AfterAll&lt;/code&gt; 必须加 &lt;code&gt;static&lt;/code&gt; 关键字，因为它们在类实例创建之前就要运行。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;依赖冲突&lt;/strong&gt;：如果你在 &lt;code&gt;pom.xml&lt;/code&gt; 里用的是 JUnit 4，这些注解（来自 &lt;code&gt;org.junit.jupiter&lt;/code&gt; 包）是无法识别的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;不要混用&lt;/strong&gt;：通常一个方法要么标 &lt;code&gt;@Test&lt;/code&gt;，要么标 &lt;code&gt;@ParameterizedTest&lt;/code&gt;，不要两个都标。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id="规范"&gt;规范
&lt;/h3&gt;&lt;p&gt;在企业开发规范中，这种写法被称为 &lt;strong&gt;“测试环境准备（Test Fixture Setup）”&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; UserService userService; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@BeforeEach&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;setUp&lt;/span&gt;(){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 userService &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; UserService(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="依赖范围"&gt;依赖范围
&lt;/h1&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;范围 (Scope)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;编译 (main)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;测试 (test)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;运行 (runtime)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;打包&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;典型例子&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;compile&lt;/code&gt;&lt;/strong&gt; (默认)&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;Spring 核心库、Log4j&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;test&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;❌&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;❌&lt;/td&gt;
					&lt;td&gt;❌&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;JUnit 5&lt;/strong&gt;、Mockito&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;provided&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;❌&lt;/td&gt;
					&lt;td&gt;❌&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Servlet API&lt;/strong&gt;、Lombok&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;runtime&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;❌&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;JDBC 驱动实现&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;system&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;本地磁盘上的 Jar 包，&lt;strong&gt;迁移报错&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="详细范围"&gt;详细范围
&lt;/h2&gt;&lt;h3 id="compile编译范围"&gt;compile（编译范围）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;逻辑&lt;/strong&gt;：如果不写 &lt;code&gt;&amp;lt;scope&amp;gt;&lt;/code&gt;，默认就是这个。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;特性&lt;/strong&gt;：全能型。你在写代码、跑测试、部署上线时都需要它。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;复用性&lt;/strong&gt;：它具有&lt;strong&gt;传递性&lt;/strong&gt;（如果你依赖 A，A 依赖 B，那么你的项目也会获得 B）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="-test测试范围"&gt;🔹 test（测试范围）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;逻辑&lt;/strong&gt;：只在 &lt;code&gt;src/test/java&lt;/code&gt; 下的代码中有效。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;为什么要用&lt;/strong&gt;：像 JUnit 这种工具，上线运行代码时根本不需要。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;规范&lt;/strong&gt;：&lt;strong&gt;必须&lt;/strong&gt;给所有测试框架加上 &lt;code&gt;test&lt;/code&gt; 范围，防止线上包由于包含测试类而变得臃肿。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="-provided已提供范围"&gt;🔹 provided（已提供范围）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;逻辑&lt;/strong&gt;：编译时我需要它，但&lt;strong&gt;打包时请不要带上它&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;典型场景&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Servlet API&lt;/strong&gt;：你的代码需要它来编译，但你最终要把项目部署到 Tomcat。Tomcat 已经自带了 Servlet 的 Jar 包，如果你的包里也带一个，就会产生版本冲突。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Lombok&lt;/strong&gt;：编译时生成 Getter/Setter，编译完后就不再需要了。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="-runtime运行时范围"&gt;🔹 runtime（运行时范围）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;逻辑&lt;/strong&gt;：写代码（编译）时不需要，但程序跑起来（运行）时必须有。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;典型场景&lt;/strong&gt;：&lt;strong&gt;数据库驱动（如 MySQL Connector）&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;我们在代码里通常使用 JDK 自带的 &lt;code&gt;java.sql.Connection&lt;/code&gt;（接口），不需要直接调用 MySQL 的具体实现类。只有在程序运行时，Maven 才会加载驱动包来建立真实连接。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="bom"&gt;BOM
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;BOM&lt;/strong&gt; 的全称是 &lt;strong&gt;Bill of Materials&lt;/strong&gt;（物料清单）&lt;/p&gt;
&lt;p&gt;简单来说，BOM 是一个特殊的 &lt;code&gt;pom.xml&lt;/code&gt; 文件，它的核心逻辑不是为了提供代码，而是为了&lt;strong&gt;统一管理依赖的版本号&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="使用bom"&gt;使用BOM
&lt;/h2&gt;&lt;p&gt;在 &lt;code&gt;pom.xml&lt;/code&gt; 中导入 BOM&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;dependencyManagement&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span style="color:#f92672"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-dependencies&lt;span style="color:#f92672"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.2.0&lt;span style="color:#f92672"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;type&amp;gt;&lt;/span&gt;pom&lt;span style="color:#f92672"&gt;&amp;lt;/type&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;import&lt;span style="color:#f92672"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/dependencyManagement&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;引入具体依赖（不写版本号）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span style="color:#f92672"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-web&lt;span style="color:#f92672"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;传统方式&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;使用 BOM&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;版本控制&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;每个模块各自维护，易冲突&lt;/td&gt;
					&lt;td&gt;全局统一，一处修改全线更新&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;配置量&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;每个 &lt;code&gt;&amp;lt;dependency&amp;gt;&lt;/code&gt; 都要写版本&lt;/td&gt;
					&lt;td&gt;只在顶层写一次，子模块极简&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;复用性&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;差，需要反复确认版本号&lt;/td&gt;
					&lt;td&gt;极强，确保所有组件完美兼容&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;稳定性&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;容易出现 Jar 包版本不匹配&lt;/td&gt;
					&lt;td&gt;官方认证的“全家桶”组合，最稳定&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;</description></item><item><title>Vue3 &amp; Ajax.md</title><link>https://creat.asia/post/vue3--ajax/</link><pubDate>Thu, 09 Apr 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/vue3--ajax/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-09&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="vue"&gt;Vue
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;Vue.js&lt;/strong&gt; 是一个用于构建用户界面的 &lt;strong&gt;JavaScript 框架&lt;/strong&gt;。
它最核心的价值在于：&lt;strong&gt;不再需要手动操作 DOM。&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;框架：就是一套完整的项目解决方案，用于快速构建项目&lt;/li&gt;
&lt;li&gt;优点：大大提升前端项目的开发效率
&lt;img src="Vue3%20&amp;amp;%20Ajax-1.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;li&gt;引入Vue模块&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;app&amp;#34;&lt;/span&gt;&amp;gt;{{ message }}&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;module&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;createApp&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;ref&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;https://unpkg.com/vue@3/dist/vue.esm-browser.js&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;createApp&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;setup&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;message&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ref&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Hello Vue!&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }).&lt;span style="color:#a6e22e"&gt;mount&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;#app&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="Vue3%20&amp;amp;%20Ajax-2.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h2 id="指令"&gt;指令
&lt;/h2&gt;&lt;p&gt;&lt;img src="Vue3%20&amp;amp;%20Ajax-3.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h3 id="基础显示指令"&gt;基础显示指令
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;指令&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;v-text&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;更新元素的文本内容&lt;/td&gt;
					&lt;td&gt;类似 &lt;code&gt;innerText&lt;/code&gt;，但通常直接用 &lt;code&gt;{{ }}&lt;/code&gt; 更方便。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;v-html&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;更新元素的 &lt;code&gt;innerHTML&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;内容按 HTML 解析&lt;/strong&gt;。注意：只在信任的内容上使用，防止 XSS 攻击。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;v-once&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;只渲染一次&lt;/td&gt;
					&lt;td&gt;之后即使数据变了，这里也不会更新，用于性能优化。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="条件渲染指令"&gt;条件渲染指令
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;v-if&lt;/code&gt; / &lt;code&gt;v-else-if&lt;/code&gt; / &lt;code&gt;v-else&lt;/code&gt;&lt;/strong&gt;：真正的条件渲染。如果条件为假，元素根本不会被创建（不出现在 DOM 树中）&lt;/p&gt;
&lt;ul&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;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;v-show&lt;/code&gt;&lt;/strong&gt;：通过修改 CSS 的 &lt;code&gt;display: none&lt;/code&gt; 来切换显隐。元素始终存在于 DOM 中&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;原理&lt;/strong&gt;:基于CSS样式display来控制显示与隐藏&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;场景&lt;/strong&gt;:频繁切换显示隐藏的场景&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;场景建议&lt;/strong&gt;：频繁切换显示用 &lt;code&gt;v-show&lt;/code&gt;，运行时条件不大可能改变用 &lt;code&gt;v-if&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="列表渲染指令"&gt;列表渲染指令
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;v-for&lt;/code&gt;&lt;/strong&gt;：基于一个数组来渲染一个列表&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;语法&lt;/strong&gt;：&lt;code&gt;v-for=&amp;quot;(item, index) in list&amp;quot; :key=&amp;quot;item.id&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;item&lt;/code&gt;：当前遍历项&lt;/li&gt;
&lt;li&gt;&lt;code&gt;index&lt;/code&gt;：当前索引（从 0 开始）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;list&lt;/code&gt;：要循环的数组&lt;/li&gt;
&lt;li&gt;&lt;code&gt;:key=&amp;quot;item.id&amp;quot;&lt;/code&gt;：给列表项唯一标识，提升渲染性能&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-HTML" data-lang="HTML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;tbody&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;tr&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v-for&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;(e, index) in empList&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;:key&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;e.id&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;{{index+1}}&amp;lt;/&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;{{e.name}}&amp;lt;/&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;{{e.gender == 1?&amp;#34;男&amp;#34;:&amp;#34;女&amp;#34; }}&amp;lt;/&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;{{e.job}}&amp;lt;/&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;{{e.entrydate}}&amp;lt;/&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;{{e.updatetime}}&amp;lt;/&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;tr&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;tbody&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	empList: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 { &amp;#34;id&amp;#34;: 1,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&amp;#34;name&amp;#34;: &amp;#34;姓名&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&amp;#34;gender&amp;#34;: 1,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&amp;#34;job&amp;#34;: &amp;#34;1&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&amp;#34;entrydate&amp;#34;: &amp;#34;2023-06-09&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&amp;#34;updatetime&amp;#34;: &amp;#34;2024-07-30T14:59:38&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;关键点&lt;/strong&gt;：使用 &lt;code&gt;v-for&lt;/code&gt; 时&lt;strong&gt;必须&lt;/strong&gt;绑定 &lt;code&gt;:key&lt;/code&gt;。这能帮助 Vue 的 Diff 算法精准识别每个节点，提高更新性能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;注意&lt;/strong&gt;：遍历的数组，必须在data中定义;要想让哪个标签循环展示多次，就在哪个标签上使用 v-for 指令。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id="属性绑定与事件监听"&gt;属性绑定与事件监听
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;v-bind&lt;/code&gt; (缩写 &lt;code&gt;:&lt;/code&gt;)&lt;/strong&gt;：动态绑定 HTML 属性。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;img&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v-bind:src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;imageSrc&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;img&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;:src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;imageSrc&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	插值表达式不能在标签内使用
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;v-on&lt;/code&gt; (缩写 &lt;code&gt;@&lt;/code&gt;)&lt;/strong&gt;：绑定事件监听器。
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;完整写法&lt;/strong&gt;：&lt;code&gt;v-on:事件名=&amp;quot;方法名&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;简写形式&lt;/strong&gt;（最常用）：&lt;strong&gt;&lt;code&gt;@事件名=&amp;quot;方法名&amp;quot;&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//HTML
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;button type&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;button&amp;#34;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;@&lt;/span&gt;click&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;search&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;查询&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/&lt;/span&gt;button&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;    &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;button type&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;reset&amp;#34;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;@&lt;/span&gt;click&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;clear&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;清空&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/&lt;/span&gt;button&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//JS
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;methods&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#a6e22e"&gt;search&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			},
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#a6e22e"&gt;clear&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;gender&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;job&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="双向绑定指令表单"&gt;双向绑定指令(表单)
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;v-model&lt;/code&gt;&lt;/strong&gt;：在表单元素（input, select, textarea）上创建双向数据绑定。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;原理&lt;/strong&gt;：它是 &lt;code&gt;v-bind:value&lt;/code&gt; 和 &lt;code&gt;v-on:input&lt;/code&gt; 的语法糖&lt;/p&gt;
&lt;ul&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;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;select&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;gender&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v-model&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;searchForm.gender&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;/&lt;span style="color:#f92672"&gt;select&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;select&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;job&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v-model&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;searchForm.job&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;/&lt;span style="color:#f92672"&gt;select&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	searchForm:{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				name:&amp;#39;&amp;#39;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				gender:&amp;#39;&amp;#39;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				job:&amp;#39;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;                },
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="ajax"&gt;Ajax
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Ajax (Asynchronous JavaScript and XML)&lt;/strong&gt; 是让网页实现“局部刷新”的核心技术。它允许网页在不重新加载整个页面的情况下，从服务器请求数据。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;XML:&lt;/strong&gt; (Extensible Markup Language)可扩展标记语言，本质是一种数据格式，可以用来存储复杂的数据结构。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;数据交换:&lt;/strong&gt; 通过Ajax可以给服务器发送请求，并获取服务器响应的数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;异步交互:&lt;/strong&gt; 可以在不重新加载整个页面的情况下，与服务器交换数据并更新部分网页的技术，如:搜索联想、用户名是否可用的校验等等。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="同步异步"&gt;同步异步
&lt;/h3&gt;&lt;h4 id="同步"&gt;同步
&lt;/h4&gt;&lt;p&gt;浏览器页面在发送请求给服务器，在服务器处理请求的过程中，浏览器页面不能做其他的操作。只能等到服务器响应结束后才能，浏览器页面才能继续做其他的操作
&lt;img src="Vue3%20&amp;amp;%20Ajax-5.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h4 id="异步"&gt;异步
&lt;/h4&gt;&lt;p&gt;浏览器页面发送请求给服务器，在服务器处理请求的过程中，浏览器页面还可以做其他的操作。
&lt;img src="Vue3%20&amp;amp;%20Ajax-6.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h3 id="async--await"&gt;async &amp;amp; await
&lt;/h3&gt;&lt;p&gt;可以通过async、await可以让异步变为同步操作。async就是来声明一个异步方法，await是用来等待异步任务执行&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-JavaScript" data-lang="JavaScript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;search&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//基于axios发送异步请求，请求http://127.0.0.1:5500/json/simple.json，根据条件查询员工列表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;result&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;axios&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`http://127.0.0.1:5500/json/simple.json?name=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;amp;gender=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;gender&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;amp;job=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;job&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;empList&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="axios"&gt;&lt;a class="link" href="https://www.axios-http.cn" target="_blank" rel="noopener"
 &gt;Axios&lt;/a&gt;
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;步骤&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;引入Axios的js文件&lt;/li&gt;
&lt;li&gt;使用Axios发送请求，并获取响应结果
&lt;img src="Vue3%20&amp;amp;%20Ajax-4.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;为了方便，Axios已经为所有支持的请求方法提供了别名&lt;/li&gt;
&lt;li&gt;格式：&lt;code&gt;axios.请求方式(url [,data [, config ]])&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//GET请求
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;    document.&lt;span style="color:#a6e22e"&gt;querySelector&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;#getData&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;onclick&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;        &lt;span style="color:#75715e"&gt;//发出请求后 不会等待服务器返回（异步），而是继续执行后续代码
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;axios&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;https://jsonplaceholder.typicode.com/posts/1&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}).&lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;================================&amp;#39;&lt;/span&gt;);&lt;span style="color:#75715e"&gt;//先输出
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="vue-的生命周期"&gt;Vue 的生命周期
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;阶段&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;状态名 (Vue 2)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;Vue 3 (组合式 API)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;状态描述&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;创建&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;beforeCreate&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;setup&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;实例初始化，无数据&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;created&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;setup&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;数据可用&lt;/strong&gt;，无 DOM&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;挂载&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;beforeMount&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;onBeforeMount&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;虚拟 DOM 已准备好&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;mounted&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;onMounted&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;DOM 已渲染&lt;/strong&gt;（最常用）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;更新&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;beforeUpdate&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;onBeforeUpdate&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;数据变了，页面没变&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;updated&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;onUpdated&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;页面更新完成&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;销毁&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;beforeDestroy&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;onBeforeUnmount&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;清理现场&lt;/strong&gt;（防内存泄漏）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;destroyed&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;onUnmounted&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;完全消失&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;https://unpkg.com/axios/dist/axios.min.js&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;/script&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;module&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 导入 Vue 3 的 createApp 方法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;createApp&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;https://unpkg.com/vue@3/dist/vue.esm-browser.js&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;createApp&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 搜索表单绑定的数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;// 姓名
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;gender&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;// 性别
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;job&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 职位
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 员工列表，表格渲染的数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;empList&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;methods&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 查询方法，点击“查询”按钮或页面加载时调用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;search&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 发送 GET 请求到远程接口，带上表单参数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;axios&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`https://web-server.itheima.net/emps/list?name=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;amp;gender=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;gender&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;amp;job=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;job&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 将返回的员工数组赋值给 empList，页面自动渲染
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;empList&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 控制台输出分隔线，调试用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;================================&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/*
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; result.data：是整个响应体（包含 code、msg、data 等字段）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; result.data.data：才是真正需要的员工数组
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 清空方法，点击“清空”按钮时调用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;clear&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 重置表单
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;gender&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;job&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 重新查询，显示所有数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;search&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 生命周期钩子，页面加载完成后自动查询一次，显示所有数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;mounted&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;search&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }).&lt;span style="color:#a6e22e"&gt;mount&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;#container&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;/script&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>HTML</title><link>https://creat.asia/post/htmlcssjs/</link><pubDate>Tue, 07 Apr 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/htmlcssjs/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-07&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="html"&gt;HTML
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;HyperText Markup Language&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;HTML 不是一种编程语言，而是一种&lt;strong&gt;标记语言&lt;/strong&gt;（Markup Language）。它通过一系列“标签”来描述网页的结构，是构建 Web 页面的基石。&lt;/p&gt;
&lt;h2 id="html-核心标签"&gt;HTML 核心标签
&lt;/h2&gt;&lt;p&gt;HTML 是网页的骨架，用于定义页面内容。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;标题标签 (&lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; - &lt;code&gt;&amp;lt;h6&amp;gt;&lt;/code&gt;)&lt;/strong&gt;：用于定义 1 到 6 级标题，数字越小级别越高，字体越大。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;超链接标签 (&lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;href&lt;/code&gt; 属性&lt;/strong&gt;：指定资源访问的 URL 地址。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;target&lt;/code&gt; 属性&lt;/strong&gt;：指定打开链接的位置。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;_self&lt;/code&gt;：在当前页面打开（默认）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;_blank&lt;/code&gt;：在新的空白页面打开。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="表单"&gt;表单
&lt;/h2&gt;&lt;h3 id="表单容器-form"&gt;表单容器 &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;所有表单控件必须放在 &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; 标签内，它负责定义数据提交的方向和方式。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;action&lt;/code&gt;&lt;/strong&gt;: 服务器接收数据的 URL 地址。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;method&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;GET&lt;/code&gt;: 数据跟在 URL 后面，适合搜索、查询（安全性低，有长度限制）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;POST&lt;/code&gt;: 数据放在请求体中，适合注册、上传文件（安全性高，无长度限制）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	form表单&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	action&lt;span style="color:#960050;background-color:#1e0010"&gt;：表单数据提交的&lt;/span&gt;url地址
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	method&lt;span style="color:#960050;background-color:#1e0010"&gt;：提交方式&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 get&lt;span style="color:#960050;background-color:#1e0010"&gt;：默认，表单数据会出现在&lt;/span&gt;url后面&lt;span style="color:#960050;background-color:#1e0010"&gt;，形式：&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;save&lt;span style="color:#f92672"&gt;?&lt;/span&gt;name&lt;span style="color:#f92672"&gt;=&lt;/span&gt;Tom&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;age&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;18&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#960050;background-color:#1e0010"&gt;特点：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;．如果表单中包含了隐私数据，&lt;/span&gt;get方式并不安全&lt;span style="color:#960050;background-color:#1e0010"&gt;，不推荐使用该方式．&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;．在浏览器中&lt;/span&gt;get请求的大小是有限制的&lt;span style="color:#960050;background-color:#1e0010"&gt;，不适合提交大数据量的表单．&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 post&lt;span style="color:#960050;background-color:#1e0010"&gt;：表单数据会在消息体&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;请求体中提交到服务器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#960050;background-color:#1e0010"&gt;特点：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;．安全．&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;．请求大小没有限制&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#960050;background-color:#1e0010"&gt;注意：表单项要想能够采集数据，必须得设置&lt;/span&gt;name属性&lt;span style="color:#960050;background-color:#1e0010"&gt;，表示当前表单项的名字&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="表单项"&gt;表单项
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; 标签 (点击文字也能选中)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;极力推荐使用&lt;/strong&gt;。它能通过 &lt;code&gt;for&lt;/code&gt; 属性绑定到对应的 &lt;code&gt;input&lt;/code&gt; 的 &lt;code&gt;id&lt;/code&gt; 上。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;好处&lt;/strong&gt;：点击“用户名”这三个字，光标也会跳进输入框，对移动端非常友好。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;code&gt;name&lt;/code&gt; 属性 (后端唯一标识)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;这是表单项最核心的属性&lt;/strong&gt;。后端程序只认 &lt;code&gt;name&lt;/code&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 &lt;em&gt;比喻：&lt;code&gt;name&lt;/code&gt; 是变量名，用户输入的是变量值。没写 &lt;code&gt;name&lt;/code&gt;，后端就收不到这个项的数据。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start="3"&gt;
&lt;li&gt;&lt;code&gt;value&lt;/code&gt; 属性 (初始值/提交值)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;对于文本框：它是默认填好的文字。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;对于单选/复选框：它是选中后传给后端的“暗号”。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="input"&gt;&lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;
&lt;/h4&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;常用 Type&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;视觉效果&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;text&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;单行输入框&lt;/td&gt;
					&lt;td&gt;用户名、地址&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;password&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;掩盖输入内容&lt;/td&gt;
					&lt;td&gt;密码、敏感信息&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;radio&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;圆形选择点&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;单选&lt;/strong&gt;（必须设置相同 &lt;code&gt;name&lt;/code&gt; 才能互斥）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;checkbox&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;方形勾选框&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;多选&lt;/strong&gt;（如爱好、协议确认）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;file&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;文件选择按钮&lt;/td&gt;
					&lt;td&gt;上传头像、文档&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;submit&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;提交按钮&lt;/td&gt;
					&lt;td&gt;确认并发送整个表单&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="select--option"&gt;&lt;code&gt;&amp;lt;select&amp;gt; &amp;amp; &amp;lt;option&amp;gt;&lt;/code&gt;
&lt;/h4&gt;&lt;p&gt;用于在有限的空间里提供大量选项。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;select&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &amp;lt;&lt;span style="color:#f92672"&gt;option&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;bj&amp;#34;&lt;/span&gt;&amp;gt;北京&amp;lt;/&lt;span style="color:#f92672"&gt;option&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &amp;lt;&lt;span style="color:#f92672"&gt;option&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;sh&amp;#34;&lt;/span&gt;&amp;gt;上海&amp;lt;/&lt;span style="color:#f92672"&gt;option&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;/&lt;span style="color:#f92672"&gt;select&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="textarea"&gt;&lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt;
&lt;/h4&gt;&lt;p&gt;用于输入大量文字（如自我介绍、评价），支持换行。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="表格"&gt;表格
&lt;/h2&gt;&lt;p&gt;HTML 表格是由行（Row）组成的，行里面再拆分单元格（Cell）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt;&lt;/strong&gt;: 表格的容器。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;tr&amp;gt;&lt;/code&gt;&lt;/strong&gt; (Table Row): 定义一行。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;th&amp;gt;&lt;/code&gt;&lt;/strong&gt; (Table Header): &lt;strong&gt;表头&lt;/strong&gt;单元格。文字默认加粗、居中。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;td&amp;gt;&lt;/code&gt;&lt;/strong&gt; (Table Data): &lt;strong&gt;普通&lt;/strong&gt;单元格。承载具体内容。
为了让长表格更易读、更符合标准，建议使用以下标签：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;标签&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;thead&amp;gt;&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;包裹表头部分（通常是第一行）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;tbody&amp;gt;&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;包裹表格主体（数据部分）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;tfoot&amp;gt;&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;包裹表格页脚（如合计行）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;caption&amp;gt;&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;表格的标题，紧跟在 &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; 之后。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="单元格合并"&gt;单元格合并
&lt;/h3&gt;&lt;p&gt;这是表格布局中最常用的技巧，用于处理复杂的表头或跨行数据。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;colspan&lt;/code&gt; (跨列)&lt;/strong&gt;：将多个单元格水平合并。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;rowspan&lt;/code&gt; (跨行)&lt;/strong&gt;：将多个单元格垂直合并。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="页脚"&gt;页脚
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;**&amp;lt;footer&amp;gt;&lt;/code&gt; (页面页脚)**&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;tfoot&amp;gt; &lt;/code&gt;(表格页脚)&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;所属父级&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; 或 &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;主要功能&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;放置版权、导航、作者信息&lt;/td&gt;
					&lt;td&gt;放置表格数据的合计、平均值&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;出现频率&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;一个页面通常只有一个主 &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;每个表格可以有一个 &lt;code&gt;&amp;lt;tfoot&amp;gt;&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;布局技巧&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;常配合 CSS 固定在页面底部&lt;/td&gt;
					&lt;td&gt;常配合 &lt;code&gt;colspan&lt;/code&gt; 合并单元格&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h1 id="css"&gt;CSS
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;Cascading Style Sheets&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CSS 负责网页的&lt;strong&gt;表现（Presentation）&lt;/strong&gt;。如果说 HTML 是建筑的骨架，那么 CSS 就是装修、油漆和家具布局。它通过选择器定位 HTML 元素，并应用样式属性。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="css-引入方式"&gt;CSS 引入方式
&lt;/h2&gt;&lt;p&gt;CSS 用于美化 HTML 页面，主要有三种引入手段：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;行内样式 (Inline Styles)&lt;/strong&gt;：直接写在标签的 &lt;code&gt;style&lt;/code&gt; 属性中，优先级最高但不易维护。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;内部样式表 (Internal Style Sheet)&lt;/strong&gt;：写在 &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; 标签内的 &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; 标签中，适用于单页样式。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;外部样式表 (External Style Sheet)&lt;/strong&gt;：&lt;strong&gt;推荐做法&lt;/strong&gt;。通过 &lt;code&gt;&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;路径.css&amp;quot;&amp;gt;&lt;/code&gt; 引入独立的 &lt;code&gt;.css&lt;/code&gt; 文件，实现结构与表现分离。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="颜色表示"&gt;颜色表示
&lt;/h2&gt;&lt;h3 id="十六进制颜色值"&gt;十六进制颜色值
&lt;/h3&gt;&lt;p&gt;这是目前网页开发中最常用的表达方式&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;格式&lt;/strong&gt;：&lt;code&gt;#RRGGBB&lt;/code&gt;（前缀为 &lt;code&gt;#&lt;/code&gt;，后面跟着三组十六进制数）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;原理&lt;/strong&gt;：使用十六进制（0-9, A-F）分别定义红 (Red)、绿 (Green)、蓝 (Blue) 三原色的强度。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;示例&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;#FFFFFF&lt;/code&gt;：纯白色。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;#000000&lt;/code&gt;：纯黑色。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rgb-与-rgba-模式"&gt;RGB 与 RGBA 模式
&lt;/h3&gt;&lt;p&gt;直接通过数字定义三原色的混合比例，更符合计算机颜色的底层逻辑。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;RGB 格式&lt;/strong&gt;：&lt;code&gt;rgb(红色值, 绿色值, 蓝色值)&lt;/code&gt;。每个数值范围是 &lt;code&gt;0-255&lt;/code&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;示例&lt;/em&gt;：&lt;code&gt;rgb(231, 76, 60)&lt;/code&gt; 等同于十六进制的 &lt;code&gt;#e74c3c&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;RGBA 格式&lt;/strong&gt;：&lt;code&gt;rgba(r, g, b, alpha)&lt;/code&gt;。多了一个 &lt;code&gt;alpha&lt;/code&gt; 通道用于控制&lt;strong&gt;透明度&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;alpha&lt;/code&gt; 取值范围是 &lt;code&gt;0&lt;/code&gt;（完全透明）到 &lt;code&gt;1&lt;/code&gt;（完全不透明）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;示例&lt;/em&gt;：&lt;code&gt;rgba(52, 152, 219, 0.5)&lt;/code&gt; 表示 50% 透明度的蓝色。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="选择器"&gt;选择器
&lt;/h2&gt;&lt;h3 id="基本选择器"&gt;基本选择器
&lt;/h3&gt;&lt;p&gt;这是最常用、最基础的选择方法。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;标签选择器 (1)&lt;/strong&gt;：通过 HTML 标签名选择。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;p { color: red; }&lt;/code&gt;（选中页面上所有的 &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; 标签）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;类选择器 (10)&lt;/strong&gt;：选择具有特定 &lt;code&gt;class&lt;/code&gt; 属性的元素。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;.highlight { background: yellow; }&lt;/code&gt;（选中所有 &lt;code&gt;class=&amp;quot;highlight&amp;quot;&lt;/code&gt; 的元素）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ID 选择器 (100)&lt;/strong&gt;：选择具有特定 &lt;code&gt;id&lt;/code&gt; 属性的唯一元素。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;#header { font-size: 24px; }&lt;/code&gt;（选中 &lt;code&gt;id=&amp;quot;header&amp;quot;&lt;/code&gt; 的元素）。&lt;strong&gt;注意：一个 ID 在 HTML 页面中应该是唯一的。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;通配符选择器 (0)&lt;/strong&gt;：选择页面上的所有元素。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;* { margin: 0; padding: 0; }&lt;/code&gt;（常用于重置页面默认边距）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="复合选择器"&gt;复合选择器
&lt;/h3&gt;&lt;p&gt;用于更精确地定位元素。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;后代选择器 (Descendant Selector)&lt;/strong&gt;：选择某个元素内部的所有指定后代。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;.container p { ... }&lt;/code&gt;（选中 &lt;code&gt;.container&lt;/code&gt; 内部所有的 &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; 标签，无论嵌套多深）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;子元素选择器 (Child Selector)&lt;/strong&gt;：仅选择某个元素的直接子元素。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;.container &amp;gt; p { ... }&lt;/code&gt;（只选中 &lt;code&gt;.container&lt;/code&gt; 下的第一层 &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt;）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;并集选择器 (Grouping Selector)&lt;/strong&gt;：同时给多个选择器设置相同的样式。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;h1, h2, .title { ... }&lt;/code&gt;（用逗号分隔）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="伪类选择器"&gt;伪类选择器
&lt;/h3&gt;&lt;p&gt;用于选择元素的特定&lt;strong&gt;状态&lt;/strong&gt;，常用于交互效果。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;:hover&lt;/code&gt;&lt;/strong&gt;：鼠标悬停在元素上的状态。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;a:hover { text-decoration: underline; }&lt;/code&gt;（鼠标移上去显示下划线）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;:active&lt;/code&gt;&lt;/strong&gt;：元素被激活（鼠标点击按下）的状态。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;:nth-child(n)&lt;/code&gt;&lt;/strong&gt;：选择父元素中的第 n 个子元素。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;li:nth-child(2) { color: blue; }&lt;/code&gt;（选中列表中的第二项）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="属性选择器"&gt;属性选择器
&lt;/h3&gt;&lt;p&gt;根据 HTML 标签的属性来选择，这在处理你之前提到的 &lt;code&gt;contest.xml&lt;/code&gt; 这种结构化数据转换成的 HTML 时非常有用。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;[type=&amp;quot;text&amp;quot;] { border: 1px solid #ccc; }&lt;/code&gt;（选中所有 &lt;code&gt;type&lt;/code&gt; 属性为 &lt;code&gt;text&lt;/code&gt; 的输入框）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="选择器的优先级"&gt;选择器的优先级
&lt;/h3&gt;&lt;p&gt;当多个选择器指向同一个元素并设置相同属性时，浏览器会根据“权重”来决定听谁的：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;行内样式 (&lt;code&gt;style=&amp;quot;...&amp;quot;&lt;/code&gt;)&lt;/strong&gt;：权重最高 (1000)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ID 选择器 (&lt;code&gt;#id&lt;/code&gt;)&lt;/strong&gt;：权重高 (100)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;类、伪类、属性选择器 (&lt;code&gt;.class&lt;/code&gt;)&lt;/strong&gt;：权重中 (10)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;标签选择器 (&lt;code&gt;div&lt;/code&gt;, &lt;code&gt;p&lt;/code&gt;)&lt;/strong&gt;：权重低 (1)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;通配符 (&lt;code&gt;*&lt;/code&gt;)&lt;/strong&gt;：权重最低 (0)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;原则&lt;/strong&gt;：描述得越精准，权重越高。如果权重相同，则&lt;strong&gt;后写的样式&lt;/strong&gt;会覆盖先写的样式。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="正文样式"&gt;正文样式
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;属性&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;功能说明&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;常见取值示例&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;color&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;设置字体颜色&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;#e74c3c&lt;/code&gt; (十六进制), &lt;code&gt;rgba(0,0,0,0.8)&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;font-size&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;设置字体大小&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;16px&lt;/code&gt;, &lt;code&gt;1rem&lt;/code&gt;, &lt;code&gt;1.2em&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;line-height&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;设置行高（行间距）&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;1.5&lt;/code&gt;, &lt;code&gt;1.6&lt;/code&gt; (通常为字号的倍数)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;letter-spacing&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;设置字间距&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;1px&lt;/code&gt;, &lt;code&gt;2px&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;text-indent&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;首行缩进&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;2em&lt;/code&gt; (缩进两个字符)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;text-align&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;文本对齐方式&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;left&lt;/code&gt;, &lt;code&gt;center&lt;/code&gt;, &lt;code&gt;right&lt;/code&gt;, &lt;code&gt;justify&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="盒子模型"&gt;盒子模型
&lt;/h2&gt;&lt;p&gt;在 CSS 中，所有的 HTML 元素都可以看作是一个矩形的“盒子”。
这个盒子由内到外由四个部分（区域）组成。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;内容 (Content)&lt;/strong&gt;：盒子的核心，显示文本、图片等实际内容。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;内边距 (Padding)&lt;/strong&gt;：内容与边框之间的透明区域。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;边框 (Border)&lt;/strong&gt;：围绕在内边距和内容外的线。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;外边距 (Margin)&lt;/strong&gt;：边框外的区域，用于控制元素与其它元素之间的距离。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="HTML&amp;amp;CSS&amp;amp;JS-1.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;通过 &lt;code&gt;box-sizing&lt;/code&gt; 属性切换计算逻辑，这是最容易出错的地方：&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="标准盒子模型-content-box"&gt;标准盒子模型 (&lt;code&gt;content-box&lt;/code&gt;)
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;特性&lt;/strong&gt;：&lt;code&gt;width&lt;/code&gt; 只等于 &lt;strong&gt;Content&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;总宽度公式&lt;/strong&gt;：&lt;code&gt;Width + Padding*2 + Border*2&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;结果&lt;/strong&gt;：加了边框或内边距，盒子会被“撑大”。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="怪异盒子模型-border-box"&gt;怪异盒子模型 (&lt;code&gt;border-box&lt;/code&gt;)
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;特性&lt;/strong&gt;：&lt;code&gt;width&lt;/code&gt; 等于 &lt;strong&gt;Content + Padding + Border&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;总宽度公式&lt;/strong&gt;：等于你设置的 &lt;code&gt;Width&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;结果&lt;/strong&gt;：加了边框或内边距，内容区会“向内压缩”，盒子总尺寸不变。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="布局"&gt;布局
&lt;/h2&gt;&lt;h3 id="布局标签"&gt;布局标签
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;1.&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; 标签 (Division) —— 块级容器&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; 是 &amp;ldquo;division&amp;rdquo;（部分、分区）的缩写，用于定义文档中的一个区块。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;显示特性&lt;/strong&gt;：&lt;strong&gt;块级元素 (Block-level)&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;默认情况下，它会独占一行（宽度默认铺满父容器 100%）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;它可以设置宽度 (&lt;code&gt;width&lt;/code&gt;)、高度 (&lt;code&gt;height&lt;/code&gt;)、内边距 (&lt;code&gt;padding&lt;/code&gt;) 和外边距 (&lt;code&gt;margin&lt;/code&gt;)。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;常用场景&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;划分页面的大区域（如：页眉、导航栏、内容区、页脚）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;作为 CSS 布局（如 Flex 或 Grid）的父容器。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;示例&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-HTML" data-lang="HTML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;team-card&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;h2&lt;/span&gt;&amp;gt;Alpha Team&amp;lt;/&lt;span style="color:#f92672"&gt;h2&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;积分：1500&amp;lt;/&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="HTML&amp;amp;CSS&amp;amp;JS-2.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; 标签 —— 行内容器&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; 用于组合文档中的行内元素，以便通过 CSS 修改局部样式。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;显示特性&lt;/strong&gt;：&lt;strong&gt;行内元素 (Inline)&lt;/strong&gt;。
&lt;ul&gt;
&lt;li&gt;它不会换行，只会占据内容所需的宽度，与其他文本排在同一行。&lt;/li&gt;
&lt;li&gt;默认情况下，设置宽高属性无效。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;常用场景&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;修改一段文字中某个词的颜色、字号或字体。&lt;/li&gt;
&lt;li&gt;在一行内放置小图标或状态标签。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;示例&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-HTML" data-lang="HTML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;队伍 T001 的状态是 &amp;lt;&lt;span style="color:#f92672"&gt;span&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;style&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;color: green;&amp;#34;&lt;/span&gt;&amp;gt;AC&amp;lt;/&lt;span style="color:#f92672"&gt;span&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;特性&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;元素类型&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;块级元素 (Block)&lt;/td&gt;
					&lt;td&gt;行内元素 (Inline)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;占用空间&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;独占一行，默认宽度 100%&lt;/td&gt;
					&lt;td&gt;随内容变化，不换行&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;嵌套规则&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;可以包含其它 &lt;code&gt;div&lt;/code&gt; 或 &lt;code&gt;span&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;只能包含文本或其它行内元素&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;布局用途&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;构建网页骨架、容器&lt;/td&gt;
					&lt;td&gt;局部修饰、修饰行内小部件&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="flex布局"&gt;flex布局
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;flex是flexible Box的缩写，意为&amp;quot;弹性布局&amp;quot;，是一种一维的布局模型。flex布局可以为元素之间提供强大的空间分布和对齐能力。&lt;/li&gt;
&lt;li&gt;通过给&lt;strong&gt;父容器&lt;/strong&gt;添加flex的相关属性,来控制&lt;strong&gt;子元素的位置和排列方式&lt;/strong&gt;，&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;理解 Flex 的关键在于明白它有两个轴：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;主轴 (Main Axis)&lt;/strong&gt;：默认是水平方向（从左到右）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;交叉轴 (Cross Axis)&lt;/strong&gt;：默认是垂直方向（从上到下）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以通过 &lt;code&gt;flex-direction&lt;/code&gt; 来交换这两个轴。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;属性&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;常用取值&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;justify-content&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;控制子元素在 &lt;strong&gt;主轴&lt;/strong&gt;（横向）上的对齐&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;center&lt;/code&gt;, &lt;code&gt;space-between&lt;/code&gt;, &lt;code&gt;flex-end&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;align-items&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;控制子元素在 &lt;strong&gt;交叉轴&lt;/strong&gt;（纵向）上的对齐&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;center&lt;/code&gt;, &lt;code&gt;flex-start&lt;/code&gt;, &lt;code&gt;stretch&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;flex&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;控制子元素如何 &lt;strong&gt;分配剩余空间&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;1&lt;/code&gt; (平分), &lt;code&gt;2&lt;/code&gt; (占两份)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src="HTML&amp;amp;CSS&amp;amp;JS-3.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;flex布局相关的CSS样式&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;属性&lt;/th&gt;
					&lt;th style="text-align: left"&gt;说明&lt;/th&gt;
					&lt;th style="text-align: left"&gt;取值&lt;/th&gt;
					&lt;th style="text-align: left"&gt;含义&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;display&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;模式&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;flex&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;使用 flex 布局&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;flex-direction&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;设置主轴&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;row&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;主轴方向为 x 轴，水平向右（默认）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;column&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;主轴方向为 y 轴，垂直向下&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;justify-content&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;子元素在主轴上的对齐方式&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;flex-start&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;从头开始排列&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;flex-end&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;从尾部开始排列&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;center&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;在主轴居中对齐&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;space-around&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;平分剩余空间&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;space-between&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;先两边贴边，再平分剩余空间&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h1 id="html--css总览"&gt;HTML &amp;amp; CSS总览
&lt;/h1&gt;&lt;p&gt;&lt;img src="HTML&amp;amp;CSS&amp;amp;JS-4.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;
&lt;img src="HTML&amp;amp;CSS&amp;amp;JS-5.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="javascript"&gt;JavaScript
&lt;/h1&gt;&lt;h2 id="组成"&gt;组成
&lt;/h2&gt;&lt;h3 id="1-ecmascript-核心语法"&gt;1. ECMAScript (核心语法)
&lt;/h3&gt;&lt;p&gt;这是 JavaScript 的&lt;strong&gt;大脑&lt;/strong&gt;，定义了语言的基础规则。它不涉及浏览器，只规定语法。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;包含内容&lt;/strong&gt;：变量声明 (&lt;code&gt;var&lt;/code&gt;, &lt;code&gt;let&lt;/code&gt;, &lt;code&gt;const&lt;/code&gt;)、数据类型、流程控制 (if/else, for)、函数、类 (Class)、对象等。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;标准制定者&lt;/strong&gt;：由 ECMA 国际组织负责更新（如 ES6, ES2023）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;通俗理解&lt;/strong&gt;：就像汉语的语法字典，规定了怎么造句，但不规定这些句子是在书里还是在墙上。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="2-dom-文档对象模型"&gt;2. DOM (文档对象模型)
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;DOM (Document Object Model)&lt;/strong&gt; 是 JavaScript 操作网页内容的&lt;strong&gt;手脚&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;功能&lt;/strong&gt;：将 HTML 页面抽象为一棵“树”。JS 通过 DOM 接口可以增、删、改、查网页上的任何标签、属性和样式。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;常见操作&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;document.getElementById()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;修改文字内容 (&lt;code&gt;innerText&lt;/code&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;修改 CSS 样式 (&lt;code&gt;style.display = 'none'&lt;/code&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;通俗理解&lt;/strong&gt;：把 HTML 页面看作一间屋子，DOM 就是家具的控制面板，让你能随时换个沙发或者关上灯。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="3-bom-浏览器对象模型"&gt;3. BOM (浏览器对象模型)
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;BOM (Browser Object Model)&lt;/strong&gt; 是 JavaScript 与浏览器软件本身对话的&lt;strong&gt;窗口&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;功能&lt;/strong&gt;：提供与浏览器窗口交互的对象，不涉及页面内部的具体内容。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;包含内容&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;window&lt;/code&gt;&lt;/strong&gt;: 顶层对象（所有 JS 全局变量都在这里）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;location&lt;/code&gt;&lt;/strong&gt;: 获取或设置当前页面的 URL。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;navigation&lt;/code&gt;&lt;/strong&gt;: 获取浏览器信息（版本、系统等）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;history&lt;/code&gt;&lt;/strong&gt;: 操作浏览器的前进和后退。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;screen&lt;/code&gt;&lt;/strong&gt;: 获取屏幕分辨率。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;通俗理解&lt;/strong&gt;：它是浏览器的外壳控制，比如弹出一个警告框 (&lt;code&gt;alert&lt;/code&gt;) 或开启一个新的标签页。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="引入方式"&gt;引入方式
&lt;/h2&gt;&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;h3 id="行内引入"&gt;行内引入
&lt;/h3&gt;&lt;p&gt;直接将 JS 代码写在 HTML 标签的事件属性中（如 &lt;code&gt;onclick&lt;/code&gt;）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-HTML" data-lang="HTML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;button&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;onclick&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;alert(&amp;#39;你点击了按钮！&amp;#39;)&amp;#34;&lt;/span&gt;&amp;gt;点击我&amp;lt;/&lt;span style="color:#f92672"&gt;button&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：简单、快速，用于极少量的交互。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;缺点&lt;/strong&gt;：代码与 HTML 耦合度过高，极难维护，&lt;strong&gt;不推荐使用&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="内部引入"&gt;内部引入
&lt;/h3&gt;&lt;p&gt;将代码写在 HTML 文档的 &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 标签内。通常放在 &lt;code&gt;&amp;lt;/body&amp;gt;&lt;/code&gt; 标签之前。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;代码示例&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-HTML" data-lang="HTML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&amp;lt;&lt;span style="color:#f92672"&gt;h1&lt;/span&gt;&amp;gt;标题&amp;lt;/&lt;span style="color:#f92672"&gt;h1&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;title&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; document.&lt;span style="color:#a6e22e"&gt;querySelector&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;h1&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;title&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;innerText&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;/&lt;span style="color:#f92672"&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：不需要额外创建文件，适合单个页面的简短脚本。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;缺点&lt;/strong&gt;：如果脚本过长，会使 HTML 文件变得臃肿，无法在多个页面间复用代码。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="外部引入推荐"&gt;外部引入&amp;ndash;推荐
&lt;/h3&gt;&lt;p&gt;将 JS 代码写在独立的 &lt;code&gt;.js&lt;/code&gt; 文件中，通过 &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 标签的 &lt;code&gt;src&lt;/code&gt; 属性引入。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HTML 部分&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-HTML" data-lang="HTML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;js/main.js&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;JS 部分 (main.js)&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-JavaScript" data-lang="JavaScript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;alert&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;这是来自外部文件的代码&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;代码复用&lt;/strong&gt;：多个网页可以引用同一个 JS 文件。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;结构清晰&lt;/strong&gt;：HTML 只负责结构，JS 负责逻辑，各司其职。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;缓存优化&lt;/strong&gt;：浏览器会缓存外部 JS 文件，提高页面加载速度。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="基础语法"&gt;基础语法
&lt;/h2&gt;&lt;h3 id="1-变量声明-variables"&gt;1. 变量声明 (Variables)
&lt;/h3&gt;&lt;p&gt;在现代 JS 中，我们使用 &lt;code&gt;let&lt;/code&gt; 和 &lt;code&gt;const&lt;/code&gt; 来代替过时的 &lt;code&gt;var&lt;/code&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;const&lt;/code&gt;&lt;/strong&gt;: 声明&lt;strong&gt;常量&lt;/strong&gt;。一旦赋值，不能修改。优先使用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;let&lt;/code&gt;&lt;/strong&gt;: 声明&lt;strong&gt;变量&lt;/strong&gt;。值可以被重新覆盖。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-JavaScript" data-lang="JavaScript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;pi&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3.14&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 不可变
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;score&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 可变
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;score&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 允许
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="2-数据类型-data-types"&gt;2. 数据类型 (Data Types)
&lt;/h3&gt;&lt;p&gt;JS 的数据分为“简单”和“复杂”两类。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;分类&lt;/th&gt;
					&lt;th style="text-align: left"&gt;数据类型&lt;/th&gt;
					&lt;th style="text-align: left"&gt;英文&lt;/th&gt;
					&lt;th style="text-align: left"&gt;说明 &amp;amp; 示例&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;基本类型&lt;/td&gt;
					&lt;td style="text-align: left"&gt;数字&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;number&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;数字（10, 3.14）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;字符串&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;string&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;字符串&lt;code&gt;(&amp;quot;Hello&amp;quot;, 'Hi')&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;布尔&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;boolean&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;布尔（true, false）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;空值&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;空值,&lt;code&gt;null != Null != NULL&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;未定义&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;该变量未初始化&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;引用类型&lt;/td&gt;
					&lt;td style="text-align: left"&gt;对象&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;object&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;对象，用 {} 表示，存储键值对&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;数组&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;array&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;数组，用 [] 表示，存储有序列表&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;使用&lt;code&gt;typeof&lt;/code&gt;运算符可以获取数据类型
&lt;code&gt;typeof a -&amp;gt; number&lt;/code&gt;
避免使用 &lt;code&gt;var&lt;/code&gt;，否则变量可能在声明前被访问而导致 &lt;code&gt;undefined&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING] 注意&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;由字母、数字、下划线 &lt;code&gt;_&lt;/code&gt;、美元符 &lt;code&gt;$&lt;/code&gt; 组成&lt;/li&gt;
&lt;li&gt;不能以数字开头&lt;/li&gt;
&lt;li&gt;严格区分大小写&lt;/li&gt;
&lt;li&gt;不能是 JavaScript 关键字或保留字&lt;/li&gt;
&lt;li&gt;建议见名知意，语义清晰&lt;/li&gt;
&lt;li&gt;推荐使用小驼峰命名法，第一个单词小写，后面单词首字母大写&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h4 id="模板字符串"&gt;模板字符串
&lt;/h4&gt;&lt;p&gt;三种功能&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;变量嵌入
通过 &lt;code&gt;${}&lt;/code&gt; 语法，可以直接在字符串中插入变量或表达式，不再需要用大量的 &lt;code&gt;+&lt;/code&gt; 号&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Gemini&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;version&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3.0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 旧版写法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;你好，我是 &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;，当前版本是 &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;version&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 模板字符串写法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`你好，我是 &lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;，当前版本是 &lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;version&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;多行字符串
在传统字符串中，换行需要使用 &lt;code&gt;\n&lt;/code&gt;。而在模板字符串中，可以直接按回车键换行&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 自动保留换行格式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;htmlTemplate&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;	 &amp;lt;div&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;	 &amp;lt;h1&amp;gt;标题&amp;lt;/h1&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;	 &amp;lt;p&amp;gt;内容段落&amp;lt;/p&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;	 &amp;lt;/div&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;	`&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;嵌入表达式
&lt;code&gt;${}&lt;/code&gt; 内部不仅可以放变量，还可以进行运算、调用函数或逻辑判断。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;price&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;tax&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`总价是：&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;price&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; (&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;tax&lt;/span&gt;)&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt; 元`&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 运算
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`状态：&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;price&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;50&lt;/span&gt; &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;昂贵&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;便宜&amp;#39;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 三元运算
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!tip]
如果在模板字符串中需要显示反引号本身，请使用转义符：&lt;code&gt;` \` `&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;如果在模板字符串中需要显示 &lt;code&gt;${}&lt;/code&gt; 原样字符，也需要转义：&lt;code&gt;\${}&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="函数"&gt;函数
&lt;/h2&gt;&lt;p&gt;在 &lt;code&gt;JavaScript&lt;/code&gt; 中，&lt;strong&gt;函数（Function）&lt;/strong&gt; 是执行特定任务的可重复调用的代码块。它是程序中最基本的“逻辑单元”。&lt;/p&gt;
&lt;h3 id="函数声明-function-declaration"&gt;函数声明 (Function Declaration)
&lt;/h3&gt;&lt;p&gt;最传统、最常用的方式。具有“声明提升”特性（可以在声明前调用）。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;greet&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`你好, &lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;!`&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;greet&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;张三&amp;#34;&lt;/span&gt;)); &lt;span style="color:#75715e"&gt;// 调用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="匿名函数"&gt;匿名函数
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;匿名函数（Anonymous Function）&lt;/strong&gt; 是指在定义时&lt;strong&gt;没有函数名称&lt;/strong&gt;的函数。在 JavaScript 中，它们通常作为“工具人”使用，在需要的地方临时定义并立即执行或传递。&lt;/p&gt;
&lt;h4 id="函数表达式-function-expression"&gt;函数表达式 (Function Expression)
&lt;/h4&gt;&lt;p&gt;将函数赋值给一个变量。没有提升特性。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;add&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="箭头函数-arrow-function--现代主流"&gt;箭头函数 (Arrow Function) —— &lt;strong&gt;现代主流&lt;/strong&gt;
&lt;/h4&gt;&lt;p&gt;ES6 引入的简洁写法。注意：它没有自己的 &lt;code&gt;this&lt;/code&gt;，适合用作回调函数。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;multiply&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;) =&amp;gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
由于匿名函数没有名字，在复杂的报错调试（Debug）时，错误堆栈里可能只显示 &lt;code&gt;anonymous&lt;/code&gt;，找起 Bug 来会比具名函数稍微麻烦一点。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="自定义对象"&gt;自定义对象
&lt;/h2&gt;&lt;p&gt;在 JavaScript 中，&lt;strong&gt;自定义对象（Custom Objects）&lt;/strong&gt; 是将相关数据（属性）和行为（方法）组织在一起的容器。它是 JS 模拟现实世界实体（如：用户、商品、订单）的核心方式。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;对象名&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;属性名1&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;属性值1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;属性名2&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;属性值2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;属性名3&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;属性值3&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;方法名&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;形参列表&lt;/span&gt;){}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 调用格式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;对象名&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;属性名&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;对象名&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;方法名&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="字面量方式常用"&gt;字面量方式（常用）
&lt;/h3&gt;&lt;p&gt;直接用大括号 &lt;code&gt;{}&lt;/code&gt; 定义，适合创建一个独立、唯一的对象&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;phone&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;brand&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;华为&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;model&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Mate 60&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;price&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;5999&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;// 方法：对象中的函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;call&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {&lt;span style="color:#75715e"&gt;//不推荐使用箭头函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;正在拨打电话...&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="构造函数"&gt;构造函数
&lt;/h3&gt;&lt;p&gt;当需要批量创建多个结构相似的对象时（如 100 个学生），使用构造函数
&lt;strong&gt;约定&lt;/strong&gt;：函数名首字母大写&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Student&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;age&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;age&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;age&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;study&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt; 正在学习`&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;s1&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Student&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;小明&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;18&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;s2&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Student&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;小红&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;19&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="类"&gt;类
&lt;/h3&gt;&lt;p&gt;ES6 引入的语法糖，逻辑更清晰，接近 Java/C# 的风格&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Car&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;constructor&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;color&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;speed&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;color&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;color&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;speed&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;speed&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;drive&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`这辆&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;color&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;的车正在以&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;speed&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;码行驶`&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;myCar&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Car&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;白色&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;120&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="json"&gt;JSON
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;JSON (JavaScript Object Notation)&lt;/strong&gt; 是一种轻量级的&lt;strong&gt;数据交换格式&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;它基于 JavaScript 的一个子集，但它是独立于语言的文本格式，目前几乎所有的编程语言（Python, Java, PHP, Go 等）都支持 JSON&lt;/p&gt;
&lt;h2 id="语法规则"&gt;语法规则
&lt;/h2&gt;&lt;p&gt;JSON 的结构非常简单，主要由&lt;strong&gt;键值对&lt;/strong&gt;组成。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;数据在键值对中&lt;/strong&gt;：键（Key）必须用&lt;strong&gt;双引号&lt;/strong&gt;包裹。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;数据由逗号分隔&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;对象&lt;/strong&gt;由大括号 &lt;code&gt;{}&lt;/code&gt; 保存。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;数组&lt;/strong&gt;由方括号 &lt;code&gt;[]&lt;/code&gt; 保存。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="数据类型"&gt;数据类型
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;示例&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;字符串&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;&amp;quot;Hello World&amp;quot;&lt;/code&gt; (必须双引号)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;数字&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;123&lt;/code&gt;, &lt;code&gt;45.6&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;布尔值&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;true&lt;/code&gt;, &lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;数组&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;[&amp;quot;Apple&amp;quot;, &amp;quot;Orange&amp;quot;]&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;对象&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;{&amp;quot;id&amp;quot;: 1, &amp;quot;name&amp;quot;: &amp;quot;Gemini&amp;quot;}&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;空值&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;⚠️ &lt;strong&gt;注意&lt;/strong&gt;：JSON &lt;strong&gt;不能&lt;/strong&gt;包含函数、日期对象或 &lt;code&gt;undefined&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="javascript-中的-json-操作"&gt;JavaScript 中的 JSON 操作
&lt;/h2&gt;&lt;p&gt;&lt;img src="HTML&amp;amp;CSS&amp;amp;JS-6.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// JSON.parse() 当从服务器收到一段 JSON 字符串时，需要用它将其解析为 JS 对象。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;jsonStr&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;{&amp;#34;name&amp;#34;: &amp;#34;小明&amp;#34;, &amp;#34;age&amp;#34;: 18}&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;parse&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;jsonStr&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 输出: 小明
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// JSON.stringify() 当准备把数据发送给服务器时，需要将 JS 对象转换为 JSON 字符串。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;user&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;小明&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;age&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;18&lt;/span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;jsonString&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;stringify&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;user&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;jsonString&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 输出: &amp;#39;{&amp;#34;name&amp;#34;:&amp;#34;小明&amp;#34;,&amp;#34;age&amp;#34;:18}&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="dom"&gt;DOM
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;DOM (Document Object Model)&lt;/strong&gt;，即文档对象模型，是 JavaScript 操作网页内容的“桥梁”
它将 HTML 文档表现为一个&lt;strong&gt;树状结构&lt;/strong&gt;，让我们可以通过脚本动态地修改页面的内容、结构和样式。
&lt;img src="HTML&amp;amp;CSS&amp;amp;JS-7.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h2 id="dom操作"&gt;DOM操作
&lt;/h2&gt;&lt;p&gt;根据CSS选择器获取DOM对象&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;document.querySelector('选择器')&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;：返回匹配到的&lt;strong&gt;第一个&lt;/strong&gt;对象。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;示例&lt;/strong&gt;：&lt;code&gt;document.querySelector('.my-class')&lt;/code&gt; 或 &lt;code&gt;document.querySelector('#my-id p')&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;document.querySelectorAll('选择器')&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;：返回匹配到的&lt;strong&gt;所有&lt;/strong&gt;对象。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;结果&lt;/strong&gt;：一个 &lt;code&gt;NodeList&lt;/code&gt;（类似数组的集合，可以用 &lt;code&gt;forEach&lt;/code&gt; 遍历）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;注意:得到的是一个NodeList节点集合，是一个伪数组(有长度、有索引的数组)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;方法&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;获取依据&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;返回值类型&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getElementById('id')&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;唯一 ID&lt;/td&gt;
					&lt;td&gt;单个对象&lt;/td&gt;
					&lt;td&gt;速度最快，只能找 ID&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getElementsByClassName('class')&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;类名&lt;/td&gt;
					&lt;td&gt;动态集合 (HTMLCollection)&lt;/td&gt;
					&lt;td&gt;实时更新的集合&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;getElementsByTagName('标签名')&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;标签名&lt;/td&gt;
					&lt;td&gt;动态集合 (HTMLCollection)&lt;/td&gt;
					&lt;td&gt;比如找所有的 &lt;code&gt;div&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="事件监听"&gt;事件监听
&lt;/h2&gt;&lt;h3 id="三要素"&gt;三要素
&lt;/h3&gt;&lt;p&gt;可以把事件监听想象成一个&lt;strong&gt;报警系统&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;事件源 (Target)&lt;/strong&gt;：谁触发了事件？（比如：一个 &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; 按钮）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;事件源.addEventListener('事件类型',事件触发执行的函数);&lt;/code&gt;可以多次绑定同一事件&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;早期版本写法:&lt;code&gt;事件源.on事件=function{}&lt;/code&gt;如果多次绑定同一事件，就会&lt;strong&gt;覆盖&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;事件类型 (Type)&lt;/strong&gt;：发生了什么事？（比如：&lt;code&gt;click&lt;/code&gt; 点击）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;事件处理程序 (Handler)&lt;/strong&gt;：要做什么？（通常是一个&lt;strong&gt;回调函数&lt;/strong&gt;）&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;分类&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;事件名&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;触发时机&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;鼠标事件&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;click&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;鼠标点击&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;mouseenter&lt;/code&gt; / &lt;code&gt;mouseleave&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;鼠标移入 / 移出&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;键盘事件&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;keydown&lt;/code&gt; / &lt;code&gt;keyup&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;按键按下 / 松开&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;表单事件&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;input&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;输入内容改变时（实时）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;change&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;内容改变并失去焦点时&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;submit&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;表单提交时&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;窗口事件&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;load&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;整个页面加载完成&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;scroll&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;页面滚动&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="js优化"&gt;JS优化
&lt;/h2&gt;&lt;p&gt;&lt;img src="HTML&amp;amp;CSS&amp;amp;JS-8.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;</description></item><item><title>基础</title><link>https://creat.asia/post/%E5%9F%BA%E7%A1%80/</link><pubDate>Tue, 07 Apr 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/%E5%9F%BA%E7%A1%80/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-09&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="http"&gt;HTTP
&lt;/h1&gt;&lt;p&gt;HTTP 是互联网上应用最为广泛的一种&lt;strong&gt;网络协议&lt;/strong&gt;。它定义了浏览器（客户端）与服务器之间交换数据的格式和规则&lt;/p&gt;
&lt;h2 id="http-的基本特性"&gt;HTTP 的基本特性
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;应用层协议&lt;/strong&gt;：运行在 TCP/IP 协议栈之上（默认端口 80，HTTPS 为 443）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;请求-响应模型&lt;/strong&gt;：必须由客户端发起请求，服务器给出响应。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;无状态 (Stateless)&lt;/strong&gt;：协议本身不保留之前的事务记忆。
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;对策&lt;/em&gt;：在开发中通过 &lt;strong&gt;Cookie/Session&lt;/strong&gt; 或 &lt;strong&gt;JWT (Token)&lt;/strong&gt; 来维持登录状态。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;灵活&lt;/strong&gt;：允许传输任意类型的数据对象，通过 &lt;code&gt;Content-Type&lt;/code&gt; 加以标记。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src="%e5%9f%ba%e7%a1%80-1.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h2 id="http-请求报文结构"&gt;HTTP 请求报文结构
&lt;/h2&gt;&lt;p&gt;一个标准的 HTTP 请求由四部分组成：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;请求行 (Request Line)&lt;/strong&gt;：
&lt;code&gt;Method&lt;/code&gt; + &lt;code&gt;URL&lt;/code&gt; + &lt;code&gt;Version&lt;/code&gt; (如 &lt;code&gt;GET /index.html HTTP/1.1&lt;/code&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;请求头 (Request Headers)&lt;/strong&gt;：键值对格式，描述客户端环境和偏好。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Host&lt;/code&gt;: 目标主机。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;User-Agent&lt;/code&gt;: 浏览器标识。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Accept&lt;/code&gt;: 客户端可接受的内容类型。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;空行&lt;/strong&gt;：必须存在，用于分隔头部和正文。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;请求体 (Request Body)&lt;/strong&gt;：仅 &lt;code&gt;POST/PUT&lt;/code&gt; 等方法使用，存放要提交的数据（如 JSON）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="http-响应报文与状态码"&gt;HTTP 响应报文与状态码
&lt;/h2&gt;&lt;p&gt;响应报文同样由 &lt;strong&gt;状态行&lt;/strong&gt;、&lt;strong&gt;响应头&lt;/strong&gt;、&lt;strong&gt;空行&lt;/strong&gt;、&lt;strong&gt;响应体&lt;/strong&gt; 组成。&lt;/p&gt;
&lt;h4 id="核心状态码分类"&gt;核心状态码分类：
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;2xx (成功)&lt;/strong&gt;：&lt;code&gt;200 OK&lt;/code&gt; (请求成功)。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;3xx (重定向)&lt;/strong&gt;：&lt;code&gt;301&lt;/code&gt; (永久重定向)、&lt;code&gt;302&lt;/code&gt; (临时重定向)。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;4xx (客户端错误)&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;400 Bad Request&lt;/code&gt;: 请求语法错误。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;403 Forbidden&lt;/code&gt;: 服务器拒绝执行。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;404 Not Found&lt;/code&gt;: 资源不存在。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;405 Method Not Allowed&lt;/code&gt;: 方法不支持（如用 GET 访问 POST 接口）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;5xx (服务器错误)&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;500 Internal Server Error&lt;/code&gt;: 后端代码抛出未处理的异常。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;502 Bad Gateway&lt;/code&gt;: 网关从后端收到了非法响应（如 Nginx 找不到 Java 服务）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;504 Gateway Timeout&lt;/code&gt;: 后端处理超时。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="长链接与短链接"&gt;长链接与短链接
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;HTTP&lt;/th&gt;
					&lt;th&gt;应用层协议&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;TCP&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;传输层协议&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ip&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;网络层协议&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;特性&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;短连接 (Short Connection)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;长连接 (Keep-Alive)&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;底层表现&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;一次请求/响应消耗一个 TCP 连接&lt;/td&gt;
					&lt;td&gt;多次请求/响应复用一个 TCP 连接&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;HTTP 版本&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;HTTP/1.0 默认&lt;/td&gt;
					&lt;td&gt;HTTP/1.1 默认&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;HTTP Header&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Connection: close&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Connection: keep-alive&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;握手开销&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;高（每次请求都要三次握手）&lt;/td&gt;
					&lt;td&gt;低（仅首次建立需要）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;服务器压力&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;CPU 压力较大（频繁建立/销毁连接）&lt;/td&gt;
					&lt;td&gt;内存压力较大（需维持空闲连接的 socket）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;偶尔交互的单次请求、请求频率极低的服务&lt;/td&gt;
					&lt;td&gt;Web 页面浏览、前后端高频 API 交互、图片服务器&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;</description></item><item><title>InnoDB引擎</title><link>https://creat.asia/post/innodb%E5%BC%95%E6%93%8E/</link><pubDate>Sun, 05 Apr 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/innodb%E5%BC%95%E6%93%8E/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-05&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;InnoDB 是 MySQL 的默认事务型引擎，也是目前最常用、最强大的存储引擎。它被设计用来处理大量的短期事务，具有高性能和高可用性。&lt;/p&gt;
&lt;h1 id="核心特性"&gt;核心特性
&lt;/h1&gt;&lt;p&gt;InnoDB 的强大源于其四大核心支柱：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;事务支持 (ACID)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;支持事务的原子性、一致性、隔离性和持久性。通过 &lt;strong&gt;Redo Log&lt;/strong&gt;（重做日志）保证持久性，通过 &lt;strong&gt;Undo Log&lt;/strong&gt;（回滚日志）保证原子性。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;行级锁 (Row-level Locking)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不同于 MyISAM 的表级锁，InnoDB 支持行锁，极大提高了多用户并发操作的性能。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;外键约束 (Foreign Key)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;它是 MySQL 中唯一支持外键的内置存储引擎，能够维护数据的参照完整性。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;MVCC (多版本并发控制)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;通过 Read View 和 Undo Log 实现非阻塞读。在“可重复读”隔离级别下，读操作不会加锁，从而提升了并发查询效率。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="逻辑存储结构"&gt;逻辑存储结构
&lt;/h1&gt;&lt;p&gt;InnoDB 将所有数据逻辑地存放在一个名为 &lt;strong&gt;Tablespace&lt;/strong&gt;（表空间）的地方，其结构从大到小依次为：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;表空间 (Tablespace)&lt;/strong&gt;：包含系统表空间（ibdata1）或独立表空间（.ibd）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;段 (Segment)&lt;/strong&gt;：分为数据段（Leaf node segment）、索引段（Non-leaf node segment）等。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;区 (Extent)&lt;/strong&gt;：固定大小为 1MB，由 64 个连续的页组成。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;页 (Page)&lt;/strong&gt;：InnoDB 磁盘管理的最小单位，默认大小为 &lt;strong&gt;16KB&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;行 (Row)&lt;/strong&gt;：InnoDB存储引擎数据是按行进行存放的&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="mysql-innodb-架构"&gt;MySQL InnoDB 架构
&lt;/h1&gt;&lt;p&gt;InnoDB 存储引擎的架构设计主要分为两个部分：
&lt;strong&gt;内存结构 (In-Memory Structures)&lt;/strong&gt; 和 &lt;strong&gt;磁盘结构 (On-Disk Structures)&lt;/strong&gt;。
这种设计旨在平衡高性能（内存操作）与数据持久性（磁盘存储）。&lt;/p&gt;
&lt;h2 id="内存结构-in-memory-structures"&gt;内存结构 (In-Memory Structures)
&lt;/h2&gt;&lt;p&gt;内存池是 InnoDB 性能的核心，其主要组件包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Buffer Pool (缓冲池)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;核心作用&lt;/strong&gt;：缓存磁盘上的真实数据页和索引页。
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;机制&lt;/strong&gt;：读取数据时，若缓冲池有则直接返回；修改数据时，先修改缓冲池中的页（变为“脏页”），再通过 Checkpoint 机制异步刷入磁盘。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;img src="InnoDB%e5%bc%95%e6%93%8e-3.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Change Buffer (写缓冲区)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;针对&lt;strong&gt;非唯一辅助索引&lt;/strong&gt;的优化。当插入或更新辅助索引且该页不在缓冲池时，先记录在 Change Buffer 中，等未来读取该页时再进行合并。&lt;/li&gt;
&lt;li&gt;&lt;img src="InnoDB%e5%bc%95%e6%93%8e-4.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Adaptive Hash Index (自适应哈希索引)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;InnoDB 会监控表上的索引查询，如果观察到某些索引值被频繁访问，会自动建立哈希索引以加速查询（将 B+ 树查询变为 O(1) 查找）&lt;/li&gt;
&lt;li&gt;&lt;img src="InnoDB%e5%bc%95%e6%93%8e-5.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Log Buffer (日志缓冲区)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用于保存准备写入磁盘的 &lt;strong&gt;Redo Log&lt;/strong&gt; 数据。默认大小为 16MB，定期刷入磁盘以保证事务的持久性。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;意义：&lt;/strong&gt; 即使内存里的数据还没来得及写回磁盘就断电了，重启后也能通过磁盘上的 Redo Log 把数据恢复回来。&lt;/li&gt;
&lt;li&gt;&lt;img src="InnoDB%e5%bc%95%e6%93%8e-6.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="磁盘结构-on-disk-structures"&gt;磁盘结构 (On-Disk Structures)
&lt;/h2&gt;&lt;p&gt;磁盘结构确保了数据的物理存储和崩溃恢复能力：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Tablespaces (表空间)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;System Tablespace (系统表空间)&lt;/strong&gt;：存储 InnoDB 数据字典、双写缓冲区等。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;File-Per-Table Tablespaces (独立表空间)&lt;/strong&gt;：每个表对应一个 &lt;code&gt;.ibd&lt;/code&gt; 文件，存储该表的数据和索引&lt;/li&gt;
&lt;li&gt;&lt;img src="InnoDB%e5%bc%95%e6%93%8e-7.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;li&gt;创建表空间&amp;amp;撤销表空间&amp;amp;临时表空间&lt;/li&gt;
&lt;li&gt;&lt;img src="InnoDB%e5%bc%95%e6%93%8e-8.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Doublewrite Buffer (双写缓冲区)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;位于系统表空间的物理存储区。在将页写入数据文件前，先写入此处。用于防止在写入过程中发生断电导致的“页破碎”问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Redo Log (重做日志)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;记录对页的物理修改。当数据库宕机重启，会根据 Redo Log 将未落盘的脏页恢复。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Undo Logs (回滚日志)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;逻辑日志，记录事务变更前的样子。用于&lt;strong&gt;事务回滚&lt;/strong&gt;和 &lt;strong&gt;MVCC&lt;/strong&gt;（实现非阻塞读）。
&lt;img src="InnoDB%e5%bc%95%e6%93%8e-9.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="核心后台线程"&gt;核心后台线程
&lt;/h2&gt;&lt;p&gt;InnoDB 依靠多个后台线程来维持运行：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Master Thread&lt;/strong&gt;：负责将缓冲池数据异步刷新到磁盘，保持数据一致性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IO Thread&lt;/strong&gt;：主要负责 AIO（异步IO）请求的回调处理（分为 Read, Write, Log, Insert Buffer 线程）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Purge Thread&lt;/strong&gt;：事务提交后，负责回收已经不再需要的 Undo Log 页。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Page Cleaner Thread&lt;/strong&gt;：专门负责脏页的刷新工作，减轻 Master Thread 的负担。
&lt;img src="InnoDB%e5%bc%95%e6%93%8e-10.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="架构设计的精髓wal-write-ahead-logging"&gt;架构设计的精髓：WAL (Write-Ahead Logging)
&lt;/h2&gt;&lt;p&gt;InnoDB 遵循 &lt;strong&gt;日志先行策略&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当数据发生变更时，先修改内存（Buffer Pool），并同步记录 Redo Log 到磁盘。&lt;/li&gt;
&lt;li&gt;只要 Redo Log 落地，即使此时内存中的“脏页”还没来得及刷入磁盘，数据库发生崩溃也能通过日志恢复。&lt;/li&gt;
&lt;li&gt;这种将“随机写磁盘”转变为“顺序写日志”的设计，是 InnoDB 高性能读写的基石。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="事务原理"&gt;事务原理
&lt;/h1&gt;&lt;p&gt;事务（Transaction）是逻辑上的一组操作，要么全部成功，要么全部失败。在 InnoDB 引擎中，事务的四大特性（ACID）是通过不同的技术手段共同保障的。&lt;/p&gt;
&lt;h2 id="持久性-durability--redo-log"&gt;持久性 (Durability) — Redo Log
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;定义&lt;/strong&gt;：一旦事务提交，它对数据库的改变就是永久性的，即使系统崩溃也不会丢失。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;实现原理&lt;/strong&gt;：&lt;strong&gt;Redo Log（重做日志）&lt;/strong&gt; 与 &lt;strong&gt;WAL（Write-Ahead Logging）&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;工作机制&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;当数据修改时，InnoDB 先修改 Buffer Pool 中的内存页。&lt;/li&gt;
&lt;li&gt;同时将修改操作记录到 &lt;strong&gt;Redo Log Buffer&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;事务提交时，根据策略将 Redo Log 顺序写入磁盘文件。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Crash Recovery&lt;/strong&gt;：如果数据库宕机，虽然内存里的脏页丢了，但重启后系统会读取磁盘上的 Redo Log，把未落盘的修改“重做”一遍。
&lt;img src="InnoDB%e5%bc%95%e6%93%8e-11.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="原子性-atomicity--undo-log"&gt;原子性 (Atomicity) — Undo Log
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;定义&lt;/strong&gt;：事务是不可分割的最小单位，要么全部完成，要么全部不完成。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;实现原理&lt;/strong&gt;：&lt;strong&gt;Undo Log（回滚日志）&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;工作机制&lt;/strong&gt;：当事务对数据库进行修改时，InnoDB 会生成对应的 Undo Log。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果你执行的是 &lt;code&gt;INSERT&lt;/code&gt;，日志会记录一条对应的 &lt;code&gt;DELETE&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;如果你执行的是 &lt;code&gt;UPDATE&lt;/code&gt;，日志会记录修改前的数据。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;结果&lt;/strong&gt;：如果事务执行失败或调用了 &lt;code&gt;ROLLBACK&lt;/code&gt;，系统会利用 Undo Log 中的逻辑记录将数据恢复到事务开始前的样子。
&lt;img src="InnoDB%e5%bc%95%e6%93%8e-12.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="一致性-consistency"&gt;一致性 (Consistency)
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;定义&lt;/strong&gt;：事务执行前后，数据库的完整性约束没有被破坏，数据从一个一致性状态转移到另一个一致性状态。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;实现原理&lt;/strong&gt;：一致性是事务追求的&lt;strong&gt;最终目标&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;手段&lt;/strong&gt;：它由原子性、隔离性和持久性共同维系，同时也依赖于数据库的完整性约束（如外键、唯一索引、非空限制）以及应用层的逻辑正确性。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="隔离性-isolation--mvcc--锁"&gt;隔离性 (Isolation) — MVCC &amp;amp; 锁
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;定义&lt;/strong&gt;：多个并发事务之间相互隔离，互不干扰。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;实现原理&lt;/strong&gt;：&lt;strong&gt;锁机制&lt;/strong&gt; 与 &lt;strong&gt;MVCC（多版本并发控制）&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工作机制&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;锁&lt;/strong&gt;：处理“写-写”冲突，确保同一时间只有一个事务能修改同一行数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MVCC&lt;/strong&gt;：处理“读-写”冲突。通过在每行记录后面保存隐藏列（事务ID、回滚指针）并结合 &lt;strong&gt;Read View&lt;/strong&gt;，让事务能读取到符合自己隔离级别的数据快照，实现非阻塞读。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="总结acid-实现脑图"&gt;总结：ACID 实现脑图
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;特性&lt;/th&gt;
					&lt;th style="text-align: left"&gt;实现技术&lt;/th&gt;
					&lt;th style="text-align: left"&gt;核心作用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;原子性 (A)&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Undo Log&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;逻辑回滚，确保要么都做，要么都不做。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;隔离性 (I)&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;MVCC + 锁&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;并发控制，确保事务执行不被干扰。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;持久性 (D)&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Redo Log&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;崩溃恢复，确保提交的数据不丢失。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;一致性 (C)&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;上述三者 + 代码逻辑&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;最终目的，确保数据逻辑正确。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;核心提示&lt;/strong&gt;：对于 Java 开发来说，理解 &lt;code&gt;Redo Log&lt;/code&gt;（保证不丢数据）和 &lt;code&gt;Undo Log&lt;/code&gt;（保证能回滚）的区别是面试和调优的关键。&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="mvcc"&gt;MVCC
&lt;/h1&gt;&lt;p&gt;MVCC 全称 &lt;strong&gt;多版本并发控制&lt;/strong&gt; (Multi-Version Concurrency Control)，是 InnoDB 实现隔离级别（读已提交 RC 和 可重复读 RR）的核心技术。
它的核心思想是：&lt;strong&gt;通过保存数据的历史版本，实现“读-写”操作的非阻塞。&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;快照读 (Snapshot Read)：&lt;/strong&gt; 普通的 &lt;code&gt;SELECT&lt;/code&gt; 语句（不加锁）。它读的是记录的“某个版本”，可能是历史数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;当前读 (Current Read)：&lt;/strong&gt; &lt;code&gt;INSERT&lt;/code&gt;、&lt;code&gt;UPDATE&lt;/code&gt;、&lt;code&gt;DELETE&lt;/code&gt; 或 &lt;code&gt;SELECT ... FOR UPDATE&lt;/code&gt;。它必须读取记录的“最新版本”，并且要加锁。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;MVCC 解决的就是“快照读”的问题。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="隐式字段"&gt;隐式字段
&lt;/h2&gt;&lt;p&gt;InnoDB 在每行记录后面都会自动加上三个隐藏列：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;DB_TRX_ID&lt;/strong&gt;：最近修改该记录的事务 ID。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;DB_ROLL_PTR&lt;/strong&gt;：回滚指针，指向该记录的上一个版本（在 Undo Log 中）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;DB_ROW_ID&lt;/strong&gt;：如果表没有主键，InnoDB 会自动生成一个自增 ID（有主键则无此列）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="作用"&gt;作用
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;实现回滚 (Rollback)： 当你执行 ROLLBACK 时，系统通过 DB_ROLL_PTR 找到旧数据，直接覆盖回来。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;实现 MVCC（读写不冲突）： 当事务 A 在改数据（加了排他锁），事务 B 来读。B 会根据自己的 Read View 和记录上的 DB_TRX_ID 判断：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“这个版本是 A 正在改的，我不能看。”于是 B 顺着 DB_ROLL_PTR 去读 Undo Log 里的旧版本。&lt;/li&gt;
&lt;li&gt;结果： 事务 A 慢慢改，事务 B 照样读，互不干扰。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="undo-log版本链"&gt;undo log版本链
&lt;/h2&gt;&lt;p&gt;每当一个事务修改数据时，旧版本的数据会被写入 Undo Log 中。通过 &lt;strong&gt;DB_ROLL_PTR&lt;/strong&gt;，不同事务对同一行记录的修改会形成一个由旧到新的链表。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt; 当前聚簇索引记录 (最新行) &lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;┌─────────────────────────────────────┐&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; 业务字段&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;&lt;/span&gt;王五&lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; 隐藏字段 DB_TRX_ID &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 30 &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; 隐藏字段 DB_ROLL_PTR &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 指针地址 A &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;└───────────────┬─────────────────────┘&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt; 指针指向 Undo Log
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;┌─────────────────────────────┐&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;【&lt;/span&gt;Undo Log 版本1&lt;span style="color:#960050;background-color:#1e0010"&gt;】&lt;/span&gt;A &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; 数据&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;&lt;/span&gt;李四&lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; 事务ID&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;TRX_ID &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 20 &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; 回滚指针&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;指针地址 B &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└───────────────┬─────────────┘&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt; 继续指向上一版本
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;┌─────────────────────┐&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;【&lt;/span&gt;Undo Log 版本2&lt;span style="color:#960050;background-color:#1e0010"&gt;】&lt;/span&gt;B &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; 数据&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;&lt;/span&gt;张三&lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; 事务ID&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;TRX_ID &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 10 &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; 回滚指针&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;NULL &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└─────────────────────┘&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;【&lt;/span&gt;链表结束&lt;span style="color:#960050;background-color:#1e0010"&gt;】&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="InnoDB%e5%bc%95%e6%93%8e-13.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h2 id="read-view一致性视图"&gt;read view(一致性视图)
&lt;/h2&gt;&lt;p&gt;ReadView(读视图)是 &lt;strong&gt;快照读&lt;/strong&gt; SQL执行时MVCC提取数据的依据，记录并维护系统当前活跃的事务(未提交的)id。
它包含四个核心字段：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;m_ids&lt;/strong&gt;：当前活跃（未提交）的事务 ID 列表。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;min_trx_id&lt;/strong&gt;：活跃事务中的最小值。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;max_trx_id&lt;/strong&gt;：预分配给下一个事务的 ID 值，当前最大失误ID+1（事物的ID是自增的）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;creator_trx_id&lt;/strong&gt;：创建该 Read View 的事务 ID。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="版本可见性算法-核心逻辑"&gt;版本可见性算法 (核心逻辑)
&lt;/h2&gt;&lt;p&gt;当一个事务读取某行记录时，它会拿着该行的 &lt;code&gt;DB_TRX_ID&lt;/code&gt; 去和自己的 &lt;code&gt;Read View&lt;/code&gt; 进行比对：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;trx_id == creator_trx_id&lt;/strong&gt;：该版本是我自己改的，&lt;strong&gt;可见&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;trx_id &amp;lt; min_trx_id&lt;/strong&gt;：该版本在 Read View &lt;strong&gt;创建前已提交&lt;/strong&gt;，&lt;strong&gt;可见&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;trx_id &amp;gt;= max_trx_id&lt;/strong&gt;：该版本在 Read View &lt;strong&gt;创建后才开启&lt;/strong&gt;，&lt;strong&gt;不可见&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;min_trx_id &amp;lt;= trx_id &amp;lt; max_trx_id&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;若 &lt;code&gt;trx_id&lt;/code&gt; 在 &lt;code&gt;m_ids&lt;/code&gt; 列表中：说明事务还没提交，&lt;strong&gt;不可见&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;若 &lt;code&gt;trx_id&lt;/code&gt; 不在 &lt;code&gt;m_ids&lt;/code&gt; 列表中：说明事务已提交，&lt;strong&gt;可见&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;如果不可见怎么办？&lt;/strong&gt; 顺着 &lt;code&gt;DB_ROLL_PTR&lt;/code&gt; 回滚指针去找 Undo Log 里的上一个版本，直到找到可见的版本为止。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;MVCC 在 &lt;strong&gt;RC&lt;/strong&gt; 和 &lt;strong&gt;RR&lt;/strong&gt; 级别下的唯一区别在于 &lt;strong&gt;生成 Read View 的时机&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;读已提交 (RC)&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;每次执行 SELECT 语句时&lt;/strong&gt; 都会重新生成一个新的 Read View。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;结果&lt;/em&gt;：可以看到其他事务期间提交的数据（不可重复读）。
&lt;img src="InnoDB%e5%bc%95%e6%93%8e-14.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;属性&lt;/th&gt;
					&lt;th style="text-align: left"&gt;含义&lt;/th&gt;
					&lt;th style="text-align: left"&gt;第一个 ReadView&lt;/th&gt;
					&lt;th style="text-align: left"&gt;第二个 ReadView&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;m_ids&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;当前&lt;strong&gt;活跃&lt;/strong&gt;事务 ID 列表（正在运行的事务）&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;{3, 4, 5}&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;{4, 5}&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;min_trx_id&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;m_ids 中的最小值&lt;/td&gt;
					&lt;td style="text-align: left"&gt;3&lt;/td&gt;
					&lt;td style="text-align: left"&gt;4&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;max_trx_id&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;生成 ReadView 时，系统分配的下一个事务 ID&lt;/td&gt;
					&lt;td style="text-align: left"&gt;6&lt;/td&gt;
					&lt;td style="text-align: left"&gt;6&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;creator_trx_id&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;生成该视图的事务 ID（当前事务 ID）&lt;/td&gt;
					&lt;td style="text-align: left"&gt;5&lt;/td&gt;
					&lt;td style="text-align: left"&gt;5&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;可重复读 (RR)&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;仅在事务第一次执行 SELECT 时&lt;/strong&gt; 生成一个 Read View，后续所有查询共用这一个。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;结果&lt;/em&gt;：整个事务期间看到的数据始终一致（解决了不可重复读，并在很大程度上解决了幻读）。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;img src="InnoDB%e5%bc%95%e6%93%8e-16.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;属性&lt;/th&gt;
					&lt;th style="text-align: left"&gt;值&lt;/th&gt;
					&lt;th style="text-align: left"&gt;含义&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;m_ids&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;{3, 4, 5}&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;生成 ReadView 时，系统中&lt;strong&gt;所有活跃（未提交）事务 ID&lt;/strong&gt;的集合&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;min_trx_id&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;m_ids&lt;/code&gt; 中的最小值&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;max_trx_id&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;6&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;生成 ReadView 时，系统即将分配的下一个事务 ID（比当前所有活跃 ID 都大）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;creator_trx_id&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;5&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;生成这个 ReadView 的事务 ID（也就是事务 5 自己）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src="InnoDB%e5%bc%95%e6%93%8e-17.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="mysql管理"&gt;MySQL管理
&lt;/h1&gt;&lt;h2 id="系统数据库"&gt;系统数据库
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;数据库名&lt;/th&gt;
					&lt;th style="text-align: left"&gt;角色&lt;/th&gt;
					&lt;th style="text-align: left"&gt;常用操作&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;mysql&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;管理员&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;修改用户密码、配置 SSL 证书、调整权限。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;information_schema&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;开发者&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;检查表结构、查找大表、确认字段长度。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;performance_schema&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;DBA / 性能专家&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;深度分析 CPU 尖峰、定位锁等待根源。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;sys&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;运维/开发者&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;快速查看慢查询 Top 10、分析未使用的索引。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="常用工具"&gt;常用工具
&lt;/h2&gt;&lt;h3 id="mysql客户端工具"&gt;mysql客户端工具
&lt;/h3&gt;&lt;p&gt;&lt;img src="InnoDB%e5%bc%95%e6%93%8e-18.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h2 id="mysqlbinlog二进制日志查看工具"&gt;mysqlbinlog二进制日志查看工具
&lt;/h2&gt;&lt;p&gt;&lt;img src="InnoDB%e5%bc%95%e6%93%8e-20.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h2 id="mysqlshow查看数据库表字段的统计信息"&gt;mysqlshow查看数据库、表、字段的统计信息
&lt;/h2&gt;&lt;p&gt;&lt;img src="InnoDB%e5%bc%95%e6%93%8e-21.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h2 id="mysqldump数据备份工具"&gt;mysqldump数据备份工具
&lt;/h2&gt;&lt;p&gt;&lt;img src="InnoDB%e5%bc%95%e6%93%8e-19.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h2 id="mysqlimportsource数据导入工具"&gt;mysqlimport/source数据导入工具
&lt;/h2&gt;&lt;p&gt;&lt;img src="InnoDB%e5%bc%95%e6%93%8e-22.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;</description></item><item><title>JDBC &amp; Mybatis</title><link>https://creat.asia/post/jdbc--mybatis/</link><pubDate>Sun, 05 Apr 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/jdbc--mybatis/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-05&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="api"&gt;API
&lt;/h1&gt;&lt;h2 id="drivermanager-驱动管理类"&gt;DriverManager 驱动管理类
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;注册驱动&lt;/strong&gt;：让 &lt;code&gt;DriverManager&lt;/code&gt; 知道当前有哪些可用的数据库驱动（如 MySQL, Oracle, PostgreSQL）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;建立连接&lt;/strong&gt;：根据传入的 URL、用户名和密码，找到匹配的驱动并返回一个 &lt;code&gt;Connection&lt;/code&gt; 对象。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#e6db74"&gt;&amp;#34;jdbc:mysql://127.0.0.1:3306/school_db?useSSL=false&amp;amp;serverTimezone=UTC&amp;amp;characterEncoding=UTF-8&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;//127.0.0.1:3306/&lt;/code&gt;&lt;/strong&gt;：指定数据库服务器的地址和监听端口（默认 3306）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;school_db&lt;/code&gt;&lt;/strong&gt;：要连接的具体数据库模式（Schema）名称。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;useSSL=false&lt;/code&gt;&lt;/strong&gt;：关闭 SSL 加密连接（开发环境下常用，减少性能开销）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;serverTimezone=UTC&lt;/code&gt;&lt;/strong&gt;：指定服务器时区。若不设置，在某些 MySQL 版本中可能会抛出时区错误。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;characterEncoding=UTF-8&lt;/code&gt;&lt;/strong&gt;：强制使用 UTF-8 编码，防止中文乱码。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 1. 注册驱动 (JDBC 4.0 以后这一步可以省略)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Class.&lt;span style="color:#a6e22e"&gt;forName&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;com.mysql.cj.jdbc.Driver&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 2. 通过 DriverManager 获取连接&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String url &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;jdbc:mysql://localhost:3306/test_db&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Connection conn &lt;span style="color:#f92672"&gt;=&lt;/span&gt; DriverManager.&lt;span style="color:#a6e22e"&gt;getConnection&lt;/span&gt;(url, &lt;span style="color:#e6db74"&gt;&amp;#34;root&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;password&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="connection"&gt;Connection
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Connection&lt;/code&gt; 接口是 JDBC API 的核心，代表与特定数据库的&lt;strong&gt;物理会话（Session）&lt;/strong&gt;。所有的 SQL 语句都在此连接的上下文中执行。&lt;/p&gt;
&lt;h3 id="核心方法"&gt;核心方法
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;方法&lt;/th&gt;
					&lt;th style="text-align: left"&gt;功能描述&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;&lt;code&gt;createStatement()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;创建一个基本的 &lt;code&gt;Statement&lt;/code&gt; 对象，用于执行静态 SQL。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;&lt;code&gt;prepareStatement(String sql)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;创建一个预编译的语句对象，支持参数化查询（防注入）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;&lt;code&gt;setAutoCommit(boolean)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;设置是否自动提交事务。默认为 &lt;code&gt;true&lt;/code&gt;。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;&lt;code&gt;commit()&lt;/code&gt; / &lt;code&gt;rollback()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;手动提交或回滚当前事务中的所有更改。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;&lt;code&gt;close()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;释放该连接占用的数据库和 JDBC 资源。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;&lt;code&gt;isClosed()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;检查连接是否已关闭或失效。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="jdbc的事务处理"&gt;JDBC的事务处理
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Connection conn &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 conn &lt;span style="color:#f92672"&gt;=&lt;/span&gt; DriverManager.&lt;span style="color:#a6e22e"&gt;getConnection&lt;/span&gt;(url, user, pass);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;// 1. 关闭自动提交，开启事务&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 conn.&lt;span style="color:#a6e22e"&gt;setAutoCommit&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;// 2. 执行 SQL A (扣钱)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;// 3. 执行 SQL B (加钱)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;// 4. 业务全部成功，手动提交&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 conn.&lt;span style="color:#a6e22e"&gt;commit&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	} &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (Exception e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;// 5. 一旦出异常，全部回滚&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (conn &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 conn.&lt;span style="color:#a6e22e"&gt;rollback&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 } &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (SQLException ex) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 ex.&lt;span style="color:#a6e22e"&gt;printStackTrace&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	} &lt;span style="color:#66d9ef"&gt;finally&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;// 6. 记得关闭连接&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (conn &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) conn.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="statement"&gt;Statement
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Statement&lt;/code&gt; 是 JDBC 中最基础的执行对象，用于执行静态 SQL 语句。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 1. 通过连接创建一个邮差&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Statement stmt &lt;span style="color:#f92672"&gt;=&lt;/span&gt; conn.&lt;span style="color:#a6e22e"&gt;createStatement&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 2. 让邮差去送信（执行 SQL）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String sql &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;UPDATE user SET name = &amp;#39;张三&amp;#39; WHERE id = 1&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; rows &lt;span style="color:#f92672"&gt;=&lt;/span&gt; stmt.&lt;span style="color:#a6e22e"&gt;executeUpdate&lt;/span&gt;(sql); &lt;span style="color:#75715e"&gt;// 返回受影响的行数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 3. 如果是查询，会带回一个结果集&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ResultSet rs &lt;span style="color:#f92672"&gt;=&lt;/span&gt; stmt.&lt;span style="color:#a6e22e"&gt;executeQuery&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;SELECT * FROM user&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;特性&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;executeUpdate()&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;executeQuery()&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;SQL 类型&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;INSERT, UPDATE, DELETE, DDL&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;返回类型&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;int&lt;/code&gt; (行数)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;ResultSet&lt;/code&gt; (数据集合)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;典型场景&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;转账、注册、修改密码、删帖&lt;/td&gt;
					&lt;td&gt;查余额、搜商品、看个人资料&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;为空时&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;返回 &lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;返回一个空的 &lt;code&gt;ResultSet&lt;/code&gt;（&lt;code&gt;rs.next()&lt;/code&gt; 为 false）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="resultset-结果集对象"&gt;Resultset 结果集对象
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;ResultSet&lt;/code&gt;（结果集）是 JDBC 中用于存储和操作数据库查询结果的对象。它类似于一张&lt;strong&gt;虚拟的临时表&lt;/strong&gt;，维持着一个指向当前数据行的光标（Cursor）&lt;/p&gt;
&lt;h3 id="工作原理光标机制-the-cursor"&gt;工作原理：光标机制 (The Cursor)
&lt;/h3&gt;&lt;p&gt;当你执行 &lt;code&gt;executeQuery()&lt;/code&gt; 后，返回的 &lt;code&gt;ResultSet&lt;/code&gt; 对象初始状态下，光标指向第一行数据的&lt;strong&gt;上方&lt;/strong&gt;（即“Before First”位置）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;next()&lt;/code&gt; 方法&lt;/strong&gt;：将光标下移一行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;返回值&lt;/strong&gt;：如果下一行有数据，返回 &lt;code&gt;true&lt;/code&gt;；如果已经到达末尾，返回 &lt;code&gt;false&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;常用遍历模式&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (rs.&lt;span style="color:#a6e22e"&gt;next&lt;/span&gt;()) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 处理当前行的数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; rs.&lt;span style="color:#a6e22e"&gt;getXxx&lt;/span&gt;(参数);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="获取数据的方法-getter-methods"&gt;获取数据的方法 (Getter Methods)
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;ResultSet&lt;/code&gt; 提供了丰富的 &lt;code&gt;getXXX&lt;/code&gt; 方法来获取不同类型的数据，通常支持两种定位方式：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;获取方式&lt;/th&gt;
					&lt;th style="text-align: left"&gt;示例&lt;/th&gt;
					&lt;th style="text-align: left"&gt;优缺点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;通过列索引&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;rs.getString(1)&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;性能略高，但代码可读性差，且依赖 SQL 字段顺序。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;通过列标签&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;rs.getInt(&amp;quot;user_id&amp;quot;)&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;推荐方式&lt;/strong&gt;。可读性强，不依赖 SQL 字段顺序。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;常用类型映射：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getString()&lt;/code&gt; -&amp;gt; &lt;code&gt;String&lt;/code&gt; (VARCHAR, TEXT)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getInt()&lt;/code&gt; -&amp;gt; &lt;code&gt;int&lt;/code&gt; (INT)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getDouble()&lt;/code&gt; -&amp;gt; &lt;code&gt;double&lt;/code&gt; (DOUBLE, DECIMAL)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getTimestamp()&lt;/code&gt; -&amp;gt; &lt;code&gt;java.sql.Timestamp&lt;/code&gt; (DATETIME)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getObject()&lt;/code&gt; -&amp;gt; 通用类型，通常用于处理动态查询。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE] 注意
JDBC 的列索引是从 &lt;strong&gt;1&lt;/strong&gt; 开始的（1-based），而 Java 数组和集合是从 &lt;strong&gt;0&lt;/strong&gt; 开始的（0-based）。如果在循环里混用了，会导致 &lt;code&gt;SQLException: Column Index out of range&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Connection conn &lt;span style="color:#f92672"&gt;=&lt;/span&gt; DriverManager.&lt;span style="color:#a6e22e"&gt;getConnection&lt;/span&gt;(url,username,password); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String sql &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;SELECT * FROM users&amp;#34;&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; (conn; Statement stmt &lt;span style="color:#f92672"&gt;=&lt;/span&gt; conn.&lt;span style="color:#a6e22e"&gt;createStatement&lt;/span&gt;(); ResultSet rs &lt;span style="color:#f92672"&gt;=&lt;/span&gt; stmt.&lt;span style="color:#a6e22e"&gt;executeQuery&lt;/span&gt;(sql)) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (rs.&lt;span style="color:#a6e22e"&gt;next&lt;/span&gt;()){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String user &lt;span style="color:#f92672"&gt;=&lt;/span&gt; rs.&lt;span style="color:#a6e22e"&gt;getString&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;username&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String passwd &lt;span style="color:#f92672"&gt;=&lt;/span&gt; rs.&lt;span style="color:#a6e22e"&gt;getString&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;password&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String date &lt;span style="color:#f92672"&gt;=&lt;/span&gt; rs.&lt;span style="color:#a6e22e"&gt;getString&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;created_at&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(user &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; passwd &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; date); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="preparedstatement-预编译语句对象"&gt;PreparedStatement 预编译语句对象
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;PreparedStatement&lt;/code&gt; 继承自 &lt;code&gt;Statement&lt;/code&gt; 接口，是 JDBC 中最常用的 SQL 执行对象。它代表一条&lt;strong&gt;预编译&lt;/strong&gt;的 SQL 语句，能够有效提高性能并彻底杜绝 SQL 注入风险&lt;/p&gt;
&lt;h3 id="优势"&gt;优势
&lt;/h3&gt;&lt;p&gt;相比于普通的 &lt;code&gt;Statement&lt;/code&gt;，&lt;code&gt;PreparedStatement&lt;/code&gt; 具有三大核心优势：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;防止 SQL 注入&lt;/strong&gt;：通过参数化查询，将 SQL 逻辑与数据分离，使恶意代码无法改变 SQL 结构。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;性能优化&lt;/strong&gt;：数据库会对预编译后的 SQL 进行缓存（执行计划）。后续执行相同结构的 SQL（仅参数不同）时，无需重新解析。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;代码可读性&lt;/strong&gt;：使用占位符 &lt;code&gt;?&lt;/code&gt; 代替繁琐的字符串拼接，代码更加整洁。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="使用步骤"&gt;使用步骤
&lt;/h3&gt;&lt;p&gt;使用 &lt;code&gt;PreparedStatement&lt;/code&gt; 遵循以下固定流程：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;编写带占位符的 SQL&lt;/strong&gt;：使用 &lt;code&gt;?&lt;/code&gt; 作为参数位置。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;预编译 SQL&lt;/strong&gt;：通过 &lt;code&gt;Connection&lt;/code&gt; 对象获取 &lt;code&gt;PreparedStatement&lt;/code&gt; 实例。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;设置参数&lt;/strong&gt;：调用 &lt;code&gt;setXXX()&lt;/code&gt; 方法为每个 &lt;code&gt;?&lt;/code&gt; 赋值（注意：索引从 &lt;strong&gt;1&lt;/strong&gt; 开始）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;执行 SQL&lt;/strong&gt;：调用 &lt;code&gt;executeQuery()&lt;/code&gt; 或 &lt;code&gt;executeUpdate()&lt;/code&gt;（注意：执行时&lt;strong&gt;不需要&lt;/strong&gt;再传入 SQL 字符串）。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;代码示例：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String sql &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;SELECT * FROM users WHERE username = ? AND password = ?&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; (PreparedStatement pstmt &lt;span style="color:#f92672"&gt;=&lt;/span&gt; conn.&lt;span style="color:#a6e22e"&gt;prepareStatement&lt;/span&gt;(sql)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;// 1. 设置参数（索引从 1 开始）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 pstmt.&lt;span style="color:#a6e22e"&gt;setString&lt;/span&gt;(1, &lt;span style="color:#e6db74"&gt;&amp;#34;admin&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 pstmt.&lt;span style="color:#a6e22e"&gt;setString&lt;/span&gt;(2, &lt;span style="color:#e6db74"&gt;&amp;#34;123456&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;// 2. 执行查询&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; (ResultSet rs &lt;span style="color:#f92672"&gt;=&lt;/span&gt; pstmt.&lt;span style="color:#a6e22e"&gt;executeQuery&lt;/span&gt;()) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (rs.&lt;span style="color:#a6e22e"&gt;next&lt;/span&gt;()) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;// 处理结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="常用api"&gt;常用API
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;方法&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;功能描述&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;setObject(int, Object)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;最通用的赋值方法，自动映射 Java 类型到数据库类型。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;setInt / setString / ...&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;强类型赋值，确保数据类型安全。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;setNull(int, int)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;为数据库字段设置 NULL 值。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;addBatch()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;将当前参数组加入批处理队列。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;clearParameters()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;清除当前设置的所有参数，以便重用该对象。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="批处理"&gt;&lt;code&gt;*&lt;/code&gt;批处理
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String sql &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;INSERT INTO students (name, score) VALUES (?, ?)&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; (PreparedStatement pstmt &lt;span style="color:#f92672"&gt;=&lt;/span&gt; conn.&lt;span style="color:#a6e22e"&gt;prepareStatement&lt;/span&gt;(sql)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (Student s : studentList) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 pstmt.&lt;span style="color:#a6e22e"&gt;setString&lt;/span&gt;(1, s.&lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 pstmt.&lt;span style="color:#a6e22e"&gt;setInt&lt;/span&gt;(2, s.&lt;span style="color:#a6e22e"&gt;getScore&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 pstmt.&lt;span style="color:#a6e22e"&gt;addBatch&lt;/span&gt;(); &lt;span style="color:#75715e"&gt;// 添加到批处理&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 pstmt.&lt;span style="color:#a6e22e"&gt;executeBatch&lt;/span&gt;(); &lt;span style="color:#75715e"&gt;// 一次性发送所有数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!WARNING] 注意
SQL语句中的占位符&lt;strong&gt;只能给值/参数使用&lt;/strong&gt;，&lt;strong&gt;不能给表名使用&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="原理"&gt;原理
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;PreparedStatement&lt;/code&gt; 不仅仅是 &lt;code&gt;Statement&lt;/code&gt; 的子接口，它在数据库层面引入了&lt;strong&gt;预编译（Prepare&lt;/strong&gt;机制。&lt;/p&gt;
&lt;h4 id="防注入原理语义定型"&gt;防注入原理：语义定型
&lt;/h4&gt;&lt;p&gt;这是 &lt;code&gt;PreparedStatement&lt;/code&gt; 最核心的安全特性。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;逻辑固定&lt;/strong&gt;：在预编译阶段，SQL 的逻辑结构（如 &lt;code&gt;SELECT...WHERE...AND&lt;/code&gt;）已经确定并被数据库理解。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;字面量处理&lt;/strong&gt;：随后传入的任何参数，无论包含什么特殊字符（如 &lt;code&gt;' OR '1'='1&lt;/code&gt;），都会被数据库引擎强制视为一个&lt;strong&gt;整体的字符串常量&lt;/strong&gt;，而不会被当作 SQL 指令的一部分。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;类型检查&lt;/strong&gt;：&lt;code&gt;setXXX&lt;/code&gt; 方法在 Java 端就进行了类型校验，不符合类型的参数无法通过编译。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="数据库连接池"&gt;数据库连接池
&lt;/h1&gt;&lt;p&gt;数据库连接池是程序启动时自动建立的一定数量的数据库连接，并将这些连接维持在一个“池”中。当应用程序需要访问数据库时，直接从池中借用，使用完毕后归还给池。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;数据库连接池&lt;/strong&gt;是个容器，负责分配、管理数据库连接 (Connection)。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;它允许应用程序重复使用一个现有的数据库连接，而不是再重新建立一个。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;释放空闲时间超过最大空闲时间的连接，来避免因为没有释放连接而引起的数据库连接遗漏。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;优势：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;资源重用&lt;/li&gt;
&lt;li&gt;提升系统响应速度&lt;/li&gt;
&lt;li&gt;避免数据库连接遗漏&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="为什么走连接池"&gt;为什么走连接池？
&lt;/h2&gt;&lt;p&gt;在不使用连接池的情况下，每次数据库操作都遵循“六步走”：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;加载驱动&lt;/strong&gt; (消耗 CPU)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;建立物理连接&lt;/strong&gt; (涉及 TCP 三次握手，最耗时，通常需 0.1s - 0.5s)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;身份验证&lt;/strong&gt; (安全开销)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;执行 SQL&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; (TCP 四次挥手)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;弊端&lt;/strong&gt;：在高并发场景下，频繁创建/销毁连接会产生巨大的网络负载，甚至导致数据库因连接数过多而宕机&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="主流连接池对比"&gt;主流连接池对比
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;HikariCP 追光者(推荐)&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特点&lt;/strong&gt;：目前性能最强的连接池，字节码精简，速度极快。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;地位&lt;/strong&gt;：Spring Boot 2.0+ 默认连接池。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Druid 德鲁伊(阿里巴巴)&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特点&lt;/strong&gt;：功能最全面，自带 &lt;strong&gt;SQL 监控&lt;/strong&gt;、防御 SQL 注入、统计信息等。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;地位&lt;/strong&gt;：国内 Java 开发者的首选，利于排查慢 SQL。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C3P0 / DBCP&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特点&lt;/strong&gt;：较老，配置繁琐，性能在现代高并发环境下略显不足。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="核心参数配置"&gt;核心参数配置
&lt;/h2&gt;&lt;p&gt;在使用连接池（如 Druid 或 HikariCP）时，这些参数直接决定了系统的吞吐量：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;参数名称&lt;/th&gt;
					&lt;th style="text-align: left"&gt;描述&lt;/th&gt;
					&lt;th style="text-align: left"&gt;建议&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;initialSize&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;初始连接数&lt;/td&gt;
					&lt;td style="text-align: left"&gt;建议与 &lt;code&gt;minIdle&lt;/code&gt; 一致。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;maxActive&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;最大活跃连接数&lt;/td&gt;
					&lt;td style="text-align: left"&gt;根据数据库承载能力设置（如 50-100）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;maxWait&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;获取连接的最大等待时间&lt;/td&gt;
					&lt;td style="text-align: left"&gt;设置过长会导致前端请求挂起，建议 2000ms 左右。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;minIdle&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;最小空闲连接数&lt;/td&gt;
					&lt;td style="text-align: left"&gt;始终保持在池中的“保底”连接。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;validationQuery&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;验证连接是否有效的 SQL&lt;/td&gt;
					&lt;td style="text-align: left"&gt;MySQL 常用 &lt;code&gt;SELECT 1&lt;/code&gt;。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 1. 加载配置文件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	Properties props &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Properties();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	props.&lt;span style="color:#a6e22e"&gt;load&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileInputStream(&lt;span style="color:#e6db74"&gt;&amp;#34;druid.properties&amp;#34;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 2. 获取数据源 (DataSource)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	DataSource ds &lt;span style="color:#f92672"&gt;=&lt;/span&gt; DruidDataSourceFactory.&lt;span style="color:#a6e22e"&gt;createDataSource&lt;/span&gt;(props);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 3. 从池中获取连接&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; (Connection conn &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ds.&lt;span style="color:#a6e22e"&gt;getConnection&lt;/span&gt;()) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;// 这里的 close() 只是把连接归还给池&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;获取到连接：&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; conn);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="mybatis"&gt;MyBatis
&lt;/h1&gt;&lt;h2 id="预编译占位符最常用最安全"&gt;&lt;code&gt;#{}&lt;/code&gt;：预编译占位符（最常用、最安全）
&lt;/h2&gt;&lt;p&gt;这是 MyBatis 的默认推荐方式。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;底层原理&lt;/strong&gt;：它是基于 JDBC 的 &lt;code&gt;PreparedStatement&lt;/code&gt; 实现的。MyBatis 会先将 SQL 语句中的 &lt;code&gt;#{}&lt;/code&gt; 替换为 &lt;code&gt;?&lt;/code&gt;，发送给数据库进行预编译，然后再将参数值设置进去。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;特点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;安全性高&lt;/strong&gt;：自动处理 SQL 注入风险。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自动转义&lt;/strong&gt;：如果传入的是字符串，它会自动加上单引号 &lt;code&gt;' '&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;示例&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Mysql" data-lang="Mysql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 输入参数 name = &amp;#34;Zhang&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;user&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; username &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#75715e"&gt;#{name}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 解析后的 SQL：SELECT * FROM user WHERE username = ?
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 执行时：SELECT * FROM user WHERE username = &amp;#39;Zhang&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;特性&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;#{}&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;${}&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;处理方式&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;预编译 (PreparedStatement)&lt;/td&gt;
					&lt;td&gt;字符串替换 (Statement)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;场景&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;参数值传递&lt;/td&gt;
					&lt;td&gt;表名、字段名动态设置时使用&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;安全性&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;高&lt;/strong&gt;，防止 SQL 注入&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;低&lt;/strong&gt;，有 SQL 注入风险&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;性能&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;高（预编译可重用执行计划）&lt;/td&gt;
					&lt;td&gt;低（每次都需要重新解析 SQL）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;自动加引号&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;是&lt;/td&gt;
					&lt;td&gt;否&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;这些场景通常是 &lt;strong&gt;“参数不是作为值，而是作为 SQL 的语法组成部分”&lt;/strong&gt; 时：&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;动态表名&lt;/strong&gt;：&lt;code&gt;SELECT * FROM ${tableName}&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;动态列名&lt;/strong&gt;：&lt;code&gt;SELECT ${columnName} FROM user&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;动态排序&lt;/strong&gt;：&lt;code&gt;ORDER BY ${orderColumn} ${sortType}&lt;/code&gt;（比如让用户点击表头按不同字段排序）&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="问为什么--能防止-sql-注入而--不能"&gt;问：“为什么 &lt;code&gt;#{}&lt;/code&gt; 能防止 SQL 注入，而 &lt;code&gt;${}&lt;/code&gt; 不能？”
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;回答：&lt;/strong&gt; “因为 &lt;code&gt;#{}&lt;/code&gt; 采用了 JDBC 的 &lt;strong&gt;预编译 (PreparedStatement)&lt;/strong&gt; 机制。在这种机制下，SQL 的结构在参数传入前就已经确定并发送给数据库解析了。参数被视为单纯的‘值’，即使参数里包含 &lt;code&gt;OR 1=1&lt;/code&gt; 这样的指令，也只会被当作一段普通的文本处理，不会改变 SQL 的逻辑语义。 而 &lt;code&gt;${}&lt;/code&gt; 只是简单的 &lt;strong&gt;字符串拼接&lt;/strong&gt;，参数会直接参与 SQL 语句的解析和编译，从而可能改变 SQL 的执行意图，导致注入风险。”&lt;/p&gt;
&lt;h2 id="增删改查"&gt;增删改查
&lt;/h2&gt;&lt;h3 id="插入insert"&gt;插入INSERT
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mapper接口&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Insert&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;INSERT INTO user(username,password,name,age) VALUES(#{username},#{password},#{name},#{age})&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;insert&lt;/span&gt;(User user);&lt;span style="color:#75715e"&gt;//插入用户信息&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Spring测试&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Test&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;testInsert&lt;/span&gt;(){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; User user &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; User(&lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;jjj&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;666888&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;鸡鸡鸡&amp;#34;&lt;/span&gt;,18); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; userMapper.&lt;span style="color:#a6e22e"&gt;insert&lt;/span&gt;(user);&lt;span style="color:#75715e"&gt;//调用UserMapper接口中的insert方法，插入用户信息 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="删除delete"&gt;删除DELETE
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mapper接口&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Delete&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;DELETE FROM user WHERE id = #{id}&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;deleteById&lt;/span&gt;(Integer id);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Spring测试&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Autowired&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; UserMapper userMapper;&lt;span style="color:#75715e"&gt;//注入UserMapper接口的代理对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Test&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;testDeleteById&lt;/span&gt;(){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 userMapper.&lt;span style="color:#a6e22e"&gt;deleteById&lt;/span&gt;(5); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="修改update"&gt;修改UPDATE
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mapper接口&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Update&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;UPDATE user set username = #{username},password = #{password},name = #{name},age = #{age} WHERE id = #{id}&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;update&lt;/span&gt;(User user);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Spring测试&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;testUpdate&lt;/span&gt;(){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; User user &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; User(1,&lt;span style="color:#e6db74"&gt;&amp;#34;zhouyu&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;8989&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;周瑜&amp;#34;&lt;/span&gt;,19); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; userMapper.&lt;span style="color:#a6e22e"&gt;update&lt;/span&gt;(user);&lt;span style="color:#75715e"&gt;//调用UserMapper接口中的update方法，更新用户信息 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="查询select"&gt;查询SELECT
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Select&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;SELECT * FROM user WHERE username = #{username} AND password = #{password}&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; User &lt;span style="color:#a6e22e"&gt;findByUsernameAndPassword&lt;/span&gt;( 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Param&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;username&amp;#34;&lt;/span&gt;)String username, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Param&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;password&amp;#34;&lt;/span&gt;) String password);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;❗说明:&lt;/strong&gt;
&lt;strong&gt;基于官方骨架创建的springboot项目中&lt;/strong&gt;，接口编译时会&lt;strong&gt;保留方法形参名&lt;/strong&gt;，@Param注解可以省略(#{形参名})&lt;/p&gt;
&lt;h4 id="param内部原理图解"&gt;@Param内部原理图解
&lt;/h4&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;调用接口&lt;/strong&gt;：调用 &lt;code&gt;findByUsernameAndPassword(&amp;quot;Zhang&amp;quot;, &amp;quot;123&amp;quot;)&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;封装 Map&lt;/strong&gt;：MyBatis 内部会将这些参数封装成一个 &lt;code&gt;Map&lt;/code&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;没有 &lt;code&gt;@Param&lt;/code&gt;&lt;/strong&gt;：Map 为 &lt;code&gt;{arg0: &amp;quot;Zhang&amp;quot;, arg1: &amp;quot;123&amp;quot;}&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;有 &lt;code&gt;@Param&lt;/code&gt;&lt;/strong&gt;：Map 为 &lt;code&gt;{username: &amp;quot;Zhang&amp;quot;, password: &amp;quot;123&amp;quot;}&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SQL 填充&lt;/strong&gt;：执行时，MyBatis 从 Map 中根据 Key（即 &lt;code&gt;username&lt;/code&gt;）取出 Value&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="问mybatis-的-param-注解有什么用"&gt;问：“MyBatis 的 &lt;code&gt;@Param&lt;/code&gt; 注解有什么用？”
&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;回答：&lt;/strong&gt; “&lt;code&gt;@Param&lt;/code&gt; 主要用于&lt;strong&gt;多参数传递&lt;/strong&gt;的场景。由于 Java 字节码在编译后可能会丢失方法参数名，导致 MyBatis 无法将 SQL 中的占位符与方法参数对应。 通过 &lt;code&gt;@Param&lt;/code&gt; 注解，我们可以显式地为参数命名，MyBatis 会将这些参数封装进一个 Map 中，从而在解析 SQL 语句时能够准确地通过 Key 找到对应的 Value。这增强了代码的可读性，并避免了多参数环境下参数找不到的异常。”&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="xml映射配置"&gt;XML映射配置
&lt;/h2&gt;&lt;h3 id="基本组成结构"&gt;基本组成结构
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34; ?&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!DOCTYPE mapper
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; PUBLIC &amp;#34;-//mybatis.org//DTD Mapper 3.0//EN&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; &amp;#34;http://mybatis.org/dtd/mybatis-3-mapper.dtd&amp;#34;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;mapper&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;namespace=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;com.example.mapper.UserMapper&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;select&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;findById&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;resultType=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;com.example.pojo.User&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; SELECT * FROM user WHERE id = #{id}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/mapper&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="核心对应关系"&gt;核心对应关系
&lt;/h3&gt;&lt;p&gt;为了让 Spring 容器能通过接口找到对应的 SQL，必须严格遵守以下约定：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;名称空间一致&lt;/strong&gt;：XML映射文件 的 &lt;code&gt;namespace&lt;/code&gt; 属性必须是接口的&lt;strong&gt;全路径名&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ID与方法名 一致&lt;/strong&gt;：XML映射文件中 SQL 标签的 &lt;code&gt;id&lt;/code&gt; 属性必须与接口中的&lt;strong&gt;方法名&lt;/strong&gt;完全一致。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;包名类名一致&lt;/strong&gt;： XML映射文件 的名称与&lt;code&gt;Mapper&lt;/code&gt;接口名称一致，并且将XML映射文件和Mapper放在相同包下（同包同名）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;参数/结果一致&lt;/strong&gt;：&lt;code&gt;parameterType&lt;/code&gt;（通常可省略）和 &lt;code&gt;resultType&lt;/code&gt; 要与接口的入参和出参对应&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34; ?&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!DOCTYPE mapper 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; PUBLIC &amp;#34;-//mybatis.org//DTD Mapper 3.0//EN&amp;#34; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; &amp;#34;http://mybatis.org/dtd/mybatis-3-mapper.dtd&amp;#34;&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;mapper&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;namespace=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;org.example.mapper.UserMapper&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;select&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;findAll&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;resultType=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;org.example.pojo.User&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; #往User封装 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; SELECT id,username,password,name,age FROM user 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/select&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/mapper&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;相当于Mapper中的：@Select(&amp;#34;SELECT id,username,password,name,age FROM user&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;场景&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;推荐方式&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;原因&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;简单的根据 ID 查询、删除&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;注解&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;快速、省事，不用在文件间跳来跳去。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;复杂的关联查询（Join）&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;XML&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;注解难以处理复杂的 &lt;code&gt;resultMap&lt;/code&gt; 嵌套映射。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;动态搜索、批量插入&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;XML&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;动态标签（&lt;code&gt;&amp;lt;if&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;foreach&amp;gt;&lt;/code&gt;）是 XML 的杀手锏。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;SQL 语句经常需要优化&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;XML&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;修改 SQL 时不影响 Java 逻辑，更易于维护。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="辅助配置"&gt;辅助配置
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-properties" data-lang="properties"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;# 指定XML映射文件的位置 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;mybatis.mapper-locations&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;classpath:mapper/*.xml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="xml-中的-sql"&gt;XML 中的 SQL
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;mapper&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;namespace=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;asia.creat.mapper.EmpMapper&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;select&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;listByCondition&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;resultType=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;asia.creat.pojo.Emp&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; SELECT *FROM emp e LEFT JOIN dept d ON e.dept_id = d.id WHERE e.name 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; LIKE CONCAT(&amp;#39;%&amp;#39;,#{name},&amp;#39;%&amp;#39;) AND e.gender = #{gender} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; AND e.entry_date BETWEEN #{begin} AND #{end} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ORDER BY e.update_time DESC 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;/select&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/mapper&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="动态sql"&gt;动态SQL
&lt;/h2&gt;&lt;p&gt;MyBatis 提供了几个强大的逻辑标签：&lt;/p&gt;
&lt;h3 id="if条件判断"&gt;&lt;code&gt;&amp;lt;if&amp;gt;&lt;/code&gt;：条件判断
&lt;/h3&gt;&lt;p&gt;最常用的标签。如果 &lt;code&gt;test&lt;/code&gt; 属性中的表达式为真，则拼接标签内的 SQL&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;select&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;find&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;resultType=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Emp&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; SELECT * FROM emp WHERE 1=1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;test=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;name != null&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; AND name LIKE #{name}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/if&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;test=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;gender != null&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; AND gender = #{gender}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/if&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="where智能处理"&gt;&lt;code&gt;&amp;lt;where&amp;gt;&lt;/code&gt;：智能处理
&lt;/h3&gt;&lt;p&gt;上面的写法里我们被迫写了 &lt;code&gt;WHERE 1=1&lt;/code&gt;，这很丑。&lt;code&gt;&amp;lt;where&amp;gt;&lt;/code&gt; 标签能自动完成两件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;如果子标签有内容，才插入 &lt;code&gt;WHERE&lt;/code&gt; 关键字&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;自动剔除内容开头多余的 &lt;code&gt;AND&lt;/code&gt; 或 &lt;code&gt;OR&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;select&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;find&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;resultType=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Emp&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; SELECT * FROM emp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;where&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;test=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;name != null&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;AND name = #{name}&lt;span style="color:#f92672"&gt;&amp;lt;/if&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;test=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;gender != null&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;AND gender = #{gender}&lt;span style="color:#f92672"&gt;&amp;lt;/if&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/where&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="set动态更新"&gt;&lt;code&gt;&amp;lt;set&amp;gt;&lt;/code&gt;：动态更新
&lt;/h3&gt;&lt;p&gt;用于 &lt;code&gt;UPDATE&lt;/code&gt; 语句。它会自动插入 &lt;code&gt;SET&lt;/code&gt; 关键字，并聪明地删掉最后一个多余的&lt;strong&gt;逗号&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;update&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;update&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; UPDATE emp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;set&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;test=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;username != null&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;username = #{username},&lt;span style="color:#f92672"&gt;&amp;lt;/if&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;test=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;password != null&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;password = #{password},&lt;span style="color:#f92672"&gt;&amp;lt;/if&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/set&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; WHERE id = #{id}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/update&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="foreach循环遍历"&gt;&lt;code&gt;&amp;lt;foreach&amp;gt;&lt;/code&gt;：循环遍历
&lt;/h3&gt;&lt;p&gt;专门处理 &lt;code&gt;IN&lt;/code&gt; 查询或批量插入。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;collection&lt;/code&gt;：参数名（如 List 或数组）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;item&lt;/code&gt;：遍历出的每一项变量名&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;separator&lt;/code&gt;：分隔符（如逗号）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;open&lt;/code&gt;：遍历开始前拼接的片段&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;close&lt;/code&gt;：遍历结束后拼接的片段&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;delete&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;deleteByIds&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; DELETE FROM emp WHERE id IN
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;foreach&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;collection=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ids&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;item=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;open=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;(&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;close=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;)&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;separator=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;,&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; #{id}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/foreach&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/delete&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="工作原理"&gt;工作原理
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;解析&lt;/strong&gt;：MyBatis 在执行前扫描 XML 标签&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;判断&lt;/strong&gt;：根据你传入的参数对象（比如 &lt;code&gt;EmpQueryParam&lt;/code&gt;）的值，计算 &lt;code&gt;test&lt;/code&gt; 里的表达式&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;渲染&lt;/strong&gt;：只保留符合条件的片段，拼接成最终的“原生 SQL”交给数据库执行&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="使用提示"&gt;使用提示
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;字符串判空&lt;/strong&gt;：对于 String 类型，习惯上写成 &lt;code&gt;&amp;lt;if test=&amp;quot;name != null and name != ''&amp;quot;&amp;gt;&lt;/code&gt;，同时检查 &lt;code&gt;null&lt;/code&gt; 和空字符串&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SQL 注入&lt;/strong&gt;：始终使用 &lt;code&gt;#{}&lt;/code&gt; 传参，它会自动进行预编译。除非是要动态传表名或排序列名（这种极少数情况才用 &lt;code&gt;${}&lt;/code&gt;）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;XML 还是注解？&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;简单的 SQL 可以写在注解 &lt;code&gt;@Select&lt;/code&gt; 里&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;复杂的动态 SQL &lt;strong&gt;强烈建议&lt;/strong&gt;写在 XML 里，因为 XML 的结构化标签比在 Java 字符串里拼 SQL 舒服且清晰得多&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="springboot配置文件"&gt;SpringBoot配置文件
&lt;/h1&gt;&lt;h2 id="配置格式"&gt;配置格式
&lt;/h2&gt;&lt;p&gt;SpringBoot项目提供了多种属性配置方式(properties、yaml、yml)&lt;/p&gt;
&lt;h2 id="核心语法规则避坑指南"&gt;核心语法规则（避坑指南）
&lt;/h2&gt;&lt;p&gt;YAML 的语法非常严苛，这些错误尤其会导致 Spring Boot 启动失败：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;大小写敏感&lt;/strong&gt;：&lt;code&gt;Name&lt;/code&gt; 和 &lt;code&gt;name&lt;/code&gt; 是不同的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;使用缩进表示层级&lt;/strong&gt;：禁止使用 Tab 键，必须使用 &lt;strong&gt;空格&lt;/strong&gt;（通常缩进 2 个空格）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;冒号后必须有空格&lt;/strong&gt;：这是最容易忘的！&lt;code&gt;key: value&lt;/code&gt; 冒号后面必须跟着一个空格。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;“#” 表示注释&lt;/strong&gt;：与 Java 里的 &lt;code&gt;//&lt;/code&gt; 作用一样。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="yaml-的数据格式"&gt;YAML 的数据格式
&lt;/h2&gt;&lt;h3 id="纯量普通键值对"&gt;纯量（普通键值对）
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;server&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;port&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;8080&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 注意冒号后的空格&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;address&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;127.0.0.1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="对象层级关系"&gt;对象（层级关系）
&lt;/h3&gt;&lt;p&gt;YAML 天然适合表达这种父子结构：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;student&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ZhangKun&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;age&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;major&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;SoftwareEngineering&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="数组--集合"&gt;数组 / 集合
&lt;/h3&gt;&lt;p&gt;使用 &lt;strong&gt;短横线 &lt;code&gt;-&lt;/code&gt;&lt;/strong&gt; 表示列表中的一个项：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;subjects&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;Java&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;MyBatis&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;SpringBoot&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
在yml格式的配置文件中，如果配置项的值是以0开头的，值需要使用&amp;rsquo; &amp;lsquo;引起来，因为以0开头在yml中表示8进制的数据。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果 &lt;code&gt;src/main/resources&lt;/code&gt; 下同时存在 &lt;code&gt;application.properties&lt;/code&gt; 和 &lt;code&gt;application.yml&lt;/code&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Spring 会同时加载两个文件&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果有重复配置，&lt;strong&gt;&lt;code&gt;.properties&lt;/code&gt; 的优先级更高&lt;/strong&gt;（它会覆盖 &lt;code&gt;.yml&lt;/code&gt; 的内容）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;建议&lt;/strong&gt;：项目中统一只用一种格式，避免逻辑混乱。&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>进阶-SQL优化</title><link>https://creat.asia/post/%E8%BF%9B%E9%98%B6-sql%E4%BC%98%E5%8C%96/</link><pubDate>Sat, 04 Apr 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/%E8%BF%9B%E9%98%B6-sql%E4%BC%98%E5%8C%96/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-04&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="插入数据"&gt;插入数据
&lt;/h1&gt;&lt;h2 id="普通-insert-优化-批量插入"&gt;普通 Insert 优化 (批量插入)
&lt;/h2&gt;&lt;p&gt;如果需要插入多条数据，不要每一条都执行一次 &lt;code&gt;INSERT&lt;/code&gt; 语句。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;错误做法&lt;/strong&gt;：循环执行 1000 次 &lt;code&gt;INSERT INTO user VALUES (...);&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;优化做法&lt;/strong&gt;：使用批量插入（建议一次批量 500-1000 条）。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;INSERT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INTO&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;user&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;VALUES&lt;/span&gt; (&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;Tom&amp;#39;&lt;/span&gt;), (&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;Jerry&amp;#39;&lt;/span&gt;), (&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;Rose&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;原理&lt;/strong&gt;：减少了客户端与数据库之间的网络连接开销，降低了 SQL 解析的次数。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="事务优化-手动提交事务"&gt;事务优化 (手动提交事务)
&lt;/h2&gt;&lt;p&gt;MySQL 默认是自动提交（autocommit）的，这意味着每执行一次 &lt;code&gt;INSERT&lt;/code&gt;，数据库就会进行一次磁盘同步（Disk Flush）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;优化做法&lt;/strong&gt;：手动开启并提交事务。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	START TRANSACTION;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;INSERT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INTO&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;user&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;VALUES&lt;/span&gt; (...);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;INSERT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INTO&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;user&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;VALUES&lt;/span&gt; (...);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 执行成百上千条后再统一提交
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	COMMIT;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;原理&lt;/strong&gt;：将多次磁盘 I/O 操作合并为一次，极大提升写入性能。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="主键顺序插入"&gt;主键顺序插入
&lt;/h2&gt;&lt;p&gt;在设计表结构时，主键的选择直接影响插入效率。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;优化建议&lt;/strong&gt;：尽量使用&lt;strong&gt;自增主键&lt;/strong&gt;，保证主键顺序插入。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;原因&lt;/strong&gt;：InnoDB 使用 B+Tree 索引。如果主键乱序（如 UUID），会导致频繁的&lt;strong&gt;页分裂 (Page Split)&lt;/strong&gt; 和记录移动，增加磁盘开销。顺序插入则只需在索引页末尾追加。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="大批量数据加载-load-data-local-infile"&gt;大批量数据加载 (load data local infile)
&lt;/h2&gt;&lt;p&gt;如果你有成百万条数据存在文本文件（如 CSV）中，使用 &lt;code&gt;INSERT&lt;/code&gt; 语句会非常缓慢。此时应使用 MySQL 提供的 &lt;code&gt;load&lt;/code&gt; 指令。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;操作步骤&lt;/strong&gt;：
&lt;ol&gt;
&lt;li&gt;客户端连接时开启本地文件加载：&lt;code&gt;mysql --local-infile -u root -p&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;设置全局参数：&lt;code&gt;set global local_infile = 1;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;执行加载语句：&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;load&lt;/span&gt; data local &lt;span style="color:#66d9ef"&gt;infile&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;/root/sql_data.log&amp;#39;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;into&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;table&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;user&lt;/span&gt;&lt;span style="color:#f92672"&gt;`&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	fields &lt;span style="color:#66d9ef"&gt;terminated&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;by&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;,&amp;#39;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;lines&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;terminated&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;by&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;性能&lt;/strong&gt;：这种方式直接绕过了部分 SQL 解析逻辑，比普通的 &lt;code&gt;INSERT&lt;/code&gt; 快一个数量级。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="主键优化"&gt;主键优化
&lt;/h1&gt;&lt;h2 id="innodb-数据组织方式-index-organized-table"&gt;InnoDB 数据组织方式 (Index Organized Table)
&lt;/h2&gt;&lt;p&gt;在 InnoDB 存储引擎中，表数据都是根据&lt;strong&gt;主键顺序&lt;/strong&gt;组织存放的。这种存储方式的表称为 &lt;strong&gt;索引组织表 (Index Organized Table, IOT)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;核心特征&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;行数据即索引&lt;/strong&gt;：在 InnoDB 的聚集索引中，叶子节点直接存储了整行数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主键即路径&lt;/strong&gt;：当你通过主键查询时，不需要额外的寻址，找到索引即找到了数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;强制性&lt;/strong&gt;：由于数据必须按序存放，如果表没有显式定义主键，InnoDB 会自动寻找或生成隐式主键来组织数据。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="数据存储原理页分裂-page-split"&gt;数据存储原理：页分裂 (Page Split)
&lt;/h2&gt;&lt;p&gt;InnoDB 的最小存储单元是 &lt;strong&gt;页 (Page)&lt;/strong&gt;，默认大小为 16KB。
页可以为空，也可以填充一半，也可以填充100%。每个页包含了2-N行数据(如果一行数据多大，会行溢出)，根据主键排列。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;顺序插入&lt;/strong&gt;：如果主键自增，数据会按顺序填满物理页。当一页满时，直接开辟新页继续写入，效率极高。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;乱序插入 (如 UUID)&lt;/strong&gt;：如果主键是随机的，新行可能需要插入到已经写满的页中间。此时，InnoDB 必须将该页拆分为两页，并移动部分数据，这被称为&lt;strong&gt;页分裂&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;后果&lt;/strong&gt;：页分裂会导致大量的磁盘 I/O，并产生物理碎片。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="数据存储原理页合并-page-merge"&gt;数据存储原理：页合并 (Page Merge)
&lt;/h2&gt;&lt;p&gt;当删除一行记录时，实际上记录并未从磁盘物理删除，只是被标记为“已删除”，其空间可以被覆盖利用。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;合并逻辑&lt;/strong&gt;：当一个页中被删除的记录达到一定比例（默认为 MERGE_THRESHOLD 50%），InnoDB 会尝试寻找相邻的页，看是否可以将两个页合并以优化空间。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;后果&lt;/strong&gt;：频繁的页合并和分裂会使索引树结构变得不稳定。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="主键设计原则-best-practices"&gt;主键设计原则 (Best Practices)
&lt;/h2&gt;&lt;h3 id="尽量降低主键长度"&gt;尽量降低主键长度
&lt;/h3&gt;&lt;p&gt;二级索引（辅助索引）的叶子节点存储的是主键值。如果主键过长，会导致&lt;strong&gt;所有的二级索引&lt;/strong&gt;都占用巨大的空间，增加磁盘 I/O 并降低内存命中率。&lt;/p&gt;
&lt;h3 id="尽量选择自增主键-auto_increment"&gt;尽量选择自增主键 (AUTO_INCREMENT)
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;保证顺序插入，完全规避页分裂问题。&lt;/li&gt;
&lt;li&gt;写入速度最快，索引树最紧凑。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="避免使用-uuid-或其他随机字符串"&gt;避免使用 UUID 或其他随机字符串
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;原因&lt;/strong&gt;：UUID 是随机无序的，插入时会引发频繁的页分裂；且 UUID 通常较长（36位），会增加二级索引的负担。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;方案&lt;/strong&gt;：如果业务需要全局唯一标识，建议使用&lt;strong&gt;雪花算法 (Snowflake)&lt;/strong&gt; 生成的趋势递增整数。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="业务逻辑不要作为主键"&gt;业务逻辑不要作为主键
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;不要使用身份证号、手机号等具有业务意义的字段作为主键。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;原因&lt;/strong&gt;：业务逻辑可能发生变化（如身份证号升位），一旦主键修改，所有二级索引都要同步更新，代价极大。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="order-by-优化"&gt;ORDER BY 优化
&lt;/h1&gt;&lt;p&gt;MySQL 的排序实现方式主要有两种：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Using index&lt;/strong&gt;：通过有序索引顺序扫描直接返回有序数据，不需要额外排序，效率最高。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Using filesort&lt;/strong&gt;：通过表的索引或全表扫描读取数据，然后在排序缓冲区 &lt;code&gt;sort_buffer&lt;/code&gt; 中进行排序。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="排序优化的核心原则"&gt;排序优化的核心原则
&lt;/h2&gt;&lt;p&gt;如果要实现 &lt;code&gt;Using index&lt;/code&gt; 提升性能，必须满足以下条件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;最左前缀法则&lt;/strong&gt;：&lt;code&gt;ORDER BY&lt;/code&gt; 的字段顺序必须符合联合索引的列顺序。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;方向一致性&lt;/strong&gt;：如果排序包含多个列，这些列的排序方向（升序 &lt;code&gt;ASC&lt;/code&gt; / 降序 &lt;code&gt;DESC&lt;/code&gt;）必须一致（MySQL 8.0 引入了&lt;strong&gt;降序索引&lt;/strong&gt;，可部分解决此问题）&lt;/li&gt;
&lt;li&gt;降序索引：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 创建联合索引：age 升序，phone 降序
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INDEX&lt;/span&gt; idx_user_age_phone_desc &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;user&lt;/span&gt;(age &lt;span style="color:#66d9ef"&gt;ASC&lt;/span&gt;, phone &lt;span style="color:#66d9ef"&gt;DESC&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;覆盖索引&lt;/strong&gt;：&lt;code&gt;SELECT&lt;/code&gt; 的字段最好只包含索引列，否则可能因为回表开销过大，导致优化器放弃索引排序而选择 &lt;code&gt;filesort&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;场景&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;索引 idx(a, b) 是否生效&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;备注&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;ORDER BY a&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;是&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;符合最左前缀&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;WHERE a = 1 ORDER BY b&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;是&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;a&lt;/code&gt; 已固定，&lt;code&gt;b&lt;/code&gt; 在索引内有序&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;ORDER BY a, b&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;是&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;顺序一致&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;ORDER BY b&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;否&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;违背最左前缀&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;WHERE a &amp;gt; 10 ORDER BY b&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;否&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;a&lt;/code&gt; 是范围查询，其后的 &lt;code&gt;b&lt;/code&gt; 在全局上是无序的&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;ORDER BY a ASC, b DESC&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;否&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;排序方向不一致（MySQL 8.0 以下）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="优化建议总结-best-practices"&gt;优化建议总结 (Best Practices)
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;根据排序字段建立索引&lt;/strong&gt;：尤其是针对 &lt;code&gt;WHERE&lt;/code&gt; 过滤后还需要 &lt;code&gt;ORDER BY&lt;/code&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;code&gt;SELECT *&lt;/code&gt;，尽量使用&lt;strong&gt;覆盖索引&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;统一排序方向&lt;/strong&gt;：除非使用了 MySQL 8.0 的降序索引功能，否则尽量保证所有排序字段都是 &lt;code&gt;ASC&lt;/code&gt; 或都是 &lt;code&gt;DESC&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不可避免 filesort 时&lt;/strong&gt;：对于大数据量排序，适当调大 &lt;code&gt;sort_buffer_size&lt;/code&gt; 减少磁盘 I/O。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="group-by优化"&gt;GROUP BY优化
&lt;/h1&gt;&lt;p&gt;MySQL 在执行 &lt;code&gt;GROUP BY&lt;/code&gt; 时，主要有两种方式：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Using index&lt;/strong&gt;：通过索引直接进行分组，效率最高&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Using temporary; Using filesort&lt;/strong&gt;：需要建立临时表并在内存或磁盘中排序，性能较差&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="核心优化原则利用索引"&gt;核心优化原则：利用索引
&lt;/h2&gt;&lt;p&gt;由于分组操作通常涉及排序，因此 &lt;strong&gt;最左前缀法则&lt;/strong&gt; 在 &lt;code&gt;GROUP BY&lt;/code&gt; 中同样适用。&lt;/p&gt;
&lt;h3 id="场景分析"&gt;场景分析
&lt;/h3&gt;&lt;p&gt;联合索引：&lt;code&gt;idx_user_pro_age (pro, age)&lt;/code&gt;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;场景类型&lt;/th&gt;
					&lt;th style="text-align: left"&gt;SQL 语句&lt;/th&gt;
					&lt;th style="text-align: left"&gt;执行状态&lt;/th&gt;
					&lt;th style="text-align: left"&gt;说明&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;全匹配（索引生效）&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;SELECT pro, count(*) FROM user GROUP BY pro, age;&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;Using index&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;-&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;符合最左前缀（索引生效）&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;SELECT pro, count(*) FROM user GROUP BY pro;&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;Using index&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;-&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;不符合最左前缀（&lt;strong&gt;索引失效&lt;/strong&gt;）&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;SELECT age, count(*) FROM user GROUP BY age;&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;Using temporary; Using filesort&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;-&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;结合 WHERE 使用（索引生效）&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;SELECT age, count(*) FROM user WHERE pro = '软件工程' GROUP BY age;&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;Using index&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;虽然 &lt;code&gt;GROUP BY&lt;/code&gt; 跳过了第一列，但 &lt;code&gt;WHERE&lt;/code&gt; 子句已经补齐了最左前缀。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h1 id="limit优化"&gt;LIMIT优化
&lt;/h1&gt;&lt;h2 id="性能瓶颈深度分页问题"&gt;性能瓶颈：深度分页问题
&lt;/h2&gt;&lt;p&gt;当执行 &lt;code&gt;LIMIT 1000000, 10&lt;/code&gt; 时，MySQL 并不是直接跳过前 100 万行，而是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;全表扫描（或索引扫描）&lt;/strong&gt;：读取前 1000010 条记录。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;回表查询&lt;/strong&gt;：如果查询的是 &lt;code&gt;SELECT *&lt;/code&gt;，则需要回表 1000010 次获取行数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;丢弃数据&lt;/strong&gt;：抛弃前 100 万条，仅返回最后 10 条。&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;结论&lt;/strong&gt;：偏移量（Offset）越大，磁盘 I/O 越高，查询越慢。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="2-优化方案-覆盖索引--子查询-延迟关联"&gt;2. 优化方案 ：覆盖索引 + 子查询 (延迟关联)
&lt;/h2&gt;&lt;p&gt;这是最通用的优化方案。通过子查询先在索引树上定位主键 ID（不回表），再关联原表获取数据。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;优化前（慢）&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;user&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;LIMIT&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1000000&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;优化后（快）&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;user&lt;/span&gt; t, (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; id &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;user&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ORDER&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; id &lt;span style="color:#66d9ef"&gt;LIMIT&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1000000&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	)a 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; t.id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a.id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;原理&lt;/strong&gt;：子查询 &lt;code&gt;(SELECT id ...)&lt;/code&gt; 利用了&lt;strong&gt;覆盖索引&lt;/strong&gt;，极大地减少了回表次数。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="count-优化"&gt;COUNT 优化
&lt;/h1&gt;&lt;h2 id="存储引擎的差异"&gt;存储引擎的差异
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;MyISAM&lt;/strong&gt;：把一个表的总行数存在了磁盘上，因此执行 &lt;code&gt;count(*)&lt;/code&gt; 时会直接返回这个数，效率极高（前提是没有 WHERE 条件）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;InnoDB&lt;/strong&gt;：由于多版本并发控制 (MVCC) 的原因，InnoDB 表“应该返回多少行”是不确定的。它必须把数据一行一行从引擎里面读出来，然后累计计数。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;优化结论&lt;/strong&gt;：在 InnoDB 中，&lt;code&gt;count(*)&lt;/code&gt; 是需要全表扫描或索引扫描的。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="count-的几种用法对比"&gt;COUNT 的几种用法对比
&lt;/h2&gt;&lt;p&gt;假设执行 &lt;code&gt;SELECT COUNT(X) FROM table;&lt;/code&gt;，性能排序通常为：
&lt;strong&gt;count(*) ≈ count(1) &amp;gt; count(主键ID) &amp;gt; count(字段)&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;用法&lt;/th&gt;
					&lt;th style="text-align: left"&gt;执行逻辑&lt;/th&gt;
					&lt;th style="text-align: left"&gt;性能评估&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;count(主键ID)&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;遍历整张表，取每行的 ID，返回给服务层，服务层判断不为 NULL 后累加。&lt;/td&gt;
					&lt;td style="text-align: left"&gt;较快，但涉及取值。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;count(字段)&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;遍历整张表，取该字段值。有 NOT NULL 约束则直接累加；没有则需判断是否为 NULL。&lt;/td&gt;
					&lt;td style="text-align: left"&gt;最慢，涉及取值和判断。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;count(1)&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;遍历整张表，但不取值。服务层对返回的每一行放入一个数字“1”，直接累加。&lt;/td&gt;
					&lt;td style="text-align: left"&gt;极快，不涉及取值。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;count(*)&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;MySQL 专门优化过&lt;/strong&gt;。不取值，直接按行累加。它会选择体积最小的二级索引树进行扫描。&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;推荐使用&lt;/strong&gt;，性能最高。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h1 id="update-优化"&gt;UPDATE 优化
&lt;/h1&gt;&lt;h2 id="核心原理行锁与表锁"&gt;核心原理：行锁与表锁
&lt;/h2&gt;&lt;p&gt;InnoDB 存储引擎支持&lt;strong&gt;行级锁 (Row Lock)&lt;/strong&gt;，这是它支持高并发的关键。但需要注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;行锁是针对索引加的锁&lt;/strong&gt;：不是针对记录加的锁。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;索引失效则锁全表&lt;/strong&gt;：如果 &lt;code&gt;UPDATE&lt;/code&gt; 语句的 &lt;code&gt;WHERE&lt;/code&gt; 条件没有使用索引，或者索引失效，InnoDB 会对全表所有记录加锁，实际上变成了&lt;strong&gt;表级锁&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 有索引 -&amp;gt; 行锁
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;UPDATE&lt;/span&gt; course &lt;span style="color:#66d9ef"&gt;SET&lt;/span&gt; name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;SpringBoot&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 无索引 -&amp;gt; 表锁
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;UPDATE&lt;/span&gt; course &lt;span style="color:#66d9ef"&gt;SET&lt;/span&gt; name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;SpringBoot&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;JavaEE&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;</description></item><item><title>进阶-锁</title><link>https://creat.asia/post/%E8%BF%9B%E9%98%B6-%E9%94%81/</link><pubDate>Sat, 04 Apr 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/%E8%BF%9B%E9%98%B6-%E9%94%81/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-05
&lt;img src="https://creat.asia/post/image/%e8%bf%9b%e9%98%b6-%e9%94%81-3.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;锁是数据库引擎用来管理对共享资源并发访问的机制，旨在保证事务的隔离性（Isolation）和一致性（Consistency）&lt;/p&gt;
&lt;h2 id="锁的粒度-lock-granularity"&gt;锁的粒度 (Lock Granularity)
&lt;/h2&gt;&lt;p&gt;锁定的资源范围大小决定了系统的并发度&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;粒度等级&lt;/th&gt;
					&lt;th style="text-align: left"&gt;描述&lt;/th&gt;
					&lt;th style="text-align: left"&gt;特点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;行级锁 (Row Lock)&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;锁定单行记录。&lt;/td&gt;
					&lt;td style="text-align: left"&gt;并发度最高，但加锁开销大（消耗内存多）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;页级锁 (Page Lock)&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;锁定一组相邻的数据页。&lt;/td&gt;
					&lt;td style="text-align: left"&gt;介于行锁与表锁之间（常见于 BDB 存储引擎）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;表级锁 (Table Lock)&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;锁定整张表。&lt;/td&gt;
					&lt;td style="text-align: left"&gt;开销小，加锁快，但并发度低（会导致大量阻塞）。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h1 id="全局锁"&gt;全局锁
&lt;/h1&gt;&lt;p&gt;全局锁就是对整个数据库实例加锁，加锁后整个实例就处于只读状态，后续的DML的写语句，DDL语句，已经更新操作的事务提交语句都将被阻塞。&lt;/p&gt;
&lt;p&gt;其典型的使用场景是做&lt;strong&gt;全库的逻辑备份&lt;/strong&gt;，对所有的表进行锁定，从而获取一致性视图，保证数据的完整性&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;功能&lt;/strong&gt;：让整个库处于只读状态。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;受限操作&lt;/strong&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;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;FLUSH&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLES&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;WITH&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;READ&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;LOCK&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;UNLOCK&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLES&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特点：&lt;/strong&gt; 数据库中加全局锁，是一个比较重的操作，存在以下问题:
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;如果在主库上备份，那么在备份期间都不能执行更新，业务基本上就得停摆&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果在从库上备份，那么在备份期间从库不能执行主库同步过来的二进制日志(binlog)，会导致主从延迟。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="single-transaction"&gt;&amp;ndash;single-transaction
&lt;/h2&gt;&lt;p&gt;如果使用的引擎支持 &lt;strong&gt;事务&lt;/strong&gt;（如 InnoDB，在使用 &lt;code&gt;mysqldump&lt;/code&gt; 时可以使用参数 &lt;code&gt;--single-transaction&lt;/code&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;原理&lt;/strong&gt;：在导数据之前就会启动一个事务，确保拿到一致性视图（Read View）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优势&lt;/strong&gt;：由于 MVCC（多版本并发控制）的支持，数据库在备份期间依然可以正常更新数据，不会阻塞业务&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="表级锁"&gt;表级锁
&lt;/h1&gt;&lt;p&gt;MySQL 的表级锁开销小，加锁快，不会出现死锁，但锁冲突的概率最高，并发度也最低。&lt;/p&gt;
&lt;h2 id="表锁-table-lock"&gt;表锁 (Table Lock)
&lt;/h2&gt;&lt;p&gt;显式加锁语法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;加锁：&lt;code&gt;lock tables 表名 read/write;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;释放：&lt;code&gt;unlock tables;&lt;/code&gt;（或客户端断开连接）&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;锁类型&lt;/th&gt;
					&lt;th style="text-align: left"&gt;描述&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;表共享&lt;strong&gt;读锁 (Read Lock)&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;共享锁。所有客户端（包括自己）只能读，不能写。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;表独占&lt;strong&gt;写锁 (Write Lock)&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;独占锁。只有当前客户端可以读写，其他客户端被阻塞。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="元数据锁-metadata-lock-mdl"&gt;元数据锁 (Metadata Lock, MDL)
&lt;/h2&gt;&lt;p&gt;MDL 是&lt;strong&gt;隐式&lt;/strong&gt;加锁的，不需要显式调用。
它的作用是防止 DDL（结构变更）与 DML（数据增删改）之间的冲突。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;对表做 DML 操作时&lt;/strong&gt;：自动加 &lt;strong&gt;MDL 读锁&lt;/strong&gt;（共享），不影响多个线程同时增删改查。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;对表做 DDL 操作时&lt;/strong&gt;：自动加 &lt;strong&gt;MDL 写锁&lt;/strong&gt;（排他），此时会阻塞所有的增删改查。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;风险点&lt;/strong&gt;：给大表加字段时，如果有一个长查询在运行，MDL 写锁会排队，进而导致后续所有的查询和更新都被堵住，甚至拖垮整个数据库。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://creat.asia/post/image/%e8%bf%9b%e9%98%b6-%e9%94%81-2.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h2 id="意向锁-intention-lock"&gt;意向锁 (Intention Lock)
&lt;/h2&gt;&lt;p&gt;意向锁是为了解决“行锁”与“表锁”共存时的效率问题。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;意向共享锁 (IS)&lt;/strong&gt;：事务准备给某些行加读锁前，先给表加 IS。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;与表锁共享锁(read)兼容，与表锁排他锁(write)互斥。&lt;/li&gt;
&lt;li&gt;执行 &lt;code&gt;SELECT ... FOR SHARE&lt;/code&gt; 前自动加。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;意向排他锁 (IX)&lt;/strong&gt;：事务准备给某些行加写锁前，先给表加 IX。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;与表锁共享锁(read)及排他锁(write)都互斥，意向锁之间不会互斥。&lt;/li&gt;
&lt;li&gt;执行 &lt;code&gt;INSERT/UPDATE/DELETE&lt;/code&gt; 前自动加。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;锁类型&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;IS (意向共享)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;IX (意向排他)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;S (表级共享)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;X (表级排他)&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;IS&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;兼容&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;兼容&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;兼容&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;冲突&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;IX&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;兼容&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;兼容&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;冲突&lt;/td&gt;
					&lt;td&gt;冲突&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;S&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;兼容&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;冲突&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;兼容&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;冲突&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;冲突&lt;/td&gt;
					&lt;td&gt;冲突&lt;/td&gt;
					&lt;td&gt;冲突&lt;/td&gt;
					&lt;td&gt;冲突&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;核心意义&lt;/strong&gt;：当你想加表锁（如 &lt;code&gt;lock tables write&lt;/code&gt;）时，不需要逐行检查是否有行锁，直接看表上是否有意向锁即可，极大提高了性能。&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;[!tip] 解释
意向锁就像是酒店大堂的&lt;strong&gt;状态指示牌&lt;/strong&gt;。如果没有它，你想包下整个酒店（表锁），得挨个敲门看有没有人住（行锁）；有了它，你看一眼前台的登记簿（意向锁）就全明白了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="auto-inc-锁"&gt;AUTO-INC 锁
&lt;/h2&gt;&lt;p&gt;这是一种特殊的表级锁，主要用于处理带有 &lt;code&gt;AUTO_INCREMENT&lt;/code&gt; 列的表。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当插入数据时，会加一个表级的 AUTO-INC 锁来获取自增值。&lt;/li&gt;
&lt;li&gt;在高并发插入场景下，这可能成为性能瓶颈（现代 MySQL 可以通过 &lt;code&gt;innodb_autoinc_lock_mode&lt;/code&gt; 参数进行优化，使用轻量级互斥锁代替）。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="行级锁"&gt;行级锁
&lt;/h1&gt;&lt;p&gt;行级锁是 MySQL 中锁粒度最小的一种锁，主要由 &lt;strong&gt;InnoDB&lt;/strong&gt; 存储引擎实现&lt;/p&gt;
&lt;p&gt;它的特点是锁冲突概率最低，并发处理能力最强，但开销相对较大，且可能会出现&lt;strong&gt;死锁&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;锁类型&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;名称&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;锁定范围&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;支持&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Record Lock&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;记录锁&lt;/td&gt;
					&lt;td&gt;仅锁定单个索引记录。&lt;/td&gt;
					&lt;td&gt;防止其他事务修改或删除该行。&lt;/td&gt;
					&lt;td&gt;在RC,RR隔离级别下都支持&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Gap Lock&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;间隙锁&lt;/td&gt;
					&lt;td&gt;锁定索引记录之间的间隙（不含记录本身）。&lt;/td&gt;
					&lt;td&gt;防止其他事务在间隙内插入数据，解决&lt;strong&gt;幻读&lt;/strong&gt;。&lt;/td&gt;
					&lt;td&gt;在RR隔离级别下支持&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Next-Key Lock&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;临键锁&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;记录锁 + 间隙锁&lt;/strong&gt;的组合。（锁住数据及前面的间隙）&lt;/td&gt;
					&lt;td&gt;锁定一个范围，并锁定记录本身。InnoDB 默认的锁算法。&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="行锁"&gt;行锁
&lt;/h2&gt;&lt;h2 id="行锁分类"&gt;行锁分类
&lt;/h2&gt;&lt;p&gt;行锁在逻辑上主要分为两类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;共享锁 (S 锁 / Shared Lock)&lt;/strong&gt;：又称读锁。允许事务读取一行数据。多个事务可以同时持有同一行的 S 锁。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;特点&lt;/em&gt;：兼容 S 锁，冲突 X 锁。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;排他锁 (X 锁 / Exclusive Lock)&lt;/strong&gt;：又称写锁。允许事务删除或更新一行数据。当一个事务持有 X 锁时，其他事务无法再对该行加任何锁。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;特点&lt;/em&gt;：冲突一切锁（包括 S 和 X）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;SQL 语句&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;行锁类型&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;INSERT ...&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;排他锁 (X)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;自动加锁。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;UPDATE ...&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;排他锁 (X)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;自动加锁。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;DELETE ...&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;排他锁 (X)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;自动加锁。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;SELECT (正常)&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;不加任何锁&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;基于 MVCC 实现的快照读，不阻塞其他事务。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;SELECT ... LOCK IN SHARE MODE&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;共享锁 (S)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;需要手动在 &lt;code&gt;SELECT&lt;/code&gt; 之后添加（兼容 S，互斥 X）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;SELECT ... FOR UPDATE&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;排他锁 (X)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;需要手动在 &lt;code&gt;SELECT&lt;/code&gt; 之后添加（互斥 S 和 X）。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIPS]
InnoDB 的行锁是通过&lt;strong&gt;给索引上的索引项加锁&lt;/strong&gt;来实现的，而不是针对记录本身。
这意味着：&lt;strong&gt;如果你的 SQL 没有走索引，行锁就会升级为表锁。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="间隙锁和临键锁"&gt;间隙锁和临键锁
&lt;/h2&gt;&lt;p&gt;在 InnoDB 的 &lt;strong&gt;可重复读 (RR)&lt;/strong&gt; 隔离级别下，间隙锁和临键锁是解决 &lt;strong&gt;幻读 (PR)&lt;/strong&gt; 的核心机制。它们都是行级锁的变体，但是锁定的范围不同&lt;/p&gt;
&lt;h3 id="间隙锁-gap-lock"&gt;间隙锁 (Gap Lock)
&lt;/h3&gt;&lt;p&gt;间隙锁锁定的不是记录本身，而是两条索引记录之间的“间隙”，或者是第一条记录之前、最后一条记录之后的空间。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;目的&lt;/strong&gt;：防止其他事务在间隙中插入（INSERT）新数据，从而避免幻读。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;特性&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;间隙锁之间是&lt;strong&gt;兼容&lt;/strong&gt;的。一个事务持有的间隙锁不会阻止另一个事务在同一个间隙上获取间隙锁。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;它们唯一的冲突点是：&lt;strong&gt;防止其他事务插入数据&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;示例&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;假设表中 id 有 1, 5, 10。执行 &lt;code&gt;SELECT * FROM t WHERE id = 3 FOR UPDATE;&lt;/code&gt;。
由于 id=3 不存在，InnoDB 会在 (1, 5) 这个间隙加锁。此时，任何想插入 id=2, 3, 4 的操作都会被阻塞。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="临键锁-next-key-lock"&gt;临键锁 (Next-Key Lock)
&lt;/h3&gt;&lt;p&gt;临键锁是 &lt;strong&gt;记录锁 (Record Lock)&lt;/strong&gt; 和 &lt;strong&gt;间隙锁 (Gap Lock)&lt;/strong&gt; 的组合。它既锁定索引记录本身，也锁定记录之前的间隙。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;公式&lt;/strong&gt;：Next-Key Lock = Gap Lock + Record Lock。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;范围&lt;/strong&gt;：默认是&lt;strong&gt;左开右闭&lt;/strong&gt;区间。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;默认机制&lt;/strong&gt;：InnoDB 在 RR 隔离级别下，对行扫描时默认加的就是 Next-Key Lock。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;示例&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;假设表中 id 有 1, 5, 10。执行范围查询 &lt;code&gt;WHERE id &amp;gt; 5 AND id &amp;lt;= 10 FOR UPDATE&lt;/code&gt;。
临键锁会锁定区间 &lt;strong&gt;(5, 10]&lt;/strong&gt;。这包括了间隙 (5, 10) 和记录 id=10 本身。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="锁的退化规则-优化"&gt;锁的退化规则 (优化)
&lt;/h3&gt;&lt;p&gt;为了提高并发性能，InnoDB 在某些特定条件下会将临键锁“降级”：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;唯一索引等值查询（记录存在）&lt;/strong&gt;：
当使用主键或唯一索引进行等值查询，且记录确实存在时，Next-Key Lock 会退化为 &lt;strong&gt;记录锁 (Record Lock)&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;原因&lt;/em&gt;：既然记录是唯一的且已存在，就不可能再插入相同的记录，没必要锁间隙。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;唯一索引等值查询（记录不存在）&lt;/strong&gt;：
当查询的记录不存在时，Next-Key Lock 会退化为 &lt;strong&gt;间隙锁 (Gap Lock)&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;范围&lt;/em&gt;：锁定该值所在的那个间隙。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;非唯一索引（普通索引）查询&lt;/strong&gt;：
即便命中记录，InnoDB 也会在记录两边加锁（Next-Key Lock 加上右侧的 Gap Lock），以确保不会有新的相同索引值插入。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h3 id="总结对比"&gt;总结对比
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;锁类型&lt;/th&gt;
					&lt;th style="text-align: left"&gt;锁定对象&lt;/th&gt;
					&lt;th style="text-align: left"&gt;包含记录本身&lt;/th&gt;
					&lt;th style="text-align: left"&gt;主要作用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;记录锁 (Record Lock)&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;单行记录&lt;/td&gt;
					&lt;td style="text-align: left"&gt;是&lt;/td&gt;
					&lt;td style="text-align: left"&gt;防止其他事务修改或删除该行&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;间隙锁 (Gap Lock)&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;索引之间的间隙&lt;/td&gt;
					&lt;td style="text-align: left"&gt;否&lt;/td&gt;
					&lt;td style="text-align: left"&gt;防止其他事务插入数据，解决幻读&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;临键锁 (Next-Key Lock)&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;间隙 + 记录&lt;/td&gt;
					&lt;td style="text-align: left"&gt;是&lt;/td&gt;
					&lt;td style="text-align: left"&gt;RR 级别下的默认锁，结合了前两者优点&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;核心提示&lt;/strong&gt;：间隙锁和临键锁只在 &lt;strong&gt;可重复读 (RR)&lt;/strong&gt; 或更严苛的隔离级别下生效。在 &lt;strong&gt;读已提交 (RC)&lt;/strong&gt; 级别下，间隙锁会被禁用（除非涉及外键约束或重复键检查）。&lt;/p&gt;</description></item><item><title>多表查询</title><link>https://creat.asia/post/%E5%A4%9A%E8%A1%A8%E6%9F%A5%E8%AF%A2/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/%E5%A4%9A%E8%A1%A8%E6%9F%A5%E8%AF%A2/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-02&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="sql-进阶---多表查询"&gt;SQL 进阶 - 多表查询
&lt;/h1&gt;&lt;h2 id="多表关系"&gt;多表关系
&lt;/h2&gt;&lt;p&gt;在真实业务中，合理的表结构设计是高并发、高性能查询的基石。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;一对多 (One-to-Many)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&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;strong&gt;不建立物理外键约束&lt;/strong&gt;，而是由应用层代码来保证逻辑外键的完整性。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;多对多 (Many-to-Many)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;案例&lt;/strong&gt;：学生选课；电商系统中商品与订单。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实现&lt;/strong&gt;：必须通过第三张&lt;strong&gt;中间表&lt;/strong&gt;（关联表）来实现。中间表通常包含两个外键，分别对应两张原表的主键。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实战细节&lt;/strong&gt;：中间表除了存储双方的 ID，往往还会挂载业务字段，比如“选课时间”、“购买数量”等。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;一对一 (One-to-One)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;案例&lt;/strong&gt;：用户基础表与用户隐私详情表。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实现&lt;/strong&gt;：在任意一方加入外键，并设置&lt;strong&gt;唯一约束 (UNIQUE)&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实战细节&lt;/strong&gt;：主要用于&lt;strong&gt;冷热数据分离&lt;/strong&gt;（垂直拆分）。将不常用的、大体积的字段（如用户简介）拆分出来，提升主表的查询效率。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="多表查询概述与性能陷阱"&gt;多表查询概述与性能陷阱
&lt;/h2&gt;&lt;p&gt;多表查询的本质是将多张表按照某种逻辑横向“拼接”起来。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;笛卡尔积 (Cartesian Product)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;原理&lt;/strong&gt;：不加任何条件的 &lt;code&gt;SELECT * FROM A, B;&lt;/code&gt;。如果 A 表有 1 万条数据，B 表有 1 万条数据，结果将产生 &lt;strong&gt;1 亿条&lt;/strong&gt;垃圾数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;避坑&lt;/strong&gt;：在编写任何多表查询时，&lt;strong&gt;永远先写连接条件（ON 或 WHERE）&lt;/strong&gt;，防止产生笛卡尔积导致数据库瞬间卡死。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="内连接-inner-join"&gt;内连接 (Inner Join)
&lt;/h2&gt;&lt;p&gt;最基础的连接，查询的是两张表&lt;strong&gt;完全匹配&lt;/strong&gt;的交集。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;隐式内连接&lt;/strong&gt;（传统的 SQL92 标准，可读性较差）：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; e.name, d.name 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp e, dept d 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; e.dept_id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; d.id &lt;span style="color:#66d9ef"&gt;AND&lt;/span&gt; e.salary &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;5000&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;显式内连接&lt;/strong&gt;（SQL99 标准，强烈推荐，逻辑清晰）：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-mysql" data-lang="mysql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; e.name, d.name 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp e 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#66d9ef"&gt;INNER&lt;/span&gt;] &lt;span style="color:#66d9ef"&gt;JOIN&lt;/span&gt; dept d &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; e.dept_id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; d.id &lt;span style="color:#75715e"&gt;-- INNER 可省略
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; e.salary &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;5000&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;原理&lt;/strong&gt;：MySQL 会用小表作为驱动表，去大表中进行匹配（通常配合索引提高速度）。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="外连接-outer-join"&gt;外连接 (Outer Join)
&lt;/h2&gt;&lt;p&gt;当你想保留某张表的&lt;strong&gt;全部数据&lt;/strong&gt;，即使另一张表没有对应的数据时，使用外连接。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;左外连接 (LEFT JOIN)&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特点&lt;/strong&gt;：包含左表的&lt;strong&gt;全部行&lt;/strong&gt;。如果右表没有匹配，右表的列显示为 &lt;code&gt;NULL&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;经典案例&lt;/strong&gt;：查询&lt;strong&gt;所有&lt;/strong&gt;员工及其对应的部门（包括刚入职、还没分配部门的新员工）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-mysql" data-lang="mysql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; e.name, d.name 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp e 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;LEFT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;JOIN&lt;/span&gt; dept d &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; e.dept_id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; d.id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;右外连接 (RIGHT JOIN)&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特点&lt;/strong&gt;：包含右表的全部行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实战建议&lt;/strong&gt;：在实际开发中，我们 95% 的情况下都使用 &lt;code&gt;LEFT JOIN&lt;/code&gt;。因为只需要调整表的先后顺序，&lt;code&gt;LEFT JOIN&lt;/code&gt; 完全可以替代 &lt;code&gt;RIGHT JOIN&lt;/code&gt;，代码风格更统一。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="自连接-self-join"&gt;自连接 (Self Join)
&lt;/h2&gt;&lt;p&gt;这是一道极为经典的高频面试题。当表中的&lt;strong&gt;某列关联了本表的另一列&lt;/strong&gt;时使用。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;典型场景&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;员工表（包含 &lt;code&gt;emp_id&lt;/code&gt; 和 &lt;code&gt;manager_id&lt;/code&gt;，领导也是员工）。&lt;/li&gt;
&lt;li&gt;地区表（包含 &lt;code&gt;area_id&lt;/code&gt; 和 &lt;code&gt;parent_id&lt;/code&gt;，省、市、区都在一张表里）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;核心技巧&lt;/strong&gt;：必须把一张表当成两张完全独立的表来看待，通过&lt;strong&gt;别名&lt;/strong&gt;加以区分。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;案例&lt;/strong&gt;：查询员工姓名及其直属领导的姓名。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-mysql" data-lang="mysql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 这里 a 代表员工表，b 代表领导表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; a.name &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;员工&amp;#39;&lt;/span&gt;, b.name &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;领导&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp a 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;LEFT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;JOIN&lt;/span&gt; emp b &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; a.manager_id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; b.id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="联合查询-union"&gt;联合查询 (Union)
&lt;/h2&gt;&lt;p&gt;用于把多次 &lt;code&gt;SELECT&lt;/code&gt; 的结果集&lt;strong&gt;纵向拼接&lt;/strong&gt;在一起，变成一个大结果集。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;UNION&lt;/strong&gt;：自动去除重复的行，性能稍低，因为包含去重排序的操作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UNION ALL&lt;/strong&gt;：直接拼接，不进行去重。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能军规&lt;/strong&gt;：除非业务明确要求去重，否则在实际开发中&lt;strong&gt;一律优先使用 &lt;code&gt;UNION ALL&lt;/code&gt;&lt;/strong&gt;，性能远高于 &lt;code&gt;UNION&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;限制条件&lt;/strong&gt;：
&lt;ol&gt;
&lt;li&gt;两次查询的列数必须相同。&lt;/li&gt;
&lt;li&gt;对应列的字段类型或语义必须一致。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="子查询-subquery-全景解析"&gt;子查询 (Subquery) 全景解析
&lt;/h2&gt;&lt;p&gt;子查询是多表查询中极具技巧性的部分。根据子查询&lt;strong&gt;返回结果的不同&lt;/strong&gt;，分为以下四类：&lt;/p&gt;
&lt;h3 id="标量子查询"&gt;标量子查询
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特征&lt;/strong&gt;：子查询只返回&lt;strong&gt;一个孤零零的值&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;案例&lt;/strong&gt;：查询薪资比“张三”高的所有员工&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; salary &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; salary &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;张三&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="列子查询"&gt;列子查询
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特征&lt;/strong&gt;：子查询返回的是&lt;strong&gt;一列数据&lt;/strong&gt;（多行单列）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;核心操作符&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;IN&lt;/code&gt;：在指定的集合范围内。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NOT IN&lt;/code&gt;：不在范围内。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ANY&lt;/code&gt; / &lt;code&gt;SOME&lt;/code&gt;：满足其中任意一个即可。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ALL&lt;/code&gt;：必须满足所有的条件。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;案例&lt;/strong&gt;：查询研发部和销售部所有员工的工资。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; name, salary &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; dept_id &lt;span style="color:#66d9ef"&gt;IN&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; id &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; dept &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; name &lt;span style="color:#66d9ef"&gt;IN&lt;/span&gt; (&lt;span style="color:#e6db74"&gt;&amp;#39;研发部&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;销售部&amp;#39;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="行子查询"&gt;行子查询
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特征&lt;/strong&gt;：子查询返回的是&lt;strong&gt;一行数据&lt;/strong&gt;（单行多列）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;案例&lt;/strong&gt;：查询与“李四”的薪资&lt;strong&gt;且&lt;/strong&gt;直属领导完全相同的员工。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; (salary, manager_id) &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; salary, manager_id &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;李四&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="表子查询"&gt;表子查询
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特征&lt;/strong&gt;：子查询返回的是&lt;strong&gt;一个二维表格&lt;/strong&gt;（多行多列）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;经典用法&lt;/strong&gt;：作为 &lt;code&gt;FROM&lt;/code&gt; 后面的&lt;strong&gt;临时表&lt;/strong&gt;使用，或者用 &lt;code&gt;IN&lt;/code&gt; 配合多列。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;案例&lt;/strong&gt;：查询入职日期在“2025-01-01”之后的员工，并关联他们的部门信息。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 将子查询的结果作为一张临时表 temp
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; t.name, d.dept_name 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; entry_date &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;2025-01-01&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	)t
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;LEFT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;JOIN&lt;/span&gt; dept d &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; t.dept_id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; d.id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="外键约束"&gt;外键约束
&lt;/h1&gt;&lt;h2 id="一对多"&gt;一对多
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;父表（Parent Table / Referenced Table）&lt;/strong&gt;：被引用的表，通常主键（Primary Key）所在的表&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;子表（Child Table / Foreign Key Table）&lt;/strong&gt;：引用父表的表，外键所在的表&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;外键列&lt;/strong&gt;：子表中存储父表主键值的列&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 父表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Departments&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; DeptID &lt;span style="color:#66d9ef"&gt;INT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; DeptName &lt;span style="color:#66d9ef"&gt;VARCHAR&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;50&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 子表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Emp&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; EmpID &lt;span style="color:#66d9ef"&gt;INT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; EmpName &lt;span style="color:#66d9ef"&gt;VARCHAR&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;50&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; DeptID &lt;span style="color:#66d9ef"&gt;INT&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;-- 定义外键约束
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;CONSTRAINT&lt;/span&gt; fk_dept 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;FOREIGN&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt; (DeptID) &lt;span style="color:#66d9ef"&gt;REFERENCES&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Departments&lt;/span&gt;(DeptID)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;DELETE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;CASCADE&lt;/span&gt; &lt;span style="color:#75715e"&gt;-- 部门删除时，员工也自动删除
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果表已经创建好了，可以使用 &lt;code&gt;ALTER TABLE&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 添加外键
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;ALTER&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; Emp &lt;span style="color:#66d9ef"&gt;ADD&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;CONSTRAINT&lt;/span&gt; fk_dept &lt;span style="color:#66d9ef"&gt;FOREIGN&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt; (DeptID) &lt;span style="color:#66d9ef"&gt;REFERENCES&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Departments&lt;/span&gt;(DeptID)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 删除外键
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;ALTER&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; Emp &lt;span style="color:#66d9ef"&gt;DROP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FOREIGN&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt; fk_dept
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="一对一"&gt;一对一
&lt;/h2&gt;&lt;p&gt;一个用户只能有一个身份证号，一个身份证号也只能对应一个用户&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 用户表（主表）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Users&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; user_id &lt;span style="color:#66d9ef"&gt;INT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;AUTO_INCREMENT&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; username &lt;span style="color:#66d9ef"&gt;VARCHAR&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;50&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 身份证表（从表）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;IDCards&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; card_id &lt;span style="color:#66d9ef"&gt;INT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;AUTO_INCREMENT&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; card_number &lt;span style="color:#66d9ef"&gt;CHAR&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;18&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;UNIQUE&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; user_id &lt;span style="color:#66d9ef"&gt;INT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;UNIQUE&lt;/span&gt;, &lt;span style="color:#75715e"&gt;-- 关键点：UNIQUE 约束确保一对一
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;CONSTRAINT&lt;/span&gt; fk_user &lt;span style="color:#66d9ef"&gt;FOREIGN&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt; (user_id) &lt;span style="color:#66d9ef"&gt;REFERENCES&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Users&lt;/span&gt;(user_id)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="多对多"&gt;多对多
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 学生表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Students&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; student_id &lt;span style="color:#66d9ef"&gt;INT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;AUTO_INCREMENT&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name &lt;span style="color:#66d9ef"&gt;VARCHAR&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;50&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 课程表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Courses&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; course_id &lt;span style="color:#66d9ef"&gt;INT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;AUTO_INCREMENT&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; title &lt;span style="color:#66d9ef"&gt;VARCHAR&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;50&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 中间表（维护多对多关系）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Student_Courses&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; student_id &lt;span style="color:#66d9ef"&gt;INT&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; course_id &lt;span style="color:#66d9ef"&gt;INT&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt; (student_id, course_id), &lt;span style="color:#75715e"&gt;-- 联合主键防止重复选课
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;CONSTRAINT&lt;/span&gt; fk_student 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;FOREIGN&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt; (student_id) &lt;span style="color:#66d9ef"&gt;REFERENCES&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Students&lt;/span&gt;(student_id),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;CONSTRAINT&lt;/span&gt; fk_course 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;FOREIGN&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt; (course_id) &lt;span style="color:#66d9ef"&gt;REFERENCES&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Courses&lt;/span&gt;(course_id)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;联合主键（Composite Primary Key）&lt;/strong&gt;：中间表通常建议使用 &lt;code&gt;(ID_A, ID_B)&lt;/code&gt; 作为联合主键，这样可以从物理层面防止数据重复（例如：防止同一个学生对同一门课选两次）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;冗余字段&lt;/strong&gt;：中间表不一定只能有两个 ID。它还可以存储“关系本身”的属性。例如：在 &lt;code&gt;Student_Courses&lt;/code&gt; 中增加 &lt;code&gt;score&lt;/code&gt;（成绩）或 &lt;code&gt;enroll_date&lt;/code&gt;（选课时间）字段&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查询方式&lt;/strong&gt;：查询多对多数据通常需要 &lt;strong&gt;两次 JOIN&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;查询张三选了哪些课：&lt;/em&gt; &lt;code&gt;Students&lt;/code&gt; JOIN &lt;code&gt;Student_Courses&lt;/code&gt; JOIN &lt;code&gt;Courses&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="物理外键的缺点"&gt;物理外键的缺点
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;性能瓶颈&lt;/strong&gt;：在高并发写入时，外键校验会导致频繁的行锁竞争，降低吞吐量&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;分库分表困难&lt;/strong&gt;：当数据量大到需要拆分到不同物理数据库时，跨库的物理外键是无法实现的&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;死锁风险&lt;/strong&gt;：复杂的级联更新容易导致数据库产生死锁，排查极其困难&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;测试麻烦&lt;/strong&gt;：手动构造测试数据时，必须先造父表再造子表，流程繁琐&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="个人常犯的错误"&gt;个人常犯的错误
&lt;/h1&gt;&lt;h2 id="题目要求查询拥有员工的部门"&gt;题目要求：查询拥有员工的部门
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;内连接！&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;INNER JOIN&lt;/strong&gt; = 只查两边都匹配的数据（最适合本题）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;RIGHT JOIN&lt;/strong&gt; 会把没有部门的员工也带进来，&lt;strong&gt;产生 NULL 部门&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;题目要&lt;strong&gt;有员工的部门&lt;/strong&gt; → 必须用 &lt;strong&gt;INNER JOIN&lt;/strong&gt; 或加 &lt;strong&gt;IS NOT NULL&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MYSQL" data-lang="MYSQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt; d.dept_name &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; department d 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;INNER&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;JOIN&lt;/span&gt; employee e 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; e.dept_id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; d.dept_id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="join的使用"&gt;JOIN的使用
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; e.emp_name &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; employee e 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;JOIN&lt;/span&gt;( 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; dept_id,&lt;span style="color:#a6e22e"&gt;AVG&lt;/span&gt;(salary) &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; avg_salary 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; employee 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;GROUP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; dept_id 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	)t &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; e.dept_id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; t.dept_id 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; e.salary &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; t.avg_salary;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;此&lt;code&gt;SQL&lt;/code&gt;语句等价于&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; e.emp_name &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; employee e 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; e.salary &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AVG&lt;/span&gt;(salary) &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; employee &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; dept_id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; e.dept_id);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="count是什么"&gt;&lt;code&gt;COUNT(*)&lt;/code&gt;是什么？
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;写法&lt;/th&gt;
					&lt;th&gt;意思&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;COUNT(*)&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;数&lt;strong&gt;总行数&lt;/strong&gt;，包括 NULL&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;COUNT(字段)&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;数这个字段&lt;strong&gt;不为 NULL&lt;/strong&gt; 的行数&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;COUNT(1)&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;效果基本同 &lt;code&gt;COUNT(*)&lt;/code&gt;，也是数行数&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;COUNT(*)&lt;/code&gt;：&lt;strong&gt;统计当前组里一共有多少条记录&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 查询每个部门的人数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; d.dept_name,&lt;span style="color:#a6e22e"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#f92672"&gt;*&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; employee e,department d 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; e.dept_id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; d.dept_id &lt;span style="color:#66d9ef"&gt;GROUP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; d.dept_name;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>进阶-存储引擎</title><link>https://creat.asia/post/%E8%BF%9B%E9%98%B6-%E5%AD%98%E5%82%A8%E5%BC%95%E6%93%8E/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/%E8%BF%9B%E9%98%B6-%E5%AD%98%E5%82%A8%E5%BC%95%E6%93%8E/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-02&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="mysql-体系结构"&gt;MySQL 体系结构
&lt;/h1&gt;&lt;h2 id="连接层-connection-layer"&gt;连接层 (Connection Layer)
&lt;/h2&gt;&lt;p&gt;最上层由一些客户端和链接服务组成，主要完成连接处理、授权认证及相关的安全方案。服务器会为每个成功接入的客户端验证其所具有的操作权限，确保数据访问的安全性。&lt;/p&gt;
&lt;h2 id="服务层-service-layer"&gt;服务层 (Service Layer)
&lt;/h2&gt;&lt;p&gt;第二层架构是 MySQL 的大脑，主要完成大多数的核心服务功能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;功能组件&lt;/strong&gt;：包括 SQL 接口、解析器、优化器以及部分内置函数的执行（如日期、时间、数学函数等）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;跨引擎实现&lt;/strong&gt;：所有跨存储引擎的功能都在这一层实现，例如存储过程、触发器、视图等。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;查询缓存&lt;/strong&gt;：完成对 SQL 查询缓存的处理和匹配。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="存储引擎层"&gt;存储引擎层
&lt;/h2&gt;&lt;h3 id="引擎层-engine-layer"&gt;引擎层 (Engine Layer)
&lt;/h3&gt;&lt;p&gt;存储引擎层真正负责了 MySQL 中数据的存储和提取，是插件式的架构。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;通信方式&lt;/strong&gt;：服务器通过 API 与不同的存储引擎进行通信。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;灵活选择&lt;/strong&gt;：不同的存储引擎具有不同的特性和功能（如 InnoDB 支持事务，而 MyISAM 不支持），我们可以根据业务需求选取合适的存储引擎。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="存储层-storage-layer"&gt;存储层 (Storage Layer)
&lt;/h3&gt;&lt;p&gt;最底层是数据存储层，主要将数据存储在文件系统之上（如磁盘、日志文件等），并完成与上层存储引擎的数据交互。&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="存储引擎"&gt;存储引擎
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;存储引擎就是&lt;strong&gt;存储数据、建立索引、更新/查询数据&lt;/strong&gt;等技术的实现方式。存储引擎是&lt;strong&gt;基于表&lt;/strong&gt;的，而不是基于数据库的，所以存储引擎也可以被称为表类型。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="核心innodb-存储引擎"&gt;核心：InnoDB 存储引擎
&lt;/h2&gt;&lt;p&gt;InnoDB 是 MySQL 5.5 之后默认的存储引擎，也是最通用的引擎。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特点&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;事务 (ACID)&lt;/strong&gt;：DML操作支持事务安全，具有提交、回滚和崩溃恢复能力。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;外键 (Foreign Key)&lt;/strong&gt;：支持外键约束，保证数据的完整性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;行级锁 (Row-level Locking)&lt;/strong&gt;：提高多用户并发操作的性能。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文件存储&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;每一张 InnoDB 表对应一个 &lt;code&gt;.ibd&lt;/code&gt; 表空间文件（存储表结构(frm,sdi)、数据和索引）&lt;/li&gt;
&lt;li&gt;参数：&lt;code&gt;innodb_file_per_table&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;逻辑存储结构&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;TableSpace（表空间） -&amp;gt; Segment（段） -&amp;gt; Extent（区，1MB） -&amp;gt; Page（页，16KB，磁盘操作的最小单元） -&amp;gt; Row（行）
&lt;img src="https://creat.asia/post/image/%e8%bf%9b%e9%98%b6-%e5%ad%98%e5%82%a8%e5%bc%95%e6%93%8e-1.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="myisam-存储引擎"&gt;MyISAM 存储引擎
&lt;/h2&gt;&lt;p&gt;MyISAM 是 MySQL 早期的默认存储引擎。它不支持事务，但在读取性能和空间占用上具有一定优势。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;介绍&lt;/strong&gt;：主要用于以读为主的业务场景。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;特点&lt;/strong&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;strong&gt;文件存储&lt;/strong&gt;：每一张 MyISAM 表对应三个文件：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;xxx.sdi&lt;/code&gt;：存储表结构信息（JSON 格式）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;xxx.MYD&lt;/code&gt;：存储数据 (MYData)。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;xxx.MYI&lt;/code&gt;：存储索引 (MYIndex)。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="memory-存储引擎"&gt;Memory 存储引擎
&lt;/h2&gt;&lt;p&gt;Memory 引擎将表数据存储在内存中，由于不需要磁盘 I/O，其访问速度极快。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;介绍&lt;/strong&gt;：通常用于存储临时数据、缓存或中间计算结果。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;特点&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;内存存放：速度极快，但安全性低。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;易失性&lt;/strong&gt;：一旦数据库重启或崩溃，内存表中的数据会全部丢失，但表结构会保留。&lt;/li&gt;
&lt;li&gt;默认使用 &lt;strong&gt;Hash 索引&lt;/strong&gt;（适合等值查询，不适合范围查询）。&lt;/li&gt;
&lt;li&gt;支持表级锁。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文件存储&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;xxx.sdi&lt;/code&gt;：只存储表结构信息。数据全部驻留在内存中，不生成物理数据文件。
&lt;strong&gt;重点&lt;/strong&gt;
&lt;img src="https://creat.asia/post/image/%e8%bf%9b%e9%98%b6-%e5%ad%98%e5%82%a8%e5%bc%95%e6%93%8e-2.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="存储引擎选择建议"&gt;存储引擎选择建议
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;InnoDB&lt;/strong&gt;：&lt;strong&gt;首选&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果应用对事务的完整性有要求，或者需要处理高并发的增删改查操作，InnoDB 是唯一的选择。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;MyISAM&lt;/strong&gt;：过去MySQL的引擎&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果应用是以读操作和插入操作为主，只有很少的更新和删除操作，并且对事务的完整性、并发性要求不是很高，那么可以选择 MyISAM（但在现代开发中已逐渐被 InnoDB 取代）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Memory&lt;/strong&gt;：将所有数据保存在&lt;strong&gt;内存&lt;/strong&gt;中，访问&lt;strong&gt;速度极快&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;通常用于存储临时数据或缓存，由于数据在断电或重启后会丢失，因此不适合存储持久化数据。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="存储引擎相关-sql-操作"&gt;存储引擎相关 SQL 操作
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;查看当前数据库支持的存储引擎&lt;/strong&gt;：
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SHOW&lt;/span&gt; ENGINES;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;创建表时指定存储引擎&lt;/strong&gt;：
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;) ENGINE &lt;span style="color:#f92672"&gt;=&lt;/span&gt; INNODB;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;查询建表语句（查看当前表引擎）&lt;/strong&gt;：
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SHOW&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>进阶-索引</title><link>https://creat.asia/post/%E8%BF%9B%E9%98%B6-%E7%B4%A2%E5%BC%95/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/%E8%BF%9B%E9%98%B6-%E7%B4%A2%E5%BC%95/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-02&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="mysql-索引概述-index"&gt;MySQL 索引概述 (Index)
&lt;/h1&gt;&lt;p&gt;索引是帮助 MySQL &lt;strong&gt;高效获取数据&lt;/strong&gt; 的 &lt;strong&gt;数据结构 (有序)&lt;/strong&gt;。（⭐⭐⭐）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在数据之外，数据库系统还维护着满足特定查找算法的数据结构，这些数据结构以某种方式引用（指向）数据， 这样就可以在这些数据结构上实现高级查找算法，这种数据结构就是索引&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="索引的优缺点"&gt;索引的优缺点
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;特性&lt;/th&gt;
					&lt;th style="text-align: left"&gt;优点&lt;/th&gt;
					&lt;th style="text-align: left"&gt;缺点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;查询效率&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;提高数据检索的效率，降低数据库的 IO 成本。&lt;/td&gt;
					&lt;td style="text-align: left"&gt;索引列也是要占用空间的。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;排序效率&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;通过索引列对数据进行排序，降低 CPU 的消耗。&lt;/td&gt;
					&lt;td style="text-align: left"&gt;索引大大提高了查询效率，但降低了更新表的速度（如 INSERT、UPDATE、DELETE）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="索引的本质数据结构"&gt;索引的本质：数据结构
&lt;/h2&gt;&lt;p&gt;假设有一张包含数百万条记录的表，如果没有索引，数据库必须进行&lt;strong&gt;全表扫描 (Full Table Scan)&lt;/strong&gt;，即从第一行开始逐行比对，效率极低。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;无索引&lt;/strong&gt;：$O(n)$ 的时间复杂度。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;有索引&lt;/strong&gt;：通过 B+Tree 等结构，将复杂度降低至 $O(\log n)$。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="索引结构"&gt;索引结构
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;在&lt;a class="link" href="MySQL/%e8%bf%9b%e9%98%b6-%e5%ad%98%e5%82%a8%e5%bc%95%e6%93%8e##%e5%ad%98%e5%82%a8%e5%bc%95%e6%93%8e%e5%b1%82" &gt;存储引擎层&lt;/a&gt;实现，不同的存储引擎有着不同的索引结构&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;索引结构&lt;/th&gt;
					&lt;th style="text-align: left"&gt;描述&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;B+Tree 索引&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;最常见的索引类型，大部分引擎都支持。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Hash 索引&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;底层采用哈希表实现，只有 Memory 引擎支持，不支持范围查询。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;R-tree 索引&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;空间索引，主要用于地理信息数据类型（MyISAM 支持）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Full-text 索引&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;全文索引，通过建立倒排索引快速匹配文本中的关键词。类似于：Lucence，Solr，ES&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src="https://creat.asia/post/image/%e8%bf%9b%e9%98%b6-%e7%b4%a2%e5%bc%95-1.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：InnoDB 具有&lt;strong&gt;自适应哈希索引 (Adaptive Hash Index)&lt;/strong&gt; 功能。当 InnoDB 注意到某些索引值被频繁查询时，会在内存中自动基于 B+Tree 索引建立哈希索引，以加速等值寻找。&lt;/p&gt;
&lt;h2 id="b-tree"&gt;B-Tree
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class="link" href="JavaSE/09-%e6%95%b0%e6%8d%ae%e7%bb%93%e6%9e%84###%e5%bc%8a%e7%ab%af" &gt;二叉树缺点&lt;/a&gt;：顺序插入时，会形成一个链表，查询性能大大下降。大数据量情况下，层级较深，检索速度慢&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class="link" href="JavaSE/09-%e6%95%b0%e6%8d%ae%e7%bb%93%e6%9e%84#%e7%ba%a2%e9%bb%91%e6%a0%91" &gt;红黑树&lt;/a&gt;：大数据量情况下，层次较深，检索速度慢&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;B-Tree:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.cs.usfca.edu/~galles/visualization/BTree.html" target="_blank" rel="noopener"
 &gt;点击查看演示&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;B树是一种&lt;strong&gt;多路平衡查找树&lt;/strong&gt;。这里的“多路”是指一个节点可以有多个子节点（不像二叉树只有 2 个）&lt;/li&gt;
&lt;li&gt;以一颗最大度数(max-degree)为5(5阶)的b-tree为例(每个节点最多存储4个key，5个指针)
&lt;img src="https://creat.asia/post/image/%e8%bf%9b%e9%98%b6-%e7%b4%a2%e5%bc%95-2.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="核心特征"&gt;核心特征：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;节点包含数据：&lt;/strong&gt; 每个节点既存储了&lt;strong&gt;索引键 (Key)&lt;/strong&gt;，也存储了对应的&lt;strong&gt;整行数据 (Data)&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自平衡：&lt;/strong&gt; 无论插入多少数据，树的高度始终保持平衡，确保查询效率稳定在 $O(\log n)$。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;搜索规则：&lt;/strong&gt; 类似于二叉查找树。比当前节点小的走左边，大的走右边，中间的走中间分支。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="btree"&gt;B+Tree
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class="link" href="https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html" target="_blank" rel="noopener"
 &gt;点击查看演示&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;相对于B树的区别：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;所有的数据都会出现在叶子节点&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;叶子节点形成一个单向链表&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;以一颗最大度数（max-degree）为4（4阶）的B+Tree为例：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;B+Tree 将所有数据记录节点按照键值大小顺序存放在同一层的叶子节点上，而非叶子节点只存储索引（中间键）和指向下一层的指针。
&lt;img src="https://creat.asia/post/image/%e8%bf%9b%e9%98%b6-%e7%b4%a2%e5%bc%95-3.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;B+Tree（B+树）是 B-Tree 的变体，也是 MySQL InnoDB 存储引擎索引的底层实现。&lt;/li&gt;
&lt;li&gt;在原B+Tree的基础上，增加一个指向相邻叶子节点的链表指针，就形成了带有顺序指针的B+Tree，提高区间访问的性能 -&amp;gt; 利于数据库排序
&lt;img src="https://creat.asia/post/image/%e8%bf%9b%e9%98%b6-%e7%b4%a2%e5%bc%95-4.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE] 关键区别
B树：数据分布在所有节点中。适合单一 Key 查找（像 MongoDB 部分场景）。
B+树：数据仅在叶子节点中。适合范围扫描和大规模排序（MySQL 的标准选择）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="hash索引"&gt;Hash索引
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;哈希索引（Hash Index）是建立在哈希表结构上的索引。&lt;/li&gt;
&lt;li&gt;它通过哈希算法将列值转换为哈希码（Hash Code），并将其映射到对应的桶（Bucket）中&lt;/li&gt;
&lt;li&gt;如果两个(或多个)键值，映射到一个相同的槽位上，他们就产生了hash冲突(也称为hash碰撞)，可以通过链表来解决
&lt;img src="https://creat.asia/post/image/%e8%bf%9b%e9%98%b6-%e7%b4%a2%e5%bc%95-5.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="工作原理"&gt;工作原理
&lt;/h3&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;h3 id="hash-索引的特点"&gt;Hash 索引的特点
&lt;/h3&gt;&lt;h4 id="优势查询速度极快"&gt;优势：查询速度极快
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;等值查询&lt;/strong&gt;：对于 &lt;code&gt;=&lt;/code&gt;、&lt;code&gt;IN&lt;/code&gt;、&lt;code&gt;&amp;lt;=&amp;gt;&lt;/code&gt; 操作，通常只需要一次检索即可定位数据。（前提不出现哈希冲突）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;复杂度&lt;/strong&gt;：理想情况下，时间复杂度为 $O(1)$，性能优于 B+Tree 的 $O(\log n)$。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="局限性重点"&gt;局限性（重点）
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;不支持范围查询&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;哈希码的大小顺序与原始值的大小顺序无关，因此无法处理 &lt;code&gt;&amp;gt;&lt;/code&gt;、&lt;code&gt;&amp;lt;&lt;/code&gt;、&lt;code&gt;BETWEEN&lt;/code&gt; 或 &lt;code&gt;LIKE&lt;/code&gt; 前缀匹配。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;无法利用索引排序&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;由于存储是无序的，数据库无法利用哈希索引来加速 &lt;code&gt;ORDER BY&lt;/code&gt; 操作。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;不支持部分索引列匹配&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对于复合索引，Hash 索引必须使用全部索引列才能计算哈希值。例如索引 &lt;code&gt;(A, B)&lt;/code&gt;，只查 &lt;code&gt;A&lt;/code&gt; 无法使用索引。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;哈希碰撞（Hash Collision）&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果大量不同键值的哈希码相同，会导致碰撞，此时需要遍历链表，查询效率会随之下降。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;在MySQL中，支持hash索引的是Memory引擎，而innoDB中具有自适应hash功能，hash索引是存储引擎根据B+Tree索引在指定条件下自动构建的&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="问题"&gt;问题&amp;hellip;
&lt;/h2&gt;&lt;h3 id="为什么innodb存储引擎选择使用btree索引结构"&gt;为什么InnoDB存储引擎选择使用B+tree索引结构?
&lt;/h3&gt;&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;虽然 Hash 索引查询单条数据是 $O(1)$，但它不支持模糊查询（&lt;code&gt;LIKE&lt;/code&gt;）和范围查询（&lt;code&gt;&amp;gt;&lt;/code&gt; &lt;code&gt;&amp;lt;&lt;/code&gt;），且容易产生哈希冲突。因此 InnoDB 只将其作为“自适应哈希索引”插件使用，核心结构依然是 B+Tree&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;对于B-tree，无论是叶子节点还是非叶子节点，都会保存数据，这样导致一页中存储的键值减少，指针跟着减少，要同样保存大量数据，只能增加树的高度，导致性能降低&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;相对Hash索引，B+Tree支持范围匹配及排序操作&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h3 id="为什么数据库初衷想用-b树"&gt;为什么数据库初衷想用 B树？
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;相比于二叉树（如红黑树、AVL树），B树在数据库中有巨大优势：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;降低树的高度：&lt;/strong&gt; 数据库数据量极大。二叉树太高了，意味着找个数据要进行很多次磁盘 IO。B树通过增加“路数”，让树变得“矮胖”，通常 3-4 层就能支撑百万级数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;磁盘预读策略：&lt;/strong&gt; 数据库每次从磁盘读数据都是按“页（Page）”读的。B树的节点大小可以设计得刚好等于一个磁盘页，一次 IO 就能把一整个节点加载到内存。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h1 id="索引分类"&gt;索引分类
&lt;/h1&gt;&lt;h2 id="从逻辑业务层面分类"&gt;从逻辑业务层面分类
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;索引名称&lt;/th&gt;
					&lt;th style="text-align: left"&gt;关键字&lt;/th&gt;
					&lt;th style="text-align: left"&gt;功能描述&lt;/th&gt;
					&lt;th style="text-align: left"&gt;限制&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;主键索引&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;PRIMARY KEY&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;针对表的主键创建的索引。&lt;/td&gt;
					&lt;td style="text-align: left"&gt;默认自动创建，唯一且不允许 NULL。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;唯一索引&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;UNIQUE&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;避免同一个表中某列的数据重复。&lt;/td&gt;
					&lt;td style="text-align: left"&gt;允许有 NULL 值，但值必须唯一。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;常规索引&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;INDEX&lt;/code&gt; / &lt;code&gt;KEY&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;快速定位特定数据，最常用的类型。&lt;/td&gt;
					&lt;td style="text-align: left"&gt;无限制，可重复。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;全文索引&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;FULLTEXT&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;用于在大量文本中查找关键词。&lt;/td&gt;
					&lt;td style="text-align: left"&gt;主要用于 &lt;code&gt;CHAR&lt;/code&gt;、&lt;code&gt;VARCHAR&lt;/code&gt;、&lt;code&gt;TEXT&lt;/code&gt;。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="从物理存储层面分类-innodb-引擎核心"&gt;从物理存储层面分类 (InnoDB 引擎核心)
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;类型&lt;/th&gt;
					&lt;th style="text-align: left"&gt;定义&lt;/th&gt;
					&lt;th style="text-align: left"&gt;特点&lt;/th&gt;
					&lt;th style="text-align: left"&gt;选取/规则&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;聚集索引&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;数据与索引存放在一起，叶子节点存储完整行数据&lt;/td&gt;
					&lt;td style="text-align: left"&gt;每张表&lt;strong&gt;有且只有一个&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;1. 主键优先&lt;br&gt;2. 无主键则用第一个唯一索引&lt;br&gt;3. 都无则自动生成隐式 rowid&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;二级索引&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;数据与索引分开存储，叶子节点存储&lt;strong&gt;主键值&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;一张表可以有&lt;strong&gt;多个&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;查找非索引字段需要执行&lt;strong&gt;回表查询&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;img src="https://creat.asia/post/image/%e8%bf%9b%e9%98%b6-%e7%b4%a2%e5%bc%95-6.png"
 loading="lazy"
 data-pending-gallery
 alt="聚集索引与二级索引（非聚焦索引）"
 &gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;img src="https://creat.asia/post/image/%e8%bf%9b%e9%98%b6-%e7%b4%a2%e5%bc%95-7.png"
 loading="lazy"
 data-pending-gallery
 alt="回表查询"
 &gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="问题-1"&gt;问题&amp;hellip;
&lt;/h2&gt;&lt;h3 id="为什么不建议在所有列上都建索引"&gt;为什么不建议在所有列上都建索引？
&lt;/h3&gt;&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;虽然索引能加快查询，但每增加一个索引，都会增加 &lt;strong&gt;INSERT/UPDATE/DELETE&lt;/strong&gt; 的开销，因为数据库在修改数据的同时还要维护索引树的有序性。&lt;/li&gt;
&lt;li&gt;同时，索引也会占用额外的物理磁盘空间&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id="以下sql语句哪个执行效率高为什么"&gt;以下SQL语句，哪个执行效率高，为什么？
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;user&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;user&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Arm&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 备注：id 为主键，name字段创建的有索引
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;第一条语句：基于 &lt;code&gt;id&lt;/code&gt;（聚簇索引）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;搜索路径&lt;/strong&gt;：直接在主键 B+Tree 中搜索。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;结果获取&lt;/strong&gt;：由于主键索引是&lt;strong&gt;聚簇索引&lt;/strong&gt;，它的叶子节点直接存放了这一行的&lt;strong&gt;完整数据&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;效率&lt;/strong&gt;：只需搜索一棵树，找到 &lt;code&gt;id=10&lt;/code&gt; 的节点后，直接取出整行记录。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;第二条语句：基于 &lt;code&gt;name&lt;/code&gt;（二级索引/辅助索引）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;第一步（搜索二级索引）&lt;/strong&gt;：在 &lt;code&gt;name&lt;/code&gt; 字段的 B+Tree 中搜索 &lt;code&gt;'Arm'&lt;/code&gt;。二级索引的叶子节点存放的是该行对应的&lt;strong&gt;主键值&lt;/strong&gt;（即 &lt;code&gt;id=10&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;第二步（回表查询）&lt;/strong&gt;：拿到主键值后，程序必须&lt;strong&gt;再跑去主键索引树&lt;/strong&gt;里搜一遍，才能拿到 &lt;code&gt;SELECT *&lt;/code&gt; 所需的完整行数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;效率&lt;/strong&gt;：需要搜索两棵树。这个过程被称为 &lt;strong&gt;“回表”（Look-up）&lt;/strong&gt;，多了一次树的遍历和可能的磁盘 I/O。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;步骤&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;WHERE id = 10&lt;/th&gt;
					&lt;th&gt;WHERE name = &amp;lsquo;Arm&amp;rsquo;&lt;/th&gt;
					&lt;th&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;第一步&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;查找主键 B+Tree&lt;/td&gt;
					&lt;td&gt;查找 &lt;code&gt;name&lt;/code&gt; 索引 B+Tree&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;第二步&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;直接返回数据&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;获取主键值&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;第三步&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;-&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;回到主键 B+Tree 查找完整数据（回表）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;I/O 次数&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;较少&lt;/td&gt;
					&lt;td&gt;较多&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="innodb主键索引的btree高度为多高"&gt;InnoDB主键索引的B+tree高度为多高
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;InnoDB 的 B+Tree 高度通常在 3 到 4 层，因为根节点和二级节点存的是‘主键+指针’（16KB 的页约能存 1170 个分支），只有叶子节点存‘整行数据’（约能存 16 行），这种‘矮胖’结构使得 3 层树就能支撑约 2190 万行数据的极速查询。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h1 id="索引语法"&gt;索引语法
&lt;/h1&gt;&lt;h2 id="创建索引"&gt;创建索引
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; [&lt;span style="color:#66d9ef"&gt;UNIQUE&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FULLTEXT&lt;/span&gt;] &lt;span style="color:#66d9ef"&gt;INDEX&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;索引名&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt; (&lt;span style="color:#960050;background-color:#1e0010"&gt;字段名&lt;/span&gt;,...);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 为 user 表的 name 字段创建常规索引 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INDEX&lt;/span&gt; idx_user_name &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;tb_user&lt;/span&gt;(name);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 为 user 表的 phone 字段创建唯一索引
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;UNIQUE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INDEX&lt;/span&gt; idx_user_phone &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;tb_user&lt;/span&gt;(phone);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 为 user 表的 name, age, status 创建联合索引
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INDEX&lt;/span&gt; idx_user_name_age_sta &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;tb_user&lt;/span&gt;(name, age, status);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;字段说明&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;UNIQUE&lt;/code&gt;：可选，创建唯一索引&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FULLTEXT&lt;/code&gt;：可选，创建全文索引&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(字段名,...)&lt;/code&gt;：如果是多个字段，则为&lt;strong&gt;联合索引&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="查看索引"&gt;查看索引
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SHOW&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INDEX&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 格式化输出
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SHOW&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INDEX&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名\&lt;/span&gt;G;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="删除索引"&gt;删除索引
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;DROP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INDEX&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;索引名&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="sql性能分析"&gt;SQL性能分析
&lt;/h1&gt;&lt;h2 id="查看-sql-执行频率"&gt;查看 SQL 执行频率
&lt;/h2&gt;&lt;p&gt;了解当前数据库是以查询为主，还是以增删改为主，决定了优化的侧重点。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;命令&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 查看全局 session 的状态信息
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SHOW&lt;/span&gt; GLOBAL STATUS &lt;span style="color:#66d9ef"&gt;LIKE&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Com_______&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;说明&lt;/strong&gt;：通过 &lt;code&gt;Com_select&lt;/code&gt; (查询)、&lt;code&gt;Com_insert&lt;/code&gt; (插入)、&lt;code&gt;Com_update&lt;/code&gt; (更新)、&lt;code&gt;Com_delete&lt;/code&gt; (删除) 的次数，可以判断数据库的负载特征。如果以查询为主，则应重点关注索引优化。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="慢查询日志slow-query-log"&gt;慢查询日志(Slow Query Log)
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;慢查询日志记录了 所有执行时间超过指定参数（&lt;code&gt;long_query_time&lt;/code&gt;，单位：秒，默认10秒）的 SQL 语句。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;查看开关状态&lt;/strong&gt;：&lt;code&gt;show variables like 'slow_query_log';&lt;/code&gt;* &lt;strong&gt;开启配置&lt;/strong&gt;（在 &lt;code&gt;/etc/my.cnf&lt;/code&gt; 中）：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Shell" data-lang="Shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;# 开启慢查询日志&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	slow_query_log&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;# 设置慢查询阈值为2秒&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	long_query_time&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="show-profiles-查看执行耗时"&gt;show profiles (查看执行耗时)
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;show profiles&lt;/code&gt; 能够帮助我们了解 SQL 在执行过程中，时间具体消耗在了哪个环节（如：Sending data, Sorting, Copying to tmp table）。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;查看支持情况&lt;/strong&gt;：&lt;code&gt;SELECT @@have_profiling;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;开启&lt;/strong&gt;：&lt;code&gt;SET profiling = 1;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;使用步骤&lt;/strong&gt;：
&lt;ol&gt;
&lt;li&gt;执行 SQL 语句。&lt;/li&gt;
&lt;li&gt;查看所有 SQL 的简要耗时：&lt;code&gt;SHOW PROFILES;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;查看特定 query_id 的详细阶段耗时：&lt;code&gt;SHOW PROFILE FOR QUERY [query_id];&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;查看 CPU 消耗：&lt;code&gt;SHOW PROFILE CPU FOR QUERY [query_id];&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="explain-执行计划"&gt;explain 执行计划
&lt;/h2&gt;&lt;p&gt;这是最常用的性能分析手段。在 &lt;code&gt;SELECT&lt;/code&gt; 语句前加上 &lt;code&gt;EXPLAIN&lt;/code&gt; 关键字，MySQL 会模拟执行并返回该 SQL 的执行计划。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;EXPLAIN&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;字段&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;条件&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;重点关注字段说明：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;字段&lt;/th&gt;
					&lt;th style="text-align: left"&gt;含义&lt;/th&gt;
					&lt;th style="text-align: left"&gt;状态解析&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;查询序列号&lt;/td&gt;
					&lt;td style="text-align: left"&gt;id 相同，执行顺序由上至下；id 不同，值越大优先级越高。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;select_type&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;查询类型&lt;/td&gt;
					&lt;td style="text-align: left"&gt;SIMPLE (简单查询), PRIMARY (主查询), UNION, SUBQUERY。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;type&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;连接类型&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;性能由好到差：&lt;code&gt;NULL&lt;/code&gt;&amp;gt;&lt;code&gt;system&lt;/code&gt; &amp;gt; &lt;code&gt;const&lt;/code&gt; &amp;gt; &lt;code&gt;eq_ref&lt;/code&gt; &amp;gt; &lt;code&gt;ref&lt;/code&gt; &amp;gt; &lt;code&gt;range&lt;/code&gt; &amp;gt; &lt;code&gt;index&lt;/code&gt; &amp;gt; &lt;code&gt;ALL&lt;/code&gt;。&lt;strong&gt;至少达到 range 级别，要求 ref。&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;possible_keys&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;可能用到的索引&lt;/td&gt;
					&lt;td style="text-align: left"&gt;显示可能应用在这张表上的索引。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;key&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;实际用到的索引&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;如果为 NULL，则没有使用索引。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;key_len&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;索引使用的字节数&lt;/td&gt;
					&lt;td style="text-align: left"&gt;越短越好（不损失精确性的前提下）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;rows&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;扫描行数&lt;/td&gt;
					&lt;td style="text-align: left"&gt;预估扫描的行数，越小越好。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Extra&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;额外信息&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;Using filesort&lt;/code&gt; (效率低), &lt;code&gt;Using temporary&lt;/code&gt; (效率低), &lt;code&gt;Using index&lt;/code&gt; (性能好)。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h1 id="索引使用规则"&gt;索引使用规则
&lt;/h1&gt;&lt;h2 id="最左前缀法则-most-left-prefix-rule"&gt;最左前缀法则 (Most Left Prefix Rule)
&lt;/h2&gt;&lt;p&gt;如果索引了多列（联合索引），要遵守最左前缀法则。指的是查询从索引的最左列开始，并且不跳过索引中的列。
如果跳过，索引将部分失效&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;匹配规则&lt;/strong&gt;：必须包含索引最左边的列。如果跳过了某列，&lt;strong&gt;该列及后面所有的索引失效&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;案例&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;建立联合索引 &lt;code&gt;idx_user_pro_age_sta (profession, age, status)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;建立索引&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt; profession &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; age &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; stats
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; profession &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;软件工程&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;AND&lt;/span&gt; age &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;31&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;AND&lt;/span&gt; status &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;0&amp;#39;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;（全生效）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 字段顺序不会影响索引
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; age &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;31&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;AND&lt;/span&gt; status &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;0&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;AND&lt;/span&gt; profession &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;软件工程&amp;#39;&lt;/span&gt;;(&lt;span style="color:#960050;background-color:#1e0010"&gt;全生效&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; profession &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;软件工程&amp;#39;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;（生效）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; age &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;31&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;AND&lt;/span&gt; status &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;0&amp;#39;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;（失效，跳过了最左列）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; profession &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;软件工程&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;AND&lt;/span&gt; status &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;（只有&lt;/span&gt; profession &lt;span style="color:#960050;background-color:#1e0010"&gt;生效，&lt;/span&gt;status &lt;span style="color:#960050;background-color:#1e0010"&gt;失效）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="范围查询-range-query"&gt;范围查询 (Range Query)
&lt;/h2&gt;&lt;p&gt;联合索引中，出现范围查询（&lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;），&lt;strong&gt;范围查询右侧的列索引失效&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;案例&lt;/strong&gt;：&lt;code&gt;WHERE profession = '软件工程' AND age &amp;gt; 30 AND status = '0'&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;此时 &lt;code&gt;status&lt;/code&gt; 字段无法用到索引。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;规避方案&lt;/strong&gt;：在业务允许的情况下，尽量使用 &lt;code&gt;&amp;gt;=&lt;/code&gt; 或 &lt;code&gt;&amp;lt;=&lt;/code&gt;，这样可以避免索引失效。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="索引失效场景"&gt;索引失效场景
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;函数/运算操作&lt;/strong&gt;：在索引列上进行运算或使用函数，索引失效。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;失效：&lt;code&gt;WHERE substring(phone, 10, 2) = '15'&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;失效：&lt;code&gt;WHERE age + 1 = 20&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;字符串不加引号&lt;/strong&gt;：字符串类型字段查询时不加单引号，MySQL 会进行隐式类型转换，导致索引失效。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;失效：&lt;code&gt;WHERE phone = 13800001111&lt;/code&gt; （应为 &lt;code&gt;'13800001111'&lt;/code&gt;）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;模糊查询&lt;/strong&gt;：如果仅仅是尾部模糊匹配，索引不会失效。如果是&lt;strong&gt;头部模糊匹配&lt;/strong&gt;，索引失效。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有效：&lt;code&gt;WHERE name LIKE '张%'&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;失效&lt;/strong&gt;：&lt;code&gt;WHERE name LIKE '%张'&lt;/code&gt; 或 &lt;code&gt;WHERE name LIKE '%张%'&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;OR 连接条件&lt;/strong&gt;：用 &lt;code&gt;OR&lt;/code&gt; 分割开的条件，如果 &lt;code&gt;OR&lt;/code&gt; 前的列有索引，而&lt;strong&gt;后面的列没有索引&lt;/strong&gt;，那么涉及的索引都不会被用到。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;解决方案：对于无索引的列也建立索引&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;注意：两侧必须有各自的索引&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;数据分布影响&lt;/strong&gt;：如果 MySQL 评估&lt;strong&gt;使用索引&lt;/strong&gt;比&lt;strong&gt;全表扫描&lt;/strong&gt;更慢（例如查询的数据占全表绝大多数），则不会使用索引&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="sql-提示-sql-hint"&gt;SQL 提示 (SQL Hint)
&lt;/h2&gt;&lt;p&gt;当一个字段有多个索引可选时，我们可以通过 SQL 提示来“建议”或“强制” MySQL 使用哪个索引。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;USE INDEX&lt;/strong&gt;（建议）：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; tb_user &lt;span style="color:#66d9ef"&gt;USE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INDEX&lt;/span&gt;(idx_user_name) &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;张三&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;IGNORE INDEX&lt;/strong&gt;（忽略）：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; tb_user &lt;span style="color:#66d9ef"&gt;IGNORE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INDEX&lt;/span&gt;(idx_user_name) &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;张三&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;FORCE INDEX&lt;/strong&gt;（强制）：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; tb_user &lt;span style="color:#66d9ef"&gt;FORCE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INDEX&lt;/span&gt;(idx_user_name) &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;张三&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="覆盖索引-covering-index"&gt;覆盖索引 (Covering Index)
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;覆盖索引是性能优化的极致目标&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;尽量使用覆盖索引(查询使用了索引，并且需要返回的列，在该索引中已经全部能够找到)，减少&lt;code&gt;SELECT*&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;原理&lt;/strong&gt;：无需回表查询（无需回到聚集索引中找行数据）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;判定&lt;/strong&gt;：在 &lt;code&gt;EXPLAIN&lt;/code&gt; 的 &lt;code&gt;Extra&lt;/code&gt; 列中出现 &lt;code&gt;Using index&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Using index condition&lt;/code&gt;：查找使用了索引，但是需要回表查询数据&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Using where ; using index&lt;/code&gt;：查找使用了索引，但是需要的数据在索引列中能找到，所以不需要回表查询
&lt;img src="https://creat.asia/post/image/%e8%bf%9b%e9%98%b6-%e7%b4%a2%e5%bc%95-8.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="问题-2"&gt;问题
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;一张表,有四个字段(id,username,password,status)由于数据量大,需要对以下SQL语句进行优化&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;该如何进行才是最优方案:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; id,username,password &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; tb &lt;span style="color:#66d9ef"&gt;user&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;where&lt;/span&gt; username &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;itcast&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;方案&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;索引配置&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;查询行为&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;评价&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;方案一（差）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;无索引&lt;/td&gt;
					&lt;td&gt;全表扫描&lt;/td&gt;
					&lt;td&gt;随着数据量增大，性能直线下降。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;方案二（中）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;INDEX(username)&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;索引查找 + &lt;strong&gt;回表&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;能定位，但需要回表去查 &lt;code&gt;password&lt;/code&gt;，有额外 I/O。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;方案三（优）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;INDEX(username, password)&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;覆盖索引扫描&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;最快。&lt;/strong&gt; 无需回表，数据直接从索引树取出。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="前缀索引"&gt;前缀索引
&lt;/h2&gt;&lt;p&gt;当字段类型为长文本（如 &lt;code&gt;TEXT&lt;/code&gt; 或很长的 &lt;code&gt;VARCHAR&lt;/code&gt;）时，建立完整索引会导致索引文件巨大，查询浪费大量磁盘IO，效率低。
此时可以只将字符串的前一部分建立索引，这样可以大大节约索引空间，从而提高索引效率&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;语法&lt;/strong&gt;：&lt;code&gt;CREATE INDEX idx_xxx ON table_name(column(n));&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;选择性&lt;/strong&gt;：前缀的长度 &lt;code&gt;n&lt;/code&gt; 取决于字段的&lt;strong&gt;选择性&lt;/strong&gt;（不重复的索引值 / 总行数），选择性越高效率越高。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/*
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;	索引选择性 = 不重复的索引值数量（基数） / 总记录数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;	取值范围：0 ~ 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;	选择性越接近 1，索引的区分度越高，查询效率越好
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;	唯一索引的选择性是 1，是最优情况
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 计算完整 email 字段的选择性
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;count&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;distinct&lt;/span&gt; email) &lt;span style="color:#f92672"&gt;/&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;count&lt;/span&gt;(&lt;span style="color:#f92672"&gt;*&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; tb_user;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 计算 email 前 5 个字符的选择性
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;count&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;distinct&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;substring&lt;/span&gt;(email,&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;)) &lt;span style="color:#f92672"&gt;/&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;count&lt;/span&gt;(&lt;span style="color:#f92672"&gt;*&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; tb_user;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;完整列索引 (Full Index)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;前缀索引 (Prefix Index)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;影响分析&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;存储空间&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;较大（占用磁盘多）&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;极小（显著节省空间）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;数据量越大，前缀索引的成本优势越明显。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;写入性能 (DML)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;较慢（索引树维护重）&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;较快（索引页更紧凑）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;插入和更新长字符串时，前缀索引负担更轻。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;查询定位速度&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;极快（精准匹配）&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;快（但存在哈希冲突风险）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;如果前缀区分度高，两者定位速度接近。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;覆盖索引&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;支持 (Using index)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;不支持 (必须回表)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;前缀索引无法提供完整字段值，必须回主表二次验证。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;排序 (ORDER BY)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;不支持&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;数据库无法利用前缀的顺序来完成全字段的排序。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;分组 (GROUP BY)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;不支持&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;必须拉取完整数据到内存中进行分组计算。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;区分度 (Selectivity)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;最高&lt;/td&gt;
					&lt;td&gt;取决于截取长度&lt;/td&gt;
					&lt;td&gt;截取太短会导致索引失效（类似全表扫描）。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="单列索引与联合索引"&gt;单列索引与联合索引
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;单列索引 (Single-Column Index)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;联合索引 (Composite/Joint Index)&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;定义&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;基于表中的一个列建立的索引。&lt;/td&gt;
					&lt;td&gt;基于表中的两个或多个列建立的索引。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;B+树键值&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;节点中只包含 &lt;code&gt;[该列值 | 主键ID]&lt;/code&gt;。&lt;/td&gt;
					&lt;td&gt;节点中包含 &lt;code&gt;[列1, 列2, 列3... | 主键ID]&lt;/code&gt;。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;排序规则&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;按该列的逻辑顺序排列。&lt;/td&gt;
					&lt;td&gt;按创建索引时的列顺序，逐级排序（字典序）。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;优缺点&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;维度&lt;/th&gt;
					&lt;th style="text-align: left"&gt;单列索引&lt;/th&gt;
					&lt;th style="text-align: left"&gt;联合索引&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;优点&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;灵活，适用于多种不同的简单查询；索引维护成本相对低。&lt;/td&gt;
					&lt;td style="text-align: left"&gt;复合查询性能极强；支持覆盖索引；减少索引文件总数（相比建多个单列）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;缺点&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;在多条件复合查询下，过滤效率不如联合索引。&lt;/td&gt;
					&lt;td style="text-align: left"&gt;遵循最左前缀，灵活性差；索引列多时，单条记录变宽，单页存储数量下降。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;字段分布散、查询条件单一、或该列在多个不同场景被单独引用。&lt;/td&gt;
					&lt;td style="text-align: left"&gt;存在高频的多个字段组合查询；需要通过索引覆盖来规避大表回表。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="设计原则"&gt;设计原则
&lt;/h1&gt;&lt;h2 id="数据规模与查询频次"&gt;数据规模与查询频次
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;原则：&lt;/strong&gt; 针对于&lt;strong&gt;数据量较大&lt;/strong&gt;，且&lt;strong&gt;查询比较频繁&lt;/strong&gt;的表建立索引。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;解读：&lt;/strong&gt; 小表或极少查询的表建立索引的意义不大，反而会增加维护开销。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="关键操作字段"&gt;关键操作字段
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;原则：&lt;/strong&gt; 针对于常作为&lt;strong&gt;查询条件（where）&lt;/strong&gt;、&lt;strong&gt;排序（order by）&lt;/strong&gt;、**分组（group by）**操作的字段建立索引。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;解读：&lt;/strong&gt; 索引不仅能加速过滤，还能利用 B+ 树的有序性加速排序和分组过程。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="选择性与区分度"&gt;选择性与区分度
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;原则：&lt;/strong&gt; 尽量选择&lt;strong&gt;区分度高&lt;/strong&gt;的列作为索引，尽量建立&lt;strong&gt;唯一索引&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;解读：&lt;/strong&gt; 区分度越高（重复值越少），MySQL 优化器使用索引的效率越高。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="字符串长字段处理"&gt;字符串长字段处理
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;原则：&lt;/strong&gt; 如果是字符串类型的字段，且字段长度较长，可以针对字段的特点建立&lt;strong&gt;前缀索引&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;解读：&lt;/strong&gt; 通过截取字段的前一部分建立索引，可以节省存储空间并提升 I/O 效率。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="联合索引优先"&gt;联合索引优先
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;原则：&lt;/strong&gt; 尽量使用&lt;strong&gt;联合索引&lt;/strong&gt;，减少单列索引。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;解读：&lt;/strong&gt; 联合索引在很多时候可以实现&lt;strong&gt;覆盖索引&lt;/strong&gt;（Covering Index），从而避免回表查询，节省存储空间并显著提高查询效率。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="控制索引数量"&gt;控制索引数量
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;原则：&lt;/strong&gt; 要控制索引的数量，索引并不是多多益善。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;解读：&lt;/strong&gt; 索引越多，维护索引结构的代价（磁盘 I/O 和 CPU）也就越大，会直接影响**增删改（INSERT/DELETE/UPDATE）**的效率。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="null-值约束"&gt;NULL 值约束
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;原则：&lt;/strong&gt; 如果索引列不能存储 NULL 值，请在创建表时使用 &lt;strong&gt;NOT NULL&lt;/strong&gt; 约束它。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;解读：&lt;/strong&gt; 当优化器知道每列是否包含 NULL 值时，它可以更好地确定哪个索引最有效地用于查询。此外，索引 NULL 值在存储和计算上更复杂。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>事务</title><link>https://creat.asia/post/%E4%BA%8B%E5%8A%A1/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/%E4%BA%8B%E5%8A%A1/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-02&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="简介"&gt;简介
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;事务是一组 SQL 语句组成的逻辑处理单元。这组操作&lt;strong&gt;要么全部执行成功，要么全部失败回滚&lt;/strong&gt;，&lt;strong&gt;不能只执行其中的一部分&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;典型场景&lt;/strong&gt;：银行转账。A 账户减 100 元，B 账户加 100 元。这两个操作必须同时成功，否则钱就“凭空消失”了&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="事务操作"&gt;事务操作
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;在 MySQL 中，默认是 &lt;strong&gt;自动提交 (autocommit)&lt;/strong&gt; 的。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;查看/设置自动提交&lt;/strong&gt;：&lt;code&gt;SELECT @@autocommit;&lt;/code&gt; (1为自动, 0为手动)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;开启事务&lt;/strong&gt;：&lt;code&gt;START TRANSACTION;&lt;/code&gt; 或 &lt;code&gt;BEGIN;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;提交事务&lt;/strong&gt;：&lt;code&gt;COMMIT;&lt;/code&gt;（将更改永久保存到数据库）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;回滚事务&lt;/strong&gt;：&lt;code&gt;ROLLBACK;&lt;/code&gt;（撤销所有未提交的操作，恢复到事务开始前的状态）
1.修改提交方式&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;@@&lt;/span&gt;autocommit; &lt;span style="color:#75715e"&gt;-- 查看当前的自动提交状态 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SET&lt;/span&gt; &lt;span style="color:#f92672"&gt;@@&lt;/span&gt;autocommit &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#75715e"&gt;-- 关闭自动提交 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; account &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;张三&amp;#39;&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 查询姓名为张三的账户信息 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;UPDATE&lt;/span&gt; account &lt;span style="color:#66d9ef"&gt;SET&lt;/span&gt; money &lt;span style="color:#f92672"&gt;=&lt;/span&gt; money &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1000&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;张三&amp;#39;&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 给张三的账户减少1000元 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#960050;background-color:#1e0010"&gt;报错语句&lt;/span&gt;...; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;UPDATE&lt;/span&gt; account &lt;span style="color:#66d9ef"&gt;SET&lt;/span&gt; money &lt;span style="color:#f92672"&gt;=&lt;/span&gt; money &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1000&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;李四&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 给李四的账户增加1000元 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	ROLLBACK ; &lt;span style="color:#75715e"&gt;-- 回滚事务，撤销之前的修改 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	COMMIT; &lt;span style="color:#75715e"&gt;-- 提交事务，保存修改
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;2.开启事务的方式&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	START TRANSACTION; &lt;span style="color:#75715e"&gt;-- 开始一个新的事务
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	...&lt;span style="color:#960050;background-color:#1e0010"&gt;同上&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="事务的四大特性-acid"&gt;事务的四大特性 (ACID)
&lt;/h2&gt;&lt;p&gt;这是数据库事务的基石，必须死记硬背：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;原子性 (Atomicity)&lt;/strong&gt;：事务是最小的执行单位，不可分割。要么全部完成，要么全部不执行。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;一致性 (Consistency)&lt;/strong&gt;：事务执行前后，数据库从一个一致性状态转换到另一个一致性状态（如转账前后总金额不变)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(事务完成时必须是所有的数据保持一致状态)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;隔离性 (Isolation)&lt;/strong&gt;：并发访问数据库时，多个事务之间相互隔离，互不干扰（通过锁机制和多版本并发控制 &lt;code&gt;MVCC&lt;/code&gt; 实现）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;持久性 (Durability)&lt;/strong&gt;：一旦事务&lt;strong&gt;提交或回滚&lt;/strong&gt;，其对数据库中数据的改变就是永久性的，即使系统崩溃也不会丢失。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rollback-符合持久性是因为"&gt;&lt;code&gt;ROLLBACK&lt;/code&gt; 符合持久性，是因为：
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;结果永久化：&lt;/strong&gt; 回滚后的数据状态和提交后的状态一样，都受到系统故障保护，不会在重启后失效。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;物理一致性：&lt;/strong&gt; 数据库确保了“回滚”这一决策在物理磁盘上是完整执行且不可逆转的。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id="并发事务引发的问题"&gt;并发事务引发的问题
&lt;/h1&gt;&lt;p&gt;当多个事务同时操作同一批数据时，如果不加控制，会产生以下问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;脏读 (Dirty Read)&lt;/strong&gt;：一个事务读取到了另一个事务&lt;strong&gt;尚未提交&lt;/strong&gt;的数据&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;类似于：读到了草稿纸上的数据&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;不可重复读 (Non-Repeatable Read)&lt;/strong&gt;：一个事务先后读取同一条记录，但两次读取的数据不同（中间有另一个事务更新并提交了该数据）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;幻读 (Phantom Read)&lt;/strong&gt;：一个事务按照条件查询数据时，没有对应的数据行，但在插入数据时又发现这行数据已经存在（中间有另一个事务插入并提交了数据）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;类似于：更改密码的时候不可以使用旧密码&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="事务隔离级别"&gt;事务隔离级别
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;为了解决上述并发问题，数据库提供了四种隔离级别。级别越高，数据越安全，但并发性能越低。&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;隔离级别（√表示会出现）&lt;/th&gt;
					&lt;th style="text-align: center"&gt;脏读&lt;/th&gt;
					&lt;th style="text-align: center"&gt;不可重复读&lt;/th&gt;
					&lt;th style="text-align: center"&gt;幻读&lt;/th&gt;
					&lt;th style="text-align: left"&gt;性能&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Read Uncommitted&lt;/strong&gt; (读未提交)&lt;/td&gt;
					&lt;td style="text-align: center"&gt;√&lt;/td&gt;
					&lt;td style="text-align: center"&gt;√&lt;/td&gt;
					&lt;td style="text-align: center"&gt;√&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;最高&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Read Committed&lt;/strong&gt; (读已提交)&lt;/td&gt;
					&lt;td style="text-align: center"&gt;×&lt;/td&gt;
					&lt;td style="text-align: center"&gt;√&lt;/td&gt;
					&lt;td style="text-align: center"&gt;√&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;高（Oracle默认）&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Repeatable Read&lt;/strong&gt; (可重复读)&lt;/td&gt;
					&lt;td style="text-align: center"&gt;×&lt;/td&gt;
					&lt;td style="text-align: center"&gt;×&lt;/td&gt;
					&lt;td style="text-align: center"&gt;√&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;中 (MySQL默认)&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Serializable&lt;/strong&gt; (串行化)&lt;/td&gt;
					&lt;td style="text-align: center"&gt;×&lt;/td&gt;
					&lt;td style="text-align: center"&gt;×&lt;/td&gt;
					&lt;td style="text-align: center"&gt;×&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;最低&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：MySQL 的 InnoDB 引擎在 &lt;code&gt;Repeatable Read&lt;/code&gt; 级别下，通过间隙锁（Next-Key Locks）在很大程度上规避了幻读问题。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-mysql" data-lang="mysql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 查看事物隔离级别
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;@@&lt;/span&gt;TRAN_ISOLATION_LEVEL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 设置事务隔离级别
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SET&lt;/span&gt; [SESSION&lt;span style="color:#f92672"&gt;|&lt;/span&gt;GLOBAL] TRANSACTION ISOLATION LEVEL 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	[&lt;span style="color:#66d9ef"&gt;READ&lt;/span&gt; UNCOMMITTED&lt;span style="color:#f92672"&gt;|&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;READ&lt;/span&gt; COMMITTED&lt;span style="color:#f92672"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	REPEATABLE &lt;span style="color:#66d9ef"&gt;READ&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt;SERIALIZABLE];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 精简：‘’中不能有空格，用 - 代替
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SET&lt;/span&gt; &lt;span style="color:#f92672"&gt;@@&lt;/span&gt;SESSION.TRANSACTION_ISOLATION &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;READ-COMMITTED |...&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="事务原理简介"&gt;事务原理简介
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;MySQL 如何实现 ACID？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;原子性&lt;/strong&gt;：由 &lt;strong&gt;undo log&lt;/strong&gt;（回滚日志）保证。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;持久性&lt;/strong&gt;：由 &lt;strong&gt;redo log&lt;/strong&gt;（重做日志）保证。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;隔离性&lt;/strong&gt;：由 &lt;strong&gt;锁机制&lt;/strong&gt; + &lt;strong&gt;MVCC&lt;/strong&gt;（多版本并发控制）保证。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;一致性&lt;/strong&gt;：由原子性、持久性、隔离性共同支撑，外加数据库逻辑约束。&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>函数</title><link>https://creat.asia/post/%E5%87%BD%E6%95%B0/</link><pubDate>Sun, 29 Mar 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/%E5%87%BD%E6%95%B0/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-03-29&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="字符串函数"&gt;字符串函数
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;基础处理函数&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;函数&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;功能&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;示例代码块&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;CONCAT(s1, s2&amp;hellip;sn)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;字符串拼接，将多个字符串合并为一个&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT CONCAT('Hello', ' ', 'World');&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;LOWER(str)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;将字符串全部转换为&lt;strong&gt;小写&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT LOWER('MySQL');&lt;/code&gt; → &lt;code&gt;mysql&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;UPPER(str)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;将字符串全部转换为&lt;strong&gt;大写&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT UPPER('mysql');&lt;/code&gt; → &lt;code&gt;MYSQL&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;TRIM(str)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;去除字符串左右两边的&lt;strong&gt;空格&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT TRIM(' abc ');&lt;/code&gt; → &lt;code&gt;abc&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;截取与填充函数&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;函数&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;功能&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;示例代码块&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;SUBSTR(s, start, len)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;从 start 位置开始截取 len 长度的字符串&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT SUBSTR('HelloSQL', 1, 5);&lt;/code&gt; → &lt;code&gt;Hello&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;LPAD(str, len, pad)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;左填充&lt;/strong&gt;，用 pad 将 str 填充到 len 长度&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT LPAD('01', 5, '-');&lt;/code&gt; → &lt;code&gt;---01&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RPAD(str, len, pad)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;右填充&lt;/strong&gt;，用 pad 将 str 填充到 len 长度&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT RPAD('01', 5, '-');&lt;/code&gt; → &lt;code&gt;01---&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意点：&lt;/strong&gt;
&lt;strong&gt;1.索引位置&lt;/strong&gt;：在 SQL 的 &lt;code&gt;SUBSTR&lt;/code&gt; 函数中，索引是从 &lt;strong&gt;1&lt;/strong&gt; 开始的，而不是像 Java 或 Python 那样从 0 开始。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2.NULL 值陷阱&lt;/strong&gt;：在使用 &lt;code&gt;CONCAT&lt;/code&gt; 拼接时，如果其中任何一个参数是 &lt;code&gt;NULL&lt;/code&gt;，在很多数据库（如 MySQL）中整个结果都会变成 &lt;code&gt;NULL&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt; _解决方法_：使用 `CONCAT_WS`（可以指定分隔符并跳过空值）。
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;3.多字节字符（中文）&lt;/strong&gt;：有些数据库的 &lt;code&gt;SUBSTR&lt;/code&gt; 是按字符截取，有些是按字节截取。在 MySQL 中，&lt;code&gt;SUBSTR&lt;/code&gt; 通常按字符截取，非常友好。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="数值函数"&gt;数值函数
&lt;/h1&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;函数&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;功能&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;示例代码块&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;CEIL(x)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;向上取整&lt;/strong&gt;（返回大于等于 x 的最小整数）&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT CEIL(1.1);&lt;/code&gt; → &lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;FLOOR(x)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;向下取整&lt;/strong&gt;（返回小于等于 x 的最大整数）&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT FLOOR(1.9);&lt;/code&gt; → &lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;MOD(x, y)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;取模&lt;/strong&gt;（返回 x 除以 y 的余数）&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT MOD(10, 3);&lt;/code&gt; → &lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RAND()&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;随机数&lt;/strong&gt;（返回 0~1 之间的随机浮点数）&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT RAND();&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ROUND(x, y)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;四舍五入&lt;/strong&gt;（对 x 求值，保留 y 位小数）&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT ROUND(2.345, 2);&lt;/code&gt; → &lt;code&gt;2.35&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ABS(x)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;绝对值&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT ABS(-5);&lt;/code&gt; → &lt;code&gt;5&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;</description></item><item><title>SQL</title><link>https://creat.asia/post/sql%E5%9F%BA%E7%A1%80/</link><pubDate>Sat, 28 Mar 2026 00:00:00 +0000</pubDate><guid>https://creat.asia/post/sql%E5%9F%BA%E7%A1%80/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-03-28&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="基础书写规则"&gt;基础书写规则
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;分号结束&lt;/strong&gt;：每条 SQL 语句通常以分号 &lt;code&gt;;&lt;/code&gt; 结尾（虽然某些单条执行环境不强制，但在脚本中是必需的）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;不区分大小写&lt;/strong&gt;：SQL 关键字（如 &lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;FROM&lt;/code&gt;）不区分大小写，但为了代码可读性，习惯上&lt;strong&gt;关键字大写&lt;/strong&gt;，表名和列名小写。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;推荐写法：&lt;/em&gt; &lt;code&gt;SELECT name FROM users;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;空格与缩进&lt;/strong&gt;：SQL 对空格和换行不敏感。合理的缩进能显著提高代码的可读性。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;注释规范&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;单行注释：&lt;code&gt;-- 注释内容&lt;/code&gt; 或 &lt;code&gt;# 注释内容&lt;/code&gt;（仅限 MySQL）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;多行注释：&lt;code&gt;/* 注释内容 */&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;缩写&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;全称&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;操作对象&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;常用动词&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;场景示例&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;a class="link" href="#DDL" &gt;&lt;strong&gt;DDL&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Definition&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;表结构/数据库&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;CREATE&lt;/code&gt;, &lt;code&gt;DROP&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;“建个名为‘用户’的表”&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;a class="link" href="#DML" &gt;&lt;strong&gt;DML&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Manipulation&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;行记录&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;INSERT&lt;/code&gt;, &lt;code&gt;UPDATE&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;“把小明的年龄改成18”&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;a class="link" href="#DQL" &gt;&lt;strong&gt;DQL&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Query&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;数据结果集&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;“找出所有北京的用户”&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;a class="link" href="#DCL" &gt;&lt;strong&gt;DCL&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Control&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;权限/安全&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;GRANT&lt;/code&gt;, &lt;code&gt;REVOKE&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;“允许小李查看工资表”&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="数据类型"&gt;数据类型
&lt;/h1&gt;&lt;h2 id="整型"&gt;整型
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;类型名称&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;取值范围&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;大小&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;TINYINT&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;-128〜127&lt;/td&gt;
					&lt;td&gt;1个字节&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;SMALLINT&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;-32768〜32767&lt;/td&gt;
					&lt;td&gt;2个宇节&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;MEDIUMINT&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;-8388608〜8388607&lt;/td&gt;
					&lt;td&gt;3个字节&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;INT&lt;/code&gt; (&lt;code&gt;INTEGER&lt;/code&gt;)&lt;/td&gt;
					&lt;td&gt;-2147483648〜2147483647&lt;/td&gt;
					&lt;td&gt;4个字节&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;BIGINT&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;-9223372036854775808〜9223372036854775807&lt;/td&gt;
					&lt;td&gt;8个字节&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;无符号在数据类型后加 unsigned 关键字。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="浮点型"&gt;浮点型
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;类型名称&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;存储需求&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;FLOAT&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;单精度浮点数&lt;/td&gt;
					&lt;td&gt;4 个字节&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;DOUBLE&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;双精度浮点数&lt;/td&gt;
					&lt;td&gt;8 个字节&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;DECIMAL&lt;/code&gt; (&lt;code&gt;M&lt;/code&gt;, &lt;code&gt;D&lt;/code&gt;)，&lt;code&gt;DEC&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;压缩的“严格”定点数&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;M&lt;/code&gt;+2 个字节&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="日期和时间"&gt;日期和时间
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;类型名称&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;日期格式&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;日期范围&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;存储需求&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;YEAR&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;YYYY&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;1901 ~ 2155&lt;/td&gt;
					&lt;td&gt;1 个字节&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;TIME&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;HH&lt;/code&gt;:&lt;code&gt;MM&lt;/code&gt;:&lt;code&gt;SS&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;-838:59:59 ~ 838:59:59&lt;/td&gt;
					&lt;td&gt;3 个字节&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;DATE&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;YYYY&lt;/code&gt;-&lt;code&gt;MM&lt;/code&gt;-&lt;code&gt;DD&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;1000-01-01 ~ 9999-12-3&lt;/td&gt;
					&lt;td&gt;3 个字节&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;DATETIME&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;YYYY&lt;/code&gt;-&lt;code&gt;MM&lt;/code&gt;-&lt;code&gt;DD&lt;/code&gt; &lt;code&gt;HH&lt;/code&gt;:&lt;code&gt;MM&lt;/code&gt;:&lt;code&gt;SS&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;1000-01-01 00:00:00 ~ 9999-12-31 23:59:59&lt;/td&gt;
					&lt;td&gt;8 个字节&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;TIMESTAMP&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;YYYY&lt;/code&gt;-&lt;code&gt;MM&lt;/code&gt;-&lt;code&gt;DD&lt;/code&gt; &lt;code&gt;HH&lt;/code&gt;:&lt;code&gt;MM&lt;/code&gt;:&lt;code&gt;SS&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;1980-01-01 00:00:01 &lt;code&gt;UTC&lt;/code&gt; ~ 2040-01-19 03:14:07 &lt;code&gt;UTC&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;4 个字节&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="字符串"&gt;字符串
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;类型名称&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;存储需求&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;CHAR&lt;/code&gt;(&lt;code&gt;M&lt;/code&gt;)&lt;/td&gt;
					&lt;td&gt;固定长度非二进制字符串&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;M&lt;/code&gt; 字节，1&amp;lt;=&lt;code&gt;M&lt;/code&gt;&amp;lt;=255&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;VARCHAR&lt;/code&gt;(&lt;code&gt;M&lt;/code&gt;)&lt;/td&gt;
					&lt;td&gt;变长非二进制字符串&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;L&lt;/code&gt;+1字节，在此，&lt;code&gt;L&lt;/code&gt; &amp;lt;= &lt;code&gt;M&lt;/code&gt;和 1&amp;lt;=&lt;code&gt;M&lt;/code&gt;&amp;lt;=255&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;TINYTEXT&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;非常小的非二进制字符串&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;L&lt;/code&gt;+1字节，在此，&lt;code&gt;L&lt;/code&gt;&amp;lt;2^8&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;TEXT&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;小的非二进制字符串&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;L&lt;/code&gt;+2字节，在此，&lt;code&gt;L&lt;/code&gt;&amp;lt;2^16&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;MEDIUMTEXT&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;中等大小的非二进制字符串&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;L&lt;/code&gt;+3字节，在此，&lt;code&gt;L&lt;/code&gt;&amp;lt;2^24&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;LONGTEXT&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;大的非二进制字符串&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;L&lt;/code&gt;+4字节，在此，&lt;code&gt;L&lt;/code&gt;&amp;lt;2^32&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;ENUM&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;枚举类型，只能有一个枚举字符串值&lt;/td&gt;
					&lt;td&gt;1或2个字节，取决于枚举值的数目 (最大值为65535)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;SET&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;一个设置，字符串对象可以有零个或 多个&lt;code&gt;SET&lt;/code&gt;成员&lt;/td&gt;
					&lt;td&gt;1、2、3、4或8个字节，取决于集合 成员的数量（最多64个成员）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="二进制类型"&gt;二进制类型
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;类型名称&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;存储需求&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;BIT&lt;/code&gt;(&lt;code&gt;M&lt;/code&gt;)&lt;/td&gt;
					&lt;td&gt;位字段类型&lt;/td&gt;
					&lt;td&gt;大约 (&lt;code&gt;M&lt;/code&gt;+7)/8 字节&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;BINARY&lt;/code&gt;(&lt;code&gt;M&lt;/code&gt;)&lt;/td&gt;
					&lt;td&gt;固定长度二进制字符串&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;M&lt;/code&gt; 字节&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;VARBINARY&lt;/code&gt; (&lt;code&gt;M&lt;/code&gt;)&lt;/td&gt;
					&lt;td&gt;可变长度二进制字符串&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;M&lt;/code&gt;+1 字节&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;TINYBLOB&lt;/code&gt; (&lt;code&gt;M&lt;/code&gt;)&lt;/td&gt;
					&lt;td&gt;非常小的&lt;code&gt;BLOB&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;L&lt;/code&gt;+1 字节，在此，&lt;code&gt;L&lt;/code&gt;&amp;lt;2^8&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;BLOB&lt;/code&gt; (&lt;code&gt;M&lt;/code&gt;)&lt;/td&gt;
					&lt;td&gt;小 &lt;code&gt;BLOB&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;L&lt;/code&gt;+2 字节，在此，&lt;code&gt;L&lt;/code&gt;&amp;lt;2^16&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;MEDIUMBLOB&lt;/code&gt; (&lt;code&gt;M&lt;/code&gt;)&lt;/td&gt;
					&lt;td&gt;中等大小的&lt;code&gt;BLOB&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;L&lt;/code&gt;+3 字节，在此，&lt;code&gt;L&lt;/code&gt;&amp;lt;2^24&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;LONGBLOB&lt;/code&gt; (&lt;code&gt;M&lt;/code&gt;)&lt;/td&gt;
					&lt;td&gt;非常大的&lt;code&gt;BLOB&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;L&lt;/code&gt;+4 字节，在此，&lt;code&gt;L&lt;/code&gt;&amp;lt;2^32&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="ddl"&gt;DDL
&lt;/h1&gt;&lt;h2 id="create创建"&gt;CREATE（创建）
&lt;/h2&gt;&lt;p&gt;用于建立新的数据库对象。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 创建一个名为 users 的表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; users (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; id INT &lt;span style="color:#66d9ef"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt; AUTO_INCREMENT, &lt;span style="color:#75715e"&gt;-- 主键，自动增长
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; username VARCHAR(&lt;span style="color:#ae81ff"&gt;50&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;, &lt;span style="color:#75715e"&gt;-- 不允许为空
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; email VARCHAR(&lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;UNIQUE&lt;/span&gt;, &lt;span style="color:#75715e"&gt;-- 唯一约束
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; created_at &lt;span style="color:#66d9ef"&gt;TIMESTAMP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;DEFAULT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;CURRENT_TIMESTAMP&lt;/span&gt; &lt;span style="color:#75715e"&gt;-- 默认值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="alter修改"&gt;ALTER（修改）
&lt;/h2&gt;&lt;p&gt;用于修改现有的表结构，例如增加新列、更改数据类型或重命名。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;1.添加字段&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ALTER TABLE 表名 ADD 字段名 类型（长度） [comment] [约束];&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2.修改数据类型&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ALTER TABLE MODIFY 字段名 新数据类型（长度）;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3.修改字段名和字段类型&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ALTER TABLE　表名　CHANGE　旧字段名　新字段名　类型（长度）[comment][约束];&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;4.删除字段&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ALTER TABLE 表名 DROP 字段名;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;5.修改表名&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ALTER TABLE 表名 RENAME TO 新表名&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 在 users 表中增加一行“手机号”
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;ALTER&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; users &lt;span style="color:#66d9ef"&gt;ADD&lt;/span&gt; phone_number VARCHAR(&lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 修改字段类型
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;ALTER&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; users &lt;span style="color:#66d9ef"&gt;MODIFY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;COLUMN&lt;/span&gt; username VARCHAR(&lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 删除某一列
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;ALTER&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; users &lt;span style="color:#66d9ef"&gt;DROP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;COLUMN&lt;/span&gt; email;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="drop删除"&gt;DROP（删除）
&lt;/h2&gt;&lt;p&gt;将整个对象从数据库中彻底抹去。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 删除整个 users 表（结构和数据全部消失）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;DROP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; users;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 删除整个数据库
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;DROP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;DATABASE&lt;/span&gt; my_app;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="truncate清空"&gt;TRUNCATE（清空）
&lt;/h2&gt;&lt;p&gt;用于删除表中的&lt;strong&gt;所有&lt;/strong&gt;数据，但保留表结构。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;与 DELETE 的区别&lt;/strong&gt;：&lt;code&gt;DELETE&lt;/code&gt; 是一行行删，速度慢；&lt;code&gt;TRUNCATE&lt;/code&gt; 是直接销毁表并重建一个空的，速度极快且不记录逐行日志。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;TRUNCATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; users;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="dml"&gt;DML
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;DML 主要由三个核心关键字组成：&lt;code&gt;INSERT&lt;/code&gt;（增）、&lt;code&gt;UPDATE&lt;/code&gt;（改）、&lt;code&gt;DELETE&lt;/code&gt;（删）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="insert-插入数据"&gt;INSERT (插入数据)
&lt;/h2&gt;&lt;p&gt;用于向表中添加新行。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;指定列插入：&lt;/strong&gt;（推荐，更安全）&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;INSERT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INTO&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt; (&lt;span style="color:#960050;background-color:#1e0010"&gt;字段名&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;字段名&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, ...) &lt;span style="color:#66d9ef"&gt;VALUES&lt;/span&gt; (&lt;span style="color:#960050;background-color:#1e0010"&gt;值&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;值&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, ...);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;INSERT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INTO&lt;/span&gt; users (username, age, email) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;VALUES&lt;/span&gt; (&lt;span style="color:#e6db74"&gt;&amp;#39;张三&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;25&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;zhangsan@example.com&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;全列插入：&lt;/strong&gt;（必须按表结构顺序提供所有值）&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;INSERT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INTO&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;VALUES&lt;/span&gt; (&lt;span style="color:#960050;background-color:#1e0010"&gt;值&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;值&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, ...);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;INSERT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INTO&lt;/span&gt; users &lt;span style="color:#66d9ef"&gt;VALUES&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;李四&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;30&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;lisi@example.com&amp;#39;&lt;/span&gt;, NOW());
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;批量插入：&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;-- 指定字段的批量插入（推荐）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;INSERT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INTO&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt; (&lt;span style="color:#960050;background-color:#1e0010"&gt;字段名&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;字段名&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, ...) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;VALUES&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		(&lt;span style="color:#960050;background-color:#1e0010"&gt;值&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;值&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, ...),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		(&lt;span style="color:#960050;background-color:#1e0010"&gt;值&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;值&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, ...),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		(&lt;span style="color:#960050;background-color:#1e0010"&gt;值&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;值&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, ...);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;INSERT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INTO&lt;/span&gt; student (name, age, gender) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;VALUES&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		(&lt;span style="color:#e6db74"&gt;&amp;#39;张三&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;男&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		(&lt;span style="color:#e6db74"&gt;&amp;#39;李四&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;19&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;女&amp;#39;&lt;/span&gt;), 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		(&lt;span style="color:#e6db74"&gt;&amp;#39;王五&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;21&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;男&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 省略字段的批量插入(所有字段)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;INSERT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INTO&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;VALUES&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		(&lt;span style="color:#960050;background-color:#1e0010"&gt;值&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;值&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, ...),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		(&lt;span style="color:#960050;background-color:#1e0010"&gt;值&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;值&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, ...),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		(&lt;span style="color:#960050;background-color:#1e0010"&gt;值&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;值&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, ...);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;INSERT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INTO&lt;/span&gt; student
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;VALUES&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 (&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;赵六&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;男&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 (&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;钱七&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;18&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;女&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;添加数据时，&lt;strong&gt;字段名与值的顺序、个数必须一一对应&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;字符串类型和日期类型&lt;/strong&gt;的值，需要包含在&lt;strong&gt;引号&lt;/strong&gt;中。&lt;/li&gt;
&lt;li&gt;插入的数据&lt;strong&gt;必须在字段允许的范围之内&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id="update-更新数据"&gt;UPDATE (更新数据)
&lt;/h2&gt;&lt;p&gt;用于修改表中已存在的记录。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;关键点：&lt;/strong&gt; 永远不要忘记 &lt;code&gt;WHERE&lt;/code&gt; 子句，否则全表数据都会被修改！&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;UPDATE&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;SET&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;字段名&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;值&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;字段名&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;值&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, ... [&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;条件&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;UPDATE&lt;/span&gt; users &lt;span style="color:#66d9ef"&gt;SET&lt;/span&gt; age &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;26&lt;/span&gt;, email &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;san_new@example.com&amp;#39;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; username &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;张三&amp;#39;&lt;/span&gt;; &lt;span style="color:#75715e"&gt;-- 只更新张三的数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
注意:修改语句的条件可以有，也可以没有，如果没有条件，则会修改整张表的所有数据。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="delete-删除数据"&gt;DELETE (删除数据)
&lt;/h2&gt;&lt;p&gt;用于删除表中的特定行。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;关键点：&lt;/strong&gt; 同样必须配合 &lt;code&gt;WHERE&lt;/code&gt; 使用，否则会清空整个表的数据。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;DELETE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt; [&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;条件&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;DELETE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; users 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;101&lt;/span&gt;; &lt;span style="color:#75715e"&gt;-- 删除 ID 为 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DELETE 语句的条件可以有，也可以没有，如果没有条件，则会删除整张表的所有数据。&lt;/li&gt;
&lt;li&gt;DELETE 语句不能删除某一个字段的值（可以使用 UPDATE）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id="对比"&gt;对比
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;DELETE (DML)&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;TRUNCATE (DDL)&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;底层逻辑&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;逐行扫描与标记&lt;/strong&gt;。像“精细手术”，逐条检查并标记删除。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;数据页释放&lt;/strong&gt;。像“拆迁重建”，直接解除数据页与表的映射。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;事务日志 (Logging)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;全额记录&lt;/strong&gt;。记录每一行数据的变化，以便回滚。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;最小化记录&lt;/strong&gt;。仅记录页面释放的操作，日志开销极小。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;执行速度&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;慢&lt;/strong&gt;。随着数据量增加，性能呈线性下降。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;极快&lt;/strong&gt;。无论数据量是 1 万还是 1 亿，耗时基本一致。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;空间回收 (HWM)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;不释放&lt;/strong&gt;。高水位线（High Water Mark）不变，表占用的物理空间不减小。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;立即释放&lt;/strong&gt;。重置高水位线，将空间还给表空间/操作系统。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;自增列 (Identity)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;不重置&lt;/strong&gt;。删除后插入新数据，ID 会接着原来的序号递增。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;重置&lt;/strong&gt;。将自增计数器恢复到初始状态（通常是 1）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;触发器 (Triggers)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;激活&lt;/strong&gt;。每一行被删除时都会触发对应的 &lt;code&gt;DELETE&lt;/code&gt; 触发器。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;忽略&lt;/strong&gt;。不会激活任何触发器，因为不进行逐行操作。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;WHERE 子句&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;。可以精确删除某一部分符合条件的数据。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;不支持&lt;/strong&gt;。只能“一锅端”，清空整个表。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;回滚能力 (Rollback)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;。在未提交的事务中可以完全撤销。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;视数据库而定&lt;/strong&gt;。MySQL 等多数库不支持，PostgreSQL/SQL Server 支持。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;外键约束&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;。受外键约束限制，若有关联数据会报错。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;受限&lt;/strong&gt;。如果表被外键引用，通常必须先删除外键才能执行。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;锁机制&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;行级锁&lt;/strong&gt;。执行时只锁定被操作的行，并发性较高。&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;表级锁&lt;/strong&gt;。执行时通常会锁定整张表，阻止其他访问。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="什么时候必须用-delete"&gt;什么时候必须用 &lt;code&gt;DELETE&lt;/code&gt;？
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;需要根据特定条件（如 &lt;code&gt;status = 'expired'&lt;/code&gt;）删除数据时。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;当你需要依赖 &lt;strong&gt;事务安全性&lt;/strong&gt;（即如果操作失败，必须能撤回所有更改）时。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;表中有复杂的 &lt;strong&gt;触发器&lt;/strong&gt; 逻辑需要维持数据的一致性或审计。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="什么时候必须用-truncate"&gt;什么时候必须用 &lt;code&gt;TRUNCATE&lt;/code&gt;？
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;清理日志表/临时表&lt;/strong&gt;：当数据已经过期且量级巨大（百万、千万级以上）时。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;重置环境&lt;/strong&gt;：在开发测试阶段，希望快速清空表并让自增主键归零。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优化存储&lt;/strong&gt;：当表删除大量数据后，物理空间依然占用过高，需要通过 &lt;code&gt;TRUNCATE&lt;/code&gt; 彻底释放磁盘空间。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="dql"&gt;DQL
&lt;/h1&gt;&lt;h2 id="基本查询"&gt;基本查询
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;设置别名&lt;/strong&gt;(别名会在表头显示)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;字段&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; [&lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;别名&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;], &lt;span style="color:#960050;background-color:#1e0010"&gt;字段&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; [&lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;别名&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;] ... &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 使用 AS 给列起中文名
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; name, age &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;年龄&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; users; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 直接空格加别名
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; name &lt;span style="color:#e6db74"&gt;&amp;#39;姓名&amp;#39;&lt;/span&gt;, entrydate &lt;span style="color:#e6db74"&gt;&amp;#39;入职日期&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;**去除重复记录 **(DISTINCT)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;字段列表&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 查询公司有哪些不同的工作岗位 单字段去重
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt; job &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 只有当 job 和 dept 同时相同时才会被去重 多字段去重
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt; job, dept &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="条件查询"&gt;条件查询
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;语法&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;字段列表&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;条件列表&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;条件&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;比较运算符&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;运算符&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;功能描述&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;示例代码块&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;gt;=&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;lt;=&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;大于、大于等于、小于、小于等于&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;WHERE age &amp;gt;= 18&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;=&lt;/code&gt;, &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; 或 &lt;code&gt;!=&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;等于、不等于&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;WHERE job != '经理'&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;BETWEEN &amp;hellip; AND &amp;hellip;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;在范围内（含最小值和最大值）&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;WHERE age BETWEEN 20 AND 30&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;IN(&amp;hellip;)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;在指定的集合/列表中，多选一&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;WHERE city IN ('北京', '上海', '广州')&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;LIKE 占位符&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;模糊匹配&lt;/strong&gt;（&lt;code&gt;_&lt;/code&gt; 匹配单个字符，&lt;code&gt;%&lt;/code&gt; 匹配任意字符）&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;WHERE name LIKE '张%'&lt;/code&gt; (姓张的)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;IS NULL&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;判断值是否为空&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;WHERE email IS NULL&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;逻辑运算符&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;运算符&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;功能描述&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;示例代码块&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;AND&lt;/strong&gt; 或 &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;并且（多个条件必须同时成立）&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;WHERE age &amp;gt; 18 AND gender = '女'&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;OR&lt;/strong&gt; 或 `&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;`&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;NOT&lt;/strong&gt; 或 &lt;code&gt;!&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;非、不是（取反）&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;WHERE age NOT BETWEEN 20 AND 30&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="聚合函数"&gt;聚合函数
&lt;/h2&gt;&lt;h3 id="常见聚合函数"&gt;常见聚合函数
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;函数&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;功能&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;示例代码&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;COUNT()&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;统计数量（行数）&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT COUNT(*) FROM emp;&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;SUM()&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;求和&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT SUM(salary) FROM emp;&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;AVG()&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;求平均值&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT AVG(salary) FROM emp;&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;MAX()&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;求最大值&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT MAX(age) FROM emp;&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;MIN()&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;求最小值&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;SELECT MIN(age) FROM emp;&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="基础语法"&gt;基础语法
&lt;/h3&gt;&lt;p&gt;聚合函数通常直接紧跟在 &lt;code&gt;SELECT&lt;/code&gt; 之后：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;聚合函数&lt;/span&gt;(&lt;span style="color:#960050;background-color:#1e0010"&gt;字段列表&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt; [&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;条件&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;聚合函数注意点：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NULL 值被忽略&lt;/strong&gt;：所有的聚合函数（尤其是 &lt;code&gt;COUNT&lt;/code&gt;, &lt;code&gt;AVG&lt;/code&gt;, &lt;code&gt;SUM&lt;/code&gt;）都会&lt;strong&gt;自动忽略 NULL 值&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;_例子_：如果 10 个人里有 2 个人没发工资（NULL），`AVG(salary)` 的结果是 `总工资 / 8`，而不是除以 10。
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;WHERE 的限制&lt;/strong&gt;：聚合函数&lt;strong&gt;不能&lt;/strong&gt;直接写在 &lt;code&gt;WHERE&lt;/code&gt; 子句中。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;_错误写法_：`SELECT * FROM emp WHERE salary &amp;gt; AVG(salary);` (这是初学者最容易犯的错)。
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;正确做法&lt;/em&gt;：需要使用子查询或使用 &lt;code&gt;HAVING&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;单值输出&lt;/strong&gt;：聚合函数的结果是一个单行单列的数值。除非配合 &lt;code&gt;GROUP BY&lt;/code&gt;，否则不能在 &lt;code&gt;SELECT&lt;/code&gt; 中同时查询聚合函数和普通字段（如 &lt;code&gt;SELECT name, COUNT(*)&lt;/code&gt; 在大多数数据库中是逻辑错误的）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="分组查询"&gt;分组查询
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;基本查询&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;字段列表&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt; [&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;条件&lt;/span&gt;] &lt;span style="color:#66d9ef"&gt;GROUP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;分组字段名&lt;/span&gt; [&lt;span style="color:#66d9ef"&gt;HAVING&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;分组后过滤条件&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;--	执行时机不同：where 是分组之前进行过滤，不满足 where 条件，不参与分组；而 having 是分组之后对结果进行过滤。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;--	判断条件不同：where 不能对聚合函数进行判断，而 having 可以.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;聚合函数&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;HAVING&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意点：&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 逻辑 1：统计行数（包含 NULL）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 只要这一组有 2 行，哪怕地址全是空，结果也显示 2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; workaddress, &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#f92672"&gt;*&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;GROUP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; workaddress 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;HAVING&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#f92672"&gt;*&lt;/span&gt;) &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 逻辑 2：统计非空值数量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 虽然这一组有 2 行（满足 HAVING），但由于这两行地址是 NULL，
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- COUNT(workaddress) 统计不到任何非空值，结果显示 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; workaddress, &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(workaddress) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;GROUP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; workaddress 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;HAVING&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#f92672"&gt;*&lt;/span&gt;) &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="排序查询"&gt;排序查询
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;基本查询&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;字段列表&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt; [&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;条件&lt;/span&gt;] [&lt;span style="color:#66d9ef"&gt;GROUP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;分组字段&lt;/span&gt;] [&lt;span style="color:#66d9ef"&gt;HAVING&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;过滤条件&lt;/span&gt;] &lt;span style="color:#66d9ef"&gt;ORDER&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;字段&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;排序方式&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;字段&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;排序方式&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;ASC&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;升序（默认值）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;DESC&lt;/span&gt;:&lt;span style="color:#960050;background-color:#1e0010"&gt;降序&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 需求：查询所有员工信息，并按照年龄升序排序
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp &lt;span style="color:#66d9ef"&gt;ORDER&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; age &lt;span style="color:#66d9ef"&gt;ASC&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 需求：查询所有员工，按入职时间降序排序（最近入职的在前）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp &lt;span style="color:#66d9ef"&gt;ORDER&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; entrydate &lt;span style="color:#66d9ef"&gt;DESC&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;多字段排序（二次排序）&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 需求：按照年龄升序排序；如果年龄相同，再按照入职时间降序排序
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp &lt;span style="color:#66d9ef"&gt;ORDER&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; age &lt;span style="color:#66d9ef"&gt;ASC&lt;/span&gt;, entrydate &lt;span style="color:#66d9ef"&gt;DESC&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
&lt;strong&gt;NULL：&lt;strong&gt;在 &lt;strong&gt;MySQL&lt;/strong&gt; 中，&lt;code&gt;NULL&lt;/code&gt; 被视为&lt;/strong&gt;最小值&lt;/strong&gt;
&lt;strong&gt;执行顺序&lt;/strong&gt;：&lt;code&gt;ORDER BY&lt;/code&gt; 是在 &lt;code&gt;SELECT&lt;/code&gt; 之后执行的。这意味着你可以在 &lt;code&gt;ORDER BY&lt;/code&gt; 中使用你在 &lt;code&gt;SELECT&lt;/code&gt; 里起的&lt;strong&gt;别名&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="分页查询"&gt;分页查询
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;基础语法&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;字段列表&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;LIMIT&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;起始索引&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;查询记录数&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 查询第一页 (前 10 条)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 起始索引为 0 时，可以省略不写
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp &lt;span style="color:#66d9ef"&gt;LIMIT&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 等价于：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp &lt;span style="color:#66d9ef"&gt;LIMIT&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 查询第二页 (第 11-20 条)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 从索引 10 开始（即第 11 条），往后查 10 条
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp &lt;span style="color:#66d9ef"&gt;LIMIT&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 查询第三页 (第 21-30 条)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; emp &lt;span style="color:#66d9ef"&gt;LIMIT&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;计算公式:&lt;/strong&gt;
&lt;strong&gt;起始索引 = (查询页码 - 1) * 每页显示记录数&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;例子&lt;/em&gt;：想看第 5 页，每页 10 条。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;计算&lt;/em&gt;：&lt;code&gt;(5 - 1) * 10 = 40&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;SQL&lt;/em&gt;：&lt;code&gt;SELECT * FROM emp LIMIT 40, 10;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;另外注意点：&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;方言限制&lt;/strong&gt;：&lt;code&gt;LIMIT&lt;/code&gt; 是 &lt;strong&gt;MySQL&lt;/strong&gt; 的方言。如果用的是 Oracle，需要用 &lt;code&gt;ROWNUM&lt;/code&gt;；如果是 SQL Server，需要用 &lt;code&gt;TOP&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;执行顺序&lt;/strong&gt;：&lt;code&gt;LIMIT&lt;/code&gt; 永远是 SQL 语句中&lt;strong&gt;最后执行&lt;/strong&gt;的一个环节&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;大分页性能&lt;/strong&gt;：当数据量达到百万级，&lt;code&gt;LIMIT 1000000, 10&lt;/code&gt; 会变得很慢，因为数据库需要先扫描前 100 万条再丢弃，后续需要通过索引优化或子查询来解决&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="执行顺序-逻辑顺序"&gt;执行顺序 (逻辑顺序)
&lt;/h2&gt;&lt;p&gt;理解 DQL 的关键不在于怎么写，而在于数据库&lt;strong&gt;怎么读&lt;/strong&gt;。书写顺序和执行顺序是不一样的：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#960050;background-color:#1e0010"&gt;字段列表&lt;/span&gt; &lt;span style="color:#75715e"&gt;-- 5. 确定要显示的字段
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#960050;background-color:#1e0010"&gt;表名列表&lt;/span&gt; &lt;span style="color:#75715e"&gt;-- 1. 确定去哪张表找
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#960050;background-color:#1e0010"&gt;条件列表&lt;/span&gt; &lt;span style="color:#75715e"&gt;-- 2. 第一次行过滤
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;GROUP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#960050;background-color:#1e0010"&gt;分组字段列表&lt;/span&gt; &lt;span style="color:#75715e"&gt;-- 3. 数据分组
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;HAVING&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#960050;background-color:#1e0010"&gt;分组后过滤条件&lt;/span&gt; &lt;span style="color:#75715e"&gt;-- 4. 第二次组过滤
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;ORDER&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#960050;background-color:#1e0010"&gt;排序字段列表&lt;/span&gt; &lt;span style="color:#75715e"&gt;-- 6. 对结果进行排序
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;LIMIT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#960050;background-color:#1e0010"&gt;起始索引&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;记录数&lt;/span&gt;; &lt;span style="color:#75715e"&gt;-- 7. 截取最终结果
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;执行步骤&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;关键字&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Step 1&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;FROM&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;确定去哪张表找数据。&lt;/td&gt;
					&lt;td&gt;表名列表&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Step 2&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;WHERE&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;按照条件过滤原始行数据。&lt;/td&gt;
					&lt;td&gt;条件列表&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Step 3&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;GROUP BY&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;将过滤后的数据分组（如按部门）。&lt;/td&gt;
					&lt;td&gt;分组字段列表&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Step 4&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;HAVING&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;对分组后的结果再次进行过滤。&lt;/td&gt;
					&lt;td&gt;分组后条件列表&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Step 5&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;SELECT&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;选出最终要显示的列。&lt;/td&gt;
					&lt;td&gt;字段列表&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Step 6&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;ORDER BY&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;对最终结果进行排序。&lt;/td&gt;
					&lt;td&gt;排序字段列表&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Step 7&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;LIMIT&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;限制显示的行数（分页）。&lt;/td&gt;
					&lt;td&gt;分页参数&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="dcl"&gt;DCL
&lt;/h1&gt;&lt;h2 id="管理用户"&gt;管理用户
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;查询用户&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;USE&lt;/span&gt; mysql;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;user&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;创建用户&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;USER&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;用户名&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;@&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;主机名&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;IDENTIFIED&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;密码&amp;#39;&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 示例：创建一个只能在当前主机(localhost)登录的用户
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;USER&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;work_user&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;@&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;IDENTIFIED&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;123456&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 示例：创建一个可以在任意主机(%)登录的用户
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;USER&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;remote_user&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;@&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;%&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;IDENTIFIED&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;123456&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;修改/删除用户&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-MySQL" data-lang="MySQL"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 修改用户密码 (MySQL 8.0+)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;ALTER&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;USER&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;work_user&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;@&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;IDENTIFIED&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;WITH&lt;/span&gt; mysql_native_password &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;new_password&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 删除用户
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;DROP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;USER&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;work_user&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;@&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="权限控制"&gt;权限控制
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;常用权限&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;权限名称&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;作用描述&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;SELECT&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;查询数据（最常用）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;INSERT&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;插入新数据&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;修改现有数据&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;DELETE&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;删除现有数据&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ALTER&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;修改表结构（如增加列）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;DROP&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;删除表或数据库&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;CREATE&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;创建新表或数据库&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ALL [PRIVILEGES]&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;所有权限（最高权限）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;查询权限&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-mysql" data-lang="mysql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 查询指定用户的权限
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SHOW&lt;/span&gt; GRANTS &lt;span style="color:#66d9ef"&gt;FOR&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;heima&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;@&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;授予权限&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-mysql" data-lang="mysql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;GRANT&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;权限列表&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;数据库名&lt;/span&gt;.&lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TO&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;用户名&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;@&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;主机名&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 1. 授予单个权限：允许用户查询 test 库中的 emp 表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;GRANT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; test.emp &lt;span style="color:#66d9ef"&gt;TO&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;heima&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;@&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 2. 授予多个权限：允许用户对 test 库所有表进行查询、插入、修改
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;GRANT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;INSERT&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;UPDATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; test.&lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TO&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;heima&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;@&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 3. 授予所有权限：允许用户操作所有数据库的所有表（DBA 级别）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;GRANT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ALL&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;.&lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TO&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;admin&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;@&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;%&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;撤销权限&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-mysql" data-lang="mysql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;REVOKE&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;权限列表&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;数据库名&lt;/span&gt;.&lt;span style="color:#960050;background-color:#1e0010"&gt;表名&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;用户名&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;@&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;主机名&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 撤回用户对 test 库所有表的插入(INSERT)权限
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;REVOKE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INSERT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; test.&lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;heima&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;@&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;-- 撤回所有权限
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;REVOKE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ALL&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;.&lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;admin&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;@&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;%&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item></channel></rss>