404 Note Found 現場程式設計
目錄
- 組員職責分工
- github 的提交日誌截圖(鼓勵小粒度提交)
- 程式執行截圖
- 程式執行環境
- GUI介面
- 基礎功能實現
- 附加功能實現(20分)
- 鼓勵有想法且有用的功能(10分)
- 遇到的困難及解決方法
- 馬後炮
- 貢獻分評估
- PSP表格(個人獨立釋出)(1分)
- 學習進度表(個人獨立釋出)(1分)
組員職責分工
組員 | 職責 |
---|---|
緒佩 | 組織分工、改進前端、後端、雲化 |
莊卉 | 改進前端、後端 |
家偉 | 演算法關鍵詞識別、附加題實現 |
家燦 | 資料庫 |
一好 | 演算法隨機數、演算法審查 |
鴻傑 | 演算法隨機數、演算法審查 |
政演 | 提供演算法思路、附加題idea思路、部落格撰寫 |
凱琳 | 前端審查 |
丹丹 | 前端審查 |
青元 | 前端改進 |
宇恆 | 前端審查 |
github 的提交日誌截圖(鼓勵小粒度提交)
程式執行截圖
執行結果
抽獎結果名單
程式執行環境
環境 | 名稱 |
---|---|
作業系統 | Windows10 |
編譯器 | Eclipse javaee |
本地伺服器 | Tomcat |
資料庫 | MySQL |
視覺化資料庫工具 | Navicat |
GUI介面
進入介面
抽獎規則設定1
抽獎規則設定2
抽獎結果名單
錯誤提示
釋出成功顯示
基礎功能實現
本演算法具有以下模式:
- 不過濾模式:剔除機器,所有參與抽獎的人,都納入開獎範圍。
- 普通模式:篩除只參與抽獎而無發表任何原創言論的使用者(抽獎機器人),鼓勵大家積極參與有意義的發言。
- 深度模式:為了使發言更有意義,減少灌水,對以下使用者的中獎概率進行降權處理:
- 只參與抽獎而無發表任何原創言論(抽獎機器人)
- 只參與抽獎且只發送表情(水軍)
隨機演算法:
LCG演算法
我們的抽獎演算法基於LCG演算法,LCG(linear congruential generator)線性同餘演算法,是一個古老的產生隨機數的演算法。
本演算法有以下優點:
- 計算速度快:抽獎時的演算法時間複雜度是一個較大的問題,在微博開獎的時候,由於抽獎人數眾多,(例如王思聰的抽獎微博,轉發量、評論數、點贊數均達到了兩千萬,總數達到了六千萬,輸入量十分巨大)所以常常需要花費幾十分鐘的時間開獎,如此的演算法效能是難以忍受的。對此,我們的演算法基於LCG演算法,利用其速度優勢,減少開獎時間。
- 易於實現:演算法易於理解,可以通過改變取餘數來控制演算法的空間複雜度與隨機分佈效果。且演算法是線性的演算法,和非線性的模型相比,具有較低的複雜度。
- 易於推廣:本演算法改變取餘引數,對空間資源和隨機準確率權衡,根據不同的裝置資源和計算能力調優,具有很強的靈活性,易於使用推廣。
本演算法基於的LCG演算法由以下引數組成:
引數 | m | a | c | X |
---|---|---|---|---|
性質 | 模數 | 乘數 | 加數 | 隨機數 |
作用 | 取模 | 移位 | 偏移 | 作為結果 |
LCG演算法是如下的一個遞推公式,每下一個隨機數是當前隨機數向左移動 log2 a 位,加上一個 c,最後對 m 取餘,使隨機數限制在 0 ~ m-1 內
從該式可以看出,該演算法由於構成簡單,具有以下優點:
- 計算速度快
- 易於實現
- 易於寫入硬體
以下是針對不同引數 lcg 產生隨機數的效果圖
可以看出,針對不同的引數,lcg產生的效果差別很大
以下是針對不同環境下的引數選擇
根據我們機器的情況,我們選擇使用引數:
過濾(降權)演算法
演算法思路
抽獎演算法對兩種情況進行了處理:
無發言剔除:當用戶只轉發抽獎關鍵字,而沒有相關發言時,直接剔出抽獎名單。
惡意刷屏:抽獎者可以自行定義一個抽獎閾值φ1,當發言數超過φ1時,對該使用者進行中獎概率降權處理。
灌水剔除:抽獎者可以自行定義一個抽獎閾值φ2,傳送的表情數超過閾值的時候,判定為灌水,剔出抽獎名單
for (Map.Entry<String, Integer> en : map.entrySet()) {
//System.out.println(en.getKey() + "=" + en.getValue());
x[i] = ( a * x[i-1] + b ) % m;
if (en.getValue() < 0) { //發言為空,剔出抽獎名單
i++;
continue;
} else if (en.getValue() > 0) { //惡意刷屏,降低權重
weight = en.getValue();
if (weight > 30) {
weight = 30;
}
x[i] = (int) (x[i] * ((double)(30 - weight) / 30.0));
}
map.put(en.getKey(), x[i]);
//System.out.println(en.getKey() + "=" + en.getValue());
i++;
}
紅黑樹
紅黑樹是一種自平衡的二叉查詢樹,是一種高效的查詢樹。
提供良好的效率:可在O(logN)時間內完成查詢、增加、刪除等操作,能保證在最壞情況下,基本的動態幾何操作的時間均為O(lgn)。只要求部分地達到平衡要求,降低了對旋轉的要求,任何不平衡都會在三次旋轉之內解決,從而提高了效率。抽獎伏安法涉及大量增刪改查操作,紅黑樹演算法提供了良好的效率支撐。
提供效能下限保證:相比於BST,紅黑樹可以能確保樹的最長路徑不大於兩倍的最短路徑的長度,可見其查詢效果的最低保證。最壞的情況下也可以保證O(logN)的複雜度,好於二叉查詢樹O(N)複雜度。在大資料量情況下,紅黑樹演算法為抽獎演算法提供良好的效能保證。
提供詞頻統計的高效能:紅黑樹的演算法時間複雜度和AVL樹相同,但統計效能更高。插入 AVL樹和紅黑樹的速度取決於所插入的資料。在資料比較雜亂的情況,則紅黑樹的統計效能優於AVL樹。在抽獎時時,資料分佈較為雜亂,在此應用場景下,紅黑樹演算法與抽獎器契合。
提供較小的資源開銷:與基於雜湊的演算法相比,基於紅黑樹方法帶來更小的資源開銷,程式消耗記憶體較少。雜湊的算法佔用大量資源,需要維護大量的計數器,並且在雜湊過程中消耗了大量的計算資源。抽獎系統器消耗的資源較少。
附加功能實現(20分)
sketch 是一種基於雜湊的資料結構,可以在高速網路環境中,實時地儲存流量特徵資訊,只佔用較小的空間資源,並且具備在理論上可證明的估計精度與記憶體的平衡特性
原理
sketch是基於雜湊的資料結構,通過設定雜湊函式,將具有相同雜湊值的鍵值資料存入相同的桶內,以減少空間開銷。桶內的資料值作為測量結果,是真實值的近似。利用開闢二維地址空間,多重雜湊等技術減少雜湊衝突,提高測量結果的準確度。Count-Min[7] 是一種典型的 sketch ,在 2004 年被提出。實際上 Count-Min sketch 用到的是分類的思想:將具有相同雜湊值的網路流歸為一類,並使用同一個計數器計數。
當高速網路流量到來時,逐個記錄所有流量的資訊,會帶來巨大的計算和空間資源開銷。而網路測量往往也無需記錄所有的資訊。
Count-Min sketch由多個雜湊函式(f1……fn)和一張二維表組成。二維表的每個儲存空間維護了一個計數器,其中每個雜湊函式分別對應表中的每一行。當一個網路流到來時,需要經過每個雜湊函式 f1……fn 的處理,根據處理得到的雜湊值分別存入每一行對應雜湊值的計數器。有幾個雜湊函式,就要計算幾次。算完後,取這m個計數器中的最小值,作為測量的最終值。
設計考量
測量值偏大:使用雜湊的方法會產生衝突,多個網路流資料雜湊到同一個桶內,那麼這個桶的計數值就會偏大。
1.為什麼允許有誤差:在高速網路條件下,若把所有資訊都準確地記錄下來,要消耗大量計算和空間開銷,無法滿足實時性;而且在很多情況下,並不需要非常精確的測量資料,在一定程度上可靠的估計值,便足以滿足需求。
2.為什麼要設定多個雜湊函式:如果只設置一個雜湊函式,多個流資料存入同一個桶,誤差就會很大。通過設計多個雜湊函式,減少雜湊值的衝突,以減少誤差。每個流都要經過所有雜湊函式的處理,存入不同的計數器中。計數器的最小值雖然還是大於等於真實值,但最接近真實值。這也是 “ Count-Min ”的由來。
3.雜湊函式個數:雜湊函式越多,衝突越少,測量值越精確,但計算開銷大。需要權衡測量精度和準確度,來設定合適的雜湊函式個數。
鼓勵有想法且有用的功能(10分)
遇到的困難及解決方法
組員:胡緒佩
困難:
- 分工沒有分很合理;
- 分好工的準備的不夠充分;
- 和隊友交流不夠密切及時,導致他們誤入歧途寫了很久效率卻還很低;
- JavaWeb不熟悉,差不多全忘了...重頭再寫很艱難;
- web介面細節佈局還是處理的不夠好,所以介面還挺醜;
- 其他作業、考試實在太多,忙不過來;
- 軟工這麼多專案,已經佔用了太多太多其他學科的時間了;
解決辦法
- 下次盡力在開始的時候明確合理分工;
- 爭取高效率、及時的和隊友交流(這次是因為下午有實驗,隊友直接就默默地開始打);
- 重頭寫也不難,不就是通個宵嗎?
- 儘量把軟工規定在每天什麼時間做吧,不能再佔用過多其他的時間了。大學不僅僅只有軟工實踐;
- 考試優先,考後熬夜;
組員:莊卉
困難:alpha還在單機階段課堂實戰已經進入web,時間分配不均,分工出現混亂,作為後端負責人沒有檢查環境軟體版本甚至不少人沒有某某軟體,導致不熟悉。
解決辦法:冷靜冷靜冷靜,儘量不焦慮,事情一件一件來(嗯,體會到了瀕臨死亡的感覺)
組員:政演
困難:時間太短,對程式碼要求很高,不允許迭代修改bug。演算法全新,需要構思。附加題構思。
解決辦法:考慮到前一段學習的djb2雜湊函式,修改使用LCG線性同餘法,解決隨機數的問題。考慮在實際場景下,微博轉發數量太大,要進行資料探勘等工作,需要耗費很大計算和空間資源,故使用LCG和Sketch解決。
組員:劉一好
困難:隨機數生成演算法需要從網上查閱很多相關資料,需要同後端使用相同的類和傳參方式
組員 翟丹丹
困難:
1.編碼方面,在其他人面前,真的是有點過於弱。
2.前端方面,淺顯的還能寫出來,深度一點的就會一直出bug。
3.擅長的東西過於單一,理解的知識也是過於膚淺,個人能力有待提升。
解決辦法:
1.看教程,一步步來。
2.看隊友操作,積累經驗。
解決辦法:在網上查詢程式碼,並同其他同學交流,制定相同的傳參規則
組員:劉愷琳
困難:前端介面太不友好,不瞭解程式碼,修改起來有難度。與後端交接時,返回值有待商榷。
解決辦法:檢視網上程式碼,下載模板進行修改。
組員:青元
困難:
- 不會寫java,要現學
- 不會寫html和css,要現學
解決辦法:
- 只能儘量學。
組員:葛家燦
困難:
- 對於javaweb的0知識量,導致的無從下手
- 動態html頁面的實現
- 頁面之間跳轉之後,怎麼做到向新頁面傳遞資訊
解決辦法
- 用servlrt實現一個動態頁面的out,頁面的資料資料從伺服器的資料庫中匯出
- 用到 中的action觸發servlet,在form中使用type=hidden,作為一個隱藏域,傳遞它的value給servlet
- 有函式可以直接實現,伺服器內部的頁面跳轉
組員:何家偉
困難:對於抽獎應該如何實現沒有頭緒
解決辦法:求助了組內的周政演和黃鴻傑同學
組員:黃鴻傑
困難:
- 關於線性同餘法的瞭解很粗淺
- 關於JAVA的String和DATE之間的轉換
- 網路上基本上都是虛擬碼,在轉化成JAVA程式碼過程中各種引數不知道怎麼設定
解決辦法:
- 稍微熟悉了JAVA程式碼的書寫
- 修改網路部落格上的轉換例項符合專案的需求
- 找部落格看原理,茫茫大海里面找到了有JAVA示例的程式碼修改
組員:何宇恆
困難:對於web很麼有經驗,對於排版,真的難為我這個男生
解決辦法:找了一個婚慶的模板套了一下,改了些字和圖
馬後炮
由於本次現場程式設計開發進度低於預期,給每位同學一個一句話吐槽機會,格式為:如果……,那麼……
組員:胡緒佩
如果能睡一個好覺,那麼我會補一個月的覺
組員:何家偉
如果我有好好學搜尋引擎或者好好看前端,那麼這次作業大家做起來都會快很多
組員:翟丹丹
如果我能力強一些,那麼我的團隊就可以更快更完美的完成這項專案。
組員:劉一好
如果給定時間長一點或者不在考試之前釋出這麼複雜的問題,那麼大家能更輕鬆愉快地完成這項任務。
組員:劉愷琳
如果能拿到相關教程,學習一段時間,那麼我們就不會感覺很慌張
組員:青元
如果能重來,那麼我一定要在課前學習,課上裝逼。
組員:莊卉
如果能重來一次,那麼我可能會選擇做自閉軟體或者直接自閉吧
組員:何宇恆
如果我再強一些,那麼我的團隊就可以更開心的完成
貢獻分評估
以下部分計入個人得分:
PSP表格(個人獨立釋出)(1分)
PSP2.1 | header 2 | 預估耗時(分鐘) | 實際耗時(分鐘) |
---|---|---|---|
Planning | 計劃 | 40 | 30 |
· Estimate | ·估計這個任務需要多少時間 | 20 | 20 |
Development | 開發 | 150 | 240 |
· Analysis | 需求分析(包括學習新技術) | 60 | 60 |
· Design Spec | · 生成設計文件 | 0 | 0 |
· Design Review | · 設計複審 | 0 | 0 |
· Coding Standard | · 程式碼規範 (為目前的開發制定合適的規範) | 0 | 0 |
· Design | · 具體設計 | 180 | 150 |
· Coding | · 具體編碼 | 120 | 450 |
· Code Review | · 程式碼複審 | 0 | 0 |
· Test | ·測試(自我測試,修改程式碼,提交修改) | 0 | 0 |
Reporting | 報告 | 10 | 10 |
· Test Repor | · 測試報告 | 0 | 0 |
· Size Measurement | · 計算工作量 | 0 | 0 |
· Postmortem & Process Improvement Plan | · 事後總結, 並提出過程改進計劃 | 20 | 20 |
合計 | 600 | 950 |
學習進度表(個人獨立釋出)(1分)
學習進度條
第N周 | 新增程式碼(行) | 累計程式碼(行) | 本週學習耗時(小時) | 累計學習耗時(小時) | 重要成長 |
---|---|---|---|---|---|
1 | 300 | 300 | 15 | 15 | 學會程式碼質量分析 |
2 | 100 | 400 | 10 | 25 | Axure設計原型 |
3 | 500 | 900 | 15 | 50 | 學會正則表示式和NFA的應用 |
4 | 300 | 1200 | 15 | 65 | 學會了andorid前端頁面的書寫 |
5 | 500 | 1700 | 25 | 90 | 對前端與後端的互動有了新的瞭解,同時對前端的認識加深了 |
6 | 500 | 2200 | 38 | 108 | 學習了一定的web +java 程式設計 |