在线编程竞赛期间,在线判题系统为什么会崩溃?


我们都知道,如今各种编码平台都包含了竞技编程,例如 GeeksforGeeks、CodeChef、Codeforces、atCoder、SPOJ、HackerRank、HackerEarth 等等,在这些平台上,用户需要自己编写代码,可以通过连接本地编辑器文件(例如 Sublime 编辑器)或直接在平台提供的编辑器中编写。

那么,这些测试用例是如何被访问的呢?或者换句话说,我们的代码是如何被编译和运行的呢?在这些用于竞技编程的平台上,在线判题系统充当了代码编译和运行的核心。

在线判题系统

在线判题系统用于判断用户提交的代码,这些代码将在一个同质的环境中进行编译和测试。在线判题系统被分类为各种不同的系统,这些系统支持建立竞技编程竞赛、增强教育和招聘流程、促进数据挖掘挑战的解决,以及作为其他自定义系统组件的在线编译器和开发平台。因此,它将被实现为一个高效的系统,帮助学生学习数据结构和编程技能。该系统包括用户界面、沙盒判题环境、用于评估分数和将报告更新到数据库的功能。本文将讨论在线判题系统在编程竞赛期间是如何崩溃的。下图将帮助我们更好地解释其崩溃的原因。

  • 时间限制完成 - 代码应在一定时间内执行完成。我们能否在默认情况下设置操作系统执行线程的时间限制?

  • 内存限制完成 - 程序不应该占用 CPU 上的所有内存。我们如何以更简单的方式更改这一点?

  • 栈溢出错误 - 系统在跟踪程序后,会了解程序是否成功运行。那么,这些信息是如何传递给我们的?

以上所有要点都解释了系统检查和运行程序的问题。用户被允许在程序中提交任何代码。我们如何确定提交的代码是否具有恶意性,或者其恶意程度如何?

一些代码可以执行不同的进程,或者它们可以调查您的文档目录,获取少量信息,或者可以运行管理命令,或者可以吞噬服务器的带宽,代码还可以执行各种操作。我们不需要允许系统执行这些操作。所以问题是,我们如何将这些权限准则付诸实施?为了处理上述场景,我们将解释以下方法:

方法

用于应用系统权限和硬件的技术称为代码沙箱。有两种代码沙箱方法,网络决定通过这些方法来处理上述不同的场景。

  • 糟糕的方法

  • 冗长的历史方法

方法 1:糟糕的方法

有一些可见的在线决策计划,开发人员试图在执行代码之前发现代码中的恶意功能。例如,如果我们的代码是用 C++ 编写的,则决策将首先查看是否存在任何使用“system”短语的代码行。这种方法不会出于各种原因而有效,因为许多编程语言的工作方式并不相同。您可以动态地生成一个函数并在某些编程语言中调用它,因此过滤在这些代码中将不起作用。还有一点,如果您想打印“system”作为输出怎么办?这种方法会认为代码是恶意的,但实际上并非如此。

方法 2:冗长的历史方法

在这种方法中,网络决定了大多数工作。并且此方法主要与基于 Linux 的系统相关。可以通过程序的返回值检查栈溢出/运行时错误。如果返回值为 0,则可以认为系统能够成功运行,否则表示崩溃。

通过使用各种基于 Unix 的完整库,可以提供内存限制问题和时间限制。一些编程语言默认支持这种限制标志功能,例如 Java。可以使用各种基于 Unix 的库提供时间限制和内存限制。一些编程语言默认支持此类边界标志,例如 Java。

在 Linux 上,目录权限很简单。我们可以简单地创建一个用户,并允许该用户访问某些目录以及一些读/写权限。然后通过使用该用户执行应用程序,可以解决文档列表问题。此外,代码无法运行某些管理命令。

使用一些库(例如 Trickle)也可以限制网络功能。为了简单地解决一个安全漏洞,我们可以设置不同的库并编写不同的代码。

结论

如果我们使用 Docker 或基于 VM(虚拟机)的容器,则可以解决以上所有问题。如果我们想要预设内存、预设网络权限、容器的时间限制,可以创建一个容器。通过使用虚拟机,所有这些问题都可以被忽略。开发人员可能知道一些替代方案。在这种解决方案中,整个判题系统可能看起来比其他方法慢,但从大规模来看,它实际上更快,并且比其他任何解决方案都更安全、更干净。您可以查看此 GitHub 存储库以了解如何使用 docker 进行判题。

整个判题过程是在线判题系统最重要的组成部分之一。要实现一个判题系统,需要了解操作系统的工作原理,或者编程语言的工作原理。

更新时间: 2023年8月1日

99 次查看

开启您的 职业生涯

完成课程获得认证

开始学习
广告