Skip to content

Latest commit

 

History

History
271 lines (216 loc) · 22 KB

File metadata and controls

271 lines (216 loc) · 22 KB

문항 저작 규약

이 문서는 cachehit의 문항을 어떻게 만드는지 정한다. 읽지 않고 문항을 추가하지 마라.

객관식 퀴즈의 품질은 정답이 아니라 오답이 결정한다. 오답이 허술하면 지식이 아니라 소거법을 시험하게 되고, 그 순간 퀴즈는 학습 도구가 아니라 시간 때우기가 된다. 이 문서의 대부분이 오답을 다루는 이유가 여기에 있다.


0. 설계의 근거

결정 근거
객관식 4지선다 단답형과 비교해도 최종 파지의 차이는 작다(Smith & Karpicke, 4개 실험 종합 d=0.07 [1]). 형식보다 인출 성공률이 중요하고, 웹에서는 채점 가능성과 이탈률이 형식을 결정한다
보기 4개 (오답 3개) 기능하는 오답이 2~3개일 때 문항 난이도와 변별력이 가장 좋다. 5지선다는 이득 없이 저작 비용만 올린다 [2]
오답은 실제 오개념에서 정답과 의미적으로 경쟁하는 오답(competitive distractor)이라야 깊은 처리가 일어난다. 무작위 오답은 재인 훈련에 그친다 [3]
확신도 입력 확신했는데 틀린 오류가 가장 강하게 교정된다(hypercorrection). 기제가 놀람이므로 즉시 피드백이 있어야 작동한다 [4][5]
즉시 해설 + 오답별 해설 객관식은 오답 보기에 노출시키는 대가로 오개념을 심을 수 있는데, 정답 확인 피드백이 그 부작용을 없애면서 파지 이득은 키운다 [6]. 세션이 끝나면 재접촉이 없는 웹 퀴즈에서는 해설을 줄 수 있는 시점이 즉시뿐이다
오답 재도전 라운드 교정에 성공한 오류도 일주일 뒤에는 되돌아오고, 확신이 높았던 오답일수록 더 잘 되돌아온다 [7]. 그래서 같은 세션 안에서 한 번 더 인출시킨다

1. 문항이 갖춰야 할 것

{
  "id": "cdn-cache-key-001",          // 영역-주제-일련번호, 변경 금지(공유 링크가 참조)
  "topic": "cdn",                      // cdn | caching | image | video | storage
  "tags": ["cache-key", "cardinality"],
  "difficulty": 2,                     // 1 쉬움 / 2 보통 / 3 어려움
  "question": "",
  "options": [
    {
      "text": "",
      "correct": true,
      "why": "왜 이것이 정답인가. 한두 문장."
    },
    {
      "text": "",
      "correct": false,
      "distractorType": "one-step-short",
      "why": "이 보기를 고른 사람은 무엇을 오해한 것인가. 한 문장."
    }
    // 오답 3개
  ],
  "explanation": "정답 해설. 3~6문장. 왜 그런 설계인지까지.",
  "source": "RFC 9111 §5.2.2.2",       // 표준·공식문서·공개 발표 등 확인 가능한 근거
  "seeAlso": ["https://…"]             // 선택
}

필수 불변식

  • options는 정확히 4개, correct: true는 정확히 1개.
  • 모든 오답에 distractorTypewhy가 있어야 한다. 하나라도 비면 문항 전체가 탈락한다.
  • source는 검증 가능해야 한다. "일반적으로 알려짐" 같은 것은 근거가 아니다.

2. 오답 생성: 발명하지 말고 수집하라

2.1 먼저 오개념 원장을 만든다

문항을 쓰기 전에 그 주제에서 실제로 일어나는 오해의 목록을 모은다. 오답은 이 목록에서 가져와 쓴다. 원장에 없는 오답을 즉석에서 지어내는 순간 품질이 무너진다.

원장의 출처:

  1. 헷갈리는 쌍 — 이름이 비슷하거나 역할이 인접해서 실무자가 실제로 섞어 쓰는 것들. no-cacheno-store / max-ages-maxage / 코덱 ↔ 컨테이너 / remux ↔ transcode / liveness ↔ readiness / requests ↔ limits / L4 ↔ L7 / Vary ↔ 캐시 키 / ETag strong ↔ weak
  2. 시대가 지난 정답 — 예전엔 맞았지만 지금은 틀린 것. S3의 eventual consistency, HTTP/2 서버 푸시 권장, "WebP는 지원이 부족하다"
  3. 벤더 혼동 — A 클라우드에서는 맞지만 B에서는 틀린 것. "CDN에 스토리지를 오리진으로 직접 붙인다"(CloudFront는 되지만 Cloud CDN은 LB를 거쳐야 한다)
  4. 방향이 반대인 것 — 요청 헤더/응답 헤더, 원인/결과, 인코딩/디코딩을 뒤집은 진술.
  5. 조건부인데 단정한 것 — 특정 상황에서만 참인 것을 항상 참인 것처럼.
  6. 직관적으로 그럴듯하지만 틀린 것 — 사람들이 처음 추측하는 답. "AVIF가 더 좋으니 다 AVIF로 주면 된다"(인코딩 CPU 비용이 서빙 구조를 바꾼다)

이 레포에서는 data/misconceptions/*.md에 주제별 원장을 유지한다. 문항의 오답은 원장 항목을 참조하는 형태로 쓴다.

2.2 오답 유형 7종: distractorType에 반드시 하나를 태그한다

타입 예 (정답: no-cache는 "캐시하되 매번 재검증")
adjacent 인접 개념 치환 no-store(아예 저장 금지)
inverted 방향·주체를 뒤집음 "요청 헤더로만 쓰인다"
overgeneralized 조건부 참을 단정 "모든 응답이 매번 오리진까지 간다"
one-step-short 부분적으로 맞지만 핵심 누락 "브라우저가 캐시하지 않는다"
vendor-mixup 다른 벤더/버전의 동작 "CloudFront에서는 TTL 0과 같다"
outdated 예전엔 맞았던 것 "HTTP/1.0 호환을 위해 Pragma가 필요하다"
plausible-number 자릿수·단위가 그럴듯하게 틀린 값 수치 문항 전용

한 문항의 오답 3개가 전부 같은 타입이면 안 된다. 최소 2종을 섞는다. 유형이 편중되면 응시자가 패턴을 학습해서 내용을 몰라도 풀게 된다.

one-step-short가 가장 좋은 오답이다. 아는 사람과 어설프게 아는 사람을 가르는 것은 대개 "거의 맞았지만 핵심을 빠뜨린 답"이기 때문이다. 문항당 최소 1개는 이 타입으로 넣도록 노력한다.

2.3 핵심 게이트: 한 줄 테스트

"이 보기를 고른 사람은 무엇을 오해한 것인가"를 한 문장으로 쓸 수 없으면, 그 보기는 버린다.

이 게이트 하나가 나머지를 대부분 해결한다.

  • 쓸 수 없다 = 아무도 고르지 않을 보기다 = 실질적으로 3지선다가 된다.
  • 쓸 수 있다 = 그 문장이 곧 why 필드다. 해설이 공짜로 따라온다.

3. 금지 사항: 시험 요령으로 풀리게 만드는 것들

18번은 문항 저작 가이드라인 연구가 80년치 문헌에서 정리한 규칙과 겹치고 [8], tools/validate.mjs가 기계적으로 검사한다. 911번은 블라인드 감사(§6.2)에서 실측으로 드러난 것이고, 9·10번은 기계로 검사되지 않는다. 검사를 구현해서 측정해 봤지만 지목군과 대조군의 분포가 분리되지 않았다(실측 기록은 tools/validate.mjs 상단 주석). 11번은 절반만 검사된다(전제를 부정하는 오답은 검출되지만, 오답이 결함을 서술하는지는 검출되지 않는다). 그래서 이 셋은 사람이 저작 시점에 지켜야 하고, 확인은 블라인드 감사로만 가능하다.

  1. 길이 편향 금지. 정답이 오답보다 눈에 띄게 길면 안 된다. 정답 길이는 오답 평균의 1.4배 이하. (아는 것이 없어도 "제일 길고 자세한 것을 고른다"는 요령이 통하면 안 된다)
  2. "위의 모든 것", "정답 없음", "해당 없음" 금지. 변별력이 없고 저작 회피의 신호다.
  3. 문법 단서 금지. 조사·어미·단복수가 정답에만 자연스럽게 맞아떨어지면 안 된다. 모든 보기가 같은 문형으로 끝나야 한다.
  4. 절대 표현 편중 금지. "항상/절대/모든/반드시"가 오답에만 몰리면 안 된다. (몰리면 그 단어만 보고 소거된다)
  5. 정답 위치 편중 금지. 정답 인덱스가 특정 위치에 몰리면 안 된다. 빌드 시 셔플하지만, 원본 데이터도 균등해야 한다.
  6. 부정문 남용 금지. "다음 중 옳지 않은 것은?"은 전체의 20%를 넘지 않는다. 넘으면 독해력 시험이 된다.
  7. 한 문항에 두 가지를 묻지 않는다. 복합 질문은 무엇을 몰라서 틀렸는지 알 수 없게 만든다.
  8. 트리비아 금지. 외워야만 알 수 있고 몰라도 일에 지장 없는 것(정확한 기본 TTL 초 값 등)은 내지 않는다. 판단을 묻는다.
  9. 발문이 답을 진단해 주지 않는다. 이것이 실측에서 가장 많이 발견된 결함이다(1차 블라인드 감사 77문항 중 24건). 상황을 제시할 때는 증상만 서술하고 원인·기준·전략을 발문에 쓰지 않는다. 발문이 원인을 말해 버리면 정답은 그것을 되풀이하는 보기가 되고, 풀이자는 의미를 몰라도 발문과 어휘가 겹치는 보기를 고르면 된다.
    • 나쁜 예: "쿼리 파라미터 순서와 대소문자가 달라 같은 이미지가 중복 캐시되고 있다. 해법은?" → 정답 "URL을 정규화한다"는 발문에 적힌 진단을 그대로 되풀이한다.
    • 좋은 예: "같은 이미지의 CDN 히트율이 40%대에 머문다. 접근 로그를 보니 동일 이미지에 대한 URL이 수십 종이다. 원인은?"
    • 자기 점검: 발문에서 정답을 가린 채, 발문과 어휘가 가장 많이 겹치는 보기를 골라 보라. 그 보기가 정답이면 실패다.
  10. 구체성 격차 금지. 정답에만 수치·고유명사·메커니즘 서술이 붙고 오답은 뭉뚱그려져 있으면, 길이 제한(1.4배)을 지켜도 "자세한 쪽이 정답"이라는 요령으로 풀린다. 네 보기의 서술 밀도를 맞춘다. 즉 정답이 메커니즘을 말하면 오답도 (틀린) 메커니즘을 말해야 한다.
  11. 결함을 묻는 발문은 오답도 결함을 서술해야 한다. 이 발문 형태("무엇이 깨지는가 / 구조적 결함은? / 실질적 문제는?")는 그 자체로 위험하다. 오답으로 쓰기 쉬운 형태가 처방("~하면 해결된다"), 방어("~를 켜면 관리가 된다"), 부정("아무 문제 없다")인데, 셋 중 어느 쪽이든 넣으면 결함을 서술한 보기가 정답 하나뿐이 되어 내용을 몰라도 문형만으로 답이 특정된다. 3라운드 감사에서 반복 지목된 유형 중 가장 많았던 것이 이것이다.
    • 부정형은 절대 금지한다. 발문과 정면으로 모순되어 읽자마자 소거되기 때문이다. 이 절반은 게이트가 검사한다.
    • 처방형·방어형도 쓰지 않는다. 오답 셋을 모두 다른 결함 서술로 쓴다.
    • 그러면 "그 결함도 실제로 참"이 되어 정답이 둘 이상으로 읽히기 쉽다. 발문에 "가장 근본적으로" 같은 한정을 넣어서, 부차적으로 참인 결함이 정답과 경쟁은 하되 정답에는 밀리게 한다.
    • 나쁜 예: 결함=A / 오답="B를 켜면 해결된다", "비용은 무시할 만하다", "문제되지 않는다"
    • 좋은 예: 결함=A(전면적) / 오답=B·C·D(각각 실재하지만 부차적이거나, 그럴듯하지만 거짓인 결함)
    • node tools/validate.mjs --defect-stems가 이 형태의 발문을 모아 준다. 게이트는 결함 서술 여부를 판정하지 않는다. 대상만 지목하고, 판정은 사람이 한다.

4. 좋은 문항의 형태

나쁜 예 — 정의 암기

stale-while-revalidate는 무엇인가?

좋은 예 — 판단

이미지 CDN에서 오리진 부하가 특정 시각마다 튄다. TTL이 만료되는 순간 같은 객체에 대한 요청이 한꺼번에 오리진으로 몰리는 것이 원인으로 확인됐다. 코드 변경 없이 헤더만으로 완화하려면?

두 번째가 좋은 이유는 오답이 자연스럽게 경쟁한다는 점이다. stale-if-error(인접), TTL 상향(one-step-short: 문제를 미루기만 함), no-cache 추가(inverted: 오히려 악화시킴)가 전부 그럴듯하다.

형태 권장

  • 상황을 2~3문장으로 준 뒤 "무엇을 하겠는가 / 원인은 무엇인가 / 무엇이 깨지는가"를 묻는다.
  • 수치가 있으면 넣는다. 실측이 있는 문항이 기억에 남는다.
  • 실무에서 실제로 내려야 하는 결정을 묻는다.

5. 난이도 기준

난이도 기준 목표 정답률
1 해당 분야를 다뤄봤으면 안다 70~85%
2 한 번 데어봤거나 문서를 읽었어야 안다 45~65%
3 설계 결정을 직접 내려봤어야 안다 25~45%

정답률이 90%를 넘으면 오답이 죽은 보기가 된 것이고, 25% 미만(무작위 수준)이면 문항이 모호하거나 트리비아다. 둘 다 교체 대상이다.


6. 검증 절차

문항을 추가하면 순서대로 통과해야 한다.

  1. 기계 게이트node tools/validate.mjs. §1 불변식과 §3 금지 사항을 검사한다. 실패하면 머지하지 않는다.
  2. 블라인드 감사tools/blind.mjs로 정답·해설을 제거한 세트를 만들어 다른 사람(또는 다른 모델)에게 풀리고, tools/grade-blind.mjs로 채점한다. 기계 게이트 통과는 §3-9·§3-10을 보증하지 않으므로, 문항을 추가하거나 발문·보기를 고친 뒤에는 이 단계를 다시 거쳐야 한다.
    • 정답률이 지나치게 높으면 오답이 약하다.
    • "지식 없이 요령만으로 답을 고를 수 있었나" 를 함께 묻는다. "그렇다"면 그 문항은 재작성한다.
    • 판정은 그대로 수용하지 말고 두 부류로 나눈다. 어휘 반복·문형·길이·구체성으로 풀렸다면 진짜 결함이고, "보기가 발문과 모순되어 소거됐다"는 판정은 그 모순을 알아채는 데 도메인 지식이 필요한지 되물어야 한다. 도메인 지식이 필요하다면 그것은 정상적인 문항이다. 1차 감사에서 40건이 지목됐고 이 분류로 16건이 남았다.
    • 한 라운드의 판정은 재현되지 않는다. 3라운드를 돌리고 2회 이상 지목된 것만 고친다. 실측(2026-08-27, 같은 89문항·같은 기준·같은 모델로 3회): 지목률이 51.9% → 5.6% → 13.5%로 단조적이지 않았고, 2차와 3차의 자카드 유사도는 0.13이었다. 즉 두 라운드가 거의 다른 문항을 지목했다. 2회 이상 지목은 12건, 정확히 1회만 지목은 32건이었다. 반복 지목만이 신호이고 나머지는 노이즈다. 단일 라운드를 근거로 고치면 노이즈를 따라 고치게 되고, 그 라운드를 다시 돌려 0건을 만들려는 시도는 수렴하지 않는다. 라운드를 병렬로 3개 돌려라. 순차로 돌리면 앞 라운드의 수정이 다음 라운드의 입력을 바꾸기 때문에 비교가 성립하지 않는다.
    • 다른 문항 집합에서 한 번 더 재현됐다. 신규 60문항에 같은 절차를 돌린 결과 지목 수가 3 / 1 / 12건, 라운드 쌍의 자카드가 0.00 · 0.08 · 0.15였다(2026-08-27). 2회 이상 지목은 6건, 1회만 지목은 10건이었다. 첫 측정(89문항, 자카드 0.13)과 같은 결론이므로 이 규약은 한 번의 우연에서 나온 것이 아니다. 참고로 세 라운드 모두 60문항을 100% 정답으로 풀었다. 즉 정답률은 이 감사의 판정 기준이 아니다. 요령으로 풀렸는지가 판정 기준이다.

"정답이 둘 이상"이라는 결함을 발문에 조건을 추가해서 해소하면 그 보기가 죽은 보기가 된다. 3차 감사에서 실측된 자기 유발 결함이다. 2차에서 "보기 두 개가 모두 참"이라는 지적을 받고 발문에 조건을 넣어 경쟁 보기를 배제했는데(예: 발문에 "브라우저 지원 비율은 이미 확인했다"를 추가), 그 조건이 해당 보기를 읽자마자 소거되는 보기로 바꿨다. 두 결함은 상호 배타적이다. 조건을 넣지 말고 보기 자체를 다른 오개념으로 교체하라. 판정 기준은 이렇게 갈린다. 경쟁 보기가 거짓인데 발문의 전제 때문에 참처럼 읽히는 것이면 조건 추가가 옳다(그 보기는 여전히 그럴듯한 오개념으로 남는다). 경쟁 보기가 그냥 참이면 조건을 넣어도 참은 참이므로 결함이 해소되지 않고, 교체만이 수정이다. 실측 사례: cdn-purge-all-risk-001의 경쟁 보기 둘(무효화 전파 창, purge가 브라우저 캐시에 닿지 않음)은 둘 다 사실이었고, "가장 근본적인"이라는 한정만이 순위를 매기고 있었다. 그래서 오답 셋을 모두 거짓인 결함 서술로 교체했다. why가 자기 보기와 다른 이야기를 하는 결함은 기계로 검출되지 않는다. 편집 중에 문장이 뒤섞이면서 생기고, 화면에서는 정상으로 보인다(실측 4건: 오답 텍스트는 "계산이 수 초 걸려 병목"인데 why는 "단일 지표는 게이팅에 약하다"를 말하고 있었다). 어휘 겹침으로 근사해서 596개 보기 전부를 측정해 봤지만 겹침 0인 보기가 42%였고, 지목된 4건도 그 42% 한가운데에 있었다. 오답의 why는 원래 보기를 되풀이하지 않고 그 오해를 설명하는 글이므로, 겹침이 낮은 것이 정상이다. §2.3의 한 줄 테스트를 보기 하나하나에 소리 내어 적용하는 것이 유일한 검사다.

  1. 근거 확인source를 실제로 열어 진술과 일치하는지 본다. 시점 의존 수치(벤더 기본값, 지원 현황)는 문항으로 내지 않거나, 확인 날짜를 함께 적는다.
    • node tools/check-links.mjs — 레지스트리와 문항이 만들어 내는 URL이 살아 있는지. 403은 봇 차단이므로 실패가 아니다.
    • node tools/check-rfc-sections.mjsRFC 절 번호와 괄호에 적은 이름을 원문 목차와 대조한다. 이 게이트를 만든 날 46개 인용 중 9개가 틀려 있었다: Vary를 RFC 9110 §12.5.5가 아니라 §12.5.1(실제 제목 "Accept")로 적은 문항 세 건, If-Range를 §13.1.4(실제 "If-Unmodified-Since")로 적은 한 건, stale-if-error를 RFC 5861 §4가 아니라 §3(실제는 stale-while-revalidate)로 적은 한 건, 그 밖에도 부모 절을 자식 절의 이름으로 적은 사례들이 있었다. 전부 사람의 눈이 아니라 목차 대조로 발견됐다.
    • 잘 알려진 출처를 링크로 걸어 두었는데 그 문서가 주장을 뒷받침하지 않는 것이 가장 손실이 큰 결함이다. 클릭 한 번으로 확인되고, 하나가 틀린 것으로 드러나면 나머지 인용 전체의 신뢰가 같이 떨어진다. 같은 라운드에서 이 부류로 13건을 지웠다(예: AWS 개념인 Origin Shield를 GCP 발표 자료로 인용, 배포 카나리 사실을 CDN 페일오버 근거로 인용). 인용을 지우는 비용은 거의 0이다. 벤더 문서가 이미 진짜 근거였기 때문이다. 확신이 없으면 링크 없이 텍스트 근거만 둔다.

7. 출시 후: 데이터로 고친다

기능하지 않는 오답은 데이터로만 확인된다.

  • 문항별 보기 선택 분포를 익명 집계한다.
  • 선택률 5% 미만인 오답은 죽은 보기다. 원장에서 다른 오개념을 꺼내 교체한다.
  • 정답률이 §5의 목표 범위를 벗어난 문항은 난이도를 재분류하거나 재작성한다.
  • 확신도 × 정답 여부 교차표를 본다. "확신했는데 틀린" 비율이 높은 문항이 가장 가치 있는 문항이다. 그 주제를 더 깊이 다뤄서 문항을 늘린다.

8. 문항을 기여하려면

  1. data/misconceptions/<topic>.md에 근거가 될 오개념이 있는지 본다. 없으면 먼저 추가한다.
  2. data/questions/<topic>.json에 문항을 추가한다.
  3. node tools/validate.mjs를 통과시킨다.
  4. PR에 각 오답이 어느 오개념에서 왔는지 한 줄씩 적는다.

오답의 출처를 설명하지 못하는 PR은 병합하지 않는다.


9. 근거 문헌

§0 표와 §3의 근거다. 이 문서의 다른 인용과 같은 기준을 적용한다: 문서가 주장을 실제로 뒷받침하는 것만 싣고, 전해 들은 요약은 싣지 않는다. 링크는 DOI 를 쓴다. 일부 출판사는 자동화 요청에 403 을 주지만(check-links 의 봇 차단 규칙과 같은 부류), 브라우저에서는 열린다.

  1. Smith, M. A., & Karpicke, J. D. (2014). Retrieval practice with short-answer, multiple-choice, and hybrid tests. Memory, 22(7), 784–802. https://doi.org/10.1080/09658211.2013.831454
  2. Rodriguez, M. C. (2005). Three options are optimal for multiple-choice items: A meta-analysis of 80 years of research. Educational Measurement: Issues and Practice, 24(2), 3–13. https://doi.org/10.1111/j.1745-3992.2005.00006.x
  3. Little, J. L., Bjork, E. L., Bjork, R. A., & Angello, G. (2012). Multiple-choice tests exonerated, at least of some charges: Fostering test-induced learning and avoiding test-induced forgetting. Psychological Science, 23(11). https://doi.org/10.1177/0956797612443370
  4. Butterfield, B., & Metcalfe, J. (2001). Errors committed with high confidence are hypercorrected. Journal of Experimental Psychology: Learning, Memory, and Cognition, 27(6), 1491–1494. https://doi.org/10.1037/0278-7393.27.6.1491
  5. Metcalfe, J. (2017). Learning from errors. Annual Review of Psychology, 68. https://doi.org/10.1146/annurev-psych-010416-044022
  6. Butler, A. C., & Roediger, H. L. (2008). Feedback enhances the positive effects and reduces the negative effects of multiple-choice testing. Memory & Cognition, 36(3), 604–616. https://doi.org/10.3758/MC.36.3.604
  7. Butler, A. C., Fazio, L. K., & Marsh, E. J. (2011). The hypercorrection effect persists over a week, but high-confidence errors return. Psychonomic Bulletin & Review, 18(6). https://doi.org/10.3758/s13423-011-0173-y
  8. Haladyna, T. M., Downing, S. M., & Rodriguez, M. C. (2002). A review of multiple-choice item-writing guidelines for classroom assessment. Applied Measurement in Education, 15(3). https://doi.org/10.1207/S15324818AME1503_5