이모지 아이콘을 SVG로 바꾸다가, 더 큰 원인을 발견해 함께 고쳤다.
■ 폰트: 이름만 부르고 파일은 안 받아오고 있었다
global.css에 font-family: "Pretendard"가 적혀 있었지만 @font-face도 CDN
링크도 없었다. 그래서 이 글꼴이 따로 깔린 사람 외에는 전원 맑은 고딕으로
보고 있었다 — 앱과 학습 문서 19개 전부. 에러가 안 나서 조용히 넘어간 케이스.
- PretendardStdVariable.woff2(285KB)를 public/fonts에 self-host
· CDN 의존 없음 → 외부 서비스가 죽어도, 오프라인에서도 안 깨진다
· variable font → 파일 하나가 굵기 45~920을 전부 담는다
· font-display: swap → 받는 동안 흰 화면(FOIT) 방지
- 전체판(2MB) 대신 Std판(상용 한글 2,350자)을 골랐다. 앱이 쓰는 한글
1,276자가 Std에 전부 있는지 브라우저에서 실측 확인했다(폴백 0자).
- 학습 문서 19개에도 같은 @font-face 적용
■ 아이콘: 이모지 95종 → Lucide 132개
이모지는 OS마다 다른 그림으로 렌더링되고, 굵기·색을 통제할 수 없고,
스크린리더가 "bust in silhouette"처럼 읽는다.
- 카탈로그의 icon: '📜'(문자) → Icon: ScrollText(컴포넌트)로 전환
- strokeWidth={1.5}로 굵기 통일, aria-hidden으로 장식임을 명시
- 개별 import만 사용(트리셰이킹) → gzip +14KB
- slug: null인 '개발 환경 설치 가이드' 항목이 일괄 변환에서 누락돼
Icon이 undefined가 될 뻔한 것을 정합성 검사(항목 수 vs Icon 수)로 잡았다
■ 토큰: 여백·글자 크기·굵기를 :root로 승격
--space-1~7(4의 배수), --text-xs~2xl, --weight-*, --radius-sm/lg/full.
값을 직접 박으면 다크 모드에서 깨지고 화면마다 미묘하게 어긋난다.
CSS 프레임워크는 도입하지 않았다 — 손으로 쓴 global.css와 충돌하고,
교재로서 "왜 이렇게 썼는지"가 사라지기 때문이다.
■ /design: 재료를 고르는 화면
색·글자·여백·모서리를 실제 CSS 변수로 렌더링(다크 모드 자동 반영) +
Lucide 아이콘 1,993개 검색·복사. lucide-react는 아이콘 하나를 이름 3개로
내보내(Rocket/RocketIcon/LucideRocket) 5,981개처럼 보이므로 별칭을 걸렀다.
아이콘 전체를 훑어야 해 무거운 화면이라 lazy로 분리했다
→ 첫 화면 번들은 1.9KB만 증가(575.57 → 577.44KB).
검증: ESLint 통과, Vitest 30개 통과, 프로덕션 빌드 성공, 콘솔 에러 0.
브라우저에서 수습 7카테고리 + 초급~특급 4과정 = 11개 화면 전수 확인
(각 12카드/12아이콘/이모지 0).
문서: DESIGN.md(폰트·토큰·비용), ICONS.md(규약·대응표 132행)
483 lines
29 KiB
HTML
483 lines
29 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>
|
||
/* 웹폰트: 앱과 같은 Pretendard를 문서에도 적용한다(선언만 있고 파일이 없던 문제 수정). */
|
||
@font-face {
|
||
font-family: "Pretendard";
|
||
src: url("/fonts/PretendardStdVariable.woff2") format("woff2-variations");
|
||
font-weight: 45 920;
|
||
font-display: swap;
|
||
}
|
||
|
||
: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>
|