Step 297. ★ CTF #10: 10회차 기념 — 전체 회고 — 성장은 선형이 아니라 정체와 도약의 반복이다
Level 3 — CTF 실전과 공격 스킬 심화 | 난이도 ★★★★☆ | 예상 소요 시간 2일 (대회 24~48시간 + 통합 회고 1일)
전제: Step 279~295의 대회 #1~#9 전체, 각 대회의 로그·복기표·갭 분석 기록.
- 준비물: 주말 대회 1개(열 번째 출전), 지금까지의 대회 기록 전부(로그·복기표·갭 분석·순위 메모), 파이썬 + matplotlib, 팀 전원이 모이는 회고 시간. 이 챕터의 대회 장면은 화면 예시이고, 통합 분석 스크립트는 여러분의 기록으로 직접 돌리는 실측 도구입니다.
- ⚠️ 이 챕터의 실습은 내 랩·합법 플랫폼 전용입니다. 허가 없는 시스템에 적용하면 범죄입니다. 회고 자료에 팀원의 개인정보·기록을 실을 때는 본인 동의와 가공이 먼저입니다.
- 이 챕터는 대회 + 정리입니다 — 열 번째 대회에 평소 루틴으로 출전하고, 10개 대회의 궤적을 하나의 문서로 회고합니다.
열 번째 대회는 이정표입니다. 첫 대회의 로그를 펼쳐 보세요 — 전 문제 훑기 30분에 벌벌 떨던 팀, 쉬운 문제 2개를 풀고 환호하던 팀. 그리고 지금의 여러분을 나란히 놓아 보세요. 푼 문제 수, 순위 백분위, 커버하는 분야, 문제를 보는 속도 — 전부 다른 숫자일 것입니다.
그런데 그 변화를 그래프로 그리면 직선이 아닙니다. 성장은 정체기와 도약의 반복으로 옵니다 — 몇 회 연속 제자리인 듯하다가, 어느 대회에 갑자기 계단을 오릅니다. 오늘의 회고는 그 궤적을 데이터로 확인하고, 도약의 직전에 무엇을 했는지를 연결해, 다음 10회(시즌 2)를 설계하는 일입니다. 기념일의 의무는 축하가 아니라 기록의 완성입니다.
1. 학습 목표
이 챕터를 끝내면 다음을 할 수 있습니다:
- 평소 루틴을 유지한 채 10번째 대회에 출전해 비교 가능한 데이터를 확보한다
- 10개 대회를 "회차|순위|득점|푼 문제|분야별 득점|비고"의 통합 데이터표로 정리한다
- 순위 백분위 추이를 그래프로 그리고 도약 시점과 그 직전 훈련을 연결한다
- 정체기의 원인과 탈출 계기를 분석해 재현 가능한 성장 조건을 추출한다
- 시즌 2(대회 #11~#20)의 목표 순위대·훈련 방향·운영 방향을 설계한다
2. 배경 지식 — 오늘의 도구와 개념
오늘의 도구 한눈에 보기
| 구분 | 내용 |
|---|---|
| 언어·환경 | 파이썬 3 + matplotlib(추이 그래프), 스프레드시트 또는 마크다운 표 |
| 오늘의 명령 | python season_review.py — 통합 데이터표 + 백분위 추이 그래프 |
| 필요한 개념 | 백분위 추이, 정체기·도약의 구조, 장기 회고 글의 구성 |
| 오늘의 산출물 | 대회 #10 로그 + 10회 통합 회고 문서 + 시즌 2 계획 |
2-1. 왜 백분위인가 — 절대 점수의 함정
10개 대회의 점수를 나란히 놓으면 비교가 안 됩니다 — 대회마다 총점·참가 수준·난이도가 다릅니다. 450점은 어느 대회에선 하위이고 어느 대회에선 중위입니다. 비교 가능한 지표는 순위 백분위(내 순위 ÷ 전체 팀 수)입니다 — 참가 풀 안에서의 상대 위치이므로 대회 규모가 달라도 같은 단위로 읽힙니다.
단, 백분위에도 노이즈는 있습니다 — 강팀이 몰린 대회에서는 같은 실력도 백분위가 나빠집니다. 그래서 회고는 한 회차의 등락이 아니라 추세선을 읽는 일입니다. 한 번의 하락은 데이터이고, 세 번 연속의 하락은 신호입니다.
2-2. 정체기와 도약 — 성장 곡선의 실제 모양
기술 습득의 곡선은 계단형입니다. 훈련을 시작해도 점수는 당장 안 오릅니다 — 배운 것이 실전 패턴으로 굳는 데 시차가 있기 때문입니다. 그 시차 동안의 제자리가 정체기이고, 굳은 것이 한꺼번에 점수로 환산되는 회차가 도약입니다.
이 구조를 모르면 정체기에 "안 늘어난다"며 루틴을 바꾸고, 막 굳어가던 것을 버립니다. 구조를 알면 정체기의 질문이 달라집니다 — "왜 안 늘지?"가 아니라 "지금 굳어가고 있는 것이 무엇인가". 회고의 핵심 작업은 각 도약 시점을 찾아 그 직전 2~3주의 훈련을 연결하는 것입니다 — 그 연결이 시즌 2 설계의 원재료입니다.
2-3. 통합 데이터표 — 기록이 없는 회차는 "기록 없음"
10개 대회를 한 표에 모읍니다. 규칙이 하나 있습니다 — 기억에 의존해 채우지 않습니다. 로그도 순위 메모도 없는 회차는 빈칸이 아니라 "기록 없음"으로 명시합니다.
이 규칙이 억지스러워 보일 수 있지만, 두 가지 이유가 있습니다. ① 기억으로 채운 숫자는 분석을 오염시킵니다 — 추세선이 기억의 미화를 반영하게 됩니다. ② "기록 없음" 칸의 분포 자체가 데이터입니다 — 기록이 비는 시기에 기록 루틴이 무너졌었다는 뜻이고, 그것이 시즌 2 운영 계획의 첫 항목이 됩니다.
2-4. 장기 회고 글의 구성 — 블로그에 쓸 이정표 문서
이 회고는 블로그 포트폴리오(Step 294)의 대표작 후보이기도 합니다. 10개 대회 회고 글의 권장 구성은 다섯 단락입니다.
1. 숫자로 보는 10회 — 통합 데이터표와 추이 그래프 (수식어 없이 숫자만)
2. 도약의 지도 — 각 도약 시점과 그 직전에 한 훈련의 연결
3. 정체기의 기록 — 멈췄던 구간, 원인, 탈출 계기
4. 팀의 진화 — 운영 규칙·전술이 어떻게 바뀌었나 (헌장의 버전 이력)
5. 시즌 2 선언 — 다음 10회의 목표와 측정 방법
포인트는 1단락의 "수식어 없이"입니다. 장기 회고 글의 신뢰는 숫자가 먼저 나오는 데서 옵니다 — 해석은 2단락 이후의 일입니다.
3. 따라 하기
3-1. 대회 #10 — 평소 루틴으로
열 번째라고 특별한 전술을 쓰지 마세요. 회고의 비교 가능성은 "같은 조건"에서 나옵니다 — 확정된 팀 전술, 4시간 점검, 스왑 규칙, 킥오프 예측표까지 전부 평소 그대로입니다. 기념 대회의 특별함은 전술이 아니라 기록의 충실도로 표현합니다 — 이번 대회 로그는 10회 통합표의 마지막 행이 되니, 시간 기록과 분야별 득점을 특히 빠짐없이 남깁니다.
화면 예시 (대회 #10 종료 직후 메모):
대회 #10: 428팀 중 120위 (상위 28.0%) — 30% 선 첫 진입
득점 2900, 해결 8문제 (web 2, pwn 2, crypto 2, rev 1, forensics 1)
비고: babyheap 류 힙 문제 첫 해결 — 대회 #9 갭 분석의 단일 목표 달성 확인
마지막 줄을 보세요 — 대회 #9의 단일 개선 목표("힙 특훈")가 이번 대회의 득점으로 회수됐습니다. 판정 기준이 있는 목표는 이렇게 다음 대회에서 결산이 됩니다. 이 한 줄이 회고 글의 가장 값진 문장입니다.
3-2. 통합 데이터표 작성
10개 대회의 기록을 모읍니다. 대회 로그와 CTFtime 기록을 대조하며 채우고, 없는 것은 "기록 없음"입니다.
화면 예시 (통합 데이터표 — 이 챕터의 예시 데이터):
| 회차 | 전체 | 순위 | 백분위 | 득점 | 해결 | 비고 |
|---|---|---|---|---|---|---|
| #1 | 380 | 291 | 상위 77% | 450 | 2 | 첫 대회, 완주가 목표 |
| #2 | 405 | 262 | 상위 65% | 700 | 3 | 팀 첫 출전 |
| #3 | 356 | 178 | 상위 50% | 1100 | 4 | 행동 목표 도입 |
| #4 | 390 | 187 | 상위 48% | 1050 | 4 | 약점 공략 실험 |
| #5 | 402 | 165 | 상위 41% | 1400 | 5 | Hard 첫 도전 |
| #6 | 433 | 201 | 상위 46% | 1250 | 5 | 중간 평가 — 하락 |
| #7 | 368 | 140 | 상위 38% | 1900 | 6 | 라이브러리 검증 |
| #8 | 395 | 158 | 상위 40% | 1700 | 5 | 로테이션 실험 |
| #9 | 412 | 156 | 상위 38% | 2350 | 7 | 30% 도전 미달, 갭 분석 |
| #10 | 428 | 120 | 상위 28% | 2900 | 8 | 30% 진입, 힙 특훈 결실 |
읽는 법: 두 구간이 보여야 합니다 — #5→#6의 하락(41%→46%)과 #8~#10의 완만한 진입. 하락이 실패가 아니라는 것은 비고란이 설명합니다 — #6은 강팀이 몰린 대회였고, 절대 해결 수(5문제)는 유지됐습니다. 숫자의 등락을 비고의 맥락과 함께 읽는 것이 통합표의 정확한 사용법입니다.
3-3. 추이 그래프 — 성장 곡선의 시각화
표를 그래프로 그립니다. matplotlib으로 백분위 추이를 선 그래프로 그리고, 50%·30% 기준선을 긋는 스크립트입니다. season_review.py로 저장하세요.
# season_review.py — CTF 10개 대회 통합 회고 분석기
# ROUNDS 목록을 우리 팀 기록으로 교체해서 사용
import sys
from pathlib import Path
import matplotlib.pyplot as plt
plt.rcParams["font.family"] = ["Malgun Gothic", "Noto Sans SC"] # 한글 폰트
plt.rcParams["axes.unicode_minus"] = False
ROUNDS = [ # 회차, 전체 팀 수, 우리 순위, 득점, 푼 문제 수
(1, 380, 291, 450, 2), (2, 405, 262, 700, 3), (3, 356, 178, 1100, 4),
(4, 390, 187, 1050, 4), (5, 402, 165, 1400, 5), (6, 433, 201, 1250, 5),
(7, 368, 140, 1900, 6), (8, 395, 158, 1700, 5), (9, 412, 156, 2350, 7),
(10, 428, 120, 2900, 8),
]
CATS = ["web", "pwn", "rev", "crypto", "forensics"]
R1 = [1, 0, 0, 1, 0] # 대회 #1의 분야별 해결 수
R10 = [2, 2, 1, 2, 1] # 대회 #10의 분야별 해결 수
print("[10개 대회 통합 데이터]")
print(f"{'회차':>3} {'전체':>5} {'순위':>5} {'백분위':>8} {'득점':>6} {'해결':>4}")
pcts = []
for r, total, rank, score, solves in ROUNDS:
pct = rank / total * 100
pcts.append(pct)
print(f"{r:>3} {total:>5} {rank:>5} {'상위 %.1f%%' % pct:>10} {score:>6} {solves:>4}")
print("\n[분야별 성장 — #1 대비 #10]")
for c, a, b in zip(CATS, R1, R10):
print(f" {c:<10} {a}개 → {b}개 (+{b - a})")
fig, ax = plt.subplots(figsize=(8, 4.2))
ax.plot([r[0] for r in ROUNDS], pcts, marker="o", color="#2b6cb0")
ax.axhline(50, ls="--", lw=1, color="gray"); ax.axhline(30, ls="--", lw=1, color="crimson")
ax.text(1, 51, "상위 50%", color="gray"); ax.text(1, 31, "상위 30%", color="crimson")
ax.invert_yaxis() # 백분위는 낮을수록 좋으니 위로 갈수록 좋게 뒤집는다
ax.set_xlabel("대회 회차"); ax.set_ylabel("순위 백분위(%, 낮을수록 좋음)")
ax.set_title("CTF #1~#10 순위 백분위 추이")
ax.set_xticks([r[0] for r in ROUNDS])
fig.savefig("season_trend.png", bbox_inches="tight")
print("\n그래프 저장: season_trend.png")
실행 결과입니다 — 예시 데이터를 넣은 실측 출력입니다:
[10개 대회 통합 데이터]
회차 전체 순위 백분위 득점 해결
1 380 291 상위 76.6% 450 2
2 405 262 상위 64.7% 700 3
3 356 178 상위 50.0% 1100 4
4 390 187 상위 47.9% 1050 4
5 402 165 상위 41.0% 1400 5
6 433 201 상위 46.4% 1250 5
7 368 140 상위 38.0% 1900 6
8 395 158 상위 40.0% 1700 5
9 412 156 상위 37.9% 2350 7
10 428 120 상위 28.0% 2900 8
[분야별 성장 — #1 대비 #10]
web 1개 → 2개 (+1)
pwn 0개 → 2개 (+2)
rev 0개 → 1개 (+1)
crypto 1개 → 2개 (+1)
forensics 0개 → 1개 (+1)
그래프 저장: season_trend.png
저장된 season_trend.png를 열어 보세요 — 77%에서 시작한 선이 #3에서 50% 선을 넘고, #5~#6에서 오르락하며, #10에서 마침내 30% 선 아래로 내려갑니다. 분야별 성장 표는 또 다른 이야기를 합니다 — #1에는 0개였던 분야가 셋(pwn·rev·forensics)이었는데, #10에서는 전 분야에서 득점이 나왔습니다. 순위의 성장보다 커버리지의 성장이 체급 상승의 본체입니다.
3-4. 도약과 정체기의 연결
그래프의 등락마다 "그 직전에 뭘 했나"를 기록에서 찾습니다.
화면 예시 (도약 분석):
도약 1: #2(65%) → #3(50%) — 직전에 한 일: 팀 분업 도입, 행동 목표 설정
도약 2: #6(46%) → #7(38%) — 직전에 한 일: 익스플로잇 라이브러리 구축 (블록 C)
도약 3: #9(38%) → #10(28%) — 직전에 한 일: 힙 특훈 (대회 #9의 단일 개선 목표)
정체기: #3~#5 (50→48→41%) — 완만했지만 실은 준비 구간
#6 하락의 원인: 강팀 몰림 + Hard 도전에 시간 배분 (해결 수는 유지)
읽는 법: 세 도약의 공통점이 보입니다 — 전부 특정한 사전 투자(분업, 라이브러리, 특훈)의 회수입니다. 우연히 잘된 대회는 없었습니다. 이것이 시즌 2 계획의 근거입니다 — 다음 도약을 원하면 투자를 먼저 예약해야 하고, 점수는 시차를 두고 옵니다.
3-5. 시즌 2 설계와 회고 글 발행
마지막으로 다음 10회를 설계합니다. 목표는 백분위로, 투자는 구체 루틴으로 적습니다.
화면 예시 (시즌 2 계획):
== 시즌 2 (대회 #11~#20) 계획 ==
목표 순위대: #15까지 상위 30% 안착 → #20까지 상위 20% 도전
훈련 방향: ① 국내 대회(코드게이트·CCE) 예선 대비 기출 훈련
② rev·forensics 세컨드 육성 — 커버리지 깊이 확보
③ Medium급 속도 — 문제당 평균 시간 20% 단축
운영 방향: 팀 헌장 v1의 KPT 갱신 리듬 유지, 기록 루틴 강화
(시즌 1의 "기록 없음" 칸 재발 방지 — 대회 로그 템플릿 고정)
측정: 매 대회 갭 분석 + 5회마다 중간 회고 (#15, #20)
이 문서를 2-4의 다섯 단락 구성으로 블로그에 발행합니다 — 통합표, 추이 그래프(season_trend.png), 도약의 지도, 정체기 기록, 시즌 2 선언. 10개 대회의 회고 글은 그 자체가 대표작입니다 — 꾸준함의 증명 위에 분석력까지 보여주는 글이니까요.
4. 미션과 연습문제
미션 — 대회 #10 완주 + 10회 통합 회고 문서
- 평소 루틴 그대로 대회 #10에 출전하고, 로그를 특히 충실히 기록합니다 — 통합표의 마지막 행이 됩니다.
- 10개 대회의 통합 데이터표(회차|전체|순위|백분위|득점|해결|비고)를 작성합니다 — 없는 기록은 "기록 없음".
season_review.py의ROUNDS·R1·R10을 우리 팀 기록으로 교체해 실행하고, 추이 그래프를 저장합니다.- 각 도약 시점과 그 직전 훈련을 연결한 "도약의 지도"를 작성하고, 정체기 1개 이상의 원인과 탈출 계기를 분석합니다.
- 대회 #9의 단일 개선 목표가 이번 대회에서 회수됐는지 결산합니다 — 회수됐다면 회고 글에 명시합니다.
- 시즌 2 계획(목표 순위대·훈련 방향·운영 방향·측정 주기)을 작성하고, 2-4의 다섯 단락 구성으로 회고 글을 블로그에 발행합니다.
연습문제
문제 1. 10개 대회의 성적 비교에 절대 점수 대신 순위 백분위를 쓰는 이유는 무엇인가요? 백분위에도 남아 있는 노이즈는 무엇인가요?
문제 2. 성장 곡선이 선형이 아니라 계단형(정체기+도약)으로 나타나는 이유를 "훈련의 점수 환산 시차" 개념으로 설명해 보세요. 정체기에 루틴을 바꾸면 왜 위험한가요?
문제 3. 기록이 없는 회차를 기억으로 채우지 않고 "기록 없음"으로 남기는 이유 두 가지를 설명해 보세요.
문제 4. "순위의 성장보다 분야 커버리지의 성장이 체급 상승의 본체"라는 해석의 근거를, 이 챕터의 예시 데이터(#1 대비 #10)로 설명해 보세요.
5. 모범 답안과 완료 기준
미션 모범 답안
검증 기준으로 확인하세요.
- 루틴의 일관성: 대회 #10에 기념 특별 전술 없이 평소 루틴을 적용했는가 — 비교 가능성이 회고의 생명입니다.
- 통합표의 완결: 10개 행이 전부 있고, 빈 칸이 "기록 없음"으로 명시됐으며, 비고란이 등락의 맥락을 설명하는가.
- 그래프의 정확성: 추이 그래프가 통합표의 숫자와 일치하고(그래프의 점 = 표의 백분위), 50%·30% 기준선이 있는가.
- 도약 연결의 실증성: 각 도약이 "직전 2~3주의 구체 훈련"과 연결됐는가 — "열심히 했다"는 연결이 아닙니다.
- 목표 결산: 대회 #9의 단일 개선 목표의 회수 여부가 판정 기준대로 결산됐는가.
- 시즌 2의 측정 가능성: 목표가 백분위로, 측정 주기가 명시된가 — "더 잘하자"는 계획이 아닙니다.
- 회고 글의 구성: 다섯 단락 구조를 따르고 첫 단락이 수식어 없는 숫자인가.
연습문제 해답
문제 1 해답. 대회마다 총점·난이도·참가 수준이 달라 절대 점수는 단위가 통일되지 않기 때문입니다 — 450점은 어느 대회에선 하위권, 어느 대회에선 중위권입니다. 백분위는 "참가 풀 내 상대 위치"라서 규모가 다른 대회끼리도 비교됩니다. 남은 노이즈는 참가 풀의 구성입니다 — 강팀이 몰린 대회에서는 같은 실력도 백분위가 나빠집니다(예시의 #6). 그래서 백분위는 단일 회차가 아니라 추세선으로 읽고, 등락은 비고란의 맥락과 함께 해석해야 합니다.
문제 2 해답. 배운 기법이 실전에서 점수가 되려면 "문제를 보고 그 기법을 떠올리는" 패턴 인식까지 굳어야 하는데, 이 숙성에 시간이 걸리기 때문입니다. 훈련 직후에는 지식은 있지만 발동이 느려 점수가 안 오르고(정체기), 숙성이 끝난 회차에 여러 기법이 한꺼번에 환산됩니다(도약). 정체기에 루틴을 바꾸면 막 굳어가던 것이 폐기됩니다 — 환산 직전에 투자를 회수하지 못하는 것입니다. 정체기의 올바른 질문은 "왜 안 오르지"가 아니라 "지금 굳어가고 있는 것이 무엇인가"입니다.
문제 3 해답. 첫째, 기억으로 채운 숫자는 미화되는 경향이 있어 추세선을 오염시킵니다 — 분석의 입력이 허구면 출력도 허구입니다. 둘째, "기록 없음" 칸의 분포 자체가 유효한 데이터이기 때문입니다 — 기록이 비는 시기는 기록 루틴이 무너진 시기이고, 그 정보는 시즌 2의 운영 계획(기록 템플릿 고정 같은)으로 직결됩니다. 없는 것을 없다고 쓰는 것이 회고의 정직성이고, 정직하지 않은 회고는 다음 시즌의 잘못된 설계로 되돌아옵니다.
문제 4 해답. 예시에서 백분위는 77%→28%로 개선됐지만 이것은 상대 위치라 대회 풀에 따라 흔들립니다. 반면 분야 커버리지는 #1의 "5개 분야 중 2개만 득점"에서 #10의 "전 분야 득점"으로 바뀌었고, 이것은 대회 풀과 무관한 절대 역량의 확장입니다. 특히 pwn이 0→2개로 움직인 것은 힙 특훈이라는 특정 투자의 회수이므로 재현 가능합니다. 순위는 환경이 만들고, 커버리지는 팀이 만듭니다 — 그래서 체급을 재는 자로는 후자가 정확합니다.
완료 기준 체크리스트
- [ ] 대회 #10에 평소 루틴으로 출전하고 로그를 충실히 남겼다
- [ ] 10개 대회 통합 데이터표를 완성했다 (없는 기록은 "기록 없음")
- [ ]
season_review.py를 우리 기록으로 실행해 추이 그래프를 저장했다 - [ ] 도약 시점과 직전 훈련의 연결(도약의 지도)을 작성했다
- [ ] 정체기 1개 이상의 원인과 탈출 계기를 분석했다
- [ ] 대회 #9 단일 개선 목표의 회수 여부를 결산했다
- [ ] 시즌 2 계획(목표 백분위·훈련·운영·측정 주기)을 문서화했다
- [ ] 다섯 단락 구성의 회고 글을 블로그에 발행했다
6. 흔한 실수와 해결
벽 1. 그래프의 한글이 전부 네모(□□)로 깨져요
증상: 저장할 때 이런 경고가 뜹니다.
UserWarning: Glyph 45824 (\N{HANGUL SYLLABLE DAE}) missing from font(s) Noto Sans SC.
fig.savefig(Path(__file__).parent / "season_trend.png", bbox_inches="tight")
원인: matplotlib의 기본 CJK 폰트(Noto Sans SC)는 중국어 간체 폰트라 한글 글리프가 없습니다 (실측).
해결: 스크립트의 폰트 설정처럼 윈도우라면 Malgun Gothic을 첫 항목으로 지정하세요 — plt.rcParams["font.family"] = ["Malgun Gothic", "Noto Sans SC"]. 폰트 설정은 import 직후, 그림을 만들기 전에 해야 적용됩니다. macOS라면 AppleGothic, 리눅스라면 Noto Sans CJK KR를 씁니다.
벽 2. 옛날 대회 기록이 반쯤 없어요 — 회고를 포기해야 하나요?
증상: 초기 대회 2~3개의 순위·득점이 기억에만 있습니다.
원인: 시즌 1 초반에는 기록 루틴이 잡히기 전이었습니다 — 대부분의 팀이 그렇습니다.
해결: 회고는 포기하지 않되, 기억과 기록을 분리하세요. CTFtime에 팀이 등록돼 있었다면 과거 대회 결과 페이지에서 순위가 복구되는 경우가 많습니다 — 그것은 기록입니다. 복구가 안 되는 칸은 "기록 없음"으로 남기고, 회고 글의 정체기 분석에 "기록 루틴 부재" 자체를 초기 정체의 한 요인으로 씁니다. 그리고 시즌 2 첫 항목이 됩니다 — 대회 로그 템플릿 고정. 결손도 분석하면 자산이 됩니다.
벽 3. 추이 그래프가 하락세라 보여주기가 창피해요
증상: 백분위가 나빠진 구간이 있어 발행을 망설입니다.
원인: 회고 글을 성적표로 생각하기 때문입니다 — 회고 글의 독자가 보는 것은 성적이 아니라 분석력입니다.
해결: 하락 구간이 있는 회고가 오히려 강합니다. 예시의 #6 하락도 "강팀 몰림 + 해결 수 유지"라는 맥락과 함께라면 성실한 분석의 증거입니다. 우상향만 있는 회고는 두 가지로 읽힙니다 — 운이 좋았거나, 솔직하지 않거나. 등락을 숫자와 맥락으로 설명하는 글, 그것이 대표작감입니다.
벽 4. 시즌 2 목표를 "상위 10%"로 높게 잡았어요
증상: 기념 대회의 분위기에 목표가 부풀었습니다.
원인: 도약 직후의 고양감은 좋은 것이지만, 목표 설정에는 독입니다.
해결: 목표 상향의 규칙으로 돌아가세요 — "마지막으로 달성한 선의 다음 눈금"(Step 295). 30%에 이제 막 진입했다면 다음 눈금은 "30% 안착 → 20% 도전"이지 10%가 아닙니다. 도약은 계단을 한 칸 오르는 것이지 층을 뛰어넘는 것이 아닙니다 — 시즌 2의 10회를 믿고 점진으로 배팅하세요. 목표가 과하면 갭 분석이 매번 "대실패"를 출력하고, 팀은 지칩니다.
벽 5. 회고 글이 자서전처럼 길어져요
증상: 대회마다의 에피소드를 다 쓰다 보니 1만 자가 넘습니다.
원인: 10회의 기억이 전부 소중합니다 — 그러나 회고 글은 기억의 보관소가 아니라 분석 문서입니다.
해결: 2-4의 다섯 단락 구성을 뼈대로 고정하고, 각 단락에 분량 제한(1단락 표+그래프, 2~4단락 각 5문장 이내)을 거세요. 개별 대회의 에피소드는 이미 각 대회의 Write-up에 있습니다 — 회고 글에서는 링크로 회수하면 됩니다. "이 대회의 자세한 이야기는 여기"라는 링크 10개가 회고 글을 가볍게 하고, 동시에 블로그의 다른 글로 독자를 흘려보내는 시리즈 묶기(Step 294)의 효과도 냅니다.
7. 정리
오늘의 개념
| 개념 | 한 줄 설명 |
|---|---|
| 순위 백분위 | 규모가 다른 대회를 같은 단위로 비교하는 지표 — 추세선으로 읽는다 |
| 계단형 성장 | 훈련→숙성→환산의 시차 구조 — 정체기는 준비 구간 |
| 도약의 지도 | 각 도약과 그 직전 투자의 연결 — 다음 도약의 예약 방법 |
| 기록 없음 원칙 | 기억으로 채우지 않는다 — 결손의 분포도 데이터 |
| 커버리지 성장 | 전 분야 득점 확장 — 대회 풀과 무관한 절대 역량 지표 |
| 시즌 설계 | 목표는 백분위로, 투자는 루틴으로, 측정은 주기로 |
오늘의 도구·명령어
| 도구·명령 | 하는 일 |
|---|---|
python season_review.py |
통합 데이터표 출력 + 백분위 추이 그래프 저장 |
plt.rcParams["font.family"] |
그래프 한글 폰트 지정 — 윈도우는 Malgun Gothic |
| 통합 데이터표 | 10회의 단일 진실 공급원 — 비고란이 맥락 담당 |
| 도약의 지도 | 투자→도약 연결표 — 시즌 2의 근거 문서 |
| 회고 글 다섯 단락 | 숫자 → 도약 → 정체 → 팀 진화 → 시즌 2 선언 |
명령어보다 중요한 감각
10개 대회의 데이터가 말해주는 가장 중요한 사실은 순위가 아닙니다 — "이 팀은 투자한 것을 회수하는 팀이 됐다"는 것입니다. 분업을 도입하면 다음 대회에 점수가 오르고, 라이브러리를 만들면 그다음에 오르고, 특훈을 하면 그 유형이 풀립니다. 이 인과가 데이터로 확인된 팀은 더 이상 대회 결과를 운으로 읽지 않습니다.
시즌 2의 첫 투자는 이미 정해져 있습니다 — 국내 대회 예선입니다. 코드게이트와 CCE는 지금까지의 주말 대회와는 결이 다른 무대이고, 그 결을 파악하는 방법은 기출입니다. 그것이 다음 스텝의 주제입니다.
전부 체크되면 Step 297 완료입니다. 사이드바의 체크박스를 눌러 진도를 저장하세요.