SubmitHub Engine Myers Diff 줄 추적 · Docker 격리 채점 · Winnowing 표절 검증

과제 제출도 Git처럼 버전으로,
줄 단위 코드 리뷰와 피드백 자동 추적

학생이 제출할 때마다 v1, v2 버전이 보존되고, 교수는 코드의 정확한 줄을 짚어 리뷰합니다. 다음 제출에서 지적받은 줄이 실제로 고쳐졌는지 Myers Diff와 AI 판정기가 실시간으로 추적합니다.

자료구조 · 과제 #2 이진 탐색 트리 구현
자동 채점 5/5 통과 · 100점
탐색기 · v2 (최신)
src/BinarySearchTree.java +6 -1
src/Node.java 동일
src/Main.java +2
피드백 반영 현황
반영률 100% (2/2)
src/BinarySearchTree.java · 줄 번호 클릭으로 범위 코멘트 작성 UTF-8 · Java 17
21public class BinarySearchTree {
22 private Node root;
23
24 public Node search(int key) {
25 return searchRecursive(root.left, key); // 버그 위치
26 }
줄 24~26 · 김교수 교수 v2에서 반영됨 · AI 검증 완료
루트 노드가 null일 때 방어 코드가 없고, 탐색 시작점이 root가 아니라 root.left로 고정되어 있습니다. 빈 트리 케이스에서 NullPointerException이 발생합니다.
AI 판정: 해결됨 학생이 v2에서 if (root == null) return null; 가드를 추가하고 searchRecursive(root, key)로 수정하여 문제를 정확히 해결했습니다.
27 private Node searchRecursive(Node cur, int key) {
28 if (cur == null || cur.key == key) return cur;
29 return key < cur.key ? searchRecursive(cur.left, key) : searchRecursive(cur.right, key);
30 }
Myers Diff 비교 · v1 → v2 (공백 무시 ON) +4줄 추가 · -1줄 삭제
24 public Node search(int key) {
-25- return searchRecursive(root.left, key);
+25+ if (root == null) {
+26+ return null;
+27+ }
+28+ return searchRecursive(root, key);
29 }
Myers Diff 줄 위치 추적기 (LineTracker) 상태 자동 전환: 미반영 → 반영됨
v1의 24~26번 줄에 달렸던 코멘트 영역이 v2의 25~28번 줄로 확장·수정된 것을 감지하여 자동으로 반영률 통계에 합산했습니다.
구조 토큰 + Winnowing 지문 비교 (변수명·주석 치환 무력화) 구조 유사도 94% 검출
학생 A (v2) · 겹침 94%
Node findVal(Node n, int k) {
while (n != null) {
if (k == n.val) return n;
n = (k < n.val) ? n.l : n.r;
}
학생 B (v1) · 변수명·주석 변경 시도
Node lookup(Node cur, int target) {
// 탐색 루프 주석 추가
while (cur != null) {
if (target == cur.key) return cur;
cur = (target < cur.key) ? cur.left : cur.right;
Interactive Workflow

스크롤을 내리면 코드 리뷰의 전 과정이 펼쳐집니다

단순히 파일만 올리고 끝나는 과제방이 아닙니다. 제출부터 자동 채점, 인라인 리뷰, 재제출 추적까지 실제 개발팀의 PR 워크플로우가 그대로 돌아갑니다.

STEP 01 · SUBMIT & SANDBOX

파일·ZIP 또는 GitHub 커밋 제출과 즉시 격리 채점

학생이 소스 파일이나 GitHub 공개 저장소 커밋 SHA를 제출하면 v1 스냅샷이 생성됩니다. 동시에 네트워크가 차단된 Docker 컨테이너에서 공개·비공개 테스트 케이스를 자동 실행합니다.

STEP 02 · INLINE CODE REVIEW

줄 번호를 클릭해 남기는 정확한 코드 피드백

교수는 코드 뷰어 또는 Diff 화면에서 특정 줄(또는 Shift+클릭 범위)을 바로 선택해 코멘트를 남깁니다. 학생과 교수는 해당 줄 아래에서 스레드로 질의응답을 이어갈 수 있습니다.

STEP 03 · ITERATE & DIFF

피드백을 반영한 v2 재제출과 좌우 분할 Diff

이전 버전을 덮어쓰지 않고 v2, v3가 타임라인으로 쌓입니다. 좌우 분할(Split) 및 통합(Unified) Diff 뷰어로 어느 줄이 어떻게 고쳐졌는지 한눈에 대조합니다.

STEP 04 · AUTO-TRACKING & AI JUDGE

Myers Diff 줄 추적 + Gemini AI 해결 여부 판정

교수가 이전 코멘트를 일일이 다시 찾아볼 필요가 없습니다. 다른 줄에 코드가 추가되어 줄 번호가 밀려도 Myers Diff가 원래 코멘트 위치를 추적하고, AI가 실제 해결 여부를 한 번 더 검증합니다.

Step 01 · Docker 격리 컨테이너 자동 채점
docker --network=none
$ docker run --rm --network=none --memory=256m --cpus=1.0 submithub-runner
> Compiling Main.java, BinarySearchTree.java ... OK (412ms)
> Running 4 configured test cases (2 public, 2 hidden)...
1. 기본 삽입 및 중위 순회 공개 통과 · 25 / 25점 (38ms)
2. 중복 키 처리 검증 공개 통과 · 25 / 25점 (41ms)
3. 빈 트리 탐색 예외 처리 비공개 런타임 오류 (NPE) · 0 / 25점
4. 대용량 노드(N=50,000) 시간 제한 비공개 통과 · 25 / 25점 (620ms)
// 줄 24~26 선택됨 (Shift+클릭 범위 지정)
24 | public Node search(int key) {
25 | return searchRecursive(root.left, key);
26 | }
줄 24~26에 인라인 피드백 작성 Markdown 및 줄바꿈 보존
빈 트리에서 search() 호출 시 root가 null이어서 NPE가 납니다. null 체크를 먼저 추가해 보세요!
등록 즉시 학생의 '남은 피드백' 카운트에 반영됩니다. 코멘트 남기기
좌우 분할 비교 (v1 → v2) 테스트 통과율: 75% → 100% (▲ +25%p)
v1 (이전 버전)
24: public Node search(int key) {
-25: return searchRecursive(root.left, key);
26: }
v2 (새 버전)
24: public Node search(int key) {
+25: if (root == null) return null;
+26: return searchRecursive(root, key);
27: }
피드백 자동 추적 결과 반영률 100% 달성
BinarySearchTree.java:24-26 (v1 코멘트) → v2의 25~26번 줄에서 수정 감지됨
AI 판정 해결됨 (RESOLVED) · 교수 수락 완료
단순 줄바꿈이나 주석 추가가 아니라, 교수가 지적한 root == null 예외 처리와 루트 탐색 인자가 실제로 수정되었음을 확인했습니다.
Built for Computer Science Courses

프로그래밍 수업에 필요한 모든 도구를 하나로

단순 텍스트 비교를 넘어 알고리즘과 컨테이너 기술로 채점과 코드 리뷰를 자동화합니다.

STANFORD MOSS ALGORITHM

변수명·주석·공백을 바꿔도 잡아내는 Winnowing 표절 검사

소스코드를 언어별 구조 토큰(AST/Lexer)으로 정규화한 뒤 k-gram 해시와 Winnowing 지문을 추출합니다. 교수가 배포한 뼈대 코드(Baseline)는 자동으로 제외하고 순수 학생 작성 영역만 나란히 하이라이트 비교합니다.

지문 정규화 파이프라인 공통 지문 48개 일치 (유사도 92%)
int studentSum = 0; ↔ int total_val = 0; → 정규화 토큰: [TYPE_INT, ID, ASSIGN, NUM] (동일 구조 판정)
CONTAINER SANDBOX

네트워크 차단 Docker 격리 채점

제출된 Java·Python 코드는 외부 통신이 완전히 차단된 컨테이너에서 시간 제한(초)과 메모리 상한(MB) 안에 실행되어 무한 루프나 시스템 접근을 원천 방어합니다.

네트워크 격리 --network=none (차단됨)
리소스 제한 시간 1~30s · 메모리 64~512MB
출력 비교 CRLF/LF 및 줄 끝 공백 정규화
COURSE ANALYTICS

마감 직전 제출 집중도 & 성장 추이 통계

과제별 제출률, 미제출자 명단, 시간대별 제출 분포와 버전이 올라갈수록 상승하는 학생들의 테스트 통과율 추이를 실시간 차트로 시각화합니다.

시간대별 제출 분포 (마감 22~23시 집중) 평균 반영률 88%
GITHUB SYNC & CLASSROOM

GitHub 저장소 커밋 연동 & 8자리 초대 코드 수강 관리

파일 업로드뿐만 아니라 GitHub 공개 저장소 URL과 브랜치·커밋 SHA만 입력하면 소스 파일을 자동으로 가져와 버전을 생성합니다. 교수가 강의를 개설하면 즉시 발급되는 8자리 초대 코드로 학생들이 1초 만에 합류합니다.

GitHub a1b2c3d → v1 생성 → v2 리뷰 반영 (+14 -3)
동일 커밋 중복 제출 자동 방지

지금 바로 SubmitHub를 시작해 보세요

교수 계정으로 강의를 개설하거나, 학생 계정으로 초대 코드를 입력해 버전 관리형 과제 제출과 줄 단위 코드 리뷰를 직접 경험할 수 있습니다.