主頁 > 後端開發 > 你還在 if...else?代碼這樣寫才好看!

你還在 if...else?代碼這樣寫才好看!

2020-11-25 18:10:06 後端開發

前言

if...else 是所有高級編程語言都有的必備功能,但現實中的代碼往往存在著過多的 if...else,雖然 if...else 是必須的,但濫用 if...else 會對代碼的可讀性、可維護性造成很大傷害,進而危害到整個軟體系統,現在軟體開發領域出現了很多新技術、新概念,但 if...else 這種基本的程式形式并沒有發生太大變化,使用好 if...else 不僅對于現在,而且對于將來,都是十分有意義的,今天我們就來看看如何“干掉”代碼中的 if...else,還代碼以清爽,

問題一:if…else 過多

問題表現

if...else 過多的代碼可以抽象為下面這段代碼,其中只列出5個邏輯分支,但實際作業中,能見到一個方法包含10個、20個甚至更多的邏輯分支的情況,另外,if...else 過多通常會伴隨著另兩個問題:邏輯運算式復雜和 if...else 嵌套過深,對于后兩個問題,本文將在下面兩節介紹,本節先來討論 if...else 過多的情況,

if (condition1) {

} else if (condition2) {

} else if (condition3) {

} else if (condition4) {

} else {

}

通常,if...else 過多的方法,通常可讀性和可擴展性都不好,從軟體設計角度講,代碼中存在過多的 if...else 往往意味著這段代碼違反了違反單一職責原則和開閉原則,因為在實際的專案中,需求往往是不斷變化的,新需求也層出不窮,所以,軟體系統的擴展性是非常重要的,而解決 if...else 過多問題的最大意義,往往就在于提高代碼的可擴展性,

如何解決

接下來我們來看如何解決 if...else 過多的問題,下面我列出了一些解決方法,

    1. 表驅動
    1. 職責鏈模式
    1. 注解驅動
    1. 事件驅動
    1. 有限狀態機
    1. Optional
    1. Assert
    1. 多型

方法一:表驅動

介紹

對于邏輯表達模式固定的 if...else 代碼,可以通過某種映射關系,將邏輯運算式用表格的方式表示;再使用表格查找的方式,找到某個輸入所對應的處理函式,使用這個處理函式進行運算,

適用場景

邏輯表達模式固定的 if...else

實作與示例

if (param.equals(value1)) {
    doAction1(someParams);
} else if (param.equals(value2)) {
    doAction2(someParams);
} else if (param.equals(value3)) {
    doAction3(someParams);
}
// ...

可重構為

Map<?, Function<?> action> actionMappings = new HashMap<>(); // 這里泛型 ? 是為方便演示,實際可替換為你需要的型別

// When init
actionMappings.put(value1, (someParams) -> { doAction1(someParams)});
actionMappings.put(value2, (someParams) -> { doAction2(someParams)});
actionMappings.put(value3, (someParams) -> { doAction3(someParams)});

// 省略 null 判斷
actionMappings.get(param).apply(someParams);

上面的示例使用了 Java 8 的 Lambda 和 Functional Interface,這里不做講解,

表的映射關系,可以采用集中的方式,也可以采用分散的方式,即每個處理類自行注冊,也可以通過組態檔的方式表達,總之,形式有很多,

還有一些問題,其中的條件運算式并不像上例中的那樣簡單,但稍加變換,同樣可以應用表驅動,下面借用《編程珠璣》中的一個稅金計算的例子:

if income <= 2200
  tax = 0
else if income <= 2700
  tax = 0.14 * (income - 2200)
else if income <= 3200
  tax = 70 + 0.15 * (income - 2700)
else if income <= 3700
  tax = 145 + 0.16 * (income - 3200)
......
else
  tax = 53090 + 0.7 * (income - 102200)

對于上面的代碼,其實只需將稅金的計算公式提取出來,將每一檔的標準提取到一個表格,在加上一個回圈即可,具體重構之后的代碼不給出,大家自己思考,

方法二:職責鏈模式

介紹

當 if...else 中的條件運算式靈活多變,無法將條件中的資料抽象為表格并用統一的方式進行判斷時,這時應將對條件的判斷權交給每個功能組件,并用鏈的形式將這些組件串聯起來,形成完整的功能,

適用場景

條件運算式靈活多變,沒有統一的形式,

實作與示例

職責鏈的模式在開源框架的 Filter、Interceptor 功能的實作中可以見到很多,下面看一下通用的使用模式:

重構前:

public void handle(request) {
    if (handlerA.canHandle(request)) {
        handlerA.handleRequest(request);
    } else if (handlerB.canHandle(request)) {
        handlerB.handleRequest(request);
    } else if (handlerC.canHandle(request)) {
        handlerC.handleRequest(request);
    }
}

重構后:

public void handle(request) {
  handlerA.handleRequest(request);
}

public abstract class Handler {
  protected Handler next;
  public abstract void handleRequest(Request request);
  public void setNext(Handler next) { this.next = next; }
}

public class HandlerA extends Handler {
  public void handleRequest(Request request) {
    if (canHandle(request)) doHandle(request);
    else if (next != null) next.handleRequest(request);
  }
}

當然,示例中的重構前的代碼為了表達清楚,做了一些類和方法的抽取重構,現實中,更多的是平鋪式的代碼實作,

注:職責鏈的控制模式

職責鏈模式在具體實作程序中,會有一些不同的形式,從鏈的呼叫控制角度看,可分為外部控制和內部控制兩種,

外部控制不靈活,但是減少了實作難度,職責鏈上某一環上的具體實作不用考慮對下一環的呼叫,因為外部統一控制了,但是一般的外部控制也不能實作嵌套呼叫,如果有嵌套呼叫,并且希望由外部控制職責鏈的呼叫,實作起來會稍微復雜,具體可以參考 Spring Web Interceptor 機制的實作方法,

內部控制就比較靈活,可以由具體的實作來決定是否需要呼叫鏈上的下一環,但如果呼叫控制模式是固定的,那這樣的實作對于使用者來說是不便的,

設計模式在具體使用中會有很多變種,大家需要靈活掌握

方法三:注解驅動

介紹

通過 Java 注解(或其它語言的類似機制)定義執行某個方法的條件,在程式執行時,通過對比入參與注解中定義的條件是否匹配,再決定是否呼叫此方法,具體實作時,可以采用表驅動或職責鏈的方式實作,

適用場景

適合條件分支很多多,對程式擴展性和易用性均有較高要求的場景,通常是某個系統中經常遇到新需求的核心功能,

實作與示例

很多框架中都能看到這種模式的使用,比如常見的 Spring MVC,因為這些框架很常用,demo 隨處可見,所以這里不再上具體的演示代碼了,

這個模式的重點在于實作,現有的框架都是用于實作某一特定領域的功能,例如 MVC,故業務系統如采用此模式需自行實作相關核心功能,主要會涉及反射、職責鏈等技術,具體的實作這里就不做演示了,

方法四:事件驅動

介紹

通過關聯不同的事件型別和對應的處理機制,來實作復雜的邏輯,同時達到解耦的目的,

適用場景

從理論角度講,事件驅動可以看做是表驅動的一種,但從實踐角度講,事件驅動和前面提到的表驅動有多處不同,具體來說:

  1. 表驅動通常是一對一的關系;事件驅動通常是一對多;
  2. 表驅動中,觸發和執行通常是強依賴;事件驅動中,觸發和執行是弱依賴

正是上述兩者不同,導致了兩者適用場景的不同,具體來說,事件驅動可用于如訂單支付完成觸發庫存、物流、積分等功能,

實作與示例

實作方式上,單機的實踐驅動可以使用 Guava、Spring 等框架實作,分布式的則一般通過各種訊息佇列方式實作,但是因為這里主要討論的是消除 if...else,所以主要是面向單機問題域,因為涉及具體技術,所以此模式代碼不做演示,

方法五:有限狀態機

介紹

有限狀態機通常被稱為狀態機(無限狀態機這個概念可以忽略),先參考維基百科上的定義:

有限狀態機(英語:finite-state machine,縮寫:FSM),簡稱狀態機,是表示有限個狀態以及在這些狀態之間的轉> 移和動作等行為的數學模型,

其實,狀態機也可以看做是表驅動的一種,其實就是當前狀態和事件兩者組合與處理函式的一種對應關系,當然,處理成功之后還會有一個狀態轉移處理,

適用場景

雖然現在互聯網后端服務都在強調無狀態,但這并不意味著不能使用狀態機這種設計,其實,在很多場景中,如協議堆疊、訂單處理等功能中,狀態機有這其天然的優勢,因為這些場景中天然存在著狀態和狀態的流轉,

實作與示例

實作狀態機設計首先需要有相應的框架,這個框架需要實作至少一種狀態機定義功能,以及對于的呼叫路由功能,狀態機定義可以使用 DSL 或者注解的方式,原理不復雜,掌握了注解、反射等功能的同學應該可以很容易實作,

參考技術:

  • Apache Mina State Machine
    Apache Mina 框架,雖然在 IO 框架領域不及 Netty,但它卻提供了一個狀態機的功能,https://mina.apache.org/mina-project/userguide/ch14-state-machine/ch14-state-machine.html,有自己實作狀態機功能的同學可以參考其原始碼,
  • Spring State Machine
    Spring 子專案眾多,其中有個不顯山不露水的狀態機框架 —— Spring State Machine https://projects.spring.io/spring-statemachine/,可以通過 DSL 和注解兩種方式定義,

上述框架只是起到一個參考的作用,如果涉及到具體專案,需要根據業務特點自行實作狀態機的核心功能,

方法六:Optional

介紹

Java 代碼中的一部分 if...else 是由非空檢查導致的,因此,降低這部分帶來的 if...else 也就能降低整體的 if...else 的個數,

Java 從 8 開始引入了 Optional 類,用于表示可能為空的物件,這個類提供了很多方法,用于相關的操作,可以用于消除 if...else,開源框架 Guava 和 Scala 語言也提供了類似的功能,

使用場景

有較多用于非空判斷的 if...else,

實作與示例

傳統寫法:

String str = "Hello World!";
if (str != null) {
    System.out.println(str);
} else {
    System.out.println("Null");
}

使用 Optional 之后:

1 Optional<String> strOptional = Optional.of("Hello World!");
2 strOptional.ifPresentOrElse(System.out::println, () -> System.out.println("Null"));

Optional 還有很多方法,這里不一一介紹了,但請注意,不要使用 get() 和 isPresent() 方法,否則和傳統的 if...else 無異,

擴展:Kotlin Null Safety

Kotlin 帶有一個被稱為 Null Safety 的特性:

bob?.department?.head?.name

對于一個鏈式呼叫,在 Kotlin 語言中可以通過 ?. 避免空指標例外,如果某一環為 null,那整個鏈式運算式的值便為 null,

方法七:Assert 模式

介紹

上一個方法適用于解決非空檢查場景所導致的 if...else,類似的場景還有各種引數驗證,比如還有字串不為空等等,很多框架類別庫,例如 Spring、Apache Commons 都提供了工具里,用于實作這種通用的功能,這樣大家就不必自行撰寫 if...else 了,

  • Apache Commons Lang 中的 Validate 類:https://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/Validate.html
  • Spring 的 Assert 類:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/util/Assert.html

使用場景

通常用于各種引數校驗

擴展:Bean Validation

類似上一個方法,介紹 Assert 模式順便介紹一個有類似作用的技術 —— Bean Validation,Bean Validation 是 Java EE 規范中的一個,Bean Validation 通過在 Java Bean 上用注解的方式定義驗證標準,然后通過框架統一進行驗證,也可以起到了減少 if...else 的作用,

方法八:多型

介紹

使用面向物件的多型,也可以起到消除 if...else 的作用,在代碼重構這本書中,對此也有介紹:

https://refactoring.com/catalog/replaceConditionalWithPolymorphism.html

使用場景

鏈接中給出的示例比較簡單,無法體現適合使用多型消除 if...else 的具體場景,一般來說,當一個類中的多個方法都有類似于示例中的 if...else 判斷,且條件相同,那就可以考慮使用多型的方式消除 if...else,

同時,使用多型也不是徹底消除 if...else,而是將 if...else 合并轉移到了物件的創建階段,在創建階段的 if..,我們可以使用前面介紹的方法處理,

小結

上面這節介紹了 if...else 過多所帶來的問題,以及相應的解決方法,除了本節介紹的方法,還有一些其它的方法,比如,在《重構與模式》一書中就介紹了“用 Strategy 替換條件邏輯”、“用 State 替換狀態改變條件陳述句”和“用 Command 替換條件調度程式”這三個方法,其中的“Command 模式”,其思想同本文的“表驅動”方法大體一致,另兩種方法,因為在《重構與模式》一書中已做詳細講解,這里就不再重復,

何時使用何種方法,取決于面對的問題的型別,上面介紹的一些適用場景,只是一些建議,更多的需要開發人員自己的思考,

問題二:if…else 嵌套過深

問題表現

if...else 多通常并不是最嚴重的的問題,有的代碼 if...else 不僅個數多,而且 if...else 之間嵌套的很深,也很復雜,導致代碼可讀性很差,自然也就難以維護,

if (condition1) {
    action1();
    if (condition2) {
        action2();
        if (condition3) {
            action3();
            if (condition4) {
                action4();
            }
        }
    }
}

if...else 嵌套過深會嚴重地影響代碼的可讀性,當然,也會有上一節提到的兩個問題,

如何解決

上一節介紹的方法也可用用來解決本節的問題,所以對于上面的方法,此節不做重復介紹,這一節重點一些方法,這些方法并不會降低 if...else 的個數,但是會提高代碼的可讀性:

  1. 抽取方法
  2. 衛陳述句

方法一:抽取方法

** **

介紹

抽取方法是代碼重構的一種手段,定義很容易理解,就是將一段代碼抽取出來,放入另一個單獨定義的方法,借

用 https://refactoring.com/catalog/extractMethod.html 中的定義:

適用場景

if...else 嵌套嚴重的代碼,通常可讀性很差,故在進行大型重構前,需先進行小幅調整,提高其代碼可讀性,抽取方法便是最常用的一種調整手段,

實作與示例

重構前:

public void add(Object element) {
  if (!readOnly) {
    int newSize = size + 1;
    if (newSize > elements.length) {
      Object[] newElements = new Object[elements.length + 10];
      for (int i = 0; i < size; i++) {
        newElements[i] = elements[i];
      }

      elements = newElements
    }
    elements[size++] = element;
  }
}

重構后:

public void add(Object element) {
  if (readOnly) {
    return;
  }

  if (overCapacity()) {
    grow();
  }

  addElement(element);
}

方法二:衛陳述句

介紹

在代碼重構中,有一個方法被稱為“使用衛陳述句替代嵌套條件陳述句”https://refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html,直接看代碼:

double getPayAmount() {
    double result;
    if (_isDead) result = deadAmount();
    else {
        if (_isSeparated) result = separatedAmount();
        else {
            if (_isRetired) result = retiredAmount();
            else result = normalPayAmount();
        };
    }
    return result;
}

重構之后

double getPayAmount() {
    if (_isDead) return deadAmount();
    if (_isSeparated) return separatedAmount();
    if (_isRetired) return retiredAmount();
    return normalPayAmount();
}

使用場景

當看到一個方法中,某一層代碼塊都被一個 if...else 完整控制時,通常可以采用衛陳述句,

問題三:if…else 運算式過于復雜

問題表現

if...else 所導致的第三個問題來自過于復雜的條件運算式,下面給個簡單的例子,當 condition 1、2、3、4 分別為 true、false,請大家排列組合一下下面運算式的結果,

1 if ((condition1 && condition2 ) || ((condition2 || condition3) && condition4)) {
2   
3 }

我想沒人愿意干上面的事情,關鍵是,這一大坨運算式的含義是什么?關鍵便在于,當不知道運算式的含義時,沒人愿意推斷它的結果,

所以,運算式復雜,并不一定是錯,但是運算式難以讓人理解就不好了,

如何解決

對于 if...else 運算式復雜的問題,主要用代碼重構中的抽取方法、移動方法等手段解決,因為這些方法在《代碼重構》一書中都有介紹,所以這里不再重復,

總結

本文一個介紹了10種(算上擴展有12種)用于消除、簡化 if...else 的方法,還有一些方法,如通過策略模式、狀態模式等手段消除 if...else 在《重構與模式》一書中也有介紹,

正如前言所說,if...else 是代碼中的重要組成部分,但是過度、不必要地使用 if...else,會對代碼的可讀性、可擴展性造成負面影響,進而影響到整個軟體系統,

“干掉”if...else 的能力高低反映的是程式員對軟體重構、設計模式、面向物件設計、架構模式、資料結構等多方面技術的綜合運用能力,反映的是程式員的內功,要合理使用 if...else,不能沒有設計,也不能過度設計,這些對技術的綜合、合理地運用都需要程式員在作業中不斷的摸索總結,

作者:艾瑞克·邵
來源:www.cnblogs.com/eric-shao/p/10115577.html

歡迎關注公眾號 【碼農開花】一起學習成長
我會一直分享Java干貨,也會分享免費的學習資料課程和面試寶典
回復:【計算機】【設計模式】【002】有驚喜哦

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/227693.html

標籤:Java

上一篇:增強for回圈

下一篇:python去除(京東,抖音,小紅書等等)視頻水印

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more