BUAA_OO_U1_Summary

来源:https://www.cnblogs.com/Ylog1000/archive/2022/04/30/16211517.html
-Advertisement-
Play Games

前言 所謂軟體過程模型就是一種開發策略,這種策略針對軟體工程的各個階段提供了一套範形,使工程的進展達到預期的目的。對一個軟體的開發無論其大小,我們都需要選擇一個合適的軟體過程模型,這種選擇基於項目和應用的性質、採用的方法、需要的控制,以及要交付的產品的特點。一個錯誤模型的選擇,將迷失我們的開發方向。 ...


BUAA_OO_U1_Summary

由於本人廢話比較多,所以提供一個目錄

BUAA_OO_U1_Summary一 / 架構設計1.0> 題目解析1.1> HW51.1.1> 做法分析1.1.2> 獲取請求1.1.3> 請求分配1.1.4> 電梯調度1.1.5> 托盤(緩衝區)1.1.6> 輸出1.1.7> 類圖1.2> HW61.2.1> 迭代開發1.2.2> 請求分配 1.3.3> 橫向電梯調度1.3.4> 類圖1.3> HW71.3.1> 迭代開發1.3.2> 請求拆解1.3.3> 請求分配1.3.4> 電梯調度1.3.5> 如何結束1.3.6> 架構圖1.4> 順序圖二 / 捉蟲大戰2.1> 自測bug2.2> 互測bug三 / 度量分析3.1> 代碼長度3.2> 複雜度分析四 / 心得體會

一 / 架構設計

1.0> 題目解析

  1. 有人要坐電梯

  2. 電梯要儘量快的把他們送到目的地

  3. 電梯有豎向的,也有環形的,環形電梯有可到達樓座的限制

1.1> HW5

1.1.1> 做法分析

我們現在有電梯和很多在一定時間和一定地點出現的有一定需求的乘客。需要做的就是在電梯不超載的前提下儘量快速地完成所有人的請求。

而根據訓練所給出的兩種設計模式的提示,本人首先利用了大量時間學習生產-消費者模式,並嘗試思考出如何進行第五次作業的編碼。這個過程歷時過長,導致最後留給調試的時間不多,只是將將通過了中弱測,併在強測迎來了慘死,當然,這是後話了。

為了套用這個生產-消費者模式,首先需要解決的問題是誰是生產者誰又是消費者,他們在生產什麼又在消費什麼

一開始本人以為生產消費針對電梯上面的空位,人下電梯則空位是被生產,人上電梯則空位被消費。但是轉念一想,發現了問題。如果人乘客電梯,那麼乘客是消費者,電梯是生產者。但如果乘客下電梯了,電梯是消費者,乘客是生產者,角色並不固定,並不能利用此設計模式進行編碼。很顯然,對於這個被生產消費的物品,本人選錯了。

那我們繼續來觀察整個電梯運行事件中出現又消失了的事件——乘客的需求。在這樣的條件下,生產者固定,為到達電梯口想要從這裡出發去別的樓層的乘客;消費者固定,為運輸這個乘客到達目的地,滿足其需求的電梯。所以,我們的代碼需要做的事情就是在乘客輸入請求後,把請求分配電梯,讓電梯處理請求。這三件事,即整個代碼中要用到的三個線程,串其這三條線程,貫穿於整個程式之中的,便是裝有請求的托盤,而用於按時間戳遞增的順序輸出信息的,便是線程安全輸出類

1.1.2> 獲取請求

讀入線程。我們只需要把乘客的請求讀入,放上托盤。

這個線程設計到的難點是,如何在輸入停止後,通知另外兩個線程沒有新請求了,大家處理完手頭的任務就可以下班跑路了一事,即線程結束的問題。這裡的方法在訓練的代碼中有詳細的指導,於是本人便毫不猶豫地將其搬了過來,大概思路為:如果當前讀入表示沒有新的請求,則將所有的電梯待處理隊列的狀態設為結束態。當電梯的處理隊列為空且狀態為結束態時,直接退出線程。

1.1.3> 請求分配

分配器線程。我們需要把乘客的請求分類,分發給不同的電梯處理。

在此次作業中,有5棟獨立的樓,裡面分別由一個電梯,於是這個分配器需要做的事情就是把每個請求扔到對應的樓座里的電梯那裡。在當前這個每個電梯互相獨立互不幹擾的前提下,此線程的實現並沒有什麼難點和需要註意的地方。

1.1.4> 電梯調度

電梯線程。我們需要讓電梯跑起來,去接每個乘客從自己的起始地點開始上電梯,到達自己的目的地,出電梯。

這裡是本次作業中最難最難最難的部分,本人幾乎所有的時間都利用在思考如何編寫這個電梯的調度上了。畢竟,我可以讓我的電梯每次指處理一個請求,然後享受RTLE的洗禮,並繼續硬著頭皮思考如何調度電梯。在當時較為絕望的境況下,本人並不能夠理解ALS的調度方法中的主請求是如何被設置併在代碼中實現這一點,也未能相處如何編寫在大量往屆學長學姐的博客中撲騰到的LOOK演算法,但本人並沒有放棄,而是利用了三天時間仔細的和自己講述、辯論,並編寫、調試。在此非常樂意記錄一下自己的分析過程。

抽象來看,所有的調度不過是狀態的轉換。從乘客的請求方面,有未進電梯(請求等待)、進入電梯(處理請求中)和出電梯(完成請求)三個狀態;從電梯的運行方面,有原地等待(等待請求),接人(獲得請求),運行(處理請求),開/關門這四個狀態。對這些狀態如何互相轉化進行設計,形成一個狀態機,則電梯就可以完成基本的運作了。

《狀態機》

而調度的關鍵在於接人的順序,這也是所有演算法著重處理的地方。

本人的想法很貪心,但是是沒有被證明過的那種(應該可以證明有更優解但我並沒有仔細思考),可能更加貼近LOOK一些:

  • 電梯在等待狀態下:

    • 選擇出發樓層距離1層和10層位置最近的請求(為了一趟多接一些人)

    • 滿足上條的情況下,選擇出發樓層距離電梯當前位置最近的請求

    • 滿足上條的情況下,選擇目的樓層距出發樓層最近的請求(為了一趟多接一些人)

    • 如果沒有這樣的請求,則繼續等待

  • 電梯在上行狀態下:

    • 選擇移動方向為上行的請求

    • 滿足上條的情況下,選擇出發樓層不低於當前電梯所在樓層的請求

    • 滿足上條的情況下,選擇目的樓層距出發樓層最近的請求

    • 如果沒有這樣的請求,則繼續上行,完成當前的請求

  • 電梯在下行的狀態下:

    • 選擇移動方向為下行的請求

    • 滿足上條的情況下,選擇出發樓層不高於當前電梯

    • 滿足上條的情況下,選擇目的樓層距出發樓層最近的請求

    • 如果沒有這樣的請求,則繼續下行,完成當前的請求

但是,必須承認的一點是,其性能分比較糟糕。

但是,只有這樣一個方案,對於最終形成代碼依舊有一定困難:比如,代碼在什麼時候進行這個狀態的檢測並去詢問有沒有可以捎帶的人呢?所以,更詳細來說:

  • 電梯初始為等待狀態

  • 按規則獲取請求

  • 得到請求

    • 到達請求的起始層

    • 若電梯未滿,按規則獲取新的請求

    • 得到新的請求

      • 向著當前新的請求的起始層移動

      • 若電梯未滿,按規則獲取新的請求

      • 每次移動一層

      • 到達樓層的時候判斷是否有請求要出電梯 / 進電梯

      • 後出後進,先下後上,弘揚中華民族的傳統美德(為了保證不超人數)

    • 沒有新的請求則直接處理當前請求

  • 沿當前方向繼續按層運行,到電梯中所有人都出去為止

  • 電梯狀態再次設為等待

上面的流程不斷重覆,直到獲得了等待隊列為空且沒有新的請求了的信號,則退出線程,結束電梯的調度任務。

1.1.5> 托盤(緩衝區)

在生產-消費者模式中,形象化描述起來就是托盤;換成操作系統就可以稱作臨界區,在本人的代碼中,被稱為緩衝區

這個部分的難點在於需要避免數據競爭,保證線程安全,因為緩衝區涉及到乘客請求的放入和分配器對請求的拿取。所以對於所有在緩衝區內的方法,都需要加鎖,防止多個線程交錯調用產生各種各樣的不安全行為。在這裡,由於本人沒有使用一些保證了部分存取方法安全的容器類型,而是直接使用了ArrayList,所以對於所有方法都添加了sychronized關鍵字。

同時,在本人的托盤中存在一個最大容量的屬性。當托盤中存儲的請求到達了這一最大值,會讓當前放入托盤的動作進入等待狀態,待請求被取走一些再繼續放入。其目的是為了催促消費者即電梯不要堆積任務,儘快完成,理論上聽起來有些作用,但在實際測試中對於提升效率的用處並不大。

1.1.6> 輸出

保證時間戳遞增的輸出方法。

一開始本人並沒有單獨的輸出類。但是在第五次強測結果出來並獲得了時間戳不遞增的結果之後,本人悔改了。時間戳不遞增的問題在本地從未出現過,但是多線程同時輸出,難免會有不安全的問題,所以確實需要一個為了保證線程安全的輸出方法。解決方法很簡單,只需要對這個被多個線程調用的輸出方法加上sychronized修飾即可。

1.1.7> 類圖

 

相對於第一單元的作業,這個架構相對更加清晰一些。

可以看出,代碼由主類、讀入線程(生產者)、調度器、緩衝區、消費者、安全輸出類構成。

Main:負責創建緩衝區,併在此基礎上創建讀入、調度器、消費者線程。 Request:包裝一個請求。後來在互測的時候才意識到,可以直接繼承官方包裡面的類,使用其中的方法,不用自己再單獨寫一個。 Allocator:分配器,按樓座為各個消費者分配緩衝區內的請求。 MyBuffer:緩衝區,內部設有put和get方法,用於存放所有請求,同時也可以作為一個用來存放請求的容器被使用。 Producer:生產者,即讀入線程,用於讀取輸入的請求並put進緩衝區;同時在讀入結束時發出結束線程的信號。 Consumer:消費者,即電梯,內部設置有電梯的運行方式即各個電梯狀態下應該有的行為。 Output:線程安全輸出類。

1.2> HW6

1.2.1> 迭代開發

在這次作業中,新增了環形電梯。但是即使有了環形電梯,由於題目限制,我們依舊可以認為每個樓座互相獨立,同樣的,每層樓也互相獨立。環形電梯與縱向電梯之間也互相獨立。所以,環形電梯除了可以環形運動以外,和第五次作業並無太大區別。

所以,題目新增的需求要求我們從兩個方面對第五次作業的代碼進行迭代更新:請求的分配橫向電梯的調度

1.2.2> 請求分配

首先,對橫向的請求和縱向的請求,這種區分還是很明顯的,此處就不加以贅述了。

這裡的請求分配重在如何把請求分配給同一層 / 同一樓座中的多座電梯中。指導書提供的思路是按餘數進行平均分配。本人一開始採取了隨機分配的方法,但交到評測姬中發現時間都非常慢,於是後來換成了向等待隊列最短的電梯中放入請求。原因主要在於,這樣比較好實現。在第五次作業的時候,本人也暢想過自由競爭的實現方法,但是真正到了需要實現的時候,卻並不能形成一個很清晰的思路(但從互測時的觀察來看,自由競爭確實快了很多);同樣的,還有提前預估各部電梯處理完手頭的請求需要的時長,根據時長的長短分配請求的做法,也需要較強的程設能力和清晰的思維,對於本人這種周六才解決完RTLE的蒟蒻來說實在是沒有時間思考了。

1.3.3> 橫向電梯調度

其實對於橫向電梯,和縱向電梯並無太大區別,主要需要解決的問題就是怎麼轉圈。

本人的公式推導在六作業中是有誤的,導致電梯可能會選擇更長的一側(如從C到A選擇CDEA的路徑)運行,使得性能分不太好看。後來再次破環成鏈,重新推導了一遍,得到了正確的公式(Q:clockWise;C:counterClockWise):

((st - nd + 5) % 5 > (nd - st + 5) % 5 ? 'Q' : 'C');

而至於處理請求的順序,和前文提到的縱向電梯別無二致,在此也不再重覆了。

1.3.4> 類圖

 

Main:負責創建緩衝區,併在此基礎上創建讀入、調度器、消費者線程。 MyRequest:為了不和官方包撞名字,所以改成了MyRequest,直接繼承了官方包提供的PersonRequest,但是增加了一些對於請求運動方向、請求的狀態等屬性的記錄。 Allocator:分配器,按樓座為各個消費者分配緩衝區內的請求。 MyBuffer:緩衝區,內部設有put和get方法,用於存放所有請求,同時也可以作為一個用來存放請求的容器被使用。 Producer:生產者,即讀入線程,用於讀取輸入的請求並put進緩衝區;同時在讀入結束時發出結束線程的信號。 Consumer:消費者,即電梯,內部設置有電梯的開關門和達到樓層的行為。 Lift:縱向電梯,設計單獨的縱向電梯運行方法。 Belt:環形電梯,名字取材於機場里可見的自動人行道電梯或者說傳送帶一類的平面傳輸裝置,設計單獨的環形電梯運行方法。 Output:線程安全輸出類。

 

1.3> HW7

1.3.1> 迭代開發

本次作業中,為了完成一個請求,乘客可能需要換乘了。並且,環形電梯對可到達的樓座進行了設置。

所以,題目新增的需求依舊要求我們從兩個方面對第六次作業的代碼進行迭代更新:請求的分配橫向電梯的調度

但是在分配請求之前,多了一個拆解請求的問題。

1.3.2> 請求拆解

奔著不求性能分只求過的心態,本人直接進行了一個圖論的撰寫。

一開始想用floyd,後來發現一開始設計的時候維度設計錯了又換成了dijkstra,等維度設計對了又懶得換回floyd了。不過數據量較小,所以跑最短路速度還能忍。

本人的做法很暴力也很靜態。首先,是建圖的環節。由於有5個樓座和10個樓層,於是我們將A座1層映射為1,A座2層映射為2,B座一層映射為11,以此類推,公式即為:(building - 'A') * 10 + floor;。對於可以到達的樓層,則根據該電梯的容量和運行速度屬性加權建邊(所以是靜態的,這裡的權重蒟蒻也沒能好好設計,所以可能浪費了很多性能)。然後便是跑最短路的過程,是一個非常普通的dijkstra,但是其中每次進行鬆弛操作的時候都需要記錄路徑,以便獲得最短路徑的具體行走方法,用於最終獲得請求的拆解結果。

請求拆解的結果是,所有分請求必須按順序執行,但保證每個分請求的[起點座 == 終點座] + [起點層 == 終點層] == 1,這樣對於之前的請求分配和調度演算法改動最小(適合比較懶的蒟蒻,不適合喜歡性能分的大佬)。

所以,可以看到以前單個請求的存儲方式不再能滿足這個設計了。本人改用了請求序列來存放一個讀入的請求被拆解的結果,但是每次只處理改隊列的隊首請求,然後依次處理後續請求,每處理完畢則刪除,直至清空整個隊列。

1.3.3> 請求分配

這裡和上一次作業的區別在於,眾多電梯中需要挑出那些個能運送這個請求的電梯,否則就會像本人一樣失去強測的分數。

所以,先特判出能送這個乘客的電梯,然後再選擇等待隊列最短的電梯,放入這個請求。

1.3.4> 電梯調度

由於本人的實現方法,在獲得請求的時候就已經把請求拆解成為可以套用第六次作業的調度方法來處理的請求了,所以第七次作業中的電梯調度沒有做新的修改。

但是這樣的風險非常大,最後得到的性能分也是兩極分化嚴重。

1.3.5> 如何結束

在本次作業中,由於一個請求可能對應一個有多項的請求序列,所以需要更加註意的地方是如何判斷當前的所有請求都被處理完了,以結束當前電梯的線程,同時保證線程結束時沒有人還在等待換乘或還卡在電梯里沒能到達目的地。這裡本人選用了上機中提供的代碼使用的信號量來解決這樣的問題。請求的總數在讀入線程中是可以被記錄並清楚確定的。那麼,每次清空一個請求序列的時候,釋放一個“資源”;需要結束線程的時候,判斷是否有資源可以被獲取,如果有就拿,沒有就等著,直到有請求被處理完畢釋放“資源”,就可以給拿取了。其中判斷次數為請求的總數。

多線程的信號量可以保證,在整個進程結束時,所有的請求都被處理完畢

1.3.6> 架構圖

 

這次作業的類又變得更加豐富了起來。

Main:負責創建緩衝區,併在此基礎上創建讀入、調度器、消費者線程。 Unit:包裝一個請求。直接繼承了官方包提供的PersonRequest,但是增加了一些對於請求運動方向、請求的狀態等屬性的記錄。 MyRequest:請求序列,存有一個請求經過最短路處理後得到的所有分請求。 Allocator:分配器,按樓座為各個消費者分配緩衝區內的請求。 MyBuffer:緩衝區,內部設有put和get方法,用於存放所有請求,同時也可以作為一個用來存放請求的容器被使用。 Producer:生產者,即讀入線程,用於讀取輸入的請求並put進緩衝區;同時在讀入結束時發出結束線程的信號。 Consumer:消費者,即電梯,內部設置有電梯的運行方式即各個電梯狀態下應該有的行為。 Consultant:顧問。思考良久都沒能想出一個適合的名字,最後對這個拆解請求的程設法最短路徑運行者付與了顧問一職,深表敬畏。 Output:線程安全輸出類。

1.4> 順序圖

由於三次作業是迭代設計,但是對於線程之間的交互和處理順序從本質上將沒什麼區別,故在此指放一張第七次作業對應代碼的順序圖,以示本人多線程作業的思路。

首先,在讀入一個乘客的請求之後,跑最短路,將請求拆解,放入緩衝區。在讀入一個新增電梯的請求之後,新增一個電梯並運行該線程,同時重新建圖。

第二,分配器從緩衝區拿取請求,將其放入對應電梯的等待序列。

第三,電梯按照其調度策略處理該請求,若該請求仍需換乘,則重新放回緩衝區,繼續處理;否則,完成此任務,釋放資源,信號量+1。期間不斷山城輸出

第四,若讀取到線程結束,則設置所有等待隊列的狀態為結束態,並回收所有資源

 

二 / 捉蟲大戰

本次作業中,本人並未嘗試編寫評測姬,一則是作業難度大導致沒有時間再去大量測試了,二則是沒有研究明白如何使用popen,無法做到通過自己寫的評測姬實時投放請求。這也導致了很嚴重的後果,即本人的代碼被強測和互測hack得千瘡百孔不忍直視。

最最重要的bug來源依舊是沒有仔細閱讀指導書

2.1> 自測bug

這個部分用來記錄自己出現過的bug。

首先在第五次作業中,本人理解錯了到達一層需要輸出arrive信息這句話的意思,並且沒有詳細閱讀樣例,導致這個蒟蒻設計的電梯只在需要開門出入人的層才輸出了arrive信息,以至於丟失所有性能分,併在互測房中獲得了被hack20/20的好成績。其次,由於本地測試並未出現輸出線程不安全的情況,於是本人沒有意識到封裝線程安全類的必要性,在強測中出現時間戳不遞增的問題。第三,本人的調度設計非常糟糕,榮獲了不少RTLE,在修複的時候也廢了不少心思,最後意識到,當時設計的捎帶處理邏輯每次選取的只是同方向且能捎帶的,是時間最早的而不是距離最近的,於是顯而易見,這樣的調度很熱愛已讓電梯陷入反覆橫跳的境地,浪費時間。在修改完請求處理順序的邏輯之後,便順利的修複了所有的bug。

第六次作業中,本人首先利用了第五次作業bug修複的代碼預覽處,解決了一個由於手抖打錯,把每次處理本層到下一個請求的起始樓層的方法寫成了處理從本層到下一個請求的目的地樓層,從而(調了一天)導致的RTLE問題,在強測中終於取得了一個可堪入眼的成績。其次,嘗試解決了橫向電梯不沿最短方向運行的問題,是解決了一些手頭的數據但也沒有完全解決所有問題,在前文已經闡述過了。

第七次作業中,依舊出現了RTLE的問題,而且令人絕望的是115s的時間要求本人的代碼需要117s跑完。問題依舊出在調度策略上,每次只處理一個請求,致使時間被拉長。

所以說,整個第二單元都是被可惡的RTLE包圍的狀態,在互測和強測中我因為線程不安全的問題除了第一次的輸出時間戳不遞增的問題外並未被hack出來,可能主要的問題還是別的錯誤太多了吧(嘆氣)。

2.2> 互測bug

第五次作業,由於當時已經意識到自己是一個掛在強測房裡的靈魂,於是早早倒下,沒有再出刀。

第六次作業中,本人意欲大開殺戒,但是並未造出什麼可靠的數據,只是把所有關於橫向電梯的數據都喂給了各個程式併發現了有RTLE的情況,最後發現是該戰友的電梯以為還有乘客沒上來,一直在空轉。所以線程的結束是一個很重要的問題。

第七次作業中,本人也是暴力造出了所有可能的數據,並挑選了運行時間最長的50條請求,針對一位同志的超乘、另一位同志的不使用新電梯所以會RTLE的問題、第三位同志的輪詢還有同層的橫向請求無輸出的情況進行了攻擊。當然,觀察到房內每個人的成功率都在66%,蒟蒻也早該意識到她這次的強測所遭遇的不測。

三 / 度量分析

3.1> 代碼長度

同比代碼行數多了很多,每次迭代的工程量都不小,但是裡面不乏很多重覆的可以整合的代碼。

3.2> 複雜度分析



可見,三次作業的複雜度都不低,這裡只選取了總表和有紅色標出的部分表格。

複雜度高的地方主要為電梯調度方法和程設法的圖論顧問,蒟蒻目前除了繼續提取類似代碼以外也確實沒有什麼解決辦法了。同樣的,複雜度高的地方出錯概率也高,這點在這次的bug中也有很好的印證。

四 / 心得體會

本單元意圖教會我什麼是多線程,如何處理多線程。

或許,蒟蒻只能說或許,她可能懂得了一點點多線程的入門,懂得了一點點為什麼要上鎖(解決數據競爭)、怎麼上鎖(同步塊、讀寫鎖等);兩個線程的執行順序是怎樣的(隨機),線程又是怎麼被調度的(可能同期的OS課涉及這類內容更多);線程怎麼互相讓位(wait/sleep),又怎樣喚醒(notifyAll);為什麼會出現線程不安全(隨機性強,鎖上的不准確),怎麼產生的死鎖(都在等待)、活縮(都在乾自己的事情,但無法互相喚醒交互)、輪詢(不使用wait/notify)等等不正常的現象。至少她現在以不像剛剛拿到一份training中錯誤的多線程代碼時和該程式期待著它的完結一樣絕望了,她已經掌握了一點點調試多線程的方法,無論是隨地分發System.out.println()還是(在需要自己挑選的地方)打斷點(利用過於方便的IDEA)進行單步調試,都能幫助她加深對於多線程代碼是如何運行的理解。

所以,這個單元的設計是成功的,但從所獲得的成績來看,本人是失敗的。

但她真的只得到了挫敗感嗎?並不,在一次次電梯超出邏輯的運行方式中她也在磨煉自己的性子,靜下來調試、研究,從奇異的輸出中獲取樂趣,從捉蟲成功中獲取動力;在一次次作業的push下努力學習設計模式,從工廠模式、組合模式到生產-消費者模式、觀察者模式、單例模式、裝飾器模式,這些奇怪的抽象概念一點點變得清晰,雖說在運用中仍有許多困難,理解中仍有許多障礙,但是獲取知識的過程遠比獲得成績單的打擊要快樂許多。

撐過電梯月,俺歪三仍是一條好漢!


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

-Advertisement-
Play Games
更多相關文章
  • STM8S103F3 產品手冊, 接線 ST-LINK和開發板的SWIM口是一一對應的, 直接連到開發板的同名PIN, 開發工具庫 SPL 第三方維護的 STM8S103F3_SPL 創建項目 打開 STVD 工具鏈: 選擇STM8 Cosmic, 指定toolchains到對應的目錄, 選擇晶元型... ...
  • linux套接字編程示例 簡單TCP、UDP編程示例。 TCP TCP通信模型 伺服器代碼 #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> #include <stdi ...
  • SAS (Statistical Analysis System) 是一個統計軟體系統,由 SAS Institute 開發, 用於數據管理、高級分析、多元分析、商業智能、刑事調查和預測分析. SAS 由北卡羅來納州立大學在1966至1976年之間開發, 並於1976年成立了SAS軟體研究所. 19... ...
  • HDFS HDFS由大量伺服器組成存儲集群,將數據進行分片與副本,實現高容錯。 而分片最小的單位就是塊。預設塊的大小是64M。 HDFS Cli操作 官網https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/F ...
  • 一、Spark on Hive 和 Hive on Spark的區別 1)Spark on Hive Spark on Hive 是Hive只作為存儲角色,Spark負責sql解析優化,執行。這裡可以理解為Spark 通過Spark SQL 使用Hive 語句操作Hive表 ,底層運行的還是 Spa ...
  • 常用的資料庫代碼 -- 通過 * 把 users 表中所有的數據查詢出來 -- select * from users -- 從 users 表中把 username 和 password 對應的數據查詢出來 -- select username, password from users -- 向 ...
  • ##Bootstrap導航欄樣式不生效的原因 今天在看bootstrap教程,想要將代碼複製粘貼到編譯器中運行,可是無法將效果正常顯示 ####情況如下: ####代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> ...
  • 菜單中有的項目有夏季菜單,需要添加一個三角形,這個三角形是利用兩個邊框不同顏色產生的楔形製作的 設置盒子的高度和寬度均為0,邊框合適的大小,透明顏色,對應邊設置高度、顏色 幾個變形如下 最終的效果如下: ...
一周排行
    -Advertisement-
    Play Games
  • 概述:本文代碼示例演示瞭如何在WPF中使用LiveCharts庫創建動態條形圖。通過創建數據模型、ViewModel和在XAML中使用`CartesianChart`控制項,你可以輕鬆實現圖表的數據綁定和動態更新。我將通過清晰的步驟指南包括詳細的中文註釋,幫助你快速理解並應用這一功能。 先上效果: 在 ...
  • openGauss(GaussDB ) openGauss是一款全面友好開放,攜手伙伴共同打造的企業級開源關係型資料庫。openGauss採用木蘭寬鬆許可證v2發行,提供面向多核架構的極致性能、全鏈路的業務、數據安全、基於AI的調優和高效運維的能力。openGauss深度融合華為在資料庫領域多年的研 ...
  • openGauss(GaussDB ) openGauss是一款全面友好開放,攜手伙伴共同打造的企業級開源關係型資料庫。openGauss採用木蘭寬鬆許可證v2發行,提供面向多核架構的極致性能、全鏈路的業務、數據安全、基於AI的調優和高效運維的能力。openGauss深度融合華為在資料庫領域多年的研 ...
  • 概述:本示例演示了在WPF應用程式中實現多語言支持的詳細步驟。通過資源字典和數據綁定,以及使用語言管理器類,應用程式能夠在運行時動態切換語言。這種方法使得多語言支持更加靈活,便於維護,同時提供清晰的代碼結構。 在WPF中實現多語言的一種常見方法是使用資源字典和數據綁定。以下是一個詳細的步驟和示例源代 ...
  • 描述(做一個簡單的記錄): 事件(event)的本質是一個委托;(聲明一個事件: public event TestDelegate eventTest;) 委托(delegate)可以理解為一個符合某種簽名的方法類型;比如:TestDelegate委托的返回數據類型為string,參數為 int和 ...
  • 1、AOT適合場景 Aot適合工具類型的項目使用,優點禁止反編 ,第一次啟動快,業務型項目或者反射多的項目不適合用AOT AOT更新記錄: 實實在在經過實踐的AOT ORM 5.1.4.117 +支持AOT 5.1.4.123 +支持CodeFirst和非同步方法 5.1.4.129-preview1 ...
  • 總說周知,UWP 是運行在沙盒裡面的,所有許可權都有嚴格限制,和沙盒外交互也需要特殊的通道,所以從根本杜絕了 UWP 毒瘤的存在。但是實際上 UWP 只是一個應用模型,本身是沒有什麼許可權管理的,許可權管理全靠 App Container 沙盒控制,如果我們脫離了這個沙盒,UWP 就會放飛自我了。那麼有沒... ...
  • 目錄條款17:讓介面容易被正確使用,不易被誤用(Make interfaces easy to use correctly and hard to use incorrectly)限制類型和值規定能做和不能做的事提供行為一致的介面條款19:設計class猶如設計type(Treat class de ...
  • title: 從零開始:Django項目的創建與配置指南 date: 2024/5/2 18:29:33 updated: 2024/5/2 18:29:33 categories: 後端開發 tags: Django WebDev Python ORM Security Deployment Op ...
  • 1、BOM對象 BOM:Broswer object model,即瀏覽器提供我們開發者在javascript用於操作瀏覽器的對象。 1.1、window對象 視窗方法 // BOM Browser object model 瀏覽器對象模型 // js中最大的一個對象.整個瀏覽器視窗出現的所有東西都 ...