JVM 核心知識全解析:從類加載到垃圾回收的深度認知

什么是JVM?
  • JVM全稱(Java Virtual Machine),中譯為:Java虛擬機
    • 本質:是一個運行在計算機上的程序
  • 職責:運行Java字節碼文件(因為計算機只能認識機器碼文件,所以需要JVM將自字節碼轉為機器碼)
  • 功能:
    • 解釋和運行:字節碼轉機器碼
    • 內存管理:自動為對象/方法分配內存,垃圾回收
    • 即時編譯:對熱點代碼進行優化
常見的JVM

JVM的組成部分

類加載器:加載class文件

運行時數據區域:管理內存

執行引擎:垃圾回收器/即時編譯器/解釋器

本地接口:java使用native修飾的方法

字節碼文件的組成
  • 打開方式:
    • 字節碼是以二進制存儲,不能直接使用文本軟件打開
    • 使用軟件:jclasslib-bytecode-viewer

MAC安裝命令: brew install jclasslib-bytecode-viewer

  • 組成(5部分)
    • 基礎信息:存儲java版本號,訪問標識
    • 常量池:存儲字符串常量/類或接口名/字段名
    • 字段:存儲變量名/變量類型/標識
    • 方法:存儲方法原代碼指令
    • 屬性:存儲類的屬性

字節碼文件組成詳解(基本信息/常量池/方法)
  • 基本信息包含:Magic魔數/副版本號/主版本號/訪問標識/類等
    • Magic魔數(固定字符):是字節碼文件的前幾個字節,用于確定文件的文件類型

- 主副版本號:主(大版本號 )使用當前的主版本號-44得到真正的jdk版本號* 例如:主版本號為:52,減完后得到jdk1.8
- 副版本號:為主版本號相同時,區分不同版本的標識
- 版本號的作用:判斷當前字節碼的版本和運行時jdk是否相兼容* 例如:報錯:<font style="color:#DF2A3F;">字節碼文件為jdk8,運行時jdk為6</font>

- 版本號不同的解決方案:
- ![](https://i-blog.csdnimg.cn/img_convert/bea7ceac8c7c3c4f26ef36121acd028b.png)
字節碼文件的組成-常量池
  • 常量池作用:避免相同的內容重復定義
字節碼文件的組成-方法
  • 字節碼指令
  • 字節碼執行過程:

iconst_0 # 現將o放入到操作數棧中,
istore_1 #0從操作數棧彈出,存儲到局部變量表中下標為1的位置中
注意:下標為0中存儲args數組
iload_1 # 將局部變量中的下標為1的內容復制到棧中
iinc1 by 1 將下標為1的值變為1
istore_1 # #0從操作數棧彈出,存儲到局部變量表中下標為1的位置中
return 返回
總結:最后的結果還是為0
字節碼文件-練習題:

 0 iconst_01 istore_12 iconst_03 istore_24 iconst_05 istore_36 iinc 1 by 19 iload_2
10 iconst_1
11 iadd
12 istore_2
13 iinc 3 by 1
16 return
字節碼文件常用工具
  1. 命令:javap -v

  1. jclasslib插件
    1. 注意點:想看哪一個文件,先點擊文件后在點擊視圖打開jclasslib
    2. 注意點:修改后的文件,需要重新編譯后才會有對應的字節碼文件

  1. 阿里arthas
    1. jad命令可以將class文件還原java文件

類的生命周期
  • 類的生命周期描述了一個類加載/使用/卸載的整個過程
  • 概述:
    • 生命周期分為5個階段:加載(Loading)》連接(Linking)〉初始化(Init)》使用(Using)〉卸載(Unloading)
    • 注意:連接可以在分為三個階段為:驗證》準備〉解析
類的加載階段
  • 第一步:類加載器根據類的全限定名通過不同渠道以二進制方式獲取字節碼信息
  • 第二步:加載類完成后,JVM會將字節碼信息存到內存中的方法區中
    • 生成一個instanceKlass對象,保存了類的所有信息(例如:基本信息,常量池/字段/方法等)
  • 第三步:JVM還有在堆中生成一份與方法區數據類似的java.lang.Class對象
  • 總結:類加載器根據類的類名會將類的字節碼信息存入到內存中,并在方法區的對區分別分配一個對象,保存類的信息
  • 注意:方法區和堆區的對象是有關聯的
類的連接階段

  1. 驗證階段
    1. 舉例:
      1. 魔數校驗

    2. 元信息校驗(類必須有父類)3. 主版本號校驗

  1. 準備階段
    1. 準備階段:在堆區分配一塊空間給Student對象,并對屬性value賦默認值0

注意點:如果使用final修飾的話,在準備階段就是賦值

  1. 解析階段
  • 作用:將常量池中的符號引用轉為直接引用
類加載器的初始化階段
  1. 行為:會執行靜態代碼塊中的代碼,并為靜態變量賦值
  2. 使用的字節碼命令:clinit
  3. 示例:
    1. 先賦值2,在賦值1,最后value中的值為:1

  1. 類初始化的幾種方式
  • 訪問一個類的靜態變量或者靜態方法,
public class Test {public static void main(String[] args) {int i = Test1.i;System.out.println(i);}
}
class Test1{public static int i=0;static{System.out.println("init");}
}

  • 調用Class.forName(String className)
public class Test {public static void main(String[] args) throws ClassNotFoundException {Class.forName("Test1");}
}
class Test1{static{System.out.println("init");}
}
  • new一個該類的對象時
  • 執行Main方法的當前類
public class Test {static {System.out.println("init Test");}public static void main(String[] args) throws ClassNotFoundException {Test1 test = new Test1();}
}
class Test1{static{System.out.println("init Test1");}
}

  1. 面試題(靜態代碼塊先執行,在執行main方法,在執行構造方法和構造器方法)
    1. 答案:DACBCB

  1. clinit不會出現的情況:

  1. 面試題2

  1. 練習題1

  1. 練習題2

  1. 總結

類加載器ClassLoader
  1. 用途:將二進制流》加載〉本地接口調用》生成方法區和堆區的對象
  2. 應用場景:
    1. SPI機制
    2. 類的熱部署
    3. Tomcat類的隔離
    4. 面試題:雙親委派機制,如何打破雙親,自定義類加載
類加載器的分類
  1. 兩類
    1. java虛擬機低層實現
      1. 例如:hotspot使用C++
    2. java代碼實現
      1. 根據需要自定義
  2. 特點:需要繼承ClassLoder

類加載器-啟動類加載器Bootstrap
  1. String類是由啟動類加載器加載的,但是在使用String.class.getClassLoader()方法時,返回的結果為null,因為,類加載器存在于jvm中,所以獲取不到。
  2. 命令:sc -d java.lang.String

class-loader 為空

  1. 如何使用啟動類加載器加載自定義的jar包

  1. 練習:使用方法二:

類加載器-擴展類加載器(Extension Class Loader)
  • 默認加載Java安裝目錄/jre/lib/ext下的類文件
package cn.varin.Test;import jdk.nashorn.internal.runtime.ScriptEnvironment;import javax.script.ScriptEngineManager;
import java.io.IOException;public class Test {public static void main(String[] args)  {ClassLoader classLoader = ScriptEnvironment.class.getClassLoader();System.out.println(classLoader);}}

  • 將自己編寫的擴展jar包,添加到ext包下

類加載器-應用程序加載器(Application Class Loader)
  • 程序員自己創建的類和第三方類會使用Application加載
package cn.varin.Test;import jdk.nashorn.internal.runtime.ScriptEnvironment;import javax.script.ScriptEngineManager;
import java.io.IOException;public class Test {public static void main(String[] args)  {ClassLoader classLoader = Person.class.getClassLoader();System.out.println(classLoader);}}
class Person{private String name;private int age;
}

雙親委派機制
  1. 核心:解決一個類到底是由誰加載的問題
  2. 作用:
    1. 保證類加載的安全性
    2. 避免重復加載
  3. 解釋:

1. 示例1:假設cn.varin.Person對象加載,它會先找Application,如果沒有找到加載,繼續找Ext,沒有再繼續找 Boot,找到,返回
2. 示例2:加載cn.varin.Person對象都沒有被三個加載器加載過,它會從boot找,是否在路徑中,沒有的話,繼續找Ext,沒有的話,繼續找Application,找到,返回

問題:如果一個類重復出現在三個類加載器中,誰來加載

答案:啟動類加載器加載,根據雙親委派機制,它的優先級最高

問題2:在自己的項目中創建一個java.lang.String類,會被加載嗎

答案:不能,會返回啟動類加載器加載在rt包中的String類

package cn.varin.Test;import jdk.nashorn.internal.runtime.ScriptEnvironment;import javax.script.ScriptEngineManager;
import java.io.IOException;public class Test {public static void main(String[] args) throws ClassNotFoundException {ClassLoader classLoader = Test.class.getClassLoader();System.out.println(classLoader);Class<?> aClass = classLoader.loadClass("java.lang.String");System.out.println(aClass.getClassLoader());}}
#  結果為:Applicationnull
面試題:類的雙親委派機制是什么?

當一個類加載器區加載某一個類的時候,會自底向上的查詢父類是否加載過,

如果加載過,直接返回,

如果沒有加載過,會自頂向下查詢路徑進行加載。

app 的父為:Ext

Ext 的父為:Boot

打破雙親委派機制
  1. 打破雙親委派機制的三種方式
    1. 自定義類加載器
    2. 利用上下文類加載器
    3. 使用Osg框架的類加載器
  2. 需要打破雙親委派機制的場景
    1. 有兩個應用需要運行,但是兩個應用中的某一個類的全路徑名是相同的,假設A加載了,B再加載,類加載器會認為是A類
打破雙親委派機制-自定義類加載器

實現方法:重寫findClass方法,這樣就不會破壞雙親委派機制

打破雙親委派機制-線程上下問加載器

利用上下文類加載器加載類,比如:JDBC和JNDI

  • 快速獲取到線程上下文類加載器
Thread.currentThread().getContextClassLoader()
  • 總結

  • 思考:JDBC案例是否真正的打破了雙親委派

打破雙親委派機制-Osgi模塊化(了解)
JDK9之后的類加載器
  1. 區別一

  1. 區別二:擴展類加載器

  1. 區別三:應用程序類加載器

類加載器小結
  1. 類加載器的作用

  1. 有幾種類加載器?

  1. 什么是雙親委派機制

  1. 怎么打破雙親委派機制

運行時數據區域

運行時數據區是:jVM在運行Java程序過程中管理的內存區域

  • 分類:

運行時數據區域-程序計數器

程序計數器:

作用一:用于存放下一條指令需要執行的地址

作用二:在多線程執行下,程序計數器可以記錄CPU切換前每個線程解釋執行到那一條指令

問題:程序計數器會發生內存溢出嗎:

答案:不會,因為每個線程只存儲了一個固定長度的地址,是不會發生內存溢出的。

運行時數據區域-棧
  1. 分為了:
    1. Java虛擬機棧
      1. 保存在Java中實現的方法
    2. 本地方法棧
      1. 保存方法中有native關鍵字的
      2. 源代碼保存在c++中
運行時數據區域-棧-Java虛擬機棧
  1. 存儲順序:先進后出
  2. 棧幀的組成:
    1. 局部變量表:
      1. 方法執行過程中存放所有的局部變量
      2. 保存的內容:有實例的this對象,方法的參數,方法體中聲明的局部變量。

例題:

答案:6個

2. 操作數棧:1. 存放臨時數據,例如:常量
3. 棧數據1.  存儲:動態鏈接,方法出口,異常表
  • 設置修改棧的大小

    • 注意點:

運行時數據區-堆
  1. 堆內存是空間最大的一塊內存區域,創建出來的對象都存在于堆上
  2. 堆空間可以分為:use+total+max
    1. use:使用空間
    2. total(默認是系統內容的六十四分之一):剩余空間(可以動態增加, )
    3. max(默認分配系統內存的四分之一):最大可用空間
  3. 手動設置total和max

運行時數據區域-方法區
  1. 存儲 :
    1. 類的基本信息
    2. 運行時常量池
    3. 字符串常量池
  2. jdk7把方法區存儲在堆區域中的永久代空間
  3. jdk8將方法區存放在元空間中,云空間位于內存中,只要不超過內存,可以一直存
運行時數據區域-方法區-字符串常量池
  1. 代碼示例

String s1 = new String(“1”);

String s2 = “1”;

解釋:s1中的字符串是通過new對象創立的,內容會存儲在堆中

s2中的字符串是直接創立的,會存儲在方法區的字符串常量池中

s1和s2都是存儲在棧中,

  • 運行時常量池和字符串常量池的區別

  • 練習題1:

  • false和true
  • 練習題2

  • 練習題3

  • 總結
  • 在jdk7及以后版本中,靜態變量是存儲在堆的Class對象中,脫離了永久代
直接內存
  1. 直接內存的作用:
    1. 適應NIO機制
    2. 提升IO操作效率

3. 在jdk8后,直接保存方法區中的數據
  1. 直接內存設置

運行時數據區域總結
  1. 運行時數據區分為幾部分,每一部分的作用是什么?

兩大部分:

線程不共享:

程序計數器:記錄當前要執行的字節碼指令的地址(不會出現內存溢出)

Java虛擬機棧:

本地方法棧:

Java虛擬機棧和本地方法棧都是采用棧式存儲,用于保存方法調用的基本數據(局部變量,操作數等)(會出現內存溢出)

線程共享:

方法區:主要存儲類的元信息,以及常量池(會出現內存溢出)

堆區: 存放創建出來的對象(會出現內存溢出 )

  1. 不同JDK版本直接的運行時數據區的區別是什么?

jdk6:

jdk7:

jdk8:

自動垃圾回收
  1. 范圍:負責對堆上的內存進行回收(回收不再使用的對象)

  2. 優點:降低程序員實現難度

自動垃圾回收-方法區回收
  1. 回收條件

  1. 擴展:System.gc()
    1. 作用:手動出發垃圾回收器
自動垃圾回收-堆區回收判斷-引用計數法
  1. 如何判斷堆上的對象有沒有被引用:使用引用計數法
  2. 每一個對象有一個引用計數器:當對象被引用時+1,取消引用-1
  3. 存在缺陷:
    1. 可能產生循環引用
自動垃圾回收-堆區回收判斷-可達性分析算法
  1. 可達性分析將對象分為兩類:
    1. 垃圾回收的根對象(GC root) :
    2. 普通對象
  2. 回收原理:可達性分析中,存在一個不可回收的GC Root對象, 該對象會引用其他對象,可達分析通過判斷,如果從GC Root開始找,沒有找到的對象就是可以回收的。?

  • GC Root對象種類
  1. 線程Thread對象,
  2. 系統類加載器加載的Java.lang.Class對象
  3. 監視器對象,用來保存同步鎖synchroized關鍵字的對象
  4. 本地方法調用時使用的全局對象
  • 可達性分析法中的引用屬于強引用
自動垃圾回收-軟引用

軟引用:如果一個對象只有軟引用,當程序內存不足時,就會將軟引用中的數據進行回收

常用于:緩存中

如何實現軟引用:提供SoftReference類實現

案例分析:

當先A對象屬于一個強引用,不會不回收

此時:A對象為一個軟引用,可能被回收

  • 注意點:
    • SoftReferenc對象也需要被GC對象強引用,否則也會被回收
自動垃圾回收-弱引用(WaekReference)
  1. 弱引用和軟引用類似,不同點就是**軟引用是在內存不足時才會回收,但是弱引用不需要看內存夠不夠直接回收**。
自動垃圾回收-虛引用和終結器引用
  1. 虛引用作用:當對象被垃圾回收器回收時可以接收到對應的通知
  2. 終結器引用:

垃圾回收算法的評價標準

核心思想:找到內存中存活的對象 ,把不再存活的對象釋放

常見的垃圾回收算法:

標記-清除算法

復制算法

標記-整理算法

分代GC

評價標準:

STW(stop the world):停止所有的用戶線程的時間

吞吐量(越高效率越好):執行用戶代碼時間?(執行用戶代碼時間+GC使勁)

最大暫停時間:在垃圾回收時,STW時間的最大值

垃圾回收算法-標記清除算法

2個階段:

  1. 標記階段:將所有存活的對象標記(使用可達性分析法)
  2. 清除階段:從內存中刪除沒有被標記的對象

優點:實現簡單,第一階段將存活的標記為1,第二階段刪除非1的對象

缺點:

碎片化:對象刪除后,出現多個很小的可用單元;

分配速度慢

垃圾回收算法-復制算法

執行過程:

準備2塊空間(from和To),只使用from空間,

在垃圾回收階段,將存活的對象復制到to中

回收結束后,將from和to的名稱互換。

優點:吞吐量高,不會產生碎片化

缺點:內存使用效率低(每次只能使用一般的空間)

垃圾回收算法-標記-整理算法

2個階段:

  1. 標記階段:將所有存活的對象標記(使用可達性分析法)
  2. 整理階段:將存活的對象移動到堆的一端,清除掉間空隙和碎片

優點:內存使用效率高,不會產生碎片化

缺點:整理階段效率不高

垃圾回收算法-分代GC
  1. 分區
    1. 年輕代(yong區):使用復制算法
      1. 分為:
        1. 伊甸園區
        2. s0:from
        3. s1:to
    2. 老年代(old區)
  2. 年輕代到老年代:年輕代沒執行一次GC,會在存活對象標記一個屬性并加一,到屬性值達到某一個值,就會轉移到老年代
  3. 為什么要分為年輕代和老年代?
    1.
垃圾回收算器
  1. 垃圾回收器的種類

組合:

G1垃圾回收器

垃圾回收器的選擇

自動垃圾回收總結
  1. Java中有那幾塊內存需要進行垃圾回收

    1. 在運行時數據區總堆中的數據需要垃圾回收器進行回收
  2. 有哪幾種常見的引用類型

  1. 有哪幾種常見的垃圾回收算法

    1. 標記清除:標記可用的,沒用的清除
    2. 復制算法:分兩塊空間,將可用的復制同一塊區域中,清除掉另一塊,并交換名字
    3. 標記整理:將可用的標記并放到另一端后,將另一端清除
    4. 分代GC:分為年輕代和老年代,可以用多中回收算法
  2. 常見的垃圾回收器有哪些?

    1. serial和serial old:單線程回收,使用單核CPU場景
    2. parNew和CMS:暫停時間較短,適用于大型互聯網應用中與用戶交互的部分
    3. parallel Scavenge和Parallel old:吞吐量高,適用于后臺進行大量數據操作
    4. G1:適用于較大的堆,具有可控的暫停時間

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/99094.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/99094.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/99094.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Keepalived 負載均衡

Keepalived 負載均衡 Keepalived 可以與 LVS&#xff08;Linux Virtual Server&#xff09;結合&#xff0c;提供強大的四層負載均衡功能。它通過 IPVS&#xff08;IP Virtual Server&#xff09;內核模塊實現高性能的負載分發。 核心組件 Virtual Server&#xff1a;虛擬服務器…

拷打DeepSeek實現自動生成差分電荷計算文件和后處理

差分電荷&#xff08;charge density difference&#xff09;是材料模擬中分析電子結構變化的直觀工具。 它把成鍵后的真實電荷密度減去成鍵前各碎片疊加的電荷密度&#xff0c;得到一張“電子遷移地圖” 于是可以一眼看出化學鍵形成時電子從哪里來到哪里去&#xff0c;表面吸…

AI問答-Nuxt4:什么時候發布的,有哪些特性,和Nuxt3相比 有哪些優勢 / Nuxt4 / Nuxt-v4

Nuxt 4于2025年7月至8月期間正式發布&#xff0c;作為Nuxt框架的重大版本更新&#xff0c;其核心聚焦于穩定性提升、開發者體驗優化及性能增強&#xff0c;與Nuxt 3相比&#xff0c;優勢體現在項目結構、數據獲取、類型系統、開發工具鏈等多個層面。一、Nuxt 4 發布時間線測試階…

isinstance()和insubclass()

??isinstance() 和 issubclass() 的功能與用法????1. isinstance(obj, classinfo)????功能??&#xff1a;檢查對象 obj 是否是 classinfo 類&#xff08;或其子類&#xff09;的實例。 ??返回值??&#xff1a;True 或 False。 ??用法??&#xff1a;class A…

判斷QMetaObject::invokeMethod()里的函數是否調用成功

今天&#xff0c;在Qt編程&#xff0c;碰到一個需要使用invokeMethod方式來獲取函數是否執行成功的情況。 ? ? invokeMethod()即可以同步調用&#xff0c;也可以異步調用。若調用者、被調用者&#xff0c;都在同一個線程&#xff0c;則是同步調用&#xff1b;若調用者、被調用…

【linux】特殊權限

us對文件&#xff1a;用戶執行該文件時&#xff0c;會以文件所有者的權限運行chmod us filename # 符號模式 chmod 4755 filename # 數字模式&#xff08;4表示SetUID&#xff09;典型應用&#xff1a;/usr/bin/passwd&#xff08;允許普通用戶修改自己的密碼&#xff0c;…

OpenCV:指紋識別

目錄 一、核心算法 1&#xff1a;SIFT 特征提取&#xff08;尺度不變特征變換&#xff09; 1.1 算法原理&#xff08;4 步核心流程&#xff09; 1.2 重點代碼實現與參數解析 1.3 關鍵輸出解讀 二、核心算法 2&#xff1a;FLANN 特征匹配&#xff08;快速最近鄰搜索&#x…

快速排序:高效的分治排序算法

快速排序因其平均時間復雜度$O(n\log n)$而成為廣泛應用的高效排序算法。其核心是分治法: 選擇基準 (Pivot):從待排序序列中選取一個元素(如第一個元素$arr[0]$)。 分區 (Partition):將序列重新排列,所有小于基準的元素置于其前,大于或等于的置于其后。基準元素最終位于…

網絡編程之UDP廣播與粘包問題

一&#xff0c;廣播簡介從上述講的例?中&#xff0c;不管是TCP協議還是UDP協議&#xff0c;都是”單播”, 就是”點對點”的進?通信&#xff0c;如果要對網絡里面的所有主機進?通信&#xff0c;實現”點對多”的通信&#xff0c;我們可以使用UDP中的?播通信。 理論上可以像…

教育領域大模型生成題目安全研究報告

教育領域大模型生成題目安全研究報告 一、研究背景與意義 隨著大語言模型&#xff08;LLM&#xff09;在教育領域的深度應用&#xff0c;自動生成題目已成為提升教學效率、實現個性化教學的關鍵技術手段&#xff0c;廣泛應用于課堂練習、作業布置、考試命題等場景。然而&…

Android安卓項目調試之Gradle 與 Gradle Wrapper的概念以及常用gradle命令深度詳解-優雅草卓伊凡

Android安卓項目調試之Gradle 與 Gradle Wrapper的概念以及常用gradle命令深度詳解-優雅草卓伊凡好的&#xff0c;我們來詳細梳理一下 Android 開發中 Gradle 的常用配置和調試命令。這對于每一位 Android 開發者來說都是必須掌握的核心技能。第一部分&#xff1a;Gradle 與 Gr…

Maven入門_簡介、安裝與配置

ZZHow(ZZhow1024) 參考課程&#xff1a; 【尚硅谷新版Maven教程】 [https://www.bilibili.com/video/BV1JN411G7gX] 一、Maven簡介 02_依賴管理工具 解決 jar 包的規模問題解決 jar 包的來源問題解決 jar 包的導入問題解決 jar 包之間的依賴 03_構建工具 我們沒有注意過…

Spark(1):不依賴Hadoop搭建Spark環境

不依賴Hadoop搭建Spark環境0 概述1 單機安裝Spark1.1 下載Spark預編譯包1.2 解壓和設置1.3 配置環境變量1.4 驗證安裝2 Spark運行模式2.1 Local模式&#xff08;本地模式&#xff09;2.1.1 Spark Shell2.1.1.1 Python版的Shell2.1.1.2 Scala版的Shell2.1.2 提交獨立的Spark應用…

【ThreeJs】【自帶依賴】Three.js 自帶依賴指南

&#x1f6e0;? Three.js 輔助庫生態手冊 定位&#xff1a;覆蓋 90% 開發場景的工具選型實操指南&#xff0c;區分「入門必備」和「進階擴展」。 適用人群&#xff1a;Three.js 新手&#xff08;≥ r132 版本&#xff09;、需要規范開發流程的團隊。 1. 控制器&#xff08;Co…

Mac電腦上如何打印出字體圖標

背景 我今天打開了一個之前開發的APP&#xff0c;看到項目中用到了字體圖標&#xff0c;發現有個“面條”圖標用錯了&#xff0c;想著修改一下吧。然后用輸入法打出”面條“&#xff0c;在輸入法的彈窗中就一直往下找&#xff0c;發現并沒有出現圖標。 想著打出”面條圖標“也沒…

當AI遇上數據庫:Text2Sql.Net如何讓“說人話查數據“成為現實

一句話概括&#xff1a;還在為寫復雜SQL而頭疼&#xff1f;Text2Sql.Net讓你用自然語言就能查數據庫&#xff0c;堪稱程序員的"數據庫翻譯官"&#xff01; &#x1f3af; 引言&#xff1a;從"SQL地獄"到"自然語言天堂" 想象一下這樣的場景&…

整體設計 之 緒 思維導圖引擎 之 引 認知系統 之8 之 序 認知元架構 之4 統籌:范疇/分類/目錄/條目 之2 (豆包助手 之6)

問題Q68、我們現在僅僅分析了 認知演進 的 “進”的問題&#xff0c;通過層次結構 和 統籌 的同構約束 給出了 不同對象及其對應的操作和約束。 --這句話 你能完全理解嗎&#xff08;這意味著 完整的程序細節設計&#xff09;。 還沒有分析的還有 “演” 以及組合詞 “演進” -…

開始 ComfyUI 的 AI 繪圖之旅-Qwen-Image-Edit(十二)

文章標題一、Qwen-Image-Edit1.ComfyOrg Qwen-Image-Edit 直播回放2.Qwen-Image-Edit ComfyUI 原生工作流示例2.1 工作流文件2.2 模型下載3.3 按步驟完成工作流一、Qwen-Image-Edit Qwen-Image-Edit 是 Qwen-Image 的圖像編輯版本&#xff0c;基于20B模型進一步訓練&#xff0c…

機械制造專屬ERP:降本增效與數字轉型的關鍵

轉型升級壓力下&#xff0c;ERP系統是機械企業破局的得力助手。本文深入解析ERP的核心功能、選型要點與實施價值&#xff0c;助您精準選型&#xff0c;賦能智能制造&#xff0c;全面提升競爭力。在數字化浪潮席卷之下&#xff0c;機械制造企業正面臨提質、增效、降本的關鍵轉型…

npm / yarn / pnpm 包管理器對比與最佳實踐(含國內鏡像源配置與緩存優化)

這篇不是“誰更快”的玄學討論,而是把團隊能落地的做法一次說清:如何選型、如何統一版本、如何把鏡像與緩存配好、如何在 CI 和 Monorepo 下穩住“可重復構建”。 一、結論先說在前 單倉庫 / 以穩定為先:直接用 npm(配合 npm ci) 足夠,維護成本低,生態一等一,Node 16.1…