[HIGH] - 로그인 잠금 XFF 스푸핑 우회: X-Forwarded-For leftmost(위조 가능) → rightmost(Caddy가 붙인 실제 IP) 사용 - 멘토 기본 비밀번호 하드코딩 제거: env 미설정 시 SecureRandom 생성 후 로그 1회 출력. compose에 MENTOR_INITIAL_PASSWORD 추가 - 클릭 카드 키보드 접근 불가(학습문서 전체): Card에 role=button·tabIndex·Enter/Space·aria-label [MEDIUM] - CSV 수식 인젝션: =+-@ 로 시작하는 학생 자유입력 앞에 ' 붙여 엑셀 수식화 차단 (+회귀 테스트) - 학습문서 17개 <html lang=ko> 골격 주입 (스크린리더 한국어 발음) - 과제 제출 폼 label htmlFor/id 연결 - 상단 아이콘 링크(👤·🔑) aria-label + 이모지 aria-hidden - 멘토 제출물 표 행 키보드 접근(role/tabIndex/Enter·Space) - 배지 amber/teal 글자 대비 4.5:1 확보(테마별 --amber-text/--teal-text) [LOW] - 코드에디터 포커스 표시(:focus-within), 문제번호 색 대비(--muted), 카드 :focus-visible - 폼 오류 메시지 role=alert (스크린리더 즉시 안내) 검증: 테스트 26개 통과, 운영에서 XFF 우회 차단(6회째 429)·카드 role/aria·문서 lang=ko 확인. PMD 29건은 전부 저심각 스멜로 실질 결함 없음. 각 수정에 원리 학습 주석. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
475 lines
28 KiB
HTML
475 lines
28 KiB
HTML
<!doctype html>
|
||
<html lang="ko">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>CS 기본기 4주 커리큘럼</title>
|
||
<style>
|
||
:root {
|
||
--paper: #FAFBFD; --card: #FFFFFF; --ink: #101A28; --ink-soft: #46536A;
|
||
--ink-faint: #7B8798; --line: #E4E8F0; --line-soft: #EFF2F7;
|
||
--primary: #2159C5; --primary-soft: #E5EDFB; --primary-deep: #163F8F;
|
||
--amber: #B9772A; --amber-soft: #F6EBDA; --amber-line: #E4C79A;
|
||
--blue: #0E8C86; --blue-soft: #E0F1EF;
|
||
--code-bg: #F1F4F9;
|
||
--shadow: 0 1px 2px rgba(16,26,40,.05), 0 8px 24px -12px rgba(16,26,40,.16);
|
||
--radius: 14px;
|
||
}
|
||
@media (prefers-color-scheme: dark) {
|
||
:root {
|
||
--paper: #0B1017; --card: #131A24; --ink: #E8EDF4; --ink-soft: #A4B0C0;
|
||
--ink-faint: #74808F; --line: #263140; --line-soft: #1C242F;
|
||
--primary: #6AA0F0; --primary-soft: #172A44; --primary-deep: #AECBF8;
|
||
--amber: #DBA25C; --amber-soft: #2C2318; --amber-line: #4A3B23;
|
||
--blue: #4FC7BE; --blue-soft: #14302E;
|
||
--code-bg: #161E28;
|
||
--shadow: 0 1px 2px rgba(0,0,0,.35), 0 10px 30px -14px rgba(0,0,0,.65);
|
||
}
|
||
}
|
||
:root[data-theme="light"] {
|
||
--paper: #FAFBFD; --card: #FFFFFF; --ink: #101A28; --ink-soft: #46536A;
|
||
--ink-faint: #7B8798; --line: #E4E8F0; --line-soft: #EFF2F7;
|
||
--primary: #2159C5; --primary-soft: #E5EDFB; --primary-deep: #163F8F;
|
||
--amber: #B9772A; --amber-soft: #F6EBDA; --amber-line: #E4C79A;
|
||
--blue: #0E8C86; --blue-soft: #E0F1EF; --code-bg: #F1F4F9;
|
||
--shadow: 0 1px 2px rgba(16,26,40,.05), 0 8px 24px -12px rgba(16,26,40,.16);
|
||
}
|
||
:root[data-theme="dark"] {
|
||
--paper: #0B1017; --card: #131A24; --ink: #E8EDF4; --ink-soft: #A4B0C0;
|
||
--ink-faint: #74808F; --line: #263140; --line-soft: #1C242F;
|
||
--primary: #6AA0F0; --primary-soft: #172A44; --primary-deep: #AECBF8;
|
||
--amber: #DBA25C; --amber-soft: #2C2318; --amber-line: #4A3B23;
|
||
--blue: #4FC7BE; --blue-soft: #14302E; --code-bg: #161E28;
|
||
--shadow: 0 1px 2px rgba(0,0,0,.35), 0 10px 30px -14px rgba(0,0,0,.65);
|
||
}
|
||
|
||
* { box-sizing: border-box; }
|
||
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
|
||
body {
|
||
margin: 0; background: var(--paper); color: var(--ink);
|
||
font-family: "Pretendard", "Apple SD Gothic Neo", "Malgun Gothic", "Noto Sans KR", system-ui, sans-serif;
|
||
line-height: 1.72; -webkit-font-smoothing: antialiased; letter-spacing: -0.01em;
|
||
}
|
||
.wrap { max-width: 860px; margin: 0 auto; padding: clamp(20px, 4vw, 48px); }
|
||
|
||
.eyebrow { font-size: 12px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--amber); display: flex; align-items: center; gap: 10px; }
|
||
.eyebrow::before { content: ""; width: 22px; height: 2px; background: var(--amber); border-radius: 2px; }
|
||
.eyebrow.green { color: var(--primary); } .eyebrow.green::before { background: var(--primary); }
|
||
.eyebrow.blue { color: var(--blue); } .eyebrow.blue::before { background: var(--blue); }
|
||
|
||
/* Masthead */
|
||
header.mast {
|
||
border: 1px solid var(--line); border-radius: var(--radius);
|
||
background: radial-gradient(120% 140% at 0% 0%, var(--amber-soft) 0%, transparent 55%), var(--card);
|
||
box-shadow: var(--shadow); padding: clamp(26px, 4vw, 42px);
|
||
}
|
||
.wordmark { font-size: 13px; font-weight: 800; letter-spacing: 0.22em; text-transform: uppercase; color: var(--ink-soft); }
|
||
.wordmark b { color: var(--amber); }
|
||
header.mast h1 { font-size: clamp(28px, 5.6vw, 42px); line-height: 1.14; margin: 16px 0 0; font-weight: 800; letter-spacing: -0.03em; text-wrap: balance; }
|
||
header.mast .lede { margin: 16px 0 0; font-size: clamp(15px, 2.4vw, 17px); color: var(--ink-soft); max-width: 56ch; }
|
||
.mast-meta { margin-top: 24px; display: flex; flex-wrap: wrap; gap: 10px; }
|
||
.chip { font-size: 13px; font-weight: 600; color: var(--ink-soft); background: var(--paper); border: 1px solid var(--line); padding: 6px 12px; border-radius: 999px; display: inline-flex; align-items: center; gap: 7px; }
|
||
.chip .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--amber); }
|
||
|
||
section { margin-top: clamp(34px, 6vw, 52px); scroll-margin-top: 20px; }
|
||
section > h2 { font-size: clamp(21px, 3.6vw, 27px); font-weight: 800; letter-spacing: -0.025em; margin: 14px 0 0; text-wrap: balance; }
|
||
section > .sub { color: var(--ink-soft); margin: 9px 0 0; font-size: 15.5px; max-width: 62ch; }
|
||
|
||
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); padding: clamp(20px, 3vw, 28px); }
|
||
.mt { margin-top: 18px; } .mt-s { margin-top: 12px; }
|
||
p { margin: 0; } strong { font-weight: 700; }
|
||
|
||
/* How-we-run ops box */
|
||
.ops { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px,1fr)); gap: 0; }
|
||
.ops .o { padding: 6px 18px; border-left: 3px solid var(--amber); }
|
||
.ops .o:first-child { padding-left: 0; border-left: 0; }
|
||
.ops .o .k { font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--amber); }
|
||
.ops .o .v { margin-top: 5px; font-size: 14.5px; color: var(--ink); }
|
||
.ops .o .v b { font-weight: 700; }
|
||
@media (max-width:560px){ .ops .o { border-left: 0; border-top: 1px solid var(--line-soft); padding: 12px 0; } .ops .o:first-child { border-top:0; } }
|
||
|
||
/* Week block */
|
||
.week-head { display: grid; grid-template-columns: auto 1fr; gap: 18px; align-items: center; margin-bottom: 4px; }
|
||
.week-badge { width: 62px; height: 62px; border-radius: 15px; background: var(--primary); color: #fff; display: grid; place-items: center; text-align: center; line-height: 1.05; box-shadow: var(--shadow); }
|
||
.week-badge .w { font-size: 11px; font-weight: 700; letter-spacing: 0.1em; opacity: .85; }
|
||
.week-badge .n { font-size: 24px; font-weight: 800; font-variant-numeric: tabular-nums; }
|
||
@media (prefers-color-scheme: dark){ .week-badge { color: #0E1512; } }
|
||
:root[data-theme="dark"] .week-badge { color: #0E1512; }
|
||
.w2 .week-badge { background: var(--amber); }
|
||
.w3 .week-badge { background: var(--blue); }
|
||
.w4 .week-badge { background: var(--primary-deep); }
|
||
.week-head h3 { margin: 0; font-size: clamp(19px,3.2vw,23px); font-weight: 800; letter-spacing: -0.02em; }
|
||
.week-head .goal { margin-top: 3px; color: var(--ink-soft); font-size: 14.5px; }
|
||
|
||
/* Daily rows */
|
||
.days { display: grid; gap: 0; margin-top: 6px; }
|
||
.day { display: grid; grid-template-columns: 66px 1fr; gap: 18px; padding: 18px 0; border-top: 1px solid var(--line-soft); }
|
||
.day:first-child { border-top: 0; }
|
||
.day .badge { font-size: 12px; font-weight: 800; letter-spacing: 0.03em; color: var(--primary); background: var(--primary-soft); border-radius: 8px; padding: 8px 4px; text-align: center; height: fit-content; white-space: nowrap; }
|
||
.w2 .day .badge { color: var(--amber); background: var(--amber-soft); }
|
||
.w3 .day .badge { color: var(--blue); background: var(--blue-soft); }
|
||
.w4 .day .badge { color: var(--primary-deep); background: var(--primary-soft); }
|
||
.day h4 { margin: 2px 0 0; font-size: 16px; font-weight: 800; letter-spacing: -0.01em; }
|
||
.meta { margin-top: 10px; display: grid; gap: 7px; }
|
||
.meta .m { display: grid; grid-template-columns: 74px 1fr; gap: 12px; font-size: 14px; align-items: start; }
|
||
.meta .m .lab { font-size: 11px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; padding-top: 3px; }
|
||
.meta .m.prac .lab { color: var(--amber); }
|
||
.meta .m.link .lab { color: var(--primary); }
|
||
.meta .m .txt { color: var(--ink-soft); }
|
||
.meta .m .txt b { color: var(--ink); font-weight: 600; }
|
||
code { font-family: "SF Mono","Cascadia Code","Consolas",ui-monospace,monospace; font-size: 0.9em; background: var(--code-bg); padding: 1px 6px; border-radius: 5px; letter-spacing: 0; }
|
||
|
||
.friday { background: var(--primary-soft); border-radius: 10px; padding: 4px 12px; }
|
||
.w2 .friday { background: var(--amber-soft); } .w3 .friday { background: var(--blue-soft); }
|
||
|
||
/* Designer track */
|
||
.dz { border: 1px dashed var(--blue); background: var(--blue-soft); border-radius: 12px; padding: 18px 20px; }
|
||
.dz .h { font-weight: 800; color: var(--blue); font-size: 14px; display: flex; align-items: center; gap: 8px; }
|
||
.dz p { color: var(--ink-soft); font-size: 14px; margin-top: 8px; }
|
||
.dz b { color: var(--ink); }
|
||
|
||
/* Check / assessment */
|
||
.assess { display: grid; gap: 12px; }
|
||
.assess .a { display: grid; grid-template-columns: 82px 1fr; gap: 16px; padding: 14px 0; border-top: 1px solid var(--line-soft); align-items: start; }
|
||
.assess .a:first-child { border-top: 0; }
|
||
.assess .a .wk { font-weight: 800; color: var(--primary); font-variant-numeric: tabular-nums; font-size: 14px; }
|
||
.assess .a .txt { font-size: 14.5px; color: var(--ink-soft); } .assess .a .txt b { color: var(--ink); font-weight: 600; }
|
||
|
||
.callout { margin-top:18px; border: 1px solid var(--amber-line); border-radius: var(--radius); background: var(--amber-soft); padding: 20px 24px; }
|
||
.callout h3 { margin: 0 0 6px; font-size: 16px; font-weight: 800; color: var(--ink); }
|
||
.callout p { color: var(--ink-soft); font-size: 14.5px; }
|
||
|
||
footer { margin-top: 48px; padding-top: 22px; border-top: 1px solid var(--line); color: var(--ink-faint); font-size: 13px; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px; }
|
||
|
||
@media (max-width: 560px) {
|
||
.day { grid-template-columns: 56px 1fr; gap: 12px; }
|
||
.meta .m { grid-template-columns: 60px 1fr; gap: 8px; }
|
||
.assess .a { grid-template-columns: 64px 1fr; }
|
||
}
|
||
@media print { body{background:#fff;} .card,header.mast,.week-badge{box-shadow:none;} section{break-inside:avoid;} }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<div class="wrap">
|
||
|
||
<header class="mast">
|
||
<div class="wordmark"><b>AWESOMEDEV</b> · 수습 교육 · Layer B</div>
|
||
<h1>컴퓨터 기본기<br>4주 커리큘럼</h1>
|
||
<p class="lede">개발 수습생 3명이 <strong>매일 아침 1시간</strong>씩, 4주 동안 컴퓨터의 뼈대를 잡는 과정이에요. 도구 사용법이 아니라 <strong>"컴퓨터가 어떻게 돌아가는가"</strong>를 배웁니다. 모든 주제는 마지막에 <strong>우리 회사 시스템</strong>으로 연결돼요.</p>
|
||
<div class="mast-meta">
|
||
<span class="chip"><span class="dot"></span>매일 아침 09:30–10:30 · 20일</span>
|
||
<span class="chip"><span class="dot"></span>강의 20분 + 실습 40분</span>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- How we run -->
|
||
<section id="how">
|
||
<div class="eyebrow">운영 방식</div>
|
||
<h2>이렇게 진행해요</h2>
|
||
<p class="sub">지루한 이론 통독은 안 해요. 짧게 배우고, 바로 손으로 확인하고, 우리 것에 붙입니다.</p>
|
||
<div class="card mt">
|
||
<div class="ops">
|
||
<div class="o"><div class="k">시간</div><div class="v"><b>매일 아침 1시간.</b> 하루를 가볍게 여는 루틴으로.</div></div>
|
||
<div class="o"><div class="k">구성</div><div class="v">강의 20분 → <b>실습 40분.</b> 듣기보다 해보기 위주.</div></div>
|
||
<div class="o"><div class="k">실습 언어</div><div class="v"><b>JavaScript</b>(React에서 쓰는 언어)로 개념 확인. 잡히면 <b>Java</b>(Spring Boot)로도 확인.</div></div>
|
||
<div class="o"><div class="k">마무리</div><div class="v">매일 <b>3줄 회고</b>, 금요일 <b>미니 퀴즈</b>로 이해도 확인.</div></div>
|
||
</div>
|
||
</div>
|
||
<div class="callout">
|
||
<h3>💡 멘토를 위한 한 가지 원칙</h3>
|
||
<p>모든 개념 끝에 꼭 <b>"그래서 우리 회사에선?"</b>을 붙여주세요. 학생이 배운 걸 우리 실제 스택(<b>React 웹 · Spring Boot · 클라우드 · React Native · Flutter</b>)에서 직접 보면, 죽은 지식이 살아 있는 이해가 됩니다.</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- WEEK 1 -->
|
||
<section id="w1" class="w1">
|
||
<div class="eyebrow green">Week 1</div>
|
||
<div class="card mt">
|
||
<div class="week-head">
|
||
<div class="week-badge"><span class="w">WEEK</span><span class="n">1</span></div>
|
||
<div>
|
||
<h3>컴퓨터 구조 — 컴퓨터는 결국 뭘 하는 기계인가</h3>
|
||
<div class="goal">데이터가 0과 1로 저장되고, 부품들이 어떻게 협력해 프로그램을 실행하는지 이해해요.</div>
|
||
</div>
|
||
</div>
|
||
<div class="days">
|
||
<div class="day">
|
||
<div class="badge">1일차<br>월</div>
|
||
<div>
|
||
<h4>2진수 · 비트 · 바이트 — 모든 건 0과 1</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">실습</span><span class="txt">10진수 ↔ 2진수 손으로 변환. 글자가 숫자로 바뀌는 것 보기(ASCII), <b>색이 숫자로</b>: <code>#15715A</code> 가 곧 RGB 숫자라는 것 확인.</span></div>
|
||
<div class="m link"><span class="lab">연결</span><span class="txt">디자이너가 쓰는 색상 코드도, 사진 한 장도 전부 숫자 덩어리예요.</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="day">
|
||
<div class="badge">2일차<br>화</div>
|
||
<div>
|
||
<h4>CPU · 메모리(RAM) · 저장장치 · 입출력</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">실습</span><span class="txt">내 PC <b>작업 관리자</b>로 CPU·메모리 사용량 관찰. 비유로 정리: 책상=RAM(작업 공간), 책장=디스크(보관).</span></div>
|
||
<div class="m link"><span class="lab">연결</span><span class="txt">우리가 서비스를 올리는 <b>클라우드 서버</b>도 똑같은 부품 구성. 사양(vCPU·RAM)이 뭘 뜻하는지 함께 확인.</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="day">
|
||
<div class="badge">3일차<br>수</div>
|
||
<div>
|
||
<h4>프로그램이 실행되면 벌어지는 일</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">실습</span><span class="txt">소스코드 → 실행 과정 따라가기. 간단한 <b>JavaScript(Node)</b> 프로그램을 돌리며 <b>프로세스</b>가 메모리에 올라가는 것 관찰.</span></div>
|
||
<div class="m link"><span class="lab">연결</span><span class="txt">우리가 만드는 <b>Spring Boot 서버 앱</b>도 이렇게 하나의 프로세스로 떠서 돌아가요.</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="day">
|
||
<div class="badge">4일차<br>목</div>
|
||
<div>
|
||
<h4>네트워크 기초 — 컴퓨터끼리 대화하는 법</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">실습</span><span class="txt">브라우저 <b>개발자도구 → Network 탭</b>으로 우리 사이트가 서버에 보내는 요청/응답 직접 보기. IP·포트·HTTP 개념.</span></div>
|
||
<div class="m link"><span class="lab">연결</span><span class="txt">우리 <b>React 웹</b>이 <b>REST API</b>로 <b>Spring Boot 서버</b>에 요청을 보내는 흐름을 눈으로 확인.</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="day">
|
||
<div class="badge">5일차<br>금</div>
|
||
<div>
|
||
<h4 class="friday">정리 & 미니 퀴즈 & 우리 시스템 세미나</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">확인</span><span class="txt">한 주 개념 퀴즈(10문항). "왜 메모리가 부족하면 서버가 느려지나?"를 스스로 설명해보기.</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dz" style="margin-top:16px;">
|
||
<div class="h">🎨 디자이너 대체 트랙 (같은 시간)</div>
|
||
<p><b>디자인 기본기 ①</b> — 색(색상·명도·채도, RGB/HEX), 타이포그래피 기초. + 컴퓨터가 색·이미지를 숫자로 다루는 원리는 개발자와 함께 들어요(협업 기반).</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- WEEK 2 -->
|
||
<section id="w2" class="w2">
|
||
<div class="eyebrow">Week 2</div>
|
||
<div class="card mt">
|
||
<div class="week-head">
|
||
<div class="week-badge"><span class="w">WEEK</span><span class="n">2</span></div>
|
||
<div>
|
||
<h3>자료구조 — 데이터를 어떻게 담는가</h3>
|
||
<div class="goal">상황마다 왜 다른 그릇(구조)을 쓰는지 감을 잡고, 직접 만들어봐요.</div>
|
||
</div>
|
||
</div>
|
||
<div class="days">
|
||
<div class="day">
|
||
<div class="badge">6일차<br>월</div>
|
||
<div>
|
||
<h4>배열 · 리스트 — 순서대로 담기</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">실습</span><span class="txt">JavaScript 배열로 <b>할 일 목록·상품 목록</b> 만들기 — 추가·삭제·인덱스로 꺼내기.</span></div>
|
||
<div class="m link"><span class="lab">연결</span><span class="txt">화면에 목록을 뿌리는 모든 기능(<b>React의 리스트 렌더링</b>)이 결국 이 목록 데이터예요.</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="day">
|
||
<div class="badge">7일차<br>화</div>
|
||
<div>
|
||
<h4>스택 · 큐 — 쌓기(LIFO)와 줄서기(FIFO)</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">실습</span><span class="txt">스택·큐를 <b>직접 구현</b>. 스택=실행취소(Undo), 큐=먼저 온 순서대로 처리.</span></div>
|
||
<div class="m link"><span class="lab">연결</span><span class="txt">알림·이벤트를 <b>들어온 순서대로 처리</b>하는 큐(Kafka) 개념의 씨앗.</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="day">
|
||
<div class="badge">8일차<br>수</div>
|
||
<div>
|
||
<h4>해시 (맵 · 객체) — 열쇠로 한 번에 찾기</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">실습</span><span class="txt">JavaScript 객체(Map)로 <b>아이디 → 사용자 정보</b> 캐시 흉내내기. 목록을 뒤지는 것 vs 바로 찾는 것 속도 비교.</span></div>
|
||
<div class="m link"><span class="lab">연결</span><span class="txt">자주 쓰는 데이터를 빠르게 꺼내는 <b>캐시(Redis)가 왜 빠른가 = 해시</b> 덕분. 이 순간을 크게 강조!</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="day">
|
||
<div class="badge">9일차<br>목</div>
|
||
<div>
|
||
<h4>트리 — 계층으로 담기</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">실습</span><span class="txt">폴더 구조·<b>JSON</b>을 트리로 그려보기. 부모-자식 관계 이해.</span></div>
|
||
<div class="m link"><span class="lab">연결</span><span class="txt">웹 화면의 <b>HTML(DOM) 트리</b>, 서버가 주는 JSON 응답이 다 트리 구조.</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="day">
|
||
<div class="badge">10일차<br>금</div>
|
||
<div>
|
||
<h4 class="friday">시간복잡도 맛보기 & 미니 퀴즈</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">확인</span><span class="txt">"왜 상황마다 다른 구조를 쓰나" = 빠른 것/순서 지키는 것의 차이. Big-O 감각만 가볍게. 퀴즈 10문항.</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dz" style="margin-top:16px;">
|
||
<div class="h">🎨 디자이너 대체 트랙 (같은 시간)</div>
|
||
<p><b>디자인 기본기 ②</b> — 레이아웃·<b>그리드</b>·여백·정렬 원칙. 트리 개념은 함께 들어요(화면이 컴포넌트 트리로 구성된다는 이해 = 개발 협업의 핵심).</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- WEEK 3 -->
|
||
<section id="w3" class="w3">
|
||
<div class="eyebrow blue">Week 3</div>
|
||
<div class="card mt">
|
||
<div class="week-head">
|
||
<div class="week-badge"><span class="w">WEEK</span><span class="n">3</span></div>
|
||
<div>
|
||
<h3>프로그램의 변화 — 지금 우리가 쓰는 것이 어디서 왔나</h3>
|
||
<div class="goal">언어와 소프트웨어가 어떻게 진화해 왔는지 큰 지도를 그리고, 우리 스택의 위치를 찾아요.</div>
|
||
</div>
|
||
</div>
|
||
<div class="days">
|
||
<div class="day">
|
||
<div class="badge">11일차<br>월</div>
|
||
<div>
|
||
<h4>언어의 진화 — 기계어에서 사람 말까지</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">실습</span><span class="txt">같은 동작을 <b>저수준 vs 고수준</b>으로 비교. "왜 점점 사람 말에 가까워졌나" 이야기 나누기.</span></div>
|
||
<div class="m link"><span class="lab">연결</span><span class="txt">우리가 Java·JavaScript 같은 고급 언어를 쓰는 이유.</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="day">
|
||
<div class="badge">12일차<br>화</div>
|
||
<div>
|
||
<h4>프로그래밍 패러다임 — 절차 → 객체 → 함수</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">실습</span><span class="txt">같은 문제를 <b>절차지향 vs 객체지향</b>으로 각각 짜보고 차이 느끼기.</span></div>
|
||
<div class="m link"><span class="lab">연결</span><span class="txt">우리 백엔드(Java)가 <b>객체지향</b>인 이유, 프론트에 함수형 요소가 섞인 이유.</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="day">
|
||
<div class="badge">13일차<br>수</div>
|
||
<div>
|
||
<h4>웹의 등장 — 클라이언트와 서버로 나뉘다</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">실습</span><span class="txt">혼자 도는 프로그램 → 웹으로. <b>프론트엔드 / 백엔드</b>가 나뉜 이유와 역할 분담 정리.</span></div>
|
||
<div class="m link"><span class="lab">연결</span><span class="txt">우리 <b>React 웹(프론트)</b> 과 <b>Spring Boot(백엔드)</b>가 딱 이 구도. 4일차 Network 탭과 이어짐.</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="day">
|
||
<div class="badge">14일차<br>목</div>
|
||
<div>
|
||
<h4>아키텍처의 진화 — 모놀리식 → MSA → 클라우드 → AI</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">실습</span><span class="txt">하나로 뭉친 프로그램 vs 잘게 나눈 <b>마이크로서비스</b>의 장단점 토론.</span></div>
|
||
<div class="m link"><span class="lab">연결</span><span class="txt">우리가 <b>웹(React) · 앱(React Native·Flutter) · 서버(Spring Boot)</b>를 나눠 만들고 <b>클라우드</b>에 올리는 방식이 바로 이 진화의 결과.</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="day">
|
||
<div class="badge">15일차<br>금</div>
|
||
<div>
|
||
<h4 class="friday">우리 서비스 구성도 그려보기 & 미니 퀴즈</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">확인</span><span class="txt">배운 흐름으로 우리 시스템 구성도를 <b>직접 그려보기</b>. 퀴즈 10문항.</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dz" style="margin-top:16px;">
|
||
<div class="h">🎨 디자이너 대체 트랙 (같은 시간)</div>
|
||
<p><b>디자인 시스템 & 핸드오프</b> — 컴포넌트·재사용 개념, 개발자에게 넘기는 스펙(간격·상태·인터랙션) 작성법. 웹의 프론트/백 구분은 함께 들어요.</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- WEEK 4 -->
|
||
<section id="w4" class="w4">
|
||
<div class="eyebrow green">Week 4</div>
|
||
<div class="card mt">
|
||
<div class="week-head">
|
||
<div class="week-badge"><span class="w">WEEK</span><span class="n">4</span></div>
|
||
<div>
|
||
<h3>통합 · 복습 · 발표 — 배운 걸 내 말로</h3>
|
||
<div class="goal">3주간 배운 조각들을 하나로 잇고, "내가 이해한 것"을 발표로 증명해요.</div>
|
||
</div>
|
||
</div>
|
||
<div class="days">
|
||
<div class="day">
|
||
<div class="badge">16–17일차<br>월·화</div>
|
||
<div>
|
||
<h4>한 요청의 여행 — 클릭에서 응답까지 따라가기</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">실습</span><span class="txt">화면에서 버튼 하나 눌렀을 때: <b>React 웹/앱 → REST API → Spring Boot 서버 → DB → 응답</b>까지 전 과정을 추적하고 그림으로 정리.</span></div>
|
||
<div class="m link"><span class="lab">연결</span><span class="txt">1~3주 개념(네트워크·자료구조·아키텍처)이 여기서 전부 만나요.</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="day">
|
||
<div class="badge">18일차<br>수</div>
|
||
<div>
|
||
<h4>발표 주제 정하고 깊게 파기</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">실습</span><span class="txt">각자 가장 흥미로웠던 주제 하나 선택(예: "캐시는 왜 빠른가", "React와 서버는 어떻게 대화하나", "웹과 앱은 뭐가 다른가") — 자료 조사.</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="day">
|
||
<div class="badge">19일차<br>목</div>
|
||
<div>
|
||
<h4>발표 자료 만들기</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">실습</span><span class="txt">10분 분량 슬라이드 작성. <b>어려운 말 없이, 내 말로</b> 설명하는 걸 목표로. (멘토가 1:1 코칭)</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="day">
|
||
<div class="badge">20일차<br>금</div>
|
||
<div>
|
||
<h4 class="friday">미니 발표회 🎤 — Layer B의 졸업식</h4>
|
||
<div class="meta">
|
||
<div class="m prac"><span class="lab">발표</span><span class="txt">한 사람당 10분 "내가 이해한 컴퓨터 / 우리 시스템". 팀 앞에서 발표하고 질문받기.</span></div>
|
||
<div class="m link"><span class="lab">평가</span><span class="txt">이 발표가 <b>기본기 이해도의 핵심 평가 포인트</b>. (아래 평가 방법 참고)</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dz" style="margin-top:16px;">
|
||
<div class="h">🎨 디자이너 대체 트랙 (같은 시간)</div>
|
||
<p>디자이너도 함께 요청 흐름을 따라가고(협업 이해), 발표는 <b>"내가 다시 디자인한다면"</b> 주제로 — 우리가 다루는 서비스 화면 하나를 골라 개선안을 발표해요.</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Assessment -->
|
||
<section id="assess">
|
||
<div class="eyebrow green">이해도 확인</div>
|
||
<h2>어떻게 평가하나</h2>
|
||
<p class="sub">시험 점수가 목적이 아니에요. <strong>"이해했는지, 그리고 내 말로 설명할 수 있는지"</strong>를 봅니다.</p>
|
||
<div class="card mt assess">
|
||
<div class="a"><div class="wk">매일</div><div class="txt"><b>3줄 회고</b> — 오늘 배운 것 / 이해 안 된 것 / 궁금한 것. 이해가 막힌 지점을 멘토가 바로 캐치.</div></div>
|
||
<div class="a"><div class="wk">매주 금</div><div class="txt"><b>미니 퀴즈 10문항</b> — 맞고 틀림보다, 틀린 개념을 다음 주에 보완하는 용도.</div></div>
|
||
<div class="a"><div class="wk">4주차</div><div class="txt"><b>미니 발표 (가장 중요)</b> — 어려운 용어 없이 자기 말로 설명하면 진짜 이해한 것. 암기가 아니라 이해를 봐요.</div></div>
|
||
<div class="a"><div class="wk">상시</div><div class="txt"><b>"그래서 우리 회사에선?" 대답</b> — 배운 개념을 우리 실제 개발(React·Spring Boot·앱·클라우드)에 연결해 말할 수 있는지가 최종 목표.</div></div>
|
||
</div>
|
||
<div class="callout">
|
||
<h3>⚠️ 눈높이 주의</h3>
|
||
<p>고교생에게 Big-O 증명이나 CPU 파이프라인 같은 <b>깊은 이론은 목표가 아니에요.</b> "왜 이렇게 만들어졌고, 우리 시스템의 어디에 있는가"라는 <b>큰 그림과 직관</b>을 잡는 게 이 4주의 목적입니다. 못 따라오면 속도를 늦춰도 괜찮아요.</p>
|
||
</div>
|
||
</section>
|
||
|
||
<footer>
|
||
<span>AWESOMEDEV · 수습 교육 · Layer B 커리큘럼</span>
|
||
<span>2026 · 수습 가이드와 함께 사용</span>
|
||
</footer>
|
||
|
||
</div>
|
||
</body>
|
||
</html>
|