實踐 | 突破傳統 OJ 瓶頸,「判題姬」接入雲函數

Online Judge 系統(簡稱 OJ)是一個在線的判題系統。用戶能夠在線提交多種程序(如C、C++、Pascal)源代碼,系統對源代碼進行編譯和執行,並經過預先設計的測試數據來檢驗程序源代碼的正確性。

隨着時代的發展,OJ 已經真正地成爲了測評工具,其做用再也不侷限爲 ACM 備戰,還有老師檢測學生能力、學生入學考試、能力評測(例如 ZJU 的 PAT)、找工做刷題和麪試(例如牛客)等,而目前 OJ 的開源框架也愈來愈多,可是不少 OJ 都是基於 HUSTOJ 進行定製或者二次開發。前端

不管是什麼方法,在關於 OJ 的衆多問題中,有一個就是:性能問題。python

說實話,一些 OJ 羣裏,總會有人問:1 核 1G 的機器,能夠同時判多少題目?能夠有多少人同時用?若是比賽,大約有多少人須要多高性能的機器?那麼『判題姬』是否只能存在傳統的宿主機中,可否經過其餘方式煥發新的生命力?git

其中一種方法,就是和現有的雲函數進行結合。github

▎簡單思路

經過雲函數實如今線編程的思路基本有兩個:面試

  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 內容。

以本題輸出結果:

這樣就實現了 Python 判題機的基本功能,此時經過騰訊云云 API 實現參數傳入,經過 Explorer進行代碼撰寫,直接接入本身的 OJ 就能夠了。

▎額外的話

雖然這是一個簡單的代碼執行工具,可是這個小工具還能夠應用在不少其餘地方。本文只是拋磚引玉,例如咱們作了一個 OJ,若是在本地跑代碼可能性能和安全性都會受到挑戰,那麼此時,放入騰訊云云函數中,就會簡單、安全、便捷得多,最主要的是騰訊雲的函數調用免費額度很高。

此外,若是臨時舉辦比賽,也不用費心費力擴容縮容,只要有雲函數,後端的主要壓力,都傳給 Serverless 搞定,這也算是發揮了雲函數的一個優點和特性。

那麼,除了在 OJ 中使用的用途,它還有啥用?簡單舉兩個例子:

  1. Anycodes、Codepad 這些在線編程網站,以前不少人就問是如何實現的。試想一下,經過這個策略,是否是很好實現了在線編程?確切說,只須要一個前端,就能夠實如今線寫代碼的一個網頁。
  2. 菜鳥教程這些網站,能夠看代碼而後點擊運行,很炫酷的功能,不少小夥伴也想往本身博客增長一個相似的功能,也能夠基於這個方法來實現。

除此以外,還有好多的用途,各位小夥伴們,快來本身挖掘吧!

歡迎關注:騰訊雲 Serverless 團隊

咱們專一於 Serverless 架構的最佳實踐!

相關文章
相關標籤/搜索