推陳換新系列————java8新特性(編程語言的文藝復興)

文章目錄

  • 前言
  • 一、新特性秘籍
  • 二、Lambda表達式
    • 2.1 語法
    • 2.2 函數式接口
    • 2.3 內置函數式接口
    • 2.4 方法引用和構造器引用
  • 三、Stream API
    • 3.1 基本概念
    • 3.2 實戰
    • 3.3 優勢
  • 四、新的日期時間API
    • 4.1 核心概念與設計原則
    • 4.2 核心類詳解
      • 4.2.1 LocalDate(本地日期)
      • 4.2.2 LocalTime(本地時間)
      • 4.2.3 LocalDateTime(本地日期時間)
      • 4.2.4 ZonedDateTime(帶時區的日期時間)
      • 4.2.5 Instant(瞬時點)
    • 4.3 時間間隔與周期
      • 4.3.1 Duration(持續時間)
      • 4.3.2 Period(日期間隔)
    • 4.4 時間調整器(TemporalAdjuster)
    • 4.5 總結
  • 五、optional類
    • 5.1 概念
    • 5.2 創建實例
    • 5.3 常用的方法
    • 5.4 實戰
    • 5.5 最佳實踐
  • 六、接口中默認方法和靜態方法
  • 獻給讀者


在這里插入圖片描述
在這里插入圖片描述


前言

想象一下,Java世界迎來了一場盛大的革命——Java 8隆重登場。這次更新不僅僅是技術上的進步,更是一場編程思維的轉變,讓開發者們仿佛從黑白電視時代一步跨入了4K超高清智能電視的新紀元。

首先,不得不提的是Lambda表達式,這是Java 8送給程序員的一份大禮。以往編寫代碼時,我們總是被繁瑣的匿名內部類所困擾,而Lambda表達式的出現就像是給這段枯燥的旅程中注入了一股清泉。它讓你能夠以一種更加簡潔、直觀的方式操作數據和定義行為,就像在畫布上用寥寥幾筆勾勒出一幅生動的畫卷。函數式接口則像是為這場表演搭建了一個舞臺,讓Lambda表達式可以在這個舞臺上自由舞蹈。

接著是Stream API,它為處理集合提供了一種全新的方式。如果你曾經為了遍歷一個列表并從中篩選出符合條件的元素而絞盡腦汁,那么現在只需要幾行優雅的代碼就能搞定這一切。Stream API就像是一個魔法棒,輕輕一點就能將你的數據轉換成你想要的樣子,無論是過濾、排序還是聚合,一切都變得輕而易舉。

再來看看新的日期和時間API(java.time包),這簡直是對舊版日期處理機制的一次徹底顛覆。曾經那些關于日期計算的噩夢,在這里都能找到簡單而有效的解決方案。這個新API提供了強大的功能來處理瞬時點、時間段以及不同地區的日期和時間,使得即使是處理復雜的國際化應用也能游刃有余。

還有那令人興奮的Optional類,它就像是一個貼心的小助手,幫助我們避免了空指針異常這個長久以來的敵人。通過使用Optional,我們可以明確地表示某個值可能存在也可能不存在的情況,從而寫出更加健壯且易于理解的代碼。

最后,不要忘了Java 8對注解的支持也得到了加強。重復注解和類型注解的引入,讓我們的代碼不僅能夠傳達更多的信息,同時也變得更加靈活。這就像是給你的工具箱里添加了幾把多功能的瑞士軍刀,無論遇到什么樣的挑戰,都能夠從容應對。
在這里插入圖片描述

一、新特性秘籍

Java 8的新特性,猶如一場編程語言的文藝復興,開啟了代碼優雅與效率并存的新篇章。

  • Lambda表達式,是將行為抽象為藝術的畫筆,用簡潔的線條勾勒出邏輯的本質。
  • Stream API,則是數據流動的詩意,讓集合操作如溪流般自然流暢,匯聚、過濾、映射一氣呵成。
  • 新的日期時間API,如同精準的鐘表匠,撥開了舊版日期處理的迷霧,賦予時間運算以秩序與美感。
  • Optional類,宛如一位守護者,用溫柔的方式提醒我們關注可能的空值陷阱,讓代碼多了一份從容與穩健。
  • 接口中的默認方法與靜態方法,仿佛給傳統接口注入了靈魂,使其既能傳承經典,又能靈活擴展。
  • 方法引用,則是對已有實現的致敬,通過簡短的符號喚醒隱藏在代碼深處的力量。

💡貼士:這一切,正如遞歸是探索自我重復的奇妙之旅,Java 8的新特性,則是引領開發者邁向簡潔、優雅與高效的全新境界。

二、Lambda表達式

Lambda表達式是Java 8引入的一個重要特性,它為Java語言帶來了函數式編程的能力。Lambda表達式允許你將行為作為參數傳遞給方法或存儲為變量,簡化了代碼結構,使得編寫更加簡潔、清晰的代碼成為可能。Lambda表達式是一個匿名函數,使用lambda表達式使代碼更加簡潔緊湊。

2.1 語法

  • 基本語法格式如下:
(parameters) -> expression
  • 或者對于需要多行語句的情況:
(parameters) -> { statements; }

這里,parameters是參數列表,->符號用來分隔參數列表和Lambda體,expressionstatements構成了Lambda體,即你要執行的操作。

假設我們有一個簡單的例子,使用傳統方式定義一個線程:

new Thread(new Runnable() {@Overridepublic void run() {System.out.println("Running in a thread");}
}).start();

使用Lambda表達式可以簡化為:

new Thread(() -> System.out.println("Running in a thread")).start();

可以看到,使用Lambda表達式不僅減少了冗余代碼,而且使代碼意圖更加明確。

2.2 函數式接口

Lambda表達式只能用于上下文為目標類型是“函數式接口”的地方。函數式接口是指僅包含一個抽象方法的接口(雖然可以有多個默認方法和靜態方法)。為了方便識別,Java 8提供了@FunctionalInterface注解來標注這樣的接口,但即使不加此注解,只要接口滿足條件,就可以與Lambda表達式一起使用。
例如,Runnable接口就是一個函數式接口,因為它只定義了一個run()方法。

2.3 內置函數式接口

查看詳細的內置函數👉👉👉 點我
查看詳細的內置函數👉👉👉 點我
查看詳細的內置函數👉👉👉 點我

Java 8在java.util.function包中提供了一系列通用的函數式接口,包括但不限于:

  • Predicate:接受一個參數,返回一個布爾值。
  • Function<T, R>:接受一個參數,返回一個結果。
  • Consumer:接受一個參數,沒有返回值。
  • Supplier:不接受任何參數,返回一個結果。
  • BinaryOperator:接受兩個同類型的參數,返回相同類型的結果。

💡貼士:這些內置接口極大地提高了Lambda表達式的靈活性和適用性。

2.4 方法引用和構造器引用

Lambda表達式還支持方法引用和構造器引用,進一步增強了其表現力。方法引用通過::操作符實現,可以直接引用已有方法或構造器。例如,String類的compareTo方法可以通過方法引用來使用:

Arrays.sort(strArray, String::compareTo);

這表示使用String類的compareTo方法對strArray數組進行排序。

三、Stream API

Java 8引入的Stream API(流)為處理集合提供了強大的功能,使得對數據的操作更加簡潔和高效。Stream是一個從支持數據處理操作的源生成的元素序列,這些操作包括過濾、排序、映射等。Stream API的設計靈感來源于函數式編程語言中的概念,它允許開發者以聲明式的方式定義數據處理管道。

查看詳細的Stream API👉👉👉 點我
查看詳細的Stream API👉👉👉 點我
查看詳細的Stream API👉👉👉 點我

3.1 基本概念

  • 流(Stream):是從支持數據處理操作的源生成的元素序列。流本身并不存儲數據,而是通過一系列中間操作來描述計算過程,最終由終端操作觸發計算并產生結果。
  • 源(Source):提供流的數據來源,如集合、數組或I/O資源。
  • 中間操作(Intermediate Operations):返回一個新的流,允許進行鏈式調用。常見的有filter, map, sorted等。
  • 終端操作(Terminal Operation):觸發流的執行,并產生一個結果或副作用。常見的有forEach, collect, reduce等。

3.2 實戰

  1. 創建流
    可以從集合、數組等創建流:
List<String> list = Arrays.asList("apple", "banana", "orange");
Stream<String> stream = list.stream();
  1. 中間操作
  • 過濾(Filter): 根據給定的條件篩選元素。
stream.filter(s -> s.startsWith("a"));
  • 映射(Map): 將元素轉換為其他形式或提取信息。
stream.map(String::toUpperCase);
  • 排序(Sorted): 對流中的元素進行排序。
stream.sorted();
  1. 終端操作
  • 遍歷(ForEach): 對每個元素執行某個動作。、
stream.forEach(System.out::println);
  • 收集(Collect): 將流中的元素收集成集合或其他形式。
List<String> resultList = stream.collect(Collectors.toList());
  • 歸約(Reduce): 將流中的元素組合成一個單一的結果。
Optional<String> result = stream.reduce((s1, s2) -> s1 + "," + s2);
  1. 并行流
    Stream API還支持并行流,可以輕松實現并行處理:
List<String> list = Arrays.asList("apple", "banana", "orange");
list.parallelStream().forEach(System.out::println);

💡貼士:使用并行流時需要注意線程安全問題,特別是在修改共享狀態的情況下。

3.3 優勢

  • 惰性求值:中間操作不會立即執行,只有當遇到終端操作時才會真正開始處理。
  • 內部迭代:與傳統的外部迭代相比,Stream采用內部迭代,使得代碼更加簡潔。
  • 易于并行:通過簡單的API即可實現并行處理,提高程序性能。

💡貼士:StreamAPI極大地簡化了對集合數據的操作,讓編寫清晰、高效的代碼變得更加容易。無論是進行復雜的數據分析還是簡單的查詢操作,StreamAPI都能提供靈活且強大的支持。

四、新的日期時間API

Java 8引入了全新的日期和時間API(java.time包及其子包),以解決舊版日期時間API(如java.util.Date和java.util.Calendar)存在的問題,例如非線程安全、設計不佳和時區處理困難。新的API不僅線程安全,還提供了更直觀、更強大的功能,滿足了現代應用對日期和時間處理的需求。

4.1 核心概念與設計原則

  • 不可變性
    所有日期和時間類都是不可變的(Immutable),一旦創建就無法修改。這使得它們天然適合多線程環境。

  • 清晰的職責劃分
    LocalDate:僅表示日期(年月日),無時區信息。
    LocalTime:僅表示時間(小時分鐘秒),無時區信息。
    LocalDateTime:結合日期和時間,無時區信息。
    ZonedDateTime:包含日期、時間和時區信息。
    Instant:表示時間線上的一個瞬時點(UTC時間戳)。

  • ISO標準
    遵循ISO 8601國際標準,日期格式為yyyy-MM-dd,時間格式為HH:mm:ss。

4.2 核心類詳解

4.2.1 LocalDate(本地日期)

用于表示不帶時區的日期,例如2025-03-26。

  • 常用方法:
    • LocalDate.now():獲取當前日期。
    • LocalDate.of(year, month, day):創建指定日期。
    • plusDays(long daysToAdd):增加天數。
    • minusDays(long daysToSubtract):減少天數。
    • isBefore(LocalDate other):判斷是否在某個日期之前。
    • isAfter(LocalDate other):判斷是否在某個日期之后。
LocalDate today = LocalDate.now();
System.out.println("今天是:" + today);LocalDate birthday = LocalDate.of(1998, 1, 6);
System.out.println("生日是:" + birthday);LocalDate tomorrow = today.plusDays(1);
System.out.println("明天是:" + tomorrow);

4.2.2 LocalTime(本地時間)

用于表示不帶時區的時間,例如21:41:30。

  • 常用方法:
    • LocalTime.now():獲取當前時間。
    • LocalTime.of(hour, minute, second):創建指定時間。
    • plusHours(long hoursToAdd):增加小時數。
    • minusMinutes(long minutesToSubtract):減少分鐘數。
    • isBefore(LocalTime other):判斷是否在某個時間之前。
LocalTime nowTime = LocalTime.now();
System.out.println("當前時間是:" + nowTime);LocalTime specificTime = LocalTime.of(14, 30, 45);
System.out.println("指定時間是:" + specificTime);LocalTime laterTime = nowTime.plusHours(2);
System.out.println("兩小時后的時間是:" + laterTime);

4.2.3 LocalDateTime(本地日期時間)

用于表示不帶時區的日期和時間,例如2025-03-26T21:41:30。

  • 常用方法:
    • LocalDateTime.now():獲取當前日期時間。
    • LocalDateTime.of(year, month, day, hour, minute, second):創建指定日期時間。
    • plusDays(long daysToAdd):增加天數。
    • minusHours(long hoursToSubtract):減少小時數。
LocalDateTime currentDateTime = LocalDateTime.now();
System.out.println("當前日期時間是:" + currentDateTime);LocalDateTime specificDateTime = LocalDateTime.of(2025, 3, 26, 21, 41, 30);
System.out.println("指定日期時間是:" + specificDateTime);LocalDateTime nextWeek = currentDateTime.plusDays(7);
System.out.println("一周后的日期時間是:" + nextWeek);

4.2.4 ZonedDateTime(帶時區的日期時間)

用于表示帶時區的日期和時間,例如2025-03-26T21:41:30+08:00[Asia/Shanghai]。

  • 常用方法:
    • ZonedDateTime.now(ZoneId zone):獲取指定時區的當前日期時間。
    • withZoneSameInstant(ZoneId zone):轉換到另一個時區的相同時刻。
ZonedDateTime nowInShanghai = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
System.out.println("上海當前日期時間是:" + nowInShanghai);ZonedDateTime nowInNewYork = nowInShanghai.withZoneSameInstant(ZoneId.of("America/New_York"));
System.out.println("紐約當前日期時間是:" + nowInNewYork);

4.2.5 Instant(瞬時點)

用于表示時間線上的一個瞬時點(UTC時間戳),通常用于記錄事件發生的時間或進行時間計算。

  • 常用方法:
    • Instant.now():獲取當前瞬時點。
    • Duration.between(Instant start, Instant end):計算兩個瞬時點之間的時間差。
Instant now = Instant.now();
System.out.println("當前瞬時點是:" + now);Instant oneHourLater = now.plus(Duration.ofHours(1));
System.out.println("一小時后的瞬時點是:" + oneHourLater);Duration duration = Duration.between(now, oneHourLater);
System.out.println("時間差是:" + duration.toMillis() + " 毫秒");

4.3 時間間隔與周期

4.3.1 Duration(持續時間)

用于表示兩個瞬時點之間的時間間隔,適用于秒和納秒級別的時間計算。

Duration duration = Duration.ofHours(2);
System.out.println("持續時間為:" + duration.toMinutes() + " 分鐘");

4.3.2 Period(日期間隔)

用于表示兩個日期之間的間隔,適用于年、月、日級別的時間計算。

LocalDate startDate = LocalDate.of(2024, 1, 1);
LocalDate endDate = LocalDate.of(2025, 3, 26);Period period = Period.between(startDate, endDate);
System.out.println("間隔為:" + period.getYears() + " 年 " + period.getMonths() + " 月 " + period.getDays() + " 天");

4.4 時間調整器(TemporalAdjuster)

用于執行復雜的日期調整操作,例如“本月的第一個周一”或“下個月的最后一天”。

LocalDate today = LocalDate.now();
LocalDate firstMondayOfMonth = today.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
System.out.println("本月的第一個周一是:" + firstMondayOfMonth);

4.5 總結

Java 8的新日期時間API解決了舊版API的諸多問題,提供了更加現代化、易用的功能。無論是簡單的日期操作還是復雜的時區處理,它都能輕松勝任。以下是使用新API的一些最佳實踐:

  • 盡量避免直接操作原始類型(如int),而使用LocalDate、LocalTime等專用類。
  • 在需要精確時間計算時,優先使用Duration和Period。
  • 使用ZonedDateTime和ZoneId處理跨時區的應用場景。

通過這些改進,Java 8讓日期和時間的處理變得更加優雅和高效!

五、optional類

Optional是Java 8引入的一個容器類,旨在優雅地處理可能為null的值,避免潛在的NullPointerException。它鼓勵開發者顯式處理可能缺失的值,而不是依賴于null檢查,從而編寫出更清晰、更健壯的代碼。

5.1 概念

核心概念

  1. 存在性:Optional對象可以包含一個非空值(通過isPresent()方法判斷)或為空(即不包含任何值)。
  2. 不可變性:一旦創建了Optional實例,就不能更改其內部的值。
  3. 避免強制解包:與原始類型的包裝類型不同,Optional設計來避免直接調用.get()獲取值前沒有進行null檢查的情況。

5.2 創建實例

有幾種方式可以創建Optional實例:

  1. Optional.of(value):當確定value不是null時使用。如果傳入null,會拋出NullPointerException。
  2. Optional.ofNullable(value):允許傳入null值。如果傳入的是null,則返回一個空的Optional實例。
  3. Optional.empty():創建一個空的Optional實例。

5.3 常用的方法

  • isPresent():如果Optional包含值,則返回true。
  • ifPresent(Consumer<? super T> consumer):如果有值,則對其執行提供的Consumer操作,否則不執行任何操作。這通常用于對存在的值執行某些操作而不需要顯式的null檢查。
  • get():如果Optional包含值,則返回該值;如果沒有值,則拋出NoSuchElementException。建議在調用此方法之前先檢查是否有值存在。
  • orElse(T other):如果存在值則返回該值,否則返回指定的默認值。
  • orElseGet(Supplier<? extends T> supplier):功能類似于orElse,但它接受一個提供者函數,只有在需要時才計算默認值。
  • orElseThrow(Supplier<? extends X> exceptionSupplier):如果存在值,則返回該值;否則拋出由提供的異常供應商生成的異常。

5.4 實戰

使用of和get

Optional<String> optionalValue = Optional.of("Hello, World!");
System.out.println(optionalValue.get()); // 輸出: Hello, World!

使用ofNullable處理可能為null的情況

Optional<String> optionalNull = Optional.ofNullable(null);
System.out.println(optionalNull.isPresent()); // 輸出: false

使用ifPresent執行操作

optionalValue.ifPresent(value -> System.out.println("Value is present: " + value));
// 如果optionalValue有值,則輸出: Value is present: Hello, World!

提供默認值

String defaultValue = optionalNull.orElse("Default Value");
System.out.println(defaultValue); // 輸出: Default Value

5.5 最佳實踐

  • 避免過度使用Optional作為方法參數或字段類型,它更適合用于返回類型以表示可能存在也可能不存在的返回值。
  • 不要將Optional用于集合或數組類型的封裝,因為這些類型本身已經提供了表達“無元素”的機制(如空集合或空數組)。
  • 在適當的情況下,優先考慮使用ifPresent、orElse等方法,而不是直接調用get(),這樣可以減少運行時錯誤的風險。

💡貼士: 通過合理使用Optional,可以使代碼更加清晰地表達意圖,并有效減少因未處理null值而導致的錯誤。

六、接口中默認方法和靜態方法

Java 8引入了對接口的重要增強,允許在接口中定義默認方法(default methods)和靜態方法(static methods)。這些特性為接口添加了新的維度,使得它們不僅僅是抽象規范的集合,還可以包含具體的實現邏輯。這不僅簡化了API的設計和演化,還為現有接口提供了向后兼容的方式進行擴展。

默認方法
默認方法允許你在接口中提供一個具體的方法實現。這意味著即使實現類沒有提供該方法的具體實現,也可以使用接口中提供的默認實現。這對于庫的設計者來說特別有用,因為他們可以在不破壞現有實現類的情況下向接口添加新功能。

定義默認方法
默認方法通過使用default關鍵字來定義:

public interface MyInterface {// 抽象方法void abstractMethod();// 默認方法default void defaultMethod() {System.out.println("This is a default method.");}
}

使用默認方法
當一個類實現了包含默認方法的接口時,它可以:

  • 直接使用接口中的默認方法。
  • 覆蓋默認方法以提供自己的實現。
    例如:
public class MyClass implements MyInterface {@Overridepublic void abstractMethod() {System.out.println("MyClass's implementation of abstractMethod");}// 可選:覆蓋默認方法@Overridepublic void defaultMethod() {System.out.println("MyClass's implementation of defaultMethod");}
}

靜態方法
靜態方法是另一個Java 8為接口新增的功能。它們類似于普通類中的靜態方法,可以通過接口名直接調用。靜態方法主要用于提供與接口相關的工具函數或輔助函數。

定義靜態方法
靜態方法通過使用static關鍵字來定義:

public interface MyInterface {static void staticMethod() {System.out.println("This is a static method.");}
}

使用靜態方法

MyInterface.staticMethod(); // 輸出: This is a static method.

解決沖突
當一個類實現多個接口,而這些接口包含了相同簽名的默認方法時,會發生方法沖突。解決這種沖突有幾種方式:

  • 類優先:如果實現類提供了該方法的具體實現,則使用類中的實現。
  • 明確指定:如果需要使用某個特定接口的默認實現,可以通過InterfaceName.super.methodName()的方式來調用。
    例如:
public interface InterfaceA {default void myMethod() {System.out.println("InterfaceA's default method");}
}public interface InterfaceB {default void myMethod() {System.out.println("InterfaceB's default method");}
}public class MyClass implements InterfaceA, InterfaceB {@Overridepublic void myMethod() {InterfaceA.super.myMethod(); // 調用InterfaceA的默認方法}
}

💡貼士:Java 8通過引入默認方法和靜態方法極大地增強了接口的功能性,使接口能夠更好地適應現代編程的需求。這些改進有助于減少樣板代碼,同時保持向后兼容性。


獻給讀者


💯 計算機技術的世界浩瀚無垠,充滿了無限的可能性和挑戰,它不僅是代碼與算法的交織,更是夢想與現實的橋梁。無論前方的道路多么崎嶇不平,希望你始終能保持那份初心,專注于技術的探索與創新,用每一次的努力和進步書寫屬于自己的輝煌篇章。

🏰在這個快速發展的數字時代,愿我們都能成為推動科技前行的中堅力量,不忘為何出發,牢記心中那份對技術執著追求的熱情。繼續前行吧,未來屬于那些為之努力奮斗的人們。


親,碼字不易,動動小手,歡迎 點贊 ? 收藏,如 🈶 問題請留言(評論),博主看見后一定及時給您答復,💌💌💌


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

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

相關文章

樹莓派5從零開發至脫機腳本運行教程——1.系統部署篇

樹莓派5應用實例——工創視覺 前言 哈嘍&#xff0c;各位小伙伴&#xff0c;大家好。最近接觸了樹莓派&#xff0c;然后簡單的應用了一下&#xff0c;學習程度并不是很深&#xff0c;不過足夠剛入手樹莓派5的小伙伴們了解了解。后面的幾篇更新的文章都是關于開發樹莓派5的內容…

GPT Researcher 的win docker安裝攻略

github網址是&#xff1a;https://github.com/assafelovic/gpt-researcher 因為docker安裝方法不夠清晰&#xff0c;因此寫一個使用方法 以下是針對 Windows 系統 使用 Docker 運行 AI-Researcher 項目的 詳細分步指南&#xff1a; 步驟 1&#xff1a;安裝 Docker 下載 Docke…

【后端】【Django DRF】從零實現RBAC 權限管理系統

Django DRF 實現 RBAC 權限管理系統 在 Web 應用中&#xff0c;權限管理 是一個核心功能&#xff0c;尤其是在多用戶系統中&#xff0c;需要精細化控制不同用戶的訪問權限。本文介紹如何使用 Django DRF 設計并實現 RBAC&#xff08;基于角色的訪問控制&#xff09;系統&…

C#基礎學習(五)函數中的ref和out

1. 引言&#xff1a;為什么需要ref和out&#xff1f; ?問題背景&#xff1a;函數參數默認按值傳遞&#xff0c;值類型在函數內修改不影響外部變量&#xff1b;引用類型重新賦值時外部對象不變。?核心作用&#xff1a;允許函數內部修改外部變量的值&#xff0c;實現“雙向傳參…

八綱辨證總則

一、八綱辨證的核心定義 八綱即陰、陽、表、里、寒、熱、虛、實&#xff0c;是中醫分析疾病共性的綱領性辨證方法。 作用&#xff1a;通過八類證候歸納疾病本質&#xff0c;為所有辨證方法&#xff08;如臟腑辨證、六經辨證&#xff09;的基礎。 二、八綱分類與對應關系 1. 總…

【linux重設gitee賬號密碼 克隆私有倉庫報錯】

出現問題時 Cloning into xxx... remote: [session-1f4b16a4] Unauthorized fatal: Authentication failed for https://gitee.com/xxx/xxx.git/解決方案 先打開~/.git-credentials vim ~/.git-credentials或者創建一個 torch ~/.git-credentials 添加授權信息 username/pa…

綠聯NAS安裝內網穿透實現無公網IP也能用手機平板遠程訪問經驗分享

文章目錄 前言1. 開啟ssh服務2. ssh連接3. 安裝cpolar內網穿透4. 配置綠聯NAS公網地址 前言 大家好&#xff0c;今天給大家帶來一個超級炫酷的技能——如何在綠聯NAS上快速安裝cpolar內網穿透工具。想象一下&#xff0c;即使沒有公網IP&#xff0c;你也能隨時隨地遠程訪問自己…

CSS 美化頁面(一)

一、CSS概念 CSS&#xff08;Cascading Style Sheets&#xff0c;層疊樣式表&#xff09;是一種用于描述 HTML 或 XML&#xff08;如 SVG、XHTML&#xff09;文檔 樣式 的樣式表語言。它控制網頁的 外觀和布局&#xff0c;包括字體、顏色、間距、背景、動畫等視覺效果。 二、CS…

空轉 | GetAssayData doesn‘t work for multiple layers in v5 assay.

問題分析 當我分析多個樣本的時候&#xff0c;而我的seurat又是v5時&#xff0c;通常就會出現這樣的報錯。 錯誤的原因有兩個&#xff1a; 一個是參數名有slot變成layer 一個是GetAssayData 不是自動合并多個layers&#xff0c;而是選擇保留。 那么如果我們想合并多個樣本&…

UE4學習筆記 FPS游戲制作17 讓機器人持槍 銷毀機器人時也銷毀機器人的槍 讓機器人射擊

添加武器插槽 打開機器人的Idle動畫&#xff0c;方便查看武器位置 在動畫面板里打開骨骼樹&#xff0c;找到右手的武器節點&#xff0c;右鍵添加一個插槽&#xff0c;重命名為RightWeapon&#xff0c;右鍵插槽&#xff0c;添加一個預覽資產&#xff0c;選擇Rifle&#xff0c;根…

【JavaScript】七、函數

文章目錄 1、函數的聲明與調用2、形參默認值3、函數的返回值4、變量的作用域5、變量的訪問原則6、匿名函數6.1 函數表達式6.2 立即執行函數 7、練習8、邏輯中斷9、轉為布爾型 1、函數的聲明與調用 function 函數名(形參列表) {函數體 }eg&#xff1a; // 聲明 function sayHi…

硬件基礎--05_電壓

電壓(電勢差) 有了電壓&#xff0c;電子才能持續且定向移動起來&#xff0c;所有電壓是形成電流的必要條件。 電壓越大&#xff0c;能“定向移動”起來的電子就越多&#xff0c;電流就會越大。 有電壓的同時&#xff0c;形成閉合回路才會有電流&#xff0c;不是有電壓就有電流…

ES數據過多,索引拆分

公司企微聊天數據存儲在 ES 中&#xff0c;雖然按照企業分儲在不同的ES 索引中&#xff0c;但某些常用的企微主體使用量還是很大。4年中一個索引存儲數據已經達到46多億條數據&#xff0c;占用存儲3.1tb, ES 配置 由于多一個副本&#xff0c;存儲得翻倍&#xff0c;成本考慮…

存儲服務器是指什么

今天小編主要來為大家介紹存儲服務器主要是指什么&#xff0c;存儲服務器與傳統的物理服務器和云服務器是不同的&#xff0c;其是為了特定的目標所設計的&#xff0c;在硬件配置方式上也有著一定的區別&#xff0c;存儲空間會根據需求的不同而改變。 存儲服務器中一般會配備大容…

golang不使用鎖的情況下,對slice執行并發寫操作,是否會有并發問題呢?

背景 并發問題最簡單的解決方案加個鎖,但是,加鎖就會有資源爭用,提高并發能力其中的一個優化方向就是減少鎖的使用。 我在之前的這篇文章《開啟多個協程,并行對struct中的每個元素操作,是否會引起并發問題?》中討論過多協程場景下struct的并發問題。 Go語言中的slice在…

Java知識整理round1

一、常見集合篇 1. 為什么數組索引從0開始呢&#xff1f;假如從1開始不行咩 數組&#xff08;Array&#xff09;&#xff1a;一種用連續的內存空間存儲相同數據類型數據的線性數據結構 &#xff08;1&#xff09;在根據數組索引獲取元素的時候&#xff0c;會用索引和尋址公式…

【C++指針】搭建起程序與內存深度交互的橋梁(下)

&#x1f525;&#x1f525; 個人主頁 點擊&#x1f525;&#x1f525; 每文一詩 &#x1f4aa;&#x1f3fc; 往者不可諫&#xff0c;來者猶可追——《論語微子篇》 譯文&#xff1a;過去的事情已經無法挽回&#xff0c;未來的歲月還可以迎頭趕上。 目錄 C內存模型 new與…

JavaScript創建對象的多種方式

在JavaScript中&#xff0c;創建對象有多種方式&#xff0c;每種方式都有其優缺點。本文將介紹四種常見的對象創建模式&#xff1a;工廠模式、構造函數模式、原型模式和組合模式&#xff0c;并分析它們的特點以及如何優化。 1. 工廠模式 工廠模式是一種簡單的對象創建方式&am…

muduo庫的思路梳理

前言 對于muduo庫源碼的剖析我發現還是有些混亂的&#xff0c;所以這里再次梳理一下muduo網絡庫爭取可以簡單明了 首先對于muduo庫來說&#xff0c;不能想的得太過于復雜&#xff0c;它無非就是一個線程池加上epoll組成的網絡庫 這里我們從用的角度出發理解muoduo網絡庫 #inc…

Keil5 安裝全攻略

Keil5 安裝全攻略 Keil5 是一款廣泛用于嵌入式開發的 IDE&#xff0c;支持多種微控制器架構&#xff08;如 ARM、C51&#xff09;。本文將詳細介紹 Keil5 的安裝步驟、常見問題及解決方法&#xff0c;幫助您快速上手。 1. 安裝前的準備工作 (1) 系統要求 操作系統&#xff1…