首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

前端輸入 Java 代碼後端執行?在線判題系統(OJ)核心原理與安全實現

     編輯:程式設計疑難解答

結論:完全可行,這就是在線判題系統(OJ)的核心模式

如 LeetCode、Codeforces、洛谷、各大廠面試筆試平台,本質都是:前端提交代碼字符串 → 後端動態編譯/解釋執行 → 沙箱隔離 → 返回結果。

核心技術棧

  1. 動態編譯:Java Compiler API (javax.tools.JavaCompiler) 或調用 javac 進程,將字符串編譯為 .class 字節碼。
  2. 類加載與執行:自定義 ClassLoader 定義類,反射調用 main 或指定方法。
  3. 安全沙箱(關鍵):
    • SecurityManager(JDK17 已移除):禁止文件讀寫、網絡訪問、系統屬性修改、線程操作、Runtime.exec。
    • 容器隔離:Docker 容器限制 CPU、內存、磁盤、網絡、進程數(--cpus=1 --memory=256m --pids-limit=50 --network=none)。
    • Seccomp/Bpf:系統調用白名單,禁用危險調用(ptrace, clone, execve 等)。
    • 獨立用戶/命名空間:以無權限用戶運行,Mount/UTS/IPC/PID/User Network Namespace 隔離。
  4. 資源限制與超時控制:
    • 編譯/運行超時殺進程(Future.get(timeout) + Process.destroyForcibly())。
    • 限制輸出大小(防止輸出炸彈)。
    • 限制遞歸深度、線程數。

簡化版 Java 代碼執行 Demo(僅演示原理,生產環境不可直接用)

public class SimpleJavaRunner {
    public static String run(String javaCode, String className, String[] args) throws Exception {
        // 1. 寫入臨時文件
        Path tempDir = Files.createTempDirectory("oj_");
        Path srcFile = tempDir.resolve(className + ".java");
        Files.write(srcFile, javaCode.getBytes(StandardCharsets.UTF_8));

        // 2. 編譯
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        int compileResult = compiler.run(null, null, null, srcFile.toString());
        if (compileResult != 0) return "Compilation Error";

        // 3. 加載並運行
        URLClassLoader classLoader = new URLClassLoader(new URL[]{tempDir.toUri().toURL()});
        Class clazz = classLoader.loadClass(className);
        Method main = clazz.getMethod("main", String[].class);
        
        // 捕獲標準輸出
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PrintStream oldOut = System.out;
        System.setOut(new PrintStream(baos));
        try {
            main.invoke(null, (Object) args);
        } finally {
            System.setOut(oldOut);
        }
        return baos.toString();
    }
}

生產級開源方案推薦

  • Judge0:支持 50+ 語言,API 化,Docker 隔離,GitHub。
  • HustOJ / HydroOJ:國內高校常用,PHP/Java/Go 版本,含題目管理、比賽系統。
  • Universal Judge:Go 編寫,高性能,支持 Kubernetes 集群調度。

安全警示

絕不可直接在業務服務器運行用戶代碼!** 必須使用獨立判題機/容器集群,網絡隔離,定期銷毀重建。歷史上多起 OJ 平台被「挖礦代碼」「刪庫代碼」「反彈 Shell」攻陷,教訓慘痛。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved