主頁 > 後端開發 > 如何學習23種設計模式及其思想?

如何學習23種設計模式及其思想?

2020-12-15 07:12:18 後端開發

感覺設計模式是看著簡單 ,但是一用就不會,23種設計模式,學的人頭大,相信大家都是這樣的

 

設計模式在程式員的面試中會被考到,通常是介紹其原理并說出優缺點,或者對比幾個比較相似的模式的異同點,在筆試中可能會出現畫出某個設計模式的UML圖這樣的題,雖說面試中占的比重不大,但并不代表它不重要,恰恰相反,設計模式于程式員而言相當重要,它是我們寫出優秀程式的保障,設計模式與程式員的架構能力與閱讀原始碼的能力息息相關,非常值得我們深入學習,

 

面向物件的威力從這個小例子中只能看到冰山一角,好比一段兩公里的路程,坐飛機和走路花費的時間差不了多少,但當我們需要翻山越嶺、漂洋過海時,坐飛機的人就會將走路的人遠遠拋在后面,

面向物件的特點是可維護、可復用、可擴展、靈活性好,它真正強大的地方在于:隨著業務變得越來越復雜,面向物件依然能夠使得程式結構良好,而面向程序卻會導致程式越來越臃腫,

讓面向物件保持結構良好的秘訣就是 設計模式,

 

熟練掌握各種設計模式,并能在實際編程開發中靈活運用它們,不僅能使代碼更規范,重用性更高,同時也能保證代碼的可靠性,提高開發效率,這段時間又系統看了設計模式的相關內容,
整理學習總結如下:

  • 七個設計原則
  • 創建型模式(5種)
  • 結構型模式(7種)
  • 行為型模式(11種)

總體來說設計模式分為三大類:(本文著重講解標紅)
創建型模式,共五種: 工廠方法模式、 抽象工廠模式、 單例模式、 建造者模式、原型模式,
結構型模式,共七種: 配接器模式、裝飾器模式、 代理模式、外觀模式、橋接模式、組合模式、 享元模式,
行為型模式,共十一種: 策略模式、模板方法模式、 觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式,

二.七個設計原則

面向物件編程有七大原則,即經常提到的Design Pattern,提倡它的根本原因是為了代碼復用,增加可維護性,設計模式就是實作了這些原則,從而達到了代碼復用、增加可維護性的目的,

 

 

因為設計模式就是基于這些原則的實作,所以很有必要了解這些原則,下面主要對面向物件編程的幾個原則進行簡單介紹,

1、單一職責原則 ( SRP )

英文全稱是Single Responsibility Principle,定義是一個類,應該只有一個引起它變化的原因,類變化的原因就是職責,如果一個類承擔的職責過多,就等于把這些職責耦合在一起了,一個職責的變化可能會削榷訓者抑制這個類完成其他職責的能力,這種耦合會導致脆弱的設計,當發生變化時,設計會遭受到意想不到的破壞,而如果想要避免這種現象的發生,就要盡可能的遵守單一職責原則,此原則的核心就是解耦和增強內聚性,


2、開閉原則 ( OCP )
英文全稱是Open Close Principle,定義是軟體物體(包括類、模塊、函式等)應該對于擴展時開放的,對于修改是封閉的,開閉原則是是面向物件設計中最重要的原則之一,其它很多的設計原則都是實作開閉原則的一種手段,


3、里氏替換原則 ( LSP )
英文全稱是Liskov Substitution Principle,是面向物件設計的基本原則之一, 定義是任何基類可以出現的地方,子類一定可以出現,LSP 是繼承復用的基石,只有當派生類可以替換掉基類,且軟體單位的功能不受到影響時,基類才能真正被復用,而派生類也能夠在基類的基礎上增加新的行為,里氏替換原則是對開閉原則的補充,實作開閉原則的關鍵步驟就是抽象化,而基類與子類的繼承關系就是抽象化的具體實作,所以里氏替換原則是對實作抽象化的具體步驟的規范,


4、依賴倒置原則 ( DIP )
英文全稱是Dependence Inversion Principle,這個原則是開閉原則的基礎,依賴倒置原則就是要求呼叫者和被呼叫者都依賴抽象,這樣兩者沒有直接的關聯和接觸,在變動的時候,一方的變動不會影響另一方的變動,依賴倒置強調了抽象的重要性,針對介面編程,依賴于抽象而不依賴于具體,


5、介面隔離原則 ( ISP )
英文全稱是Interface Segregation Principle,這個原則的意思是使用多個隔離的介面,比使用單個介面要好,目的就是降低類之間的耦合度,便于軟體升級和維護,


6、最少知道原則(迪米特原則)
一個物體應當盡量少地與其他物體之間發生相互作用,使得系統功能模塊相對獨立,通俗地說就是不要和陌生人說話,即一個物件應對其他物件有盡可能少的了解,迪米特法則的初衷在于降低類之間的耦合,由于每個類盡量減少對其他類的依賴,因此,很容易使得系統的功能模塊功能獨立,相互之間不存在(或很少有)依賴關系,


7、合成/聚合復用(CARP)
英文全稱是Composite Reuse Principle,合成/聚合復用原則經常又叫做合成復用原則,合成/聚合復用原則的潛臺詞是:我只是用你的方法,我們不一定是同類,繼承的耦合性更大,比如一個父類后來添加實作一個介面或者去掉一個介面,那子類可能會遭到毀滅性的編譯錯誤,但如果只是組合聚合,只是參考類的方法,就不會有這種巨大的風險,同時也實作了復用,


三.創建者模式(5種)

創建型模式是指這些設計模式提供了一種在創建物件的同時隱藏創建邏輯的方式,而不是使用新的運算子直接實體化物件,這使得程式在判斷針對某個給定實體需要創建哪些物件時更加靈活

 

1.單例模式

 

  • 定義

確保某一個類只有一個實體,并自行實體化向整個系統提供這個實體,

  • 簡介

單例模式理解起來不難,典型例子有一個公司只能有一個CEO,它主要是為了保證一個類僅有一個實體,這個類中自己提供一個回傳實體的方法,方法中先判斷系統是否已經有這個單例,如果有則回傳,如果沒有則創建,如果創建多個實體會消耗過多的資源或者某種型別的物件只應該有且只有一個時,應該考慮使用單例模式,

  • 實作

單例模式理解起來不難,重要的是需要掌握它的幾種常見寫法,
餓漢式:

public class Singleton {
// 直接創建物件
public static Singleton instance = new Singleton();
// 私有化建構式
private Singleton() {
}
// 回傳物件實體
public static Singleton getInstance() {
return instance;
}
}

 


懶漢式:

//寫法一、懶漢式寫法

public class Singleton {
 
    private static Singleton instance; 

    //建構式私有
    private Singleton (){
    }  

    public static synchronized Singleton getInstance() { 
         if (instance == null) {  
             instance = new Singleton();  
         }  
         return instance;  
    }  
}  
 

//寫法二、DCL(Double Check Lock) 雙重校驗鎖

public class Singleton {  

    private volatile static Singleton singleton;  

    private Singleton (){
    }  

    public static Singleton getSingleton() {  

        if (singleton == null) {  
            synchronized (Singleton.class) {  
            if (singleton == null) {  
                singleton = new Singleton();  
            }  
          }  
        }  
        return singleton;  
    }  
} 
 

//寫法三、靜態內部類單例模式

public class Singleton {  

    private Singleton (){
    }  

    public static final Singleton getInstance() {  
          return SingletonHolder.INSTANCE;  
    }  

    private static class SingletonHolder {  
         private static final Singleton INSTANCE = new Singleton();  
    }
}   

 


上面的第一種懶漢式寫法做到了延遲創建和執行緒安全,缺點是每次呼叫getInstance()時都必須進行同步,效率不佳,第二種DCL方式比較常見,兩次判空,第一次判空避免了不必要的同步,第二次保證了單例創建,這種方式比較不錯,但是在高并發環境下有時會出現問題,第三種方法最被推薦,執行緒安全也保證了實體唯一,

2.工廠方法模式

  • 定義

定義一個用于創建物件的介面,讓子類決定實體化哪一個類,

工廠方法模式分為三種:普通工廠模式,就是建立一個工廠類,對實作了同一介面的一些類進行實體的創建,多個工廠方法模式,是對普通工廠方法模式的改進,在普通工廠方法模式中,如果傳遞的字串出錯,則不能正確創建物件,而多個工廠方法模式是提供多個工廠方法,分別創建物件,靜態工廠方法模式,將上面的多個工廠方法模式里的方法置為靜態的,不需要創建實體,直接呼叫即可 .

(1)普通工廠模式

public interface Sender {
public void Send();
}
public class MailSender implements Sender {
@Override
public void Send() {
System.out.println("this is mail sender!");
}
}
public class SmsSender implements Sender {
@Override
public void Send() {
System.out.println("this is sms sender!");
}
}
public class SendFactory {
public Sender produce(String type) {
if ("mail".equals(type)) {
return new MailSender();
} else if ("sms".equals(type)) {
return new SmsSender();
} else {
System.out.println("請輸入正確的型別!");
return null;
}
}
}

 

 

(2)多個工廠模式

該模式是對普通工廠方法模式的改進,在普通工廠方法模式中,如果傳遞的字串出錯,則不能正確創建物件,而多個工廠方法模式是提供多個工廠方法,分別創建物件,

public class SendFactory {
public Sender produceMail(){
return new MailSender();
}
public Sender produceSms(){
return new SmsSender();
}
}
public class FactoryTest {
public static void main(String[] args) {
SendFactory factory = new SendFactory();
Sender sender = factory.produceMail();
sender.send();
}
}

 

 

(3)靜態工廠模式

靜態工廠方法模式,將上面的多個工廠方法模式里的方法置為靜態的,不需要創建實體,直接呼叫即可

public class SendFactory {
 public static Sender produceMail(){
return new MailSender();
}
public static Sender produceSms(){
return new SmsSender();
}
}
public class FactoryTest {
public static void main(String[] args) {
Sender sender = SendFactory.produceMail();
sender.send();
}
}

 

 

3.抽象工廠模式

工廠方法模式有一個問題就是,類的創建依賴工廠類,也就是說,如果想要拓展程式,必須對工廠類進行修改,這違背了閉包原則,所以,從設計角度考慮,有一定的問題,如何解決?就用到抽象工廠模式,創建多個工廠類,這樣一旦需要增加新的功能, 直接增加新的工廠類就可以了,不需要修改之前的代碼,

代碼還是在工廠方法模式的基礎上改進

public interface Provider {
public Sender produce();
}
----------------------------------------------------------------------------
public interface Sender {
public void send();
}
----------------------------------------------------------------------------
public class MailSender implements Sender {
@Override
public void send() {
System.out.println("this is mail sender!");
}
}
---------------------------------------------------------------------------
public class SmsSender implements Sender {
@Override
public void send() {
System.out.println("this is sms sender!");
}
}
---------------------------------------------------------
public class SendSmsFactory implements Provider {
@Override
public Sender produce() {
return new SmsSender();
}
}
public class SendMailFactory implements Provider {
@Override
public Sender produce() {
return new MailSender();
}
}
-------------------------------------------------------------
public class Test {
public static void main(String[] args) {
Provider provider = new SendMailFactory();
Sender sender = provider.produce();
sender.send();
}
}

 

4.建造者模式(Builder )

工廠類模式提供的是創建單個類的模式,而建造者模式則是將各種產品集中起來進行管理,用來創建復合物件,所謂復合物件就是指某個類具有不同的屬性,其實建造者模式就是前面抽象工廠模式和最后的 Test 結合起來得到的

public class Builder {
private List<Sender> list = new ArrayList<Sender>();
public void produceMailSender(int count) {
for (int i = 0; i < count; i++) {
list.add(new MailSender());
}
}
public void produceSmsSender(int count) {
for (int i = 0; i < count; i++) {
list.add(new SmsSender());
}
}
}
 

public class TestBuilder {
public static void main(String[] args) {
Builder builder = new Builder();
builder.produceMailSender(10);
}
}

 

5.原型模式

 

  • 定義

用原型實體指定創建物件的種類,并且通過拷貝這些原型創建新的物件,

  • 簡介

原型模式不難理解,它主要是用在實體創建的時候,因為有的時候我們通過new創建一個物件時可能成本過高,這時我們可以考慮直接通過直接克隆實體快速創建物件,克隆后的實體與原實體內部屬性一致,原型模式需要注意一個深拷貝和淺拷貝的問題,
四.結構型模式(7種)
結構型模式關注類和物件的組合,繼承的概念被用來組合介面和定義組合物件獲得新功能的方式,

 

 

1.配接器設計模式

配接器模式將某個類的介面轉換成客戶端期望的另一個介面表示,目的是消除由于介面不匹配所造成的類的兼容性問題,主要分為三類:類的配接器模式、物件的配接器模式、介面的配接器模式

  • 類的配接器模式
public class Source {
public void method1() {
System.out.println("this is original method!");
}
}
-------------------------------------------------------------
public interface Targetable {
/* 與原類中的方法相同 */
public void method1();
 /* 新類的方法 */
 public void method2();
 }
 public class Adapter extends Source implements Targetable {
 @Override
 public void method2() {
 System.out.println("this is the targetable method!");
 }
 }
 public class AdapterTest {
 public static void main(String[] args) {
 Targetable target = new Adapter();
 target.method1();
 target.method2();
 }
}

 

  • 物件的配接器模式

基本思路和類的配接器模式相同,只是將 Adapter 類作修改,這次不繼承 Source 類,而是持有 Source 類的實體,以達到解決兼容性的問題

public class Wrapper implements Targetable {
private Source source;
public Wrapper(Source source) {
super();
this.source = source;
}
@Override
public void method2() {
System.out.println("this is the targetable method!");
}
@Override
public void method1() {
source.method1();
}
}
--------------------------------------------------------------
public class AdapterTest {
public static void main(String[] args) {
Source source = new Source();
Targetable target = new Wrapper(source);
target.method1();
target.method2();
}
}

 

  • 介面的配接器模式

介面的配接器是這樣的:有時我們寫的一個介面中有多個抽象方法,當我們寫該介面的實作類時,必須實作該介面的所有方法,這明顯有時比較浪費,因為并不是所有的方法都是我們需要的,有時只需要某一些,此處為了解決這個問題,我們引入了介面的配接器模式,借助于一個抽象類,該抽象類實作了該介面,實作了所有的方法,而我們不和原始的介面打交道,只和該抽象類取得聯系,所以我們寫一個類,繼承該抽象類,重寫我們需要的方法就行,

2.橋接模式

  • 定義

將抽象部分與實作部分分離,使它們都可以獨立的變化,

  • 簡介

在軟體系統中,某些型別由于自身的邏輯,它具有兩個或多個維度的變化,那么如何應對這種“多維度的變化”?這就要使用橋接模式,橋接模式需要重點理解的抽象部分,實作部分,脫耦,一個典型的例子是咖啡加糖問題,抽象部分有Coffee,其下有LargeCoffee,SmallCoffee,實作部分是CoffeeAdd,其下有Sugar,Normal,抽象類Coffee中參考CoffeeAdd,這樣CoffeeAdd其實就是一個橋接,


3.裝飾模式
顧名思義,裝飾模式就是給一個物件增加一些新的功能,而且是動態的,要求裝飾物件和被裝飾物件實作同一個 介面,裝飾物件持有被裝飾物件的實體,


4.組合模式

  • 定義

將物件組合成樹形結構以表示“部分-整體”的層次結構,使得用戶對單個物件和組合物件的使用具有一致性,

  • 簡介

組合模式理解起來相對簡單,典型的例子就是假設公司A,里面有不同的部門,不同的部分下有不同的員工,這樣一個部門下的所有員工組合成了一個部門,所有部門組合成了整個公司,


5.外觀模式

  • 定義

為子系統中的一組介面提供一個一致的界面,外觀模式定義了一個高層介面,這個介面使得這一子系統更加容易使用,

  • 簡介

外觀模式的一個典型例子是去醫院看病,掛號、門診、劃價、取藥,讓患者或患者家屬覺得很復雜,如果有提供接待人員,只讓接待人員來處理,就很方便,


6.享元模式

  • 定義

運用共享技術有效地支持大量細粒度的物件,

  • 簡介

在有大量物件時,有可能會造成記憶體溢位,我們把其中共同的部分抽象出來,如果有相同的業務請求,直接回傳在記憶體中已有的物件,避免重新創建,


7.代理模式

  • 定義

為其他物件提供一種代理以控制對這個物件的訪問,

  • 簡介

代理模式主要解決在直接訪問物件時帶來的問題,舉個例子,豬八戒去找高翠蘭結果是孫悟空變的,可以這樣理解:把高翠蘭的外貌抽象出來,高翠蘭本人和孫悟空都實作了這個介面,豬八戒訪問高翠蘭的時候看不出來這個是孫悟空,所以說孫悟空是高翠蘭代理類,


五、行為型模式 ( 11種 )


這些設計模式特別關注物件之間的通信,

1.模板方法模式

  • 定義

一個操作中的演算法的框架,而將一些步驟延遲到子類中,使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟,

  • 例子

模板方法模式一個典型例子就是Android中的異步任務類AsyncTask,它對異步任務的執行進行了流程封裝,子類繼承它時,只需在指定的流程中實作具體的操作即可,


2.命令模式

  • 定義

將一個請求封裝為一個物件,從而可用不同的請求對客戶進行引數化;對請求排隊或記錄請求日志,以及支持可取消的操作

  • 簡介

命令模式主要是通過呼叫者呼叫接受者執行命令,這個模式中需要理解的是三個角色:(1) Receiver 真正的命令執行物件 (2) Command 持有一個對Receiver的參考,呼叫Receiver的相關方法,(3) Invoker 請求者,持有一個對Command的參考,呼叫Command的方法執行具體命令,


3.迭代器模式

  • 定義

提供一種方法順序訪問一個聚合物件中各個元素, 而又不需暴露該物件的內部表示,

  • 簡介

在Java集合框架中我們知道對于一個指定的集合類,我們可以使用一個特定的Iterator迭代器來對集合中的所有元素進行遍歷,這樣結合來看,迭代器模式很好理解了,


4.觀察者模式

  • 定義

定義物件間的一種一對多的依賴關系,當一個物件的狀態發生改變時,所有依賴于它的物件都得到通知并被自動更新,

  • 簡介

觀察者模式可以結合Android中的ListView來理解,ListView關聯的配接器Adapter在資料發生變化時會通過notifyDataSetChanged()方法來通知界面重繪,


5.中介者模式

  • 定義

用一個中介物件來封裝一系列的物件互動,中介者使各物件不需要顯式地相互參考,從而使其耦合松散,而且可以獨立地改變它們之間的互動,

  • 簡介

中介者模式的典型例子就是未加入 WTO 之前各個國家相互貿易,結構復雜,大家都加入WTO后是各個國家通過 WTO 來互相貿易,變得規范,


6.備忘錄模式

  • 定義

在不破壞封裝性的前提下,捕獲一個物件的內部狀態,并在該物件之外保存這個狀態,這樣以后就可將該物件恢復到保存的狀態,

  • 簡介

備忘錄模式的典型例子就是git版本管理工具,它幫我們保存了每次提交后的專案狀態,在必要的時候我們可以回退到指定的版本中,


7.解釋器模式

  • 定義

給定一個語言,定義它的文法的一種表示,并定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子,

  • 簡介

解釋器的典型例子是在編譯原理中的應用,如果一種特定型別的問題發生的頻率足夠高,那么可能就值得將該問題的各個實體表述為一個簡單語言中的句子,這樣就可以構建一個解釋器,該解釋器通過解釋這些句子來解決該問題,


8.狀態模式

  • 定義

允許一個物件在其內部狀態改變時改變它的行為,物件看起來似乎修改了它的類,

  • 簡介

狀態模式主要解決物件的行為依賴于它的狀態(屬性),并且可以根據它的狀態改變而改變它的相關行為,典型的例子是一個人在不同的狀態下完成一件事的結果可能是不同的,


9.策略模式

  • 定義

定義一系列的演算法,把它們一個個封裝起來, 并且使它們可相互替換,本模式使得演算法可獨立于使用它的客戶而變化,

  • 簡介

從策略模式的定義可以看到它主要是將演算法和客戶獨立開,一個典型的例子是排序演算法,我們給定一個陣列,輸出排序后的結果,但是程序中我們可以采取不同的排序演算法,這些演算法其實就是策略,


10.責任鏈模式

  • 定義

使多個物件都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關系,將這些物件連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個物件處理它為止,

  • 簡介

責任鏈模式,避免請求發送者與接收者耦合在一起,讓多個物件都有可能接收請求,將這些物件連接成一條鏈,并且沿著這條鏈傳遞請求,直到有物件處理它為止,


11.訪問者模式

  • 定義

封裝一些作用于某種資料結構中的各元素的操作,它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作,

  • 簡介

訪問者模式是一種將資料操作和資料結構分離的設計模式,它通常使用在物件結構比較穩定,但是經常需要在此物件結構上定義新的操作,或者需要對一個物件結構中的物件進行很多不同的并且不相關的操作,而需要避免讓這些操作"污染"這些物件的類,使用訪問者模式將這些封裝到類中


六.總結

到這里,Java設計模式的學習總結就結束了,因為個人能力有限,有些模式只是簡單介紹了一下,想要進一步學習的話還是要靠大家自己去查閱相關資料學習,熟練地掌握設計模式,還需多多的實踐.

 

 

 

 

有完整的Java初級,高級對應的學習路線和資料!專注于java開發,分享java基礎、原理性知識、JavaWeb實戰、spring全家桶、設計模式、分布式及面試資料、開源專案,助力開發者成長!


歡迎關注微信公眾號:碼邦主

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

標籤:Java

上一篇:Jrebel License Server 激活 IDEA-Jrebel-在線-離線-均適用

下一篇:「奇淫技巧」如何寫最少的代碼

標籤雲
其他(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