首页 > 其他分享 >【持续更新】创新实训

【持续更新】创新实训

时间:2024-05-30 15:57:01浏览次数:15  
标签:容器 创新 -- 更新 judger 实训 UOJ uoj docker

项目简介

随着互联网+的生态模式和人工智能的产业化发展,程序设计已成为计算机专业乃至工科学生的必备技能之一。学生学习程序设计,不仅能提高代码水平能力,学会如何写代码,如何写好代码,而且能锻炼学生在今后面对项目开发等实际应用场景时解决问题的能力。因此,很多同学在刚刚接触到编程时往往需要练习一些简单的程序设计题目。如大一时的高级程序设计、C++程序设计等课程,老师在讲课之余往往会布置一些程序设计的习题,让同学自己去练习,在亲身实践中巩固知识,增进对编程的理解。但软件学院至今没有自己的在线评测系统,老师布置习题时往往只能选用PTA等现有平台,PTA等平台手动添加题目不便,题目往往都是经典案例,很容易就能在网络上找到相关解法,不利于同学们独立思考、独立解题。同时教师在授课的过程中往往无法根据教学进度和学生们的实际掌握程度添加适合学生练习的题目。如果学院有一个自行研发的在线评测系统,有助于教师更灵活自由地开展各种教学活动,如使用该平台可以进行上机实操的期中考试。

然而,与其他传统学科不同,程序设计可能出现的错误千变万化,有时十分隐晦。这也使得其入门门槛较高,且常常需要耗费讲师和助教大量的时间和精力帮助初学者 debug。在这样的问题背景下,我们想要获得一个AI助手,让它帮助学生进行代码纠错,从而方便了教师教学的同时提高了学生的学习效率。微软推出的 Copilot 是一款通过理解用户输入的代码注释或部分代码片段、自动生成或补全代码的AI助手。它的问世说明了大模型具备相当不错的修改和续写代码的能力。我们希望可以通过微调,得到一个更加高效的、主要面向初学者的代码纠错工具。为了生成更具教育意义的代码,我们决定使用数百道经典例题和他们相应解法的 规范代码 对 CodeGeeX2-6B 进行微调。

架构设计: 设计一个分布式系统,包括前端、后端和纠错大模型组件。
前端: 开发一个基本需求功能齐全同时对用户友好的网页界面,主要包括用户提交代码、查看纠错结果以及提供反馈信息等功能。前端会将用户的代码发送给后端,等待后端程序的处理并接受后端发送过来的纠错信息和反馈信息,并将信息以合适的方式显示在前端告知用户。
后端: 构建一个高性能的服务器端应用程序,负责接收用户提交的代码,并对代码进行评测,若评测通过,程序将会返回给前端代码通过(AC)信息。若评测无法通过,则将其发送给纠错大模型进行处理,并接受纠错信息和反馈信息,一并将这些信息发送给前端。
纠错大模型: 选择和集成一个强大的代码纠错大模型,用于自动分析和纠正用户提交的代码中的错误。这里的大模型我们选择使用清华大学开源的ChatGLM-CodeGeeX2(https://github.com/THUDM/ChatGLM-6B)。 在该模型的基础上,选用程序设计试题的专门数据,进行Fine-turning的训练(即微调)

UOJ平台的部署与学习

参照网络上UOJ平台部署的教程,进行我们自己UOJ评测平台的部署。
首先,在Linux系统下安装docker

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

sudo systemctl start docker             # 启动 docker 服务
sudo docker --version               # 检查 docker 是否正常安装

执行下面的指令来开始安装 UOJ:

sudo docker pull universaloj/uoj-system
sudo docker run --name uoj -dit -p 80:80 --cap-add SYS_PTRACE universaloj/uoj-system

接下来,UOJ将在后台运行。
稍等几分钟,访问服务器的地址,能看到UOJ正在运行了。
注册的第一个用户将被自动设为管理员。

docker的学习笔记

Docker 相当于一台虚拟机。

我们把虚拟机称作“容器(container)”,容器需要基于“镜像(image)”来运行。
容器的维护需要以下命令来实现

ocker start uoj                # 启动 uoj 容器
docker stop uoj                 # 暂停 uoj 容器
docker restart uoj              # 重启 uoj 容器

docker exec -it uoj /bin/bash   # 进入 uoj 容器的终端

docker commit uoj uoj_back:tag  # 将 uoj 容器保存为标签为 tag 的 uoj_back 镜像

docker ps -a                    # 查看所有的容器
docker images                   # 查看所有的镜像
docker rm uoj                   # 删除 uoj 容器(慎用)
docker rmi uoj_back:tag         # 删除标签为 tag 的 uoj_back 镜像,

在docker中,每个容器需要基于一个镜像来运行。最开始,我们的uoj容器是基于安装过程中构建的镜像。

下面是一次典型的数据恢复:

docker commit uoj uoj_back:20170101     # 例行备份
docker commit uoj uoj_back:20170201     # 例行备份
docker commit uoj uoj_back:20170301     # 例行备份

# 3月15日,黑恶势力破坏了 uoj,uoj 容器已经无用,必须恢复

docker stop uoj
docker rm uoj                           # 删除uoj容器
docker run --name uoj -dit -p 80:80 --cap-add SYS_PTRACE  uoj_back:20170301
# 创建新的 uoj 容器,使用3月1日的备份

数据迁移:
下面的命令可以把 uoj_back 这个容器导出为 uoj.tar 这个文件:

docker save -o uoj.tar uoj_back

把 uoj.tar 复制到其他机器上,然后可以运行下面的命令导入 uoj_back 镜像:

docker load --input uoj.tar

下面是一次典型的数据迁移:

# 服务器 A:
docker commit uoj uoj_back              # 把uoj容器存储为镜像
docker save -o uoj.tar uoj_back         # 把uoj_back镜像导出
# 然后通过某些恶毒的手段把 uoj.tar 拷到服务器 B


# 服务器 B:
docker load --input uoj.tar             # 导入uoj_back镜像
docker run --name uoj -dit -p 80:80 --cap-add SYS_PTRACE  uoj_back
# 建立 uoj 容器,基于之前服务器 A 的数据,迁移完成`

系统管理

1.管理员账户
UOJ 安装完成后,注册的第一个账户会被自动设为管理员账户。

当以管理员账户登录 UOJ 后,可以依次点击页面右上角您的用户名、系统管理来进入管理界面。

管理员账户有发布公告、新建题目和比赛等权限。但是,管理员并不能参加比赛。
2.发布公告
UOJ 发布公告的套路比较神奇。

首先,将公告发布到博客当中,然后再这篇博客的地址中(形如.../blog/478)找到最后的一串数字,记作博客 id。

之后,打开管理界面,使用博客 id 添加公告。

可以置顶公告,需要注意的是,1 表示优先级最低(显示为“三级置顶”),3 表示优先级最高(显示为“一级置顶”)。
3.全局配置文件
全局配置文件中包含了网站的基础信息。要修改全局配置文件,请先进入 Docker 容器的终端。

sudo docker exec -it uoj /bin/bash

全局配置文件的路径是/var/www/uoj/app/.config.php,您可能需要用 Vim 编辑该文件。
注意,该文件是隐藏文件,您可能需要通过ls -a命令才能看到它。
您可以再全局配置文档中修改网站的标题等信息,也可以修改发送邮件的配置。发送邮件的邮箱强烈建议您使用 sina 邮箱。

这个文件大概是这个样子的:

点击查看代码
<?php
return array (
  'profile' =>                                   // 网站相关信息
  array (
    'oj-name' => 'Universal Online Judge',           // 网站全称
    'oj-name-short' => 'UOJ',                        // 网站简称
    'administrator' => 'root',                       // 管理员 id(仅在关于中显示)
    'admin-email' => 'admin@local_uoj.ac',           // 管理员邮箱(仅在关于中显示)
    'QQ-group' => '',                                // OJ QQ 交流群(仅在关于中显示)
    'ICP-license' => '',                             // ICP 备案信息
  ),
  'database' =>                                  // 数据库相关(勿动)
  array (
    'database' => 'app_uoj233',                      // 数据库名称
    'username' => 'root',                            // 用户名
    'password' => 'root',                            // 密码
    'host' => '127.0.0.1',                           // 数据库主机名
  ),
  'web' =>                                       // 网址相关(勿动)
  array (
    'domain' => NULL,
    'main' =>
    array (
      'protocol' => 'http',
      'host' => isset($_SERVER['HTTP_X_FORWARDED_HOST']) ? $_SERVER['HTTP_X_FORWARDED_HOST'] : (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ''),
      'port' => 80,
    ),
    'blog' =>
    array (
      'protocol' => 'http',
      'host' => isset($_SERVER['HTTP_X_FORWARDED_HOST']) ? $_SERVER['HTTP_X_FORWARDED_HOST'] : (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ''),
      'port' => 80,
    ),
  ),
  'security' =>                                  // 安全相关(勿动),仅为示例
  array (
    'user' =>
    array (
      'client_salt' => 'salt',
    ),
    'cookie' =>
    array (
      'checksum_salt' =>
      array (
        0 => 'salt',
        1 => 'salt',
        2 => 'salt',
      ),
    ),
  ),
  'mail' =>                                      // 邮件相关(SMTP 协议发送)
  array (
    'noreply' =>                                     // noreply 邮箱(建议使用 sina 邮箱)
    array (
      'username' => 'noreply@none',
      'password' => 'noreply',
    ),
  ),
  'judger' =>                                    // 测评相关(勿动)
  array (
    'socket' =>                                      // 与测评机的 socket 服务器通讯的设置
    array (
      'port' => 2333,                                // 端口
      'password' => 'pass',                          // 认证密码(证明自己 UOJ 服务器),仅为示例
    ),
  ),
  'svn' =>                                       // svn 相关(勿动)
  array (
    'our-root' =>                                    // 每个题目的 svn 仓库自带的仓库管理员
    array (
      'username' => 'our-root',                          // 管理员用户名
      'password' => 'pass',                              // 密码,仅为示例
    ),
  ),
  'switch' =>                                    // 一些开关
  array (
    'ICP-license' => false,                          // 是否显示 ICP 备案信息(默认为否)
    'web-analytics' => false,                        // 是否进行网站统计(默认为否,记 uoj.ac 名下,想统计自己的得改代码)
    'blog-use-subdomain' => false,                   // 博客是否使用子域名(默认为否,不建议使用)
  ),
);

4.LOGO

LOGO 图片位于网站的/picture目录下,使用 SVN 管理。
首先,需要 checkout UOJ 的 web 目录:

svn checkout svn://<local-uoj-address>/uoj
cd uoj/1/pictures

在 /pictures 目录下替换对应的图片,然后 commit。

svn commit -m "Changed logo" *

多评测机配置

在原 UOJ 容器所在物理机上安装

使用自动构建的镜像(推荐)

首先,请进入 UOJ 容器,并记录 /opt/uoj/judger/.conf.json 的内容。

执行下面的命令,从 DockerHub 中获取评测机镜像:

sudo docker pull universaloj/uoj-system:judger`

请新建文件 judger_env.list,请根据下文说明替换下面的文件内容:

UOJ_PROTOCOL=http
UOJ_HOST=<uoj_host>
JUDGER_NAME=<judger_name>
JUDGER_PASSWORD=<judger_pwd>
SOCKET_PORT=2333
SOCKET_PASSWORD=<socket_pwd>

您需要替换:

  • <judger_name>:新评测机的名称,不应与之前的评测机重复,仅可由小写字母和数字组成。
  • <uoj_host>:UOJ 容器的容器 IP。
  • 可通过 docker inspect --format '{{ .NetworkSettings.IPAddress }}' <container_id> 来获得名为 <container_id> 的容器的 IP
  • <judger_pwd>:评测机密码,可以不修改。
  • <socket_pwd>:通讯密码,应与您在第一步中从 UOJ 容器中获得的密码相同。
  • 接下来,在 judger_env.list 所在目录下,执行下面的命令来启动评测机。其中,请将 <judger_name> 替换为评测机的名称。
sudo docker run --name <judger_name> -dit --env-file judger_env.list --cap-add SYS_PTRACE universaloj/uoj-system:judger

启动后,请您查看新启动的评测容器的 IP 并记录下来。之后,您应该进入 UOJ 容器中的 mysql 中的 app_uoj233 数据库, 并将新的评测机的信息用以下命令加入数据库(请不要在网页端后台操作添加):

insert into judger_info (judger_name, password, ip) values ('<judger_name>', '<judger_pwd>', '<judger_ip>');

最后,退出 mysql 和 docker。

此时,如果配置正确,您应该可以在网页端看到新的评测机了。您可以通过同时提交数个死循环程序,来检查多个评测机是否工作正常。

注意:对于每道题,您需要在新评测机配置完成后点击题目管理页面中的“检查配置并同步数据”来将数据同步到每台评测机。

使用 Dockerfile 手动构建

首先,您需要查看 UOJ 容器的 judger 配置并按照其配置配置新的评测机。请先在终端中进入一个临时文件夹,用于存放临时文件。之后,您需要从 UOJ 容器中复制出/opt/uoj/judger/.conf.json:

docker cp uoj:/opt/uoj/judger/.conf.json ./conf.json
然后,请您编辑复制出的 conf.json,修改:

  • uoj_host:UOJ 容器的容器IP(某容器的IP可通过命令docker inspect --format '{{ .NetworkSettings.IPAddress }}' 来获取) 。
  • jugder_name:新评测机的名称,不应与之前的评测机重复,仅可由小写字母和数字组成。
  • judger_password:密码,可以不修改。
    下一步,您需要通过 Dockerfile 构建新 judger 的镜像。

新建一个名为 Dockerfile 的文件,其内容如下:

FROM ubuntu:18.04
MAINTAINER MascoSkray <[email protected]>
ARG CLONE_ADDFLAG

WORKDIR /opt
#Update apt and install git
RUN apt-get update && apt-get install -y git
#Clone the latest UOJ Community verison to local
RUN git clone https://github.com/UniversalOJ/UOJ-System.git --depth 1 --single-branch ${CLONE_ADDFLAG} uoj
#Install environment and set startup script
COPY conf.json /opt/uoj/judger/.conf.json
RUN cd uoj/install/judger && sh install.sh -p && echo "\
#!/bin/sh\n\
if [ ! -f \"/opt/uoj/judger/.conf.json\" ]; then\n\
  cd /opt/uoj/install/judger && sh install.sh -i\n\
fi\n\
service ntp start\n\
su judger -c \"/opt/uoj/judger/judge_client start\"\n\
exec bash\n" >/opt/up && chmod +x /opt/up

ENV LANG=C.UTF-8 TZ=Asia/Shanghai
EXPOSE 2333
CMD /opt/up

该 Dockerfile 相对于原始文件,仅增加了将我们修改过的 conf.json 复制到容器的相应位置的代码。在某些国家,由于某些限制,可能导致 clone 过程执行过慢,您可以考虑将仓库手动克隆到您所在国家的代码托管网站。

使用如下命令构建该镜像:

docker build -f Dockerfile .
在经历漫长的等待后,如果构建过程正常,您将可以看到:

Successfully built <image-id>
请记录下 <image-id>

然后,您需要使用刚才构建的镜像启动一个新的评测容器:

docker run -dit --name <judger-name> --cap-add SYS_PTRACE <image-id>
启动后,请您查看新启动的评测容器的 IP 并记录下来。之后,您应该进入 UOJ 容器中的 mysql 中的 app_uoj233, 并将新的评测机的信息加入数据库(请不要在网页端后台操作添加):

insert into judger_info (judger_name, password, ip) values ('<judger_name>', '<judger_password>', '<judger_ip>');
退出 mysql ,按组合键 Ctrl+P+Q 离开并不停止容器。

此时,如果配置正确,您应该可以在网页端看到新的评测机了。

注意:对于每道题,您需要在新评测机配置完成后点击题目管理页面中的“检查配置并同步数据”来将数据同步到每台评测机。

如果需要安装更多评测机,不需要重新构建镜像。请直接使用刚才的命令从之前的镜像启动一个新的 judger 容器。然后,进入这个新的 judger 容器,并编辑
/opt/uoj/judger/.conf.json 为新 judger 的信息。之后,保存文件、退出容器并重启该容器。然后按照第四步的方式将新的评测机加入数据库。

本地构建镜像前的准备

准备一个装有 64 位 Linux 系统的服务器,这里建议使用 Ubuntu。在进行构建之前,建议先更新系统软件包,并安装必要的工具。

sudo apt update
sudo apt upgrade
sudo apt install git curl

接下来需要安装 docker,它是一种容器技术,暂且可以大致地理解成虚拟机。

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo systemctl enable --now docker  # 启用并启动 docker 服务
sudo docker --version               # 检查 docker 是否正常安装

克隆 UOJ 源码
执行下面的命令,从 GitHub 克隆 UOJ 源码。

git clone https://github.com/UniversalOJ/UOJ-System.git
使用 Docker 构建 UOJ
执行下面的命令,从源码构建 UOJ 镜像。

cd UOJ-System/install/bundle/
sudo docker build -t uoj-system .

可能需要等待一段时间才能完成构建。构建结束时,屏幕上会显示:

Successfully built xxxxxx
Successfully tagged uoj-system:latest

构建结束后,下列命令可以使用本地构建的镜像运行 UOJ 。

sudo docker run --name uoj -dit -p 80:80 --cap-add SYS_PTRACE uoj-system
稍等几分钟,访问服务器的地址,应该就能看到 UOJ 的默认主页了构建镜像

标签:容器,创新,--,更新,judger,实训,UOJ,uoj,docker
From: https://www.cnblogs.com/sduhd/p/18221448

相关文章

  • 是否有办法区分 Mac App Store 应用程序的重新安装和更新?
    我正在开发一款电子应用,并将其发布到MacAppStore。我的主要目标是在应用卸载(和重新安装)时清除应用创建的用户数据,而不是在更新时。但是这在MacOS上是不可能实现的,因为在MacOS上卸载只是将应用文件夹拖入垃圾箱,而垃圾箱是无法干预的。因此,我转而尝试在应用从全新安装中首次......
  • 对于一个页面的两个更新方法,我们到底该写成一个通用的还是两个单独的?
    如果一个页面有两个更新方法的话,分别是通过不同的功能点点击过去的,比如分别更新一个页面的上半部分内容(业务实体A),一个是只是更新其中的发票信息的(发票实体B),虽然在一个页面,但是也不应该写成一个更新请求这种的因为两个更新没什么关联的关系,而且更新的是实体不是一个,所以就可以整成......
  • 开源AI智能名片商城系统小程序:构建企业敏捷性与创新力的新引擎
    摘要:在数字化时代,企业正面临前所未有的市场变革。客户需求日新月异,市场竞争日趋激烈。为了在这场变革中立足,企业必须寻求新的解决方案,以提升自身的敏捷性和创新力。开源AI智能名片商城系统小程序,作为一种新兴的技术工具,正以其独特的优势,助力企业迅速响应市场变化,推动产品和服......
  • YOLOv10全网最新创新点改进系列:融合空间信息关注机制(SimAM)于YOLOv10网络,在通道之间和
    YOLOv10全网最新创新点改进系列:融合空间信息关注机制(SimAM)于YOLOv10网络,在通道之间和空间位置之间建立更加准确的关联,助力YOLOv10有效涨点!!!所有改进代码均经过实验测试跑通!此项目不低于30种改进!自己排列组合2-4种后,考虑位置不同后可排列组合上千万种!改进不重样!!专注AI学术,......
  • YOLOv10最新创新点改进系列:融合最新顶会提出的HCANet网络中卷积和注意力融合模块(CAFM
    YOLOv10全网最新创新点改进系列:融合最新顶会提出的HCANet网络中卷积和注意力融合模块(CAFM),有效提升小目标检测性能,大幅度拉升目标检测效果!遥遥领先!YOLOv10全网最新创新点改进系列:融合最新顶会提出的HCANet网络中卷积和注意力融合模块(CAFM-2024年4月开源),有效提升小目标检......
  • lua语言:模块热更新方案
    我们知道,lua通过package模块来管理模块的搜索和加载,当使用require首次成功加载一个模块后,模块(Table)会被存储在package.loaded中,之后的require行为会直接获取到已加载的模块缓存。如何在程序执行时,将对模块文件的修改热更新到程序中,同时确保运行时状态的正常。这是项目开发中常见......
  • MySQL约束条件,非空空约束(not nullnull),主键约束PK(primary key),外键约束FK(foreign key
    ⅠMySQL约束条件【一】什么是约束条件约束条件:限制表中的数据,保证添加到数据表中的数据准确和可靠性!凡是不符合约束的数据,插入时就会失败!约束条件在创建表时可以使用,也可以修改表的时候添加约束条件【二】约束条件概览null和notnull为空和不为空限制整数类型必须大......
  • 【python007】读取csv文件url多进程下载图片数据(最近更新中)
    1.熟悉、梳理、总结项目研发实战中的Python开发日常使用中的问题、知识点等2.欢迎点赞、关注、批评、指正,互三走起来,小手动起来!3.欢迎点赞、关注、批评、指正,互三走起来,小手动起来!4.欢迎点赞、关注、批评、指正,互三走起来,小手动起来!......
  • APP更新方案
    注意!!!后端返回数据要求字段如下 url:'http://127.0.0.1:8088/edition_manage/get_edition',//示例接口传参data:{edition_type:plus.runtime.appid,version_type:uni.getSystemInfoSync().platform,//android或者iosedition_numbe......
  • 蓝桥杯嵌入式 第六届国赛 更新中……
    题目配置注意事项复制LCD的工程,先配置资源---勾选完选项一定要再看一眼,可能选择错误ADC:配置ADC2_IN15,对应PB15引脚EEROM,配置PB6和PB7按键输入模式PB0、PB1、PB2、PA0LED一定要使能PD2PWM互补输出,用TIM15TIM6-10ms基准定时器代码-默写大师先......