說幾個常見的語法糖

目錄

面試回答

知識擴展

如何解語法糖?

糖塊一、swith 支持 String 與枚舉

糖塊二、泛型

糖塊三、自動裝箱與拆箱

糖塊四、枚舉

糖塊五、條件編譯

糖塊六、斷言

糖塊七、數值字面量

糖塊八、for-each

糖塊九、try-with-resource

可能遇到的坑

泛型

自動裝箱與拆箱

總結


面試回答

語法糖(Syntactic sugar),指在計算機語言中添加的某種語法,這種語法對語言的功能并沒有影響,但是更方便程序員使用。

雖然 Java 中有很多語法糖,但是 Java 虛擬機并不支持這些語法糖,所以這些語法糖在編譯階段就會被還原成簡單的基礎語法結構,這樣才能被虛擬機識別,這個過程就是解語法糖。

如果看過 Java 虛擬機的源碼,就會發現在編譯過程中有一個重要的步驟就是調用 desugar() ,這個方法就是負責解語法糖的實現。

常見的語法糖有 switch 支持枚舉及字符串、泛型、條件編譯、斷言、可變參數、自動裝箱/拆箱、枚舉、內部類、增強 for 循環、try-with-resources 語句、lambda 表達式等。

知識擴展

如何解語法糖?

語法糖的存在主要是方便開發人員使用。但其實,Java 虛擬機并不支持這些語法糖。這些語法糖在編譯階段就會被還原成簡單的基礎語法結構,這個過程就是解語法糖。

說到編譯,大家肯定都知道,Java 語言中 javac 命令可以將后綴名為 .java 的源文件編譯為 .class 的可以運行于 java 虛擬機的字節碼。如果你去看 com.sun.tools.javac.main.JavaCompiler 的源碼,你會發現在 compile() 中有一個步驟就是調用 desugar(),這個方法就是負責解語法糖的實現的。

糖塊一、swith 支持 String 與枚舉

從 Java 7 開始,Java 語言中的語法糖在逐漸豐富,其中一個比較重要的就是 Java 7 中 swith開始支持 String

在開始 coding 之前先科普下,Java 中的 switch自身原本就支持基本類型。比如 intchar等。對于 int類型,直接進行數值的比較。對于 char類型則是比較其 ascii 碼。所以,對于編譯器來說,switch 中其實只能使用整型,任何類型的比較都要轉換成整型。比如 byteshortchar 以及int (ascii 碼是整型)。

那么接下來看下 switchString 的支持,如以下代碼:

public class main {public static void main(String[] args) {String str="word";switch (str){case "hello":System.out.println("hello");break;case "world":System.out.println("world");break;default:break;}}
}

反編譯后內容如下:

public class main
{public main(){}public static void main(String args[]){String str = "word";String s = str;byte byte0 = -1;switch(s.hashCode()){case 99162322: if(s.equals("hello"))byte0 = 0;break;case 113318802: if(s.equals("world"))byte0 = 1;break;}switch(byte0){case 0: // '\0'System.out.println("hello");break;case 1: // '\001'System.out.println("world");break;}}
}

看到這個代碼,你知道原來字符串的 switch 是通過 equals()hashCode()方法來實現的。還好 hashCode() 方法返回的是 int ,而不是 long

仔細看下可以發現,進行 switch的實際是哈希值,然后通過使用 equals方法比較進行安全檢查,這個檢查是必要的,因為哈希可能發生碰撞。因此它的性能是不如使用枚舉進行 switch 或者使用純整數常量,但這也不是很差。

糖塊二、泛型

我們都知道,很多語言都是支持泛型的,但是很多人不知道的是,不同的編譯器對于泛型的處理方式是不同的,通常情況下,一個編譯器處理泛型有兩種方式:Code specializationCode sharing。C++ 和 C# 是使用 Code specialization的處理機制,而 Java 使用的是 Code sharing的機制。

Code sharing 方式為每個泛型類型創建唯一的字節碼表示,并且將泛型類型的實例都映射到這個唯一的字節碼表示上。將多種泛型類型實例映射到唯一的字節碼表示是通過類型擦除(type erasue)實現的。

也就是說,對于 Java 虛擬機來說,他根本不認識 Map<String,String> map 這樣的語法。需要在編譯階段通過類型擦除的方式進行解語法糖。

類型擦除的主要過程如下:

1.將所有的泛型參數用其最左邊界(最頂級的父類型)類型替換。

2.移除所有的類型參數。

以下代碼:

        Map<String,String> map=new HashMap<String,String>();map.put("name","tango");map.put("wechat","Tango");map.put("blog","https://www.baidu.com");

解語法糖之后會變成:

        Map map = new HashMap();map.put("name", "tango");map.put("wechat", "Tango");map.put("blog", "https://www.baidu.com");

以下代碼:

 public static <A extends Comparable<A>> A max(Collection<A> xs) {Iterator<A> xi = xs.iterator();A w = (Comparable)xi.next();while(xi.hasNext()) {A x = (Comparable)xi.next();if (w.compareTo(x) < 0) {w = x;}}return w;}

類型擦除之后會變成:

    public static Comparable max(Collection xs){Iterator xi = xs.iterator();Comparable w = (Comparable)xi.next();do{if(!xi.hasNext())break;Comparable x = (Comparable)xi.next();if(w.compareTo(x) < 0)w = x;} while(true);return w;}

虛擬機中沒有泛型,只有普通類和普通方法,所欲泛型類的類型參數在編譯時都會被擦除,泛型類并沒有自己獨有的 Class類對象。比如并不存在 List<String>.class 或是 List<Integer>.class ,而只有 List.class 。

糖塊三、自動裝箱與拆箱

自動裝箱就是 Java 自動將原始類型值轉換成對應的對象,比如將 int 的變量轉換成 Integer 的對象,這個過程叫做裝箱,反之將 Integer 對象轉換成 int 類型值,這個過程叫做拆箱。因為這里的裝箱和拆箱是自動進行的非人為轉換,所以就稱作為自動裝箱和拆箱。原始類型 byte、short、char、int、long、float、double 和 boolan 對應的封裝類為 Byte、Short、Character、Integer、Long、Float、Double、Boolean。

先來看個自動裝箱的代碼:

    public static void main(String[] args) {int i = 0;Integer n = i;}

反編譯后代碼如下:

    public static void main(String args[]){int i = 0;Integer n = Integer.valueOf(i);}

再來看個自動拆箱的代碼:

    public static void main(String[] args) {Integer n = 0;int i = n;}

反編譯后代碼如下:

    public static void main(String args[]){Integer n = Integer.valueOf(0);int i = n.intValue();}

從反編譯得到內容可以看出,在裝箱的時候自動調用的是 IntegervalueOf方法。而在拆箱的時候自動調用的是 IntegerintValue的方法。

所以,裝箱過程是通過調用包裝器的 valueOf 方法實現的,而拆箱過程是通過調用包裝器的 xxxValue 方法實現的。

糖塊四、枚舉

在 Java 中,枚舉是一種特殊的數據類型,用于表示有限的一組常量。枚舉常量是在枚舉類型中定義的,每個常量都是該類型的一個實例。Java 中的枚舉類型是一種安全而優雅的方式來表示有限的一組值。

要想看源碼,首先得有一個類吧,那么枚舉類型到底是什么類呢?是 enum 嗎?答案很明顯不是,enum就和 class一樣,只是一個關鍵字,他并不是一個類,那么枚舉是由什么類維護的呢?我們簡單的寫一個枚舉:

public enum t {SPRING,SUMMER;
}

然后我們使用反編譯,看看這段代碼到底是怎么實現的,反編譯后代碼如下:


public final class t extends Enum
{public static t[] values(){return (t[])$VALUES.clone();}public static t valueOf(String name){return (t)Enum.valueOf(com/chiyi/test/t, name);}private t(String s, int i){super(s, i);}public static final t SPRING;public static final t SUMMER;private static final t $VALUES[];static {SPRING = new t("SPRING", 0);SUMMER = new t("SUMMER", 1);$VALUES = (new t[] {SPRING, SUMMER});}
}

通過反編譯代碼我們可以看到,public final class t extends Enum,說明,該類是繼承了 Enum類的,同時 final關鍵字告訴我們,這個類也是不能被繼承的。當我們使用 enum 來定義一個枚舉類型的時候,編譯器會自動幫我們創建一個 final類型的類繼承 Enum類,所以枚舉類型不能被繼承。

糖塊五、條件編譯

一般情況下,程序中的每一行代碼都要參加編譯。但有時候出于對程序代碼優化的考慮,希望只對其中一部分內容進行編譯,此時就需要在程序中加上條件,讓編譯器只對滿足條件的代碼進行編譯,將不滿足條件的代碼舍棄,這就是條件編譯。

如在 C 或 CPP 中,可以通過預處理語句來實現條件編譯。其實在 Java 中也可實現條件編譯。我們先來看一段代碼:

    public static void main(String[] args) {final  boolean DEBUG=true;if (DEBUG){System.out.println("Hello,DEBUG!");}final boolean ONLINE=false;if (ONLINE){System.out.println("Hello,ONLINE!");}}

反編譯后代碼如下:

    public static void main(String args[]){boolean DEBUG = true;System.out.println("Hello,DEBUG!");boolean ONLINE = false;}

首先,我們發現,在反編譯后的代碼中沒有 System.out.println("Hello,ONLINE!");,這其實就是條件編譯。當 if (ONLINE)為 false 的時候。編譯器就沒有對其內的代碼進行編譯。

所以,Java 語法的條件編譯,是通過判斷條件為常量的 if 語句實現的。其原理也是 Java 語言的語法糖。根據 if 判斷條件的真假,編譯器直接把分支為 false 的代碼塊消除。通過該方式實現的條件編譯,必須在方法體內實現,而無法在整個 Java 類的結構或類的屬性上進行條件編譯,這與 C/C++ 的條件編譯相比,確實更有局限性。在 Java 語言設計之初并沒有引入條件編譯的功能。雖有局限,但是總比沒有更強、

糖塊六、斷言

在 Java 中, assert關鍵字是從 JAVA SE 1.4 引入的,為了避免和老版本的 Java 代碼中使用了 assert 關鍵字導致錯誤, Java 執行的時候默認是不啟動斷言檢查的(這個時候,所有的斷言語句都將忽略!),如果要開啟斷言檢查,則需要用開關 -enableassertions-ea來開啟。

看一段包含斷言的代碼:

    public static void main(String[] args) {int a = 1;int b = 1;assert a == b;System.out.println("公眾號:Tango");assert a != b : "Tango";System.out.println("百度:https://www.baidu.com");}

反編譯后代碼如下:

  public static void main(String args[]){int a = 1;int b = 1;if(!$assertionsDisabled && a != b)throw new AssertionError();System.out.println("\u516C\u4F17\u53F7\uFF1ATango");if(!$assertionsDisabled && a == b){throw new AssertionError("Tango");} else{System.out.println("\u767E\u5EA6\uFF1Ahttps://www.baidu.com");return;}}

很明顯,反編譯之后的代碼要比我們自己的代碼復雜得多。所以,使用了 assert 這個語法糖我們節省了很多代碼。其實斷言的底層實現就是 if 語句,如果斷言結果為 true,則什么都不做,程序繼續執行,如果斷言結果為 false,則程序拋出 AssertError 來打斷程序的執行。-enableassertions 會設置 $assertionsDisabled 字段的值。

糖塊七、數值字面量

在 java 7 中,數值字面量,不管是整數還是浮點數,都允許在數字之間插入任意多個下劃線。這些下劃線不會對字面量的數值產生影響,目的就是方便閱讀。

比如:

    public static void main(String[] args) {int i=10_000;System.out.println(i);}

反編譯后:

    public static void main(String args[]){int i = 10000;System.out.println(i);}

反編譯后就是把 _ 刪除了。也就是說 編譯器并不認識在數字字面量的 _,需要在編譯階段把他去掉。

糖塊八、for-each

增強 for 循環(for-each)相信大家都不陌生,日常開發經常會用到的,它會比 for 循環要少寫很多代碼,那么這個語法糖背后是如何實現的呢?

    public static void main(String[] args) {String [] strs={"南京","合肥","深圳","北京"};for (String s:strs){System.out.println(s);}List<String> strings= ImmutableList.of("南京","合肥","深圳","北京") ;for (String s:strings){System.out.println(s);}}

反編譯后代碼如下:

    public static void main(String args[]){String strs[] = {"\u5357\u4EAC", "\u5408\u80A5", "\u6DF1\u5733", "\u5317\u4EAC"};String args1[] = strs;int i = args1.length;for(int j = 0; j < i; j++){String s = args1[j];System.out.println(s);}List strings = ImmutableList.of("\u5357\u4EAC", "\u5408\u80A5", "\u6DF1\u5733", "\u5317\u4EAC");String s;for(Iterator iterator = strings.iterator(); iterator.hasNext(); System.out.println(s))s = (String)iterator.next();}

代碼很簡單,for-each 的實現原理其實就是使用了普通的 for 循環和迭代器。

糖塊九、try-with-resource

Java 里,對于文件操作 IO 流、數據庫連接等開銷非常昂貴的資源,用完之后必須及時 close 方法將其關閉,否則資源會一直處于打開狀態,可能會導致內存泄漏等問題。

關閉資源的常用方式就是在 finally 塊里是釋放,即調用 close方法。比如經常會寫這樣的代碼:

 public static void main(String[] args) {BufferedReader br = null;try {String line;br = new BufferedReader(new FileReader("D:\\youth\\java\\javacode\\base\\src\\main\\resources\\application.properties"));while ((line = br.readLine()) != null) {System.out.println(line);}} catch (IOException e) {} finally {try {if (br != null) {br.close();}} catch (IOException ex) {//handle exception}}}

在 Java 7 開始,jdk 提供了一種更好的方式關閉資源,使用 try-with-resources語句,改寫一下上面的代碼,效果如下:

    public static void main(String[] args) {try (  BufferedReader br =new BufferedReader(new FileReader("D:\\tango.xml"))){String line;while ((line = br.readLine()) != null) {System.out.println(line);}} catch (IOException e) {//handle exception}}

看,這簡直是一大福音啊,雖然我之前一般使用 IOUtils去關閉流,并不會使用在 finally中寫很多代碼的方式,但是這種新的語法糖看上去好像優雅很多呢。看下他的背后:

  public static void main(String args[]){BufferedReader br;Throwable throwable;br = new BufferedReader(new FileReader("D:\\tango.xml"));throwable = null;String line;try{while((line = br.readLine()) != null) System.out.println(line);}catch(Throwable throwable2){throwable = throwable2;throw throwable2;}if(br != null)if(throwable != null)try{br.close();}catch(Throwable throwable1){throwable.addSuppressed(throwable1);}elsebr.close();break MISSING_BLOCK_LABEL_113;Exception exception;exception;if(br != null)if(throwable != null)try{br.close();}catch(Throwable throwable3){throwable.addSuppressed(throwable3);}elsebr.close();throw exception;IOException ioexception;ioexception;}

其實背后的原理也很簡單,那些我們沒有做的關閉資源的操作,編譯器都幫我們做了。所以,再次印證了,語法糖的作用就是方便程序員的作用,但最終還是要轉成編譯器認識的語言。

可能遇到的坑

泛型

一、當泛型遇到重載

比如:

    public static void print(List<String> list){System.out.println("invoke print(List<String> list)");}public static void print(List<Integer> list){System.out.println("invoke print(List<String> list)");}

上面這段代碼,有兩個重載的函數,因為他們的參數類型不同,一個是 List<String>,另一個是 List<Integer>,但是,這段代碼是編譯通不過的。因為我們前面講過,參數 List 和 List 編譯之后都被擦除了,變成了一樣的原生類型 List,擦除動作導致這兩個方法的特征簽名變得一模一樣。

二、當泛型遇到 catch 泛型的類型參數不能用在 Java 異常處理的 catch 語句中。因為異常處理是由 JVM 在運行時刻來進行的。由于類型信息被擦除,JVM 是無法區分兩個異常類型 MyException<String>MyException<Integer>的。

三、當泛型內含靜態變量

    public static void main(String[] args) {GT<Integer> gti=new GT<Integer>();gti.var=1;GT<String> gts=new GT<String>();gts.var=2;System.out.println(gti.var);}static class GT<T>{public static int var=0;public void nothing(T x){}}

以上代碼輸出結果為:2!由于經過類型擦除,所有的泛型類實例都關聯到同一份字節碼上,泛型類的所有靜態變量是共享的。

自動裝箱與拆箱

對象相等比較

    public static void main(String[] args) {Integer a = 1000;Integer b = 1000;Integer c = 100;Integer d = 100;System.out.println("a == b is " + (a == b));System.out.println("c == d is " + (c == d));}

輸出結果:

a == b is false
c == d is true

在 Java 5 中,在 Integer 的操作上引入了一個新功能來節省內存和提高性能。整型對象通過使用相同的對象引用實現了緩存和重用。

適用于整數值區間 -128 至 +127。

只適用于自動裝箱。使用構造函數創建對象不適用。

總結

前面介紹了 9 種 Java 中常用的語法糖。所謂語法糖就是提供給開發人員便于開發的一種語法而已。但是這種語法只有開發人員認識。想要被執行,需要進行解糖,即轉成 JVM 認識的語法。當我們把語法糖解糖之后,你就會發現其實我們日常使用的這些方便的語法,其實都是一些其他更簡單的語法構成的。

有了這些語法糖,我們在日常開發的時候可以大大提升效率,但是同時也要避免過度使用。使用之前最好了解下原理,避免掉坑。

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

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

相關文章

Beats:安裝及配置 Metricbeat (一)- 8.x

在我之前的文章&#xff1a; Beats&#xff1a;Beats 入門教程 &#xff08;一&#xff09;Beats&#xff1a;Beats 入門教程 &#xff08;二&#xff09; 我詳細描述了如何在 Elastic Stack 7.x 安裝及配置 Beats。在那里的安裝&#xff0c;它通常不帶有安全及 Elasticsearc…

MapReduce介紹

目錄 ?一、什么是MapReduce 二、MapReduce 的設計思想 2.1 分而治之 2.2 構建抽象模型&#xff1a;Map和Reduce 2.3 隱藏系統層細節 三、MapReduce 的框架原理 3.1 MRv1工作原理 3.1.1 MRv1架構工作原理圖 3.1.1.1 流程說明 3.1.1.1.1 作業的提交 3.1.1.1.2 作業的初始化 3…

【AI大模型】訓練Al大模型 (上篇)

大模型超越AI 前言 潔潔的個人主頁 我就問你有沒有發揮&#xff01; 知行合一&#xff0c;志存高遠。 目前所指的大模型&#xff0c;是“大規模深度學習模型”的簡稱&#xff0c;指具有大量參數和復雜結構的機器學習模型&#xff0c;可以處理大規模的數據和復雜的問題&#x…

【Java】Queue中增加刪除方法的區別

offer&#xff0c;add 區別&#xff1a; 一些隊列有大小限制&#xff0c;因此如果想在一個滿的隊列中加入一個新項&#xff0c;多出的項就會被拒絕。 這時新的 offer 方法就可以起作用了。它不是對調用 add() 方法拋出一個 unchecked 異常&#xff0c;而只是得到由 offer() 返…

題目:售貨員的難題(狀壓dp)

售貨員的難題 題目描述輸入輸出格式輸入格式&#xff1a;輸出格式&#xff1a; 輸入輸出樣例輸入樣例#1&#xff1a;輸出樣例#1&#xff1a; 思路AC代碼&#xff1a; 題目描述 某鄉有n個村莊( 1 < n < 16 )&#xff0c;有一個售貨員&#xff0c;他要到各個村莊去售貨&am…

consul限制注冊的ip

假設當前服務器的ip是&#xff1a;192.168.56.130 1、允許 所有ip 注冊(驗證可行) consul agent -server -ui -bootstrap-expect1 -data-dir/usr/local/consul -nodedevmaster -advertise192.168.56.130 -bind0.0.0.0 -client0.0.0.0 2、只允許 當前ip 注冊 consul agent -…

Leetcode33 搜索旋轉排序數組

題解&#xff1a; /*** 旋轉排序數組可分為N1 N2兩個部分&#xff0c;如&#xff1a;[4,5,6,7,1,2,3]&#xff0c;N1為[4,5,6,7]&#xff0c;N2為[1,2,3]** 必然滿足以下兩個條件&#xff1a;* 1. N1和N2都是分別遞增的&#xff1b;* 2. N1中的所有元素大于N2中的所有元素;** …

【Python機器學習】實驗12 基于神經網絡的回歸-分類實驗

文章目錄 神經網絡的回歸例1 基于神經網絡的回歸(簡單例子)1.1 導入包1.2 構造數據集&#xff08;隨機構造的&#xff09;1.3 構造訓練集和測試集1.4 構建神經網絡模型1.5 采用訓練數據來訓練神經網絡模型 實驗1 基于神經網絡的分類(鳶尾花數據集)1.1 導入包1.2 構造數據集1.3 …

Selenium瀏覽器自動化測試框架簡單介紹

selenium簡介 介紹   Selenium [1] 是一個用于Web應用程序測試的工具。Selenium測試直接運行在瀏覽器中&#xff0c;就像真正的用戶在操作一樣。支持的瀏覽器包括IE&#xff08;7, 8, 9, 10, 11&#xff09;&#xff0c;Mozilla Firefox&#xff0c;Safari&#xff0c;Googl…

系統學習Linux-MongoDB

概述 mongodb是一個nosql數據庫&#xff0c;它有高性能、無模式、文檔型的特點。是nosql數據庫中功能最豐富&#xff0c;最像關系數據庫的。數據庫格式為BSON 相關概念實例&#xff1a;系統上運行的mongodb的進程&#xff0c;類似于mysql實例&#xff1b;庫&#xff1a;每個數…

用cpolar生成的公網地址,對位于本地的Cloudreve網盤進行訪問

文章目錄 1、前言2、本地網站搭建2.1 環境使用2.2 支持組件選擇2.3 網頁安裝2.4 測試和使用2.5 問題解決 3、本地網頁發布3.1 cpolar云端設置3.2 cpolar本地設置 4、公網訪問測試5、結語 1、前言 自云存儲概念興起已經有段時間了&#xff0c;各互聯網大廠也紛紛加入戰局&#…

MySQL 自增 ID 默認從 1 開始,如何設置自增 ID 從 0 開始

MySQL 是一種關系型數據庫&#xff0c;它是世界上最流行的關系型數據庫之一。在 MySQL 中&#xff0c;自增是一種非常有用的功能&#xff0c;它可以自動給主鍵賦值&#xff0c;并保證每個主鍵是唯一的。然而&#xff0c;許多人不知道的是&#xff0c;MySQL 默認情況下從 1 開始…

ArcGIS Pro如何制作不規則形狀圖例

在默認的情況下&#xff0c;ArcGIS Pro生成的圖例是標準的點、直線和矩形的&#xff0c;對于湖泊等要素而言&#xff0c;這樣的表示方式不夠直觀&#xff0c;我們可以將其優化一下&#xff0c;制作不規則的線和面來代替原有圖例&#xff0c;這里為大家介紹一下制作方法&#xf…

BERT數據處理,模型,預訓練

代碼來自李沐老師《動手學pytorch》 在數據處理時&#xff0c;首先執行以下代碼 def load_data_wiki(batch_size, max_len):"""加載WikiText-2數據集"""num_workers d2l.get_dataloader_workers()data_dir d2l.download_extract(wikitext-2, w…

django——配置 settings.py 及相關參數說明

3. 配置 settings.py 及相關參數說明 3.1 配置setting.py文件 設置setting.py文件 加入安裝的庫 apps.erp_test, rest_framework, django_filters, drf_spectacular,加入新增的APP users啟動項目 # 運行項目先執行數據庫相關操作&#xff0c;再啟動 django 項目 python manag…

【JavaSE】面向對象之繼承

繼承 繼承概念繼承的語法父類成員的訪問子類和父類沒有同名成員變量子類和父類有同名成員變量成員方法名字不同成員方法名字相同 super關鍵字子類構造方法super和this繼承方式 繼承概念 繼承(inheritance)機制&#xff1a;是面向對象程序設計使代碼可以復用的最重要的手段&…

docker 安裝nacos

1、下載nacos docker pull nacos/nacos-server2、啟動nacos docker run --restart always --env MODEstandalone --name nacos -d -p 8848:8848 -p 9848:9848 -p 9849:9849 nacos/nacos-server3、驗證nacos http://localhost:8848/nacos 默認用戶名和密碼&#xff1a;nacos

lvs集群與nat模式

一&#xff0c;什么是集群&#xff1a; 集群&#xff0c;群集&#xff0c;Cluster&#xff0c;由多臺主機構成&#xff0c;但是對外只表現為一個整體&#xff0c;只提供一個訪問入口&#xff08;域名與ip地址&#xff09;&#xff0c;相當于一臺大型計算機。 二&#xff0c;集…

Java書簽 #使用MyBatis接入多數據源

楔子&#xff1a;當然&#xff0c;世上有很多優秀的女性&#xff0c;我也會被她們吸引。這對男人來說是理所當然的。但目光被吸引和內心被吸引是截然不同的。- 東野圭吾《黎明之街》 今日書簽 在一些應用場景中&#xff0c;可能需要連接多個不同的數據庫&#xff0c;例如連接不…

Centos 防火墻命令

查看防火墻狀態 systemctl status firewalld.service 或者 firewall-cmd --state 開啟防火墻 單次開啟防火墻 systemctl start firewalld.service 開機自啟動防火墻 systemctl enable firewalld.service 重啟防火墻 systemctl restart firewalld.service 防火墻設置開…