автокомпиляция, автозапуск, автоматическое сравнение результатов в Java - PullRequest
2 голосов
/ 14 марта 2011

дорогой всем, я новичок в Java, и в настоящее время я пытаюсь разработать приложение под Java, чтобы делать такие вещи: допущение: есть файл, содержащий исходный код на Java.давайте предположим, что файл содержит основной класс (и его основной метод с несколькими дополнительными методами) и некоторые внутренние классы, которые будут использоваться во время выполнения основного класса.

процессы:

  1. приложение, которое я хочу разработать (назовите его ASIN), попытается скомпилировать исходный код, который мы предположили выше.
  2. после завершения фазы компиляции.я хочу, чтобы ASIN выделил некоторое пространство памяти 32 МБ (например) и предоставил максимальное время работы 2 секунды (например).
  3. после выделения памяти и максимального ограничения времени для работы, ASIN попытаетсязапустить Java-байт-код, используя выделенный ресурс (память 32 Мб) с заданным максимальным временем.Затем ASIN запишет / запишет результат.если исполняемый байт-код использует больше выделенной памяти или превышает заданный лимит времени, ASIN заставит остановить выполнение.Итак, нормальный случай - это когда выполнение заканчивается до максимального ограничения по времени и использует меньше выделенной памяти.

может ли Java сделать что-то выше?Любое предложение, что я должен делать?

С уважением,

Ответы [ 2 ]

1 голос
/ 14 марта 2011

Предполагается, что это будет система оценок для соревнования по программированию или для упражнений в университетском курсе? Для этого могут существовать системы с открытым исходным кодом, поэтому сначала зайдите в Google, если вы этого еще не сделали. Если вы хотите / хотите сделать это самостоятельно, я не уверен, что Java позволяет вам ограничивать время, затрачиваемое программой (но вы, конечно, можете просто убить программу после ожидания определенного количества времени), но предел памяти Java-программы может быть указан, например, с -Xmx32m при запуске программы командой java. Если это в системе Unix, простейшим решением, вероятно, будет использование ulimit для ограничения использования памяти и времени выполнения.

В любом случае, я думаю, вам придется использовать Runtime.exec () для запуска как компилятора, так и программы. Это также позволит вам вводить входные данные в процесс и считывать выходные данные процесса (хотя перенаправление ввода-вывода также может выполняться в / из файлов, если вы запускаете программу, например, с

Runtime.getRuntime().exec("java -Xmx32m Program.class < input.txt > output.txt");

Что касается сравнения: если вам не требуется точное совпадение (даже в пробелах), простейшее решение, вероятно, состоит в том, чтобы перенаправить вывод в файл и вызвать diff с -b или -w и, возможно, --ignore-blank-lines; если код возврата равен 0, выходной результат равен решению (за исключением различий пробелов). С другой стороны, если вам нужна интерактивная оценка (программа должна «общаться» с оценщиком) или если выходные данные могут быть сформированы по-разному, так что нет единственно правильного ответа, вы не можете использовать diff ; Вместо этого грейдер должен прочитать поток вывода процесса.

0 голосов
/ 14 марта 2011

Я бы сделал это в сценарии оболочки, а не в Java. Будет ли это вариант?

Вы можете ограничить время и память, используя ulimit. Если вы напишите небольшой скрипт оболочки, который делает это:

set -e
ulimit -v 32768 # ulimit -v works in 1 kB blocks, so this is 32 MB
ulimit -t 2 # ulimit -t works in seconds
java ProgramUnderTest >output

Затем, когда вы запустите его, он предоставит себе память и ограничения по времени, и запустит Java в качестве подпроцесса. Если программа завершается вовремя (обратите внимание, что ограничение на время ЦП, а не в режиме реального времени), она завершится со статусом выхода 0; в противном случае он будет иметь ненулевой статус выхода.

Если вы хотите записать, сколько фактического времени было использовано в пределах лимита, запустите java в time :

time java ProgramUnderTest >output

Это напечатает общее количество времени, использованного после вывода.

Компиляция кода из скрипта также проста, конечно - просто запустите javac. Не забудьте проверить состояние выхода, чтобы увидеть, правильно ли скомпилирован код.

...