目前隨着在線編程在各行各業中的應用逐漸變多起來,傳統的OJ也煥發了新的生機,不管是學校、我的仍是某些企業,都逐漸的開始使用OJ,傳統的OJ可能只是測評,爲ACM備戰,可是隨着時代的發展,OJ已經真正的成爲了測評工具,其做用再也不侷限爲ACM備戰,還有老師檢測學生能努力,學生入學考試,能力評測(例如ZJU的PAT),找工做刷題和麪試(例如牛客)等,而目前OJ的開源框架也愈來愈多,可是不少OJ都是基於HUSTOJ進行定製或者二次開發。可是不管是什麼方法,在過去,OJ的衆多問題中,有一個就是:性能問題。說實話,我也在一些OJ羣裏,我常常會看到有人問:1核1G的機器,能夠同時判多少題目?能夠有多少人同時用?若是比賽,大約有多少人須要多高性能的機器?那麼"判題姬"是否只能存在傳統的宿主機中,可否也煥發一下新的生命力?那就是和現有的雲函數進行結合?前端
經過雲函數實如今線編程的思路基本有兩個:python
1. 每一個用戶的代碼創建一個函數,用後刪除;面試
2. 每一個語言創建一個函數,用戶傳遞代碼,每次執行;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內容。bash
以本題輸出結果:
這樣就實現了Python判題機的基本功能,此時經過騰訊云云API:cloud.tencent.com/document/ap…
實現參數傳入,經過Explorer(console.cloud.tencent.com/api/explore…)進行代碼撰寫,直接接入本身的OJ就能夠了。
其實表面上這個就是一個簡單的代碼執行工具,可是實際上這個小工具能夠在不少地方有着額外的應用,我再次只是拋磚引玉,例如咱們作了一個OJ,若是在本地跑代碼可能性能和安全性都會受到挑戰,那麼此時,咱們放入騰訊云云函數中,就會簡單、安全、便捷的多,最主要的是騰訊雲的函數調用免費額度很高,同時,若是咱們由於臨時舉辦比賽,也不用費心費力擴容縮容,只要有雲函數,後端的主要壓力,都傳給serverless搞定,這也算是發揮了雲函數的一個優點和特性,還有人說,除了這個在OJ中使用的用途,他還有啥用:
1: Anycodes,Codepad這些在線編程網站,以前不少人就問是如何實現的,試想一下,經過個人這個策略,是否是很好實現了在線編程?確切說,是否是隻須要一個前端,就能夠實如今線寫代碼的一個網頁?
2: 菜鳥教程這些網站,能夠看代碼而後點擊運行,很炫酷對吧,是否是有不少小夥伴也想往本身博客增長一個相似的功能?那麼是否是也能夠根據這個方法,來實現?
除此以外,還有好多的用途,各位小夥伴們,快來本身挖掘吧!