Online Judge 系統(簡稱 OJ)是一個在線的判題系統。用戶能夠在線提交多種程序(如C、C++、Pascal)源代碼,系統對源代碼進行編譯和執行,並經過預先設計的測試數據來檢驗程序源代碼的正確性。
隨着時代的發展,OJ 已經真正地成爲了測評工具,其做用再也不侷限爲 ACM 備戰,還有老師檢測學生能力、學生入學考試、能力評測(例如 ZJU 的 PAT)、找工做刷題和麪試(例如牛客)等,而目前 OJ 的開源框架也愈來愈多,可是不少 OJ 都是基於 HUSTOJ 進行定製或者二次開發。前端
不管是什麼方法,在關於 OJ 的衆多問題中,有一個就是:性能問題。python
說實話,一些 OJ 羣裏,總會有人問:1 核 1G 的機器,能夠同時判多少題目?能夠有多少人同時用?若是比賽,大約有多少人須要多高性能的機器?那麼『判題姬』是否只能存在傳統的宿主機中,可否經過其餘方式煥發新的生命力?git
其中一種方法,就是和現有的雲函數進行結合。github
經過雲函數實如今線編程的思路基本有兩個:面試
這兩種方法,第一種相對簡單的,可是目前對於不少雲函數服務商來講,函數數量有必定限制,並且每次執行這個操做相對比較繁瑣。shell
因此,本文采用第二種策略,創建一個函數,每次執行,用戶傳入代碼,系統執行,返回結果。編程
代碼寫入系統:json
def WriteCode(code):
try:
with open("/tmp/mytest.py", "w") as f:
f.write(code)
return True
except Exception as e:
print(e)
return False
複製代碼
執行代碼:後端
def RunCode(input_data=None):
child = subprocess.Popen("python /tmp/mytest.py", stdin=input_data, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, shell=True)
error = child.stderr.read()
output = child.stdout.read()
return error, output
複製代碼
代碼和用例處理邏輯:api
def main_handler(event, context):
if WriteCode(event["code"]):
try:
temp_list = []
for eve in event["input"]:
result = RunCode()
temp_list.append({"error":result[0].decode("utf-8"),"result": result[1].decode("utf-8"), "exception":""})
return json.dumps(temp_list)
except Exception as e:
return json.dumps({"error":"","result": "", "exception":str(e)})
複製代碼
用戶在傳入數據的時候,須要注意事件爲:
{
"code": "print('hello')",
"input": ["111","22222"]
}
複製代碼
這樣就能夠每次請求的時候把代碼傳入(code),每一個測試用例的 input 就是 input 內容。
以本題輸出結果:
這樣就實現了 Python 判題機的基本功能,此時經過騰訊云云 API 實現參數傳入,經過 Explorer進行代碼撰寫,直接接入本身的 OJ 就能夠了。
▎額外的話
雖然這是一個簡單的代碼執行工具,可是這個小工具還能夠應用在不少其餘地方。本文只是拋磚引玉,例如咱們作了一個 OJ,若是在本地跑代碼可能性能和安全性都會受到挑戰,那麼此時,放入騰訊云云函數中,就會簡單、安全、便捷得多,最主要的是騰訊雲的函數調用免費額度很高。
此外,若是臨時舉辦比賽,也不用費心費力擴容縮容,只要有雲函數,後端的主要壓力,都傳給 Serverless 搞定,這也算是發揮了雲函數的一個優點和特性。
那麼,除了在 OJ 中使用的用途,它還有啥用?簡單舉兩個例子:
除此以外,還有好多的用途,各位小夥伴們,快來本身挖掘吧!
做者介紹:
歡迎關注:騰訊雲 Serverless 團隊
咱們專一於 Serverless 架構的最佳實踐!