主頁 > 軟體設計 > 淺談系統性能提升的經驗和方法

淺談系統性能提升的經驗和方法

2022-12-30 07:37:27 軟體設計

 

 

一、背景

資金核對的資料組裝-執行-應急鏈路,有著千萬級TPS并發量,同時由于資金業務特性,對系統可用性和準確性要求非常高;日常開發程序中會遇到各種各樣的高可用問題,也在不斷地嘗試做一些系統設計以及性能優化,在此期間總結了部分性能優化的經驗和方法,跟大家一起分享和交流,

二、什么是高性能系統

先理解一下什么是高性能設計,官方定義: 高可用(High Availability,HA)核心目標是保障業務的連續性,從用戶視角來看,業務永遠是正常穩定的對外提供服務,業界一般用幾個9來衡量系統的可用性,通常采用一系列專門的設計(冗余、去單點等),減少業務的停工時間,從而保持其核心服務的高度可用性,高并發(High Concurrency)通常是指系統能夠同時并行處理很多請求,一般用回應時間、并發吞吐量TPS, 并發用戶數等指標來衡量,高性能是指程式處理速度非常快,所占記憶體少,CPU占用率低,高性能的指標經常和高并發的指標緊密相關,想要提高性能,那么就要提高系統發并發能力,本文主要對做“高性能、高并發、高可用”服務的設計進行介紹和分享,

三、從哪幾個方面做好性能提升

每次談到高性能設計,經常會面臨幾個名詞:IO多路復用、零拷貝、執行緒池、冗余等等,關于這部分的文章非常的多,其實本質上是一個系統性的問題,可以從計算機體系結構的底層原來去思考,系統優化離不開計算性能(CPU)和存盤性能(IO)兩個維度,總結如下方法:

  • 如何設計高性能計算(CPU)
  • 減少計算成本: 代碼優化計算的時間復雜度O(N^2)->O(N),合理使用同步/異步、限流減少請求次數等;

  • 讓更多的核參與計算: 多執行緒代替單執行緒、集群代替單機等等;

  • 如何提升系統IO
  • 加快IO速度: 順序讀寫代替隨機讀寫、硬體上SSD提升等;

  • 減少IO次數: 索引/分布式計算代替全表掃描、零拷貝減少IO復制次數、DB批量讀寫、分庫分表增加連接數等;

  • 減少IO存盤: 資料過期策略、合理使用記憶體、快取、DB等中間件,做好訊息壓縮等;

四、高性能優化策略

1. 計算性能優化策略

1.1 減少程式計算復雜度

簡單來看這段偽代碼(業務代碼facade做了脫敏)

boolean result = true;
// 回圈遍歷請求的requests, 判斷如果是A業務且A業務未達到終態回傳false, 否則回傳true
for(Requet request: requests){
     // 1. query DB 獲取TestDO
     String id = request.getId();
     TestDO testDO = queryDOById(id);
     // 2. 如果是A業務且testDO未到達中態記錄為false
     if(StringUtils.equals("A", request.getBizType())){
         // check是否到達終態
         if(!StringUtils.equals("FINISHED", testDO.getStatus)){
             result = result && false;
         }
     }
}
return result;

代碼中存在很明顯的幾個問題:

1.每次請求過來在第6行都去查詢DB,但是在第8行對請求做了判斷和篩選,導致第6行的代碼計算資源浪費,而且第6行訪問DAO資料,是一個比較耗時的操作,可以先判斷業務是否屬于A再去查詢DB;

2.當前的需求是只要有一個A業務未到達終態即可回傳false, 11行可以在拿到false之后,直接break,減少計算次數;

優化后的代碼:

boolean result = true;
// 回圈遍歷請求的requests, 判斷如果是A業務且A業務未達到終態回傳false, 否則回傳true
for(Requet request: requests){
// 1. 不是A業務的不走查詢DB的邏輯
if(!StringUtils.equals("A", request.getBizType())){
continue;
     }
     // 2. query DB 獲取TestDO
     String id = request.getId();
     TestDO testDO = queryDOById(id);
     // check是否到達終態
     if(!StringUtils.equals("FINISHED", testDO.getStatus)){
         result = false;
         break;
     }
}
return result;
優化之后的計算耗時從平均270.75ms-->40.5ms

圖片

日常優化代碼可以用ARTHAS工具分析下程式的呼叫耗時,耗時大的任務盡可能做好過濾,減少不必要的系統呼叫,

1.2 合理使用同步異步

分析業務鏈路中,哪些需要同步等待結果,哪些不需要,核心依賴的調度可以同步,非核心依賴盡量異步,

場景:從鏈路上看A系統呼叫B系統,B系統呼叫C系統完成計算再把結論回傳給A,A系統超時時間400ms,通常A系統呼叫B系統300ms,B系統呼叫C系統200ms,

圖片

現在C系統需要將呼叫結論回傳給D系統,耗時150ms

圖片

此時A系統- B系統- C系統已有的呼叫鏈路可能會超時失敗,因為引入D系統之后,耗時增加了150ms,整個程序是同步呼叫的,因此需要C系統將呼叫D系統更新結論的非強依賴改成異步呼叫,

// C系統呼叫D系統更新結果
featureThreadPool.execute(()->{
   try{
      dSystemClient.updateResult(resultDTO);
   }catch (Exception exception){
      LogUtil.error(exception, logger, "dSystemClient.updateResult failed! resultDTO = {0}", JSON.toJSONString(resultDTO));
   }
});

1.3 做好限流保護

故障場景:A系統呼叫B系統查詢例外資料,日常10TPS左右甚至更少,某一天A系統改了定時任務觸發邏輯,加上代碼bug,呼叫頻率達到了500TPS,并且由于ID傳錯,繞過了快取直接查詢了DB和Hbase, 造成了Hbase讀熱點,拖垮集群,存盤和查詢都受到了影響,

圖片

后續對A系統做了查詢限流,保證并發量在15TPS以內,核心業務服務需要做好查詢限流保護,同時也要做好快取設計,

1.4 多執行緒代替單執行緒

場景:應急定位場景下,A系統呼叫B系統獲取診斷結論,TR超時時間是500ms,對于一個例外ID事件,需要執行多個診斷項服務,并記錄診斷流水;每個診斷的耗時大概在100ms以內,隨著業務的增長,超過5個診斷項,計算耗時累加到500ms+,這時候服務會出現高峰期短暫不可用,

圖片

將這段代碼改成異步執行,這樣執行診斷的時間是耗時最大的診斷服務

// 提交future任務并發執行
futures = executor.invokeAll(tasks, timeout, timeUnit);
// 遍歷讀取結果
for (Future<Res> future : futures) {
    try {
        // 獲取結果
        Res singleResult = future.get();
        if (singleResult != null) {
            result.add(singleResult);
        }
    } catch (Exception e) {
        LogUtil.error(e, logger, "并發執行發生例外!,poolName={0}.", threadPoolName);
    }
}
1.5 集群計算代替單機

圖片

這里可以使用三層分發,將計算任務分片后執行,Map-Reduce思想,減少單機的計算壓力,

 

2. 系統IO性能優化策略

2.1 常見的FullGC解決

系統常見的FullGC問題有很多,先講一下JVM的垃圾回識訓制: Heap區在設計上是分代設計的, 劃分為了Eden、Survivor 和 Tenured/Old ,其中Eden區、Survivor(存活)屬于年輕代,Tenured/Old區屬于老年代或者持久代,一般我們將年輕代發生的GC稱為Minor GC,對老年代進行GC稱為Major GC,FullGC是對整個堆來說,

記憶體分配策略:1. 物件優先在Eden區分配 2. 大物件直接進入老年代 3. 長期存活的物件將進入老年代4. 動態物件年齡判定(虛擬機并不會永遠地要求物件的年齡都必須達到MaxTenuringThreshold才能晉升老年代,如果Survivor空間中相同年齡的所有物件的大小總和大于Survivor的一半,年齡大于或等于該年齡的物件就可以直接進入老年代)5. 只要老年代的連續空間大于(新生代所有物件的總大小或者歷次晉升的平均大小)就會進行minor GC,否則會進行full GC,

系統常見觸發FullGC的case:

(1)查詢大物件:業務上歷史巡檢資料需要定期清理,洗掉策略是每天洗掉上個月之前的資料(業務上打上軟洗掉標記),等資料庫定時清理任務徹底回收;

圖片

某一天修改了洗掉策略,從“洗掉上個月之前的資料”改成了“洗掉上周之前的資料”,因此洗掉的資料從1000條膨脹到了15萬條,資料物件占用了80%以上的記憶體,直接導致系統的FullGC, 其他任務都有影響;

圖片

很多系統代碼對于查詢資料沒有數量限制,隨著業務的不斷增長,系統容量在不升級的情況下,經常會查詢出來很多大的物件List,出現大物件頻繁GC的情況,

(2)設定了用不回收的static方法

A系統設定了static的List物件,本身是用來做DRM配置讀取的,但是有個邏輯對配置資訊做了查詢之后,還進行了Put操作,導致隨著業務的增長,static物件越來越大且屬于類物件,無法回收,最終使得系統頻繁GC,

圖片

本身用Object做Map的Key有一定的不合理性,同時key中的物件是不可回收的,導致出現了GC,

當執行Full GC后空間仍然不足,則拋出如下錯誤【java.lang.OutOfMemoryError: Java heap space】,而為避免以上兩種狀況引起的Full GC,調優時應盡量做到讓物件在Minor GC階段被回收、讓物件在新生代多存活一段時間及不要創建過大的物件及陣列,

2.2 順序讀寫代替隨機讀寫

對于普通的機械硬碟而言,隨機寫入的性能會很差,時間久了還會出現碎片,順序的寫入會極大節省磁盤尋址及磁盤盤片旋轉的時間,極大提升性能;這層其實本身中間件幫我們實作了,比如Kafka的日志檔案存盤訊息,就是通過有序寫入訊息和不可變性,訊息追加到檔案的末尾,來保證高性能讀寫,

2.3 DB索引設計

設計表結構時,我們要考慮后期對表資料的查詢操作,設計合理的索引結構,一旦表索引建立好了之后,也要注意后續的查詢操作,避免索引失效,

圖片

 

(1)盡量不選擇鍵值較少的列即區分度不明顯,重復資料很少的做索引;比如我們用is_delete這種列做了索引,查詢10萬條資料,where is_delete=0,有9萬條資料塊,加上訪問索引塊帶來的開銷,不如全表掃描全部的資料塊了;(2)避免使用前導like "%***"以及like "%***%", 因為前面的匹配是模糊的,很難利用索引的順序去訪問資料塊,導致全表掃描;但是使用like "A**%"不影響,因為遇到"B"開頭的資料就可以停止查找列,我們在做根據用戶資訊模糊查詢資料時,遇到了索引失效的情況;

     (3) 其他可能的場景比如,or查詢,多列索引不使用第一部分查詢,查詢條件中有計算操作,或者全表掃描比索引查詢更快的情況下也會出現索引失效;

目前AntMonitor以及Tars等工具已經幫我們掃描出來耗時和耗CPU很大的SQL,可以根據執行計劃調整查詢邏輯,頻繁的少量資料查詢利用好索引,當然建立過多的索引也有存盤開銷,對于插入和洗掉很頻繁的業務,也要考慮減少不必要的索引設計,

2.4 分庫分表設計

圖片

隨著業務的增長,如果集群中的節點數量過多,最侄訓達到資料庫的連接限制,導致集群中的節點數量受限于資料庫連接數,集群節點無法持續增加和擴容,無法應對業務流量的持續增長;這也是螞蟻做LDC架構的其中原因之一,在業務層做水平拆分和擴展,使得每個單元的節點只訪問當前節點對應的資料庫,

2.5 避免大量的表JOIN

阿里編碼規約中超過三個表禁止JOIN,因為三個表進行笛卡爾積計算會出現操作復雜度呈幾何數增長,多個表JOIN時要確保被關聯的欄位有索引,

圖片

如果為了業務上某些資料的級聯,可以適當根據主鍵在記憶體中做嵌套的查詢和計算,操作非常頻繁的流水表建議對部分欄位做冗余,以空間復雜度換取時間復雜度,

 

2.6 減少業務流水表大量耗時計算

業務記錄有時候會做一些count操作,如果對時效性要求不高的統計和計算,建議定時任務在業務低峰期做好計算,然后將計算結果保存在快取,

圖片

涉及到多個表JOIN的建議采用離線表進行Map-Reduce計算,然后再將計算結果回流到線上表進行展示,

圖片

2.7 資料過期策略

一張表的資料量太大的情況下,如果不按照索引和日期進行部分掃描而出現全表掃描的情況,對DB的查詢性能是非常有影響的,建議合理的設計資料過期策略,歷史資料定期放入history表,或者備份到離線表中,減少線上大量資料的存盤,

圖片

2.8 合理使用記憶體

眾所周知,關系型資料庫DB查詢底層是磁盤存盤,計算速度低于記憶體快取,快取DB與業務系統連接有一定的呼叫耗時,速度低于本地記憶體;但是從存盤量來看,記憶體存盤資料容量低于快取,長期持久化的資料建議放DB存在磁盤中,設計程序中考慮好成本和查詢性能的平衡,

圖片

說到記憶體,就會有資料一致性問題,DB資料和記憶體資料如何保證一致性,是強一致性還是弱一致性,資料存盤順序和事務如何控制都需要去考慮,盡量做到用戶無感知,

2.9 做好資料壓縮

很多中間件對資料的存盤和傳輸采用了壓縮和解壓操作,減少資料傳輸中的帶寬成本,這里對資料壓縮不再做過多的介紹,想提的一點是高并發的運行態業務,要合理的控制日志的列印,不能夠為了便于排查,列印過多的JSON.toJSONString(Object),磁盤很容易被打滿,按照日志的容量過期策略也很容易被回收,更不方便排查問題;因此建議合理的使用日志,錯誤碼僅可能精簡,核心業務邏輯列印好摘要日志,結構化的資料也便于后續做監控和資料分析,

列印日志的時候思考幾個問題:這個日志有沒有可能會有人看,看了這個日志能做什么,每個欄位都是必須列印的嗎,出現問題能不能提高排查效率,

2.10 Hbase熱點key問題

HBase是一個高可靠、高性能、面向列、可伸縮的分布式存盤系統,是一種非關系資料庫,Hbase存盤特點如下:1.列的可以動態增加,并且列為空就不存盤資料,節省存盤空間,2.HBase自動切分資料,使得資料存盤自動具有水平scalability,3.HBase可以提供高并發讀寫操作的支持,分布式架構,讀寫鎖等待的概率大大降低,4.不能支持條件查詢,只支持按照Rowkey來查詢,

5.暫時不能支持Master server的故障切換,當Master宕機后,整個存盤系統就會掛掉,

Habse的存盤結構如下:Table在行的方向上分割為多個HRegion,HRegion是HBase中分布式存盤和負載均衡的最小單元,即不同的HRegion可以分別在不同的HRegionServer上,但同一個HRegion是不會拆分到多個HRegionServer上的,HRegion按大小分割,每個表一般只有一個HRegion,隨著資料不斷插入表,HRegion不斷增大,當HRegion的某個列簇達到一個閾值(默認256M)時就會分成兩個新的HRegion,

圖片

HBase 中的行是按照 Rowkey 的字典順序排序的,這種設計優化了 scan 操作,可以將相關的行以及會被一起讀取的行存取在臨近位置,便于scan,Rowkey這種固有的設計是熱點故障的源頭,熱點的熱是指發生在大量的 client 直接訪問集群的一個或極少數個節點(訪問可能是讀,寫或者其他操作),

大量訪問會使熱點 Region 所在的單個機器超出自身承受能力,引起性能下降甚至 Region 不可用,這也會影響同一個 RegionServer 上的其他 Region,由于主機無法服務其他 Region 的請求,這樣就造成資料熱點(資料傾斜)現象,

所以我們在向 HBase 中插入資料的時候,應優化 RowKey 的設計,使資料被寫入集群的多個 region,而不是一個,盡量均衡地把記錄分散到不同的 Region 中去,平衡每個 Region 的壓力,

常見的熱點Key避免的方法: 反轉,加鹽和哈希

  • 反轉:比如用戶ID2088這種前綴,以及BBCRL開頭的這種相同前綴,都可以適當的反轉往后移動,
  • 加鹽: RowKey 的前面增加一些前綴,比如時間戳Hash,加鹽的前綴種類越多,才會根據隨機生成的前綴分散到各個 region 中,避免了熱點現象,但是也要考慮scan方便
  • 哈希:為了在業務上能夠完整地重構 RowKey,前綴不可以是隨機的, 所以一般會拿原 RowKey 或其一部分計算 Hash 值,然后再對 Hash 值做運算作為前綴,

總之Rowkey在設計的程序中,盡量保證長度原則、唯一原則、排序原則、散列原則,

五、實戰-應急鏈路系統設計方案

要保證整體服務的高可用,需要從全鏈路視角去看待高可用系統的設計,這里簡單的分享一個上游多個系統呼叫例外處理系統執行應急的業務場景,分析其中的性能優化改造,

以資金應急系統為例分析系統設計程序中的性能優化,如下圖所示,例外處理系統涉及到多個上游App(1-N),這些App發“差異日志資料”給到訊息佇列, 例外處理系統訂閱并消費訊息佇列中的“錯誤日志資料”,然后對這部分資料進行決議、加工聚合等操作,完成例外的發送及應急處理,

圖片

  • 發送階段高可用設計
  • 生產訊息階段:本地佇列快取例外明細資料,守護執行緒定時拉取并批量發送(優化方案1中單條上報的性能問題)

 

圖片

  • 訊息壓縮發送:例外規則復用用一份組裝的模型,按照規則則Code聚合壓縮上報(優化業務層資料壓縮復用能力)

圖片

  • 中間件幫你做好了訊息的高效序列化機制以及發送的零拷貝技術

  • 存盤階段

  • 目前Kafka等中間件,采用IO多路復用+磁盤順序寫資料的機制,保證IO性能
  • 同時采用磁區分段存盤機制,提升存盤性能

  • 消費階段
  • 定時拉取一段資料批量處理,處理之后上報消費位點,繼續計算

圖片

  • 內部好做資料的冪等控制,發布程序中的抖動或者單機故障保證資料的不重復計算

圖片

  • 為了提升DB的count性能,先用Hbase對例外數量做好累加,然后定時執行緒獲取資料批量update

圖片

  • 為了提升DB的配置查詢性能,首次查詢配置放入本地記憶體存盤20分鐘,資料更新之后記憶體失效

圖片

  • 對于統計類的計算采用explorer存盤,對于非結構化的例外明細采用Hbase存盤,對于結構化且可靠性要求高的例外資料采用OB存盤

圖片

1.然后對系統的性能做好壓測和容量評估,演練資料是例外資料的3-5倍做好流量隔離,對管道進行拆分,消費鏈路的執行緒池做好隔離

圖片

2.對于單點的計算模塊做好冗余和故障轉移, 采取限流等措施

限流能力,上報端采用開關控制限流和熔斷

圖片

故障轉移能力

圖片

3.對于系統內部可以提升的地方,可以參考高可用性能優化策略去逐個突破,

六、高性能設計總結

1. 架構設計

1.1 冗余能力

做好集群的三副本甚至五副本的主動復制,保證全部資料冗余成功場景,任務才可以繼續執行,如果對可用性要求很高,可以降低副本數以及任務的提交一執行約束,

冗余很容易理解,如果一個系統的可用性為90%,兩臺機器的可用性為1-0.1*0.1=99%,機器越多,可用性會更高;對于DB這種對連接數有瓶頸的,我們需要在業務上做好分庫分表也是一種冗余的水平擴展能力,

1.2 故障轉移能力

部分業務場景對于DB的依賴性很高,在DB不可用的情況下,能不能轉移到FO庫或者先中斷現場,保存背景關系,對當前的業務場景背景關系寫入延遲佇列,等故障恢復后再對資料進行消費和計算,

有些不可抗力和第三方問題,可能會嚴重影響整個業務的可用性,因此要做好異地多話,冗余災備以及定期演練,

1.3 系統資源隔離性

在例外處理的case中,經常會因為上游資料的大量上報導致佇列阻塞,影響時效性,因此可以做好核心業務和非核心業務資源隔離,對于秒殺類的場景甚至可以單獨部署獨立的集群支撐業務,

如果A系統可用性90%,B系統的可用性40%,A系統某服務強依賴B系統,那么A系統的可用性為P(A|B), 可用性大大降低,

 

2. 事前防御

2.1 做好監控

對系統的CPU,執行緒CE、IO、服務呼叫TPS、DB計算耗時等設定合理的監控閾值,發現問題及時應急

2.2 做好限流/熔斷/降級等

上游業務流量突增的場景,需要有一定的自我保護和熔斷機制,前提是避免業務的強依賴,解決單點問題,在例外消費鏈路中,對上游做了DRM管控,下游也有一定的快速泄洪能力,防止因為單業務例外拖垮整個集群導致不可用,

瞬間流量問題很容易引發故障,一定要做好壓測和熔斷能力,秒殺類的業務減少對核心系統的強依賴,提前做好預案管控,對于快取的雪崩等也要有一定的預熱和保護機制,

同時有些業務開放了不合理的介面,采用爬蟲等大量請求web介面,也要有識別和熔斷的能力

2.3 提升代碼質量

核心業務在大促期間做好封網、資金安全提前部署核對主動驗證代碼的可靠性,編碼符合規范等等,都是避免線上問題的防御措施;

代碼的FullGC, 記憶體泄漏都會引發系統的不可用,尤其是業務低峰期可能不明顯,業務流量高的情況下性能會惡化,提前做好壓測和代碼Review,

 

3. 事后防御和恢復

事前做好可監控和可灰度,事后做好任何場景下的故障可回滾,

其他關于防御能力的還有:部署程序中如何做好代碼的平滑發布,問題代碼機器如何快速地摘流量;上下游系統呼叫的發布,如何保證依賴順序;發布程序中,正常的業務已經在發布過的代碼中執行,逆向操作在未發布的機器中執行,如何保證業務一致性,都要有充分的考慮,

   作者:單光旭(光旭)

本文來自博客園,作者:古道輕風,轉載請注明原文鏈接:https://www.cnblogs.com/88223100/p/Experience-and-method-of-improving-system-performance.html

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/540951.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