使用OC語言編寫兩個超大數相乘或相加的演算法的思路和超大正整數相乘的代碼

来源:http://www.cnblogs.com/axclogo/archive/2016/04/21/5416510.html
-Advertisement-
Play Games

正文: 在編程中,無論是OC還是C亦或是C++語言,所聲明的整數變數都會在記憶體中占有固定的存儲空間,而這些存儲空間都是固定的。 比如我們知道的int、long、short、unsigend int、unsigend long、unsigend long long等等,都有固定的存儲空間,而哪怕是64 ...


 

正文:

在編程中,無論是OC還是C亦或是C++語言,所聲明的整數變數都會在記憶體中占有固定的存儲空間,而這些存儲空間都是固定的。

比如我們知道的int、long、short、unsigend int、unsigend long、unsigend long long等等,都有固定的存儲空間,而哪怕是64位系統下的變數unsigend long long,能存儲的最大範圍只有1844674407370955161

下邊複習一下基礎類型的存儲範圍以及所占位元組:

編程語言的基礎類型速查表

char -128 ~ +127 (1 Byte)
short -32767 ~ + 32768 (2 Bytes)
unsigned short 0 ~ 65536 (2 Bytes)
int -2147483648 ~ +2147483647 (4 Bytes)
unsigned int 0 ~ 4294967295 (4 Bytes)
long == int
long long -9223372036854775808 ~ +9223372036854775807 (8 Bytes)
double 1.7 * 10^308 (8 Bytes)

unsigned int 0~4294967295  
long long的最大值:9223372036854775807
long long的最小值:-9223372036854775808
unsigned long long的最大值:1844674407370955161

__int64的最大值:9223372036854775807
__int64的最小值:-9223372036854775808
unsigned __int64的最大值:18446744073709551615

 

詳細:

====================

符號屬性 長度屬性 基本型 所占位數 取值範圍 輸入符舉例 輸出符舉例 
    -- -- char                            8 -2^7 ~ 2^7-1 %c %c 、 %d 、 %u
    signed -- char                    8 -2^7 ~ 2^7-1 %c %c 、 %d 、 %u
    unsigned -- char                8 0 ~ 2^8-1 %c %c 、 %d 、 %u
    [signed] short [int]            16 -2^15 ~ 2^15-1 %hd
    unsigned short [int]           16 0 ~ 2^16-1 %hu 、 %ho 、 %hx
    [signed] -- int                    32 -2^31 ~ 2^31-1 %d
    unsigned -- [int]                 32 0 ~ 2^32-1 %u 、 %o 、 %x
    [signed] long [int]              32 -2^31 ~ 2^31-1 %ld
    unsigned long [int]             32 0 ~ 2^32-1 %lu 、 %lo 、 %lx
    [signed] long long [int]       64 -2^63 ~ 2^63-1 %I64d
    unsigned long long [int]      64 0 ~ 2^64-1 %I64u 、 %I64o 、 %I64x
    -- -- float                            32 +/- 3.40282e+038 %f 、 %e 、 %g
    -- -- double                        64 +/- 1.79769e+308 %lf 、 %le 、 %lg %f 、 %e 、 %g
    -- long double                    96 +/- 1.79769e+308 %Lf 、 %Le 、 %Lg

幾點說明: 

1. 註意 ! 表中的每一行,代表一種基本類型。 “[]” 代表可省略。 
    例如: char 、 signed char 、 unsigned char 是三種互不相同的類型; 
    int 、 short 、 long 也是三種互不相同的類型。 

2. char/signed char/unsigned char 型數據長度為 1 位元組;
    char 為有符號型,但與 signed char 是不同的類型。 
    註意 ! 並不是所有編譯器都這樣處理, char 型數據長度不一定為 1 位元組, char 也不一定為有符號型。 

3. 將 char/signed char 轉換為 int 時,會對最高符號位 1 進行擴展,從而造成運算問題。 
    所以 , 如果要處理的數據中存在位元組值大於 127 的情況,使用 unsigned char 較為妥當。 
    程式中若涉及位運算,也應該使用 unsigned 型變數。 

4. char/signed char/unsigned char 輸出時,使用格式符 %c (按字元方式);  或使用 %d 、 %u 、 %x/%X 、 %o ,按整數方式輸出; 輸入時,應使用 %c ,若使用整數方式, Dev-C++ 會給出警告,不建議這樣使用。 

5. int 的長度,是 16 位還是 32 位,與編譯器字長有關。 
    16 位編譯器(如 TC 使用的編譯器)下, int 為 16 位; 32 位編譯器(如 VC 使用的編譯器 cl.exe )下, int 為 32位。 

6. 整型數據可以使用 %d (有符號 10 進位)、 %o (無符號 8 進位)或 %x/%X (無符號 16 進位)方式輸入輸出。 而格式符 %u ,表示 unsigned ,即無符號 10 進位方式。 

7. 整型首碼 h 表示 short , l 表示 long 。 
    輸入輸出 short/unsigned short 時,不建議直接使用 int 的格式符 %d/%u 等,要加首碼 h 。這個習慣性錯誤,來源於 TC 。 TC 下, int 的長度和預設符號屬性,都與 short 一致,於是就把這兩種類型當成是相同的,都用 int 方式進行輸入輸出。 

8. 關於 long long 類型的輸入輸出: 
    "%lld" 和 "%llu" 是 linux 下 gcc/g++ 用於 long long int 類型 (64 bits) 輸入輸出的格式符。 
    而 "%I64d" 和 "%I64u" 則是 Microsoft VC++ 庫里用於輸入輸出 __int64 類型的格式說明。 

    Dev-C++ 使用的編譯器是 Mingw32 , Mingw32 是 x86-win32 gcc 子項目之一,編譯器核心還是 linux 下的 gcc 。
    進行函數參數類型檢查的是在編譯階段, gcc 編譯器對格式字元串進行檢查,顯然它不認得 "%I64d" , 
    所以將給出警告 “unknown conversion type character `I' in format” 。對於 "%lld" 和 "%llu" , gcc 理所當然地接受了。 
    
    Mingw32 在編譯期間使用 gcc 的規則檢查語法,在連接和運行時使用的卻是 Microsoft 庫。 
    這個庫里的 printf 和 scanf 函數當然不認識 linux gcc 下 "%lld" 和 "%llu" ,但對 "%I64d" 和 "%I64u" ,它則是 樂意接受,並能正常工作的。 

9. 浮點型數據輸入時可使用 %f 、 %e/%E 或 %g/%G , scanf 會根據輸入數據形式,自動處理。 
    輸出時可使用 %f (普通方式)、 %e/%E (指數方式)或 %g/%G (自動選擇)。 

10. 浮點參數壓棧的規則: float(4 位元組 ) 類型擴展成 double(8 位元組 ) 入棧。 
    所以在輸入時,需要區分 float(%f) 與 double(%lf) ,而在輸出時,用 %f 即可。 
    printf 函數將按照 double 型的規則對壓入堆棧的 float( 已擴展成 double) 和 double 型數據進行輸出。 
    如果在輸出時指定 %lf 格式符, gcc/mingw32 編譯器將給出一個警告。 

11. Dev-C++(gcc/mingw32) 可以選擇 float 的長度,是否與 double 一致。 

12. 首碼 L 表示 long ( double )。 
    雖然 long double 比 double 長 4 個位元組,但是表示的數值範圍卻是一樣的。 
    long double 類型的長度、精度及表示範圍與所使用的編譯器、操作系統等有關。

我們看到上面所有基礎數據類型都是有限的,如果要計算天文數字級的、哪怕是最簡單的相加演算法,也會造成數據溢出。

比如:

寫了個將年齡轉為秒的程式,前126年都可以,但是從127開始就overflow了……

在電腦中,當要表示的數據超出電腦所使用的數據的表示範圍時,則產生數據的溢出。具體的自己網上可以查看下資料,很好查

 

溢出原因
數據類型超過了電腦字長的界限就會出現數據溢出的情況。導致記憶體溢出問題的原因有很多,比如:
(1) 使用非類型安全(non-type-safe)的語言如 C/C++ 等。
(2) 以不可靠的方式存取或者複製記憶體緩衝區。
(3)編譯器設置的記憶體緩衝區太靠近關鍵數據結構。

因素分析
1.記憶體溢出問題是 C 語言或者 C++ 語言所固有的缺陷,它們既不檢查數組邊界,又不檢查類型可靠性(type-safety)。眾所周知,用 C/C++ 語言開發的程式由於目標代碼非常接近機器內核,因而能夠直接訪問記憶體和寄存器,這種特性大大提升了 C/C++ 語言代碼的性能。只要合理編碼,C/C++應用程式在執行效率上必然優於其它高級語言。然而,C/C++ 語言導致記憶體溢出問題的可能性也要大許多。其他語言也存在記憶體溢出問題,但它往往不是程式員的失誤,而是應用程式的運行時環境出錯所致。
2. 當應用程式讀取用戶(也可能是惡意攻擊者)數據,試圖複製到應用程式開闢的記憶體緩衝區中,卻無法保證緩衝區的空間足夠時(換言之,假設代碼申請了 N 位元組大小的記憶體緩衝區,隨後又向其中複製超過 N 位元組的數據)。記憶體緩衝區就可能會溢出。想一想,如果你向 12 盎司的玻璃杯中倒入 16 盎司水,那麼多出來的 4 盎司水怎麼辦?當然會滿到玻璃杯外面了!
3. 最重要的是,C/C++編譯器開闢的記憶體緩衝區常常鄰近重要的數據結構。假設某個函數的堆棧緊接在在記憶體緩衝區後面時,其中保存的函數返回地址就會與記憶體緩衝區相鄰。此時,惡意攻擊者就可以向記憶體緩衝區複製大量數據,從而使得記憶體緩衝區溢出並覆蓋原先保存於堆棧中的函數返回地址。這樣,函數的返回地址就被攻擊者換成了他指定的數值;一旦函數調用完畢,就會繼續執行“函數返回地址”處的代碼。非但如此,C++ 的某些其它數據結構,比如 v-table 、例外事件處理程式、函數指針等,也可能受到類似的攻擊。

 

然而,針對這種情況,該怎麼防止數據溢出?

一、創建結構體,將溢出的數據轉移到另一個變數中存儲;

二、創建或設計一個存儲器,將所有巨大的數值存儲在這個存儲器中,演算法類似於時鐘演算法,滿多少進一位。再設計一個取出器,將轉換後的變數轉換成巨大的數值,邊轉換邊計算;

三、創建數組來按位數來存儲數據;

 

顯然第三種方法簡單便捷,比如我們要存儲一個123(一百二十三)的數據類型,則創建一個數組int【3】,數組中每個元素對應一位數,怎麼設計可以自己去設定,在這裡我們使用OC的NSMutableArray數組來計算,在此講一下C數組和OC數組的區別:

OC 數組是一個對象,有大量的方法,c 沒有都需要自己寫

C 數組刪除是需要後面往前移動,oc 數組自動處理

OC中的數組算是一個封裝好的對象,一般的操作基本就能滿足了,但是C裡面的就僅僅是個連續的記憶體空間而已。一個是對象一個空間,另外一個C裡面的數組是要在定義的時候就要初始化個數,但是OC裡面的個數比較動態。

 

這也就是為什麼涉及到演算法或者比較底層的數據處理一般使用C語言,第一:執行效率高;其次:演算法接近初級易於理解和維護,並且大量方法和函數運算規律可以完全自定義。

所以OC涉及到演算法極少,一般邏輯居多。OC來做簡單的運算也不是不可以,優點在於對於數組的處理比較簡便,以下簡述一下運算邏輯:

一:多位數相乘,第一個數的個位依次向第二位數的每位依次相乘,個位數與個位數相乘使用int來運算,如果結果是個位數,那麼把他放進一個array數組中;

二:如果結果是二位數,則存儲個位數,十位數添加到進位變數中,等待下一次相乘時與下一次的結果相加,然後繼續進行一步驟;

三:將最後array數組中的元素首尾調換,因為數組元素存儲方式是從個位到最高位,與需求數據相反;

四:將這個數組對象存儲到另一個數組中,形成OC二維數組;

五:經過以上運算,會獲得一個梯形數據:

        1234

      1234

    1234

  1234

需要對二維數組中的前位數組進行補0,為下一步方便運算做準備;

六:補0後數據為:

0001234

0012340

0123400

1234000

之後從上向下依次相加,同樣的:

1.第一個數的個位依次向第二位數的每位依次相加,個位數與個位數相乘使用int來運算,如果結果是個位數,那麼把他放進一個array數組中;

2.如果結果是二位數,則存儲個位數,十位數添加到進位變數中,等待下一次相乘時與下一次的結果相加,並且執行1步驟;

七:最後會獲得一個最終結果的數組,同樣的,裡面數據結構依然與需求數據相反,需要首尾調換;

八:返回這個數組,這個數組的每一個元素(從第一位起到第N位)都是這個最終結果(超大數)從個位到最高位的相應數值:

比如這個超大數是:1231443256827659485683297465789236578263857658265892561856138456938

那麼這個數組的元素依次是:1、2、3、1、4、4、3、2、5、6、8、.......5、6、9、3、8

 

OC雖然可以進行處理演算法和數據類型,但是相對於C來說,它所占的記憶體還是比較高的,因為這個數組所開闢的記憶體空間遠遠大於相應C數組的空間,它可以存儲多個對象,自帶各種數據處理方法,靈活多變對於C數組來說操作性很強,畢竟NSArray用於開發。

以下我把OC超大數演算法的代碼貼出來,僅供參考。。如有不對望指正:

 

 

 

 

#import "Multiplication.h"

 

@implementation Multiplication

 

-(NSString *)MulOfOneString:(NSString *)strOne AndString:(NSString *)strTwo{

    

    NSString *a = [NSString stringWithFormat:@"%lu",(unsigned long)strOne.length];

    NSString *b = [NSString stringWithFormat:@"%lu",(unsigned long)strTwo.length];

    int oneLength = [a intValue];

    int twoLength = [b intValue];

    NSMutableArray *arrOne = [[NSMutableArray alloc]init];

    NSMutableArray *arrTwo = [[NSMutableArray alloc]init];

    for (int i = 0;i < oneLength;i++) {

        unichar c = [strOne characterAtIndex:i];

        NSString *c1 = [NSString stringWithFormat:@"%c",c];

        [arrOne addObject:c1];

    }

    for (int i = 0;i < twoLength;i++) {

        unichar c = [strTwo characterAtIndex:i];

        NSString *c1 = [NSString stringWithFormat:@"%c",c];

        [arrTwo addObject:c1];

    }

    NSMutableArray *arrShi = [[NSMutableArray alloc]init];

    if (oneLength > twoLength) {

        for (int i = twoLength - 1 ;i >= 0;i--) {

            NSMutableString *strJ = [[NSMutableString alloc]init];

            int jin = 0;

            int btwo = [arrTwo[i] intValue];

            for (int j = oneLength - 1; j >= 0;j--) {

                int aone = [arrOne[j] intValue];

                int c = aone * btwo + jin;

                int z = c%10;

                jin = c/10;

                if (j != 0) {

                    [strJ appendFormat:@"%d",z];

                }else{

                    [strJ appendFormat:@"%d",c%10];

                    if (c/10!=0) {

                        [strJ appendFormat:@"%d",c/10];

                    }

                }

            }

            NSMutableString *zheng = [[NSMutableString alloc]init];

            for (NSInteger i = strJ.length-1 ;i>=0;i--) {

                unichar s = [strJ characterAtIndex:i];

                [zheng appendFormat:@"%c",s];

            }

            [arrShi addObject:zheng];

        }

    }else if(oneLength < twoLength){

        for (int i = oneLength - 1 ;i >= 0;i--) {

            NSMutableString *strJ = [[NSMutableString alloc]init];int jin = 0;

            int aone = [arrOne[i] intValue];

            for (int j = twoLength - 1; j >= 0;j--) {

                int btwo = [arrTwo[j] intValue];

                int c = aone * btwo + jin;

                int z = c%10;

                jin = c/10;

                if (j != 0) {

                    [strJ appendFormat:@"%d",z];

                }else{

                    [strJ appendFormat:@"%d",c%10];

                    if (c/10!=0) {

                        [strJ appendFormat:@"%d",c/10];

                    }                     }

            }

            NSMutableString *zheng = [[NSMutableString alloc]init];

            for (NSInteger i = strJ.length-1 ;i>=0;i--) {

                unichar s = [strJ characterAtIndex:i];

                [zheng appendFormat:@"%c",s];

            }

            [arrShi addObject:zheng];

        }

    }else if (oneLength == twoLength){

        for (int i = oneLength - 1 ;i >= 0;i--) {

            NSMutableString *strJ = [[NSMutableString alloc]init];int jin = 0;

            int aone = [arrOne[i] intValue];

            for (int j = twoLength - 1; j >= 0;j--) {

                int btwo = [arrTwo[j] intValue];

                int c = aone * btwo + jin;

                int z = c%10;

                jin = c/10;

                if (j != 0) {

                    [strJ appendFormat:@"%d",z];

                }else{

                    [strJ appendFormat:@"%d",c%10];

                    if (c/10!=0) {

                        [strJ appendFormat:@"%d",c/10];

                    }

                }

            }

            NSMutableString *zheng = [[NSMutableString alloc]init];

            for (NSInteger i = strJ.length-1 ;i>=0;i--) {

                unichar s = [strJ characterAtIndex:i];

                [zheng appendFormat:@"%c",s];

            }

            [arrShi addObject:zheng];

        }

    }

    NSMutableArray *arrBF = [[NSMutableArray alloc]init];

    if (arrShi.count == 1) {

        NSString *res = arrShi[0];

        return res;

    }else{

        for (int i = 0;i<arrShi.count;i++) {

            NSMutableString *str0 = arrShi[i];

            for (int j = 1;j<=i;j++) {

                [str0 appendFormat:@"0"];

            }

            arrBF[i] = str0;

        }

        for (int i =1;i<arrBF.count;i++) {

            int J = 0;

            NSMutableString *strConst = [[NSMutableString alloc]init];

            NSString *strC = arrBF[i-1];

            NSString *strB = arrBF[i];

            if (strC.length == strB.length) {

                for (NSInteger j = strB.length-1 ;j >= 0;j--) {

                    unichar b = [strB characterAtIndex:j];

                    unichar c = [strC characterAtIndex:j];

                    int B = [[NSString stringWithFormat:@"%c",b] intValue];

                    int C = [[NSString stringWithFormat:@"%c",c] intValue];

                    int counst = B + C + J;

                    int z = counst %10;

                    J = counst /10;

                    if (j != 0) {

                        [strConst appendFormat:@"%d",z];

                    }else{

                        [strConst appendFormat:@"%d",counst %10];

                        if (counst /10!=0) {

                            [strConst appendFormat:@"%d",counst /10];

                        }

                    }

                }

                NSMutableString *Lin = [[NSMutableString alloc]init];

                for (NSInteger i = strConst.length-1 ;i>=0;i--) {

                    unichar s = [strConst characterAtIndex:i];

                    [Lin appendFormat:@"%c",s];

                }

                arrBF[i] = Lin;

            }else{

                NSUInteger a = strC.length;

                for (NSInteger j = strB.length-1 ;j >= 0;j--) {

                    unichar b = [strB characterAtIndex:j];

                    unichar c = [strC characterAtIndex:a-1];

                    int B = [[NSString stringWithFormat:@"%c",b] intValue];

                    int C = [[NSString stringWithFormat:@"%c",c] intValue];

                    a--;

                    int counst = B + C + J;

                    int z = counst %10;

                    J = counst /10;

                    if (j != 0) {

                        [strConst appendFormat:@"%d",z];

                    }else{

                        [strConst appendFormat:@"%d",counst %10];

                        if (counst /10!=0) {

                            [strConst appendFormat:@"%d",counst /10];

                        }

                    }

                }

                NSMutableString *Lin = [[NSMutableString alloc]init];

                for (NSInteger i = strConst.length-1 ;i>=0;i--) {

                    unichar s = [strConst characterAtIndex:i];

                    [Lin appendFormat:@"%c",s];

                }

                arrBF[i] = Lin;

            }

        }

        NSString *res = arrBF[arrBF.count-1];

        return res;

    }

    return @"輸入有誤";

}

 

 

@end

 

 

 

超大數相加演算法思路和相乘演算法後半段思路相似,相對簡單很多

 

以下是超大數相加演算法的代碼:

 

 

#import "Addition.h"

 

@implementation Addition

 

- (NSString *)additionOfString:(NSString *)strOne AndString:(NSString *)strTwo{

    

    NSMutableString *One = [NSMutableString stringWithFormat:@"%@",strOne ];

    NSMutableString *Two = [NSMutableString stringWithFormat:@"%@",strTwo ];

    

    if (One.length > Two.length) {

        NSInteger t = One.length - Two.length;

        for (NSInteger i = 0;i < t;i++) {

            [Two insertString:[NSString stringWithFormat:@"0"] atIndex:0];

        }

        int jin = 0;

        NSMutableString *strJ = [[NSMutableString alloc]init];

        for (NSInteger i = One.length -1 ; i >= 0 ;i--) {

            unichar onenum = [One characterAtIndex:i];

            unichar twonum = [Two characterAtIndex:i];

            int onum = [[NSString stringWithFormat:@"%c",onenum] intValue];

            int tnum = [[NSString stringWithFormat:@"%c",twonum] intValue];

            int c = onum + tnum +jin;

            int z = c%10;

            jin = c/10;

            if (i !=0 ) {

                [strJ appendFormat:@"%d",z];

            }else{

                [strJ appendFormat:@"%d",c%10];

                if (c/10 != 0) {

                    [strJ appendFormat:@"%d",c/10];

                }

            }

        }

        NSMutableString *zheng = [[NSMutableString alloc]init];

        for (NSInteger i = strJ.length-1; i>=0;i--) {

            unichar k = [strJ characterAtIndex:i];

            [zheng appendFormat:@"%c",k];

        }

        return zheng;

    }else if(One.length < Two.length){

        NSInteger t = Two.length - One.length;

        for (NSInteger i = 0;i < t;i++) {

            [One insertString:[NSString stringWithFormat:@"0"] atIndex:0];

        }

        int jin = 0;

        NSMutableString *strJ = [[NSMutableString alloc]init];

        for (NSInteger i = Two.length - 1; i >= 0 ;i--) {

            unichar onenum = [One characterAtIndex:i];

            unichar twonum = [Two characterAtIndex:i];

            int onum = [[NSString stringWithFormat:@"%c",onenum] intValue];

            int tnum = [[NSString stringWithFormat:@"%c",twonum] intValue];

            int c = onum + tnum +jin;

            int z = c%10;

            jin = c/10;

            if (i !=0 ) {

                [strJ appendFormat:@"%d",z];

            }else{

                [strJ appendFormat:@"%d",c%10];

                if (c/10 != 0) {

                    [strJ appendFormat:@"%d",c/10];

                }

            }

        }

        NSMutableString *zheng = [[NSMutableString alloc]init];

        for (NSInteger i = strJ.length-1; i>=0;i--) {

            unichar k = [strJ characterAtIndex:i];

            [zheng appendFormat:@"%c",k];

        }

        return zheng;

    }else if(One.length == Two.length){

        int jin = 0;

        NSMutableString *strJ = [[NSMutableString alloc]init];

        for (NSInteger i = One.length - 1; i >= 0 ;i--) {

            unichar onenum = [One characterAtIndex:i];

            unichar twonum = [Two characterAtIndex:i];

            int onum = [[NSString stringWithFormat:@"%c",onenum] intValue];

            int tnum = [[NSString stringWithFormat:@"%c",twonum] intValue];

            int c = onum + tnum +jin;

            int z = c%10;

            jin = c/10;

            if (i !=0 ) {

                [strJ appendFormat:@"%d",z];

            }else{

                [strJ appendFormat:@"%d",c%10];

                if (c/10 != 0) {

                    [strJ appendFormat:@"%d",c/10];

                }

            }

        }

        NSMutableString *zheng = [[NSMutableString alloc]init];

        for (NSInteger i = strJ.length-1; i>=0;i--) {

            unichar k = [strJ characterAtIndex:i];

            [zheng appendFormat:@"%c",k];

        }

        return zheng;

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、 操作環境搭建系統:Windows7 旗艦版 64位PHP環境:wampserver2.2e-php5.4.3-httpd2.2.22-mysql5.5.24 32位版下載地址:http://www.wampserver.com/en/ ThinkPHP:3.0正式版下載地址:http://th ...
  • 1. delete 用於釋放 new 分配的空間;free 用來釋放 malloc 分配的空間 2. delete [] 用於釋放 new [] 分配的空間 3. delete 釋放空間的時候會調用 相應的析構函數 同時,new時調用構造函數,而malloc不會,它只是分配記憶體。 4. 調用free ...
  • java常量池是一個經久不衰的話題,也是面試官的最愛,題目花樣百出,小菜早就對常量池有所耳聞,這次好好總結一下。 理論 小菜先拙劣的表達一下jvm虛擬記憶體分佈: 程式計數器是jvm執行程式的流水線,存放一些跳轉指令,這個太高深,小菜不懂。 本地方法棧是jvm調用操作系統方法所使用的棧。 虛擬機棧是j ...
  • 上一篇:《 "DDD 領域驅動設計-如何完善 Domain Model(領域模型)?" 》 開源地址: "https://github.com/yuezhongxin/CNBlogs.Apply.Sample" (代碼已更新) 需要註意的是,業務流程並不是工作流程,在領域模型中,業務流程的控制很重要 ...
  • 上篇博客我們系統的介紹了三種工廠模式,今天我們就來介紹一下單例模式。單例模式雖然簡單,但是還是比較重要的,是常用設計模式之一。在之前的博客《Objective-C中的單例模式》中介紹了Objective-C中MRC和ARC下的單例模式。單例模式應該說是設計模式中最為簡單的了,但是簡單並不代表其不重要 ...
  • 職責鏈模式(Chain of Responsibility) 定義 職責鏈模式(Chain of Responsibility),使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關係。將這個對象連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個對象處理它為止。 類圖 描述 Handle ...
  • Atitit. http 代理原理 atiHttpProxy 大木馬 1. 面這張圖可以清晰地闡明HttpProxy的實現原理:1 2. 代理伺服器用途1 3. 其中流程具體如下:2 4. 設計規劃3 5. 結束語4 1. 面這張圖可以清晰地闡明HttpProxy的實現原理: 2. 代理伺服器用途 ...
  • 最近工作需要,用到了RabbitMQ來做消息隊列解耦業務系統,RabbitMQ我就不過多介紹了,我只把安裝過程的備忘粘貼在這裡,供大家參考 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...