做了这么多算法题,怎么去写一个测试代码程序呢

测试代码程序

  • 前言
  • 小知识
    • 类加载器
    • Process
  • 具体实现
    • 文本生成java文件
      • 主要代码
    • 将java文件编译为class文件
      • 主要代码
    • 自定义类加载器导入class文件
      • 主要代码
    • 接口代码
      • 主要代码
  • 成果

前言

这几天刚好了解了一部分类加载器的知识,与此同时博主又想来大三那年老师留下的作业,自己写一个做题网站,当时一点思路没有,但咱已不是当年的自己了
做了这么多算法题,怎么去写一个测试代码程序呢_第1张图片
这灵感像吃了泻药一样,一泻千里,接下来说一下思路和实现。

小知识

类加载器

众所周知,类加载器有启动器类加载器,扩展器类加载器以及自定义类加载器,他们分管不同的区域,具体的知识,该文章就不进行赘述了,以后会整理一篇详细的类加载知识。

这里我们只需要知道,类加载器就是将java文件加载到我们的jvm中,从而我们可以采用反射方式对其进行操作

本文就是采用自定义的类加载器来加载我们外部的java文件

Process

process就是为了实现发起一个进程,主要作用就是将我们生成的java文件转换为class文件,然后再由类加载器将class文件加载

具体实现

文本生成java文件

这里采用的是将h5的textarea的内容传递给接口,由后端接口直接把内容导入到java文件中

主要代码

文件工具类
这里就是实现文本写入到文件中

   bufferedWriter=new BufferedWriter(new FileWriter("D://java//xiaow.java"));
            bufferedWriter.write(info);
            bufferedWriter.close();

将java文件编译为class文件

需要采用process发起一个进程,并且执行命令生成class文件,命令如下

javac **.java

主要代码

java文件编译为class文件

  public static void execCmd(String cmd) throws Exception {
        Process process = null;
        try {
            // 执行命令, 返回一个子进程对象(命令在子进程中执行)
            process = Runtime.getRuntime().exec(cmd, null);
            // 方法阻塞, 等待命令执行完成(成功会返回0)
            process.waitFor();

        } finally {

            // 销毁子进程
            if (process != null) {
                process.destroy();
            }
        }

    }

自定义类加载器导入class文件

主要代码

这里采用是自定义的类加载器,定义如下

public class MyClassLoader extends ClassLoader {
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        try {
            //存放class文件的位置
            String path = "D:\\java\\" + name + ".class";
            ByteArrayOutputStream out=new ByteArrayOutputStream();
            //复制文件到out输出流中
            Files.copy(Paths.get(path),out);
            byte[] bytes = out.toByteArray();
            //由byte数组生成Class
            Class<?> aClass = defineClass(name, bytes, 0, bytes.length);
            return aClass;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }
   //方便外部调用
    public Class<?>  findclass(String name) throws ClassNotFoundException {
        Class<?> findclass = findClass(name);
        return findclass;
    }
}

接口代码

这里还是采用还是controller来编写接口,从而实现对上传程序的测试

主要代码

@RestController
@RequestMapping("/code")
public class CodeController {

    //测试数据集
    //博主采用写死的方式,有兴趣的可以在数据库中拿取
    private static Map<Integer,Integer> map=new HashMap<>();
    static {
        map.put(1,1);
        map.put(2,4);
        map.put(3,9);
        map.put(4,16);
        map.put(5,25);
    }
    /**
     *
     * @param java   运行代码,把包信息去掉
     * @param methodName   调用的方法名称
     * @param param     参数
     * @return
     */
    @GetMapping("/test")
    public Result test(String java,String methodName,String param){
        boolean write = FileUtil.write(java);
        if(write){
            try {
                boolean flag=true;
                //编译上传的java代码生成class文件
                ProcessUtil.execCmd("javac d:/java/xiaow.java");
                MyClassLoader myClassLoader=new MyClassLoader();
                //使用我们自己定义的类加载器进行加载刚刚生成的class
                Class<?> xiaow = myClassLoader.findclass("xiaow");
                //如下都是反射内容 获取测试方法
                Object o = xiaow.newInstance();
                //这里是写死的,大家可以在数据库中获取
                Method method = xiaow.getMethod(methodName,Integer.class);
                // 对该方法进行测试
                Set<Integer> set = map.keySet();
                for (Integer integer : set) {
                    Integer integer1 = map.get(integer);
                    Integer invoke = (Integer) method.invoke(o,integer);
                    if(!invoke.equals(integer1)){
                        return Result.fail("WA");
                    }
                }

                return Result.succ("AC");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return Result.fail("测试失败");

    }

}

成果

然后再写一下前端,就结束了

艾玛,做了这么多年题,可算AC了
做了这么多算法题,怎么去写一个测试代码程序呢_第2张图片

你可能感兴趣的:(java,后端,java,后端)