在线OJ个人项目

在线OJ个人系统

项目源码

在线OJ个人项目源码

项目描述

	类似于牛客网、LeetCode这样的做题网站,能实现代码的编写、运行与提交。

项目功能

  1. 能够保存题目,用数据库来实现题库存储
  2. 展示题目列表
  3. 展示题目的详细信息(标题、难度、题目的描述和代码模板)
  4. 在线编辑、提交、编译运行代码

项目模块

  1. 题目的存储
    进行数据库的操作:
    首先创建DBUtil类,采用单例模式创建一个DataSource 实例。目的是能够快速的获取数据库的连接和关闭。
private static volatile DataSource dataSource = null;
public static DataSource getDataSource(){
    if(dataSource == null){
        synchronized (DBUtil.class) {
            if(dataSource == null){
                dataSource = new MysqlDataSource();
                ((MysqlDataSource)dataSource).setURL(URL);
                ((MysqlDataSource)dataSource).setUser(USERNAME);
                ((MysqlDataSource)dataSource).setPassword(PASSWORD);
            }
        }
    }
    return dataSource;
}
  1. 编译运行
    模块介绍:给定Java代码文件,控制jdk进行编译和运行

首先创建CommandUtil 类:这个类里主要包含run方法,让Java代码能够去执行一个具体的指令,Runtime类和Process类,创建子进程,让子进程来执行编译和运行。

重定向:使用重定向,把进程执行完输出的内容写到指定的文件中。对标准输出和标准错误进行重定向。

if (stdoutFile != null) {
            //getInputStream得到的标准输出
            InputStream stdoutFrom = process.getInputStream();
            //通过这个对象就可以去读取到当前新进程的标准输出的内容
            FileOutputStream stdoutTo = new FileOutputStream(stdoutFile);
            //接下来就从新进程这边一次读取每个字节,写入到stdoutTo这个文件里
            while (true) {
                int ch = stdoutFrom.read();
                if (ch == -1) {
                    break;
                }
                stdoutTo.write(ch);
            }
            //文件读取完毕,关闭文件
            stdoutFrom.close();
            stdoutTo.close();
        }
        //再针对标准错误进行重定向
        if (stderrFile != null) {
            //getErrorStream 得到的是标准错误
            InputStream stderrFrom = process.getErrorStream();
            FileOutputStream stderrTo = new FileOutputStream(stderrFile);
            while (true) {
                int ch = stderrFrom.read();
                if (ch == -1) {
                    break;
                }
                stderrTo.write(ch);
            }
            stderrFrom.close();
            stderrTo.close();
        }

**进程等待:**父进程和子进程并发执行,为了确保子进程能够先执行完,先让父进程等待,

//等待新进程结束,并获取到退出码
        int exitCode = process.waitFor();
        return exitCode;

后创建一些类,把整个Java程序的编译和运行过程组合到一起:
Question 类:一次编译运行过程所需的数据(主要是要运行的代码)
Answer 类:一次编译过程产生的数据(运行结果码、错误的原因等)
FileUtil:文件读写工具类,能够方便文件的读写
Task 类:定义compileAndRun,使用这个类来实现整体的编译和运行功能。主要过程为:
(1)创建存放临时文件的目录
(2)构建所需的临时文件
(3)构建编译命令:javac -encoding utf8 ./tmp/Solution.java -d ./tmp/(-d表示在编译命令中,生成的.class文件在哪个目录中),判断编译是否出错(对应的文件是否为空),如果出错,则不再执行
(4)构建运行命令并执行:形如java -classpath ./tmp/ Solution(-classpath来指定加载路径)
判断运行是否出错(是否存在异常),如果不错,不需要去执行,即判断标准错误对应的文件是否为空;
(5)将结果包装成Answer类返回

  1. 前后端API的实现
    (1)首页显示,包含 OJ 系统的题目列表,需要一个能够显示所有题目的API
    (2)点击某个具体题目,需要显示某个题目的详细信息的API
    (3)能够实现代码的编写和提交到服务器上并编译运行的API

前端与后台的数据格式转换:
使用Gson来实现Java对象和JSON数据之间的转换。可以将一个json字符串转换为一个Java对象,或者将一个Java对象转换为json字符串

ProblemServlet 类作用:
利用重写doGet方法,解析Request对象,如果id字段为空。获取题目列表,只需要知道题目的id title level,通过调用ProblemDAO类里面的selectAll来获取到数据库中的题目列表,将它们转换成json字符串返回到前端
如果id字段不为空,就是显示某个题目的详细信息,根据获取到的id来确定。

CompileServlet 类作用:把编译框中用户编辑并提交的代码进行编译和运行并输出结果。
(1)创建两个类:CompileRequest请求对象和CompileResponse响应对象
(2)重写doPost方法:先读取请求数据中的所有数据——>解析json数据转换为CompileRequest对象——>根据CompileRequest对象的到id,按照id从数据库中读取对应题目的测试用例,再根据CompileRequest对象中用户输入的代码——>把用户代码和测试用来拼接起来,组成一个完整的可执行的代码——>创建Task对象,把组装的完整代码运行行起来——>把运行结果构造成响应数据,并写回客户端。

  1. 前端界面
    需要前端页面把后端逻辑串联起来
    系统主要有两个页面
    (1)题目列表页:主要有一个表格,显示系统中所有的题目
    (2)题目详情页:主要能显示题目的信息信息,以及一个代码编辑框

借助JQuery库,完成从网页访问服务器的操作

<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>

借助Vue框架,实现数据库的数据渲染到页面

    <!--Vue的引入-->
    <!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

项目技术

  1. HTTP:发送数据请求
  2. 多进程编程:使用多进程实现代码的编译和运行
  3. JDBC:实现数据库的操作
  4. MySQL:使用MySQL数据库作为业务数据的存储
  5. AJAX:页面发送AJAX请求至后端
  6. Gson:将Java对象和JSON数据相互转换

项目的核心流程

	用户在界面的代码编辑框内输入自己的代码,用户点击提交按钮,就在后台把用户提交的代码和测试用例代码拼接起来得到完整代码,然后调用 CompileUtil 来运行 javac代码,如果代码运行正常,就把运行的相应结果返回页面,如果出现异常,就进行异常捕获,将捕获的异常和相应的结果返回
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值