OJ在线评测系统 后端 代码沙箱原生实现 初始化项目

代码沙箱Java原生实现

之前我们完成了快速的前端页面开发

重点是在后端

历史问题修复

Java原生代码沙箱实现

docker代码沙箱实现

解决历史遗留问题 代码编辑器切换语言失败

监听language属性 动态更改编辑器的语言

我们在这里实现的是一个线程形式的监听

watch(
  () => props.language,
  () => {
    if (codeEditor.value) {
      monaco.editor.setModelLanguage(
        toRaw(codeEditor.value).getModel(),
        props.language
      );
    }
  }
);

代码沙箱只负责接收代码和输入

返回编译运行的结果

不负责判题 可以作为独立的项目/服务 提供给其他的需要执行代码的项目去使用

我们再来重新看一下这个接口

之后我们直接在配置中去修改

就行

以Java编程语言为主 带大家实现代码沙箱 重要的是学思想 学关键思想

新建一个Spring Boot Web项目

最终这个项目要提供一个能够执行代码 操作代码沙箱的接口

选择依赖

编辑启动配置

server:
  port: 8090

写一个启动类

package work.bigdata1421.dduojcodesandbox.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController("/")
public class MainController {

    @GetMapping("/health")
    public String healthCheck(){
        return "ok";
    }

}

测试一下

利用插件生成http接口的调用

成功打印了ok

我们接下来要把之前写的代码沙箱部分代码转移到里面

把代码沙箱的请求信息 响应信息都弄过来

还有接口

package work.bigdata1421.dduojcodesandbox;


//代码沙箱接口的定义


import work.bigdata1421.dduojcodesandbox.model.ExecuteCodeRequest;
import work.bigdata1421.dduojcodesandbox.model.ExecuteCodeResponse;

public interface CodeSandbox {

    ExecuteCodeResponse executeCode(ExecuteCodeRequest executeCodeRequest);
}

现在我们实现接口 就能自动实现了

原生 的 代码沙箱尽可能不借助第三方的库和依赖 用最干净最原始的方式实现代码沙箱

代码沙箱需要 接收代码 编译代码 执行代码

在java代码中使用javac编译完成的 执行代码使用java命令实现的

我们假定有这样一个程序

我们试一试怎么样去编译执行

这个代码并不是实际编译后的代码 是反编译后我们开发者可读的代码

就是我们的编译器实际还原出来的

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package work.bigdata1421.dduojcodesandbox;

public class SimpleCompute {
    public SimpleCompute() {
    }

    public static void main(String[] var0) {
        int var1 = Integer.parseInt(var0[0]);
        int var2 = Integer.parseInt(var0[1]);
        System.out.println(var1 + var2);
    }
}

但是我们用 -java 命令去运行字节码文件时

会出现找不到主类Main的问题

这是因为运行的时候我们会把包名带进去

我们新创建一个类 目的是去掉包名

这样就能重新编译运行

public class SimpleCompute {

    public static void main(String[] args) {
        int a = Integer.parseInt(args[0]);
        int b = Integer.parseInt(args[1]);
        System.out.println(a + b);

    }
}

这样进行操作

思考

为什么编译后的程序是中文乱码呢

命令行终端的编码是GBK 和java代码文件本身的编码 UTF-8 不一致 导致乱码

我们可以通过chcp命令查看编码 GBK是936

但是不建议大家改变终端编码来解决编译乱码 因为其他人运行你的代码还是要改变环境

你不能保证每一次都是在这个终端上启动的

兼容性很差

正确的编译代码

javac -encoding utf-8 

执行

java cp 

我们在编译运行过程中

不禁会思考

实际OJ系统中 对用户输入的代码会有一定要求 便于系统统一的管理

所以我们把用户输入的类名限制为Main

可以减少类名不一致的风险

public class Main {

    public static void main(String[] args) {
        int a = Integer.parseInt(args[0]);
        int b = Integer.parseInt(args[1]);
        System.out.println(a + b);

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是一只多多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值