基于java开发的在线OJ系统

2 篇文章 1 订阅
订阅专栏

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


项目背景

在线OJ系统实现像LeetCode,牛客网等在线oj网站所提供的的核心功能,可以实现在线做题,在线判题等功能。


一、项目说明

1.项目平台与技术栈

  • 技术栈:Servlet、Mysql、Runtime,多进程
  • 平台与环境:Windows、IDEA、Maven、Tomcat

2.项目功能

  • 题目列表页:展示题目id,题目标题,题目难易程度
  • 题目详情页:展示某个题的详细信息+代码编辑框
  • 提交并运行题目
  • 查看运行结果

二、项目演示

1.进入题目列表页

在这里插入图片描述

在这里插入图片描述

2.进入题目详情页

在这里插入图片描述

3.代码编辑框

在这里插入图片描述

4.提交代码并运行

在这里插入图片描述

三、项目模块划分

1.编译运行模块(compile)

此模块主要用来能让用户进行题目的编译和运行的操作。本模块里边有大致划分为四个模块。

1)执行命令模块(CommandUitl):

这个类里边完成的功能就是能进行编译和运行的指令。要进行编译和运行我们就要创建一个新的进程(子进程),用到的技术有单例设计模式、多进程。

  • 里面用run方法来实现这个模块,传入三个参数:指令,将标准输入,输出写入到哪个文件中。
    想实现编译运行,就首先需要传入一个指令,其次指令编译运行后,有三种状态:编译运行都成功,编译成功运行失败,编译失败。因此需要获取到标准输出,将其写入到一个文件中,表示编译运行都成功;获取标准错误,将其写入到一个文件,表示编译运行时的错误。

  • 单例设计模式和多进程:使用Runtime.exec方法,创建子进程。其参数表示一个可执行程序的路径,执行这个方法,就会把指定的路径的可执行程序,创建出进程并执行。同时Runtime在JVM中是一个单例模式。

  • 子进程创建后,父进程要结束的话,要等待子进程结束后才能最终结束所有进程。所以要进行等待子进程的结束,用的是 .waitFor()方法。

  • 不管是标准输出还是标准错误里边的内容,我们都采用重定向,即将两个里边的内容放在我们重新创建的文件中,方便后边对文件的读写操作。

public class CommandUtil {
    public static int run(String cmd, String stdoutFile, String stderrFile){
        try {
            Process process=Runtime.getRuntime().exec(cmd);
            if (stdoutFile!=null){
                InputStream stdoutFrom=process.getInputStream();
                FileOutputStream stdoutTo=new FileOutputStream(stdoutFile);
                while (true){
                    int ch=stdoutFrom.read();
                    if (ch==-1){
                        break;
                    }
                    stdoutTo.write(ch);
                }
                stdoutFrom.close();
                stdoutTo.close();
            }

            if (stderrFile!=null){
                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;
        } catch (IOException |InterruptedException e){
            e.printStackTrace();
        }
        return 1;
    }

2)用户编译模块(Question):

当点进具体的题目时,用户编辑代码。因此这个模块完成的功能是用户代码的输入。只需要定义code即可。

public class Question {
    private String code;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
}

3)运行结果模块(Answer):

这个模块用来反馈运行结果给用户,结果包含错误码error,出错原因reason,标准输出信息stdout,标准错误信息stderr。

  • 约定error为0表示编译运行都ok,为1编译出错,为2运行出错。reason为出错的提示信息。
public class Answer {
   private int error;

   public String getReason() {
       return reason;
   }

   public void setReason(String reason) {
       this.reason = reason;
   }

   private String reason;

   public String getStderr() {
       return stderr;
   }

   public void setStderr(String stderr) {
       this.stderr = stderr;
   }

   public String getStdout() {
       return stdout;
   }

   public void setStdout(String stdout) {
       this.stdout = stdout;
   }

   private  String stdout;
   private  String stderr;

   public int getError() {
       return error;
   }

   public void setError(int error) {
       this.error = error;
   }

   @Override
   public String toString() {
       return "Answer{" +
               "error=" + error +
               ", reason='" + reason + '\'' +
               ", stdout='" + stdout + '\'' +
               ", stderr='" + stderr + '\'' +
               '}';
   }
}

4)编译运行整个过程(Task):

每次的编译运行,都用Task类来完成,里面提供的核心方法为compileAndRun。参数为要编译运行的java源代码。返回值表示编译运行的结果。

  • 一次编译运行过程中,会产生很多临时文件,要编译运行的临时文件,编译出错的临时文件、运行出错的标准错误文件、标准输出的临时文件等等。我们将这些临时的文件放在一个目录下,方便后边进程间通信。
    考虑到会有多个人进行此系统的操作。因此要保证每一个用户生成的临时文件都有唯一的目录。用UUID来生成唯一目录。
  • java中类名和文件名要一致,因此code字符串的类名字,就要和写入的文件名一致。约定:类名和文件名都叫做Solution
  • 创建子进程,调用javac进行编译,编译时需要有一个.java文件,因此把question中的code写入到一个Solution.java文件中。编译完成后产生一个.class文件。
    创建子进程,执行java运行命令,也就是运行刚编译好的.class文件。父进程获取到刚才编译执行的结果,并打包成Answer对象。
    父进程获取到刚才编译执行的结果,并打包成Answer对象。
  • 写一个FileUtil类,提供两个方法,一个负责读取整个文件内容,返回一个字符串readFile,另一个方法负责写入整个字符串到文件中writeFile
public class Task {
   //通过一组常量来约定临时文件的名字
   //这个表示所有临时文件所在的目录
   private  String WORK_DIR="./tmp/";
   //约定代码的类名
   private   String CLASS=null;
   //要编译的代码文件
   private   String CODE=null;
   //存放编译错误信息的文件
   private   String COMPILE_ERROR=null;
   //存放运行时的标准输出
   private   String STDOUT=null;
   //存放运行时标准错误
   private   String STDERR=null;


   public Task(){
       WORK_DIR="./tmp/"+ UUID.randomUUID().toString()+"/";
       CLASS="Solution";
       CODE=WORK_DIR+"Solution.java";
       COMPILE_ERROR=WORK_DIR+"compileError.txt";
       STDOUT=WORK_DIR+"stdout.txt";
       STDERR=WORK_DIR+"stderr.txt";
   }


   public Answer compileAndRun(Question question){
       Answer answer=new Answer();
       File workDir=new File(WORK_DIR);
       if (!workDir.exists()){
           workDir.mkdirs();
       }
       //1.把question中的code写入到一个Solution.java文件中
       FileUtil.writeFile(CODE,question.getCode());
       //2.创建子进程,调用javac进行编译,编译时候需要有一个.java文件
       //    如果编译出错,javac就会把错误信息给写入到stderr里,就可以用一个专门的文件来保存compileError.txt
       //需要先把编译命令构造出来
       String compileCmd=String.format("javac -encoding utf8 %s -d %s",CODE,WORK_DIR);
       System.out.println("编译命令"+compileCmd);
       CommandUtil.run(compileCmd,null,COMPILE_ERROR);
       //如果编译出错了,错误信息就被记录到COMPILE_ERROR这个文件中,没有出错,空文件
       String compileError= FileUtil.readFile(COMPILE_ERROR);
       if (!compileError.equals("")){
           //编译出错,返回Answer
           System.out.println("编译出错");
           answer.setError(1);
           answer.setReason(compileError);
           return answer;
       }
       //编译正确
       String runCmd=String.format("java -classpath %s %s",WORK_DIR,CLASS);
       System.out.println("运行命令"+runCmd);
       CommandUtil.run(runCmd,STDOUT,STDERR);
       String runError= FileUtil.readFile(STDERR);
       if (!runError.equals("")){
           System.out.println("运行出错");
           answer.setError(2);
           answer.setReason(runError);
           return answer;
       }
       answer.setError(0);
       answer.setStdout(FileUtil.readFile(STDOUT));
       return answer;

   }

2.题目管理模块(problem):

这个模块设计了数据库,封装了数据库操作。此模块实现的功能进行题目的插入、删除、题目列表页的显示和题目详情页的显示。

1)与数据库建立连接

写一个类DBUtil:封装和数据库之间的连接操作。

public class DBUtil {
    private static final String URL="";
    private static final String USERNAME="";
    private static final String PASSWORD="";

    private static  volatile DataSource dataSource=null;

    private  static DataSource getDataSource(){
        if (dataSource==null){
            synchronized (DBUtil.class){
                if (dataSource==null){
                    MysqlDataSource mysqlDataSource=new MysqlDataSource();
                    mysqlDataSource.setURL(URL);
                    mysqlDataSource.setUser(USERNAME);
                    mysqlDataSource.setPassword(PASSWORD);
                    dataSource=mysqlDataSource;
                }
            }
        }
        return dataSource;
    }
    public static Connection getConnection() throws SQLException{
        return getDataSource().getConnection();
    }

    public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet) {
        if (resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

2)题目实体类Problem:

这个类是一个实体类,表示的是数据库中的一条记录就对应的是网页上边显示的每一个实例。里边的属性有:题目id,标题,难度,描述,模板代码,测试代码。

public class Problem {
    private int id;
@Override
    public String toString() {
        return "Problem{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", level='" + level + '\'' +
                ", description='" + description + '\'' +
                ", templateCode='" + templateCode + '\'' +
                ", testCode='" + testCode + '\'' +
                '}';
    }

    private String title;
    private String level;
    private String description;
    private String templateCode;
    private String testCode;
}

3)数据访问类PboblemDAO:

一个Problem对象,就对应着表中的一条记录,还需要针对这个表进行“增删查改”,创建一个ProblemDAO来负责进行增删查改。

  • 增 (insert):主要用的是JDBC来操作数据库,基本步骤是:和数据库建立连接、拼装sql、执行sql、断开连接。

  • 删(delete):同上,还是JDBC操作数据库,基本步骤:和数据库建立连接、拼装sql、执行sql、断开连接。

  • 题目列表页的展示(selectAll):展示题目列表页,题目id,标题,难易程度等。其JDBC操作基本步骤是:建立连接、拼装sql、执行sql、遍历结果集、断开连接。

  • 题目详情展示页(selectOne):展示一个题目的所有信息(题目序号、标题、难度级别、题目描述、模板代码、测试代码)。还是要给用户打开页面进行结果集的展示JDBC操作步骤:建立连接、拼装sql、执行sql、遍历结果集、断开连接。

public class ProblemDAO {
    public void insert(Problem problem){
        Connection connection= null;
        PreparedStatement statement=null;
        try {
            //与数据库建立连接
            connection = DBUtil.getConnection();
            //构造SQL语句
            String sql="insert into oj_table values(null,?,?,?,?,?)";
            statement=connection.prepareStatement(sql);
            statement.setString(1,problem.getTitle());
            statement.setString(2,problem.getLevel());
            statement.setString(3,problem.getDescription());
            statement.setString(4,problem.getTemplateCode());
            statement.setString(5,problem.getTestCode());
            //执行SQL
            int ret=statement.executeUpdate();
            if (ret!=1){
                System.out.println("题目新增失败");
            }else {
                System.out.println("题目新增成功");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(connection,statement,null);
        }
    }
    public void delete(int id){
        Connection connection= null;
        PreparedStatement statement=null;
        try {
            //和数据库建立连接
            connection=DBUtil.getConnection();
            //拼装sql语句
            String sql="delete from oj_table where id = ?";
            statement=connection.prepareStatement(sql);
            statement.setInt(1,id);
            //执行SQL
            int ret=statement.executeUpdate();
            if (ret!=1){
                System.out.println("删除题目失败");
            }else {
                System.out.println("删除题目成功");
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            DBUtil.close(connection,statement,null);
        }
    }
    public List<Problem> selectAll(){
        List<Problem> problems=new ArrayList<>();
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            //和数据库建立连接
            connection=DBUtil.getConnection();
            //拼装SQL
            String sql="select id,title,level from oj_table";
            statement=connection.prepareStatement(sql);
            //执行SQL
            resultSet=statement.executeQuery();
            //遍历resultSet
            while (resultSet.next()){
                Problem problem=new Problem();
                problem.setId(resultSet.getInt("id"));
                problem.setTitle(resultSet.getString("title"));
                problem.setLevel(resultSet.getString("level"));
                problems.add(problem);
            }
            return problems;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            DBUtil.close(connection,statement,resultSet);
        }
        return null;
    }
    public Problem selectOne(int id){
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            connection=DBUtil.getConnection();
            String sql="select * from oj_table where id = ?";
            statement=connection.prepareStatement(sql);
            statement.setInt(1,id);
            resultSet=statement.executeQuery();
            if (resultSet.next()){
                Problem problem=new Problem();
                problem.setId(resultSet.getInt("id"));
                problem.setTitle(resultSet.getString("title"));
                problem.setLevel(resultSet.getString("level"));
                problem.setDescription(resultSet.getString("description"));
                problem.setTemplateCode(resultSet.getString("templateCode"));
                problem.setTestCode(resultSet.getString("testCode"));
                return problem;
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            DBUtil.close(connection,statement,resultSet);
        }
        return null;
    }

3. API模块:

此模块用来实现前后端的交互。主要由两个类构成,CompileServlet,ProblemServlet

  • 要实现交互的页面:
    题目列表页:向服务器请求题目列表
    题目详情页:展示题目详细要求,向服务器请求,获取指定题目的详细信息。
    题目详情页:向服务器发送用户当前编写的代码,并获取到结果。
  • 具体设计前后端交互的API:通过JSON格式来组织,引入第三方库Jackson

1)CompileServlet类(获取用户提交代码后的结果)

  • 编译请求CompileRequest:向服务器发送用户编写的代码,服务器只需要获取题目id对应到题目和用户提交的代码code即可。
  • 编译响应CompileResponse:在给服务端发送请求之后,返回响应,响应里边包含返回码error(0编译运行都ok,1表示编译出错,2表示运行出错)、错误原因reason、标准输出(测试用例的输出情况,包含了通过几个测试用例这样的信息)。
  • 编译Servlet:CompileServlet
    这个模块主要是要完成数据格式之间的转换,完成客户端和服务端之间的相互解析响应全过程。
    (1)先读取请求的正文,按照JSON格式进行解析
    (2)根据id从数据库中查找到题目的详情,得到测试用例代码
    (3)把用户提交的代码和测试用例的代码,给拼接为一个完整代码
    (4)创建一个Task实例,调用里面的compileAndRun,来进行编译运行。
    (5)根据Task运行的结果,包装成一个HTTP响应
@WebServlet("/compile")
public class CompileServlet extends HttpServlet {
    static class CompileRequest {
        public int id;
        public String code;
    }

     private class CompileResponse {
        public  int error;
        public  String reason;
        public  String stdout;
    }
    private ObjectMapper objectMapper=new ObjectMapper();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("用户的当前工作目录:"+System.getProperty("use.dir"));
        CompileRequest compileRequest=null;
        CompileResponse compileResponse=new CompileResponse();
        try {
            resp.setStatus(200);
            resp.setContentType("application/json;charset=utf8");
            // 1.先读取请求的正文,并按照JSON 格式进行解析
            String body = readBody(req);
            compileRequest=objectMapper.readValue(body,CompileRequest.class);
            // 2.根据id从数据库中查找到题目的详情=> 得到测试用例代码
            ProblemDAO problemDAO=new ProblemDAO();
            Problem problem=problemDAO.selectOne(compileRequest.id);
            if (problem==null){
                throw new ProblemNotFoundException();
            }
            String testCode=problem.getTestCode();
            String requestCode=compileRequest.code;
            // 3.把用户提交的代码和测试用例代码,给拼接成个完整的代码.
            String finalCode=mergeCode(requestCode,testCode);
            if (finalCode==null){
                throw new CodeInValidException();
            }
            //System.out.println(finalCode);
            // 4.创建一个Task 实例,调用里面的compileAndRun 来进行编译运行
            Task task=new Task();
            Question question=new Question();
            question.setCode(finalCode);
            Answer answer=task.compileAndRun(question);
            // 5.根据Task运行的结果,包装成一个HTTP响应
            compileResponse.error=answer.getError();
            compileResponse.reason=answer.getReason();
            compileResponse.stdout=answer.getStdout();
        } catch (ProblemNotFoundException e) {
            compileResponse.error=3;
            compileResponse.reason="确认没有找到指定题目 id="+compileRequest.id;
        } catch (CodeInValidException e) {
            compileResponse.error=3;
            compileResponse.reason="提交的代码不符合要求";
        }finally {
            String respString=objectMapper.writeValueAsString(compileResponse);
            resp.getWriter().write(respString);
        }


    }
    private static String mergeCode(String requestCode,String testCode){
        int pos=requestCode.lastIndexOf("}");
        if (pos==-1){
            return null;
        }
        String subStr=requestCode.substring(0,pos);
        return subStr+testCode+"\n}";
    }

    private static String readBody(HttpServletRequest req) throws UnsupportedEncodingException {
        // 1.先根据请求头里面的ContentLength 获取到body 的长度(单位是字节)
        int contentLength=req.getContentLength();
        // 2.按照这个长度准备好一个byte[].
        byte[] buffer=new byte[contentLength];
        // 3.通过req 里面的getInputStream 方法,获取到body 的流对象。
        try(InputStream inputStream=req.getInputStream()){
            // 4.基于这个流对象,读取内容,然后把内容放到byte[] 数组中即可.
            inputStream.read(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 5.把这个byte[] 的内容构造成个String
        return new String(buffer,"utf8");
    }
}

2)ProblemServlet类

这个模块是用来展示题目列表页和题目详情页的。

  • doGet方法:通过创建problemDao请求对象,向服务端发起请求,在数据库中查找结果并转化成Json格式最终返回给客户端界面。完成的功能是展示题目列表页和题目详情页。
@WebServlet("/problem")
public class ProblemServlet extends HttpServlet {
    private ObjectMapper objectMapper=new ObjectMapper();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(200);
        resp.setContentType("application/json;charset=utf8");
        ProblemDAO problemDAO=new ProblemDAO();

         String idString=req.getParameter("id");
         if (idString==null||"".equals(idString)){
             List<Problem> problems=problemDAO.selectAll();
             String respString=objectMapper.writeValueAsString(problems);
             resp.getWriter().write(respString);
         }else{
             Problem problem=problemDAO.selectOne(Integer.parseInt(idString));
             String respString=objectMapper.writeValueAsString(problem);
             resp.getWriter().write(respString);
         }
    }
}

总结

以上就是今天要讲的内容,本文介绍了在线oj系统的核心功能:展示题目列表页,题目详情页,提交代码和显示结果如何实现。至于前端页面,小伙伴们可以自行实现想要的页面。欢迎大家讨论。

java8源码-eagle-oj:开源在线编程训练平台Eagle-OJ,一键Docker快速搭建,讨论QQ群(715215353)
06-04
java8 源码 Eagle-OJ 开源在线编程训练平台,支持Docker一键快速搭建部署 近期更新计划 因为最近事情比较多,新版本出来的比较慢 安装文档 功能简介 记录用户每一次提交的代码(需开启阿里云OSS存储功能) 支持多语言判卷(Python2.7,Python3.5,C++,C,Java8) 比赛支持ACM/OI模式,时间上支持限时和不限时模式 小组功能可以管理学生,开设小组赛 功能演示
开源bbs源码java-hustoj:在线编程裁判系统
06-06
开源 bbs 源码 java hustoj forked from Introduction 简介 HUSTOJ is an GPL FreeSoftware?. HUSTOJ 是采用GPL的自由软件。 因googlecode受阻,最新更新迁移至此。 注意:基于本项目源码从事科研、论文、系统开发,必须在文中或系统中表明来自于本项目的内容和创意,否则请勿使用本项目源码。 使用本项目源码和freeproblemset题库请尊重程序员职业和劳动 新用户必看 README 和 FAQ 快速安装指南: 1、安装Ubuntu 2、执行如下命令 sudo apt-get update sudo apt-get install subversion sudo svn co https://github.com/iMyon/hustoj/trunk/trunk/install hustoj cd hustoj sudo bash install-interactive.sh 3、安装后访问服务器80端口上的web服务JudgeOnline目录 例如 w3m http://127.0.0.1/JudgeO
Java oj 习题 计算奇数和,及如何进行输入输出
weixin_73793168的博客
03-20 299
以上只是Java输入输出的基础,实际上Java的IO系统非常丰富和强大,提供了许多其他的类和接口用于更复杂的输入输出操作,如格式化输出、对象序列化、网络通信等。以下是一些基本示例,展示了如何在Java中进行输入和输出。除了控制台输入输出外,Java还提供了对文件的读写操作。,这是一个检查型异常,必须在代码中显式处理。请编写程序,计算“1+3+5+7+...+N”的值。注意:在使用文件输入输出时,需要处理可能发生的。在Java中,进行输入和输出通常使用。在Java中,输出通常使用。Java中的输入通常通过。
开源在线评判系统HUSTOJ
03-20
开源在线评判系统,ICPC/ACM竞赛专用,架设在自己的服务器上即可实现题目上传,代码提交及实时评判
JavaWeb 项目 --- 在线 OJ 平台 (一)
wwzzzzzzzzzzzzz的博客
05-23 3850
文章目录1. 项目设计2. 项目效果图3. 创建项目① 创建一个 maven 项目② 创建 webapp/WEB-INF/web.xml③ 写入 web.xml④ 导入依赖⑤ 验证 创建 HelloServlet⑥ 运行 smartTomcat4. 项目的前置知识4.1 文件的IO操作示例: 了解读文件写文件4.2 进程和线程标准输入 标准输出 标准错误示例: 进程创建示例: 进程等待5. 编译功能的实现创建一个 CommandUtil 类创建一个类 Question创建一个类 Answer创建一个类 Fi
在线OJ项目(1)------实现代码编译运行功能
weixin_61518137的博客
08-28 1184
在线OJ
【项目篇1】一个在线OJ系统
weixin_56738054的博客
04-13 3472
回顾一下我们常见的OJ平台,例如:leetcode,牛客等等,他们都有哪些功能?
JavaEE & Spring & 项目】在线 OJ 系统
zxj20041003的博客
02-24 1142
项目的基本需求题目列表页题目详情页``代码编辑框提交给服务器编译运行展示结果利用了多进程编程, 基于多进程编程(Runtime) 封装了一个 CommandUtils 类, 就可以创建进程执行一个具体的任务, 同时把输出结果记录到指定的文件中;创建了一个 Task 类, 调用 CommandUtils 封装了一个 完整的 “编译-运行” 过程, 后面又给 Task 类扩充了一个基于黑名单的安全代码校验设计了数据库, 封装了数据库操作, OJInfo, OJMapper。
编程语言 Java 实现的在线 OJ 系统
03-01
内容概要:基于 Servlet 实现的在线 OJ 系统,包含题目的列表页和题目详情页,类似于leetcode,可以在线编辑代码,提交代码并对用户提交的代码进行编译和运行,返回运行结果或错误信息 适合人群:初学 Java 的 Servlet 框架,想要用一个项目来进行练习巩固 能学到什么:1.可以学习到项目的创建过程 2.可以学习到进程的创建,以及通过创建的进程运行指令 3.可以学习到对文件的输入和输出操作,可以将数据写入到文件中或者从文件中读出数据 4.可以学习到如何通过 JDBC 来操作数据库 5.可以学习到用户提交的代码是如何在后端编译和运行,以及如何向用户返回得到的结果 6.可以学习到如何进行前后端交互
从0到1搞定在线OJ
纪宁的博客
06-04 3263
在线OJ系统的解读及应对方法
基于Java的实训在线OJ系统安卓端设计源码
03-29
这是一个基于Java的实训在线OJ系统安卓端设计,使用JavaJavaScript、HTML和CSS语言开发,包含147个文件。主要文件类型包括38个Java源文件、28个JavaScript文件、23个HTML文件、12个JPG图片文件、12个PNG图片文件、...
在线评测系统
06-21
在线评测系统,数据采用文件系统存储,架构清晰,采用MVC框架。并使用多线程及网络编程技术实现网络版,是本人学习javaSE部分集成之作。希望能帮助到后来的同学!!!
一个基于vue+springboot 的oj系统 Zoj.zip
最新发布
05-15
该项目利用了基于springboot + vue + mysql的开发模式框架实现的课设系统,包括了项目的源码资源、sql文件、相关指引文档等等。 【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理...
基于SpringBoot和SpringCloud和Vue的在线代码评委系统(OJ).zip
08-30
基于SpringBoot和SpringCloud和Vue的在线代码评委系统(OJ).zip基于SpringBoot和SpringCloud和Vue的在线代码评委系统(OJ).zip基于SpringBoot和SpringCloud和Vue的在线代码评委系统(OJ).zip基于SpringBoot和Spring...
【项目】在线OJ(基于Servlet实现)
Xian meng在努力呐-的博客
04-04 1070
实现简易的在线OJ项目(目前只有列表页和详情页),可以实现代码的提交以及结果的展示
java oj_用java怎么做oj
weixin_35935279的博客
02-12 887
示例代码 :public static void main(String[] args) {System.out.println("Start...");ExecutorService exec = Executors.newCachedThreadPool();testTask(exec, 15); //任务成功结束后等待计算结果,不需要等到15秒testTask(exec, 5); //只...
OnlineJudge大集合
weixin_30432007的博客
11-02 3810
什么是OJ Online Judge系统(简称OJ)是一个在线的判题系统。用户可以在线提交程序源代码,系统对源代码进行编译和执行,并通过预先设计的测试数据来检验程序源代码的正确性。 一个用户提交的程序在Online Judge系统下执行时将受到比较严格的限制,包括运行时间限制,内存使用限制和安全限制等。用户程序执行的结果将被Online Judge系统捕捉并保存,然后再转交给一个裁判程序...
开源评测系统hustoj-代码解读
weixin_30500473的博客
08-26 931
非常感谢zhblue贡献了这么美丽的代码 为了开发适合自己学校的oj,努力研读代码中,不断的百度,调试,测试 对ubutun,linux的各种文件系统,进程系统,c编程都学习了不少 给大家分享下,希望能减少重复的工作量 注释里有很多不足,不到位的地方,请批评指正 /* * Copyright 2008 sempr <iamsempr@gmail.com...
C++开源跨平台OJ系统判题核心—— FreeJudger(一)
热门推荐
一个人的战争
02-03 1万+
C++开源跨平台OJ系统判题核心—— FreeJudger By 马冬亮(凝霜  Loki) 一个人的战争(http://blog.csdn.net/MDL13412) 项目背景 本项目是为作者所在学校搭建OJ系统时衍生出来的一个项目,由于我的学弟、学妹们对Linux系统不熟悉,为了我们这批人毕业了以后,有人能维护OJ系统,因此选用了可以运行在Windows平台的开源OJ系统
如何自己开发一个oj系统
05-18
开发一个 OJ 系统,需要遵循以下步骤: 1. 确定需求:首先需要明确你的 OJ 系统的目的、面向的用户以及具体的功能需求。 2. 设计数据库:根据需求设计数据库,包括数据表、字段、关系等。 3. 实现前端界面:使用 HTML、CSS、JavaScript 等技术实现用户界面。 4. 实现后端逻辑:使用 PHP、Java、Python 等语言编写后端代码,实现 OJ 系统的核心逻辑,包括用户登录、题目管理、提交判题等功能。 5. 判题系统:实现一个判题系统,可以使用任何一种编程语言实现。 6. 部署和测试:将 OJ 系统部署到服务器上,进行测试和调试。 7. 安全性:OJ 系统需要考虑到安全性,包括防止 SQL 注入、XSS 攻击等。 8. 维护和优化:OJ 系统上线后需要进行维护和优化,包括修复 bug、增加新功能、提高性能等。 以上是一个简单的开发 OJ 系统的步骤,具体的实现方式和技术选择可能因项目而异。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • 关于项目的测试 3504
  • 基于java开发的在线OJ系统 1796
  • 2021-01-11 136
  • 初识Java 109

分类专栏

  • 项目 2篇
  • 笔记 2篇

最新评论

  • 基于java开发的在线OJ系统

    低调点哈哈哈: 分享下源码学习一下呗,有偿!!!

  • 基于java开发的在线OJ系统

    不会编程的小孩子: 挂个gitee学习一下呗

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • 关于项目的测试
  • 初识Java
  • 2021-01-11
2022年2篇
2021年2篇

目录

目录

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值

深圳SEO优化公司哈密网站改版福永推广网站价格襄阳网络推广报价定西网站改版报价诸城设计公司网站报价亳州网站搭建价格阿里百姓网标王推广哪家好黔东南百姓网标王推广报价吉祥品牌网站设计公司广州网站设计模板哪家好南澳网络营销价格南澳网站制作报价嘉兴seo惠州百度爱采购公司晋中关键词按天计费报价海南百度竞价公司松原seo优化推荐丽江百姓网标王价格湖州网站关键词优化价格保山营销网站公司永州高端网站设计安康网站开发报价自贡外贸网站设计淮南关键词按天计费公司白山网络广告推广公司玉林高端网站设计推荐吉林网站开发公司汉中企业网站改版价格阜新百搜标王推荐坪地设计网站哪家好歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化