一、需求分析
利用java線程的相關知識實現
1)
二、思路分析
1、基于度量的程序結構分析
流程時序圖(利用SequenceDiagram插件)
注:使用UML Support插件時,采用實現runnable接口的方法生成的類關系圖更優美一點
Input類(三次作業復用):
Elevator類:
第一次
?
第二次
圖太大了戳這里
第三次
圖太大了戳這里
代碼行數統計(利用Statistic插件)
第一次
第二次
第三次
代碼設計復雜度(利用MetricsReloaded插件)
ev(G)基本復雜度,用來衡量程序非結構化程度
iv(G)模塊設計復雜度,用來衡量模塊判定結構
v(G)獨立路徑條數
第一次
第二次
第三次
?
2、BUG分析
第一次:
強測中得分 100
互測:未被hack。未hack別人。
第二次:
在強測中得分 82.558(所有數據性能分幾乎為0)
未被hack。未hack到別人。
第三次:
在強測中得分? 76.9294(WA兩個數據點,其余數據性能分幾乎為0)
被hack1次,hack他人1次。
自己錯誤:出現了電梯容量已滿卻仍進人的情況。
他人錯誤:電梯換向時到了21層。
?
三、知識技能總結
1、代碼編寫層面的優化
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 }
?
2、多線程設計模式的實際運用
1)單例模式
2)生產者—消費者模式
3)線程池(Worker Thread模式)
4)觀察者模式
3、輸出日志信息 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>
?
4、JProfiler的使用
5、定點投放的實現
思路:正則表達式分離時間戳+sleep
python程序已上傳至GitHub
6、線程安全容器總結
這一單元作業中我采用了CopyOnWriteArrayList作為線程安全數組
COW(Copy On Write)機制的介紹:https://yq.aliyun.com/articles/665359
?
四、自己的一點思考
1、程序測試方法
隨機數據測試(測試cpu-time和基本的功能)+構造數據測試(測試電梯是否滿足所有限制條件)
對拍器SPJ測試的功能,同時也是構造數據時重點檢驗的功能:
是否滿足到達——開門——出入人——關門的順序。
是否滿足樓層限制
是否滿足容量要求
除此之外,三次作業重難點在于:
1)HW5:是否可正常退出線程:接收器不再接收請求,電梯繼續處理完已經讀入的請求
2)HW6:是否可將所有請求捎帶(如果有請求的區間與當前等待隊列區間不重合,是否將其放入等待隊列?)、同一樓層是否會開關兩次門
3)HW7:2->3、4->3的換乘需要特殊處理。換乘指令拆解后是否按順序執行(在人下電梯后才能從同樓層上另一電梯)。
2、優化方法
四、疑問與建議
1、對拍器的意義?
助教說,A組強測和互測成績遠好于B組和C組的一大原因是“大佬們基本人手一個評測機”。
我承認互測的確是測試的有效手段,這導致我這一單元的最大收獲就是學會寫得一手好腳本。
但當我發現自己用在寫評測機的時間遠遠大于學習多線程思想的時間的時候,我感覺自己在面向“評測機”編程。
不知道老師和助教為何大力鼓勵同學們來寫評測機。知識無窮,學什么只要用心了都會有收獲,也都會有相應的歡喜和滿足。但這種偏離正軌的導向還是會讓人感覺食之無味,棄之可惜。
2、架構or性能?
自我感覺第二單元作業的難度要低于第一單元。程序的大體架構老師在課上已經基本講過,剩下的添添補補,這三次作業竟然沒有重構。
如果說性能優化基于架構的話,那性能優化的方向是什么呢?
當我問及性能的問題時,助教和老師都在強調正確性為主,但作為兩次被性能分踩死的選手,還是想要了解一下助教出題時構想的優化的可能思路。T_T
3、b站都開源了,大佬們的代碼可以開源嗎
?如果助教覺得上面的話都沒道理的話......我只是想請求看一看大佬們的優秀代碼,學習一下。/小糾結
PS. 實驗課的題面在結束之后可以開放嗎?這樣還能復習鞏固一下下。