BUAA-OO 第二單元做業「電梯調度」總結與思考

1、需求分析

利用java線程的相關知識實現java

1)單部多線程傻瓜調度(FAFS)電梯
python

2)單部多線程可捎帶調度(ALS)電梯git

3)多部多線程智能(SS)調度電梯github

2、思路分析

一、基於度量的程序結構分析

流程時序圖(利用SequenceDiagram插件)

注:使用UML Support插件時,採用實現runnable接口的方法生成的類關係圖更優美一點正則表達式

Input類(三次做業複用):編程

Elevator類:設計模式

第一次數組

 

第二次安全

圖太大了戳這裏
性能優化

第三次

圖太大了戳這裏

代碼行數統計(利用Statistic插件)

第一次

第二次

第三次

代碼設計複雜度(利用MetricsReloaded插件)

ev(G)基本複雜度,用來衡量程序非結構化程度
iv(G)模塊設計複雜度,用來衡量模塊斷定結構
v(G)獨立路徑條數

第一次

第二次

第三次

 

二、BUG分析

第一次:

強測中得分 100

互測:未被hack。未hack別人。

第二次:

在強測中得分 82.558(全部數據性能分幾乎爲0)

未被hack。未hack到別人。

第三次:

在強測中得分  76.9294(WA兩個數據點,其他數據性能分幾乎爲0)

被hack1次,hack他人1次。

本身錯誤:出現了電梯容量已滿卻仍進人的狀況。

他人錯誤:電梯換向時到了21層。

 

3、知識技能總結

一、代碼編寫層面的優化

1)第三次做業中一種快速處理換乘樓層的寫法

記A電梯爲001,B電梯爲010,C電梯爲100.

則可乘坐的電梯的類型能夠用三位二進制數來表示,例如:

在1層的人能夠乘坐A、B電梯,則創建樓層1到二進制數011的映射(map)。

在3層的人只能乘坐C電梯,則簡歷樓層3到二進制數100的映射。

這樣避免了用八個等待隊列儲存全部狀況的繁雜寫法。

 

2)電梯不一樣狀態間的切換:run方法中,用狀態機來實現,簡單直觀

 1     public void run() {  2         while (true) {  3             synchronized (this) {  4                 try {  5                     if (state == 0) {  6                         break;  7  }  8                     if (state == 1) { //main request
 9                         while (true) { 10                             if (Singleton.getInstance().isend()) { 11  close(); 12                                 state = 0; 13                                 break; 14  } 15                             mainRequest = Singleton.getInstance().getMainRequest(); 16                             if (mainRequest == null) { 17                                 synchronized (Singleton.getInstance()) { 18  Singleton.getInstance().wait(); 19  } 20                             } else { 21  solveMain(); 22                                 break; 23  } 24  } 25  } 26                     else if (state == 2) { solveUp(); } 27                     else if (state == 3) { solveDown(); } 28                 } catch (InterruptedException e) { 29                     //DO STH
30  } 31  } 32  } 33     }

 

二、多線程設計模式的實際運用

1)單例模式

2)生產者—消費者模式

3)線程池(Worker Thread模式)

4)觀察者模式

三、輸出日誌信息 Log4j

配置log4j2-test.xml文件:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <configuration status="OFF">
 3     <appenders> <!—輸出模塊-->
 4         <Console name="Console" target="SYSTEM_OUT">
 5             <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
 6         </Console>
 7     </appenders>
 8     <loggers><!—日誌模塊-->
 9 <logger name=「elevator.WorkerThread" level="trace" additivity="false">
10             <appender-ref ref="Console"/>
11         </logger>
12         <root level="error">
13             <appender-ref ref="Console"/>
14         </root>
15     </loggers>
16 </configuration>

 

四、JProfiler的使用

五、定點投放的實現

思路:正則表達式分離時間戳+sleep

python程序已上傳至GitHub

六、線程安全容器總結

這一單元做業中我採用了CopyOnWriteArrayList做爲線程安全數組

COW(Copy On Write)機制的介紹:https://yq.aliyun.com/articles/665359

 

4、本身的一點思考

一、程序測試方法

隨機數據測試(測試cpu-time和基本的功能)+構造數據測試(測試電梯是否知足全部限制條件)

對拍器SPJ測試的功能,同時也是構造數據時重點檢驗的功能:

是否知足到達——開門——出入人——關門的順序。

是否知足樓層限制

是否知足容量要求

除此以外,三次做業重難點在於:

1)HW5:是否可正常退出線程:接收器再也不接收請求,電梯繼續處理完已經讀入的請求

2)HW6:是否可將全部請求捎帶(若是有請求的區間與當前等待隊列區間不重合,是否將其放入等待隊列?)、同一樓層是否會開關兩次門

3)HW7:2->三、4->3的換乘須要特殊處理。換乘指令拆解後是否按順序執行(在人下電梯後才能從同樓層上另外一電梯)。

二、優化方法

4、疑問與建議

一、對拍器的意義?

助教說,A組強測和互測成績遠好於B組和C組的一大緣由是「大佬們基本人手一個評測機」。

我認可互測的確是測試的有效手段,這致使我這一單元的最大收穫就是學會寫得一手好腳本。

但當我發現本身用在寫評測機的時間遠遠大於學習多線程思想的時間的時候,我感受本身在面向「評測機」編程。

不知道老師和助教爲什麼大力鼓勵同窗們來寫評測機。知識無窮,學什麼只要用心了都會有收穫,也都會有相應的歡喜和知足。但這種偏離正軌的導向仍是會讓人感受食之無味,棄之惋惜。

二、架構or性能?

自我感受第二單元做業的難度要低於第一單元。程序的大致架構老師在課上已經基本講過,剩下的添添補補,這三次做業居然沒有重構。

若是說性能優化基於架構的話,那性能優化的方向是什麼呢?

當我問及性能的問題時,助教和老師都在強調正確性爲主,但做爲兩次被性能分踩死的選手,仍是想要了解一下助教出題時構想的優化的可能思路。T_T

三、b站都開源了,大佬們的代碼能夠開源嗎

 若是助教以爲上面的話都沒道理的話......我只是想請求看一看大佬們的優秀代碼,學習一下。/小糾結

PS. 實驗課的題面在結束以後能夠開放嗎?這樣還能複習鞏固一下下。

相關文章
相關標籤/搜索