網絡項目OJ 在線判題系統

點我查看代碼

思維導圖 ,一看立馬懂

在這裏插入圖片描述

思維導圖大綱:

1 獲取題目列表
1 獲取題目列表
訪問服務器特定的ip + port
2 渲染展示all_questions的html頁面
1 設置html頁面標題
2 設置每個題目超鏈接
3 建立數據字典 + 和C++正則表達式配合使用,匹配展示每個題目的id + name + star
4 設置form表單
1 設置答題的代碼編輯框textarea
2 設置提交按鈕submit
3 設置提form表單的執行動作----->向服務器該題目的目錄提交 提交方式選用post較安全

2 選擇題目
1 獲取該題目的describe + header
實現:html超鏈接
2 渲染展示該題目的html頁面
數據字典片段 + c++ 正則表達式

3 作答並提交
1 服務器對用戶作答數據進行捕捉並保存
1 抓取並解析數據包 name=xxx&body=xxx
2 拆分數據包 得到name和 body
3 獲取題目id 和 code
2 由題目Id 查找該題目在服務端保存的main函數
3 將main函數和用戶提交代碼進行拼接

4 服務器響應運行結果
1 將拼接完成的代碼交給編譯器Compiler
2 編譯器對拼接完整的代碼進行分析
1 檢查請求是否有效–>req[“code”].empty()
2 將拼接後的代碼保存在文件中 ,防止多用戶做題,文件統一命名 tmp_ + 時間戳
3 準備編譯
1 構造編譯命令
2 fork創建新進程
1 父進程回收資源
2 子進程準備編譯條件
1 準備捕捉編譯錯誤的信息,保存在文件中
2 正式程序替換,執行構造好的編譯命令
3 防止程序替換失敗,及時退出exit
3 驗證是否產生了可執行程序–>stat()
4 運行
fork 新進程
1 父進程回收資源
2 子進程準備運行條件
1 準備接收stdout/stderr的文件,將stdout/stderr 重定向到準備好的文件中
2 設置時間限制alarm + 內存限制setrlimit
3 進程程序替換,去運行編譯生成的可執行程序
4 防止程序替換失敗,及時退出exit
5 響應
1 接收運行進程退出的信號
1 正常退出errorno -->ok reason -->ok
2 異常退出errorno–> 錯誤碼 reason–> signal
3 運行信息html頁面的渲染
數據字典
6 清理服務端垃圾文件
unlink(filename)

1 環境準備:

httplib.h開源庫

2 使用C++11特性 需要版本
gcc -v。 查看 版本 4.8.2之後的版本支持
版本升級指令: source /opt/rh/devtoolset-4/enable

yum -y install jsoncpp-devel

需求分析:

1 在瀏覽器中展示題目    		 oj_server 試題模塊
2 用戶可以選擇題目進行作答		 oj_server 試題模塊
3 提交代碼到後臺	
4 針對用戶代碼進行編譯,
5 後臺運行代碼			
6 將運行結果進行打包
7 把結果返回給客戶端。		  oj_server

模塊劃分:

1 oj_server模塊
1 提供http服務,需要下面四個模塊的支持
1.1 獲取題目列表
1.2 提交選中題目的
1.3 提交題目描述,和題目代碼,代碼的編輯框

2 試題模塊
2.1 從本地加載題目
配置文件的格式;規定統一
題目 id、path、name、難易度
eg:迴文數 ./oj_data/1 簡單
2.2 加載題目的配置文件,使用數據結構/unordered_map保存加載出來的題目介紹信息,最重要的是路徑
2.3 針對具體的某一道題目而言,需要根據路徑進行加載
1 desc.txt描述信息
2 header.cpp存放本題目的頭文件和實現類
3 tail.cpp 存放main函數以及所有的測試用例
2.4 提供獲取所有題目的接口
2.5 提供獲取單個題目的接口

3 編譯運行模塊
將用戶提交的code寫到文件中,並編譯源碼文件
1 構造編譯命令
2 編譯
3 檢查是否生成可執行程序
4 運行(folk子進程執行,爲防止多題目同時運行,引起後臺顯示分不清,將運行信息重定向到自己特定文件中)
5 構造響應給用戶的信息(errono、reason、)
6 及時清理掉配置文件 (unlink)
4 日誌模塊
1 顯示錯誤類型
2 以文件的形式保存執行期間得日誌文件,日誌文件統一命名爲 tmp + 時間戳格式,防止多用戶同時作答。

5 工具模塊
1 切割類: 切割字符串,得到想要的信息 題目id 和 stdin
2 解碼類: 對網頁Json數據包進行解碼,拿到代碼,準備保存
3 文件操作類;
1 寫文件,將數據寫入到文件中保存,即將所有代碼拼接完整保存起來
2 讀文件, 從文件中拿出數據使用, 即拿出完整代碼準備執行

static Template* GetTimeplate  (路徑, 渲染方式)
1 DO_NOT_STRIP. 逐字逐句渲染到html模版文件中
2 STRIP_BLANK_LINES。刪除空行渲染到html模版文件中
3 STRIP_WITHESPACE. 刪除空行和每一行的首尾空格渲染到html模版文件中

1 數據字典: —>需要填充的數據
2 獲取了需要填充的html文件
3 渲染

底層存儲試題的數據結構的選擇
Map——>底層紅黑樹,查詢效率(logN)
unordered_map. 查詢效率高 O(1)。查詢性能更佳。 因此選擇unordered_map

遇到 問題:題目存儲 剛開始每個題目信息佔多行,由於其中某個題目信息出問題了,導致後續題目都無法正常讀取,

解決方案:每個題目信息佔一行

拉去題目 使用C++中的文件流fstream來加載文件
iostream。處理的是控制檯IO
fstream。 處理命名文件的IO
stringstream。處理內存中string對象的IO
ifstream/ofstream。 從文件中讀/向文件中寫

ifstram(const char* filename, ios_base::openmode = ios_base::in)以讀方式打開
i以讀方式打開
o以寫方式打開

使用boost庫中split函數進行對題目字符串切割。

	**#inlude <boost/algorithm/string.hpp>**
	boost::split(存儲位置,切割對象, 切割標記,以字符還是字符串的方式切割);
	切割標記 boost::is_any_of(標記 )
	以字符切割標記boost::token_compress_on
	切割成字符串: boost::token_compress_off

使用模版技術展示Html頁面

幾個標籤:
head :描述了html的各種標籤
title:標題欄
meta: 標記了各種源數據,可以背瀏覽器識別, key -value。meta<Content-Type, content = “text/html; charset=UTF-8”>.meta標籤可以只定義一個
body: 頁面主體

標籤 :可以換行, 在html頁面中定義一個分區 a標籤: 定義超鏈接 a + href: 告訴 瀏覽器具體鏈接哪個地址 Form 標籤: 瀏覽器監測到form時, 當前頁面就可以給服務器提交數據 用戶寫完數據之後提交 action:向哪個服務器提交 method 用什麼方法提交 **enctype 提交數據的格式===>json** 代碼編輯框(textarea 可以定義名稱、行、列數、內容<>/text/area)包含一些標籤:
  名稱 name="xx"
  行   rows=“xx”
  列   cols=“xx”
提交標籤:
〈input〉
	數據類型(提交submit)數據值:展示在頁面
	formenctype(回覆蓋前面的數據格式)

google提供 ctemplate:

可以使邏輯和界面分離,後臺負責計算,在使用模版技術將計算後的值填充到預定義的html頁面中

兩個部分:
1 模版:界面的展示形式
2 數據字典:填充模版的數據

四種標記:
1 變量: {{變量名}}
2 片段: {{#片段名}}
3 包含: {{>模版名稱}} 一個模版中包含另一個模版 很少使用
4 註釋: {{!}}
鏈接https://gitee.com/HGtz2222/ThirdPartLibForCpp/tree/master/1
實現日誌模塊

保存日誌的時間。,行號。,文件 日誌等級等信息

對時間獲取和時間格式轉換函數進行查詢

渲染三方面:

 1 渲染展示所有題目頁面
 2 渲染展示題目內容一面 
 3 渲染原因頁面(錯誤?正確?)

explict:顯示聲明。implict隱士聲明

C++ 提供正則表達式這樣的類

可以將string 分成多個string, 通過match[]可以獲取每個片段
正則表達式來匹配題目
\b單詞的分界
* 匹配任意長度字符串
\d 匹配一個個位數 \d+可以匹配高位數
\在C++中爲轉義字符,因此需要源碼轉義 R"()"
(\d+) 分組應用

《題目頁面 》

1。題目信息。
2。題目編輯框

JsonCpp主要提供三個類

json底層還是通過鍵值對來實現的
主要應下面三個類
Value
Reader
Writer

Json命名空間
Json::Value

Req 每條數據用&相連接 ,name=xxx&stdin=xxx
stdin 是form表單 ,name是題目

POST 響應階段

1。獲取關鍵信息—〉代碼
2。編譯&運行
3 將執行結果發送給瀏覽器

頭文件 #include <sys/resource.h>
struct rlimit rlt ;設置內存 alram(設置時間)
rlt.rlimit_cur //內存下線
rlt.rlimit_max// 內存上線。
RLIM_INFINITY. 無上限

setrlimit(RLIMIT_AS, &rlt); 令設置生效

遇到的問題

**遇到問題 1:**在構建渲染單個題目模版時一直不成功, 最後發現是因爲多寫了一個數據字典的片段(讓我迷惑半天)

**遇到問題 2:**一直過不了。顯示原因是被9號信號強制退出 在我思來想去之後發現 ,原來是內存設置太小了, 將內存限制改掉之後,結果正常

遇到問題 3: 版本無緣無故自己降級。導致不能運行 ; 將這條指令 source /opt/rh/devtoolset-4/enable 加到.bashrc最後一行。 再source ~/.bashrc

遇到問題 4 : 模版庫找不到鏈接庫 : 解決方案:第一步。添加環境變量, 第二步。makefile 添加 -l模版庫的所在路徑

遇到問題5 :題目存儲 剛開始每個題目信息佔多行,由於其中某個題目信息出問題了,導致後續題目都無法正常讀取,

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章