思維導圖 ,一看立馬懂
思維導圖大綱:
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 加載題目的配置文件,使用數據結構
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: 頁面主體
名稱 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 :題目存儲 剛開始每個題目信息佔多行,由於其中某個題目信息出問題了,導致後續題目都無法正常讀取,