主頁 > 軟體設計 > 10W+字C語言硬核總結(三),值得閱讀收藏!

10W+字C語言硬核總結(三),值得閱讀收藏!

2021-07-30 08:11:12 軟體設計

1、位運算

可以使用 C 對變數中的個別位進行操作,您可能對人們想這樣做的原因感到奇怪,這種能力有時確實是必須的,或者至少是有用的,C 提供位的邏輯運算子和移位運算子,在以下例子中,我們將使用二進制計數法寫出值,以便您可以了解對位發生的操作,在一個實際程式中,您可以使用一般的形式的整數變數或常量,例如不適用 00011001 的形式,而寫為 25 或者 031 或者 0x19.在我們的例子中,我們將使用8位數字,從左到右,每位的編號是 7 到 0,

10W+字C語言硬核總結(一),值得閱讀收藏!

10W+字C語言硬核總結(二),值得閱讀收藏!

程式員必備硬核資源,點擊下載!

1.1 位邏輯運算子

4 個位運算子用于整型資料,包括 char,將這些位運算子成為位運算的原因是它們對每位進行操作,而不影響左右兩側的位,請不要將這些運算子與常規的邏輯運算子(&& 、||和!)相混淆,常規的位的邏輯運算子對整個值進行操作,

1.1.1 按位取反~

一元運算子~將每個 1 變為 0,將每個 0 變為 1,如下面的例子:

~(10011010)
01100101

假設 a 是一個unsigned char,已賦值為 2,在二進制中,2 是00000010.于是 -a 的值為11111101或者 253,請注意該運算子不會改變 a 的值,a 仍為 2,

unsigned char a = 2;   //00000010
unsigned char b = ~a;  //11111101
printf("ret = %d\n", a); //ret = 2
printf("ret = %d\n", b); //ret = 253

1.1.2 位與(AND): &

二進制運算子 & 通過對兩個運算元逐位進行比較產生一個新值,對于每個位,只有兩個運算元的對應位都是 1 時結果才 為 1,

(10010011) & (00111101) = (00010001)

C 也有一個組合的位與-賦值運算子:&=,下面兩個將產生相同的結果:

val &= 0377
val = val & 0377

1.1.3 位或(OR): |

二進制運算子 | 通過對兩個運算元逐位進行比較產生一個新值,對于每個位,如果其中任意運算元中對應的位為 1,那么結果位就為 1,

(10010011)| (00111101) = (10111111)

C 也有組合位或-賦值運算子: |=

val |= 0377
val = val | 0377

**1.1.4 位異或: **

二進制運算子^對兩個運算元逐位進行比較,對于每個位,如果運算元中的對應位有一個是 1(但不是都是1),那么結果是 1.如果都是 0 或者都是 1,則結果位 0,

(10010011)^ (00111101) = (10101110)

C 也有一個組合的位異或 - 賦值運算子: ^=

val ^= 0377
val = val ^ 0377

1.1.5 用法

1.1.5.1 打開位

已知:10011010:

1.將位 2 打開

flag | 10011010

(10011010)|(00000100)=(10011110)

2.將所有位打開

flag | ~flag

(10011010)|(01100101)=(11111111)

1.1.5.2 關閉位

flag & ~flag

(10011010)&(01100101)=(00000000)

1.1.5.3 轉置位

轉置(toggling)一個位表示如果該位打開,則關閉該位;如果該位關閉,則打開,您可以使用位異或運算子來轉置,其思想是如果 b 是一個位(1或0),那么如果 b 為 1 則 b^1 為 0,如果 b 為 0,則 1^b 為 1,無論 b 的值是 0 還是 1,0^b 為 b,

flag ^ 0xff

(10010011)^(11111111)=(01101100)

1.1.5.4 交換兩個數不需要臨時變數

//a ^ b = temp;
//a ^ temp = b;
//b ^ temp = a
 (10010011)^(00100110)=(10110101)
 (10110101)^(00100110)= 10010011
 
  int a = 10;
  int b = 30;

1.2 移位運算子

現在讓我們了解一下 C 的移位運算子,移位運算子將位向左或向右移動,同樣,我們仍將明確地使用二進制形式來說明該機制的作業原理,

1.2.1 左移 <<

左移運算子<<將其左側運算元的值的每位向左移動,移動的位數由其右側運算元指定,空出來的位用 0 填充,并且丟棄移出左側運算元末端的位,在下面例子中,每位向左移動兩個位置,

(10001010) << 2 = (00101000)

該操作將產生一個新位置,但是不改變其運算元,

1 << 1 = 2;
2 << 1 = 4;
4 << 1 = 8;
8 << 2 = 32

左移一位相當于原值 *2,

1.2.2 右移 >>

右移運算子>>將其左側的運算元的值每位向右移動,移動的位數由其右側的運算元指定,丟棄移出左側運算元有段的位,對于unsigned型別,使用 0 填充左端空出的位,對于有符號型別,結果依賴于機器,空出的位可能用 0 填充,或者使用符號(最左端)位的副本填充,

//有符號值
(10001010) >> 2
(00100010)     //在某些系統上的結果值

(10001010) >> 2
(11100010)     //在另一些系統上的結果

//無符號值
(10001010) >> 2
(00100010)    //所有系統上的結果值

1.2.3 用法:移位運算子

移位運算子能夠提供快捷、高效(依賴于硬體)對 2 的冪的乘法和除法,

number << n: number乘以2的n次冪

number >> n: 如果number非負,則用number除以2的n次冪

程式員必備硬核資源,點擊下載!

2、陣列

2.1 一維陣列

  • 元素型別角度:陣列是相同型別的變數的有序集合

  • 記憶體角度:連續的一大片記憶體空間

在討論多維陣列之前,我們還需要學習很多關于一維陣列的知識,首先讓我們學習一個概念,

2.1.1 陣列名

考慮下面這些宣告:

int a;
int b[10];

我們把 a 稱作標量,因為它是個單一的值,這個變數是的型別是一個整數,我們把 b 稱作陣列,因為它是一些值的集合,下標和數名一起使用,用于標識該集合中某個特定的值,例如,b[0] 表示陣列 b 的第 1 個值,b[4] 表示第 5 個值,每個值都是一個特定的標量,

那么問題是 b 的型別是什么?它所表示的又是什么?一個合乎邏輯的答案是它表示整個陣列,但事實并非如此,在 C中,在幾乎所有陣列名的運算式中,陣列名的值是一個指標常量,也就是陣列第一個元素的地址,它的型別取決于陣列元素的型別:如果他們是int型別,那么陣列名的型別就是“指向 int 的常量指標”;如果它們是其他型別,那么陣列名的型別也就是“指向其他型別的常量指標”,

請問:指標和陣列是等價的嗎?

答案是否定的,陣列名在運算式中使用的時候,編譯器才會產生一個指標常量,那么陣列在什么情況下不能作為指標常量呢?在以下兩種場景下:

  • 當陣列名作為sizeof運算子的運算元的時候,此時sizeof回傳的是整個陣列的長度,而不是指標陣列指標的長度,

  • 當陣列名作為&運算子的運算元的時候,此時回傳的是一個指向陣列的指標,而不是指向某個陣列元素的指標常量,

int arr[10];
//arr = NULL; //arr作為指標常量,不可修改
int *p = arr; //此時arr作為指標常量來使用
printf("sizeof(arr):%d\n", sizeof(arr)); //此時sizeof結果為整個陣列的長度
printf("&arr type is %s\n", typeid(&arr).name()); //int(*)[10]而不是int*

2.1.2 下標參考

int arr[] = { 1, 2, 3, 4, 5, 6 };

*(arr + 3) ,這個運算式是什么意思呢?

首先,我們說陣列在運算式中是一個指向整型的指標,所以此運算式表示 arr 指標向后移動了 3 個元素的長度,然后通過間接訪問運算子從這個新地址開始獲取這個位置的值,這個和下標的參考的執行程序完全相同,所以如下運算式是等同的:

*(arr + 3)
arr[3]

問題1:陣列下標可否為負值?

問題2:請閱讀如下代碼,說出結果:

int arr[] = { 5, 3, 6, 8, 2, 9 };
int *p = arr + 2;
printf("*p = %d\n", *p);
printf("*p = %d\n", p[-1]);

那么是用下標還是指標來操作陣列呢?對于大部分人而言,下標的可讀性會強一些,

2.1.3 陣列和指標

指標和陣列并不是相等的,為了說明這個概念,請考慮下面兩個宣告:

int a[10];
int *b;

宣告一個陣列時,編譯器根據宣告所指定的元素數量為陣列分配記憶體空間,然后再創建陣列名,指向這段空間的起始位置,宣告一個指標變數的時候,編譯器只為指標本身分配記憶體空間,并不為任何整型值分配記憶體空間,指標并未初始化指向任何現有的記憶體空間,

因此,運算式 *a 是完全合法的,但是運算式 *b 卻是非法的,*b 將訪問記憶體中一個不確定的位置,將會導致程式終止,另一方面b++可以通過編譯,a++ 卻不行,因為a是一個常量值,

2.1.4 作為函式引數的陣列名

當一個陣列名作為一個引數傳遞給一個函式的時候發生什么情況呢?

我們現在知道陣列名其實就是一個指向陣列第 1 個元素的指標,所以很明白此時傳遞給函式的是一份指標的拷貝,所以函式的形參實際上是一個指標,但是為了使程式員新手容易上手一些,編譯器也接受陣列形式的函式形參,因此下面兩種函式原型是相等的:

int print_array(int *arr);
int print_array(int arr[]);

我們可以使用任何一種宣告,但哪一個更準確一些呢?答案是指標,因為實參實際上是個指標,而不是陣列,同樣 sizeof arr 值是指標的長度,而不是陣列的長度,

現在我們清楚了,為什么一維陣列中無須寫明它的元素數目了,因為形參只是一個指標,并不需要為陣列引數分配記憶體,另一方面,這種方式使得函式無法知道陣列的長度,如果函式需要知道陣列的長度,它必須顯式傳遞一個長度引數給函式,

2.2 多維陣列

如果某個陣列的維數不止1個,它就被稱為多維陣列,接下來的案例講解以二維陣列舉例,

void test01(){
 //二維陣列初始化
 int arr1[3][3] = {
  { 1, 2, 3 },
  { 4, 5, 6 },
  { 7, 8, 9 }
 };
 int arr2[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
 int arr3[][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

 //列印二維陣列
 for (int i = 0; i < 3; i++){
  for (int j = 0; j < 3; j ++){
   printf("%d ",arr1[i][j]);
  }
  printf("\n");
 }
}

2.2.1 陣列名

一維陣列名的值是一個指標常量,它的型別是“指向元素型別的指標”,它指向陣列的第 1 個元素,多維陣列也是同理,多維陣列的陣列名也是指向第一個元素,只不過第一個元素是一個陣列,例如:

int arr[3][10]

可以理解為這是一個一維陣列,包含了 3 個元素,只是每個元素恰好是包含了 10 個元素的陣列,arr 就表示指向它的第1個元素的指標,所以 arr 是一個指向了包含了 10 個整型元素的陣列的指標,

2.2.2 指向陣列的指標(陣列指標)

陣列指標,它是指標,指向陣列的指標,

陣列的型別由元素型別和陣列大小共同決定:int array[5] 的型別為 int[5]

C 語言可通過 typedef 定義一個陣列型別:

定義陣列指標有一下三種方式:

//方式一
void test01(){

 //先定義陣列型別,再用陣列型別定義陣列指標
 int arr[10] = {1,2,3,4,5,6,7,8,9,10};
 //有typedef是定義型別,沒有則是定義變數,下面代碼定義了一個陣列型別ArrayType
 typedef int(ArrayType)[10];
 //int ArrayType[10]; //定義一個陣列,陣列名為ArrayType

 ArrayType myarr; //等價于 int myarr[10];
 ArrayType* pArr = &arr; //定義了一個陣列指標pArr,并且指標指向陣列arr
 for (int i = 0; i < 10;i++){
  printf("%d ",(*pArr)[i]);
 }
 printf("\n");
}

//方式二
void test02(){

 int arr[10];
 //定義陣列指標型別
 typedef int(*ArrayType)[10];
 ArrayType pArr = &arr; //定義了一個陣列指標pArr,并且指標指向陣列arr
 for (int i = 0; i < 10; i++){
  (*pArr)[i] = i + 1;
 }
 for (int i = 0; i < 10; i++){
  printf("%d ", (*pArr)[i]);
 }
 printf("\n");

}

//方式三
void test03(){
 
 int arr[10];
 int(*pArr)[10] = &arr;

 for (int i = 0; i < 10; i++){
  (*pArr)[i] = i + 1;

 }
 for (int i = 0; i < 10; i++){
  printf("%d ", (*pArr)[i]);
 }
 printf("\n");
}

2.2.3 指標陣列(元素為指標)

2.2.3.1 堆疊區指標陣列

//陣列做函式函式,退化為指標
void array_sort(char** arr,int len){

 for (int i = 0; i < len; i++){
  for (int j = len - 1; j > i; j --){
   //比較兩個字串
   if (strcmp(arr[j-1],arr[j]) > 0){
    char* temp = arr[j - 1];
    arr[j - 1] = arr[j];
    arr[j] = temp;
   }
  }
 }

}

//列印陣列
void array_print(char** arr,int len){
 for (int i = 0; i < len;i++){
  printf("%s\n",arr[i]);
 }
 printf("----------------------\n");
}

void test(){
 
 //主調函式分配記憶體
 //指標陣列
 char* p[] = { "bbb", "aaa", "ccc", "eee", "ddd"};
 //char** p = { "aaa", "bbb", "ccc", "ddd", "eee" }; //錯誤
 int len = sizeof(p) / sizeof(char*);
 //列印陣列
 array_print(p, len);
 //對字串進行排序
 array_sort(p, len);
 //列印陣列
 array_print(p, len);
}

2.2.3.2 堆區指標陣列

//分配記憶體
char** allocate_memory(int n){
 
 if (n < 0 ){
  return NULL;
 }

 char** temp = (char**)malloc(sizeof(char*) * n);
 if (temp == NULL){
  return NULL;
 }

 //分別給每一個指標malloc分配記憶體
 for (int i = 0; i < n; i ++){
  temp[i] = malloc(sizeof(char)* 30);
  sprintf(temp[i], "%2d_hello world!", i + 1);
 }

 return temp;
}

//列印陣列
void array_print(char** arr,int len){
 for (int i = 0; i < len;i++){
  printf("%s\n",arr[i]);
 }
 printf("----------------------\n");
}

//釋放記憶體
void free_memory(char** buf,int len){
 if (buf == NULL){
  return;
 }
 for (int i = 0; i < len; i ++){
  free(buf[i]);
  buf[i] = NULL;
 }

 free(buf);
}

void test(){
 
 int n = 10;
 char** p = allocate_memory(n);
 //列印陣列
 array_print(p, n);
 //釋放記憶體
 free_memory(p, n);
}

2.2.4二維陣列三種引數形式

2.2.4.1 二維陣列的線性存盤特性

void PrintArray(int* arr, int len){
 for (int i = 0; i < len; i++){
  printf("%d ", arr[i]);
 }
 printf("\n");
}

//二維陣列的線性存盤
void test(){
 int arr[][3] = {
  { 1, 2, 3 },
  { 4, 5, 6 },
  { 7, 8, 9 }
 };

 int arr2[][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
 int len = sizeof(arr2) / sizeof(int);

 //如何證明二維陣列是線性的?
 //通過將陣列首地址指標轉成Int*型別,那么步長就變成了4,就可以遍歷整個陣列
 int* p = (int*)arr;
 for (int i = 0; i < len; i++){
  printf("%d ", p[i]);
 }
 printf("\n");

 PrintArray((int*)arr, len);
 PrintArray((int*)arr2, len);
}

2.2.4.2 二維陣列的3種形式引數

//二維陣列的第一種形式
void PrintArray01(int arr[3][3]){
 for (int i = 0; i < 3; i++){
  for (int j = 0; j < 3; j++){
   printf("arr[%d][%d]:%d\n", i, j, arr[i][j]);
  }
 }
}

//二維陣列的第二種形式
void PrintArray02(int arr[][3]){
 for (int i = 0; i < 3; i++){
  for (int j = 0; j < 3; j++){
   printf("arr[%d][%d]:%d\n", i, j, arr[i][j]);
  }
 }
}

//二維陣列的第二種形式
void PrintArray03(int(*arr)[3]){
 for (int i = 0; i < 3; i++){
  for (int j = 0; j < 3; j++){
   printf("arr[%d][%d]:%d\n", i, j, arr[i][j]);
  }
 }
}

void test(){
 
 int arr[][3] = { 
  { 1, 2, 3 },
  { 4, 5, 6 },
  { 7, 8, 9 }
 };
 
 PrintArray01(arr);
 PrintArray02(arr);
 PrintArray03(arr);
}

2.3總結

2.3.1 編程提示

  • 源代碼的可讀性幾乎總是比程式的運行時效率更為重要

  • 只要有可能,函式的指標形參都應該宣告為 const,

  • 在多維陣列的初始值串列中使用完整的多層花括號提高可讀性

2.3.2 內容總結

在絕大多數運算式中,陣列名的值是指向陣列第 1 個元素的指標,這個規則只有兩個例外,sizeof 和對陣列名&,

指標和陣列并不相等,當我們宣告一個陣列的時候,同時也分配了記憶體,但是宣告指標的時候,只分配容納指標本身的空間,

當陣列名作為函式引數時,實際傳遞給函式的是一個指向陣列第 1 個元素的指標,

我們不單可以創建指向普通變數的指標,也可創建指向陣列的指標,

程式員必備硬核資源,點擊下載

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

標籤:其他

上一篇:高等數學:微分、積分物理以及幾何意義

下一篇:本科剛畢業有點迷茫,想入門單片機,應該怎么開始?

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

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more