1. 程式人生 > >404 Note Found 現場程式設計

404 Note Found 現場程式設計

目錄

組員職責分工

組員 職責
緒佩 組織分工、改進前端、後端、雲化
莊卉 改進前端、後端
家偉 演算法關鍵詞識別、附加題實現
家燦 資料庫
一好 演算法隨機數、演算法審查
鴻傑 演算法隨機數、演算法審查
政演 提供演算法思路、附加題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分)

遇到的困難及解決方法

組員:胡緒佩

困難

  1. 分工沒有分很合理;
  2. 分好工的準備的不夠充分;
  3. 和隊友交流不夠密切及時,導致他們誤入歧途寫了很久效率卻還很低;
  4. JavaWeb不熟悉,差不多全忘了...重頭再寫很艱難;
  5. web介面細節佈局還是處理的不夠好,所以介面還挺醜;
  6. 其他作業、考試實在太多,忙不過來;
  7. 軟工這麼多專案,已經佔用了太多太多其他學科的時間了;

解決辦法

  1. 下次盡力在開始的時候明確合理分工;
  2. 爭取高效率、及時的和隊友交流(這次是因為下午有實驗,隊友直接就默默地開始打);
  3. 重頭寫也不難,不就是通個宵嗎?
  4. 儘量把軟工規定在每天什麼時間做吧,不能再佔用過多其他的時間了。大學不僅僅只有軟工實踐;
  5. 考試優先,考後熬夜;

組員:莊卉

困難:alpha還在單機階段課堂實戰已經進入web,時間分配不均,分工出現混亂,作為後端負責人沒有檢查環境軟體版本甚至不少人沒有某某軟體,導致不熟悉。

解決辦法:冷靜冷靜冷靜,儘量不焦慮,事情一件一件來(嗯,體會到了瀕臨死亡的感覺)

組員:政演

困難:時間太短,對程式碼要求很高,不允許迭代修改bug。演算法全新,需要構思。附加題構思。

解決辦法:考慮到前一段學習的djb2雜湊函式,修改使用LCG線性同餘法,解決隨機數的問題。考慮在實際場景下,微博轉發數量太大,要進行資料探勘等工作,需要耗費很大計算和空間資源,故使用LCG和Sketch解決。

組員:劉一好

困難:隨機數生成演算法需要從網上查閱很多相關資料,需要同後端使用相同的類和傳參方式

組員 翟丹丹

困難
1.編碼方面,在其他人面前,真的是有點過於弱。
2.前端方面,淺顯的還能寫出來,深度一點的就會一直出bug。
3.擅長的東西過於單一,理解的知識也是過於膚淺,個人能力有待提升。

解決辦法
1.看教程,一步步來。
2.看隊友操作,積累經驗。

解決辦法:在網上查詢程式碼,並同其他同學交流,制定相同的傳參規則

組員:劉愷琳

困難:前端介面太不友好,不瞭解程式碼,修改起來有難度。與後端交接時,返回值有待商榷。

解決辦法:檢視網上程式碼,下載模板進行修改。

組員:青元

困難

  1. 不會寫java,要現學
  2. 不會寫html和css,要現學

解決辦法

  1. 只能儘量學。

組員:葛家燦

困難

  1. 對於javaweb的0知識量,導致的無從下手
  2. 動態html頁面的實現
  3. 頁面之間跳轉之後,怎麼做到向新頁面傳遞資訊

解決辦法

  1. 用servlrt實現一個動態頁面的out,頁面的資料資料從伺服器的資料庫中匯出
  2. 用到
    中的action觸發servlet,在form中使用type=hidden,作為一個隱藏域,傳遞它的value給servlet
  3. 有函式可以直接實現,伺服器內部的頁面跳轉

組員:何家偉

困難:對於抽獎應該如何實現沒有頭緒

解決辦法:求助了組內的周政演和黃鴻傑同學

組員:黃鴻傑

困難

  1. 關於線性同餘法的瞭解很粗淺
  2. 關於JAVA的String和DATE之間的轉換
  3. 網路上基本上都是虛擬碼,在轉化成JAVA程式碼過程中各種引數不知道怎麼設定

解決辦法

  1. 稍微熟悉了JAVA程式碼的書寫
  2. 修改網路部落格上的轉換例項符合專案的需求
  3. 找部落格看原理,茫茫大海里面找到了有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 程式設計