<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>charlese_note.log</title>
        <link>https://velog.io/</link>
        <description>李家네_공부방</description>
        <lastBuildDate>Wed, 17 Jun 2026 00:19:44 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>charlese_note.log</title>
            <url>https://velog.velcdn.com/images/charlese_note/profile/824897f9-596f-4b45-9b21-394268ebf5fe/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. charlese_note.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/charlese_note" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[공식문서]]></title>
            <link>https://velog.io/@charlese_note/%EA%B3%B5%EC%8B%9D%EB%AC%B8%EC%84%9C</link>
            <guid>https://velog.io/@charlese_note/%EA%B3%B5%EC%8B%9D%EB%AC%B8%EC%84%9C</guid>
            <pubDate>Wed, 17 Jun 2026 00:19:44 GMT</pubDate>
            <description><![CDATA[<p>According to a document from 2026-06-16, 네 기존 2년 커리큘럼의 핵심은 기초 1<del>6개월: 리눅스·Git·Python·C·자료구조·컴퓨터구조·운영체제·이산수학, 기본 7</del>12개월: 디지털논리·임베디드·STM32·M5Stack·ESP-IDF·LVGL·CMake·OpenCV, 심화 13<del>18개월: 수학·ML/DL·NLP/RAG·Upstage 문서 AI·LangGraph·네트워크·Docker·보안, 실전 19</del>24개월: EdgeCanvas MVP 구현으로 정리되어 있다.  또한 EdgeCanvas의 핵심은 문서 이해 → 하드웨어 제약 추출 → LVGL 코드 생성 → 빌드 → 플래시 → 카메라 검증 → 실패 시 자가수정이고, 기술스택에는 Python, C/C++, CMake, Bash, LangGraph, LangChain, Pydantic, LVGL, arm-none-eabi-gcc, ESP-IDF, ST-Link, OpenOCD, OpenCV, Pillow, v4l2, pytest, Docker 등이 포함된다. </p>
<p>그래서 공식문서 커리큘럼은 교재 커리큘럼과 똑같이 짜면 안 된다. 공식문서는 “처음부터 끝까지 읽는 책”이 아니라, 개념을 구현 기준으로 검증하는 기준서로 써야 한다.</p>
<p>아래는 2년 동안 공식문서만 기준으로 따라갈 수 있게 만든 커리큘럼이다.</p>
<hr>
<ol start="0">
<li>공식문서 커리큘럼의 큰 원칙</li>
</ol>
<p>공식문서는 세 종류로 나눠서 봐야 한다.</p>
<p>종류    예시    읽는 목적</p>
<p>언어·도구 공식문서    Python, Git, Bash, GCC, CMake, Docker, pytest    실제 개발환경과 자동화의 기준
하드웨어·임베디드 공식문서    STM32H747I-DISCO, STM32CubeH7, ESP-IDF, M5Stack CoreS3, LVGL    실물 보드에서 동작하는 코드의 기준
AI·비전·에이전트 공식문서    OpenCV, Upstage, LangGraph, Pydantic, PyTorch, scikit-learn, DeepStream, YOLO, ONNX Runtime    EdgeCanvas/AegisEdge의 지능형 파이프라인 기준</p>
<p>그리고 수학, 자료구조, 운영체제 이론처럼 “벤더 공식문서”가 없는 영역은 MIT OpenCourseWare 같은 대학 공식 공개자료를 공식문서에 준하는 자료로 둔다. MIT 6.006은 알고리즘과 자료구조, MIT 18.06은 선형대수, MIT 18.05는 확률통계, MIT 6.1810은 운영체제 설계와 시스템 프로그래밍을 다룬다. </p>
<hr>
<ol>
<li>1~6개월: 기초 단계 공식문서 커리큘럼</li>
</ol>
<p>목표</p>
<p>이 단계에서는 EdgeCanvas를 바로 만들지 않는다. 목표는 공식문서를 읽고 개발환경, 언어, 빌드, 시스템 기초를 직접 확인하는 능력이다.</p>
<p>기존 커리큘럼에서도 기초 단계의 목표는 리눅스 터미널, Git, Python CLI, C 메모리, 자료구조, 컴퓨터구조·운영체제 기본, 상태머신 구현으로 잡혀 있다. </p>
<hr>
<p>1개월차: 리눅스 / 터미널 / Git</p>
<p>봐야 할 공식문서</p>
<ol>
<li>Linux man-pages</li>
</ol>
<ol start="2">
<li>GNU Bash Reference Manual</li>
</ol>
<ol start="3">
<li>Git 공식 문서 / Pro Git</li>
</ol>
<ol start="4">
<li>Ubuntu 공식 문서</li>
</ol>
<ol start="5">
<li>Linux Filesystem Hierarchy 관련 문서</li>
</ol>
<ol start="6">
<li>SSH 공식 문서 또는 OpenSSH manual</li>
</ol>
<p>Linux man-pages는 Linux 커널과 C 라이브러리 인터페이스를 사용자 공간 프로그램 관점에서 문서화한다. 따라서 /dev/video0, /dev/ttyUSB0, chmod, open, read, write, fork, exec 같은 시스템 감각을 익히는 데 가장 직접적이다.  Git은 Pro Git 공식 온라인 문서에서 Getting Started, Git Basics, Git Branching 등을 체계적으로 제공한다. </p>
<p>읽는 순서</p>
<ol>
<li>Git: Getting Started</li>
</ol>
<ol start="2">
<li>Git: Git Basics</li>
</ol>
<ol start="3">
<li>Git: Branching</li>
</ol>
<ol start="4">
<li>Linux man-pages: ls, chmod, chown, ln, find, grep, tar</li>
</ol>
<ol start="5">
<li>Linux man-pages: open, read, write, stat, execve, fork</li>
</ol>
<ol start="6">
<li>Bash: 변수, quoting, redirection, pipe, exit code</li>
</ol>
<ol start="7">
<li>Ubuntu: package management, users/groups, systemd 기초</li>
</ol>
<p>EdgeCanvas 연결</p>
<p>EdgeCanvas는 단순 Python 앱이 아니라 Docker, 빌드, 플래시, 카메라 장치, 시리얼 포트, 환경변수, GitHub 배포를 다룬다. 기존 정리에서도 리눅스는 빌드, Docker, 플래시, 서버, 엣지 환경 때문에 EdgeCanvas와 AegisEdge 모두 필수로 분류되어 있다. </p>
<p>실습 산출물</p>
<p>official-docs-lab/
  linux/
    file_permission.md
    device_files.md
    bash_exit_code.md
  git/
    branch_merge_rebase.md
  scripts/
    setup_env.sh
    check_devices.sh</p>
<p>통과 기준</p>
<p>chmod, chown, ln -s, grep, find를 설명하고 쓸 수 있다.</p>
<p>PATH, .env, shell variable, environment variable 차이를 설명할 수 있다.</p>
<p>Git branch, merge, rebase, tag를 설명할 수 있다.</p>
<p>/dev/video0, /dev/ttyUSB0 같은 장치 파일이 왜 중요한지 설명할 수 있다.</p>
<hr>
<p>2개월차: Python 공식문서 기반 자동화</p>
<p>봐야 할 공식문서</p>
<ol>
<li>Python Tutorial</li>
</ol>
<ol start="2">
<li>Python Standard Library</li>
</ol>
<ol start="3">
<li>venv</li>
</ol>
<ol start="4">
<li>argparse</li>
</ol>
<ol start="5">
<li>subprocess</li>
</ol>
<ol start="6">
<li>logging</li>
</ol>
<ol start="7">
<li>json</li>
</ol>
<ol start="8">
<li>pathlib</li>
</ol>
<ol start="9">
<li>typing</li>
</ol>
<ol start="10">
<li>pytest Get Started</li>
</ol>
<p>Python 공식 튜토리얼은 Python 언어와 시스템의 기본 개념을 소개하는 공식 입문 문서이고, 공식 Python 문서는 버전별 문서·튜토리얼·가이드를 제공한다.  pytest 공식문서는 빠르게 테스트를 작성하고 실패 이유를 assertion 출력으로 확인하는 흐름을 제공한다. </p>
<p>읽는 순서</p>
<ol>
<li>Python Tutorial: control flow, functions, modules</li>
</ol>
<ol start="2">
<li>Python Tutorial: classes, errors and exceptions</li>
</ol>
<ol start="3">
<li>Standard Library: json</li>
</ol>
<ol start="4">
<li>Standard Library: pathlib</li>
</ol>
<ol start="5">
<li>Standard Library: subprocess</li>
</ol>
<ol start="6">
<li>Standard Library: logging</li>
</ol>
<ol start="7">
<li>venv/pip 사용법</li>
</ol>
<ol start="8">
<li>pytest Get Started</li>
</ol>
<ol start="9">
<li>pytest fixtures는 맛보기만</li>
</ol>
<p>EdgeCanvas 연결</p>
<p>EdgeCanvas의 API 호출, JSON 스키마 처리, 빌드 명령 실행, 로그 수집, Vision-in-the-Loop 실행, LangGraph 노드 구현은 Python 중심이다. 기존 커리큘럼에서도 2개월차는 Python CLI, JSON, subprocess, logging, pytest를 목표로 잡았다. </p>
<p>실습 산출물</p>
<p>edgecanvas-cli/
  edgecanvas_cli/
    main.py
    config.py
    run_command.py
    logger.py
  tests/
    test_run_command.py
  examples/
    ui_request.json</p>
<p>통과 기준</p>
<p>JSON 파일을 읽고 검증한다.</p>
<p>subprocess.run()으로 gcc --version, cmake --version, python --version을 실행한다.</p>
<p>실행 결과를 JSON 로그로 저장한다.</p>
<p>pytest로 성공/실패 테스트를 10개 이상 만든다.</p>
<hr>
<p>3개월차: C / GCC / Make 공식문서</p>
<p>봐야 할 공식문서</p>
<ol>
<li>GCC Online Documentation</li>
</ol>
<ol start="2">
<li>GCC Warning Options</li>
</ol>
<ol start="3">
<li>GNU Make Manual</li>
</ol>
<ol start="4">
<li>C library man-pages</li>
</ol>
<ol start="5">
<li>cppreference는 공식은 아니지만 C/C++ 레퍼런스 보조로만 사용</li>
</ol>
<p>GCC 공식문서는 GCC가 C, C++, Objective-C, Fortran 등 여러 언어를 위한 컴파일러 컬렉션이라는 점과 옵션·경고·진단 체계를 제공한다.  GCC Warning Options 문서는 각 경고가 어떤 옵션으로 제어되는지 설명한다. </p>
<p>읽는 순서</p>
<ol>
<li>GCC: Overall Options</li>
</ol>
<ol start="2">
<li>GCC: Warning Options</li>
</ol>
<ol start="3">
<li>GCC: C Dialect Options</li>
</ol>
<ol start="4">
<li>GCC: Preprocessor Options</li>
</ol>
<ol start="5">
<li>GCC: Link Options</li>
</ol>
<ol start="6">
<li>Make manual: target, prerequisite, recipe</li>
</ol>
<ol start="7">
<li>Linux man-pages: malloc, free, memcpy, memset, fopen, fread, fwrite</li>
</ol>
<p>EdgeCanvas 연결</p>
<p>EdgeCanvas가 생성할 최종 코드는 Python이 아니라 MCU에서 동작하는 LVGL C 코드와 펌웨어다. 기존 정리에서도 C는 LVGL/MCU 펌웨어의 기반으로 EdgeCanvas 필수도 5로 분류되어 있다. </p>
<p>실습 산출물</p>
<p>c-official-lab/
  pointer.c
  struct_widget.c
  bit_flags.c
  Makefile
  docs/
    gcc_warnings.md
    compile_vs_link.md</p>
<p>통과 기준</p>
<p>-Wall, -Wextra, -Werror를 설명할 수 있다.</p>
<p>컴파일 오류와 링크 오류를 구분한다.</p>
<p>구조체로 LVGL 위젯 비슷한 데이터를 표현한다.</p>
<p>비트 연산으로 레지스터 플래그를 흉내 낸다.</p>
<hr>
<p>4개월차: 자료구조 / 알고리즘 공식 공개자료</p>
<p>봐야 할 공식 공개자료</p>
<ol>
<li>MIT OCW 6.006 Introduction to Algorithms</li>
</ol>
<ol start="2">
<li>MIT OCW 6.046J Introduction to Algorithms, 심화 선택</li>
</ol>
<ol start="3">
<li>Python 공식문서의 data structures 섹션</li>
</ol>
<ol start="4">
<li>C++ STL reference는 필요 시 보조</li>
</ol>
<p>MIT 6.006은 계산 문제의 수학적 모델링, 자료구조, 알고리즘 패러다임, 성능 측정과 분석 기법을 다루는 공식 공개강의다. </p>
<p>읽는 순서</p>
<ol>
<li>MIT 6.006: Algorithms and Computation</li>
</ol>
<ol start="2">
<li>Data Structures and Dynamic Arrays</li>
</ol>
<ol start="3">
<li>Sets and Sorting</li>
</ol>
<ol start="4">
<li>Hashing</li>
</ol>
<ol start="5">
<li>Trees</li>
</ol>
<ol start="6">
<li>Graph Search</li>
</ol>
<ol start="7">
<li>Shortest Paths는 맛보기</li>
</ol>
<ol start="8">
<li>Python 공식문서: list, dict, set, heapq, collections</li>
</ol>
<p>EdgeCanvas 연결</p>
<p>EdgeCanvas의 UI는 위젯 트리이고, LangGraph는 상태 그래프이며, 빌드·검증 루프는 상태 전이와 큐로 표현된다. 기존 정리에서도 자료구조는 상태머신, 트리, 그래프, 파서 때문에 EdgeCanvas와 AegisEdge 모두 필수로 분류되어 있다. </p>
<p>실습 산출물</p>
<p>ds-algo-lab/
  widget_tree.py
  graph_workflow.py
  bfs_dfs.py
  build_retry_queue.py</p>
<p>통과 기준</p>
<p>UI 위젯 트리를 JSON으로 표현한다.</p>
<p>parse → generate → build → verify → fix 상태 그래프를 만든다.</p>
<p>BFS/DFS를 설명하고 구현한다.</p>
<p>retry queue를 만든다.</p>
<hr>
<p>5개월차: 컴퓨터구조 / ARM Cortex-M / CMSIS / STM32 Reference Manual</p>
<p>봐야 할 공식문서</p>
<ol>
<li>Arm Technical Documentation</li>
</ol>
<ol start="2">
<li>CMSIS 공식문서</li>
</ol>
<ol start="3">
<li>CMSIS-Core</li>
</ol>
<ol start="4">
<li>STM32H747/757 Documentation</li>
</ol>
<ol start="5">
<li>RM0399 STM32H745/755 and STM32H747/757 Reference Manual</li>
</ol>
<ol start="6">
<li>STM32H747I-DISCO User Manual</li>
</ol>
<p>Arm 공식 문서 포털은 Arm IP와 소프트웨어에 대한 기술 문서를 제공한다.  CMSIS는 Arm Cortex-M 기반 프로세서에 대한 벤더 독립적 하드웨어 추상화 계층으로 시작했고, CMSIS-Core는 Cortex-M 디바이스의 기본 런타임과 프로세서 코어·주변장치 접근을 제공한다.  ST의 STM32H747/757 문서 페이지는 datasheet, errata, RM0399 reference manual 등을 제공한다. </p>
<p>읽는 순서</p>
<ol>
<li>Arm Cortex-M 개요</li>
</ol>
<ol start="2">
<li>CMSIS-Core overview</li>
</ol>
<ol start="3">
<li>vector table</li>
</ol>
<ol start="4">
<li>interrupt / exception</li>
</ol>
<ol start="5">
<li>memory map</li>
</ol>
<ol start="6">
<li>STM32H747 datasheet: memory, pinout, package</li>
</ol>
<ol start="7">
<li>RM0399: RCC, GPIO, DMA, LTDC, I2C, SPI</li>
</ol>
<ol start="8">
<li>STM32H747I-DISCO User Manual: 보드 구성, LCD, SDRAM, connector</li>
</ol>
<p>EdgeCanvas 연결</p>
<p>EdgeCanvas는 데이터시트와 레퍼런스 매뉴얼에서 RAM, Flash, 핀맵, 클럭, 디스플레이 인터페이스를 추출해야 한다. 기존 정리에서도 컴퓨터구조는 MCU, 메모리, 레지스터, 인터럽트 때문에 EdgeCanvas 필수도 5로 분류되어 있다. </p>
<p>실습 산출물</p>
<p>architecture-docs/
  arm_cortex_m_summary.md
  cmsis_core_summary.md
  stm32h747_memory_map.md
  stm32h747_peripheral_map.json</p>
<p>통과 기준</p>
<p>Flash, SRAM, peripheral register, memory-mapped I/O를 구분한다.</p>
<p>NVIC, SysTick, vector table을 설명한다.</p>
<p>STM32H747의 메모리 맵 일부를 JSON으로 옮긴다.</p>
<p>RM0399에서 GPIO, RCC, LTDC 관련 절을 찾을 수 있다.</p>
<hr>
<p>6개월차: 운영체제 / 시스템 프로그래밍 / 이산수학</p>
<p>봐야 할 공식 공개자료</p>
<ol>
<li>Linux man-pages</li>
</ol>
<ol start="2">
<li>MIT OCW 6.1810 Operating System Engineering</li>
</ol>
<ol start="3">
<li>MIT OCW 6.033 Computer System Engineering</li>
</ol>
<ol start="4">
<li>MIT OCW 6.042J Mathematics for Computer Science, 선택</li>
</ol>
<ol start="5">
<li>MIT OCW 6.006 그래프 파트 복습</li>
</ol>
<p>MIT 6.1810은 운영체제 설계와 구현, 가상메모리, 파일시스템, 스레드, 컨텍스트 스위치, 커널, 인터럽트, 시스템 콜, IPC를 다룬다.  MIT 6.033은 소프트웨어·하드웨어 시스템 공학, 복잡성 제어, OS, 네트워크, 보안, fault tolerance, atomicity 등을 다룬다. </p>
<p>읽는 순서</p>
<ol>
<li>Linux man-pages: fork, exec, pipe, select, poll</li>
</ol>
<ol start="2">
<li>Linux man-pages: file descriptor, process, signal</li>
</ol>
<ol start="3">
<li>MIT 6.1810: OS 개요</li>
</ol>
<ol start="4">
<li>MIT 6.1810: system call, process, virtual memory</li>
</ol>
<ol start="5">
<li>MIT 6.033: modularity, client/server, naming, reliability</li>
</ol>
<ol start="6">
<li>상태기계와 그래프 복습</li>
</ol>
<p>EdgeCanvas 연결</p>
<p>EdgeCanvas는 Python에서 외부 빌드 명령을 실행하고, 카메라 장치와 시리얼 포트를 열고, Docker에서 재현 가능한 환경을 만들어야 한다. 운영체제 개념이 없으면 “왜 권한 오류가 나는지”, “왜 장치 파일이 안 보이는지”, “왜 subprocess가 실패했는지”를 이해하기 어렵다.</p>
<p>실습 산출물</p>
<p>os-system-lab/
  process_subprocess.md
  device_file_camera.md
  file_descriptor_demo.py
  state_machine_theory.md</p>
<p>통과 기준</p>
<p>process, thread, file descriptor, system call을 설명한다.</p>
<p>/dev/video0 권한 문제를 해결하는 절차를 문서화한다.</p>
<p>상태와 전이를 이용해 EdgeCanvas workflow를 설명한다.</p>
<hr>
<ol start="2">
<li>7~12개월: 기본 단계 공식문서 커리큘럼</li>
</ol>
<p>목표</p>
<p>이 단계는 실물 보드에 HMI를 띄우고, 카메라로 검증하는 능력을 만든다. 기존 2년 커리큘럼에서도 기본 단계 목표는 디지털논리, 임베디드, STM32, M5Stack, ESP-IDF, LVGL, CMake, OpenCV를 통해 실물 보드에 HMI를 띄우고 카메라로 검증하는 능력으로 정리되어 있다. </p>
<hr>
<p>7개월차: 디지털논리 / GPIO / 통신버스 / 보드 회로도</p>
<p>봐야 할 공식문서</p>
<ol>
<li>STM32H747I-DISCO User Manual</li>
</ol>
<ol start="2">
<li>STM32H747I-DISCO schematic</li>
</ol>
<ol start="3">
<li>STM32H747/757 datasheet</li>
</ol>
<ol start="4">
<li>RM0399 reference manual</li>
</ol>
<ol start="5">
<li>M5Stack CoreS3 schematic / docs</li>
</ol>
<ol start="6">
<li>ESP32-S3 datasheet / technical reference manual</li>
</ol>
<p>STM32H747I-DISCO User Manual은 이 보드를 Arm Cortex-M7/M4 dual-core 기반 STM32H747XIH6 개발 플랫폼으로 설명한다.  M5Stack CoreS3 공식 문서는 CoreS3 장치와 플래시/개발 절차를 설명한다. </p>
<p>읽는 순서</p>
<ol>
<li>STM32H747I-DISCO block diagram</li>
</ol>
<ol start="2">
<li>power tree</li>
</ol>
<ol start="3">
<li>LCD connector</li>
</ol>
<ol start="4">
<li>SDRAM 연결</li>
</ol>
<ol start="5">
<li>touch interface</li>
</ol>
<ol start="6">
<li>USB/ST-LINK 연결</li>
</ol>
<ol start="7">
<li>M5Stack CoreS3 hardware overview</li>
</ol>
<ol start="8">
<li>ESP32-S3 pin / flash / PSRAM 구조</li>
</ol>
<ol start="9">
<li>I2C, SPI, UART, GPIO 관련 절</li>
</ol>
<p>EdgeCanvas 연결</p>
<p>EdgeCanvas가 보드 프로필을 자동화하려면 단순히 “STM32 보드”라고 알면 안 된다. LCD가 어떤 인터페이스인지, framebuffer가 어디에 있어야 하는지, touch가 I2C인지 SPI인지, 플래시는 어떤 도구로 하는지 알아야 한다.</p>
<p>실습 산출물</p>
<p>board-profiles/
  stm32h747i_disco.hardware.md
  m5stack_cores3.hardware.md
  interfaces/
    gpio.md
    i2c.md
    spi.md
    uart.md</p>
<p>통과 기준</p>
<p>STM32H747I-DISCO의 LCD, touch, SDRAM 연결을 설명한다.</p>
<p>M5Stack CoreS3의 LCD, touch, camera, flash, PSRAM 정보를 정리한다.</p>
<p>보드 프로필 JSON 초안을 만든다.</p>
<hr>
<p>8개월차: STM32CubeH7 / HAL / LL / BSP / STM32CubeProgrammer</p>
<p>봐야 할 공식문서</p>
<ol>
<li>STM32CubeH7 Product Page</li>
</ol>
<ol start="2">
<li>STM32CubeH7 GitHub</li>
</ol>
<ol start="3">
<li>UM2217 STM32H7 HAL and LL drivers</li>
</ol>
<ol start="4">
<li>STM32H747I-DISCO BSP repository</li>
</ol>
<ol start="5">
<li>STM32CubeProgrammer</li>
</ol>
<ol start="6">
<li>STM32CubeProgrammer User Manual</li>
</ol>
<p>STM32CubeH7는 STM32H7 MCU 애플리케이션 개발에 필요한 임베디드 소프트웨어 구성요소를 하나의 패키지로 제공하고, STM32CubeH7 GitHub에는 CMSIS, HAL/LL 드라이버, BSP, 미들웨어와 예제가 포함된다.  STM32CubeProgrammer는 GUI와 CLI 버전으로 제공되며, 프로그래밍 자동화와 스크립팅을 지원한다. </p>
<p>읽는 순서</p>
<ol>
<li>STM32CubeH7 package overview</li>
</ol>
<ol start="2">
<li>HAL vs LL 구조</li>
</ol>
<ol start="3">
<li>BSP drivers</li>
</ol>
<ol start="4">
<li>STM32H747I-DISCO examples</li>
</ol>
<ol start="5">
<li>GPIO example</li>
</ol>
<ol start="6">
<li>UART example</li>
</ol>
<ol start="7">
<li>LCD/BSP example</li>
</ol>
<ol start="8">
<li>STM32CubeProgrammer CLI</li>
</ol>
<ol start="9">
<li>Flash, erase, verify, reset</li>
</ol>
<p>EdgeCanvas 연결</p>
<p>EdgeCanvas가 생성한 C 코드는 단독으로 보드에서 돌지 않는다. BSP, clock, SDRAM, LCD init, linker script, startup code가 맞아야 한다. 기존 정리에서도 단순 C 코드가 아니라 보드 초기화, 클럭, SDRAM, LCD controller, touch, linker script, flash layout까지 맞아야 한다고 정리했다. </p>
<p>실습 산출물</p>
<p>stm32-official-lab/
  cubeh7_examples.md
  hal_ll_bsp_summary.md
  stm32_flash_cli.md
  generated_board_profile_stm32h747i_disco.json</p>
<p>통과 기준</p>
<p>HAL, LL, BSP 차이를 설명한다.</p>
<p>STM32CubeProgrammer CLI 명령 구조를 설명한다.</p>
<p>STM32H747I-DISCO LCD 예제가 어디 있는지 찾는다.</p>
<p>플래시 자동화 dry-run 절차를 문서화한다.</p>
<hr>
<p>9개월차: ESP-IDF / M5Stack CoreS3 / esp_lvgl_port</p>
<p>봐야 할 공식문서</p>
<ol>
<li>ESP-IDF Get Started</li>
</ol>
<ol start="2">
<li>ESP-IDF Build System</li>
</ol>
<ol start="3">
<li>ESP-IDF Build / Flash / Monitor</li>
</ol>
<ol start="4">
<li>M5Stack CoreS3 official docs</li>
</ol>
<ol start="5">
<li>M5Stack ESP-IDF Development Tutorial</li>
</ol>
<ol start="6">
<li>esp_lvgl_port</li>
</ol>
<ol start="7">
<li>ESP Component Registry</li>
</ol>
<p>ESP-IDF Get Started 문서는 ESP-IDF 앱을 개발, 빌드, 플래시, 모니터링하는 흐름을 안내한다.  ESP-IDF는 idf.py -p PORT flash monitor처럼 빌드·플래시·모니터링을 하나의 흐름으로 수행할 수 있다.  Espressif의 esp_lvgl_port는 LVGL을 Espressif LCD와 touch driver와 함께 쓰도록 돕는 컴포넌트다. </p>
<p>읽는 순서</p>
<ol>
<li>ESP-IDF installation</li>
</ol>
<ol start="2">
<li>Start project</li>
</ol>
<ol start="3">
<li>idf.py build</li>
</ol>
<ol start="4">
<li>idf.py flash monitor</li>
</ol>
<ol start="5">
<li>menuconfig</li>
</ol>
<ol start="6">
<li>build system overview</li>
</ol>
<ol start="7">
<li>M5Stack CoreS3 docs</li>
</ol>
<ol start="8">
<li>M5Stack ESP-IDF tutorial</li>
</ol>
<ol start="9">
<li>esp_lvgl_port README</li>
</ol>
<ol start="10">
<li>ESP Component Registry 의존성 관리</li>
</ol>
<p>EdgeCanvas 연결</p>
<p>STM32와 ESP32-S3는 완전히 다른 빌드·플래시·초기화 흐름을 가진다. EdgeCanvas는 이를 board_profile로 추상화해야 한다. 기존 정리에서도 STM32와 ESP32-S3를 동시에 지원하려면 보드별 빌드·플래시·LVGL 초기화 템플릿을 따로 가져가야 한다고 정리되어 있다. </p>
<p>실습 산출물</p>
<p>esp32-official-lab/
  espidf_build_flash.md
  m5stack_cores3_profile.json
  esp_lvgl_port_summary.md
  scripts/
    flash_m5stack.sh</p>
<p>통과 기준</p>
<p>idf.py build, idf.py flash, idf.py monitor를 설명한다.</p>
<p>ESP-IDF component dependency 구조를 설명한다.</p>
<p>M5Stack CoreS3용 보드 프로필 JSON을 만든다.</p>
<p>ESP-IDF와 STM32CubeH7 빌드 흐름 차이를 표로 정리한다.</p>
<hr>
<p>10개월차: LVGL 공식문서 집중</p>
<p>봐야 할 공식문서</p>
<ol>
<li>LVGL Documentation</li>
</ol>
<ol start="2">
<li>Learn the Basics</li>
</ol>
<ol start="3">
<li>Displays</li>
</ol>
<ol start="4">
<li>Input devices</li>
</ol>
<ol start="5">
<li>Widgets</li>
</ol>
<ol start="6">
<li>Styles</li>
</ol>
<ol start="7">
<li>Events</li>
</ol>
<ol start="8">
<li>Images</li>
</ol>
<ol start="9">
<li>Fonts</li>
</ol>
<ol start="10">
<li>Integration: Espressif / STM32 관련 자료</li>
</ol>
<p>LVGL 공식문서는 디스플레이, 입력 장치, 폰트, drawing, widget, style, event, scrolling 등 LVGL의 핵심 모듈을 다룬다.  LVGL의 기본 흐름은 driver 초기화, lv_init(), display/input device 생성, UI 생성, lv_timer_handler() 반복 호출로 설명된다. </p>
<p>읽는 순서</p>
<ol>
<li>LVGL 개요</li>
</ol>
<ol start="2">
<li>Learn the Basics</li>
</ol>
<ol start="3">
<li>lv_init()</li>
</ol>
<ol start="4">
<li>display driver</li>
</ol>
<ol start="5">
<li>input device</li>
</ol>
<ol start="6">
<li>screen</li>
</ol>
<ol start="7">
<li>label</li>
</ol>
<ol start="8">
<li>button</li>
</ol>
<ol start="9">
<li>image</li>
</ol>
<ol start="10">
<li>style</li>
</ol>
<ol start="11">
<li>event</li>
</ol>
<ol start="12">
<li>timer</li>
</ol>
<ol start="13">
<li>image converter</li>
</ol>
<ol start="14">
<li>memory / color depth</li>
</ol>
<ol start="15">
<li>ESP32 IDF integration</li>
</ol>
<p>EdgeCanvas 연결</p>
<p>EdgeCanvas의 산출물은 LVGL 초기화 루틴, 위젯 트리, 이벤트 핸들러 C 코드, UI 에셋 C 배열이다. 기존 정리에서도 LVGL은 최신 한국어 단행본보다 공식문서가 1순위이고, 목표는 JSON으로 표현한 UI를 LVGL C 코드로 바꾸는 내부 규칙을 만드는 것이라고 정리되어 있다. </p>
<p>실습 산출물</p>
<p>lvgl-official-lab/
  docs/
    lvgl_object_model.md
    lvgl_event_model.md
    lvgl_image_pipeline.md
  schema/
    ui_schema.json
  generator/
    json_to_lvgl_c.py
  generated/
    screen_main.c</p>
<p>통과 기준</p>
<p>label, button, image를 C 코드로 생성한다.</p>
<p>style과 event handler를 분리한다.</p>
<p>JSON 위젯 트리를 LVGL C 코드로 변환한다.</p>
<p>이미지 리소스를 LVGL에서 사용할 수 있는 형태로 변환하는 흐름을 설명한다.</p>
<hr>
<p>11개월차: CMake / Arm GNU Toolchain / OpenOCD / ST-LINK / esptool</p>
<p>봐야 할 공식문서</p>
<ol>
<li>CMake Tutorial</li>
</ol>
<ol start="2">
<li>CMake latest docs</li>
</ol>
<ol start="3">
<li>Arm GNU Toolchain</li>
</ol>
<ol start="4">
<li>GCC docs</li>
</ol>
<ol start="5">
<li>OpenOCD official docs</li>
</ol>
<ol start="6">
<li>STM32CubeProgrammer CLI</li>
</ol>
<ol start="7">
<li>ESP-IDF Flash docs</li>
</ol>
<ol start="8">
<li>esptool docs</li>
</ol>
<p>CMake는 소스 코드 빌드를 관리하는 도구이고, CMake Tutorial은 CMake가 해결하는 공통 빌드 시스템 문제를 단계별 예제로 설명한다.  Arm GNU Toolchain은 Arm 아키텍처용 C, C++, Assembly 프로그래밍을 위한 오픈소스 도구 모음이다. </p>
<p>읽는 순서</p>
<ol>
<li>CMake tutorial: basic project</li>
</ol>
<ol start="2">
<li>target, include directory, library</li>
</ol>
<ol start="3">
<li>build directory와 source directory 분리</li>
</ol>
<ol start="4">
<li>toolchain file 개념</li>
</ol>
<ol start="5">
<li>GCC compile/link options</li>
</ol>
<ol start="6">
<li>Arm GNU Toolchain 설치와 arm-none-eabi-gcc 확인</li>
</ol>
<ol start="7">
<li>STM32CubeProgrammer CLI</li>
</ol>
<ol start="8">
<li>ESP-IDF flash monitor</li>
</ol>
<ol start="9">
<li>OpenOCD 기본 구조</li>
</ol>
<p>EdgeCanvas 연결</p>
<p>EdgeCanvas의 자가수정 루프는 빌드 실패를 읽고 수정해야 한다. 따라서 컴파일 에러, 링크 에러, 플래시 에러를 구조화해야 한다. 기존 실전 계획에서도 21개월차 목표는 generated C project → build → binary → flash → serial log로 잡혀 있다. </p>
<p>실습 산출물</p>
<p>build-flash-official-lab/
  cmake_minimal/
  toolchain_arm_none_eabi.cmake
  parse_gcc_log.py
  parse_cmake_log.py
  flash_stm32.md
  flash_esp32.md</p>
<p>통과 기준</p>
<p>CMake configure, build, install 개념을 설명한다.</p>
<p>cross compile과 native compile 차이를 설명한다.</p>
<p>GCC error/warning을 JSON으로 파싱한다.</p>
<p>STM32와 ESP32 플래시 명령을 추상화한다.</p>
<hr>
<p>12개월차: OpenCV / Pillow / V4L2 공식문서</p>
<p>봐야 할 공식문서</p>
<ol>
<li>OpenCV Python Tutorials</li>
</ol>
<ol start="2">
<li>OpenCV VideoCapture</li>
</ol>
<ol start="3">
<li>OpenCV Contours</li>
</ol>
<ol start="4">
<li>OpenCV Template Matching</li>
</ol>
<ol start="5">
<li>OpenCV Camera Calibration</li>
</ol>
<ol start="6">
<li>Pillow documentation</li>
</ol>
<ol start="7">
<li>Linux Media / V4L2 documentation</li>
</ol>
<p>OpenCV Python Tutorials는 이미지 처리, feature detection, video analysis, camera calibration, object detection 등을 다룬다.  OpenCV VideoCapture 공식 튜토리얼은 카메라에서 프레임을 캡처하고 cap.read()로 프레임을 읽는 흐름을 설명한다.  Contours 문서는 threshold 후 contour를 찾아 shape analysis와 object detection에 활용하는 방식을 설명한다.  Template Matching은 template image 위치를 큰 이미지에서 찾는 방법이다.  Pillow는 Python 이미지 처리 기능을 제공하는 라이브러리로, 파일 포맷 지원과 이미지 처리 기능을 제공한다. </p>
<p>읽는 순서</p>
<ol>
<li>OpenCV image basics</li>
</ol>
<ol start="2">
<li>VideoCapture</li>
</ol>
<ol start="3">
<li>color conversion</li>
</ol>
<ol start="4">
<li>threshold</li>
</ol>
<ol start="5">
<li>contour</li>
</ol>
<ol start="6">
<li>template matching</li>
</ol>
<ol start="7">
<li>image resize / crop</li>
</ol>
<ol start="8">
<li>camera calibration 맛보기</li>
</ol>
<ol start="9">
<li>Pillow Image module</li>
</ol>
<ol start="10">
<li>V4L2 device 개념</li>
</ol>
<p>EdgeCanvas 연결</p>
<p>EdgeCanvas의 Vision-in-the-Loop는 고급 자율주행 비전이 아니라 LCD 화면이 요구사항대로 떴는지 검증하는 테스트 자동화다. 기존 정리에서도 OpenCV는 Vision-in-the-Loop 검증과 AegisEdge 영상분석 양쪽에 핵심으로 분류되어 있다. </p>
<p>실습 산출물</p>
<p>vision-official-lab/
  capture_camera.py
  detect_screen_region.py
  compare_template.py
  compare_color.py
  vision_report.json</p>
<p>통과 기준</p>
<p>USB 카메라에서 프레임을 읽는다.</p>
<p>LCD 영역을 crop한다.</p>
<p>기준 이미지와 template matching을 수행한다.</p>
<p>화면 검은색/흰색 죽음 상태를 감지한다.</p>
<p>PASS/FAIL 리포트를 만든다.</p>
<hr>
<ol start="3">
<li>13~18개월: 심화 단계 공식문서 커리큘럼</li>
</ol>
<p>목표</p>
<p>이 단계에서는 문서 이해와 자가수정 Agent 설계 능력을 만든다. 기존 커리큘럼에서도 심화 단계는 선형대수, 확률통계, ML/DL, NLP, RAG, Upstage 문서 AI, LangGraph, 네트워크, Docker, 보안을 다루는 단계로 되어 있다. </p>
<hr>
<p>13개월차: 선형대수 / 확률통계 / 평가 공식 공개자료</p>
<p>봐야 할 공식 공개자료</p>
<ol>
<li>MIT OCW 18.06 Linear Algebra</li>
</ol>
<ol start="2">
<li>MIT OCW 18.05 Introduction to Probability and Statistics</li>
</ol>
<ol start="3">
<li>scikit-learn Model Evaluation</li>
</ol>
<ol start="4">
<li>OpenCV camera geometry 관련 문서</li>
</ol>
<p>MIT 18.06은 행렬 이론과 선형대수를 다루며, 시스템 방정식, 벡터공간, determinant, eigenvalue 등을 포함한다.  MIT 18.05는 조합론, 확률변수, 확률분포, Bayesian inference, hypothesis testing, confidence interval, linear regression 등을 다룬다.  scikit-learn은 모델 fitting, preprocessing, model selection, evaluation 등을 제공하는 머신러닝 라이브러리다. </p>
<p>읽는 순서</p>
<ol>
<li>MIT 18.06: vectors, matrices</li>
</ol>
<ol start="2">
<li>matrix multiplication</li>
</ol>
<ol start="3">
<li>least squares</li>
</ol>
<ol start="4">
<li>eigenvalues</li>
</ol>
<ol start="5">
<li>MIT 18.05: probability, random variables</li>
</ol>
<ol start="6">
<li>conditional probability</li>
</ol>
<ol start="7">
<li>Bayesian inference</li>
</ol>
<ol start="8">
<li>hypothesis testing</li>
</ol>
<ol start="9">
<li>scikit-learn metrics</li>
</ol>
<ol start="10">
<li>confusion matrix, precision, recall</li>
</ol>
<p>EdgeCanvas 연결</p>
<p>Vision-in-the-Loop의 판정 일치율, 색상/위치 오차, threshold, 평가 지표, AegisEdge 객체탐지 평가에 필요하다. 기존 커리큘럼도 이 연결을 명시하고 있다. </p>
<p>실습 산출물</p>
<p>math-evaluation-lab/
  pixel_error_metric.py
  confusion_matrix_for_vision.py
  pass_fail_statistics.ipynb</p>
<p>통과 기준</p>
<p>PASS/FAIL 100개 결과로 accuracy, precision, recall을 계산한다.</p>
<p>UI 요소 위치 오차를 픽셀 단위로 계산한다.</p>
<p>threshold를 바꾸면 FP/FN이 어떻게 변하는지 설명한다.</p>
<hr>
<p>14개월차: 머신러닝 / 딥러닝 공식문서</p>
<p>봐야 할 공식문서</p>
<ol>
<li>scikit-learn Getting Started</li>
</ol>
<ol start="2">
<li>scikit-learn User Guide</li>
</ol>
<ol start="3">
<li>scikit-learn Model Selection and Evaluation</li>
</ol>
<ol start="4">
<li>PyTorch 60 Minute Blitz</li>
</ol>
<ol start="5">
<li>PyTorch Learn the Basics</li>
</ol>
<p>scikit-learn 공식문서는 supervised/unsupervised learning, model selection, model evaluation 등을 체계적으로 제공한다.  PyTorch 60 Minute Blitz는 tensor, autograd, neural network, image classifier 학습을 목표로 하는 공식 튜토리얼이다. </p>
<p>읽는 순서</p>
<ol>
<li>scikit-learn getting started</li>
</ol>
<ol start="2">
<li>train/test split</li>
</ol>
<ol start="3">
<li>preprocessing</li>
</ol>
<ol start="4">
<li>model evaluation</li>
</ol>
<ol start="5">
<li>classification metrics</li>
</ol>
<ol start="6">
<li>PyTorch tensors</li>
</ol>
<ol start="7">
<li>autograd</li>
</ol>
<ol start="8">
<li>neural networks</li>
</ol>
<ol start="9">
<li>image classifier</li>
</ol>
<ol start="10">
<li>inference mode</li>
</ol>
<p>EdgeCanvas 연결</p>
<p>EdgeCanvas는 모델을 직접 학습하지 않아도 되지만, Vision 판정과 AegisEdge 객체탐지를 평가하려면 ML/DL의 기본을 알아야 한다. AegisEdge가 YOLO/ONNX/DeepStream으로 확장되면 필수다.</p>
<p>실습 산출물</p>
<p>ml-official-lab/
  sklearn_classifier.py
  pytorch_image_classifier.py
  evaluation.md</p>
<p>통과 기준</p>
<p>train/validation/test를 구분한다.</p>
<p>overfitting을 설명한다.</p>
<p>작은 이미지 분류 모델을 학습한다.</p>
<p>평가 지표를 정리한다.</p>
<hr>
<p>15개월차: Transformer / NLP / RAG 공식문서</p>
<p>봐야 할 공식문서</p>
<ol>
<li>Hugging Face Documentation</li>
</ol>
<ol start="2">
<li>Hugging Face LLM Course</li>
</ol>
<ol start="3">
<li>Transformers documentation</li>
</ol>
<ol start="4">
<li>Tokenizers documentation</li>
</ol>
<ol start="5">
<li>Datasets documentation</li>
</ol>
<ol start="6">
<li>LangChain text splitters / retrievers, 필요 시</li>
</ol>
<p>Hugging Face LLM Course는 LLM과 NLP를 Transformers, Datasets, Tokenizers, Accelerate, Hub 생태계와 함께 학습하도록 구성되어 있다.  Transformers 문서는 transformer model의 기본부터 다양한 task 응용까지 안내한다. </p>
<p>읽는 순서</p>
<ol>
<li>LLM Course chapter 1</li>
</ol>
<ol start="2">
<li>tokenization</li>
</ol>
<ol start="3">
<li>transformer pipeline</li>
</ol>
<ol start="4">
<li>embeddings</li>
</ol>
<ol start="5">
<li>datasets</li>
</ol>
<ol start="6">
<li>chunking 개념</li>
</ol>
<ol start="7">
<li>retrieval 개념</li>
</ol>
<ol start="8">
<li>structured output 개념</li>
</ol>
<ol start="9">
<li>RAG 실패 유형 정리</li>
</ol>
<ol start="10">
<li>prompt injection 기초</li>
</ol>
<p>EdgeCanvas 연결</p>
<p>EdgeCanvas의 데이터시트 해석은 문서 이해 문제다. 기존 실전 계획도 데이터시트 PDF/Markdown → Document Parse → Information Extract → MCU hardware schema → validation report를 첫 MVP로 둔다. </p>
<p>실습 산출물</p>
<p>rag-official-lab/
  split_datasheet_markdown.py
  simple_retrieval.py
  structured_extraction_schema.py
  extraction_failure_cases.md</p>
<p>통과 기준</p>
<p>문서를 chunk로 나눈다.</p>
<p>retrieval 결과를 근거와 함께 출력한다.</p>
<p>JSON structured output을 검증한다.</p>
<p>hallucination과 extraction error를 구분한다.</p>
<hr>
<p>16개월차: Upstage Document AI / Solar / VARCO 공식문서</p>
<p>봐야 할 공식문서</p>
<ol>
<li>Upstage Document Parse API</li>
</ol>
<ol start="2">
<li>Upstage Information Extract</li>
</ol>
<ol start="3">
<li>Upstage Universal Information Extraction</li>
</ol>
<ol start="4">
<li>Upstage Solar API / Console docs</li>
</ol>
<ol start="5">
<li>Upstage Cookbook</li>
</ol>
<ol start="6">
<li>NC AI / VARCO API Platform</li>
</ol>
<ol start="7">
<li>NC AI VARCO Art 관련 공식 페이지</li>
</ol>
<p>Upstage Document Parse API는 복잡한 문서를 구조화된 HTML 또는 Markdown으로 파싱한다고 설명되어 있다.  Upstage Information Extract는 scanned images, PDFs, Office files, rotated pages, 500+ page documents 등 다양한 문서에서 데이터 추출을 지원한다고 설명한다.  Universal Information Extraction API는 템플릿이나 재학습 없이 구조화 데이터를 추출하는 API로 설명된다.  NC AI 공식 페이지는 VARCO를 콘텐츠 워크플로우를 통합하는 차세대 AI 엔진으로 소개한다. </p>
<p>읽는 순서</p>
<ol>
<li>Document Parse overview</li>
</ol>
<ol start="2">
<li>Document Parse API request/response</li>
</ol>
<ol start="3">
<li>output format: HTML / Markdown</li>
</ol>
<ol start="4">
<li>Information Extract overview</li>
</ol>
<ol start="5">
<li>Universal IE schema 설계</li>
</ol>
<ol start="6">
<li>error handling</li>
</ol>
<ol start="7">
<li>API key 관리</li>
</ol>
<ol start="8">
<li>rate limit / retry 설계</li>
</ol>
<ol start="9">
<li>Solar API</li>
</ol>
<ol start="10">
<li>VARCO API / VARCO Art 가능 범위 확인</li>
</ol>
<p>EdgeCanvas 연결</p>
<p>구현제안서상 EdgeCanvas는 Document Parse와 Information Extract로 레지스터 맵, 핀맵, 클럭 트리, 타이밍 제약을 JSON 스키마로 추출한다. 기존 정리에서도 MCU 데이터시트 전체를 읽는 것이 아니라 필요한 정보만 안정적으로 뽑아야 한다고 정리되어 있다. </p>
<p>실습 산출물</p>
<p>upstage-official-lab/
  parse_datasheet.py
  extract_mcu_schema.py
  schemas/
    mcu_schema.json
    board_profile_schema.json
  reports/
    extraction_quality_report.md</p>
<p>통과 기준</p>
<p>데이터시트 1개를 Markdown/HTML로 변환한다.</p>
<p>MCU 관련 필드 10개 이상을 JSON으로 추출한다.</p>
<p>Pydantic validation을 통과한다.</p>
<p>사람이 검토한 정답과 차이를 기록한다.</p>
<hr>
<p>17개월차: LangGraph / LangChain / Pydantic 공식문서</p>
<p>봐야 할 공식문서</p>
<ol>
<li>LangGraph Overview</li>
</ol>
<ol start="2">
<li>LangGraph Graph API</li>
</ol>
<ol start="3">
<li>StateGraph</li>
</ol>
<ol start="4">
<li>Nodes and Edges</li>
</ol>
<ol start="5">
<li>Conditional Edges</li>
</ol>
<ol start="6">
<li>Persistence / Checkpointing</li>
</ol>
<ol start="7">
<li>Human-in-the-loop</li>
</ol>
<ol start="8">
<li>LangChain Tools</li>
</ol>
<ol start="9">
<li>Pydantic Models</li>
</ol>
<ol start="10">
<li>Pydantic Validators</li>
</ol>
<p>LangGraph Graph API 문서는 nodes와 edges를 조합해 상태가 시간에 따라 진화하는 복잡하고 반복적인 workflow를 만들 수 있다고 설명한다.  LangChain tools 문서는 tool을 모델이 호출할 수 있는 유틸리티로 설명하고, tool 입력은 모델이 생성하고 출력은 다시 모델에 전달되는 구조라고 설명한다.  Pydantic은 Python에서 가장 널리 사용되는 데이터 검증 라이브러리라고 공식문서가 설명하며, model validation은 지정된 type과 constraint에 맞는 model instance를 만드는 과정으로 설명된다. </p>
<p>읽는 순서</p>
<ol>
<li>LangGraph overview</li>
</ol>
<ol start="2">
<li>Graph API</li>
</ol>
<ol start="3">
<li>StateGraph</li>
</ol>
<ol start="4">
<li>nodes</li>
</ol>
<ol start="5">
<li>edges</li>
</ol>
<ol start="6">
<li>conditional routing</li>
</ol>
<ol start="7">
<li>retry loop</li>
</ol>
<ol start="8">
<li>persistence/checkpointing</li>
</ol>
<ol start="9">
<li>human-in-the-loop</li>
</ol>
<ol start="10">
<li>LangChain tools</li>
</ol>
<ol start="11">
<li>Pydantic models</li>
</ol>
<ol start="12">
<li>Pydantic validators</li>
</ol>
<p>EdgeCanvas 연결</p>
<p>EdgeCanvas의 핵심은 LangGraph 상태머신 기반 self-healing agent다. 기존 정리에서도 LangGraph는 입력 수신부터 실기 검증까지 전 구간을 상태머신으로 제어하고, 실패 시 코드 생성 단계로 재진입하는 자가수정 루프를 실행하는 구조로 정리되어 있다. </p>
<p>실습 산출물</p>
<p>langgraph-official-lab/
  state.py
  graph.py
  nodes/
    parse_datasheet.py
    extract_schema.py
    generate_lvgl.py
    build.py
    verify.py
    fix.py
  schemas/
    workflow_state.py</p>
<p>통과 기준</p>
<p>parse → extract → generate → build → verify → fix 루프를 mock으로 구현한다.</p>
<p>조건부 edge로 PASS/FAIL 분기를 만든다.</p>
<p>Pydantic으로 state schema를 검증한다.</p>
<p>실패 시 최대 retry 횟수를 제한한다.</p>
<hr>
<p>18개월차: Docker / GitHub Actions / 보안 공식문서</p>
<p>봐야 할 공식문서</p>
<ol>
<li>Docker Get Started</li>
</ol>
<ol start="2">
<li>Dockerfile docs</li>
</ol>
<ol start="3">
<li>Docker Compose</li>
</ol>
<ol start="4">
<li>GitHub Actions docs</li>
</ol>
<ol start="5">
<li>pytest fixtures</li>
</ol>
<ol start="6">
<li>OWASP Top 10</li>
</ol>
<ol start="7">
<li>KISA / KrCERT 보안 가이드</li>
</ol>
<ol start="8">
<li>Python dependency 보안 관련 공식자료</li>
</ol>
<ol start="9">
<li>GitHub secret scanning / Actions secrets</li>
</ol>
<p>Docker 공식문서는 Docker를 시작하는 데 필요한 자료를 제공하고, Dockerfile은 컨테이너 이미지를 만들기 위한 text-based document라고 설명한다.  Docker Compose는 여러 컨테이너 애플리케이션을 정의하고 실행하는 도구로 설명된다.  GitHub Actions 공식문서는 CI/CD를 포함한 workflow를 저장소에서 자동화할 수 있다고 설명한다.  OWASP Top 10은 웹 애플리케이션 보안을 위한 표준 awareness document로 설명된다. </p>
<p>읽는 순서</p>
<ol>
<li>Docker overview</li>
</ol>
<ol start="2">
<li>Dockerfile 작성</li>
</ol>
<ol start="3">
<li>image build</li>
</ol>
<ol start="4">
<li>container run</li>
</ol>
<ol start="5">
<li>volume</li>
</ol>
<ol start="6">
<li>compose</li>
</ol>
<ol start="7">
<li>GitHub Actions quickstart</li>
</ol>
<ol start="8">
<li>workflow syntax</li>
</ol>
<ol start="9">
<li>secrets</li>
</ol>
<ol start="10">
<li>pytest fixtures</li>
</ol>
<ol start="11">
<li>OWASP Top 10</li>
</ol>
<ol start="12">
<li>KISA 보안 가이드</li>
</ol>
<ol start="13">
<li>command injection / path traversal / secret leakage 체크리스트</li>
</ol>
<p>EdgeCanvas 연결</p>
<p>EdgeCanvas는 외부 PDF 입력, 코드 생성, 파일 쓰기, 빌드 실행, API 키 사용을 모두 수행한다. 즉 보안은 나중 문제가 아니라 architecture 단계에서 들어가야 한다. 기존 정리에서도 보안은 API 키, 코드 생성, 외부 문서 입력 때문에 EdgeCanvas 필수도 4로 분류되어 있다. </p>
<p>실습 산출물</p>
<p>deployment-security-official-lab/
  Dockerfile
  docker-compose.yml
  .github/workflows/test.yml
  .env.example
  security_checklist.md
  safe_subprocess.py</p>
<p>통과 기준</p>
<p>Docker로 동일한 CLI가 재현 실행된다.</p>
<p>GitHub Actions에서 pytest가 돈다.</p>
<p>API key를 코드에 하드코딩하지 않는다.</p>
<p>외부 명령 실행은 allowlist로 제한한다.</p>
<p>보안 체크리스트를 만든다.</p>
<hr>
<ol start="4">
<li>19~24개월: 실전 단계 공식문서 커리큘럼</li>
</ol>
<p>목표</p>
<p>이 단계에서는 공식문서를 “읽는 것”이 아니라 필요한 공식문서로 돌아가며 EdgeCanvas MVP를 완성한다. 기존 실전 단계 목표도 EdgeCanvas MVP, AegisEdge 확장 프로토타입, 기술문서, 포트폴리오로 잡혀 있다. </p>
<hr>
<p>19개월차: 데이터시트 → JSON</p>
<p>기준 공식문서</p>
<p>Upstage Document Parse</p>
<p>Upstage Information Extract</p>
<p>Universal Information Extraction</p>
<p>Pydantic Models / Validators</p>
<p>STM32H747/757 datasheet</p>
<p>RM0399 Reference Manual</p>
<p>M5Stack CoreS3 docs</p>
<p>ESP32-S3 technical reference</p>
<p>구현 목표</p>
<p>PDF / Markdown / HTML
→ Document Parse
→ Information Extract
→ Pydantic validation
→ MCU hardware schema</p>
<p>반드시 확인할 공식문서 포인트</p>
<p>Upstage API request/response</p>
<p>output format</p>
<p>schema extraction</p>
<p>validation error</p>
<p>STM32 memory / pin / clock / peripheral</p>
<p>M5Stack flash / PSRAM / display / camera</p>
<p>ESP-IDF target information</p>
<p>산출물</p>
<p>edgecanvas/
  parsers/
  schemas/
  board_profiles/
    stm32h747i_disco.json
    m5stack_cores3.json
  reports/
    extraction_report.md</p>
<hr>
<p>20개월차: JSON → LVGL C 코드</p>
<p>기준 공식문서</p>
<p>LVGL Learn the Basics</p>
<p>LVGL Widgets</p>
<p>LVGL Styles</p>
<p>LVGL Events</p>
<p>LVGL Images</p>
<p>LVGL Display/Input device</p>
<p>CMake</p>
<p>GCC</p>
<p>구현 목표</p>
<p>UI requirement
→ UI schema
→ LVGL widget tree
→ C source generation</p>
<p>반드시 확인할 공식문서 포인트</p>
<p>lv_init()</p>
<p>display creation</p>
<p>input device</p>
<p>label/button/image API</p>
<p>style API</p>
<p>event callback</p>
<p>image data</p>
<p>lv_timer_handler()</p>
<p>산출물</p>
<p>edgecanvas/
  ui_schema/
  generators/
    lvgl_c_generator.py
  templates/
  generated/
    dashboard.c</p>
<hr>
<p>21개월차: 빌드 / 플래시 자동화</p>
<p>기준 공식문서</p>
<p>CMake Tutorial</p>
<p>Arm GNU Toolchain</p>
<p>GCC docs</p>
<p>STM32CubeH7</p>
<p>STM32CubeProgrammer CLI</p>
<p>ESP-IDF Build / Flash / Monitor</p>
<p>esptool</p>
<p>OpenOCD</p>
<p>구현 목표</p>
<p>generated C project
→ build
→ parse error
→ flash
→ serial log</p>
<p>반드시 확인할 공식문서 포인트</p>
<p>CMake configure/build</p>
<p>cross compile toolchain file</p>
<p>include path</p>
<p>link error</p>
<p>map file</p>
<p>STM32 flash CLI</p>
<p>ESP-IDF flash monitor</p>
<p>산출물</p>
<p>edgecanvas/
  builders/
    cmake_builder.py
    espidf_builder.py
  flashers/
    stm32_cubeprogrammer.py
    espidf_flasher.py
  logs/</p>
<hr>
<p>22개월차: Vision-in-the-Loop</p>
<p>기준 공식문서</p>
<p>OpenCV VideoCapture</p>
<p>OpenCV threshold</p>
<p>OpenCV contours</p>
<p>OpenCV template matching</p>
<p>Pillow Image</p>
<p>V4L2 docs</p>
<p>구현 목표</p>
<p>camera
→ LCD region crop
→ expected UI comparison
→ PASS/FAIL
→ report</p>
<p>반드시 확인할 공식문서 포인트</p>
<p>cv.VideoCapture</p>
<p>cap.isOpened()</p>
<p>cap.read()</p>
<p>cv.cvtColor</p>
<p>cv.threshold</p>
<p>cv.findContours</p>
<p>cv.matchTemplate</p>
<p>crop/resize</p>
<p>color comparison</p>
<p>산출물</p>
<p>edgecanvas/
  vision/
    capture.py
    lcd_region.py
    compare_layout.py
    compare_color.py
    report.py</p>
<hr>
<p>23개월차: LangGraph Self-Healing 통합</p>
<p>기준 공식문서</p>
<p>LangGraph Graph API</p>
<p>conditional edges</p>
<p>persistence/checkpoint</p>
<p>LangChain tools</p>
<p>Pydantic validators</p>
<p>pytest fixtures</p>
<p>Docker</p>
<p>GitHub Actions</p>
<p>구현 목표</p>
<p>extract schema
→ generate code
→ build
→ flash
→ verify
→ failed?
    → fix
    → retry
→ report</p>
<p>반드시 확인할 공식문서 포인트</p>
<p>state schema</p>
<p>node function</p>
<p>edge</p>
<p>conditional routing</p>
<p>retry count</p>
<p>checkpoint</p>
<p>tool execution</p>
<p>build evaluator</p>
<p>vision evaluator</p>
<p>산출물</p>
<p>edgecanvas/
  graph/
    state.py
    workflow.py
    conditions.py
  evaluators/
  fixers/
  tests/</p>
<hr>
<p>24개월차: 통합 / 문서화 / AegisEdge 확장</p>
<p>기준 공식문서</p>
<p>EdgeCanvas 통합:</p>
<p>Docker</p>
<p>GitHub Actions</p>
<p>pytest</p>
<p>CMake</p>
<p>LVGL</p>
<p>STM32CubeH7</p>
<p>ESP-IDF</p>
<p>Upstage</p>
<p>LangGraph</p>
<p>OpenCV</p>
<p>AegisEdge 영상분석 확장:</p>
<p>NVIDIA DeepStream</p>
<p>Ultralytics YOLO11</p>
<p>ONNX Runtime</p>
<p>OpenCV</p>
<p>Docker</p>
<p>DeepStream은 USB/CSI camera, video file, RTSP stream을 입력으로 받아 AI와 computer vision으로 환경 이해를 위한 insight를 생성하는 streaming analytics toolkit이다.  Ultralytics YOLO11 문서는 object detection, segmentation, classification, pose 등 작업과 train/predict/export 흐름을 제공한다.  ONNX는 머신러닝 모델을 표현하기 위한 open format이고, ONNX Runtime은 다양한 기술 스택에서 inference를 가속하는 production-grade AI engine으로 설명된다. </p>
<p>산출물</p>
<p>edgecanvas/
  README.md
  docs/
    architecture.md
    official_docs_map.md
    board_profile.md
    security.md
    benchmark.md
  examples/
    stm32_demo/
    m5stack_demo/
  docker/
  tests/
  reports/</p>
<p>aegisedge-prototype/
  capture/
  inference/
  events/
  api/
  dashboard/</p>
<hr>
<ol start="5">
<li>AegisEdge 선택 심화 공식문서 트랙</li>
</ol>
<p>AegisEdge 명세는 아직 별도로 확인되지 않았으므로, 여기서는 엣지 AI / 영상분석 / 카메라 기반 이벤트 추론으로 가정한다. AegisEdge가 실제로 다른 구조라면 이 트랙은 조정해야 한다.</p>
<p>영상분석 트랙</p>
<p>공식문서 순서</p>
<ol>
<li>OpenCV Python Tutorials</li>
</ol>
<ol start="2">
<li>Ultralytics YOLO11</li>
</ol>
<ol start="3">
<li>Ultralytics Predict</li>
</ol>
<ol start="4">
<li>Ultralytics Export</li>
</ol>
<ol start="5">
<li>ONNX</li>
</ol>
<ol start="6">
<li>ONNX Runtime</li>
</ol>
<ol start="7">
<li>NVIDIA DeepStream Overview</li>
</ol>
<ol start="8">
<li>DeepStream reference app</li>
</ol>
<ol start="9">
<li>Docker</li>
</ol>
<ol start="10">
<li>GitHub Actions</li>
</ol>
<p>목표</p>
<p>USB/RTSP camera
→ OpenCV preprocessing
→ YOLO inference
→ ONNX export
→ DeepStream pipeline
→ event JSON
→ Docker deployment</p>
<p>DeepStream reference application은 GStreamer 기반이며 camera, RTSP input, encoded file input, multi stream/source를 지원한다고 공식문서가 설명한다. </p>
<hr>
<p>로봇 연동 트랙</p>
<p>ROS2는 EdgeCanvas 본체의 1순위는 아니다. 기존 정리에서도 ROS2는 AegisEdge가 로봇과 연결되거나 EdgeCanvas가 서비스 로봇 HMI와 연동될 때 학습하는 후순위로 분리했다. </p>
<p>공식문서 순서</p>
<ol>
<li>ROS 2 Concepts</li>
</ol>
<ol start="2">
<li>Nodes</li>
</ol>
<ol start="3">
<li>Topics</li>
</ol>
<ol start="4">
<li>Services</li>
</ol>
<ol start="5">
<li>Actions</li>
</ol>
<ol start="6">
<li>Parameters</li>
</ol>
<ol start="7">
<li>tf2</li>
</ol>
<ol start="8">
<li>Gazebo ROS integration</li>
</ol>
<ol start="9">
<li>Nav2, 실제 이동로봇 필요 시</li>
</ol>
<ol start="10">
<li>Isaac ROS / Isaac Sim, NVIDIA 로봇비전 필요 시</li>
</ol>
<p>ROS2 공식문서는 topic, service, action이 노드 간 데이터 교환 인터페이스라고 설명하고, service는 synchronous request/response, action은 feedback을 포함하는 long-running task에 적합하다고 설명한다.  Gazebo 문서는 ROS와 Gazebo 버전 조합을 안내하고, ROS2와 Gazebo가 서로 데이터를 주고받도록 연동할 수 있음을 설명한다. </p>
<hr>
<p>멀티에이전트 / 도구연동 트랙</p>
<p>공식문서 순서</p>
<ol>
<li>LangGraph</li>
</ol>
<ol start="2">
<li>LangChain Tools</li>
</ol>
<ol start="3">
<li>Pydantic</li>
</ol>
<ol start="4">
<li>MCP official docs</li>
</ol>
<ol start="5">
<li>A2A official docs, 필요 시</li>
</ol>
<ol start="6">
<li>OWASP Top 10</li>
</ol>
<ol start="7">
<li>GitHub Actions secrets</li>
</ol>
<ol start="8">
<li>Docker security</li>
</ol>
<p>이 트랙은 대회 초기 구현보다 후속 제품화에 가깝다. EdgeCanvas 대회 구현은 먼저 데이터시트 → LVGL → 빌드 → 플래시 → Vision 검증을 완성해야 한다.</p>
<hr>
<ol start="6">
<li>공식문서 전체 우선순위표</li>
</ol>
<p>우선순위    공식문서    왜 보는가    단계</p>
<p>1    Python docs    Agent, API, 자동화, subprocess    기초
2    Git / Pro Git    버전관리, 협업, 포트폴리오    기초
3    Linux man-pages    장치파일, 프로세스, 시스템콜    기초
4    GCC / Make    C 컴파일, warning, 빌드 오류    기초
5    MIT 6.006    자료구조, 그래프, 상태머신    기초
6    Arm / CMSIS    Cortex-M, 인터럽트, 메모리맵    기초<del>기본
7    STM32H747I-DISCO / RM0399    실제 타깃 보드 기준    기본
8    STM32CubeH7 / HAL / BSP    보드 초기화와 드라이버    기본
9    ESP-IDF / M5Stack CoreS3    휴대 타깃 보드 기준    기본
10    LVGL    HMI 자동생성의 핵심    기본
11    CMake / Arm GNU Toolchain    펌웨어 빌드 자동화    기본
12    OpenCV / Pillow / V4L2    Vision-in-the-Loop    기본
13    MIT 18.06 / 18.05    비전·AI 평가 수학    심화
14    scikit-learn / PyTorch    ML/DL 기본과 평가    심화
15    Hugging Face docs    Transformer/RAG 이해    심화
16    Upstage docs    데이터시트 문서 AI    심화</del>실전
17    LangGraph / Pydantic    Self-Healing 상태머신    심화<del>실전
18    Docker / GitHub Actions / pytest    재현성, 테스트, 제출    심화</del>실전
19    OWASP / KISA    API 키, 코드생성 보안    심화~실전
20    DeepStream / YOLO / ONNX    AegisEdge 영상분석    선택 심화
21    ROS2 / Gazebo    로봇 연동    선택 심화</p>
<hr>
<ol start="7">
<li>주간 공식문서 공부법</li>
</ol>
<p>공식문서는 “읽었다”가 아니라 “구현 기준으로 바꿨다”가 중요하다.</p>
<p>매주 반복 루틴</p>
<p>요일    할 일</p>
<p>월    공식문서의 개요/Getting Started 읽기
화    API reference에서 함수·명령어·옵션 확인
수    최소 예제 실행
목    예제를 EdgeCanvas 구조에 맞게 변형
금    실패 로그 정리
토    README / notes 작성
일    다음 주 공식문서 목록 갱신</p>
<p>문서 읽을 때 항상 남길 것</p>
<p>docs-notes/
  source_name.md
  version.md
  why_needed.md
  commands.md
  api_summary.md
  edgecanvas_mapping.md
  failure_cases.md</p>
<p>각 공식문서마다 아래 질문에 답해야 한다.</p>
<ol>
<li>이 문서는 EdgeCanvas 어느 모듈과 연결되는가?</li>
</ol>
<ol start="2">
<li>구현에서 직접 쓰는 함수/명령어/API는 무엇인가?</li>
</ol>
<ol start="3">
<li>실패할 때 어떤 에러가 나는가?</li>
</ol>
<ol start="4">
<li>버전 의존성이 있는가?</li>
</ol>
<ol start="5">
<li>내 코드에 어떤 schema나 wrapper로 반영할 것인가?</li>
</ol>
<hr>
<ol start="8">
<li>공식문서 기준 최종 2년 로드맵 요약</li>
</ol>
<p>기초, 1~6개월</p>
<p>Linux man-pages
→ Git / Pro Git
→ Python docs
→ pytest
→ GCC / Make
→ MIT 6.006
→ Arm / CMSIS
→ MIT 6.1810</p>
<p>목표는 개발환경, 언어, 자료구조, 시스템 기초다.</p>
<p>기본, 7~12개월</p>
<p>STM32H747I-DISCO
→ RM0399
→ STM32CubeH7
→ STM32CubeProgrammer
→ ESP-IDF
→ M5Stack CoreS3
→ LVGL
→ CMake
→ OpenCV</p>
<p>목표는 실물 보드에 HMI를 띄우고 카메라로 검증하는 것이다.</p>
<p>심화, 13~18개월</p>
<p>MIT 18.06 / 18.05
→ scikit-learn
→ PyTorch
→ Hugging Face
→ Upstage Document Parse
→ Upstage Information Extract
→ LangGraph
→ Pydantic
→ Docker
→ GitHub Actions
→ OWASP / KISA</p>
<p>목표는 문서 이해, 평가, 자가수정 에이전트, 배포, 보안이다.</p>
<p>실전, 19~24개월</p>
<p>Upstage + Pydantic
→ LVGL generator
→ CMake / STM32 / ESP-IDF build
→ OpenCV Vision-in-the-Loop
→ LangGraph Self-Healing
→ Docker / GitHub Actions
→ AegisEdge optional track</p>
<p>목표는 데이터시트 → JSON → LVGL C 코드 → 빌드 → 플래시 → 카메라 검증 → 자가수정 리포트다. 이 목표는 기존 2년 커리큘럼의 최종 요약과도 일치한다. </p>
<hr>
<ol start="9">
<li>가장 먼저 봐야 할 공식문서 10개</li>
</ol>
<p>지금 바로 시작한다면 순서는 이게 가장 현실적이다.</p>
<ol>
<li>Python Tutorial</li>
</ol>
<ol start="2">
<li>Git / Pro Git</li>
</ol>
<ol start="3">
<li>Linux man-pages</li>
</ol>
<ol start="4">
<li>GCC Warning Options</li>
</ol>
<ol start="5">
<li>MIT 6.006 Introduction to Algorithms</li>
</ol>
<ol start="6">
<li>Arm CMSIS-Core</li>
</ol>
<ol start="7">
<li>STM32H747I-DISCO User Manual</li>
</ol>
<ol start="8">
<li>ESP-IDF Get Started</li>
</ol>
<ol start="9">
<li>LVGL Learn the Basics</li>
</ol>
<ol start="10">
<li>OpenCV VideoCapture + Contours + Template Matching</li>
</ol>
<p>그다음에:</p>
<ol start="11">
<li>CMake Tutorial</li>
</ol>
<ol start="12">
<li>STM32CubeH7 / HAL / BSP</li>
</ol>
<ol start="13">
<li>M5Stack CoreS3 docs</li>
</ol>
<ol start="14">
<li>Upstage Document Parse / Information Extract</li>
</ol>
<ol start="15">
<li>LangGraph Graph API</li>
</ol>
<ol start="16">
<li>Pydantic Models / Validators</li>
</ol>
<ol start="17">
<li>Dockerfile / Docker Compose</li>
</ol>
<ol start="18">
<li>GitHub Actions</li>
</ol>
<ol start="19">
<li>OWASP Top 10 / KISA</li>
</ol>
<ol start="20">
<li>DeepStream / YOLO / ONNX Runtime, AegisEdge 영상분석 시</li>
</ol>
<hr>
<p>최종적으로 말하면, <strong>공식문서 기준 커리큘럼의 중심축은 LVGL이나 LangGraph 하나가 아니라 “공식문서로 검증 가능한 파이프라인”</strong>이다. 즉, Linux/Python/C/GCC로 개발환경을 만들고, Arm/STM32/ESP-IDF/LVGL로 실물 HMI를 만들고, OpenCV로 검증하고, Upstage/LangGraph/Pydantic으로 문서 이해와 자가수정 루프를 만들고, Docker/GitHub Actions/OWASP로 재현성과 보안을 확보하는 순서가 가장 객관적으로 맞다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[먹고살자]]></title>
            <link>https://velog.io/@charlese_note/%EB%A8%B9%EA%B3%A0%EC%82%B4%EC%9E%90-yjm6ww9e</link>
            <guid>https://velog.io/@charlese_note/%EB%A8%B9%EA%B3%A0%EC%82%B4%EC%9E%90-yjm6ww9e</guid>
            <pubDate>Tue, 16 Jun 2026 13:55:19 GMT</pubDate>
            <description><![CDATA[<p>업로드된 2026-06-02 EdgeCanvas 구현제안서와 2026-06-16 정리 문서를 기준으로 보면, 이 2년 커리큘럼은 <strong>“AI 공부”가 아니라 “컴퓨터공학 + 임베디드 + HMI + 컴퓨터비전 + LLM Agent + 엣지 배포”를 통합하는 커리큘럼</strong>이어야 한다. EdgeCanvas는 “반도체 데이터시트를 읽고 임베디드 화면 HMI를 자동 구현하는 AI 에이전트”이고, 주력 하드웨어는 <strong>STM32H747I-DISCO</strong>, 휴대 시연용 하드웨어는 <strong>M5Stack CoreS3</strong>로 정의되어 있다. 또한 핵심 구조는 데이터시트 자동 해석, LVGL 코드 생성, 실기 플래시, 카메라 기반 자가검증을 하나의 파이프라인으로 묶는 방식이다. </p>
<p>AegisEdge는 별도 명세 문서가 아직 없으므로, 여기서는 이전 정리와 네 맥락에 맞춰 <strong>엣지 AI, 영상분석, 카메라 기반 추론, 보안·정책·이벤트 처리형 에이전트</strong>로 확장된다고 가정한다. 따라서 ROS2·SLAM·로보틱스는 “주전공”이 아니라 <strong>후반 선택 심화 트랙</strong>으로 둔다.</p>
<hr>
<h1 id="0-커리큘럼-설계-원칙">0. 커리큘럼 설계 원칙</h1>
<p>이 커리큘럼은 다음 세 가지 근거로 설계했다.</p>
<p>첫째, EdgeCanvas 구현제안서의 기술스택이 매우 넓다. 문서에는 <strong>Python 3.11 이상, C/C++, CMake, Make, Bash, LangGraph, LangChain, Pydantic, LVGL 9.x, arm-none-eabi-gcc, ESP-IDF v5.x, ST-Link, esptool, OpenOCD, pyserial, OpenCV, Pillow, v4l2, pytest, Docker, pip, GitHub, requirements.txt, CMakeLists.txt</strong>가 들어 있다. 즉, 단순히 LLM API만 쓰는 수준이 아니라 실제 펌웨어 빌드·플래시·비전 검증·배포까지 이해해야 한다. </p>
<p>둘째, EdgeCanvas의 핵심 루프는 <strong>문서 이해 → 하드웨어 제약 추출 → LVGL 코드 생성 → 빌드 → 플래시 → 카메라 검증 → 실패 시 자가수정</strong>이다. 구현제안서에는 Upstage Document Parse/Information Extract로 레지스터 맵·핀맵·클럭 트리·타이밍 제약을 JSON으로 추출하고, Solar Pro 3가 LVGL 초기화 루틴·위젯 트리·이벤트 핸들러 C 코드를 생성하며, USB 카메라 기반 검증과 LangGraph 상태머신 자가수정 루프를 수행한다고 되어 있다. </p>
<p>셋째, 표준 컴퓨터공학 커리큘럼 관점에서도 이 경로가 타당하다. ACM CS2023의 지식영역에는 알고리즘, 컴퓨터구조, 운영체제, 네트워크, 보안, AI, 데이터관리, HCI, 수학·통계 기초가 포함된다. (<a href="https://csed.acm.org/knowledge-areas/?utm_source=chatgpt.com" title="Knowledge Areas - CS2023 - ACM">csed.acm.org</a>) 컴퓨터공학 CE2016 쪽에서는 회로·전자, 디지털 설계, 컴퓨터구조, 임베디드 시스템, 네트워크, 알고리즘이 핵심 영역으로 제시된다. (<a href="https://www.acm.org/binaries/content/assets/education/ce2016-final-report.pdf?utm_source=chatgpt.com" title="Computer Engineering Curricula 2016">ACM</a>)</p>
<p>그래서 2년은 이렇게 나눈다.</p>
<table>
<thead>
<tr>
<th>기간</th>
<th>단계</th>
<th>목표</th>
</tr>
</thead>
<tbody><tr>
<td>1~6개월</td>
<td><strong>기초</strong></td>
<td>개발자 기본기, C/Python, 자료구조, 리눅스, 컴퓨터구조 기초</td>
</tr>
<tr>
<td>7~12개월</td>
<td><strong>기본</strong></td>
<td>임베디드, STM32/ESP32, LVGL, 빌드/플래시, OpenCV 검증</td>
</tr>
<tr>
<td>13~18개월</td>
<td><strong>심화</strong></td>
<td>머신러닝, 딥러닝, 문서 AI, RAG, LangGraph, 보안, 네트워크</td>
</tr>
<tr>
<td>19~24개월</td>
<td><strong>실전</strong></td>
<td>EdgeCanvas MVP, AegisEdge 프로토타입, CI/CD, 벤치마크, 포트폴리오</td>
</tr>
</tbody></table>
<hr>
<h1 id="1-2년-후-목표-수준">1. 2년 후 목표 수준</h1>
<p>2년 뒤에는 다음 정도까지 가는 것을 목표로 잡는다.</p>
<h2 id="edgecanvas-기준">EdgeCanvas 기준</h2>
<p>너는 다음을 혼자 설명하고 구현할 수 있어야 한다.</p>
<ol>
<li>MCU 데이터시트에서 RAM, Flash, 핀맵, 클럭, 디스플레이 인터페이스 정보를 읽는다.</li>
<li>그 정보를 JSON 스키마로 정리한다.</li>
<li>UI 요구사항을 LVGL 위젯 트리로 바꾼다.</li>
<li>LVGL C 코드를 생성한다.</li>
<li>STM32H747I-DISCO 또는 M5Stack CoreS3에서 빌드·플래시한다.</li>
<li>USB 카메라로 화면을 촬영한다.</li>
<li>OpenCV 또는 멀티모달 모델로 화면을 검증한다.</li>
<li>실패하면 LangGraph 상태머신이 수정 루프로 되돌아간다.</li>
<li>Docker, pytest, GitHub Actions로 재현 가능한 패키지를 만든다.</li>
</ol>
<p>이 목표는 구현제안서의 결과물인 <strong>타깃 MCU별 LVGL C 소스 프로젝트, 크로스 컴파일 펌웨어 바이너리, UI 에셋 C 배열, Vision-in-the-Loop 검증 리포트 번들</strong>과 직접 연결된다. </p>
<h2 id="aegisedge-기준">AegisEdge 기준</h2>
<p>AegisEdge가 영상분석·엣지 AI 방향이라면 다음을 목표로 잡는다.</p>
<ol>
<li>USB/RTSP 카메라 영상을 받는다.</li>
<li>OpenCV로 전처리한다.</li>
<li>YOLO 또는 ONNX Runtime으로 객체탐지를 수행한다.</li>
<li>이벤트를 JSON으로 구조화한다.</li>
<li>Docker 또는 Jetson 계열 환경에 배포한다.</li>
<li>보안, 로그, API, 관제 대시보드까지 확장 가능한 구조를 만든다.</li>
</ol>
<p>NVIDIA DeepStream은 실시간 스트리밍 분석 SDK로, 비디오·오디오·이미지 이해와 AI 기반 멀티센서 처리를 위한 툴킷으로 설명된다. 따라서 AegisEdge가 CCTV/RTSP/엣지 비전으로 가면 후반부에 들어가는 것이 타당하다. (<a href="https://developer.nvidia.com/deepstream-sdk?utm_source=chatgpt.com" title="NVIDIA DeepStream SDK">NVIDIA Developer</a>)</p>
<hr>
<h1 id="2-공부-시간-기준">2. 공부 시간 기준</h1>
<p>현실적으로는 아래 세 가지 중 하나를 선택해야 한다.</p>
<table>
<thead>
<tr>
<th align="right">주당 시간</th>
<th>2년 후 예상 수준</th>
</tr>
</thead>
<tbody><tr>
<td align="right">주 7~8시간</td>
<td>개념 이해 + 일부 프로토타입 가능. 깊이는 부족할 수 있음</td>
</tr>
<tr>
<td align="right">주 12~15시간</td>
<td>가장 현실적인 기준. EdgeCanvas MVP 가능</td>
</tr>
<tr>
<td align="right">주 20시간 이상</td>
<td>EdgeCanvas + AegisEdge 포트폴리오 + 기술문서까지 가능</td>
</tr>
</tbody></table>
<p>이 커리큘럼은 <strong>주 12~15시간 기준</strong>으로 설계한다.</p>
<p>주간 배분은 이렇게 한다.</p>
<table>
<thead>
<tr>
<th>활동</th>
<th align="right">시간</th>
</tr>
</thead>
<tbody><tr>
<td>교재 읽기</td>
<td align="right">4시간</td>
</tr>
<tr>
<td>공식문서 읽기</td>
<td align="right">2시간</td>
</tr>
<tr>
<td>코딩 실습</td>
<td align="right">5시간</td>
</tr>
<tr>
<td>정리/블로그/README 작성</td>
<td align="right">1시간</td>
</tr>
<tr>
<td>복습/문제풀이</td>
<td align="right">2시간</td>
</tr>
</tbody></table>
<p>매달 산출물이 있어야 한다. 책을 읽는 것만으로는 부족하고, 반드시 <strong>동작하는 코드, 회로/보드 실험, README, 테스트 결과</strong>를 남겨야 한다.</p>
<hr>
<h1 id="3-전체-난이도-맵">3. 전체 난이도 맵</h1>
<h2 id="기초-단계에서-피해야-할-것">기초 단계에서 피해야 할 것</h2>
<p>처음 6개월 동안은 아래를 깊게 파지 않는다.</p>
<ul>
<li>강화학습</li>
<li>휴머노이드</li>
<li>SLAM</li>
<li>ROS2 Nav2</li>
<li>Mobile ALOHA</li>
<li>복잡한 LLM 논문</li>
<li>멀티에이전트 프레임워크 난립</li>
</ul>
<p>이유는 명확하다. EdgeCanvas의 첫 병목은 <strong>AI 이론</strong>이 아니라 <strong>리눅스, C, 메모리, 빌드, 임베디드, LVGL, OpenCV 검증</strong>이다. 이전 정리 문서에서도 EdgeCanvas를 제대로 이해하려면 C와 메모리, 컴퓨터구조, 임베디드 시스템, LVGL/HMI, OpenCV 기반 화면 검증, LangGraph 상태머신이 핵심이라고 정리했다. </p>
<hr>
<h1 id="4-16개월-기초-단계">4. 1~6개월: 기초 단계</h1>
<h2 id="목표">목표</h2>
<p>이 단계의 목적은 “프로그래밍을 해봤다”가 아니라 <strong>시스템이 어떻게 돌아가는지 밑바닥 감각을 만드는 것</strong>이다.</p>
<p>6개월이 끝나면 다음을 할 수 있어야 한다.</p>
<ul>
<li>리눅스 터미널에서 개발환경을 구축한다.</li>
<li>Git으로 버전관리한다.</li>
<li>Python으로 CLI 도구를 만든다.</li>
<li>C로 포인터, 구조체, 파일 입출력, 메모리 개념을 이해한다.</li>
<li>자료구조를 직접 구현한다.</li>
<li>컴퓨터구조와 운영체제 기본 용어를 설명한다.</li>
<li>간단한 상태머신을 구현한다.</li>
</ul>
<hr>
<h2 id="1개월차-리눅스--git--개발환경">1개월차: 리눅스 / Git / 개발환경</h2>
<h3 id="공부할-것">공부할 것</h3>
<ul>
<li>리눅스 파일 시스템</li>
<li>터미널 명령어</li>
<li>Bash</li>
<li>권한</li>
<li>환경변수</li>
<li>프로세스</li>
<li>패키지 설치</li>
<li>Git commit / branch / merge</li>
<li>SSH</li>
<li>VS Code 또는 Cursor 개발환경</li>
</ul>
<h3 id="교재">교재</h3>
<ol>
<li>《리눅스 커맨드라인 완벽 입문서》</li>
<li>Pro Git 한국어 공식 문서</li>
</ol>
<p>《리눅스 커맨드라인 완벽 입문서》는 초보 리눅스 사용자를 위한 책으로, 파일·디렉터리·심볼릭 링크 생성과 삭제 등 커맨드라인 기본을 다룬다. (<a href="https://product.kyobobook.co.kr/detail/S000001556077?utm_source=chatgpt.com" title="리눅스 커맨드라인 완벽 입문서 | 윌리엄 E. 샤츠 주니어 - 교보문고">Kyobo Bookstore</a>) Git은 공식 사이트에서 Pro Git 한국어판을 제공하므로 책을 별도로 사지 않아도 된다. </p>
<h3 id="공식문서">공식문서</h3>
<ul>
<li>Git 공식 문서</li>
<li>Ubuntu 공식 문서</li>
<li>Docker 설치 문서, 단 개념만</li>
</ul>
<h3 id="실습-산출물">실습 산출물</h3>
<pre><code class="language-text">edgecanvas-lab/
  README.md
  scripts/
    setup_env.sh
    hello.sh
  notes/
    linux_commands.md
    git_workflow.md</code></pre>
<h3 id="통과-기준">통과 기준</h3>
<ul>
<li><code>git init</code>, <code>commit</code>, <code>branch</code>, <code>merge</code>를 설명할 수 있다.</li>
<li><code>.env</code> 파일과 환경변수 차이를 설명할 수 있다.</li>
<li>Bash 스크립트로 Python 가상환경을 만든다.</li>
<li><code>/dev/ttyUSB0</code>, <code>/dev/video0</code> 같은 장치 파일 개념을 이해한다.</li>
</ul>
<hr>
<h2 id="2개월차-python-기초--자동화">2개월차: Python 기초 + 자동화</h2>
<h3 id="공부할-것-1">공부할 것</h3>
<ul>
<li>함수</li>
<li>클래스</li>
<li>모듈</li>
<li>가상환경</li>
<li>pip</li>
<li>파일 입출력</li>
<li>JSON</li>
<li>argparse 또는 Typer</li>
<li>subprocess</li>
<li>예외 처리</li>
<li>logging</li>
<li>pytest 기초</li>
</ul>
<h3 id="교재-1">교재</h3>
<ol>
<li>《혼자 공부하는 파이썬》</li>
</ol>
<p>이 책은 독학으로 Python을 처음 배우는 사람이 필요한 내용을 체계적으로 학습하도록 구성된 입문서로 소개된다. 개정판은 혼공 계획표, 누적 예제, 도전 문제를 포함한다. (<a href="https://m.hanbit.co.kr/store/books/book_view.html?p_code=B1681646737&amp;utm_source=chatgpt.com" title="혼자 공부하는파이썬(개정판) - 한빛미디어">한빛+</a>)</p>
<h3 id="공식문서-1">공식문서</h3>
<ul>
<li>Python 공식 튜토리얼</li>
<li>pytest getting started</li>
<li>Typer 문서</li>
<li>Pydantic 문서는 아직 맛보기만</li>
</ul>
<h3 id="실습-산출물-1">실습 산출물</h3>
<pre><code class="language-text">edgecanvas-cli/
  edgecanvas_cli/
    main.py
    config.py
    logger.py
  tests/
    test_config.py
  data/
    sample_ui_request.json</code></pre>
<p>기능:</p>
<pre><code class="language-bash">edgecanvas parse-request sample_ui_request.json
edgecanvas show-config
edgecanvas run-command &quot;gcc --version&quot;</code></pre>
<h3 id="통과-기준-1">통과 기준</h3>
<ul>
<li>JSON 파일을 읽고 검증한다.</li>
<li>subprocess로 외부 명령어를 실행하고 로그를 남긴다.</li>
<li>pytest로 최소 10개 테스트를 만든다.</li>
</ul>
<hr>
<h2 id="3개월차-c-언어--메모리">3개월차: C 언어 / 메모리</h2>
<h3 id="공부할-것-2">공부할 것</h3>
<ul>
<li>포인터</li>
<li>배열</li>
<li>문자열</li>
<li>구조체</li>
<li>헤더 파일</li>
<li>전처리기</li>
<li>static / extern</li>
<li>bit operation</li>
<li>stack / heap</li>
<li>volatile 개념</li>
<li>메모리 맵 사고방식</li>
</ul>
<h3 id="교재-2">교재</h3>
<ol>
<li>《윤성우의 열혈 C 프로그래밍》</li>
</ol>
<p>이 책은 C 언어 기본서로 오래 사용되어 온 책이고, 배열·포인터·구조체·매크로 같은 C 입문 핵심을 다룬다. (<a href="https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=8016119&amp;srsltid=AfmBOop1WyIeXLe-yJxgI8pLxjnhCtJCyvQLQZZQfwP9vDVAQo9cV6IF&amp;utm_source=chatgpt.com" title="윤성우의 열혈 C 프로그래밍">Aladin</a>)</p>
<h3 id="보조-자료">보조 자료</h3>
<ul>
<li>C 언어 레퍼런스</li>
<li>GCC warning 옵션 문서</li>
</ul>
<h3 id="실습-산출물-2">실습 산출물</h3>
<pre><code class="language-text">c-lab/
  pointer_lab.c
  struct_lab.c
  bitfield_lab.c
  json_like_parser.c
  Makefile</code></pre>
<h3 id="통과-기준-2">통과 기준</h3>
<ul>
<li>포인터와 배열의 차이를 설명한다.</li>
<li>구조체 배열을 만든다.</li>
<li>비트 연산으로 레지스터 플래그처럼 값을 설정한다.</li>
<li><code>gcc -Wall -Wextra</code> 경고를 읽고 수정한다.</li>
</ul>
<hr>
<h2 id="4개월차-자료구조--알고리즘-기초">4개월차: 자료구조 / 알고리즘 기초</h2>
<h3 id="공부할-것-3">공부할 것</h3>
<ul>
<li>배열</li>
<li>연결 리스트</li>
<li>스택</li>
<li>큐</li>
<li>해시 테이블</li>
<li>트리</li>
<li>그래프</li>
<li>정렬</li>
<li>검색</li>
<li>BFS / DFS</li>
<li>시간복잡도</li>
<li>공간복잡도</li>
</ul>
<h3 id="교재-3">교재</h3>
<ol>
<li>《C로 배우는 쉬운 자료구조 4판》</li>
<li>보조: 《알고리즘 도감》</li>
</ol>
<p>《C로 배우는 쉬운 자료구조 4판》은 자료구조 원리와 구현 방법을 C 프로그램으로 차근차근 구현하도록 구성되어 있다. (<a href="https://m.hanbit.co.kr/store/books/book_view.html?p_code=B3006151946&amp;utm_source=chatgpt.com" title="IT CookBook, C로 배우는 쉬운 자료구조(4판)">한빛+</a>)</p>
<h3 id="edgecanvas-연결">EdgeCanvas 연결</h3>
<ul>
<li>LVGL UI는 위젯 트리다.</li>
<li>LangGraph는 상태 그래프다.</li>
<li>빌드·검증 루프는 큐와 상태 전이를 가진다.</li>
<li>데이터시트 추출 결과는 JSON 트리다.</li>
</ul>
<h3 id="실습-산출물-3">실습 산출물</h3>
<pre><code class="language-text">ds-lab/
  stack.c
  queue.c
  tree_widget.c
  graph_state_machine.c</code></pre>
<p><code>graph_state_machine.c</code>는 다음 상태를 가져야 한다.</p>
<pre><code class="language-text">PARSE_DOC
→ EXTRACT_SCHEMA
→ GENERATE_CODE
→ BUILD
→ FLASH
→ VERIFY
→ FIX_OR_DONE</code></pre>
<h3 id="통과-기준-3">통과 기준</h3>
<ul>
<li>트리와 그래프 차이를 설명한다.</li>
<li>DFS/BFS를 직접 구현한다.</li>
<li>간단한 상태머신을 C 또는 Python으로 구현한다.</li>
</ul>
<hr>
<h2 id="5개월차-컴퓨터구조">5개월차: 컴퓨터구조</h2>
<h3 id="공부할-것-4">공부할 것</h3>
<ul>
<li>CPU</li>
<li>레지스터</li>
<li>명령어</li>
<li>메모리 계층</li>
<li>캐시</li>
<li>버스</li>
<li>인터럽트</li>
<li>DMA</li>
<li>memory-mapped I/O</li>
<li>endian</li>
<li>stack frame</li>
<li>startup code</li>
<li>linker 개념</li>
</ul>
<h3 id="교재-4">교재</h3>
<ol>
<li>《컴퓨터 구조 및 설계 ARM》</li>
<li>보조: STM32H747I-DISCO User Manual 일부</li>
</ol>
<p>Patterson &amp; Hennessy의 《컴퓨터 구조 및 설계》는 하드웨어와 소프트웨어 사이의 상호작용을 이해하기 위한 대표적인 컴퓨터구조 교재이며, ARM 번역판도 확인된다. (<a href="https://www.yes24.com/product/goods/102716854?utm_source=chatgpt.com" title="컴퓨터 구조 및 설계 | David A. Patterson | 한티에듀">Yes24</a>)</p>
<h3 id="edgecanvas-연결-1">EdgeCanvas 연결</h3>
<p>EdgeCanvas는 MCU 데이터시트를 읽어야 한다. 따라서 레지스터, 메모리 맵, 인터럽트, DMA, 버스 개념을 모르면 데이터시트 기반 코드 생성이 껍데기만 된다.</p>
<h3 id="실습-산출물-4">실습 산출물</h3>
<pre><code class="language-text">architecture-notes/
  memory_map.md
  interrupt.md
  stack_heap.md
  stm32h747_memory_summary.md</code></pre>
<h3 id="통과-기준-4">통과 기준</h3>
<ul>
<li>RAM, Flash, Register, Peripheral, Memory-mapped I/O 차이를 설명한다.</li>
<li>MCU 데이터시트에서 메모리 맵 표를 보고 의미를 설명한다.</li>
<li>stack overflow와 heap fragmentation 개념을 설명한다.</li>
</ul>
<hr>
<h2 id="6개월차-운영체제--이산수학-입문">6개월차: 운영체제 + 이산수학 입문</h2>
<h3 id="공부할-것-5">공부할 것</h3>
<p>운영체제:</p>
<ul>
<li>프로세스</li>
<li>스레드</li>
<li>파일 시스템</li>
<li>장치 파일</li>
<li>권한</li>
<li>system call</li>
<li>I/O</li>
<li>동기화</li>
</ul>
<p>이산수학:</p>
<ul>
<li>명제논리</li>
<li>집합</li>
<li>관계</li>
<li>함수</li>
<li>그래프</li>
<li>트리</li>
<li>귀납법</li>
<li>상태기계</li>
</ul>
<h3 id="교재-5">교재</h3>
<ol>
<li>《쉽게 배우는 운영체제 3판》</li>
<li>《Rosen의 이산수학》</li>
</ol>
<p>《쉽게 배우는 운영체제 3판》은 운영체제의 기본 구조와 핵심 원리를 배우고자 하는 IT학과 학생을 대상으로 한다. (<a href="https://product.kyobobook.co.kr/detail/S000217098802?utm_source=chatgpt.com" title="쉽게 배우는 운영체제 | 조성호 - 국내도서 - 교보문고">Kyobo Bookstore</a>) 《Rosen의 이산수학》은 이산수학의 표준 교재 계열로 국내 판매 정보가 확인된다. (<a href="https://www.yes24.com/product/goods/78519939?utm_source=chatgpt.com" title="Rosen의 이산수학 | 케네스.H.로젠 | 한국맥그로힐(McGraw- ...">Yes24</a>)</p>
<h3 id="실습-산출물-5">실습 산출물</h3>
<pre><code class="language-text">os-discrete-lab/
  process_demo.py
  thread_demo.py
  file_permission_notes.md
  finite_state_machine.py
  graph_validation.py</code></pre>
<h3 id="통과-기준-5">통과 기준</h3>
<ul>
<li>프로세스와 스레드 차이를 설명한다.</li>
<li>파일 권한 오류를 해결할 수 있다.</li>
<li>LangGraph 같은 상태 그래프를 수학적으로 “상태와 전이”로 설명할 수 있다.</li>
</ul>
<hr>
<h1 id="5-712개월-기본-단계">5. 7~12개월: 기본 단계</h1>
<h2 id="목표-1">목표</h2>
<p>이 단계는 <strong>EdgeCanvas의 물리 세계 기반</strong>을 만드는 단계다.</p>
<p>12개월차가 끝나면 다음이 되어야 한다.</p>
<ul>
<li>STM32와 ESP32 계열 개발환경을 구축한다.</li>
<li>보드에 예제를 빌드·플래시한다.</li>
<li>LVGL 화면을 띄운다.</li>
<li>OpenCV로 USB 카메라 화면을 읽는다.</li>
<li>LCD 화면 검증기를 만든다.</li>
<li>Docker/pytest 기반으로 실험을 재현한다.</li>
</ul>
<hr>
<h2 id="7개월차-디지털논리--전자회로-기초">7개월차: 디지털논리 / 전자회로 기초</h2>
<h3 id="공부할-것-6">공부할 것</h3>
<ul>
<li>0/1 전압 레벨</li>
<li>논리게이트</li>
<li>플립플롭</li>
<li>레지스터</li>
<li>클럭</li>
<li>setup/hold time</li>
<li>pull-up / pull-down</li>
<li>GPIO</li>
<li>I2C</li>
<li>SPI</li>
<li>UART</li>
<li>PWM</li>
<li>ADC</li>
<li>전원/그라운드</li>
</ul>
<h3 id="교재-6">교재</h3>
<ol>
<li>《Floyd의 디지털 논리회로》</li>
<li>보조: 《마이크로전자회로》는 필요한 부분만</li>
</ol>
<h3 id="실습-산출물-6">실습 산출물</h3>
<pre><code class="language-text">electronics-notes/
  gpio.md
  uart.md
  spi_i2c.md
  clock_timing.md</code></pre>
<h3 id="통과-기준-6">통과 기준</h3>
<ul>
<li>GPIO 입력/출력 차이를 설명한다.</li>
<li>I2C, SPI, UART 차이를 설명한다.</li>
<li>왜 LCD와 Touch가 서로 다른 버스를 쓸 수 있는지 설명한다.</li>
</ul>
<hr>
<h2 id="8개월차-임베디드-시스템-개론">8개월차: 임베디드 시스템 개론</h2>
<h3 id="공부할-것-7">공부할 것</h3>
<ul>
<li>MCU</li>
<li>HAL</li>
<li>BSP</li>
<li>RTOS 기초</li>
<li>인터럽트</li>
<li>타이머</li>
<li>DMA</li>
<li>UART 로그</li>
<li>Flash / RAM</li>
<li>부트로더</li>
<li>linker script 개념</li>
</ul>
<h3 id="교재-7">교재</h3>
<ol>
<li>《임베디드 엔지니어 교과서》</li>
<li>《임종수의 STM32 Cortex-M 완벽 활용서 Vol.1》 시작</li>
</ol>
<p>《임베디드 엔지니어 교과서》는 하드웨어·소프트웨어 지식, 임베디드 프로그램 개요, 실시간 운영체제, 임베디드 소프트웨어 개발 프로세스 등을 다룬다고 소개된다. (<a href="https://books.google.com/books/about/%EC%9E%84%EB%B2%A0%EB%94%94%EB%93%9C_%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4_%EA%B5%90%EA%B3%BC%EC%84%9C.html?id=66F2EAAAQBAJ&amp;utm_source=chatgpt.com" title="인공지능 시대가 요구하는 임베디드 시스템 개발자의 핵심 스킬">Google Books</a>) 《임종수의 STM32 Cortex-M 완벽 활용서 Vol.1》은 STM32 MCU 소개, CubeIDE/CubeMX/IAR/Keil 설치, GPIO 사용 등을 다루는 책으로 확인된다. (<a href="https://product.kyobobook.co.kr/detail/S000214834114?utm_source=chatgpt.com" title="임종수의 STM32 Cortex-M 완벽 활용서 Vol. 1 - 국내도서">Kyobo Bookstore</a>)</p>
<h3 id="공식문서-2">공식문서</h3>
<ul>
<li>STM32H747I-DISCO 제품 페이지</li>
<li>STM32H747I-DISCO User Manual</li>
<li>STM32CubeH7 예제</li>
</ul>
<p>STM32H747I-DISCO는 STM32H747XIH6 마이크로컨트롤러 기반의 데모·개발 플랫폼이다. (<a href="https://www.st.com/en/evaluation-tools/stm32h747i-disco.html?utm_source=chatgpt.com" title="STM32H747I-DISCO | Product">STMicroelectronics</a>) ST의 User Manual은 보드가 STM32H747XIH6를 중심으로 설계되어 있고 주변 컴포넌트 연결 구조를 설명한다. (<a href="https://www.st.com/resource/en/user_manual/um2411-discovery-kit-with-stm32h747xi-mcu-stmicroelectronics.pdf?utm_source=chatgpt.com" title="Discovery kit with STM32H747XI MCU - User manual">STMicroelectronics</a>)</p>
<h3 id="실습-산출물-7">실습 산출물</h3>
<pre><code class="language-text">stm32-lab/
  gpio_blink/
  uart_log/
  timer_interrupt/
  notes/
    board_profile_stm32h747i_disco.md</code></pre>
<h3 id="통과-기준-7">통과 기준</h3>
<ul>
<li>LED blink를 직접 빌드·플래시한다.</li>
<li>UART 로그를 출력한다.</li>
<li>STM32 보드 프로필 문서를 작성한다.</li>
</ul>
<hr>
<h2 id="9개월차-esp32-s3--m5stack-cores3">9개월차: ESP32-S3 / M5Stack CoreS3</h2>
<h3 id="공부할-것-8">공부할 것</h3>
<ul>
<li>ESP-IDF 설치</li>
<li>menuconfig</li>
<li>build / flash / monitor</li>
<li>ESP32-S3 구조</li>
<li>M5Stack CoreS3 LCD / Touch / Camera</li>
<li>USB-C 플래시</li>
<li>PSRAM / Flash</li>
</ul>
<h3 id="공식문서-3">공식문서</h3>
<ul>
<li>M5Stack CoreS3 공식문서</li>
<li>ESP-IDF Programming Guide</li>
</ul>
<p>M5Stack CoreS3는 ESP32-S3 기반 장치이며 16MB Flash, 8MB PSRAM, USB Type-C 다운로드/플래시를 지원한다고 설명된다. (<a href="https://docs.m5stack.com/en/core/CoreS3?ref=blakadder&amp;sub_id=undefined&amp;utm_source=chatgpt.com" title="CoreS3 - m5-docs - M5Stack">M5Stack Docs</a>) ESP-IDF는 Espressif의 ESP32/ESP32-S/ESP32-C/ESP32-H/ESP32-P 계열 SoC용 공식 개발 프레임워크이며, 공식 가이드는 환경 설정, menuconfig, build, flash 과정을 안내한다. (<a href="https://docs.espressif.com/projects/esp-idf/en/stable/esp32/index.html?utm_source=chatgpt.com" title="ESP-IDF Programming Guide - ESP32">Espressif Systems</a>)</p>
<h3 id="실습-산출물-8">실습 산출물</h3>
<pre><code class="language-text">m5stack-cores3-lab/
  hello_world/
  lcd_test/
  camera_test/
  board_profile_m5stack_cores3.json</code></pre>
<h3 id="통과-기준-8">통과 기준</h3>
<ul>
<li>ESP-IDF hello_world를 빌드·플래시한다.</li>
<li>M5Stack CoreS3의 LCD 또는 기본 디스플레이 예제를 실행한다.</li>
<li>STM32와 M5Stack의 차이를 보드 프로필로 정리한다.</li>
</ul>
<hr>
<h2 id="10개월차-lvgl-기본">10개월차: LVGL 기본</h2>
<h3 id="공부할-것-9">공부할 것</h3>
<ul>
<li>LVGL object model</li>
<li>screen</li>
<li>label</li>
<li>button</li>
<li>image</li>
<li>style</li>
<li>event</li>
<li>display driver</li>
<li>input device</li>
<li>tick</li>
<li>memory buffer</li>
<li>image converter</li>
</ul>
<h3 id="공식문서-4">공식문서</h3>
<ul>
<li>LVGL 공식 문서</li>
<li>LVGL 포팅 문서</li>
<li>STM32/LVGL 예제</li>
<li>ESP-IDF/LVGL 예제</li>
</ul>
<p>LVGL은 MCU, MPU, 다양한 디스플레이 타입을 대상으로 UI를 만들기 위한 무료 오픈소스 임베디드 그래픽 라이브러리로 설명된다. (<a href="https://lvgl.io/?utm_source=chatgpt.com" title="LVGL — Light and Versatile Embedded UI Ecosystem">LVGL</a>)</p>
<h3 id="실습-산출물-9">실습 산출물</h3>
<pre><code class="language-text">lvgl-lab/
  hello_label/
  button_event/
  image_widget/
  ui_schema/
    simple_dashboard.json
  generated/
    simple_dashboard.c</code></pre>
<h3 id="통과-기준-9">통과 기준</h3>
<ul>
<li>버튼 클릭 이벤트를 구현한다.</li>
<li>JSON UI 스키마를 설계한다.</li>
<li>JSON을 읽어 LVGL C 코드 일부를 자동 생성한다.</li>
</ul>
<hr>
<h2 id="11개월차-빌드-시스템--cmake--컴파일--링크">11개월차: 빌드 시스템 / CMake / 컴파일 / 링크</h2>
<h3 id="공부할-것-10">공부할 것</h3>
<ul>
<li>Makefile</li>
<li>CMake</li>
<li>gcc</li>
<li>cross compile</li>
<li>object file</li>
<li>static library</li>
<li>include path</li>
<li>linker script</li>
<li>map file</li>
<li>compile error</li>
<li>link error</li>
<li>binary flashing</li>
</ul>
<h3 id="공식문서-5">공식문서</h3>
<ul>
<li>CMake 튜토리얼</li>
<li>Arm GNU Toolchain</li>
<li>OpenOCD</li>
<li>ST-LINK</li>
<li>ESP-IDF build system</li>
</ul>
<p>EdgeCanvas 문서에서도 CMake, Make, arm-none-eabi-gcc, ESP-IDF, ST-Link, OpenOCD, pyserial이 기술스택으로 들어 있다. </p>
<h3 id="실습-산출물-10">실습 산출물</h3>
<pre><code class="language-text">build-lab/
  makefile_project/
  cmake_project/
  gcc_error_parser.py
  flash_stm32.sh
  flash_esp32.sh</code></pre>
<h3 id="통과-기준-10">통과 기준</h3>
<ul>
<li>컴파일 에러와 링크 에러를 구분한다.</li>
<li>빌드 로그에서 에러 파일명/라인/원인을 추출한다.</li>
<li>Python에서 빌드 명령을 실행하고 결과 JSON을 생성한다.</li>
</ul>
<hr>
<h2 id="12개월차-opencv-기반-vision-in-the-loop-기초">12개월차: OpenCV 기반 Vision-in-the-Loop 기초</h2>
<h3 id="공부할-것-11">공부할 것</h3>
<ul>
<li>이미지 배열</li>
<li>RGB/BGR</li>
<li>좌표계</li>
<li>VideoCapture</li>
<li>threshold</li>
<li>contour</li>
<li>template matching</li>
<li>color histogram</li>
<li>OCR은 보조</li>
<li>PASS/FAIL 판정</li>
</ul>
<h3 id="교재-8">교재</h3>
<ol>
<li>《OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝》</li>
</ol>
<p>이 책은 OpenCV로 밝기·명암비 조절, 필터링, 에지 검출, 객체 검출, 영상 매칭, 필기체 숫자 인식까지 다루는 책으로 확인된다. (<a href="https://product.kyobobook.co.kr/detail/S000001792829?utm_source=chatgpt.com" title="OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝 | 황선규">Kyobo Bookstore</a>) 저자 페이지에서도 OpenCV를 이용해 컴퓨터비전과 머신러닝 알고리즘을 구현하는 방법을 설명한다고 소개한다. (<a href="https://sunkyoo.github.io/opencv4cvml/?utm_source=chatgpt.com" title="『OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝』">Sunkyoo Hwang</a>)</p>
<h3 id="공식문서-6">공식문서</h3>
<ul>
<li>OpenCV 공식 문서</li>
<li>OpenCV GitHub / docs</li>
</ul>
<p>OpenCV는 오픈소스 컴퓨터비전 라이브러리이며 C++, Python 등의 API와 문서·테스트를 제공한다. (<a href="https://github.com/opencv/opencv?utm_source=chatgpt.com" title="OpenCV: Open Source Computer Vision Library">GitHub</a>)</p>
<h3 id="실습-산출물-11">실습 산출물</h3>
<pre><code class="language-text">vision-loop-lab/
  capture_camera.py
  detect_lcd_region.py
  compare_color.py
  compare_layout.py
  report.json</code></pre>
<h3 id="통과-기준-11">통과 기준</h3>
<ul>
<li>USB 카메라에서 프레임을 받는다.</li>
<li>LCD 영역을 잘라낸다.</li>
<li>기준 이미지와 실제 이미지를 비교한다.</li>
<li>PASS/FAIL 리포트를 JSON으로 만든다.</li>
</ul>
<hr>
<h1 id="6-1318개월-심화-단계">6. 13~18개월: 심화 단계</h1>
<h2 id="목표-2">목표</h2>
<p>이제부터는 “보드 실습”을 넘어 <strong>AI Agent 시스템</strong>으로 들어간다.</p>
<p>18개월차가 끝나면 다음이 가능해야 한다.</p>
<ul>
<li>머신러닝/딥러닝의 기본 원리를 설명한다.</li>
<li>문서 파싱과 정보 추출을 API로 수행한다.</li>
<li>RAG와 structured output을 구현한다.</li>
<li>LangGraph 상태머신을 만든다.</li>
<li>빌드 실패와 Vision 실패를 수정 루프로 연결한다.</li>
<li>API 키, Docker, 네트워크, 보안을 고려한다.</li>
</ul>
<hr>
<h2 id="13개월차-선형대수--확률통계">13개월차: 선형대수 / 확률통계</h2>
<h3 id="공부할-것-12">공부할 것</h3>
<p>선형대수:</p>
<ul>
<li>벡터</li>
<li>행렬</li>
<li>행렬곱</li>
<li>역행렬</li>
<li>고유값</li>
<li>SVD 맛보기</li>
<li>좌표 변환</li>
<li>최소제곱</li>
</ul>
<p>확률통계:</p>
<ul>
<li>확률변수</li>
<li>조건부확률</li>
<li>베이즈 정리</li>
<li>기댓값</li>
<li>분산</li>
<li>정규분포</li>
<li>신뢰구간</li>
<li>precision / recall</li>
<li>confusion matrix</li>
</ul>
<h3 id="교재-9">교재</h3>
<ol>
<li>《스트랭 선형대수학》</li>
<li>《이공계용 확률과 통계》</li>
</ol>
<p>《스트랭 선형대수학》은 Gilbert Strang 교수의 MIT 선형대수학 강의를 기반으로 구성된 6판 번역서로 확인된다. (<a href="https://product.kyobobook.co.kr/detail/S000218797301?utm_source=chatgpt.com" title="스트랭 선형대수학 | Gilbert Strang">Kyobo Bookstore</a>) 《이공계용 확률과 통계》는 Sheldon M. Ross의 공학·과학 계열 확률통계 교재로 확인된다. (<a href="https://product.kyobobook.co.kr/detail/S000061694934?utm_source=chatgpt.com" title="이공계용 확률과 통계 | Sheldon M. Ross - 국내도서 - 교보문고">Kyobo Bookstore</a>)</p>
<h3 id="edgecanvas-연결-2">EdgeCanvas 연결</h3>
<ul>
<li>Vision 판정 일치율</li>
<li>색상/위치 오차</li>
<li>threshold 설정</li>
<li>평가 지표</li>
<li>센서 노이즈</li>
<li>AegisEdge 객체탐지 평가</li>
</ul>
<h3 id="실습-산출물-12">실습 산출물</h3>
<pre><code class="language-text">math-for-vision/
  matrix_transform.ipynb
  confusion_matrix.py
  pass_fail_statistics.py</code></pre>
<h3 id="통과-기준-12">통과 기준</h3>
<ul>
<li>검증 결과 100개를 가지고 정확도, 정밀도, 재현율을 계산한다.</li>
<li>화면 위치 오차를 픽셀 단위로 계산한다.</li>
</ul>
<hr>
<h2 id="14개월차-머신러닝--딥러닝-기초">14개월차: 머신러닝 / 딥러닝 기초</h2>
<h3 id="공부할-것-13">공부할 것</h3>
<ul>
<li>supervised learning</li>
<li>loss</li>
<li>gradient descent</li>
<li>overfitting</li>
<li>train/validation/test</li>
<li>CNN</li>
<li>transformer 개념 맛보기</li>
<li>embedding</li>
<li>inference</li>
<li>evaluation</li>
</ul>
<h3 id="교재-10">교재</h3>
<ol>
<li>《혼자 공부하는 머신러닝+딥러닝》</li>
<li>《밑바닥부터 시작하는 딥러닝 1》</li>
</ol>
<p>《혼자 공부하는 머신러닝+딥러닝》 개정판은 머신러닝과 딥러닝 핵심을 직관적 예제로 설명하고, 트랜스포머와 LLM 실습, PyTorch 예제를 보강했다고 소개된다. (<a href="https://hongong.hanbit.co.kr/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-%EB%94%A5%EB%9F%AC%EB%8B%9D/?utm_source=chatgpt.com" title="혼자 공부하는 머신러닝+딥러닝(개정판) - 혼공학습단">혼자 공부하는 책</a>)</p>
<h3 id="실습-산출물-13">실습 산출물</h3>
<pre><code class="language-text">ml-lab/
  image_classifier.ipynb
  simple_cnn.py
  evaluation_report.md</code></pre>
<h3 id="통과-기준-13">통과 기준</h3>
<ul>
<li>train/validation/test를 구분한다.</li>
<li>overfitting을 설명한다.</li>
<li>작은 이미지 분류 모델을 학습해 본다.</li>
</ul>
<hr>
<h2 id="15개월차-자연어처리--transformer--rag">15개월차: 자연어처리 / Transformer / RAG</h2>
<h3 id="공부할-것-14">공부할 것</h3>
<ul>
<li>token</li>
<li>embedding</li>
<li>attention</li>
<li>transformer</li>
<li>chunking</li>
<li>vector search</li>
<li>RAG</li>
<li>structured output</li>
<li>hallucination</li>
<li>prompt injection 기초</li>
</ul>
<h3 id="교재-11">교재</h3>
<ol>
<li>《밑바닥부터 시작하는 딥러닝 2》</li>
<li>《트랜스포머를 활용한 자연어 처리》</li>
</ol>
<h3 id="edgecanvas-연결-3">EdgeCanvas 연결</h3>
<p>EdgeCanvas의 데이터시트 해석은 결국 문서 이해 문제다. 구현제안서에서도 Document Parse와 Information Extract로 레지스터 맵, 핀맵, 클럭 트리, 타이밍 제약을 JSON 스키마로 추출한다고 되어 있다. </p>
<h3 id="실습-산출물-14">실습 산출물</h3>
<pre><code class="language-text">rag-lab/
  chunk_datasheet.py
  extract_schema.py
  schema_validator.py
  retrieval_demo.py</code></pre>
<h3 id="통과-기준-14">통과 기준</h3>
<ul>
<li>PDF/Markdown 문서를 chunk로 나눈다.</li>
<li>검색 결과를 근거로 JSON을 만든다.</li>
<li>추출된 JSON을 Pydantic으로 검증한다.</li>
</ul>
<hr>
<h2 id="16개월차-upstage-document-ai--solar-pro-3-api">16개월차: Upstage Document AI / Solar Pro 3 API</h2>
<h3 id="공부할-것-15">공부할 것</h3>
<ul>
<li>Document Parse</li>
<li>Information Extract</li>
<li>JSON schema extraction</li>
<li>API authentication</li>
<li>rate limit</li>
<li>retry</li>
<li>error handling</li>
<li>prompt template</li>
<li>structured output</li>
</ul>
<h3 id="공식문서-7">공식문서</h3>
<ul>
<li>Upstage Document Parse</li>
<li>Upstage Information Extract</li>
<li>Solar Pro 3 관련 문서</li>
</ul>
<p>Upstage Document Parse는 PDF, 스캔 이미지, 복잡한 차트 등을 LLM이 처리하기 쉬운 HTML/Markdown 같은 구조화 형식으로 변환하는 제품으로 설명된다. (<a href="https://www.upstage.ai/products/document-parse?utm_source=chatgpt.com" title="Upstage Document Parse">upstage.ai</a>) Information Extract는 다양한 문서에서 구조화 데이터를 추출하는 기능으로 설명된다. (<a href="https://www.upstage.ai/products/information-extract?utm_source=chatgpt.com" title="Upstage Information Extract">upstage.ai</a>) Solar Pro 3는 Upstage Console에서 API로 사용할 수 있다고 Upstage 블로그에서 설명한다. (<a href="https://www.upstage.ai/blog/en/solar-pro-3-0127?utm_source=chatgpt.com" title="Solar Pro 3: Better reasoning at production scale">upstage.ai</a>)</p>
<h3 id="실습-산출물-15">실습 산출물</h3>
<pre><code class="language-text">document-ai-lab/
  parse_datasheet.py
  extract_mcu_schema.py
  schemas/
    mcu_schema.json
    lvgl_constraints.json
  outputs/
    stm32_sample_extraction.json</code></pre>
<h3 id="통과-기준-15">통과 기준</h3>
<ul>
<li>데이터시트 1개에서 최소 10개 필드를 추출한다.</li>
<li>추출 실패와 누락 필드를 기록한다.</li>
<li>사람이 검토한 정답 JSON과 비교한다.</li>
</ul>
<hr>
<h2 id="17개월차-langgraph-agent--상태머신">17개월차: LangGraph Agent / 상태머신</h2>
<h3 id="공부할-것-16">공부할 것</h3>
<ul>
<li>StateGraph</li>
<li>node</li>
<li>edge</li>
<li>conditional edge</li>
<li>retry loop</li>
<li>checkpoint</li>
<li>tool calling</li>
<li>human-in-the-loop</li>
<li>evaluator</li>
<li>self-healing</li>
</ul>
<h3 id="교재-12">교재</h3>
<ol>
<li>《LangGraph로 만드는 AI 에이전트 서비스》</li>
<li>《혼자서도 척척 해내는 AI 에이전트 만들기 with 랭체인 &amp; 랭그래프》</li>
</ol>
<h3 id="공식문서-8">공식문서</h3>
<ul>
<li>LangGraph 공식문서</li>
<li>LangChain tools 문서</li>
<li>Pydantic 문서</li>
</ul>
<p>LangGraph는 장기 실행되는 stateful workflow 또는 agent를 위한 저수준 인프라를 제공한다고 공식 문서에 설명되어 있다. (<a href="https://docs.langchain.com/oss/python/langgraph/overview?utm_source=chatgpt.com" title="LangGraph overview - Docs by LangChain">LangChain Docs</a>) LangGraph는 long-running, stateful agent를 구축·관리·배포하기 위한 low-level orchestration framework로도 설명된다. (<a href="https://github.com/langchain-ai/langgraph?utm_source=chatgpt.com" title="langchain-ai/langgraph: Build resilient agents.">GitHub</a>)</p>
<h3 id="실습-산출물-16">실습 산출물</h3>
<pre><code class="language-text">edgecanvas-agent/
  graph.py
  nodes/
    parse_datasheet.py
    extract_schema.py
    generate_lvgl.py
    build_firmware.py
    flash_device.py
    verify_screen.py
    fix_code.py
  state.py
  tests/</code></pre>
<h3 id="통과-기준-16">통과 기준</h3>
<p>다음 루프가 mock으로라도 돌아가야 한다.</p>
<pre><code class="language-text">parse_datasheet
→ extract_schema
→ generate_lvgl
→ build_firmware
→ verify_screen
→ if failed: fix_code
→ if passed: report</code></pre>
<hr>
<h2 id="18개월차-네트워크--http--docker--보안-기초">18개월차: 네트워크 / HTTP / Docker / 보안 기초</h2>
<h3 id="공부할-것-17">공부할 것</h3>
<p>네트워크:</p>
<ul>
<li>TCP/IP</li>
<li>DNS</li>
<li>HTTP</li>
<li>REST API</li>
<li>TLS</li>
<li>WebSocket</li>
<li>RTSP 맛보기</li>
<li>timeout</li>
<li>retry</li>
<li>rate limit</li>
</ul>
<p>Docker:</p>
<ul>
<li>image</li>
<li>container</li>
<li>volume</li>
<li>network</li>
<li>Dockerfile</li>
<li>docker compose</li>
</ul>
<p>보안:</p>
<ul>
<li>API key</li>
<li>환경변수</li>
<li>secret leakage</li>
<li>path traversal</li>
<li>command injection</li>
<li>prompt injection</li>
<li>dependency vulnerability</li>
</ul>
<h3 id="교재-13">교재</h3>
<ol>
<li>《컴퓨터 네트워킹: 하향식 접근》</li>
<li>《HTTP 완벽 가이드》</li>
<li>《도커 교과서》</li>
<li>KISA 시큐어코딩 가이드</li>
</ol>
<p>《컴퓨터 네트워킹: 하향식 접근》은 컴퓨터 네트워킹의 기초와 전반을 학습할 수 있도록 구성된 교재로 확인된다. (<a href="https://product.kyobobook.co.kr/detail/S000061694627?utm_source=chatgpt.com" title="컴퓨터 네트워킹 하향식 접근 | 최종원 - 교보문고">Kyobo Bookstore</a>) Docker 공식 문서는 컨테이너를 이미지의 실행 가능한 인스턴스로 설명하며, Docker API/CLI로 생성·시작·중지·삭제할 수 있다고 설명한다. (<a href="https://docs.docker.com/get-started/docker-overview/?utm_source=chatgpt.com" title="What is Docker?">Docker Documentation</a>)</p>
<h3 id="실습-산출물-17">실습 산출물</h3>
<pre><code class="language-text">deployment-security-lab/
  Dockerfile
  docker-compose.yml
  .env.example
  secure_subprocess.py
  api_client_with_retry.py
  security_checklist.md</code></pre>
<h3 id="통과-기준-17">통과 기준</h3>
<ul>
<li>API key를 코드에 하드코딩하지 않는다.</li>
<li>Docker로 동일한 CLI를 재현 실행한다.</li>
<li>외부 명령 실행 시 allowlist를 적용한다.</li>
</ul>
<hr>
<h1 id="7-1924개월-실전-단계">7. 19~24개월: 실전 단계</h1>
<h2 id="목표-3">목표</h2>
<p>이제 최종 목표는 <strong>EdgeCanvas MVP + AegisEdge 확장 프로토타입 + 기술문서 + 포트폴리오</strong>다.</p>
<p>구현제안서의 구현범위도 세부업무 #1 데이터시트 구조화, #2 하드웨어 제약 기반 HMI 설계 및 다중 타깃 코드 합성, #3 Vision-in-the-Loop 기반 피지컬 구동 검증 및 Self-Healing 폐쇄 루프로 나뉘어 있다. </p>
<hr>
<h2 id="19개월차-edgecanvas-mvp-1--데이터시트-→-json">19개월차: EdgeCanvas MVP 1 — 데이터시트 → JSON</h2>
<h3 id="구현-목표">구현 목표</h3>
<pre><code class="language-text">MCU PDF / Markdown
→ Document Parse
→ Information Extract
→ MCU hardware schema
→ validation report</code></pre>
<h3 id="산출물">산출물</h3>
<pre><code class="language-text">edgecanvas/
  schemas/
    mcu_schema.py
    board_profile.py
  parsers/
    upstage_document_parse.py
    information_extract.py
  examples/
    stm32h747i_disco.json
    m5stack_cores3.json
  reports/
    extraction_report.md</code></pre>
<h3 id="성공-기준">성공 기준</h3>
<ul>
<li>STM32 또는 M5Stack 관련 문서에서 최소 필드를 추출한다.</li>
<li>추출 결과를 사람이 검토할 수 있는 리포트로 만든다.</li>
<li>Pydantic validation을 통과한다.</li>
</ul>
<hr>
<h2 id="20개월차-edgecanvas-mvp-2--json-→-lvgl-c-코드">20개월차: EdgeCanvas MVP 2 — JSON → LVGL C 코드</h2>
<h3 id="구현-목표-1">구현 목표</h3>
<pre><code class="language-text">UI requirement
→ UI schema
→ LVGL widget tree
→ generated C code</code></pre>
<h3 id="산출물-1">산출물</h3>
<pre><code class="language-text">edgecanvas/
  ui_schema/
    widgets.py
    layout.py
  generators/
    lvgl_generator.py
  templates/
    lvgl_screen.c.j2
    lvgl_events.c.j2
  generated/
    dashboard_screen.c</code></pre>
<h3 id="성공-기준-1">성공 기준</h3>
<ul>
<li>label/button/image 최소 3개 위젯을 생성한다.</li>
<li>이벤트 핸들러 코드를 생성한다.</li>
<li>생성 코드는 <code>gcc</code> 또는 타깃 빌드에서 문법 오류 없이 통과한다.</li>
</ul>
<hr>
<h2 id="21개월차-edgecanvas-mvp-3--빌드--플래시-자동화">21개월차: EdgeCanvas MVP 3 — 빌드 / 플래시 자동화</h2>
<h3 id="구현-목표-2">구현 목표</h3>
<pre><code class="language-text">generated C project
→ build
→ binary
→ flash
→ serial log</code></pre>
<h3 id="산출물-2">산출물</h3>
<pre><code class="language-text">edgecanvas/
  builders/
    cmake_builder.py
    espidf_builder.py
  flashers/
    stlink.py
    esptool.py
  logs/
    build_log.json
    flash_log.json</code></pre>
<h3 id="성공-기준-2">성공 기준</h3>
<ul>
<li>빌드 명령을 Python에서 실행한다.</li>
<li>실패 시 에러를 구조화한다.</li>
<li>성공 시 binary 경로를 기록한다.</li>
<li>플래시 명령을 실행하거나 dry-run으로 검증한다.</li>
</ul>
<hr>
<h2 id="22개월차-edgecanvas-mvp-4--vision-in-the-loop">22개월차: EdgeCanvas MVP 4 — Vision-in-the-Loop</h2>
<h3 id="구현-목표-3">구현 목표</h3>
<pre><code class="language-text">camera capture
→ LCD region detection
→ expected UI comparison
→ PASS/FAIL
→ report</code></pre>
<h3 id="산출물-3">산출물</h3>
<pre><code class="language-text">edgecanvas/
  vision/
    capture.py
    lcd_detector.py
    layout_compare.py
    color_compare.py
    report.py
  reports/
    vision_report.html
    vision_report.json</code></pre>
<h3 id="성공-기준-3">성공 기준</h3>
<ul>
<li>화면 검은색/흰색 죽음 상태를 감지한다.</li>
<li>버튼 위치/색상/텍스트 존재 여부를 검증한다.</li>
<li>PASS/FAIL 결과를 JSON과 HTML로 생성한다.</li>
</ul>
<hr>
<h2 id="23개월차-edgecanvas-mvp-5--langgraph-self-healing-통합">23개월차: EdgeCanvas MVP 5 — LangGraph Self-Healing 통합</h2>
<h3 id="구현-목표-4">구현 목표</h3>
<pre><code class="language-text">extract schema
→ generate code
→ build
→ flash
→ verify
→ failed?
   → fix prompt
   → regenerate
   → retry</code></pre>
<h3 id="산출물-4">산출물</h3>
<pre><code class="language-text">edgecanvas/
  graph/
    state.py
    workflow.py
    conditions.py
  evaluators/
    build_evaluator.py
    vision_evaluator.py
  fixers/
    code_fixer.py
    ui_fixer.py</code></pre>
<h3 id="성공-기준-4">성공 기준</h3>
<ul>
<li>빌드 실패 시 코드 수정 루프로 돌아간다.</li>
<li>Vision 실패 시 UI 수정 루프로 돌아간다.</li>
<li>최대 retry 횟수를 제한한다.</li>
<li>모든 step이 로그로 남는다.</li>
</ul>
<p>이 부분은 EdgeCanvas 문서의 “LangGraph 상태머신이 전 계층 전이를 제어하며, 불일치 시 자가 수정 루프를 자율 실행”한다는 구조와 직접 맞닿아 있다. </p>
<hr>
<h2 id="24개월차-최종-통합--aegisedge-프로토타입--포트폴리오">24개월차: 최종 통합 / AegisEdge 프로토타입 / 포트폴리오</h2>
<h3 id="edgecanvas-최종-산출물">EdgeCanvas 최종 산출물</h3>
<pre><code class="language-text">edgecanvas/
  README.md
  docs/
    architecture.md
    board_profile.md
    security.md
    benchmark.md
  examples/
    stm32_demo/
    m5stack_demo/
  docker/
    Dockerfile
  tests/
  reports/</code></pre>
<h3 id="aegisedge-선택-프로토타입">AegisEdge 선택 프로토타입</h3>
<p>AegisEdge가 영상분석 방향이면 다음을 만든다.</p>
<pre><code class="language-text">aegisedge-prototype/
  capture/
    rtsp_or_usb.py
  inference/
    yolo_or_onnx.py
  events/
    event_schema.py
  api/
    server.py
  dashboard/
    simple_viewer.py</code></pre>
<p>AegisEdge가 로봇 방향이면 ROS2는 이때부터 들어간다. 이전 정리 문서에서도 ROS2는 EdgeCanvas 본체 1순위가 아니라, AegisEdge가 로봇과 연결되거나 EdgeCanvas가 서비스 로봇 HMI와 연동될 때 학습하는 후순위 자료로 분리했다. </p>
<h3 id="최종-성공-기준">최종 성공 기준</h3>
<ul>
<li>GitHub README만 보고 설치 가능하다.</li>
<li>Docker로 실행 가능하다.</li>
<li>테스트가 자동 실행된다.</li>
<li>보드 프로필이 2개 이상 있다.</li>
<li>샘플 데이터시트 또는 샘플 JSON이 포함된다.</li>
<li>Vision-in-the-Loop 리포트가 자동 생성된다.</li>
<li>실패 로그와 자가수정 라운드 수가 기록된다.</li>
</ul>
<hr>
<h1 id="8-24개월-월별-전체표">8. 24개월 월별 전체표</h1>
<table>
<thead>
<tr>
<th align="right">월</th>
<th>단계</th>
<th>주제</th>
<th>핵심 교재</th>
<th>공식문서</th>
<th>산출물</th>
</tr>
</thead>
<tbody><tr>
<td align="right">1</td>
<td>기초</td>
<td>리눅스/Git</td>
<td>리눅스 커맨드라인</td>
<td>Git/Ubuntu</td>
<td>개발환경 repo</td>
</tr>
<tr>
<td align="right">2</td>
<td>기초</td>
<td>Python 자동화</td>
<td>혼자 공부하는 파이썬</td>
<td>Python/pytest</td>
<td>CLI 도구</td>
</tr>
<tr>
<td align="right">3</td>
<td>기초</td>
<td>C/메모리</td>
<td>열혈 C</td>
<td>GCC</td>
<td>포인터/구조체 실습</td>
</tr>
<tr>
<td align="right">4</td>
<td>기초</td>
<td>자료구조</td>
<td>C로 배우는 쉬운 자료구조</td>
<td>없음</td>
<td>트리/그래프/상태머신</td>
</tr>
<tr>
<td align="right">5</td>
<td>기초</td>
<td>컴퓨터구조</td>
<td>컴퓨터 구조 및 설계 ARM</td>
<td>STM32 memory map</td>
<td>메모리맵 노트</td>
</tr>
<tr>
<td align="right">6</td>
<td>기초</td>
<td>운영체제/이산수학</td>
<td>쉽게 배우는 운영체제, Rosen</td>
<td>Linux docs</td>
<td>프로세스/상태기계</td>
</tr>
<tr>
<td align="right">7</td>
<td>기본</td>
<td>디지털논리/전자</td>
<td>Floyd</td>
<td>보드 회로도</td>
<td>GPIO/I2C/SPI 노트</td>
</tr>
<tr>
<td align="right">8</td>
<td>기본</td>
<td>STM32/임베디드</td>
<td>임베디드 엔지니어, STM32 책</td>
<td>ST docs</td>
<td>STM32 blink/UART</td>
</tr>
<tr>
<td align="right">9</td>
<td>기본</td>
<td>M5Stack/ESP-IDF</td>
<td>STM32 책 보조</td>
<td>M5Stack/ESP-IDF</td>
<td>M5Stack LCD 예제</td>
</tr>
<tr>
<td align="right">10</td>
<td>기본</td>
<td>LVGL</td>
<td>공식문서 중심</td>
<td>LVGL docs</td>
<td>JSON→LVGL 코드</td>
</tr>
<tr>
<td align="right">11</td>
<td>기본</td>
<td>CMake/빌드/플래시</td>
<td>보조 자료</td>
<td>CMake/OpenOCD</td>
<td>빌드 로그 파서</td>
</tr>
<tr>
<td align="right">12</td>
<td>기본</td>
<td>OpenCV 검증</td>
<td>OpenCV 4 책</td>
<td>OpenCV docs</td>
<td>화면 PASS/FAIL</td>
</tr>
<tr>
<td align="right">13</td>
<td>심화</td>
<td>선형대수/확률</td>
<td>Strang, Ross</td>
<td>없음</td>
<td>평가 지표 계산</td>
</tr>
<tr>
<td align="right">14</td>
<td>심화</td>
<td>ML/DL</td>
<td>혼공 ML/DL</td>
<td>PyTorch/Scikit docs</td>
<td>이미지 분류</td>
</tr>
<tr>
<td align="right">15</td>
<td>심화</td>
<td>NLP/RAG</td>
<td>밑바닥 DL2</td>
<td>Vector DB docs</td>
<td>문서 chunk/RAG</td>
</tr>
<tr>
<td align="right">16</td>
<td>심화</td>
<td>Upstage 문서AI</td>
<td>공식문서 중심</td>
<td>Upstage docs</td>
<td>데이터시트 JSON</td>
</tr>
<tr>
<td align="right">17</td>
<td>심화</td>
<td>LangGraph Agent</td>
<td>LangGraph 교재</td>
<td>LangGraph docs</td>
<td>Agent workflow</td>
</tr>
<tr>
<td align="right">18</td>
<td>심화</td>
<td>네트워크/Docker/보안</td>
<td>네트워킹, 도커</td>
<td>Docker/KISA</td>
<td>안전한 API 클라이언트</td>
</tr>
<tr>
<td align="right">19</td>
<td>실전</td>
<td>EdgeCanvas 파서</td>
<td>이전 전체</td>
<td>Upstage</td>
<td>PDF→Schema</td>
</tr>
<tr>
<td align="right">20</td>
<td>실전</td>
<td>LVGL 코드 생성</td>
<td>이전 전체</td>
<td>LVGL</td>
<td>Schema→C</td>
</tr>
<tr>
<td align="right">21</td>
<td>실전</td>
<td>빌드/플래시</td>
<td>이전 전체</td>
<td>CMake/ST/ESP</td>
<td>자동 빌드/플래시</td>
</tr>
<tr>
<td align="right">22</td>
<td>실전</td>
<td>Vision-in-the-Loop</td>
<td>OpenCV</td>
<td>OpenCV</td>
<td>검증 리포트</td>
</tr>
<tr>
<td align="right">23</td>
<td>실전</td>
<td>Self-Healing</td>
<td>LangGraph</td>
<td>LangGraph</td>
<td>자가수정 루프</td>
</tr>
<tr>
<td align="right">24</td>
<td>실전</td>
<td>통합/포트폴리오</td>
<td>소프트웨어공학</td>
<td>Docker/GitHub</td>
<td>최종 MVP</td>
</tr>
</tbody></table>
<hr>
<h1 id="9-교재-구매-순서">9. 교재 구매 순서</h1>
<h2 id="1차-구매-16개월용">1차 구매: 1~6개월용</h2>
<p>이 10권이 기초 체력이다.</p>
<ol>
<li>《리눅스 커맨드라인 완벽 입문서》</li>
<li>《혼자 공부하는 파이썬》</li>
<li>《윤성우의 열혈 C 프로그래밍》</li>
<li>《C로 배우는 쉬운 자료구조 4판》</li>
<li>《컴퓨터 구조 및 설계 ARM》</li>
<li>《쉽게 배우는 운영체제 3판》</li>
<li>《Rosen의 이산수학》</li>
<li>《Floyd의 디지털 논리회로》</li>
<li>《스트랭 선형대수학》</li>
<li>《이공계용 확률과 통계》</li>
</ol>
<p>이전 정리 문서에서도 현실적인 첫 교재로 리눅스, Python, C, 자료구조, 컴퓨터구조, 운영체제, 이산수학, 선형대수, 임베디드, OpenCV가 제시되어 있다. </p>
<h2 id="2차-구매-712개월용">2차 구매: 7~12개월용</h2>
<ol>
<li>《임베디드 엔지니어 교과서》</li>
<li>《임종수의 STM32 Cortex-M 완벽 활용서 Vol.1》</li>
<li>《OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝》</li>
<li>필요 시 《임베디드 프로그래밍 C 코드 최적화》</li>
</ol>
<h2 id="3차-구매-1318개월용">3차 구매: 13~18개월용</h2>
<ol>
<li>《혼자 공부하는 머신러닝+딥러닝》</li>
<li>《밑바닥부터 시작하는 딥러닝 1》</li>
<li>《밑바닥부터 시작하는 딥러닝 2》</li>
<li>《트랜스포머를 활용한 자연어 처리》</li>
<li>《LangGraph로 만드는 AI 에이전트 서비스》</li>
<li>《컴퓨터 네트워킹: 하향식 접근》</li>
<li>《HTTP 완벽 가이드》</li>
<li>《도커 교과서》</li>
</ol>
<h2 id="4차-구매-1924개월-선택">4차 구매: 19~24개월 선택</h2>
<p>AegisEdge가 영상분석이면:</p>
<ol>
<li>《IT CookBook, 컴퓨터 비전과 딥러닝》</li>
<li>YOLO/ONNX/DeepStream 공식문서 중심</li>
</ol>
<p>AegisEdge가 로봇이면:</p>
<ol>
<li>《ROS2 혼자공부하는 로봇SW 직접 만들고 코딩하자》</li>
<li>《ROS 2로 시작하는 로봇 프로그래밍》</li>
<li>ROS2/Nav2/Gazebo 공식문서</li>
</ol>
<p>AegisEdge가 관제/보안/정책엔진이면:</p>
<ol>
<li>《소프트웨어 공학의 모든 것》</li>
<li>《실용주의 프로그래머》</li>
<li>KISA 시큐어코딩 가이드</li>
<li>MCP/A2A 공식문서</li>
</ol>
<hr>
<h1 id="10-공식문서-읽는-순서">10. 공식문서 읽는 순서</h1>
<p>교재보다 공식문서가 중요한 영역이 있다. 이전 정리 문서에서도 LVGL 9.x, STM32H747I-DISCO, ESP-IDF/M5Stack CoreS3, Upstage API, LangGraph, OpenCV/DeepStream/YOLO는 버전 변화가 있어 공식문서 우선이라고 정리했다. </p>
<h2 id="1순위-공식문서">1순위 공식문서</h2>
<ol>
<li>STM32H747I-DISCO User Manual</li>
<li>ESP-IDF Programming Guide</li>
<li>M5Stack CoreS3 공식문서</li>
<li>LVGL 공식문서</li>
<li>OpenCV 공식문서</li>
<li>Upstage Document Parse / Information Extract / Solar Pro 3</li>
<li>LangGraph 공식문서</li>
<li>Docker 공식문서</li>
<li>CMake 공식문서</li>
<li>DeepStream 공식문서, AegisEdge 영상분석 시</li>
</ol>
<hr>
<h1 id="11-주간-공부-루틴">11. 주간 공부 루틴</h1>
<p>매주 이렇게 반복한다.</p>
<h2 id="월요일">월요일</h2>
<p>교재 1장 읽기.
핵심 용어 10개 정리.</p>
<h2 id="화요일">화요일</h2>
<p>공식문서 읽기.
교재와 공식문서 차이 정리.</p>
<h2 id="수요일">수요일</h2>
<p>코딩 실습.
작게라도 동작하는 예제를 만든다.</p>
<h2 id="목요일">목요일</h2>
<p>실패 로그 분석.
에러 메시지를 원인별로 분류한다.</p>
<h2 id="금요일">금요일</h2>
<p>README 작성.
“내가 뭘 배웠는지”가 아니라 “다른 사람이 어떻게 재현하는지”를 쓴다.</p>
<h2 id="토요일">토요일</h2>
<p>미니 프로젝트 구현.</p>
<h2 id="일요일">일요일</h2>
<p>복습, 정리, 다음 주 계획.</p>
<hr>
<h1 id="12-매달-평가-기준">12. 매달 평가 기준</h1>
<p>매달 아래 5개를 체크한다.</p>
<table>
<thead>
<tr>
<th>항목</th>
<th>질문</th>
</tr>
</thead>
<tbody><tr>
<td>개념</td>
<td>내가 이 주제를 말로 설명할 수 있는가?</td>
</tr>
<tr>
<td>코드</td>
<td>작게라도 동작하는 코드가 있는가?</td>
</tr>
<tr>
<td>문서</td>
<td>README나 노트가 있는가?</td>
</tr>
<tr>
<td>테스트</td>
<td>실패/성공 기준이 있는가?</td>
</tr>
<tr>
<td>연결</td>
<td>EdgeCanvas 또는 AegisEdge와 어떻게 연결되는가?</td>
</tr>
</tbody></table>
<p>점수는 5점 만점으로 기록한다.</p>
<table>
<thead>
<tr>
<th align="right">점수</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td align="right">1</td>
<td>읽기만 했다</td>
</tr>
<tr>
<td align="right">2</td>
<td>예제를 따라 했다</td>
</tr>
<tr>
<td align="right">3</td>
<td>변형해서 실행했다</td>
</tr>
<tr>
<td align="right">4</td>
<td>내 프로젝트에 연결했다</td>
</tr>
<tr>
<td align="right">5</td>
<td>문서화하고 재현 가능하게 만들었다</td>
</tr>
</tbody></table>
<p><strong>2년 동안 목표는 모든 핵심 영역을 4점 이상으로 만드는 것</strong>이다.</p>
<hr>
<h1 id="13-edgecanvas-관점-핵심-역량-우선순위">13. EdgeCanvas 관점 핵심 역량 우선순위</h1>
<table>
<thead>
<tr>
<th align="right">순위</th>
<th>역량</th>
<th>이유</th>
</tr>
</thead>
<tbody><tr>
<td align="right">1</td>
<td>C와 메모리</td>
<td>LVGL/MCU 펌웨어의 기반</td>
</tr>
<tr>
<td align="right">2</td>
<td>컴퓨터구조</td>
<td>데이터시트, 레지스터, 메모리맵 이해</td>
</tr>
<tr>
<td align="right">3</td>
<td>임베디드 시스템</td>
<td>STM32/M5Stack 실기 동작</td>
</tr>
<tr>
<td align="right">4</td>
<td>LVGL/HMI</td>
<td>EdgeCanvas의 직접 산출물</td>
</tr>
<tr>
<td align="right">5</td>
<td>Python 자동화</td>
<td>Agent, API, 빌드 자동화</td>
</tr>
<tr>
<td align="right">6</td>
<td>OpenCV</td>
<td>Vision-in-the-Loop 검증</td>
</tr>
<tr>
<td align="right">7</td>
<td>LangGraph</td>
<td>Self-Healing 상태머신</td>
</tr>
<tr>
<td align="right">8</td>
<td>Docker/pytest</td>
<td>재현성, 평가, 제출 패키징</td>
</tr>
<tr>
<td align="right">9</td>
<td>보안</td>
<td>API 키, 코드 생성, 외부 문서 입력</td>
</tr>
<tr>
<td align="right">10</td>
<td>머신러닝/LLM</td>
<td>문서 이해와 코드 생성 품질 개선</td>
</tr>
</tbody></table>
<hr>
<h1 id="14-aegisedge-관점-핵심-역량-우선순위">14. AegisEdge 관점 핵심 역량 우선순위</h1>
<table>
<thead>
<tr>
<th align="right">순위</th>
<th>역량</th>
<th>이유</th>
</tr>
</thead>
<tbody><tr>
<td align="right">1</td>
<td>리눅스/네트워크</td>
<td>엣지 장비, RTSP, API 서버</td>
</tr>
<tr>
<td align="right">2</td>
<td>OpenCV</td>
<td>모든 영상분석의 기본</td>
</tr>
<tr>
<td align="right">3</td>
<td>딥러닝/객체탐지</td>
<td>YOLO/ONNX 추론</td>
</tr>
<tr>
<td align="right">4</td>
<td>Docker</td>
<td>엣지 배포</td>
</tr>
<tr>
<td align="right">5</td>
<td>DeepStream</td>
<td>실시간 멀티스트림 영상분석</td>
</tr>
<tr>
<td align="right">6</td>
<td>보안</td>
<td>관제/이벤트/카메라 시스템의 핵심</td>
</tr>
<tr>
<td align="right">7</td>
<td>데이터베이스</td>
<td>이벤트 로그와 추론 결과 저장</td>
</tr>
<tr>
<td align="right">8</td>
<td>ROS2</td>
<td>로봇 연동 시</td>
</tr>
<tr>
<td align="right">9</td>
<td>제어/SLAM</td>
<td>실제 이동체 연동 시</td>
</tr>
<tr>
<td align="right">10</td>
<td>MCP/A2A</td>
<td>멀티에이전트 확장 시</td>
</tr>
</tbody></table>
<hr>
<h1 id="15-하지-말아야-할-순서">15. 하지 말아야 할 순서</h1>
<p>아래 순서로 가면 위험하다.</p>
<pre><code class="language-text">LLM Agent → ROS2 → Isaac Sim → 강화학습 → 임베디드</code></pre>
<p>이 순서는 멋있어 보이지만 EdgeCanvas에는 비효율적이다. 왜냐하면 EdgeCanvas의 본질은 <strong>실물 MCU, LVGL, 빌드/플래시, 카메라 검증</strong>이기 때문이다.</p>
<p>올바른 순서는 다음이다.</p>
<pre><code class="language-text">리눅스
→ Python
→ C
→ 자료구조
→ 컴퓨터구조
→ 운영체제
→ 디지털논리
→ 임베디드
→ LVGL
→ OpenCV
→ 문서 AI
→ LangGraph
→ Docker/보안
→ EdgeCanvas MVP
→ AegisEdge 확장</code></pre>
<p>이전 정리 문서에서도 “기초 학문은 AI부터가 아니라 리눅스 → Python → C → 자료구조 → 컴퓨터구조 → 운영체제 → 이산수학 → 임베디드 → 선형대수/확률통계 → OpenCV → 딥러닝 → LangGraph Agent → 네트워크/보안/소프트웨어공학” 순서가 맞다고 정리했다. </p>
<hr>
<h1 id="16-최종-요약">16. 최종 요약</h1>
<p>2년 커리큘럼의 핵심은 이렇다.</p>
<h2 id="기초-16개월">기초, 1~6개월</h2>
<p>리눅스, Git, Python, C, 자료구조, 컴퓨터구조, 운영체제, 이산수학을 한다.
목표는 <strong>시스템을 이해하는 개발자 기본기</strong>다.</p>
<h2 id="기본-712개월">기본, 7~12개월</h2>
<p>디지털논리, 임베디드, STM32, M5Stack, ESP-IDF, LVGL, CMake, OpenCV를 한다.
목표는 <strong>실물 보드에 HMI를 띄우고 카메라로 검증하는 능력</strong>이다.</p>
<h2 id="심화-1318개월">심화, 13~18개월</h2>
<p>선형대수, 확률통계, 머신러닝, 딥러닝, NLP, RAG, Upstage 문서 AI, LangGraph, 네트워크, Docker, 보안을 한다.
목표는 <strong>문서 이해와 자가수정 Agent를 설계하는 능력</strong>이다.</p>
<h2 id="실전-1924개월">실전, 19~24개월</h2>
<p>EdgeCanvas MVP를 만든다.
목표는 <strong>데이터시트 → JSON → LVGL C 코드 → 빌드 → 플래시 → 카메라 검증 → 자가수정 리포트</strong>까지 연결하는 것이다.</p>
<p>가장 중요한 결론은 하나다.</p>
<p><strong>EdgeCanvas를 제대로 하려면 AI보다 먼저 C, 컴퓨터구조, 임베디드, LVGL, OpenCV, LangGraph를 순서대로 쌓아야 한다. AegisEdge까지 생각하면 그 위에 네트워크, Docker, 딥러닝 객체탐지, DeepStream, 보안을 얹으면 된다.</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[먹고살자]]></title>
            <link>https://velog.io/@charlese_note/%EB%A8%B9%EA%B3%A0%EC%82%B4%EC%9E%90</link>
            <guid>https://velog.io/@charlese_note/%EB%A8%B9%EA%B3%A0%EC%82%B4%EC%9E%90</guid>
            <pubDate>Fri, 20 Feb 2026 06:28:55 GMT</pubDate>
            <description><![CDATA[<p>좋습니다. <strong>AI_operation_system 포트폴리오(LLMOps/CVOps)</strong>랑 맞는 국가사업을 실제 공고 기준으로 추려봤어요.
(기준일: 2026-02-20)</p>
<p>1) LLMOps/AI 운영(서비스화·운영자동화) 쪽 유사 사업
2026년도 공공AX 프로젝트 사업 신규과제 모집 공고 (진행중)</p>
<p>기간: 2026-02-11 ~ 2026-03-16
링크: <a href="https://www.nipa.kr/home/2-2/16471">https://www.nipa.kr/home/2-2/16471</a>
성격: 공공영역 AI 도입/운영, MLOps·LLMOps 구조 제안에 잘 맞음
2026년도 AI 응용제품 신속 상용화 지원사업 (Type2: AI 민생 프로젝트) (예정)</p>
<p>기간: 2026-03-02 ~ 2026-03-16
링크: <a href="https://www.nipa.kr/home/2-2/16475">https://www.nipa.kr/home/2-2/16475</a>
성격: 모델을 제품/서비스로 빠르게 상용화하는 트랙
2026년 AI바우처 지원사업 공급기업 POOL 모집 공고 (진행중)</p>
<p>기간: 2026-02-10 ~ 2026-02-24
링크: <a href="https://www.nipa.kr/home/2-2/16469">https://www.nipa.kr/home/2-2/16469</a>
성격: AI 솔루션 공급기업 등록(LLM 서비스 운영기업에게 중요)
2026년도 중소기업 클라우드 서비스 보급·확산 사업 공급기업 모집 (진행중)</p>
<p>기간: 2026-02-13 ~ 2026-03-20
링크: <a href="https://www.nipa.kr/home/2-2/16474">https://www.nipa.kr/home/2-2/16474</a>
성격: LLM 서비스 운영 인프라(클라우드, 운영체계) 연계에 유리
2026년도 AI·디지털 비즈니스 파트너십 특화 프로그램 참여기업 모집 (진행중)</p>
<p>기간: 2026-02-05 ~ 2026-03-05
링크: <a href="https://www.nipa.kr/home/2-2/16463">https://www.nipa.kr/home/2-2/16463</a>
2) CVOps/제조 비전·영상분석 쪽 유사 사업
[경기] 스마트공장 구축 및 컨설팅·제조AI 지원사업 (진행중)</p>
<p>기간: 2026-02-10 ~ 2026-03-20
링크: <a href="https://www.bizinfo.go.kr/sii/siia/selectSIIA200Detail.do?pblancId=PBLN_000000000118448">https://www.bizinfo.go.kr/sii/siia/selectSIIA200Detail.do?pblancId=PBLN_000000000118448</a>
[강원] 강원형 스마트공장(기초단계) 구축지원사업 (예정)</p>
<p>기간: 2026-03-03 ~ 2026-03-23
링크: <a href="https://www.bizinfo.go.kr/sii/siia/selectSIIA200Detail.do?pblancId=PBLN_000000000118437">https://www.bizinfo.go.kr/sii/siia/selectSIIA200Detail.do?pblancId=PBLN_000000000118437</a>
[울산] AI기반 PoC 실증 지원사업(지역특화 제조데이터 활성화) (진행중)</p>
<p>기간: 2025-11-19 ~ 2026-02-28
링크: <a href="https://www.bizinfo.go.kr/sii/siia/selectSIIA200Detail.do?pblancId=PBLN_000000000116436">https://www.bizinfo.go.kr/sii/siia/selectSIIA200Detail.do?pblancId=PBLN_000000000116436</a>
중소제조 특화 Multi AI Agent 개발(R&amp;D) (예정)</p>
<p>기간: 2026-03-01 ~ 2026-03-31
링크: <a href="https://www.bizinfo.go.kr/sii/siia/selectSIIA200Detail.do?pblancId=PBLN_000000000116030">https://www.bizinfo.go.kr/sii/siia/selectSIIA200Detail.do?pblancId=PBLN_000000000116030</a>
제조AI특화 스마트공장(자율형공장 AI트랙) (예정)</p>
<p>기간: 2026-03-01 ~ 2026-04-30
링크: <a href="https://www.bizinfo.go.kr/sii/siia/selectSIIA200Detail.do?pblancId=PBLN_000000000115998">https://www.bizinfo.go.kr/sii/siia/selectSIIA200Detail.do?pblancId=PBLN_000000000115998</a>
민군경 AI 기반 해양영상 융복합 분석기술개발 (마감, 유사도 높음)</p>
<p>기간: 2026-01-26 ~ 2026-02-19
링크: <a href="https://www.bizinfo.go.kr/sii/siia/selectSIIA200Detail.do?pblancId=PBLN_000000000117465">https://www.bizinfo.go.kr/sii/siia/selectSIIA200Detail.do?pblancId=PBLN_000000000117465</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[GPT]]></title>
            <link>https://velog.io/@charlese_note/GPT</link>
            <guid>https://velog.io/@charlese_note/GPT</guid>
            <pubDate>Wed, 21 Jan 2026 11:48:08 GMT</pubDate>
            <description><![CDATA[<h1 id="1-자연어-처리-기초">1. 자연어 처리 기초</h1>
<h2 id="11-학습-목표">1.1 학습 목표</h2>
<h3 id="111-gpt-3-등장">1.1.1 GPT-3 등장</h3>
<ul>
<li>하나의 모델로 다양한 업무를 하려는 흐름</li>
<li>Pretrain → Transfer</li>
<li>Few-shot / Zero-shot</li>
</ul>
<h3 id="112-transformer의-중요성">1.1.2 Transformer의 중요성</h3>
<ul>
<li>RNN/LSTM의 한계를 <strong>Attention</strong>으로 해결</li>
</ul>
<h3 id="113-nlp의-핵심-난제">1.1.3 NLP의 핵심 난제</h3>
<ul>
<li>순서가 의미를 바꿈</li>
<li>단어 하나 변화가 의미 및 라벨을 뒤집음 (ex: “안”)</li>
<li>토큰화와 OOV(사전에 없는 단어)가 실무 난이도를 크게 좌우</li>
</ul>
<h3 id="114-기초-수식">1.1.4 기초 수식</h3>
<ul>
<li>언어 모델 확률(체인 룰)</li>
<li>내적 = 유사도</li>
<li>softmax가 확률이 되는 이유</li>
</ul>
<hr>
<h2 id="12-gpt-3">1.2 GPT-3</h2>
<h3 id="121-gpt-3-방향성">1.2.1 GPT-3 방향성</h3>
<ul>
<li>Task마다 모델을 새로 만들고 라벨을 많이 모아 학습하는 방식은 비용이 큼</li>
<li>큰 모델을 미리 학습(Pretrain)해두고, 적은 예시(Few-shot) 또는 예시 없이(Zero-shot) 다양한 Task를 수행하게 하려는 방향</li>
</ul>
<h3 id="122-gpt-3-핵심-동기">1.2.2 GPT-3 핵심 동기</h3>
<ul>
<li>Transformer가 번역에서 성공 → “Transformer 구조로 더 잘할 수 없을까?”</li>
<li>Task 및 Domain이 바뀌면 성능이 떨어지는 문제</li>
<li>다양한 데이터로 미리 학습하면 새로운 Task 적응이 쉬워진다로 개념 발전</li>
</ul>
<hr>
<h2 id="13-transformer-핵심">1.3 Transformer 핵심</h2>
<ul>
<li>Attention</li>
<li>Positional Encoding</li>
</ul>
<h3 id="131-self-attention">1.3.1 Self-Attention</h3>
<ul>
<li>문장 안의 각 토큰이 문장 내 다른 토큰들을 참고해서 자기 표현을 업데이트</li>
</ul>
<pre><code class="language-text">토큰 i의 새 표현 = (토큰 1을 보는 비율)*v1
               + (토큰 2를 보는 비율)*v2
               + ...
               + (토큰 n을 보는 비율)*vn</code></pre>
<h3 id="132-positional-encoding">1.3.2 Positional Encoding</h3>
<ul>
<li>Transformer는 구조적으로 순서 정보가 자동으로 들어가지 않음</li>
<li>토큰 위치 정보를 숫자 벡터로 추가해서 순서를 인지하게 만들어야 함</li>
</ul>
<hr>
<h2 id="14-데이터-관점-비교">1.4 데이터 관점 비교</h2>
<h3 id="141-tabular-vs-vision-vs-nlp">1.4.1 Tabular vs Vision vs NLP</h3>
<table>
<thead>
<tr>
<th>구분</th>
<th>Tabular(테이블)</th>
<th>Vision(이미지)</th>
<th>NLP(자연어)</th>
</tr>
</thead>
<tbody><tr>
<td>핵심 구조</td>
<td>피처(열) 기반</td>
<td>픽셀 <strong>로컬리티</strong>(근처가 중요)</td>
<td>토큰 <strong>순서/의존성</strong>(멀리도 중요)</td>
</tr>
<tr>
<td>위치 변화 영향</td>
<td>보통 “열 의미 고정”</td>
<td>이동해도 비슷(완전 불변은 아니지만 CNN이 강함)</td>
<td>위치 바뀌면 의미 크게 변함</td>
</tr>
<tr>
<td>작은 변화의 영향</td>
<td>열 하나 변화는 보통 점진적</td>
<td>픽셀 1개 변화는 대체로 영향 작음(일반적)</td>
<td>단어 1개(“안”)가 라벨 뒤집기도</td>
</tr>
<tr>
<td>대표 모델 가정</td>
<td>독립/약한 상관 가정이 쉬움</td>
<td>locality, (translation) equivariance</td>
<td>long-range dependency, order-sensitive</td>
</tr>
</tbody></table>
<hr>
<h2 id="15-토큰화">1.5 토큰화</h2>
<h3 id="151-토큰화란">1.5.1 토큰화란</h3>
<ul>
<li>문장을 모델이 먹을 수 있는 단위로 쪼개고 각 조각을 숫자로 바꾸는 과정</li>
</ul>
<h3 id="152-토큰화-단위">1.5.2 토큰화 단위</h3>
<ul>
<li><p>Character</p>
<ul>
<li>예: <code>나는 → [나, 는]</code></li>
<li>장점: OOV 거의 없음</li>
<li>단점: 길이 폭증, 의미 단위가 약함</li>
</ul>
</li>
<li><p>Space</p>
<ul>
<li>예: <code>I love apples → [I, love, apples]</code></li>
<li>장점: 단순함</li>
<li>단점: “tokenization!” vs “tokenization” 같은 변형에 취약, 한국어는 공백이 의미 단위와 안 맞는 경우가 많음</li>
</ul>
</li>
<li><p>Punctuation</p>
<ul>
<li>구두점 기준 분리</li>
<li>장점: 일부 개선</li>
<li>단점: 근본 해결은 아님</li>
</ul>
</li>
<li><p>Subword</p>
<ul>
<li>예: <code>unbelievable → [un, believe, able]</code></li>
<li>OOV를 크게 줄이면서 길이 폭증도 완화</li>
<li>대표: GPT 계열(BPE), BERT 계열(WordPiece)</li>
</ul>
</li>
</ul>
<hr>
<h2 id="16-언어-모델">1.6 언어 모델</h2>
<ul>
<li>문장을 확률로 모델링</li>
</ul>
<h3 id="161-문장-확률">1.6.1 문장 확률</h3>
<ul>
<li>체인 룰(Chain Rule)로 분해</li>
<li>문장을 단어들의 나열로 보면 길이 (T)인 문장은 다음처럼 표현 가능</li>
</ul>
<p>$$
(W_1, W_2, \ldots, W_T)
$$</p>
<ul>
<li>문장 전체 결합확률은 체인 룰로 다음처럼 분해</li>
</ul>
<p>$$
P(W_1, W_2, \ldots, W_T) = \prod_{t=1}^{T} P(W_t \mid W_{&lt;t})
$$</p>
<ul>
<li><p>여기서 (W_{&lt;t})는 “(t)번째 단어 이전까지의 모든 단어들”을 의미</p>
<ul>
<li>$$P(W_1)$$ : 첫 단어가 나올 확률</li>
<li>$$P(W_2 \mid W_1)$$ : 첫 단어가 주어졌을 때 두 번째 단어 확률</li>
<li>$$P(W_3 \mid W_1, W_2)$$ : 앞의 두 단어가 주어졌을 때 세 번째 단어 확률</li>
<li>$$P(W_T \mid W_1, \ldots, W_{T-1})$$ : 이전 단어들이 주어졌을 때 마지막 단어 확률</li>
</ul>
</li>
<li><p>언어 모델은 한 문장을 한 번에 통째로 외우는 게 아님</p>
</li>
<li><p>즉, “지금까지 단어들이 주어졌을 때 다음 단어 확률”을 반복적으로 예측하고 그 확률들을 곱해서 문장 전체 확률을 구성</p>
</li>
</ul>
<hr>
<h2 id="17-평가-지표">1.7 평가 지표</h2>
<ul>
<li><p>왜 번역/생성은 “정답률(Accuracy)”로 끝나지 않나</p>
</li>
<li><p>번역/요약/생성 태스크는 정답이 한 가지로 고정되지 않음</p>
</li>
<li><p>같은 의미라도 표현이 여러 가지가 가능하므로, “정확히 일치”만 보는 정답률로는 평가가 어려움</p>
</li>
<li><p>따라서 BLEU/ROUGE 같은 자동 평가 지표가 등장</p>
</li>
</ul>
<h3 id="171-핵심-지표-정리">1.7.1 핵심 지표 정리</h3>
<ul>
<li><p><strong>BLEU</strong></p>
<ul>
<li>핵심: n-gram precision(겹치는 조각 비율) + brevity penalty(짧은 번역 패널티)</li>
<li>장점: 자동 평가 가능</li>
<li>한계: 의미가 같아도 표현이 다르면 낮게 나올 수 있음</li>
</ul>
</li>
<li><p><strong>ROUGE</strong></p>
<ul>
<li>요약에서 많이 사용</li>
<li>성격: recall에 가까움(참고 요약의 내용이 얼마나 포함됐나)</li>
<li>대표: ROUGE-N, ROUGE-L</li>
</ul>
</li>
<li><p><strong>METEOR</strong></p>
<ul>
<li>정렬(alignment) 관점이 강하고, 어간(stemming), 동의어 등을 고려(세부는 설정/버전에 따라 차이)</li>
</ul>
</li>
<li><p><strong>Human Evaluation</strong></p>
<ul>
<li>여전히 중요</li>
<li>기준 예시: Adequacy(의미), Fluency(자연스러움)</li>
<li>pairwise 비교(둘 중 더 좋은 것 선택)가 안정적</li>
</ul>
</li>
</ul>
<hr>
<h2 id="18-트랜스포머-이전-rnnlstm-인코더-디코더seq2seq">1.8 트랜스포머 이전: RNN/LSTM 인코더-디코더(Seq2Seq)</h2>
<ul>
<li>“문맥(context)을 하나로 요약하고 싶다” → 인코더-디코더 구조가 자연스럽게 등장</li>
</ul>
<h3 id="181-rnn-구조시간축으로-펼침">1.8.1 RNN 구조(시간축으로 펼침)</h3>
<pre><code class="language-text">x1 -&gt; [RNN] -&gt; h1
            -&gt; (다음으로 전달)
x2 -&gt; [RNN] -&gt; h2
x3 -&gt; [RNN] -&gt; h3
...</code></pre>
<ul>
<li>(x_t): t번째 입력(토큰 임베딩)</li>
<li>(h_t): t번째 은닉 상태(문맥 누적 정보)</li>
</ul>
<h3 id="182-인코더-디코더번역-개념">1.8.2 인코더-디코더(번역) 개념</h3>
<pre><code class="language-text">(Encoder)  한국어 토큰들 -&gt; h1,h2,...,hT -&gt; (context 요약)
(Decoder)  context + 이전 출력 -&gt; 다음 단어 생성 -&gt; ...</code></pre>
<ul>
<li>인코더: 입력 문장을 읽고 표현을 만듦</li>
<li>디코더: 인코더 요약(context) + 이전 출력 토큰을 바탕으로 다음 토큰 생성</li>
</ul>
<h3 id="183-한계가-생기는-이유">1.8.3 한계가 생기는 이유</h3>
<ul>
<li><strong>정보 병목(Bottleneck)</strong>: 긴 문장을 하나의 context 벡터로 압축 → 앞부분 정보 손실</li>
<li><strong>순차 처리의 한계</strong>: 병렬화가 어려움</li>
<li><strong>장기 의존성 문제</strong>: 멀리 떨어진 정보 연결이 어렵고 학습이 불안정(대표: vanishing gradient)</li>
</ul>
<hr>
<h2 id="19-attention">1.9 Attention</h2>
<ul>
<li><p>어느 단어(토큰)에 더 집중할지 학습하여 중요한 정보에 더 큰 가중치를 주는 메커니즘</p>
</li>
<li><p>강의 요지</p>
<ul>
<li>“I do <strong>not</strong> like …”에서 핵심은 <strong>not</strong></li>
<li>번역은 단어 정렬(alignment)이 중요 (한국어 앞 단어가 영어 뒤로 갈 수도 있음)</li>
</ul>
</li>
</ul>
<h3 id="191-디코더-인코더-attention-직관seq2seq-attention">1.9.1 디코더-인코더 Attention 직관(Seq2Seq Attention)</h3>
<ul>
<li>디코더가 출력 토큰 하나(시점 (j))를 만들 때,</li>
<li>인코더의 모든 상태 ((h_1, \ldots, h_T)) 중 <strong>어디를 얼마나 참고할지(가중치)</strong>를 계산한다.</li>
</ul>
<h4 id="1-유사도-점수score-계산">(1) 유사도 점수(score) 계산</h4>
<p>$$
\text{score}_{j,i} = \mathrm{similarity}(\mathbf{s}_j, \mathbf{h}_i)
$$</p>
<h4 id="2-softmax로-가중치attention-weight-만들기">(2) softmax로 가중치(attention weight) 만들기</h4>
<p>$$
\alpha_{j,i} =
\frac{\exp(\text{score}<em>{j,i})}
{\sum</em>{k=1}^{T}\exp(\text{score}_{j,k})}
$$</p>
<h4 id="3-가중합으로-컨텍스트-벡터context-vector-만들기">(3) 가중합으로 컨텍스트 벡터(context vector) 만들기</h4>
<p>$$
\mathbf{c}<em>j = \sum</em>{i=1}^{T} \alpha_{j,i},\mathbf{h}_i
$$</p>
<h4 id="기호-의미">기호 의미</h4>
<ul>
<li><p>$$\mathbf{s}_j$$ : 디코더의 (j)번째 상태(hidden state)</p>
</li>
<li><p>$$\mathbf{h}_i$$ : 인코더의 (i)번째 상태(hidden state)</p>
</li>
<li><p>$$\alpha_{j,i}$$ : (j)번째 출력 생성 시 (i)번째 입력을 얼마나 참고할지 나타내는 가중치</p>
<ul>
<li>$$\sum_{i=1}^{T}\alpha_{j,i} = 1$$</li>
</ul>
</li>
<li><p>$$\mathbf{c}_j$$ : 디코더 (j)시점의 컨텍스트 벡터(입력 정보를 정렬+요약해서 제공)</p>
</li>
</ul>
<h3 id="192-전사본-표현-교정중요">1.9.2 전사본 표현 교정(중요)</h3>
<ul>
<li>핵심 흐름은 동일: 유사도 점수 → softmax → 가중합</li>
<li>다만 실제 구현은 여러 변형이 존재한다.</li>
</ul>
<h4 id="1-전통-seq2seq-attention의-대표-변형">(1) 전통 Seq2Seq Attention의 대표 변형</h4>
<ul>
<li>Dot-product(내적 기반)</li>
</ul>
<p>$$
\mathrm{similarity}(\mathbf{s}_j, \mathbf{h}_i) = \mathbf{s}_j^{\top}\mathbf{h}_i
$$</p>
<ul>
<li>Additive(Bahdanau, MLP 기반)</li>
</ul>
<p>$$
\mathrm{similarity}(\mathbf{s}_j, \mathbf{h}_i) =
\mathbf{v}^{\top}\tanh(W_s\mathbf{s}_j + W_h\mathbf{h}_i)
$$</p>
<h4 id="2-트랜스포머-attention과의-연결">(2) 트랜스포머 Attention과의 연결</h4>
<ul>
<li>트랜스포머는 같은 아이디어를 (Q, K, V)로 재구성해 효율적으로 만든 형태다.</li>
</ul>
<p>$$
\mathrm{Attention}(Q, K, V) =
\mathrm{softmax}\left(\frac{QK^{\top}}{\sqrt{d_k}}\right)V
$$</p>
<hr>
<h2 id="110-선형대수-기초">1.10 선형대수 기초</h2>
<ul>
<li>목표</li>
</ul>
<blockquote>
<p>수식을 봤을 때 “아 유사도구나 / 아 확률로 바꾸는구나”를 즉시 캐치하기</p>
</blockquote>
<h3 id="1101-벡터행렬전치transpose">1.10.1 벡터/행렬/전치(Transpose)</h3>
<ul>
<li>벡터(열벡터)</li>
</ul>
<p>$$
\mathbf{h} \in \mathbb{R}^{d \times 1}
$$</p>
<ul>
<li>전치(Transpose)</li>
</ul>
<p>$$
\mathbf{h}^{\top} \in \mathbb{R}^{1 \times d}
$$</p>
<ul>
<li>내적(Dot product): 결과는 스칼라</li>
</ul>
<p>$$
\mathbf{h}^{\top}\mathbf{g} \in \mathbb{R}
$$</p>
<h3 id="1102-내적이-왜-유사도-느낌인가">1.10.2 내적이 왜 “유사도” 느낌인가?</h3>
<h4 id="1-코사인-유사도에-내적이-포함됨">(1) 코사인 유사도에 내적이 포함됨</h4>
<p>$$
\cos(\theta) = \frac{\mathbf{a}^{\top}\mathbf{b}}{\lVert \mathbf{a}\rVert,\lVert \mathbf{b}\rVert}
$$</p>
<ul>
<li>방향이 비슷할수록 값이 커짐</li>
<li>정규화하면 내적이 곧 “방향 유사도”처럼 동작</li>
</ul>
<h4 id="2-거리distance-전개에도-내적이-등장">(2) 거리(distance) 전개에도 내적이 등장</h4>
<p>$$
\lVert \mathbf{x}-\mathbf{y}\rVert^{2}
= \mathbf{x}^{\top}\mathbf{x} - 2\mathbf{x}^{\top}\mathbf{y} + \mathbf{y}^{\top}\mathbf{y}
$$</p>
<ul>
<li>$$\mathbf{x}^{\top}\mathbf{y}$$ 가 커질수록(더 비슷할수록) 거리는 작아지는 구조</li>
<li>그래서 내적은 “유사도”로 자주 쓰인다</li>
</ul>
<h3 id="1103-softmax가-왜-확률이-되나">1.10.3 softmax가 왜 “확률”이 되나?</h3>
<ul>
<li>softmax 정의</li>
</ul>
<p>$$
\mathrm{softmax}(z_i) = \frac{e^{z_i}}{\sum_{k} e^{z_k}}
$$</p>
<ul>
<li>항상 0보다 큼</li>
<li>전체 합이 1</li>
<li>미분이 깔끔해 학습에 유리</li>
</ul>
<p>✅ 실무 팁(수치 안정성)</p>
<p>$$
\mathrm{softmax}(\mathbf{z})<em>i =
\frac{e^{z_i - \max(\mathbf{z})}}{\sum</em>{k} e^{z_k - \max(\mathbf{z})}}
$$</p>
<ul>
<li>overflow 방지를 위해 보통 (\max(\mathbf{z}))를 빼고 계산</li>
<li>정규화 구조 때문에 결과 확률은 동일하게 유지된다</li>
</ul>
<hr>
<h2 id="111-트랜스포머로-돌아오기-왜-gptbert가-여기서-나왔나">1.11 트랜스포머로 돌아오기: 왜 GPT/BERT가 여기서 나왔나?</h2>
<ul>
<li>트랜스포머는 RNN의 순차 처리를 버리고, Attention으로 문장 내 관계를 한 번에 계산할 수 있게 만든 구조</li>
</ul>
<h3 id="1111-트랜스포머-attention-블록자체완결">1.11.1 트랜스포머 Attention 블록(자체완결)</h3>
<pre><code class="language-text">입력 X (토큰 임베딩 + 포지션)  [n x d]

Q = XWq
K = XWk
V = XWv

A = softmax( QK^T / sqrt(dk) )   [n x n]  // 토큰-토큰 관계표
출력 = A V                        [n x d]</code></pre>
<ul>
<li>(A): 토큰-토큰 관계(어느 토큰이 어느 토큰을 얼마나 참고하는지)</li>
</ul>
<h3 id="1112-multi-head가-왜-필요">1.11.2 Multi-Head가 왜 필요?</h3>
<ul>
<li>한 번의 관계표만으로는 관계의 종류를 다양하게 담기 어려움</li>
<li>여러 헤드가 서로 다른 관점(문법/의미/지시어/장거리 의존 등)으로 관계를 학습</li>
</ul>
<hr>
<h2 id="112-gpt-vs-bert-같은-트랜스포머지만-목표가-다르다">1.12 GPT vs BERT: 같은 트랜스포머지만 목표가 다르다</h2>
<table>
<thead>
<tr>
<th>모델</th>
<th>구조</th>
<th>학습 목표</th>
<th>강점</th>
</tr>
</thead>
<tbody><tr>
<td>GPT 계열</td>
<td>Decoder-only</td>
<td>다음 토큰 예측(Autoregressive)</td>
<td>생성, 프롬프트 기반 적응(Few/Zero-shot)</td>
</tr>
<tr>
<td>BERT 계열</td>
<td>Encoder-only</td>
<td>마스크 채우기(Masked LM)</td>
<td>분류/추출(QA span 등)에서 강함</td>
</tr>
</tbody></table>
<h3 id="1121-전사본-표현-교정중요">1.12.1 전사본 표현 교정(중요)</h3>
<ul>
<li>트랜스포머도 임베딩 레이어(토큰 ID → 벡터)는 반드시 존재</li>
<li>다만 word2vec처럼 임베딩을 따로 만들고 고정하기보다,</li>
<li>모델 학습 과정에서 임베딩까지 end-to-end로 같이 최적화하는 경우가 일반적
→ “임베딩을 따로 튜닝하는 비중이 줄었다”로 이해하면 자연스럽다</li>
</ul>
<hr>
<p>아래는 네가 준 내용을 <strong>강의 흐름 그대로</strong> 유지하면서, Velog에서 <strong>수식이 절대 안 깨지게</strong> <code>$$ ... $$</code>로 통일하고, <strong>ASCII/표/shape 추적/핵심 교정</strong>까지 “교재” 톤으로 완성한 최종본이야.
(원문에 있던 <code>[</code> <code>]</code> 수식 표기, 괄호/슬래시/루트 표기 흔들림, 인덱스 표기 혼동을 전부 정리했어.)</p>
<hr>
<h1 id="2-transformer">2. Transformer</h1>
<h2 id="1-transformer">1) Transformer</h2>
<h3 id="11-트랜스포머는-인코더-디코더-구조">1.1 트랜스포머는 “인코더-디코더” 구조</h3>
<ul>
<li>입력 문장(소스)을 <strong>Encoder</strong>가 이해(표현 벡터로 변환)</li>
<li>출력 문장(타겟)을 <strong>Decoder</strong>가 생성(한 토큰씩)</li>
</ul>
<p>슬라이드의 큰 흐름은 다음처럼 잡으면 된다.</p>
<pre><code>Input (token + position)
 -&gt; Encoder blocks (self-attention + FFN)
 -&gt; Decoder blocks (masked self-attention + cross-attention + FFN)
 -&gt; Linear + Softmax
 -&gt; Output tokens</code></pre><h3 id="12-트랜스포머가-rnn보다-유리했던-이유">1.2 트랜스포머가 RNN보다 유리했던 이유</h3>
<ul>
<li><strong>병렬 처리 가능</strong>: 토큰을 순차적으로 처리하지 않고, 한 번에 행렬 연산으로 처리</li>
<li>번역 태스크에서 성능(BLEU)과 효율이 강점으로 제시됨</li>
<li>이후 <strong>BERT/GPT가 트랜스포머 블록을 채택</strong>하면서 “사전학습 → 적응”의 표준이 됨</li>
</ul>
<hr>
<h2 id="2-positional-encoding">2) Positional Encoding</h2>
<h3 id="21-왜-필요한가">2.1 왜 필요한가?</h3>
<ul>
<li>RNN은 입력이 <code>x1 → x2 → x3 ...</code> 순서대로 들어오므로 <strong>순서 정보가 구조에 내장</strong></li>
<li>트랜스포머는 병렬 처리로 토큰을 동시에 다루므로, 그냥 두면 <strong>토큰의 위치를 모름</strong></li>
<li>그래서 <strong>토큰 임베딩에 위치 정보를 더해</strong> 순서를 주입한다</li>
</ul>
<h4 id="입력-단계개념">입력 단계(개념)</h4>
<pre><code>token ids -&gt; Embedding(d_model)
          -&gt; + PositionalEncoding(d_model)
          -&gt; Encoder/Decoder blocks</code></pre><hr>
<h3 id="22-그럼-위치를-숫자로-주면-되지-않나가-왜-위험한가">2.2 “그럼 위치를 숫자로 주면 되지 않나?”가 왜 위험한가</h3>
<h4 id="a-그냥-0123-더하기">(A) 그냥 0,1,2,3… 더하기</h4>
<ul>
<li>값 스케일이 커지며 <strong>학습 안정성</strong>(초기 분포, 스케일)이 흔들릴 수 있음</li>
</ul>
<h4 id="b-01-정규화-예-0-033-066-1">(B) 0~1 정규화 (예: 0, 0.33, 0.66, 1)</h4>
<ul>
<li>문장 길이가 바뀌면 같은 “2번째 토큰”도 값이 바뀜
→ <strong>같은 위치가 일관된 의미를 갖기 어려움</strong></li>
</ul>
<h4 id="c-원-핫이진-벡터">(C) 원-핫/이진 벡터</h4>
<ul>
<li>길이에 무관하게 같은 위치에 같은 벡터를 할당 가능</li>
<li>하지만 위치 간 <strong>상대 거리/기하학적 관계</strong>를 표현하기가 까다로움(왜곡 가능)</li>
</ul>
<hr>
<h3 id="23-sinusoidal-positional-encoding-원-논문-정석">2.3 Sinusoidal Positional Encoding (원 논문 정석)</h3>
<ul>
<li>짝수 차원에는 sin, 홀수 차원에는 cos를 번갈아 사용</li>
</ul>
<p>$$
PE(pos, 2i) = \sin\left(\frac{pos}{10000^{\frac{2i}{d_{model}}}}\right)
$$</p>
<p>$$
PE(pos, 2i+1) = \cos\left(\frac{pos}{10000^{\frac{2i}{d_{model}}}}\right)
$$</p>
<h4 id="직관강의-흐름-정리">직관(강의 흐름 정리)</h4>
<ul>
<li>sin/cos 범위는 대략 ([-1, 1]) → <strong>스케일 폭주 방지</strong></li>
<li>차원마다 주파수가 달라서 <strong>짧은/긴 거리 관계를 다양한 해상도로 표현</strong></li>
<li>“위치 변화가 벡터를 회전시키는 것처럼” 이해해도 직관적으로 도움이 됨</li>
</ul>
<hr>
<h3 id="24-실전-positional-encoding-구현-예시-이해용">2.4 (실전) Positional Encoding 구현 예시 (이해용)</h3>
<pre><code class="language-python">import numpy as np

def positional_encoding(max_len: int, d_model: int) -&gt; np.ndarray:
    pos = np.arange(max_len)[:, None]              # (max_len, 1)
    i = np.arange(d_model)[None, :]                # (1, d_model)

    angle_rates = 1 / (10000 ** (2 * (i // 2) / d_model))
    angles = pos * angle_rates                     # (max_len, d_model)

    pe = np.zeros_like(angles)
    pe[:, 0::2] = np.sin(angles[:, 0::2])          # even
    pe[:, 1::2] = np.cos(angles[:, 1::2])          # odd
    return pe                                      # (max_len, d_model)</code></pre>
<hr>
<h2 id="3-self-attention--scaled-dot-product-attention">3) Self-Attention / Scaled Dot-Product Attention</h2>
<h3 id="31-q-k-v를-한-문장으로">3.1 Q, K, V를 한 문장으로</h3>
<ul>
<li><strong>Query(Q)</strong>: “지금 내가 무엇을 찾고 싶은가?”</li>
<li><strong>Key(K)</strong>: “각 토큰이 어떤 특징을 갖고 있어 매칭 기준이 되는가?”</li>
<li><strong>Value(V)</strong>: “매칭되면 실제로 가져올 정보(내용)는 무엇인가?”</li>
</ul>
<p>요약하면, 관계의 기준(Q/K)과 실제 내용(V)을 분리하면 <strong>표현력이 좋아진다</strong>는 흐름이다.</p>
<hr>
<h3 id="32-수식정석">3.2 수식(정석)</h3>
<p>$$
\mathrm{Attention}(Q, K, V)
= \mathrm{softmax}\left(\frac{QK^{\top}}{\sqrt{d_k}}\right)V
$$</p>
<h4 id="scaledsqrtd_k의-의미-중요">“Scaled(/sqrt(d_k))”의 의미 (중요)</h4>
<ul>
<li>내적 (QK^\top)는 차원 (d_k)가 커질수록 값의 분산이 커지기 쉬움</li>
<li>그대로 softmax에 넣으면 값이 과도하게 커져 <strong>softmax가 포화(거의 0/1)</strong> → 학습 불안정</li>
<li>그래서 (\sqrt{d_k})로 나눠 스케일을 안정화한다</li>
</ul>
<hr>
<h3 id="33-차원shape-추적-구현-실수-방지-핵심">3.3 차원(shape) 추적 (구현 실수 방지 핵심)</h3>
<p>시퀀스 길이 (L), 모델 차원 (d_{model}), 헤드 차원 (d_k, d_v)</p>
<table>
<thead>
<tr>
<th>항목</th>
<th>shape</th>
</tr>
</thead>
<tbody><tr>
<td>입력 (X)</td>
<td>((L, d_{model}))</td>
</tr>
<tr>
<td>(W^Q, W^K)</td>
<td>((d_{model}, d_k))</td>
</tr>
<tr>
<td>(W^V)</td>
<td>((d_{model}, d_v))</td>
</tr>
<tr>
<td>(Q=XW^Q)</td>
<td>((L, d_k))</td>
</tr>
<tr>
<td>(K=XW^K)</td>
<td>((L, d_k))</td>
</tr>
<tr>
<td>(V=XW^V)</td>
<td>((L, d_v))</td>
</tr>
<tr>
<td>(QK^\top)</td>
<td>((L, L))</td>
</tr>
<tr>
<td>(\mathrm{softmax}(QK^\top/\sqrt{d_k}))</td>
<td>((L, L))</td>
</tr>
<tr>
<td>출력 ((\cdot)V)</td>
<td>((L, d_v))</td>
</tr>
</tbody></table>
<blockquote>
<p>강의의 “(3×4)·(4×2)=(3×2)” 감각은 맞지만, 실제로는 <strong>X와 W의 shape를 일관되게 유지</strong>하는 게 핵심이다.</p>
</blockquote>
<hr>
<h2 id="4-masked-self-attention-왜-디코더에서만-마스크">4) Masked Self-Attention (왜 디코더에서만 마스크?)</h2>
<h3 id="41-이유-생성autoregressive은-미래-토큰을-보면-안-됨">4.1 이유: 생성(Autoregressive)은 “미래 토큰”을 보면 안 됨</h3>
<ul>
<li>디코더는 다음 단어를 예측해야 함</li>
<li>예: <code>I love you</code>에서 <code>love</code>를 예측할 때, 미래 토큰 <code>you</code>를 보면 치팅</li>
<li>그래서 디코더 self-attention에는 <strong>look-ahead mask(상삼각 마스크)</strong>를 적용한다</li>
</ul>
<h4 id="마스크-직관">마스크 직관</h4>
<pre><code>허용: 과거/현재
금지: 미래

t=2일 때 볼 수 있는 범위: [1..2]</code></pre><h3 id="42-구현-관점핵심">4.2 구현 관점(핵심)</h3>
<ul>
<li>마스크로 가려지는 위치의 score에 매우 작은 값을 더함(실제로는 (-\infty)에 가까운 값)</li>
<li>softmax를 거치면 해당 확률이 거의 0이 되어 영향이 사라짐</li>
</ul>
<hr>
<h2 id="5-multi-head-attention-왜-헤드를-여러-개-쓰나">5) Multi-Head Attention (왜 헤드를 여러 개 쓰나?)</h2>
<h3 id="51-직관강의-흐름">5.1 직관(강의 흐름)</h3>
<ul>
<li>어떤 헤드는 <strong>주어-동사</strong> 관계를 강하게 보고</li>
<li>어떤 헤드는 <strong>지시어/대명사</strong> 관계를 보고</li>
<li>어떤 헤드는 <strong>구문 패턴</strong>을 본다
→ 한 가지 attention만으로 모든 관계를 잡기 어렵기 때문에 <strong>여러 관점(헤드)</strong>으로 본다</li>
</ul>
<hr>
<h3 id="52-수식정석">5.2 수식(정석)</h3>
<p>$$
\mathrm{head}_i = \mathrm{Attention}(QW_i^Q,; KW_i^K,; VW_i^V)
$$</p>
<p>$$
\mathrm{MultiHead}(Q, K, V) = \mathrm{Concat}(\mathrm{head}_1, \ldots, \mathrm{head}_h)W^O
$$</p>
<h3 id="53-차원-설계-residual을-위한-차원-맞추기">5.3 차원 설계 (Residual을 위한 “차원 맞추기”)</h3>
<ul>
<li>residual add를 하려면 입력/출력 차원이 같아야 함</li>
<li>보통 (d_{model})을 헤드 수 (h)로 나눔</li>
</ul>
<p>$$
d_k = d_v = \frac{d_{model}}{h}
$$</p>
<ul>
<li>각 헤드 출력 concat → 다시 ((L, d_{model}))로 돌아와 residual add 가능</li>
</ul>
<hr>
<h2 id="6-skip-connection--layer-normalization-add--norm">6) Skip Connection + Layer Normalization (Add &amp; Norm)</h2>
<p>슬라이드에서도 “성능 향상: Skip / LayerNorm”을 따로 강조한다.</p>
<h3 id="61-residualskip-connection">6.1 Residual(Skip) Connection</h3>
<ul>
<li>목적: 깊은 네트워크에서 <strong>그라디언트 흐름</strong> 개선 + 학습 안정화</li>
</ul>
<p>$$
y = x + \mathrm{SubLayer}(x)
$$</p>
<h3 id="62-layernorm-batchnorm과-차이">6.2 LayerNorm (BatchNorm과 차이)</h3>
<ul>
<li>BatchNorm: 배치 통계에 의존 → 배치 작으면 불안정</li>
<li>LayerNorm: 토큰(샘플) 내부 feature 차원 기준 정규화 → 배치 크기에 덜 민감</li>
</ul>
<table>
<thead>
<tr>
<th>방법</th>
<th>평균/분산을 어디서 계산?</th>
<th>NLP에서 선호</th>
</tr>
</thead>
<tbody><tr>
<td>BatchNorm</td>
<td>배치 차원</td>
<td>배치 작아지면 불리</td>
</tr>
<tr>
<td>LayerNorm</td>
<td>feature((d_{model})) 차원</td>
<td>트랜스포머 표준</td>
</tr>
</tbody></table>
<hr>
<h2 id="7-encoderdecoder-블록-전체-흐름-한-장-요약">7) Encoder/Decoder 블록 전체 흐름 한 장 요약</h2>
<h3 id="71-encoder-한-층">7.1 Encoder (한 층)</h3>
<pre><code>X
 -&gt; Multi-Head Self-Attention
 -&gt; Add &amp; Norm (Residual + LayerNorm)
 -&gt; Feed Forward
 -&gt; Add &amp; Norm</code></pre><h3 id="72-decoder-한-층">7.2 Decoder (한 층)</h3>
<pre><code>Y (shifted right)
 -&gt; Masked Multi-Head Self-Attention
 -&gt; Add &amp; Norm
 -&gt; Encoder-Decoder Attention (Q: decoder, K/V: encoder)
 -&gt; Add &amp; Norm
 -&gt; Feed Forward
 -&gt; Add &amp; Norm</code></pre><hr>
<h2 id="8-다음-챕터-대비-gpt-vs-bert에서-어디가-달라지나">8) (다음 챕터 대비) GPT vs BERT에서 어디가 달라지나?</h2>
<ul>
<li><strong>BERT</strong>: Encoder-only (양방향 문맥 이해)</li>
<li><strong>GPT</strong>: Decoder-only (masked self-attention 기반, 다음 토큰 생성)</li>
</ul>
<blockquote>
<p>따라서 이번 파트의 “Positional Encoding, (Masked) Multi-Head Attention, LayerNorm, Residual”은 그대로 GPT/BERT 이해의 기반이 된다.</p>
</blockquote>
<hr>
<p>아래는 네 원문을 <strong>강의 흐름 그대로</strong> 유지하면서, Velog에서 <strong>수식이 깨지지 않도록 전부 <code>$$ ... $$</code>로 통일</strong>하고, <strong>표/ASCII/shape 추적/단계별 정리</strong>까지 “교재” 톤으로 완성한 최종본이야. 그대로 복붙하면 돼.</p>
<hr>
<h1 id="3-transformer-for-computer-vision-vit-detr">3. Transformer for Computer Vision (ViT, DETR)</h1>
<h2 id="0-이-강의에서-얻어야-하는-것-학습-목표">0) 이 강의에서 얻어야 하는 것 (학습 목표)</h2>
<ol>
<li><strong>왜 비전에서 트랜스포머를 쓰려 했는지</strong></li>
<li><strong>ViT 핵심 아이디어</strong>: 이미지를 <strong>토큰 시퀀스</strong>로 바꿔 Transformer Encoder에 넣기</li>
<li><strong>DETR 핵심 아이디어</strong>: Detection을 <strong>집합(set) 예측</strong>으로 바꾸고 <strong>NMS 제거</strong></li>
<li>두 모델 모두에서 <strong>Positional Encoding/Embedding이 왜 필수인지</strong></li>
<li>면접/실무에서 말할 수 있게: <strong>장점·단점·언제 쓰는지</strong></li>
</ol>
<hr>
<h2 id="1-도입-nlp에서-되면-cv에서도-되지-않을까--cnn의-inductive-bias">1) 도입: “NLP에서 되면 CV에서도 되지 않을까?” + CNN의 Inductive Bias</h2>
<h3 id="11-cnn이-강한-이유inductive-bias">1.1 CNN이 강한 이유(Inductive Bias)</h3>
<p>CNN은 이미지에 맞는 “가정”이 구조적으로 들어가 있어서, 비교적 적은 데이터에서도 잘 학습되는 경향이 있습니다.</p>
<ul>
<li><strong>가정 1: 지역성(Locality)</strong>
가까운 픽셀들이 의미를 만든다 → 작은 커널로도 잘 배움</li>
<li><strong>가정 2: 가중치 공유(Weight Sharing)</strong>
같은 패턴(엣지 등)은 위치가 달라도 같은 필터로 잡힌다</li>
<li><strong>가정 3: Translation Equivariance</strong>
물체가 이동하면 feature map도 같이 이동
<em>(완전한 invariance는 pooling/구조 설계로 얻는 경우가 많음)</em></li>
</ul>
<h3 id="12-cnn의-취약점강의-예시를-정확히-정리">1.2 CNN의 취약점(강의 예시를 정확히 정리)</h3>
<p>강의의 “눈/코/입 위치가 이상해도 얼굴로 인식” 요지는 다음처럼 정리하면 더 정확합니다.</p>
<ul>
<li>CNN은 <strong>국소 패턴</strong>은 매우 잘 잡지만,</li>
<li><strong>전역 관계(눈-코-입의 상대 위치)</strong>를 “자동으로 강제”하진 않음</li>
<li>따라서 데이터/학습 조건에 따라 <strong>부분만 맞으면 전체를 맞다고 착각</strong>하는 문제가 생길 수 있음</li>
</ul>
<hr>
<h2 id="2-vit-vision-transformer--이미지를-토큰으로-만든다">2) ViT (Vision Transformer) — “이미지를 토큰으로 만든다”</h2>
<blockquote>
<p>핵심 문장: <strong>이미지를 패치로 쪼개서, 각 패치를 토큰처럼 만들어 Transformer Encoder에 입력한다.</strong></p>
</blockquote>
<hr>
<h3 id="21-vit-전체-흐름-step-by-step">2.1 ViT 전체 흐름 (Step-by-step)</h3>
<h4 id="step-1-patchify-이미지를-p×p-패치로-쪼갠다">Step 1) Patchify: 이미지를 P×P 패치로 쪼갠다</h4>
<ul>
<li>입력 이미지:</li>
</ul>
<p>$$
X \in \mathbb{R}^{H \times W \times C}
$$</p>
<ul>
<li>패치 크기: (P \times P)</li>
<li>패치 개수:</li>
</ul>
<p>$$
N = \frac{H}{P}\cdot \frac{W}{P}
$$</p>
<ul>
<li>각 패치를 펼치기(flatten):</li>
</ul>
<p>$$
x_{p,i} \in \mathbb{R}^{P^2\cdot C}
$$</p>
<p>✅ <strong>shape 추적(예시)</strong></p>
<ul>
<li>이미지: (224\times224\times3)</li>
<li>패치: (16\times16)</li>
<li>패치 개수: (N=(224/16)^2=14^2=196)</li>
<li>패치 벡터 차원: (16^2\cdot3=768)</li>
</ul>
<hr>
<h4 id="step-2-linear-projection-패치를-d차원-토큰으로-바꾼다">Step 2) Linear Projection: 패치를 D차원 토큰으로 바꾼다</h4>
<ul>
<li>학습 가능한 선형 변환(프로젝션):</li>
</ul>
<p>$$
z_i = x_{p,i}W_E + b,\quad z_i \in \mathbb{R}^{D}
$$</p>
<ul>
<li>행렬 차원:</li>
</ul>
<p>$$
W_E \in \mathbb{R}^{(P^2C)\times D}
$$</p>
<hr>
<h4 id="step-3-cls-토큰-붙이기--positional-embedding-더하기">Step 3) [CLS] 토큰 붙이기 + Positional Embedding 더하기</h4>
<ul>
<li>분류를 위해 맨 앞에 <strong>[CLS] 토큰</strong> 추가:</li>
</ul>
<p>$$
Z_0 = [z_{\text{cls}};; z_1;; \dots;; z_N]
$$</p>
<ul>
<li>위치 정보를 잃기 때문에 <strong>Positional Embedding</strong>을 더함:</li>
</ul>
<p>$$
Z = Z_0 + E_{\text{pos}}
$$</p>
<p>여기서</p>
<p>$$
E_{\text{pos}} \in \mathbb{R}^{(N+1)\times D}
$$</p>
<hr>
<h4 id="step-4-transformer-encoder-통과">Step 4) Transformer Encoder 통과</h4>
<ul>
<li>표준 Encoder 블록(MHSA + FFN + Residual + LayerNorm)을 (L)번 반복</li>
</ul>
<hr>
<h4 id="step-5-mlp-head로-분류">Step 5) MLP Head로 분류</h4>
<ul>
<li>마지막 층 출력에서 <strong>[CLS] 위치 벡터</strong>를 뽑아 분류:</li>
</ul>
<p>$$
\hat{y} = \mathrm{MLP}(Z^{(L)}_{\text{cls}})
$$</p>
<hr>
<h3 id="22-중요-vit는-왜-큰-데이터가-필요했나">2.2 (중요) ViT는 왜 큰 데이터가 필요했나?</h3>
<p>강의의 “그냥 쓰면 훈련이 잘 안 된다”는 말을 <strong>원인-결과</strong>로 정확히 정리하면:</p>
<ul>
<li>CNN은 이미지에 맞는 inductive bias(지역성/공유/계층)가 있어서
<strong>상대적으로 적은 데이터</strong>에서도 안정적으로 학습되는 편</li>
<li>초기 ViT는 그 bias가 약해서
“무슨 패턴을 우선 배워야 하는지”를 <strong>데이터에서 더 많이 배워야 했음</strong></li>
<li>그래서 논문에서 <strong>대규모 데이터로 pretrain 후 fine-tune</strong>을 강조(JFT-300M 등)</li>
</ul>
<hr>
<h3 id="23-vit-시각화-결과강의-포인트-3가지">2.3 ViT 시각화 결과(강의 포인트 3가지)</h3>
<ol>
<li><strong>Embedding filter가 low-level 패턴을 학습</strong></li>
</ol>
<ul>
<li>CNN 1층이 엣지/텍스처를 배우듯, ViT 초기 층에서도 유사 패턴이 나타남</li>
</ul>
<ol start="2">
<li><strong>Positional embedding 이후 공간 구조가 드러남</strong></li>
</ol>
<ul>
<li>위치 정보가 들어가면서 “가까운 패치끼리 비슷하게 보는 경향” 같은 구조가 관찰</li>
</ul>
<ol start="3">
<li><strong>Layer가 깊어질수록 attention distance가 커짐</strong></li>
</ol>
<ul>
<li>초기층은 근처 패치, 후반층은 먼 패치까지 보며
CNN의 receptive field가 넓어지는 느낌과 유사한 현상</li>
</ul>
<hr>
<h3 id="24-vit-한-장-요약면접용">2.4 ViT 한 장 요약(면접용)</h3>
<ul>
<li>한 줄: <strong>“이미지를 패치 토큰 시퀀스로 바꿔 Transformer Encoder로 분류한다.”</strong></li>
<li>장점: 전역 관계를 MHSA로 직접 모델링</li>
<li>단점(초기 ViT 관점): CNN bias가 약해 <strong>큰 데이터/사전학습 의존도가 큼</strong></li>
</ul>
<hr>
<h2 id="3-detr--detection을-set-prediction으로-바꿔-nms-제거">3) DETR — “Detection을 Set Prediction으로 바꿔 NMS 제거”</h2>
<p>강의에서 “DETI”처럼 들린 건 <strong>DETR</strong>이 맞습니다.
<em>(End-to-End Object Detection with Transformers, ECCV 2020)</em></p>
<hr>
<h3 id="31-기존-detection의-골칫거리-후보-박스가-많아-nms-필요">3.1 기존 Detection의 골칫거리: 후보 박스가 많아 NMS 필요</h3>
<ul>
<li>앵커/후보가 많아 같은 물체에 박스가 여러 개 겹쳐 나옴</li>
<li>그래서 후처리로 <strong>NMS(Non-Maximum Suppression)</strong>로 중복 제거</li>
</ul>
<hr>
<h3 id="32-detr의-핵심-아이디어-step-by-step">3.2 DETR의 핵심 아이디어 (Step-by-step)</h3>
<h4 id="step-1-backbonecnn으로-feature-map-추출">Step 1) Backbone(CNN)으로 feature map 추출</h4>
<ul>
<li>ViT처럼 처음부터 패치 토큰화하는 게 아니라,</li>
<li>CNN으로 feature map을 뽑고 Transformer에 입력</li>
</ul>
<p>예:</p>
<p>$$
F \in \mathbb{R}^{H&#39; \times W&#39; \times C&#39;}
$$</p>
<hr>
<h4 id="step-2-feature-map을-시퀀스로-펼치고flatten-2d-positional-encoding-추가">Step 2) feature map을 시퀀스로 펼치고(Flatten), 2D Positional Encoding 추가</h4>
<ul>
<li>Flatten 후 시퀀스 길이:</li>
</ul>
<p>$$
L = H&#39;\cdot W&#39;
$$</p>
<ul>
<li>펼친 형태(개념):</li>
</ul>
<p>$$
X \in \mathbb{R}^{L \times C&#39;}
$$</p>
<ul>
<li>2D 위치 정보를 유지하기 위해 positional encoding을 더함:</li>
</ul>
<p>$$
X \leftarrow X + E_{\text{pos}}
$$</p>
<hr>
<h4 id="step-3-transformer-encoder로-전역-컨텍스트-통합">Step 3) Transformer Encoder로 전역 컨텍스트 통합</h4>
<ul>
<li>Encoder가 이미지 전체 정보를 통합한 표현을 만든다</li>
</ul>
<hr>
<h4 id="step-4-decoder에-object-queries를-넣는다-detr-감성-핵심">Step 4) Decoder에 “Object Queries”를 넣는다 (DETR 감성 핵심)</h4>
<ul>
<li>고정 개수 (N_q)개의 <strong>학습 가능한 query 벡터</strong></li>
</ul>
<p>$$
Q \in \mathbb{R}^{N_q \times d_{model}}
$$</p>
<ul>
<li>각 query가 “하나의 물체 슬롯”처럼 동작하도록 학습된다</li>
</ul>
<hr>
<h4 id="step-5-각-query-출력에서-클래스-박스-예측">Step 5) 각 query 출력에서 (클래스, 박스) 예측</h4>
<ul>
<li><p>각 query마다 출력:</p>
<ul>
<li>class logits: (K) classes + <strong>no-object</strong></li>
<li>box: ((c_x, c_y, w, h)) (보통 정규화)</li>
</ul>
</li>
</ul>
<hr>
<h3 id="33-no-object-클래스는-왜-필요">3.3 no-object 클래스는 왜 필요?</h3>
<p>고정 개수 query를 쓰면, 이미지에 물체가 2개여도 query는 예를 들어 100개일 수 있습니다.</p>
<ul>
<li>남는 query들은 “아무 물체도 담당하지 않음”이어야 함</li>
<li>그래서 <strong>no-object 클래스</strong>가 필요하다</li>
</ul>
<hr>
<h3 id="34-nms를-없애는-핵심-장치-bipartite-matching--hungarian-algorithm">3.4 NMS를 없애는 핵심 장치: Bipartite Matching + Hungarian Algorithm</h3>
<h4 id="핵심-목표">핵심 목표</h4>
<p><strong>“각 GT(정답 물체)에 예측 query를 1개씩만 매칭하자.”</strong>
→ 그러면 같은 물체를 여러 query가 중복 예측하는 학습이 줄어듦 → NMS 의존이 감소</p>
<h4 id="step-by-step">Step-by-step</h4>
<ol>
<li>예측 (N_q)개와 GT (N_{gt})개의 <strong>비용(cost) 행렬</strong> 구성</li>
<li>비용 합이 최소가 되는 <strong>1:1 매칭</strong>을 찾음 (Hungarian Algorithm)</li>
<li>그 매칭 결과로 loss를 계산하고 학습</li>
</ol>
<hr>
<h3 id="35-detr-loss를-직관으로-이해하기">3.5 DETR Loss를 “직관”으로 이해하기</h3>
<p>보통 손실은 다음 두 덩어리로 이해하면 충분합니다.</p>
<ul>
<li><p><strong>Class loss</strong>: 각 query가 어떤 클래스인지(or no-object인지)</p>
</li>
<li><p><strong>Box loss</strong>: 박스 좌표가 얼마나 맞는지</p>
<ul>
<li>L1 loss</li>
<li>IoU 계열 손실(GIoU 등)을 함께 쓰는 경우가 많음</li>
</ul>
</li>
</ul>
<p>헝가리안 매칭은 “<strong>loss를 최소화하는 1:1 매칭을 고르는 과정</strong>”으로 이해하면 정확합니다.</p>
<hr>
<h2 id="4-vit-vs-detr-vs-cnn-한-번에-정리">4) ViT vs DETR vs CNN 한 번에 정리</h2>
<table>
<thead>
<tr>
<th>구분</th>
<th>CNN(전통)</th>
<th>ViT</th>
<th>DETR</th>
</tr>
</thead>
<tbody><tr>
<td>입력 표현</td>
<td>픽셀→컨볼루션</td>
<td><strong>패치→토큰 시퀀스</strong></td>
<td>CNN feature map→시퀀스</td>
</tr>
<tr>
<td>핵심 강점</td>
<td>적은 데이터에도 강함(bias)</td>
<td>전역 관계 모델링이 깔끔</td>
<td><strong>NMS 제거</strong>, end-to-end set prediction</td>
</tr>
<tr>
<td>포지션 처리</td>
<td>구조적으로 내재(공간)</td>
<td><strong>pos embedding 필수</strong></td>
<td><strong>2D pos encoding 필수</strong></td>
</tr>
<tr>
<td>주 용도</td>
<td>분류/검출/세그 전반</td>
<td>분류(원형)</td>
<td>오브젝트 디텍션</td>
</tr>
</tbody></table>
<hr>
<h1 id="4-transformer-for-time-series-informer-중심">4. Transformer for Time Series (Informer 중심)</h1>
<h2 id="0-이-파트-한-줄-목표">0) 이 파트 한 줄 목표</h2>
<p>시계열 예측은 입력 길이 (L)이 매우 길어지기 쉬워서 <strong>Self-Attention 비용이 $(O($$L^2$$))$</strong> 로 폭증한다.
<strong>Informer(AAAI 2021)</strong> 는 이를 줄이기 위해 <strong>중요한 Query만 골라 계산하는 ProbSparse Attention</strong>으로 효율을 높여 <strong>Long Sequence Forecasting</strong>을 가능하게 하려는 모델이다.</p>
<hr>
<h2 id="1-용어발화-오류-교정-강의-이해-필수">1) 용어/발화 오류 교정 (강의 이해 필수)</h2>
<table>
<thead>
<tr>
<th>강의에서 들린 표현</th>
<th>올바른 표현</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>“트리플 AI”</td>
<td><strong>AAAI</strong></td>
<td>인공지능 분야 주요 학회 (AAAI Conference)</td>
</tr>
<tr>
<td>“리스트 / NS팀”</td>
<td><strong>LSTM</strong></td>
<td>시계열에서 전통적으로 많이 쓰던 RNN 계열</td>
</tr>
<tr>
<td>“인포멀/인포먼트”</td>
<td><strong>Informer</strong></td>
<td>Long sequence time-series forecasting 모델</td>
</tr>
<tr>
<td>“커다리티/쿼드리티”</td>
<td><strong>Quadratic complexity</strong></td>
<td>길이 (L)에서 비용이 (O(L^2))로 증가</td>
</tr>
<tr>
<td>“프로보스/프로모션 어텐션”</td>
<td><strong>ProbSparse Attention</strong></td>
<td>활성 Query만 골라 attention 계산</td>
</tr>
<tr>
<td>“확인 페이스”</td>
<td><strong>Hugging Face</strong></td>
<td>모델/코드 공유 플랫폼</td>
</tr>
<tr>
<td>“기타에서 다운”</td>
<td><strong>GitHub에서 다운</strong></td>
<td>코드 저장소</td>
</tr>
</tbody></table>
<h3 id="✅-중요한-정정-1--샘플링-예시-숫자">✅ 중요한 정정 1 — 샘플링 예시 숫자</h3>
<p>강의에서 “30초 + 100kHz → 3000개 입력”이라고 했다면 수치가 어긋나 있어요.</p>
<ul>
<li>100kHz = 초당 100,000 샘플</li>
<li>30초면:</li>
</ul>
<p>$$
L = 30 \times 100{,}000 = 3{,}000{,}000
$$</p>
<p>즉 <strong>3,000,000개</strong>가 맞습니다.
“3000개”라는 발화는 실제 의도가 <strong>100Hz(초당 100샘플)</strong> 정도였을 가능성이 큽니다.</p>
<hr>
<h2 id="2-왜-시계열은-transformer가-힘든가-핵심-논리-step-by-step">2) 왜 시계열은 Transformer가 힘든가? (핵심 논리 Step-by-step)</h2>
<h3 id="step-1-시계열은-입력-길이-l이-매우-길어지기-쉽다">Step 1) 시계열은 입력 길이 (L)이 매우 길어지기 쉽다</h3>
<ul>
<li>자연어 문장은 보통 수십~수백 토큰</li>
<li>센서/로그/계측 데이터는 초당 샘플이 누적되어 <strong>수천~수백만 포인트</strong>까지 늘어남</li>
</ul>
<h3 id="step-2-self-attention은-ltimes-l-어텐션-행렬이-생긴다">Step 2) Self-Attention은 (L\times L) 어텐션 행렬이 생긴다</h3>
<p>기본 self-attention은 다음을 계산한다.</p>
<p>$$
A = \mathrm{softmax}\left(\frac{QK^\top}{\sqrt{d_k}}\right)
$$</p>
<p>여기서 (A)의 shape는:</p>
<p>$$
A \in \mathbb{R}^{L \times L}
$$</p>
<h3 id="step-3-그래서-계산메모리가-ol2로-증가한다">Step 3) 그래서 계산/메모리가 (O(L^2))로 증가한다</h3>
<p>예를 들어 (L=3000)이면,</p>
<p>$$
L^2 = 3000 \times 3000 = 9{,}000{,}000
$$</p>
<p>어텐션 행렬만 <strong>900만 원소</strong>가 된다.
여기에 <strong>레이어 수, 헤드 수, 배치 크기</strong>까지 곱해지면 시계열에서는 큰 부담이 된다.</p>
<hr>
<h2 id="3-informer-핵심-아이디어-모든-query를-다-계산하지-말자">3) Informer 핵심 아이디어: “모든 Query를 다 계산하지 말자”</h2>
<p>강의의 직관은 다음으로 요약할 수 있다.</p>
<h3 id="31-lazy-query-vs-active-query">3.1 Lazy Query vs Active Query</h3>
<ul>
<li><strong>Lazy Query</strong>: 모든 Key에 대한 attention 분포가 거의 균등(평평)
→ 계산해도 얻는 정보가 적다</li>
<li><strong>Active Query</strong>: 특정 Key에 attention이 강하게 몰림
→ 중요한 상호작용이므로 계산 가치가 크다</li>
</ul>
<pre><code class="language-text">Lazy:   [0.02 0.02 0.02 0.02 ...]  (거의 균등)
Active: [0.60 0.20 0.10 0.05 ...]  (특정 키에 집중)</code></pre>
<hr>
<h2 id="4-probsparse-attention-active-query만-뽑아서-계산">4) ProbSparse Attention: “Active Query만 뽑아서 계산”</h2>
<h3 id="41-핵심-아이디어">4.1 핵심 아이디어</h3>
<ul>
<li>전체 Query 중에서 <strong>상위 (u)개(활성 Query)</strong>만 골라 attention을 계산</li>
<li>나머지는 근사/생략하여 비용을 줄인다</li>
</ul>
<p>강의에서 “Top 6 query” 같은 표현은 보통 다음을 의미한다.</p>
<ul>
<li>전체 Query 중 <strong>상위 (u)</strong>개만 attention 계산</li>
<li>(u)는 고정 숫자일 수도 있고, 길이 (L)에 따라 정해질 수도 있음(설계/실험에 따라)</li>
</ul>
<h3 id="✅-중요한-정정-2--uniform처럼-만들자가-아니라-uniform에서-멀수록-중요">✅ 중요한 정정 2 — “uniform처럼 만들자”가 아니라 “uniform에서 멀수록 중요”</h3>
<p>강의에서 “uniform(1/Lk)처럼 만들도록 loss를 준다”처럼 들렸다면 오해가 생길 수 있어요.
이 파트는 보통 아래 흐름으로 이해하는 게 자연스럽습니다.</p>
<ol>
<li>어떤 Query의 attention 분포가 <strong>uniform에 가까우면</strong> (lazy) 정보량이 적다</li>
<li>uniform에서 <strong>멀수록</strong> (active) 특정 Key에 집중하므로 중요하다</li>
<li>따라서 <strong>uniform에서 많이 벗어난 Query</strong>를 골라 계산한다</li>
</ol>
<p>즉 결론은:</p>
<blockquote>
<p>“uniform처럼 만들자”가 아니라
<strong>“uniform에서 많이 벗어난(active) Query를 골라 계산하자”</strong> 가 핵심입니다.</p>
</blockquote>
<hr>
<h2 id="5-informer-예측-구조-encoderdecoder-입력-구성">5) Informer 예측 구조: Encoder–Decoder 입력 구성</h2>
<p>시계열 예측에서는 디코더 입력을 다음처럼 구성하는 방식이 흔합니다.</p>
<h3 id="51-encoder-input--decoder-input">5.1 Encoder input / Decoder input</h3>
<ul>
<li><p><strong>Encoder input</strong> ((X_{enc})): 과거 관측 시계열(긴 구간)</p>
</li>
<li><p><strong>Decoder input</strong>: 두 부분으로 구성</p>
<ol>
<li>과거 끝부분 일부(known tail): 실제 관측값 일부를 넣어 시작점을 제공</li>
<li>미래 구간 placeholder: 예측할 길이만큼 0 또는 마스크 값으로 자리만 확보</li>
</ol>
</li>
</ul>
<h3 id="52-전체-흐름그림">5.2 전체 흐름(그림)</h3>
<pre><code class="language-mermaid">flowchart LR
  A[Past series X_enc] --&gt; Enc[Encoder]
  B[Known tail tokens] --&gt; DecIn[Decoder input]
  C[Future placeholders (zeros/mask)] --&gt; DecIn
  Enc --&gt; Dec[Decoder]
  DecIn --&gt; Dec
  Dec --&gt; Yhat[Forecast Y_hat]
  Ytrue[Ground truth future] --&gt; Loss
  Yhat --&gt; Loss</code></pre>
<h3 id="53-학습은-어떻게-진행되나">5.3 학습은 어떻게 진행되나?</h3>
<ul>
<li>디코더 출력 (\hat{Y})를 실제 미래 (Y)와 비교해 loss(MSE 등)를 최소화하도록 학습</li>
</ul>
<p>예:</p>
<p>$$
\mathcal{L} = \frac{1}{T}\sum_{t=1}^{T} (Y_t - \hat{Y}_t)^2
$$</p>
<p>핵심은 “긴 시퀀스를 다 보는 대신, 계산할 attention을 줄여 효율을 확보”하는 방향입니다.</p>
<hr>
<h2 id="6-차원shape-추적-구현-시-실수-방지">6) 차원(shape) 추적 (구현 시 실수 방지)</h2>
<p>시퀀스 길이 (L), 모델 차원 (d_{model}), 헤드 차원 (d_k)</p>
<table>
<thead>
<tr>
<th>항목</th>
<th>shape</th>
</tr>
</thead>
<tbody><tr>
<td>입력 (X)</td>
<td>((L, d_{model}))</td>
</tr>
<tr>
<td>(Q, K, V)</td>
<td>((L, d_k)), ((L, d_k)), ((L, d_v))</td>
</tr>
<tr>
<td>$(QK^\top)$</td>
<td>((L, L))</td>
</tr>
<tr>
<td>$(A=\mathrm{softmax}(QK^\top/\sqrt{d_k}))$</td>
<td>((L, L))</td>
</tr>
<tr>
<td>출력 (AV)</td>
<td>((L, d_v))</td>
</tr>
</tbody></table>
<p>Informer는 여기서 <strong>모든 Query에 대해 $(L\times L)$ 계산을 하지 않도록</strong> 줄이는 게 핵심이다.</p>
<hr>
<h1 id="5-bert--gpt">5 BERT &amp; GPT</h1>
<h2 id="51-이-교재-사용법">5.1 이 교재 사용법</h2>
<ol>
<li><strong>[타임라인 ↔ 슬라이드]</strong>로 “지금 강의가 어느 페이지인지” 먼저 잡습니다.</li>
<li>각 파트는 아래 순서로 공부하면 가장 안정적으로 이해가 됩니다.</li>
</ol>
<ul>
<li><strong>정확 용어/정의(발화 오류 교정 포함)</strong></li>
<li><strong>핵심 직관(그림/표로 요약)</strong></li>
<li><strong>수식(슬라이드/논문식 형태로 정확 표기 + 의미 해설)</strong></li>
<li><strong>면접/실무 답변 템플릿(15초 요약)</strong></li>
</ul>
<hr>
<h2 id="52-강의-음성-txt-↔-슬라이드-싱크-맵-pdf-페이지-기준">5.2 강의 음성 TXT ↔ 슬라이드 싱크 맵 (PDF 페이지 기준)</h2>
<table>
<thead>
<tr>
<th>음성(대략)</th>
<th align="right">PDF 페이지</th>
<th>주제</th>
<th>싱크 포인트(음성 키워드)</th>
</tr>
</thead>
<tbody><tr>
<td>00:02–02:51</td>
<td align="right">p2–p4</td>
<td>왜 BERT/GPT가 중요해졌나</td>
<td>“레이블 만들기 어렵다”, “자연어는 데이터는 많다”</td>
</tr>
<tr>
<td>02:51–07:22</td>
<td align="right">p3–p4</td>
<td>레이블링 난이도/데이터 특성 비교</td>
<td>번역/요약 “정답 정의가 애매”, “투표/다수결”</td>
</tr>
<tr>
<td>07:22–14:44</td>
<td align="right">p5–p6</td>
<td>(CV 예시로) 프리트레인–파인튜닝 / 트랜스퍼러닝</td>
<td>“로우레벨/하이레벨”, “파라미터 고정(Freeze)”</td>
</tr>
<tr>
<td>15:38–18:19</td>
<td align="right">p7</td>
<td>few-shot / zero-shot 직관</td>
<td>“서포트셋/쿼리셋”, “유사도 기반”</td>
</tr>
<tr>
<td>18:34–24:01</td>
<td align="right">p8–p10</td>
<td>용어가 엄밀하지 않다 + 도메인/러닝 패러다임 정의</td>
<td>“도메인=joint distribution”, “소스/타겟”</td>
</tr>
<tr>
<td>24:29–34:20</td>
<td align="right">p11–p19</td>
<td>GPT-1</td>
<td>“Generative Pre-Training”, “2-stage”, “L1/L2/L3”</td>
</tr>
<tr>
<td>35:14–50:18</td>
<td align="right">p20–p35</td>
<td>BERT</td>
<td>“bi-directional”, “MLM + NSP”, “segment embedding”</td>
</tr>
<tr>
<td>50:18–58:56</td>
<td align="right">p36–p44</td>
<td>GPT-2</td>
<td>“WebText”, “BPE”, “zero-shot”</td>
</tr>
<tr>
<td>58:56–01:05:03</td>
<td align="right">p45–p49</td>
<td>GPT-3 + 요약</td>
<td>“few-shot”, “gradient update 없이”, “정리 표”</td>
</tr>
</tbody></table>
<hr>
<h2 id="53-강의에서-자주-헷갈린-용어표현-정정-표">5.3 강의에서 자주 헷갈린 용어/표현 정정 표</h2>
<table>
<thead>
<tr>
<th>음성에서 들리는 표현</th>
<th>정식 용어</th>
<th>한 줄 정의</th>
</tr>
</thead>
<tbody><tr>
<td>“버터”</td>
<td><strong>BERT</strong></td>
<td><strong>Encoder 기반</strong> + <strong>MLM(마스크 토큰 복원)</strong> 중심 사전학습</td>
</tr>
<tr>
<td>“지피티”</td>
<td><strong>GPT</strong></td>
<td><strong>Decoder 기반</strong> + <strong>Causal LM(다음 토큰 예측)</strong> 중심</td>
</tr>
<tr>
<td>“언슈퍼바이즈 프리트레이닝”</td>
<td><strong>Self-supervised pretraining</strong></td>
<td>레이블 없이 <strong>예측 과제(MLM/다음토큰)</strong>로 학습</td>
</tr>
<tr>
<td>“트랜스포머 러닝” (문맥상)</td>
<td><strong>Transfer learning</strong></td>
<td>소스에서 학습한 표현/가중치를 타겟 태스크로 전이</td>
</tr>
<tr>
<td>“어블레이션”</td>
<td><strong>Ablation study</strong></td>
<td>요소를 제거/변형하며 성능 기여도를 확인</td>
</tr>
<tr>
<td>“바이디렉셔널”</td>
<td><strong>Bidirectional (BERT)</strong></td>
<td>좌/우 문맥을 함께 보며 표현학습</td>
</tr>
<tr>
<td>“레프트-투-라이트”</td>
<td><strong>Causal / Autoregressive (GPT)</strong></td>
<td>과거 토큰만 보고 다음 토큰을 예측(미래는 마스킹)</td>
</tr>
</tbody></table>
<hr>
<h1 id="54-part-a-왜-bertgpt가-폭발했나-p2p4">5.4 Part A. 왜 BERT/GPT가 폭발했나 (p2–p4)</h1>
<h2 id="541-강의-핵심-논리-step-by-step">5.4.1 강의 핵심 논리 (Step-by-step)</h2>
<h3 id="step-1-nlp는-입력-데이터-x가-매우-많다">Step 1) NLP는 입력 데이터 (X)가 매우 많다</h3>
<ul>
<li>웹/문서/댓글/로그 등 텍스트는 <strong>무한히 쌓인다</strong>(강의 요지)</li>
</ul>
<h3 id="step-2-하지만-레이블-y를-만들기-어렵다">Step 2) 하지만 레이블 (Y)를 만들기 어렵다</h3>
<ul>
<li><p>번역/요약/NLI 등은</p>
<ul>
<li>“정답의 정의” 자체가 애매하거나</li>
<li>사람마다 기준이 달라 <strong>합의(투표/다수결/가이드라인)</strong>가 필요</li>
</ul>
</li>
</ul>
<h3 id="step-3-결론-레이블-없이도-학습되는-과제로-먼저-크게-학습한다">Step 3) 결론: “레이블 없이도 학습되는 과제”로 먼저 크게 학습한다</h3>
<ul>
<li><strong>Self-supervised</strong>(자기지도) 과제(MLM/다음토큰예측)로 <strong>표현을 먼저 학습</strong></li>
<li>이후 필요한 태스크에 <strong>소량 레이블로 적응(파인튜닝/프롬프트)</strong></li>
</ul>
<hr>
<h2 id="542-p4-nlp-vs-biocv가-말하는-진짜-포인트">5.4.2 (p4) “NLP vs Bio/CV”가 말하는 진짜 포인트</h2>
<table>
<thead>
<tr>
<th>항목</th>
<th>Bio/CV(예: MRI 세그멘테이션)</th>
<th>NLP(예: 요약/의미/추론)</th>
</tr>
</thead>
<tbody><tr>
<td>입력 데이터 (X)</td>
<td>상대적으로 적음(수집 비용 큼)</td>
<td>매우 많음</td>
</tr>
<tr>
<td>레이블 (Y)</td>
<td>전문가가 만들면 “정답 정의가 비교적 명확”</td>
<td>“정답 정의 자체가 애매”한 경우 많음</td>
</tr>
<tr>
<td>병목</td>
<td>데이터 수집/품질</td>
<td><strong>레이블링 + 정답 정의</strong></td>
</tr>
<tr>
<td>자연스러운 전략</td>
<td>전이학습/파인튜닝</td>
<td><strong>대규모 사전학습 → 범용 표현 → 적응</strong></td>
</tr>
</tbody></table>
<hr>
<h1 id="55-part-b-pretrain-→-finetune--transfer--few-shot·zero-shot-p5p10">5.5 Part B. Pretrain → Finetune / Transfer / Few-shot·Zero-shot (p5–p10)</h1>
<h2 id="551-p5-cv-예시로-이해하는-프리트레인파인튜닝">5.5.1 (p5) CV 예시로 이해하는 “프리트레인–파인튜닝”</h2>
<p>강의의 “로우레벨/하이레벨 필터”를 NLP로 대응하면:</p>
<ul>
<li><strong>로우레벨</strong>: 기본 문법/표현/일반 문맥 패턴(범용)</li>
<li><strong>하이레벨</strong>: 특정 태스크(감성/QA/NER/분류)에 맞는 결정 경계(특화)</li>
</ul>
<h3 id="파라미터-고정freeze-직관">파라미터 고정(Freeze) 직관</h3>
<pre><code class="language-text">[Pretrained Backbone]
Layer1  (freeze)  &lt;- 범용 패턴
Layer2  (freeze)
Layer3  (train)   &lt;- 타겟 태스크에 맞게 조정
Head    (train)   &lt;- 태스크 출력층</code></pre>
<blockquote>
<p>실무 팁: 데이터가 적을수록 “하단 레이어 freeze + 상단만 학습”이 안정적인 출발점입니다.</p>
</blockquote>
<hr>
<h2 id="552-p6-transfer-learning-vs-finetuning-정리">5.5.2 (p6) Transfer learning vs Finetuning 정리</h2>
<table>
<thead>
<tr>
<th>용어</th>
<th>실무적으로 가장 정확한 정의</th>
<th>강의 예시 연결</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Pretraining</strong></td>
<td>대규모 데이터로 범용 표현 학습(대개 자기지도)</td>
<td>웹 텍스트로 LM 학습</td>
</tr>
<tr>
<td><strong>Finetuning</strong></td>
<td>타겟 태스크 데이터로 추가 학습(파라미터 업데이트)</td>
<td>“영-한 번역 데이터로 맞춘다”</td>
</tr>
<tr>
<td><strong>Transfer learning</strong></td>
<td>소스에서 학습한 표현/가중치를 타겟에 전이하는 전체 전략</td>
<td>“영-일로 먼저 배우고 영-한으로”</td>
</tr>
</tbody></table>
<hr>
<h2 id="553-p7-few-shot--one-shot--zero-shot-nlp-프롬프트로-정확-대응">5.5.3 (p7) Few-shot / One-shot / Zero-shot (NLP 프롬프트로 정확 대응)</h2>
<h3 id="정의시험면접">정의(시험/면접)</h3>
<ul>
<li><strong>Zero-shot</strong>: 예시 0개</li>
<li><strong>One-shot</strong>: 예시 1개</li>
<li><strong>Few-shot</strong>: 예시 (k)개</li>
</ul>
<h3 id="nlp-구현강의-번역-원샷을-정확-프롬프트로">NLP 구현(강의 “번역 원샷”을 정확 프롬프트로)</h3>
<pre><code class="language-text">[예시(1-shot)]
한국어: 나는 배고프다
영어: I am hungry

[문제]
한국어: 오늘 날씨가 좋다
영어:</code></pre>
<p>핵심:</p>
<ul>
<li><strong>파라미터 업데이트(gradient update) 없이</strong></li>
<li>프롬프트(지시 + 예시 + 질의)만으로 <strong>조건부 생성</strong>을 수행</li>
</ul>
<hr>
<h2 id="554-p8p10-domain러닝-패러다임-혼동-방지필수-2개">5.5.4 (p8–p10) Domain/러닝 패러다임 혼동 방지(필수 2개)</h2>
<h3 id="1-domain이란">(1) Domain이란?</h3>
<p>도메인 (D)는 보통 <strong>데이터가 생성/샘플링되는 분포(환경)</strong>를 의미합니다.</p>
<h3 id="2-transfer-vs-in-context-zerofew-shot을-가르는-가장-쉬운-기준">(2) Transfer vs (In-context) Zero/Few-shot을 가르는 가장 쉬운 기준</h3>
<ul>
<li><strong>Transfer(파인튜닝 포함)</strong>: 타겟 데이터로 <strong>파라미터 업데이트 있음</strong></li>
<li><strong>Zero/Few-shot(in-context)</strong>: 프롬프트에 예시가 있을 뿐 <strong>파라미터 업데이트 없음</strong></li>
</ul>
<hr>
<h1 id="56-part-c-gpt-1-p11p19--generative-pre-training--fine-tuning">5.6 Part C. GPT-1 (p11–p19) — Generative Pre-Training + Fine-tuning</h1>
<h2 id="561-p11-gpt-1-큰-그림">5.6.1 (p11) GPT-1 큰 그림</h2>
<ul>
<li>GPT = <strong>Generative Pre-Training</strong></li>
<li>철학: <strong>(1) LM으로 먼저 크게 학습 → (2) 태스크별로 약간만 맞춤</strong></li>
</ul>
<pre><code class="language-mermaid">flowchart LR
  A[Large unlabeled text] --&gt; B[Stage 1: LM Pretraining]
  B --&gt; C[Transformer Decoder (shared)]
  D[Labeled dataset per task] --&gt; E[Stage 2: Supervised fine-tuning]
  C --&gt; E
  E --&gt; F[Downstream performance]</code></pre>
<hr>
<h2 id="562-p14-stage-1-causal-language-modeling-수식정확-표기">5.6.2 (p14) Stage 1: Causal Language Modeling 수식(정확 표기)</h2>
<p>토큰 시퀀스를 (U=(u_1,\dots,u_n))라 할 때, GPT의 언어모델은 <strong>과거 토큰만</strong> 조건으로 다음 토큰을 예측합니다.</p>
<h3 id="1-최대화-관점로그우도">(1) 최대화 관점(로그우도)</h3>
<p>[
\max_{\theta}\ \sum_{i=1}^{n}\log P(u_i \mid u_{&lt;i};\theta)
]</p>
<h3 id="2-손실최소화-관점음의-로그우도">(2) 손실(최소화) 관점(음의 로그우도)</h3>
<p>[
L_{\text{LM}}(\theta)
=====================</p>
<p>-\sum_{i=1}^{n}\log P(u_i \mid u_{&lt;i};\theta)
]</p>
<blockquote>
<p>강의의 “레프트-투-라이트(미래 못 봄)”는 (u_{&lt;i})만 쓰는 조건부 확률을 뜻합니다.</p>
</blockquote>
<hr>
<h2 id="563-p15-stage-2-supervised-fine-tuning--lm-보조항">5.6.3 (p15) Stage 2: Supervised Fine-tuning + LM 보조항</h2>
<p>타겟 태스크 데이터 (C)가 ((x,y)) 쌍의 집합일 때:</p>
<h3 id="1-태스크-손실예-분류">(1) 태스크 손실(예: 분류)</h3>
<p>[
L_{\text{task}}(\theta)
=======================</p>
<p>-\sum_{(x,y)\in C}\log P(y\mid x;\theta)
]</p>
<h3 id="2-최종-손실슬라이드의-lambda-결합을-손실-형태로-정확히">(2) 최종 손실(슬라이드의 (\lambda) 결합을 “손실 형태로” 정확히)</h3>
<p>[
L(\theta)
=========</p>
<p>L_{\text{task}}(\theta)
+
\lambda\ L_{\text{LM}}(\theta)
]</p>
<ul>
<li><p>(\lambda)가 작은 이유(강의 의도):</p>
<ul>
<li><strong>태스크 성능에 집중</strong>하되</li>
<li>LM 일반성(표현)을 조금 유지해 <strong>과적합 완화</strong>에 도움</li>
</ul>
</li>
</ul>
<hr>
<h2 id="564-p16-입력-구조만-바꾸면-다양한-태스크에-적용의-의미">5.6.4 (p16) “입력 구조만 바꾸면 다양한 태스크에 적용”의 의미</h2>
<p>모델(디코더 트랜스포머)은 그대로 두고, <strong>태스크 입력을 텍스트 시퀀스로 ‘포맷팅’</strong>합니다.</p>
<table>
<thead>
<tr>
<th>태스크</th>
<th>입력 포맷(예시)</th>
<th>출력/판정</th>
</tr>
</thead>
<tbody><tr>
<td>문장 분류</td>
<td><code>[BOS] text</code></td>
<td>class</td>
</tr>
<tr>
<td>문장쌍(NLI/유사도)</td>
<td><code>[BOS] premise [SEP] hypothesis</code></td>
<td>entail/neutral/contradict</td>
</tr>
<tr>
<td>QA(간단형)</td>
<td><code>[BOS] question [SEP] context</code></td>
<td>answer span / 생성</td>
</tr>
<tr>
<td>다지선다</td>
<td>각 옵션별 <code>[BOS] question [SEP] option_i</code> 점수화</td>
<td>argmax option</td>
</tr>
</tbody></table>
<hr>
<h2 id="565-p17p19-ablation-요지강의-포인트-유지">5.6.5 (p17–p19) Ablation 요지(강의 포인트 유지)</h2>
<ul>
<li>프리트레인(LM) + 파인튜닝 조합이 성능에 기여</li>
<li>모델 깊이/규모 증가가 성능을 밀어올림</li>
<li>LSTM 대비 Transformer가 여러 태스크에서 더 강한 경향</li>
</ul>
<hr>
<h1 id="57-part-d-bert-p20p35--bidirectional-encoder--mlmnsp">5.7 Part D. BERT (p20–p35) — Bidirectional Encoder + MLM(+NSP)</h1>
<h2 id="571-p21p23-gpt-vs-bert-구조-차이핵심-1줄">5.7.1 (p21–p23) GPT vs BERT 구조 차이(핵심 1줄)</h2>
<ul>
<li><strong>GPT</strong>: Decoder + <strong>Causal(미래 마스킹)</strong> → 생성에 유리</li>
<li><strong>BERT</strong>: Encoder + <strong>Bidirectional(좌/우 문맥)</strong> → 이해/표현학습에 유리</li>
</ul>
<pre><code class="language-text">GPT (Causal):
t3는 (t1,t2)만 봄, (t4,t5)는 마스킹

BERT (Bidirectional):
t3는 (t1,t2,t4,t5) 모두 볼 수 있음
(단, MLM에서는 일부 토큰이 [MASK]로 가려짐)</code></pre>
<hr>
<h2 id="572-p24p26-pretrain-1-masked-language-modelmlm">5.7.2 (p24–p26) Pretrain 1: Masked Language Model(MLM)</h2>
<h3 id="목적">목적</h3>
<p>입력 토큰 일부를 가리고, 가려진 토큰을 맞추며 <strong>양방향 문맥 표현</strong>을 학습합니다.</p>
<p>마스크 위치 집합을 (M)이라 할 때:</p>
<p>[
L_{\text{MLM}}(\theta)
======================</p>
<p>-\sum_{i\in M}\log P(x_i \mid x_{\backslash M};\theta)
]</p>
<h3 id="801010-규칙강의-싱크-강함">80/10/10 규칙(강의 싱크 강함)</h3>
<p>마스크 후보로 뽑힌 토큰(보통 전체의 15% 내외)에 대해:</p>
<ul>
<li>80% → <code>[MASK]</code>로 치환</li>
<li>10% → 랜덤 토큰으로 치환</li>
<li>10% → 원래 토큰 유지</li>
</ul>
<p><strong>이유</strong></p>
<ul>
<li>파인튜닝/추론에서는 <code>[MASK]</code>가 없을 수 있으므로
<code>[MASK]</code>에만 과적응하는 것을 방지</li>
</ul>
<hr>
<h2 id="573-p27-pretrain-2-next-sentence-predictionnsp">5.7.3 (p27) Pretrain 2: Next Sentence Prediction(NSP)</h2>
<p>두 문장 A, B가 주어졌을 때:</p>
<ul>
<li><strong>IsNext</strong>: 실제 코퍼스에서 A 다음에 B가 이어짐</li>
<li><strong>NotNext</strong>: B를 다른 문서/문맥에서 랜덤 샘플</li>
</ul>
<p>목표는:
[
L_{\text{NSP}}(\theta)
======================</p>
<p>-\sum \log P(\text{label} \mid A,B;\theta)
]</p>
<blockquote>
<p>강의 기준에서는 NSP를 핵심 구성으로 설명하므로 그대로 따라가면 됩니다.</p>
</blockquote>
<hr>
<h2 id="574-p28-bert-입력-임베딩-3종-합시험-단골">5.7.4 (p28) BERT 입력 임베딩 3종 합(시험 단골)</h2>
<p>토큰 위치 (i)에서 최종 입력 임베딩:</p>
<p>[
\mathbf{e}_i
============</p>
<p>\mathbf{e}^{token}_i
+
\mathbf{e}^{pos}_i
+
\mathbf{e}^{segment}_i
]</p>
<ul>
<li>(\mathbf{e}^{token}): 토큰 의미(서브워드)</li>
<li>(\mathbf{e}^{pos}): 위치 정보</li>
<li>(\mathbf{e}^{segment}): 문장 A/B 구분(문장쌍 입력)</li>
</ul>
<hr>
<h2 id="575-p29-fine-tuning-패턴-2가지문장-단위-vs-토큰-단위">5.7.5 (p29) Fine-tuning 패턴 2가지(문장 단위 vs 토큰 단위)</h2>
<h3 id="1-sequence-level문장문장쌍-분류">(1) Sequence-level(문장/문장쌍 분류)</h3>
<ul>
<li><code>[CLS]</code> 출력 벡터 (\mathbf{h}_{CLS}) → 분류기 → label</li>
</ul>
<p>[
\hat{y}=\text{softmax}(W\mathbf{h}_{CLS}+b)
]</p>
<h3 id="2-token-level--span-level">(2) Token-level / Span-level</h3>
<ul>
<li>NER: 각 토큰 벡터 (\mathbf{h}_i)에 분류기</li>
<li>SQuAD(QA): start/end 위치 예측</li>
</ul>
<h4 id="squad-스팬-점수화강의의-dot-product를-수식으로-정리">SQuAD 스팬 점수화(강의의 dot product를 수식으로 정리)</h4>
<p>[
\text{score}<em>{start}(i)=\mathbf{h}*i^\top \mathbf{s},\quad
\text{score}</em>{end}(i)=\mathbf{h}<em>i^\top \mathbf{e}
]
[
P(start=i)=\text{softmax}(\text{score}</em>{start}),\quad
P(end=i)=\text{softmax}(\text{score}*{end})
]</p>
<hr>
<h2 id="576-p30p33-벤치마크가-의미하는-것강의-흐름-유지">5.7.6 (p30–p33) 벤치마크가 의미하는 것(강의 흐름 유지)</h2>
<table>
<thead>
<tr>
<th align="right">슬라이드</th>
<th>벤치마크</th>
<th>태스크 타입</th>
<th>잘하면 좋아지는 능력</th>
</tr>
</thead>
<tbody><tr>
<td align="right">p30</td>
<td>GLUE</td>
<td>문장/문장쌍 분류 묶음</td>
<td>범용 문맥 이해(일반화)</td>
</tr>
<tr>
<td align="right">p31</td>
<td>SQuAD</td>
<td>지문 기반 QA(스팬)</td>
<td>정보 위치 찾기 + 토큰 이해</td>
</tr>
<tr>
<td align="right">p32</td>
<td>SWAG</td>
<td>상식 기반 이어쓰기(다지선다)</td>
<td>문장 흐름/상식 추론</td>
</tr>
<tr>
<td align="right">p33</td>
<td>CoNLL NER</td>
<td>토큰 태깅</td>
<td>개체 인식(사람/장소/기관 등)</td>
</tr>
</tbody></table>
<hr>
<h2 id="577-p34p35-ablation-해석강의-요지-그대로">5.7.7 (p34–p35) Ablation 해석(강의 요지 그대로)</h2>
<ul>
<li>당시 설정에서는 <strong>MLM/NSP가 성능에 기여</strong></li>
<li>특히 MLM이 “문맥 표현”을 강하게 밀어줌</li>
</ul>
<hr>
<h1 id="58-part-e-gpt-2-p36p44--더-큰-데이터--bpe--zero-shot">5.8 Part E. GPT-2 (p36–p44) — 더 큰 데이터 + BPE + Zero-shot</h1>
<h2 id="581-p36p38-gpt-2가-강조한-3가지">5.8.1 (p36–p38) GPT-2가 강조한 3가지</h2>
<ol>
<li>더 큰 데이터(WebText 등)로 LM 학습</li>
<li>스케일(모델/데이터) 증가</li>
<li>파인튜닝 없이도(혹은 최소화) <strong>zero-shot 성능</strong>을 보여줄 수 있다</li>
</ol>
<hr>
<h2 id="582-p39p43-bpebyte-pair-encoding--완전-정리">5.8.2 (p39–p43) BPE(Byte Pair Encoding) — 완전 정리</h2>
<h3 id="왜-필요한가">왜 필요한가?</h3>
<ul>
<li>단어 단위 토크나이징은 OOV(사전에 없는 단어)가 빈번</li>
<li>서브워드(BPE/WordPiece 등)를 쓰면 “처음 보는 단어”도 분해/조합 가능</li>
</ul>
<h3 id="bpe-알고리즘정확-step-by-step">BPE 알고리즘(정확 Step-by-step)</h3>
<ol>
<li>초기 vocabulary를 문자(또는 바이트) 단위로 시작</li>
<li>말뭉치에서 <strong>가장 빈번한 연속 pair</strong>를 찾음</li>
<li>그 pair를 <strong>merge하여 하나의 토큰</strong>으로 추가</li>
<li>목표 vocab 크기까지 반복</li>
</ol>
<blockquote>
<p>강의의 “트위터 이모지” 맥락은, byte-level 계열 토크나이징이 특수문자/이모지 처리에 유리하다는 직관으로 이해하면 됩니다.</p>
</blockquote>
<hr>
<h2 id="583-p36p44-zero-shot-프롬프트화강의-요지">5.8.3 (p36–p44) Zero-shot 프롬프트화(강의 요지)</h2>
<ul>
<li>분류 문제도 “라벨을 출력 토큰으로 생성”하는 형태로 바꿔서 수행 가능</li>
<li>즉, <strong>헤드(softmax classifier)를 학습하지 않고</strong> 프롬프트로 태스크를 기술</li>
</ul>
<hr>
<h1 id="59-part-f-gpt-3-p45p49--스케일--in-context-learning">5.9 Part F. GPT-3 (p45–p49) — 스케일 + In-context learning</h1>
<h2 id="591-p45-gpt-3-핵심-메시지강의-표현-그대로">5.9.1 (p45) GPT-3 핵심 메시지(강의 표현 그대로)</h2>
<ul>
<li>GPT-2 철학을 확장: <strong>더 큰 모델 + 더 큰 데이터 → 더 강한 일반화</strong></li>
<li>프롬프트에 예시를 넣어 <strong>zero/one/few-shot</strong> 수행</li>
<li>중요한 포인트: <strong>gradient update 없이</strong>(학습 없이) 추론에서 해결</li>
</ul>
<hr>
<h2 id="592-in-context-learning-흐름도식">5.9.2 In-context learning 흐름(도식)</h2>
<pre><code class="language-mermaid">flowchart LR
  A[Instruction: task description] --&gt; M[Pretrained GPT]
  B[Examples: (x1-&gt;y1)...(xk-&gt;yk)] --&gt; M
  C[Query: x?] --&gt; M
  M --&gt; D[Generated answer y?]</code></pre>
<hr>
<h2 id="593-p49-강의-요약을-한-줄로">5.9.3 (p49) 강의 요약을 “한 줄”로</h2>
<ul>
<li><strong>BERT</strong>: 문장을 “이해/표현”하는 데 강한 인코더</li>
<li><strong>GPT</strong>: 문장을 “생성/연속 예측”하는 데 강한 디코더</li>
</ul>
<hr>
<h1 id="510-part-g-실무연구-동향-강의-위에-최소-확장">5.10 Part G. 실무/연구 동향 (강의 위에 최소 확장)</h1>
<h2 id="5101-peft예-lora--가볍게-적응시키는-파인튜닝">5.10.1 PEFT(예: LoRA) — “가볍게 적응시키는 파인튜닝”</h2>
<ul>
<li>대형 모델 전체를 업데이트하면 비용/메모리가 큼</li>
<li>그래서 <strong>일부 저랭크 어댑터만 학습</strong>해 빠르게 적응</li>
<li>대표: <strong>LoRA (arXiv:2106.09685)</strong></li>
</ul>
<p><strong>면접용 한 줄</strong></p>
<ul>
<li>“요즘은 full fine-tuning 대신 LoRA 같은 PEFT로 비용을 줄이고 빠르게 도메인 적응한다.”</li>
</ul>
<hr>
<h2 id="5102-rag--모르는-지식은-검색으로-보강">5.10.2 RAG — “모르는 지식은 검색으로 보강”</h2>
<ul>
<li>모델 파라미터에 지식을 ‘다’ 넣기보다
<strong>검색으로 관련 문서(근거)를 가져와 생성에 결합</strong></li>
<li>대표 개념 정리로 널리 인용되는 축: <strong>RAG (arXiv:2005.11401)</strong></li>
</ul>
<p><strong>면접용 한 줄</strong></p>
<ul>
<li>“최신/사내 지식과 근거가 필요하면 RAG로 문서를 붙여 환각을 줄인다.”</li>
</ul>
<hr>
<h1 id="511-part-h-시험면접-대비-15초-답변-템플릿-6개">5.11 Part H. (시험/면접 대비) 15초 답변 템플릿 6개</h1>
<h2 id="5111-왜-프리트레인이-필요한가">5.11.1 왜 프리트레인이 필요한가?</h2>
<p>“자연어는 입력 데이터는 많지만 레이블이 만들기 어려워서, 자기지도 과제로 대규모 사전학습을 하고 소량의 레이블로 다운스트림 태스크에 적응시키는 프리트레인–파인튜닝 전략이 강해졌습니다.”</p>
<h2 id="5112-gpt와-bert의-구조-차이">5.11.2 GPT와 BERT의 구조 차이?</h2>
<p>“GPT는 디코더 기반 causal LM이라 과거만 보고 다음 토큰을 생성하고, BERT는 인코더 기반 양방향 self-attention으로 좌우 문맥을 함께 보며 표현을 학습합니다.”</p>
<h2 id="5113-gpt-1의-2-stage는">5.11.3 GPT-1의 2-stage는?</h2>
<p>“1단계에서 언레이블 텍스트로 LM을 프리트레인하고, 2단계에서 태스크 레이블로 파인튜닝하며 필요하면 LM 손실을 (\lambda)로 섞어 일반성을 유지합니다.”</p>
<h2 id="5114-bert의-mlm-801010-이유">5.11.4 BERT의 MLM 80/10/10 이유?</h2>
<p>“추론 때 [MASK]가 없으므로 [MASK]에 과적응하지 않게 랜덤/원토큰을 섞어 견고한 문맥 표현을 학습합니다.”</p>
<h2 id="5115-zero-shotfew-shot의-핵심">5.11.5 Zero-shot/Few-shot의 핵심?</h2>
<p>“파라미터 업데이트 없이, 프롬프트에 지시문과 예시를 넣어 조건부 생성으로 태스크를 수행하는 방식입니다.”</p>
<h2 id="5116-요즘-현업-파인튜닝운영-흐름">5.11.6 요즘 현업 파인튜닝/운영 흐름?</h2>
<p>“대형 모델은 LoRA 같은 PEFT로 일부만 학습해 비용을 줄이고, 최신 지식/근거가 필요하면 RAG로 검색 문서를 결합합니다.”</p>
<hr>
<h1 id="512-part-i-연습문제--채점-기준">5.12 Part I. 연습문제 + 채점 기준</h1>
<h2 id="5121-개념-퀴즈-8문항">5.12.1 개념 퀴즈 8문항</h2>
<ol>
<li>(p4) 자연어에서 “레이블링이 어렵다”는 말이 의미하는 두 가지를 쓰시오.</li>
<li>(p5) 프리트레인–파인튜닝에서 freeze를 하는 이유를 데이터 크기 관점에서 설명하시오.</li>
<li>(p7) zero-shot과 transfer learning을 구분하는 가장 쉬운 기준은?</li>
<li>(p14) GPT의 Causal LM은 어떤 조건부 확률을 최대화하는가?</li>
<li>(p15) (L=L_{\text{task}}+\lambda L_{\text{LM}})에서 (\lambda)를 작게 두는 직관은?</li>
<li>(p28) BERT 입력 임베딩 3종과 역할을 각각 쓰시오.</li>
<li>(p29) SQuAD에서 start/end를 예측하는 점수화는 어떤 형태인가?</li>
<li>(p39–p43) BPE가 OOV를 줄이는 원리를 2~3줄로 설명하시오.</li>
</ol>
<h2 id="5122-채점-기준핵심만">5.12.2 채점 기준(핵심만)</h2>
<ul>
<li>3번: <strong>파라미터 업데이트 유무</strong>를 말하면 정답</li>
<li>5번: “태스크에 집중하면서도 LM 일반성을 조금 유지(과적합 완화)”면 정답</li>
<li>7번: “각 토큰 벡터와 start/end 벡터의 dot product(선형 점수) 후 softmax”면 정답</li>
</ul>
<hr>
<h1 id="6-hugging-face-library">6. Hugging Face Library</h1>
<p>아래는 네가 정리해둔 실습 코드를 <strong>교재형으로 “형식/수식(표기)/코드(실행가능)”까지 통일</strong>해서, <strong>앞뒤 흐름이 끊기지 않게</strong> 다시 엮은 최종본이야.
(마지막에 바로 실행 가능한 <strong>.ipynb / .py 파일</strong>도 같이 줌)</p>
<hr>
<h2 id="61-이-장의-목표">6.1 이 장의 목표</h2>
<h3 id="611-우리가-정확히-하려는-것">6.1.1 우리가 “정확히” 하려는 것</h3>
<ol>
<li><code>pipeline()</code>으로 <strong>즉시 추론(inference)</strong> 하기</li>
<li><code>AutoTokenizer</code>로 <strong>토큰화 → id 변환 → 텐서 입력</strong> 흐름 이해하기</li>
<li><code>datasets.load_dataset()</code>로 <strong>TSV/JSON 데이터 로드</strong>하기</li>
<li><code>map()</code>으로 <strong>전처리(예: HTML unescape)</strong> 하기</li>
<li>PyTorch로 <strong>학습 루프(training loop) + scheduler</strong>까지 최소 단위로 돌려보기</li>
</ol>
<hr>
<h2 id="62-실습-준비">6.2 실습 준비</h2>
<h3 id="621-설치로컬코랩-공통">6.2.1 설치(로컬/코랩 공통)</h3>
<pre><code class="language-bash">pip install -U transformers datasets accelerate torch tqdm</code></pre>
<h3 id="622-디바이스-선택공통">6.2.2 디바이스 선택(공통)</h3>
<ul>
<li>GPU가 있으면 <code>cuda</code>, 없으면 <code>cpu</code></li>
</ul>
<pre><code class="language-python">import torch
device = torch.device(&quot;cuda&quot; if torch.cuda.is_available() else &quot;cpu&quot;)
device</code></pre>
<hr>
<h2 id="63-pipeline-빠른-시작">6.3 Pipeline 빠른 시작</h2>
<h3 id="631-pipeline이-해주는-일한-줄-정의">6.3.1 Pipeline이 해주는 일(한 줄 정의)</h3>
<p><code>pipeline(task)</code>는 내부적으로 아래를 자동으로 묶어준다.</p>
<p>[
\text{pipeline} = \text{Tokenizer} \circ \text{Model} \circ \text{PostProcess}
]</p>
<p>즉, <strong>토크나이징 → 모델 forward → 후처리(확률/디코딩)</strong> 까지 “한 방”에 처리한다.</p>
<hr>
<h3 id="632-실습-1-fill-mask">6.3.2 (실습 1) fill-mask</h3>
<pre><code class="language-python">from transformers import pipeline

unmasker = pipeline(&quot;fill-mask&quot;)
unmasker(&quot;This course will teach you all about &lt;mask&gt; models&quot;, top_k=2)</code></pre>
<h4 id="핵심-포인트">핵심 포인트</h4>
<ul>
<li>문장 안에 <code>&lt;mask&gt;</code>를 넣으면, pipeline이 <strong>해당 모델의 mask 토큰</strong>으로 맞춰서 처리한다.</li>
<li>재현성을 올리려면 모델을 명시하는 게 좋다:</li>
</ul>
<pre><code class="language-python">unmasker = pipeline(&quot;fill-mask&quot;, model=&quot;bert-base-uncased&quot;)</code></pre>
<hr>
<h3 id="633-실습-2-sentiment-analysis-docx-텍스트-코드-반영">6.3.3 (실습 2) sentiment-analysis (docx 텍스트 코드 반영)</h3>
<pre><code class="language-python">from transformers import AutoTokenizer, pipeline

model_name = &quot;klue/roberta-base&quot;
tokenizer = AutoTokenizer.from_pretrained(model_name)
classifier = pipeline(&quot;sentiment-analysis&quot;, model=model_name, tokenizer=tokenizer)

classifier(&quot;이 강의 진짜 도움 많이 됐어요!&quot;)</code></pre>
<hr>
<h2 id="64-tokenizer-→-id-→-model-입력">6.4 Tokenizer → id → Model 입력</h2>
<h3 id="641-토크나이저의-역할정확-정의">6.4.1 토크나이저의 역할(정확 정의)</h3>
<p>텍스트 (x)가 들어오면, 모델이 먹을 수 있는 텐서 묶음으로 변환한다.</p>
<p>[
x ;\rightarrow; {\text{input_ids},;\text{attention_mask},;\text{token_type_ids(optional)}}
]</p>
<ul>
<li><code>input_ids</code>: 토큰 id 시퀀스</li>
<li><code>attention_mask</code>: 패딩(0) vs 실제 토큰(1)</li>
<li><code>token_type_ids</code>: 문장쌍(A/B) 구분(BERT류에서 주로 사용)</li>
</ul>
<hr>
<h3 id="642-실습-3-docx-이미지-예시-그대로--실패-라인-유지">6.4.2 (실습 3) docx 이미지 예시 그대로 + 실패 라인 유지</h3>
<pre><code class="language-python">import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification

checkpoint = &quot;distilbert-base-uncased-finetuned-sst-2-english&quot;
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = AutoModelForSequenceClassification.from_pretrained(checkpoint)

sequence = &quot;I&#39;ve been waiting for a HuggingFace course my whole life.&quot;

tokens = tokenizer.tokenize(sequence)
ids = tokenizer.convert_tokens_to_ids(tokens)
input_ids = torch.tensor(ids)

# This line will fail.
model(input_ids)</code></pre>
<h4 id="왜-실패하나-원인-정확히">왜 실패하나? (원인 “정확히”)</h4>
<p>대부분의 Transformer 모델 입력은 <strong>배치 차원(batch dimension)</strong> 을 기대한다.</p>
<ul>
<li>지금 <code>input_ids</code> shape:
[
(seq_len,)
]</li>
<li>모델이 기대하는 기본 shape:
[
(batch,;seq_len)
]</li>
</ul>
<hr>
<h3 id="643-fix실행되게-만들기-배치-차원-추가">6.4.3 Fix(실행되게 만들기): 배치 차원 추가</h3>
<pre><code class="language-python">input_ids = torch.tensor([ids])   # (batch, seq_len)
model(input_ids)</code></pre>
<hr>
<h3 id="644-실무실습에서-정석추천-tokenizer가-바로-텐서-만들게-하기">6.4.4 실무/실습에서 “정석”(추천): tokenizer가 바로 텐서 만들게 하기</h3>
<p>이게 제일 덜 틀리고, <code>attention_mask</code>도 자동으로 들어가서 안정적이다.</p>
<pre><code class="language-python">import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification

checkpoint = &quot;distilbert-base-uncased-finetuned-sst-2-english&quot;
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = AutoModelForSequenceClassification.from_pretrained(checkpoint)

sequence = &quot;I&#39;ve been waiting for a HuggingFace course my whole life.&quot;

inputs = tokenizer(sequence, return_tensors=&quot;pt&quot;)  # dict of tensors
outputs = model(**inputs)

logits = outputs.logits                    # (batch, num_labels)
pred = logits.argmax(dim=-1).item()

print(&quot;pred:&quot;, pred, &quot;label:&quot;, model.config.id2label[pred])</code></pre>
<h4 id="출력-텐서-shape시험디버깅-핵심">출력 텐서 shape(시험/디버깅 핵심)</h4>
<ul>
<li>분류 모델이면:</li>
</ul>
<p>[
\text{logits shape} = (batch,;num_labels)
]</p>
<hr>
<h2 id="65-tokenizer-내부-구조backend_tokenizer--normalizer">6.5 Tokenizer 내부 구조(backend_tokenizer) + normalizer</h2>
<h3 id="651-왜-보나">6.5.1 왜 보나?</h3>
<ul>
<li>“토큰화가 내부에서 어떻게 동작하는지”를 <strong>실제로 확인</strong>하는 용도</li>
<li>특히 <code>normalize_str</code>는 <strong>악센트/특수문자 정규화</strong> 같은 전처리 감각을 잡기 좋다.</li>
</ul>
<h3 id="652-실습-4-backend_tokenizer--normalizer">6.5.2 (실습 4) backend_tokenizer + normalizer</h3>
<pre><code class="language-python">from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained(&quot;bert-base-uncased&quot;)
print(type(tokenizer.backend_tokenizer))

print(tokenizer.backend_tokenizer.normalizer.normalize_str(&quot;Héllò hôw are ü?&quot;))</code></pre>
<hr>
<h2 id="66-datasets-로드">6.6 Datasets 로드</h2>
<h3 id="661-tsv-로드drugscom-예시">6.6.1 TSV 로드(drugsCom 예시)</h3>
<pre><code class="language-python">from datasets import load_dataset

data_files = {&quot;train&quot;: &quot;drugsComTrain_raw.tsv&quot;, &quot;test&quot;: &quot;drugsComTest_raw.tsv&quot;}
drug_dataset = load_dataset(&quot;csv&quot;, data_files=data_files, delimiter=&quot;\t&quot;)</code></pre>
<h4 id="빠른-확인">빠른 확인</h4>
<pre><code class="language-python">drug_dataset[&quot;train&quot;][&quot;condition&quot;][:3]</code></pre>
<hr>
<h3 id="662-json-로드squad_it-예시">6.6.2 JSON 로드(SQuAD_it 예시)</h3>
<pre><code class="language-python">from datasets import load_dataset

data_files = {&quot;train&quot;: &quot;SQuAD_it-train.json&quot;, &quot;test&quot;: &quot;SQuAD_it-test.json&quot;}
squad_it_dataset = load_dataset(&quot;json&quot;, data_files=data_files, field=&quot;data&quot;)</code></pre>
<p>샘플 1개 확인:</p>
<pre><code class="language-python">squad_it_dataset[&quot;train&quot;][0]</code></pre>
<hr>
<h3 id="663-단일-json-로드일반형">6.6.3 단일 JSON 로드(일반형)</h3>
<pre><code class="language-python">from datasets import load_dataset
load_dataset(&quot;json&quot;, data_files=&quot;myfile.json&quot;)</code></pre>
<hr>
<h2 id="67-map으로-전처리html-unescape">6.7 map()으로 전처리(HTML unescape)</h2>
<h3 id="671-목적">6.7.1 목적</h3>
<p>리뷰 텍스트에 <code>&amp;amp;</code>, <code>&amp;quot;</code> 같은 HTML 엔티티가 남아있으면 모델 입력이 지저분해진다.
<code>html.unescape</code>로 정리한다.</p>
<h3 id="672-실습-5-batched-map-적용">6.7.2 (실습 5) batched map 적용</h3>
<pre><code class="language-python">import html

new_drug_dataset = drug_dataset.map(
    lambda x: {&quot;review&quot;: [html.unescape(o) for o in x[&quot;review&quot;]]},
    batched=True,
)
new_drug_dataset</code></pre>
<h4 id="핵심-포인트-1">핵심 포인트</h4>
<ul>
<li><p><code>batched=True</code>면 <code>x[&quot;review&quot;]</code>가 리스트 단위로 들어오므로, <strong>리스트를 리턴</strong>해야 한다.</p>
</li>
<li><p>실무에서는 이후에 보통:</p>
<ul>
<li><code>remove_columns</code></li>
<li><code>rename_column(&quot;label&quot;, &quot;labels&quot;)</code></li>
<li><code>set_format(&quot;torch&quot;)</code>
같은 정리 루틴이 붙는다.</li>
</ul>
</li>
</ul>
<hr>
<h2 id="68-training-loop-tqdm--scheduler">6.8 Training loop (tqdm) + Scheduler</h2>
<h3 id="681-학습-루프가-하는-일정확-구조">6.8.1 학습 루프가 하는 일(정확 구조)</h3>
<p>각 스텝에서:</p>
<ol>
<li>배치 텐서를 디바이스로 이동</li>
<li>forward: ( \hat{y} = f_\theta(x) )</li>
<li>loss 계산 (보통 Cross Entropy)</li>
<li>backward: ( \nabla_\theta L )</li>
<li>optimizer step</li>
<li>scheduler step</li>
<li>grad reset</li>
</ol>
<p>분류의 표준 loss는:</p>
<p>[
L = -\sum_{c} y_c \log(\text{softmax}(\text{logits})_c)
]</p>
<hr>
<h3 id="682-실습-6-진행바-포함-training-loop-네-코드-흐름-그대로">6.8.2 (실습 6) 진행바 포함 training loop (네 코드 흐름 그대로)</h3>
<pre><code class="language-python">from tqdm import tqdm

progress_bar = tqdm(range(num_training_steps))

model.train()
for epoch in range(num_epochs):
    for batch in train_dataloader:
        batch = {k: v.to(device) for k, v in batch.items()}
        outputs = model(**batch)
        loss = outputs.loss
        loss.backward()

        optimizer.step()
        lr_scheduler.step()
        optimizer.zero_grad()
        progress_bar.update(1)</code></pre>
<hr>
<h3 id="683-실습-7-get_scheduler로-lr-scheduler-만들기">6.8.3 (실습 7) get_scheduler로 LR Scheduler 만들기</h3>
<pre><code class="language-python">from transformers import get_scheduler

num_epochs = 3
num_training_steps = num_epochs * len(train_dataloader)
lr_scheduler = get_scheduler(
    &quot;linear&quot;,
    optimizer=optimizer,
    num_warmup_steps=0,
    num_training_steps=num_training_steps,
)
print(num_training_steps)</code></pre>
<h4 id="linear-스케줄-직관">linear 스케줄 직관</h4>
<ul>
<li>학습이 진행될수록 LR을 선형으로 줄이는 형태</li>
<li>warmup을 쓰면 초반엔 LR을 점점 올린 뒤, 이후 감소</li>
</ul>
<hr>
<h2 id="69-실습에서-제일-많이-터지는-오류-top-6-바로-해결형">6.9 실습에서 제일 많이 터지는 오류 TOP 6 (바로 해결형)</h2>
<ol>
<li><p><strong>배치 차원 누락</strong></p>
<ul>
<li>해결: <code>torch.tensor([ids])</code> 또는 <code>tokenizer(..., return_tensors=&quot;pt&quot;)</code></li>
</ul>
</li>
<li><p><strong>attention_mask 없음</strong></p>
<ul>
<li>해결: 수동 입력 말고 <code>tokenizer()</code> 출력 dict 사용</li>
</ul>
</li>
<li><p><strong>모델/토크나이저 mismatch</strong></p>
<ul>
<li>해결: 같은 <code>checkpoint</code>로 둘 다 로드</li>
</ul>
</li>
<li><p><strong>fill-mask에서 마스크 토큰 혼동</strong></p>
<ul>
<li>해결: pipeline에는 <code>&lt;mask&gt;</code> 쓰면 안전, 직접이면 <code>tokenizer.mask_token</code> 확인</li>
</ul>
</li>
<li><p><strong>datasets.map에서 batched 처리 실수</strong></p>
<ul>
<li>해결: batched면 리스트를 리턴해야 함</li>
</ul>
</li>
<li><p><strong>GPU 사용 시 device 인자 미지정</strong></p>
<ul>
<li>해결: pipeline은 <code>device=0</code>, torch는 <code>.to(device)</code></li>
</ul>
</li>
</ol>
<hr>
<h2 id="610-바로-실행-가능한-파일">6.10 바로 실행 가능한 파일</h2>
<ul>
<li><a href="sandbox:/mnt/data/chapter06_huggingface_library.ipynb">Download the Notebook</a></li>
<li><a href="sandbox:/mnt/data/chapter06_huggingface_library.py">Download the Python script</a></li>
</ul>
<p>원하면 다음 단계로 <strong>HuggingFace실습.docx 이미지들을 “이미지 번호별 → 코드 셀로 정렬 → 중복 제거 → 실행 순서로 재배치”</strong> 해서, <em>docx 전체를 1개의 완성 노트북</em>으로 합치는 버전도 바로 만들어줄게.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[낚시 시즌별 정리]]></title>
            <link>https://velog.io/@charlese_note/%EB%82%9A%EC%8B%9C-%EC%8B%9C%EC%A6%8C%EB%B3%84-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@charlese_note/%EB%82%9A%EC%8B%9C-%EC%8B%9C%EC%A6%8C%EB%B3%84-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Fri, 21 Nov 2025 02:06:31 GMT</pubDate>
            <description><![CDATA[<hr>
<p>title: 한국 바다낚시 완전정리 – 1~12월 서해·남해·동해 / 원투·메탈·다운샷·선상 기준
tags: [바다낚시, 원투낚시, 메탈지그, 다운샷, 선상낚시, 서해, 남해, 동해, 물때, 월별정리]</p>
<hr>
<h1 id="한국-바다낚시-연간-정리">한국 바다낚시 연간 정리</h1>
<h3 id="112월--서해·남해·동해--원투·메탈·다운샷·선상-기준">(1~12월 / 서해·남해·동해 / 원투·메탈·다운샷·선상 기준)</h3>
<p>대한민국은 4계절 뚜렷하고 3면이 바다인 미친(?) 나라다.<br>그래서 <strong>“언제, 어느 바다(서해/남해/동해), 어떤 낚시(원투/메탈/다운샷/선상)로, 어떤 물고기를, 어느 물때에 노려야 하는지”</strong> 를 한 번에 볼 수 있게 정리했다.</p>
<blockquote>
<p>⚠️ 이 정리는 <strong>찌낚시(찌·카고·구멍찌 등)</strong> 를 전부 제외하고<br><strong>원투 / 메탈루어 / 다운샷 / 선상</strong> 네 가지만 기준으로 한다.</p>
</blockquote>
<hr>
<h2 id="1-이-글에서-다루는-낚시-스타일">1. 이 글에서 다루는 낚시 스타일</h2>
<ul>
<li><p><strong>원투낚시</strong></p>
<ul>
<li>갯바위, 방파제, 방조제, 해변(서프)</li>
<li>타깃: 광어, 도다리, 도다리, 우럭, 장어, 고등어, 전갱이, 전어 등</li>
</ul>
</li>
<li><p><strong>메탈 루어 낚시</strong></p>
<ul>
<li>메탈지그, 스틱베이트, 다이빙펜슬, 탑워터 등</li>
<li>타깃: 삼치, 방어/부시리, 고등어, 전갱이, 농어, 광어 등</li>
</ul>
</li>
<li><p><strong>다운샷 루어 낚시</strong></p>
<ul>
<li>바닥 찍고 살살 끌어오는 스타일</li>
<li>타깃: 광어, 도다리, 우럭, 노래미, 무늬오징어(응용) 등</li>
</ul>
</li>
<li><p><strong>선상 낚시</strong></p>
<ul>
<li>선상 지깅, 캐스팅, 다운샷, 타이러버, 에깅 등</li>
<li>타깃: 광어, 도다리, 우럭, 방어/부시리, 삼치, 참돔, 한치, 갈치, 주꾸미·갑오징어 등</li>
</ul>
</li>
</ul>
<hr>
<h2 id="2-연중-시즌-흐름--물때-기본-감각">2. 연중 시즌 흐름 &amp; 물때 기본 감각</h2>
<h3 id="2-1-연중-대략-흐름">2-1. 연중 대략 흐름</h3>
<ul>
<li><p><strong>1~3월 (겨울 끝 / 초봄)</strong></p>
<ul>
<li>수온 낮음 → <strong>우럭·볼락·노래미·광어 일부</strong> 위주</li>
<li>선상: <strong>광어 다운샷, 우럭지깅, 동해 대구</strong></li>
</ul>
</li>
<li><p><strong>4~6월 (봄 ~ 초여름)</strong></p>
<ul>
<li><strong>도다리·광어 산란 시즌(3~4월 피크)</strong> → 다운샷/원투 메인</li>
<li><strong>농어, 고등어, 전갱이</strong> 슬슬 붙기 시작</li>
</ul>
</li>
<li><p><strong>7~9월 (여름 ~ 초가을)</strong></p>
<ul>
<li><strong>고등어, 전갱이, 전어, 학공치, 갈치, 한치, 무늬오징어</strong> 등 회유성 어종 폭발</li>
<li>동해/남해: <strong>삼치·부시리(방어급)</strong> 메탈·지깅·캐스팅 시즌</li>
</ul>
</li>
<li><p><strong>10~12월 (가을 ~ 초겨울)</strong></p>
<ul>
<li><strong>광어·도다리·우럭·볼락</strong> 활성</li>
<li>남해/제주/부산·거제 외해 기준<br><strong>방어·부시리 빅게임 11~2월 피크</strong></li>
</ul>
</li>
</ul>
<hr>
<h3 id="2-2-물때-기본-룰-대략적인-가이드">2-2. 물때 기본 룰 (대략적인 가이드)</h3>
<ul>
<li><p><strong>광어·도다리·우럭 (다운샷/원투)</strong></p>
<ul>
<li><strong>3~7물</strong> : 조류 적당 → 채비 컨트롤 + 입질 둘 다 괜찮은 구간</li>
</ul>
</li>
<li><p><strong>삼치·방어·부시리·고등어·전갱이 (메탈/선상)</strong></p>
<ul>
<li><strong>5~8물</strong> : 조류가 어느 정도 흘러야 떼가 붙고 활성도 좋음  </li>
<li>너무 사리(9~10물)면 채비 컨트롤이 빡세니, 포인트/수심 보고 선택</li>
</ul>
</li>
<li><p><strong>주꾸미·갑오징어 (특히 서해)</strong></p>
<ul>
<li><strong>2<del>5물 정도의 약</del>중조류</strong>  </li>
<li>에기 컨트롤 편하고, 초보도 하기 쉬운 구간</li>
</ul>
</li>
<li><p><strong>볼락·노래미·장어 (원투/루어)</strong></p>
<ul>
<li>조류가 너무 세지 않은 <strong>1<del>4물, 8</del>10물</strong>  </li>
<li>야간에 물 흐름 살짝 있는 정도가 이상적</li>
</ul>
</li>
</ul>
<hr>
<h2 id="3-서해--112월--원투·메탈·다운샷·선상-정리">3. 서해 – 1~12월 / 원투·메탈·다운샷·선상 정리</h2>
<blockquote>
<p>기준: 인천·시화방조제·대부도·충남·군산·격포 등 서해 전역 공통적인 패턴을<br>“월별 + 기법 + 어종 + 물때” 로 요약한 표.</p>
</blockquote>
<h3 id="3-1-서해-월별-한눈에-보기">3-1. 서해 월별 한눈에 보기</h3>
<table>
<thead>
<tr>
<th>월</th>
<th>수온·환경 키워드</th>
<th>원투 (주요어종 / 포인트 / 추천 물때)</th>
<th>메탈루어 (주요어종 / 물때)</th>
<th>다운샷 (주요어종 / 물때)</th>
<th>선상 (주요어종 / 물때)</th>
</tr>
</thead>
<tbody><tr>
<td>1월</td>
<td>한겨울, 저수온</td>
<td>방파제·방조제 <strong>우럭·노래미·붕장어</strong> / 수심 깊은 홈·테트라 / <strong>1~4물</strong></td>
<td>소형 메탈로 우럭·노래미 / 조류 약~중</td>
<td>수심 10m 내외 암반에서 우럭 / <strong>3~5물</strong></td>
<td>근해 <strong>광어·우럭 지깅</strong>, 일부 대구 / <strong>3~6물</strong></td>
</tr>
<tr>
<td>2월</td>
<td>여전히 한겨울</td>
<td>1월과 비슷, 장어 입질은 더 약함 / 기상 우선</td>
<td>동해만큼은 아니지만 우럭 메탈 가능</td>
<td>광어 다운샷 프리 시즌 / <strong>3~6물</strong></td>
<td>광어 다운샷, 우럭지깅 / <strong>3~6물</strong></td>
</tr>
<tr>
<td>3월</td>
<td>수온 서서히 상승</td>
<td><strong>도다리·광어·우럭</strong> / 모래+혼합 바닥 / <strong>3~6물</strong></td>
<td>시화·대부도 광어 메탈 시작 / <strong>3~5물</strong></td>
<td>서해 <strong>봄 도다리 시즌 개막</strong> / <strong>3~5물</strong></td>
<td>광어 다운샷 개막, 우럭 병행 / <strong>3~7물</strong></td>
</tr>
<tr>
<td>4월</td>
<td>봄 피크, 산란기</td>
<td><strong>도다리 전성기</strong> + 광어·우럭 / 새벽 들물 / <strong>3~6물</strong></td>
<td>광어, 농어(초반) 메탈 / 물돌이 전후</td>
<td>도다리·광어 피크 / <strong>3~6물</strong></td>
<td>광어 다운샷 메인 시즌 진입 / <strong>3~7물</strong></td>
</tr>
<tr>
<td>5월</td>
<td>초여름, 회유어 시작</td>
<td><strong>광어·도다리·우럭·농어</strong> / 수초·홈통 / <strong>3~7물</strong></td>
<td>농어·광어 메탈, 지그헤드 / <strong>4~7물</strong></td>
<td>광어 다운샷 메인 / <strong>3~7물</strong></td>
<td>광어 다운샷, 갑오징어 일부 시작 (지역 한정)</td>
</tr>
<tr>
<td>6월</td>
<td>수온 확 증가</td>
<td>밤 <strong>장어·우럭</strong> / <strong>1<del>4물, 8</del>10물</strong></td>
<td>농어·광어·가끔 삼치 전조 / <strong>5~7물</strong></td>
<td>광어·우럭 다운샷 / <strong>3~7물</strong></td>
<td>광어·우럭·농어 선상루어 / <strong>4~7물</strong></td>
</tr>
<tr>
<td>7월</td>
<td>한여름</td>
<td>밤 장어·우럭·노래미 / <strong>1~4물</strong></td>
<td>인천권 광어·농어, 가끔 고등어 / <strong>5~8물</strong></td>
<td>깊은 수심 광어·우럭</td>
<td>광어, 농어, 우럭, 일부 갈치(야간) / <strong>4~8물</strong></td>
</tr>
<tr>
<td>8월</td>
<td>고수온, 태풍 변수</td>
<td>밤 장어·우럭·노래미 / 더위 피해서</td>
<td><strong>삼치·고등어 예열</strong> (남서해 외해) / <strong>5~8물</strong></td>
<td>낮보단 새벽·저녁 위주</td>
<td>갈치, 고등어, 전갱이, 농어 선상 / <strong>5~8물</strong></td>
</tr>
<tr>
<td>9월</td>
<td>수온 안정, 가을 시작</td>
<td><strong>전어·고등어·우럭</strong> / 내항·방조제 / <strong>3~7물</strong></td>
<td><strong>삼치·고등어·농어</strong> 메탈 본격 / <strong>5~8물</strong></td>
<td>광어·우럭 여전히 가능 / <strong>3~7물</strong></td>
<td><strong>주꾸미·갑오징어, 고등어·갈치·삼치</strong> 시즌 시작 / <strong>3~6물</strong></td>
</tr>
<tr>
<td>10월</td>
<td>가을 피크</td>
<td>전어·고등어·학공치·우럭·장어 / <strong>3~7물</strong></td>
<td><strong>삼치·고등어 피크</strong> – 방파제 메탈 / <strong>5~8물</strong></td>
<td>광어·도다리·우럭 다운샷 / <strong>3~6물</strong></td>
<td>주꾸미·갑오징어, 갈치, 삼치, 고등어 종합 시즌 / <strong>3~6물</strong></td>
</tr>
<tr>
<td>11월</td>
<td>늦가을~초겨울</td>
<td>고등어 막판, 우럭·노래미 / <strong>3~6물</strong></td>
<td>삼치 막판, 광어 메탈 / <strong>4~7물</strong></td>
<td><strong>광어·도다리 가을 막판</strong> / <strong>3~6물</strong></td>
<td>광어·우럭·주꾸미 막판 / <strong>3~6물</strong></td>
</tr>
<tr>
<td>12월</td>
<td>겨울 진입</td>
<td>우럭·노래미·장어(따뜻한 날) / <strong>1~4물</strong></td>
<td>메탈로 우럭·양태 정도 / 약~중조류</td>
<td>서해 광어·도다리 끝물 / <strong>3~5물</strong></td>
<td>광어·우럭 위주 겨울 선상 / <strong>3~6물</strong></td>
</tr>
</tbody></table>
<hr>
<h2 id="4-남해--112월--원투·메탈·다운샷·선상-정리">4. 남해 – 1~12월 / 원투·메탈·다운샷·선상 정리</h2>
<blockquote>
<p>기준: 부산·거제·통영·여수·완도 등 남해 전역 공통 패턴.<br><strong>어종 다양성 미친 지역</strong>이라 필요 이상으로 다 잡히는 곳.</p>
</blockquote>
<h3 id="4-1-남해-월별-한눈에-보기">4-1. 남해 월별 한눈에 보기</h3>
<table>
<thead>
<tr>
<th>월</th>
<th>수온·환경</th>
<th>원투</th>
<th>메탈루어</th>
<th>다운샷</th>
<th>선상</th>
</tr>
</thead>
<tbody><tr>
<td>1월</td>
<td>동계, 그래도 서해/동해보다 따뜻</td>
<td>방파제·갯바위 <strong>우럭·볼락·노래미</strong> / 야간 / <strong>1~4물</strong></td>
<td>소형 메탈로 우럭·볼락, 농어 일부</td>
<td>깊은 홈 공략 광어·우럭</td>
<td>근해 <strong>광어 다운샷, 우럭지깅</strong>, 열기·볼락, 외해 부시리 지깅 일부 / <strong>3~7물</strong></td>
</tr>
<tr>
<td>2월</td>
<td>겨울 끝, 수온 최저 근처</td>
<td>볼락 위주, 우럭·노래미 보조 / 야간</td>
<td>볼락 플러그·메탈, 농어 초반</td>
<td>1월과 비슷</td>
<td>부시리·방어 지깅 일부, 광어·우럭 / <strong>3~7물</strong></td>
</tr>
<tr>
<td>3월</td>
<td>봄 시작, 도다리 스타트</td>
<td>얕은 사질대 <strong>도다리</strong> / 새벽 들물 / <strong>3~5물</strong></td>
<td>광어·도다리 메탈 슬슬</td>
<td><strong>도다리·광어 산란기 시작</strong> / <strong>3~5물</strong></td>
<td>광어 다운샷, 참돔 타이러버 시작, 부시리 지깅</td>
</tr>
<tr>
<td>4월</td>
<td>봄 피크</td>
<td>도다리 전성기 + 광어 / 사천·진해·삼천포 등 / <strong>3~6물</strong></td>
<td>광어, 농어, 참돔 메탈·지그헤드</td>
<td>도다리·광어 피크 / <strong>3~6물</strong></td>
<td>광어·참돔 타이러버, 부시리 지깅, 우럭·열기</td>
</tr>
<tr>
<td>5월</td>
<td>초여름, 회유어 진입</td>
<td>고등어·전갱이, 우럭·볼락 / 방파제·내항 / <strong>3~7물</strong></td>
<td>농어, 광어, 고등어 메탈 / <strong>5~7물</strong></td>
<td>광어 위주 다운샷 / <strong>3~7물</strong></td>
<td>참돔 타이러버 메인, 광어·우럭, 갈치 극초반 지역 일부</td>
</tr>
<tr>
<td>6월</td>
<td>여름 초입</td>
<td>밤 <strong>고등어·전갱이·학공치·우럭</strong></td>
<td><strong>고등어·전갱이·농어</strong> 메탈, 삼치 전조 / <strong>5~8물</strong></td>
<td>깊은 수심 광어 다운샷</td>
<td>참돔, 광어, 갈치(지역 한정), 무늬오징어 선상 시작</td>
</tr>
<tr>
<td>7월</td>
<td>한여름</td>
<td>밤 <strong>고등어·전갱이·학공치·장어</strong> / <strong>1~4물</strong></td>
<td><strong>삼치·고등어·농어</strong> 탑워터·메탈 / <strong>5~8물</strong></td>
<td>깊은 수심 광어, 무늬오징어 다운샷 응용</td>
<td>갈치, 한치, 무늬오징어, 참돔, 부시리 여름 시즌 / <strong>4~8물</strong></td>
</tr>
<tr>
<td>8월</td>
<td>고수온, 어종 폭발</td>
<td>고등어·전갱이·전어·학공치 / 내만 방파제 / <strong>3~7물</strong></td>
<td>삼치·고등어·부시리·농어 메탈·펜슬 / <strong>5~8물</strong></td>
<td>무늬오징어 일부, 광어는 깊은 수심</td>
<td>한치 피크, 갈치, 부시리 지깅·캐스팅, 고등어·전갱이·농어 종합 시즌</td>
</tr>
<tr>
<td>9월</td>
<td>가을 피크</td>
<td>전갱이·고등어·전어·우럭 / 방파제·내항 / <strong>3~7물</strong></td>
<td><strong>삼치·부시리·고등어 메인 시즌</strong> / <strong>5~8물</strong></td>
<td>광어·도다리 가을 시즌 시작</td>
<td>갈치, 삼치, 부시리, 한치 막판, 참돔·광어 모두 좋음</td>
</tr>
<tr>
<td>10월</td>
<td>진가을, 루어 천국</td>
<td>고등어·전갱이·전어·학공치·우럭 / <strong>3~7물</strong></td>
<td>삼치·부시리·고등어 메탈 피크, 농어 밤 메탈</td>
<td>광어·도다리·우럭 다운샷 / <strong>3~6물</strong></td>
<td>부시리·방어급, 갈치, 참돔, 광어, 무늬오징어 등 종합 반찬 시즌</td>
</tr>
<tr>
<td>11월</td>
<td>늦가을~초겨울</td>
<td>고등어 막판, 우럭·볼락·도다리 / <strong>3~6물</strong></td>
<td>삼치 막판, 광어 메탈, 농어</td>
<td>광어·도다리 가을 막판 / <strong>3~6물</strong></td>
<td><strong>방어·부시리 빅게임 본격 (부산·거제·통영 외해)</strong>, 광어·참돔·갈치 막판</td>
</tr>
<tr>
<td>12월</td>
<td>겨울, 빅게임+광어</td>
<td>방파제 우럭·볼락·노래미 / 야간 / <strong>1~4물</strong></td>
<td>메탈로 우럭·볼락, 외해 삼치 조금</td>
<td>광어·도다리 겨울 시즌(깊은 수심)</td>
<td>남해·제주 <strong>방어·부시리 지깅·파핑 피크</strong>, 광어 다운샷, 우럭·열기 / <strong>3~7물</strong></td>
</tr>
</tbody></table>
<hr>
<h2 id="5-동해--112월--원투·메탈·다운샷·선상-정리">5. 동해 – 1~12월 / 원투·메탈·다운샷·선상 정리</h2>
<blockquote>
<p>기준: 포항·울산·삼척·속초 등 동해 전역 공통 패턴.<br>특징: 수심이 빠르게 깊어지고, <strong>삼치·부시리·대구</strong> 등 “동해스러운” 어종이 강함.</p>
</blockquote>
<h3 id="5-1-동해-월별-한눈에-보기">5-1. 동해 월별 한눈에 보기</h3>
<table>
<thead>
<tr>
<th>월</th>
<th>수온·환경</th>
<th>원투</th>
<th>메탈루어</th>
<th>다운샷</th>
<th>선상</th>
</tr>
</thead>
<tbody><tr>
<td>1월</td>
<td>동해 한겨울, 수심 깊음</td>
<td>방파제·갯바위 <strong>우럭·노래미·붕장어</strong> / 깊은 홈 / <strong>1~4물</strong></td>
<td>메탈지그로 우럭·노래미 노리는 겨울 루어</td>
<td>수심 15m 내외 암반 우럭 다운샷</td>
<td>근해 <strong>우럭·볼락·대구 지깅</strong>, 강도다리 일부 / <strong>3~7물</strong></td>
</tr>
<tr>
<td>2월</td>
<td>수온 최저, 날씨빨</td>
<td>볼락·우럭 야간 원투 위주</td>
<td>볼락 플러그·메탈, 우럭</td>
<td>1월과 비슷</td>
<td>대구·우럭 중심, 기상 좋을 때만</td>
</tr>
<tr>
<td>3월</td>
<td>수온 서서히 상승</td>
<td>광어·도다리·우럭 / 모래+자갈 / <strong>3~6물</strong></td>
<td>광어, 농어(남부동해) 메탈</td>
<td>광어·도다리 다운샷 프리 시즌</td>
<td>광어·우럭·대구, 일부 감성돔(찌 제외)</td>
</tr>
<tr>
<td>4월</td>
<td>봄, 산란 시작</td>
<td><strong>광어·도다리</strong> 연안 붙기 시작 / 새벽 들물 / <strong>3~6물</strong></td>
<td>광어 메탈 본격, 농어 시즌 시작</td>
<td>광어·도다리 메인 시작 / <strong>3~6물</strong></td>
<td>광어 다운샷, 우럭, 농어 지깅</td>
</tr>
<tr>
<td>5월</td>
<td>초여름, 회유어 입성</td>
<td>우럭·노래미·광어·도다리 / 방파·갯바위 / <strong>3~7물</strong></td>
<td>농어·광어 메탈, 가끔 고등어</td>
<td>광어·도다리 다운샷 / <strong>3~7물</strong></td>
<td>광어, 농어, 우럭, 한치 일부 지역에서 스타트</td>
</tr>
<tr>
<td>6월</td>
<td>수온 상승, 여름 입구</td>
<td>밤 볼락·우럭·노래미 / <strong>1~4물</strong></td>
<td><strong>한치·무늬오징어, 농어, 광어</strong> 메탈 / <strong>4~7물</strong></td>
<td>광어 다운샷 지속</td>
<td>한치, 무늬오징어, 광어, 농어 선상 루어</td>
</tr>
<tr>
<td>7월</td>
<td>여름, 난류 강세</td>
<td>고등어·전갱이·우럭·노래미 / 방파제 야간</td>
<td><strong>삼치·부시리·고등어·농어</strong> 메탈·탑워터 / <strong>5~8물</strong></td>
<td>광어는 깊은 수심, 한치·무늬 다운샷 응용</td>
<td>한치 피크, 삼치·부시리 지깅/캐스팅, 고등어·전갱이</td>
</tr>
<tr>
<td>8월</td>
<td>고수온, 피크</td>
<td>고등어·전갱이·우럭·노래미 / <strong>3~7물</strong></td>
<td>삼치·부시리·고등어 피크, 농어 밤 메탈</td>
<td>광어·도다리 여전히 가능</td>
<td>삼치·부시리·고등어·한치·무늬 등 종합 시즌</td>
</tr>
<tr>
<td>9월</td>
<td>수온 안정, 가을</td>
<td>고등어·전갱이·우럭, 가끔 전어 / 방파제 / <strong>3~7물</strong></td>
<td><strong>삼치·부시리·고등어 메탈 피크</strong> / <strong>5~8물</strong></td>
<td>광어·도다리 가을 시즌 시작</td>
<td>부시리·삼치·고등어, 광어, 농어, 한치 막판</td>
</tr>
<tr>
<td>10월</td>
<td>가을 피크</td>
<td>고등어·전갱이·우럭·노래미 / <strong>3~7물</strong></td>
<td>삼치·부시리·고등어, 농어 시즌 계속</td>
<td>광어·도다리·우럭 다운샷 / <strong>3~6물</strong></td>
<td>부시리·삼치, 광어·우럭, 무늬 일부, 대구 프리 시즌</td>
</tr>
<tr>
<td>11월</td>
<td>늦가을~초겨울</td>
<td>고등어 막판, 우럭·노래미·볼락 / <strong>3~6물</strong></td>
<td>삼치 막판, 광어 메탈</td>
<td>광어·도다리, 우럭 다운샷</td>
<td>우럭·볼락, 대구 시즌 진입, 부시리·삼치 막판</td>
</tr>
<tr>
<td>12월</td>
<td>겨울 진입</td>
<td>우럭·볼락·노래미 / 방파제 야간 / <strong>1~4물</strong></td>
<td>메탈로 우럭·볼락</td>
<td>다운샷는 우럭·광어 소규모</td>
<td>대구·우럭·볼락 선상, 외해 부시리 일부 / <strong>3~6물</strong></td>
</tr>
</tbody></table>
<hr>
<h2 id="6-이-표를-실제로-활용하는-방법">6. 이 표를 실제로 활용하는 방법</h2>
<h3 id="6-1-타깃-어종-먼저-고르기">6-1. 타깃 어종 먼저 고르기</h3>
<p>예를 들어,</p>
<ul>
<li><p><strong>“12월 방어·부시리 + 광어”</strong> 가 목표라면<br>→ 남해(부산·거제·통영) &amp; 제주 외해, 동해 남부 외해 위주<br>→ 위 표에서 <strong>남해/동해 11~2월 줄</strong> 집중 체크</p>
</li>
<li><p><strong>“4월 도다리 위주 + 광어 서브”</strong><br>→ 서해·남해 전역 도다리 산란기 / 다운샷·원투 위주<br>→ 서해/남해 3~4월 줄만 골라 보면 일정이 바로 나온다.</p>
</li>
</ul>
<hr>
<h3 id="6-2-내가-좋아하는-낚시-기법만-필터링하기">6-2. 내가 좋아하는 낚시 기법만 필터링하기</h3>
<ul>
<li>글에서 다루는 기법:<ul>
<li><strong>원투 / 메탈 / 다운샷 / 선상</strong></li>
</ul>
</li>
<li>본인이 실제로 즐기는 1~2개만 고르면 됨<ul>
<li>예: “메탈 + 선상”만 보는 식으로, 나머지 열은 그냥 참고용</li>
</ul>
</li>
</ul>
<hr>
<h3 id="6-3-물때-고르는-기준-요약">6-3. 물때 고르는 기준 요약</h3>
<ul>
<li><p><strong>삼치·방어·부시리·고등어·전갱이(메탈/지깅)</strong><br>→ <strong>5~8물</strong>: 조류가 어느 정도 흘러줘야 활성도 Good</p>
</li>
<li><p><strong>광어·도다리·우럭(다운샷/원투)</strong><br>→ <strong>3~7물</strong>: 바닥 찍기 편하고 입질 잘 들어오는 구간</p>
</li>
<li><p><strong>장어·볼락·노래미</strong><br>→ <strong>1<del>4물 또는 8</del>10물</strong>: 너무 세지 않은 느린 조류 + 야간</p>
</li>
<li><p><strong>주꾸미·갑오징어</strong><br>→ <strong>2~5물</strong>: 에기 컨트롤 쉬운 구간</p>
</li>
</ul>
<hr>
<h2 id="7-마무리--직장인-모드로-낚시-계획-세우기">7. 마무리 – “직장인 모드”로 낚시 계획 세우기</h2>
<ol>
<li><p><strong>월 &amp; 어종 선택</strong></p>
<ul>
<li>“언제 시간이 비는지” → 가능한 월 체크</li>
<li>그 달에 잘 나오는 <strong>어종</strong>을 표에서 먼저 고른다.</li>
</ul>
</li>
<li><p><strong>지역 선택 (서해 vs 남해 vs 동해)</strong></p>
<ul>
<li>거리, 숙소, 이동시간 고려</li>
<li>방어·부시리면 남해/제주·동해,<br>도다리·광어면 서해/남해,<br>삼치·부시리 메탈이면 동해/남해 쪽으로 좁힌다.</li>
</ul>
</li>
<li><p><strong>기법 선택</strong></p>
<ul>
<li>원투 / 메탈 / 다운샷 / 선상 중에서<br>이번 출조의 “컨셉”을 하나 정한다.</li>
</ul>
</li>
<li><p><strong>물때 &amp; 세부 일정</strong></p>
<ul>
<li>위 표의 추천 물때 (대부분 3~8물 사이)에서<br>본인 스케줄 가능한 날을 골라서 맞춘다.</li>
<li>마지막으로 <strong>기상(바람·파고), 최근 조황, 금어기</strong>만 한 번 더 체크하면<br>실패 확률을 꽤 많이 줄일 수 있다.</li>
</ul>
</li>
</ol>
<hr>
<p>이 글은 <strong>“찌낚시를 제외하고, 원투·메탈·다운샷·선상만으로 한국 바다 1년을 정리한 캘린더”</strong>라고 보면 된다.<br>필요하면 다음 글에서</p>
<ul>
<li><strong>“삼치/방어/광어만 따로 뽑은 전용 캘린더”</strong>  </li>
<li><strong>“월별·바다별 추천 포인트 예시(포항 뜬방, 오륙도, 조도 등)”</strong></li>
</ul>
<p>같은 식으로 더 파고들 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[5주차]]></title>
            <link>https://velog.io/@charlese_note/5%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@charlese_note/5%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Tue, 11 Nov 2025 12:44:19 GMT</pubDate>
            <description><![CDATA[<h1 id="1-워크로드-선택의-기준">1) 워크로드 선택의 기준</h1>
<ul>
<li><p><strong>Deployment(+HPA)</strong></p>
<ul>
<li><strong>성격</strong>: 상시 처리(큐 워커, 이벤트 소비).</li>
<li><strong>요구</strong>: <em>at-least-once</em> 전제, 재시도/내구성, 수평 확장.</li>
<li><strong>의미</strong>: 종료코드 143(TERM)은 롤링 등 “정상”일 확률↑ → 알림에서 노이즈 제거.</li>
</ul>
</li>
<li><p><strong>Job</strong></p>
<ul>
<li><strong>성격</strong>: 끝이 있는 배치(백필, 리인덱스, 마이그). <strong>완료 후 자원 0</strong>.</li>
<li><strong>핵심</strong>: <code>completions/parallelism</code>로 작업량·동시성 제어, <code>Indexed</code>로 샤딩/추적.</li>
<li><strong>정책</strong>: 실패 분류(podFailurePolicy), TTL 청소로 누적 방지.</li>
</ul>
</li>
<li><p><strong>CronJob</strong></p>
<ul>
<li><strong>성격</strong>: 스케줄러(백업, 청소, 리포트).</li>
<li><strong>핵심</strong>: <strong>겹침 방지(concurrencyPolicy)</strong> + <strong>놓친 스케줄 보전(startingDeadlineSeconds)</strong> + <strong>타임존</strong>.</li>
<li><strong>정책</strong>: 성공/실패 히스토리 제한 + TTL로 “작업 쓰레기” 제어.</li>
</ul>
</li>
</ul>
<h1 id="2-필수-파라미터의-의미">2) 필수 파라미터의 “의미”</h1>
<ul>
<li><p><strong>concurrencyPolicy (Forbid/Replace/Allow)</strong></p>
<ul>
<li>재진입 불가 작업이면 <strong>Forbid</strong>(중복 처리 차단), 최신만 중요하면 <strong>Replace</strong>.</li>
</ul>
</li>
<li><p><strong>startingDeadlineSeconds</strong></p>
<ul>
<li>컨트롤플레인/스케줄 지연 시 <strong>놓친 실행을 보전</strong>. 없으면 통째로 건너뜀.</li>
</ul>
</li>
<li><p><strong>completionMode: Indexed (Job)</strong></p>
<ul>
<li>각 완료 인덱스를 고유 샤드로 간주 → <strong>누가 무엇을 처리했는지</strong> 추적 가능.</li>
</ul>
</li>
<li><p><strong>backoffLimit / activeDeadlineSeconds</strong></p>
<ul>
<li><strong>재시도 한계/전체 시간 한계</strong>로 무한 재시도·좀비 작업 방지.</li>
</ul>
</li>
<li><p><strong>ttlSecondsAfterFinished</strong></p>
<ul>
<li>완료 리소스 자동 정리(운영 디폴트로 활성 가정).</li>
</ul>
</li>
<li><p><strong>resources(requests/limits)</strong></p>
<ul>
<li>OOM/Evict 예방의 1순위. 긴 작업은 <strong>체크포인트</strong>로 재시작 가능 설계.</li>
</ul>
</li>
<li><p><strong>topologySpreadConstraints / priorityClassName</strong></p>
<ul>
<li>배치 분산/중요도 보장(노드 한쪽 치우침·자원 쟁탈 완화).</li>
</ul>
</li>
<li><p><strong>timeZone (CronJob)</strong></p>
<ul>
<li>운영 타임존과 스케줄 혼선 제거(Asia/Seoul 명시).</li>
</ul>
</li>
</ul>
<h1 id="3-장애운영-인사이트">3) 장애/운영 인사이트</h1>
<ul>
<li><strong>중복 실행의 진짜 비용</strong>: 재처리·데이터 이중 반영·다운스트림 폭발 → CronJob 겹침 방지가 <strong>가장 빠른 보험</strong>.</li>
<li><strong>스케줄 유실의 진짜 원인</strong>: 컨트롤플레인 이벤트 로스·스케줄 지연 → <code>startingDeadlineSeconds</code>로 <strong>회복 탄력</strong> 확보.</li>
<li><strong>배치 실패의 분류 필요성</strong>: OOM/스케줄 불가/일시적 디스크압박 등 <strong>원인별 대응</strong>이 달라짐 → podFailurePolicy로 <strong>즉시 Fail/무시/재시도</strong> 분기.</li>
<li><strong>운영 쓰레기 누적</strong>: Job/CronJob은 기본적으로 잔해가 남음 → TTL/HistoryLimit로 <strong>SRE 위생</strong> 유지.</li>
</ul>
<h1 id="4-종료코드의-해석과-앱-행동">4) 종료코드의 해석과 앱 행동</h1>
<ul>
<li><p><strong>0</strong>: 정상 완료(Completed).</p>
</li>
<li><p><strong>143</strong>(=128+SIGTERM): 롤링/스케일다운/드레인 등 <strong>정상 시나리오</strong>에서 흔함.</p>
<ul>
<li><strong>대응</strong>: 배포 이벤트가 있는 윈도우에선 <strong>알림 제외</strong>(노이즈 컷).</li>
</ul>
</li>
<li><p><strong>137</strong>(=128+SIGKILL): <strong>Grace 초과</strong> 또는 <strong>OOMKilled</strong>.</p>
<ul>
<li><strong>대응</strong>: <code>terminationGracePeriodSeconds</code> 상향 + preStop 훅으로 우아한 종료, 또는 리소스 증설/메모리 튜닝.</li>
</ul>
</li>
<li><p><strong>앱 관점 가이드</strong></p>
<ul>
<li><strong>SIGTERM 핸들러</strong>: 현재 작업 <strong>체크포인트/재큐</strong> → Deployment 워커는 <strong>exit 0</strong>로 빠르게 교체; Job 워커는 <strong>미완료면 non-zero</strong>로 재시도 유도(단, 안전 재큐 시 0 허용).</li>
<li><strong>블로킹 호출</strong>: 타임아웃·주기적 TERM 체크 필수.</li>
</ul>
</li>
</ul>
<h1 id="5-관측성-최소-셋">5) 관측성 최소 셋</h1>
<ul>
<li><p><strong>라벨/추적키</strong>: <code>jobId</code>, <code>commitSha</code>, <code>shardIndex</code>(Indexed) → 문제 재현·영향도 파악 단축.</p>
</li>
<li><p><strong>진행률/하트비트</strong>: 장시간 작업은 <strong>하트비트 파일/키</strong> + <strong>커맨드형 liveness</strong>로 “멈춤”을 신호화.</p>
</li>
<li><p><strong>메트릭</strong>: 완료/실패/재시도 카운트, 실행시간 히스토그램(또는 로그 집계라도).</p>
</li>
<li><p><strong>알림 룰</strong>:</p>
<ul>
<li>롤링 중 <strong>143은 정상</strong>으로 취급(윈도우 제한).</li>
<li><strong>OOMKilled</strong>는 항상 경고/심각.</li>
</ul>
</li>
</ul>
<h1 id="6-redis로-직접-at-least-once-큐-만들-때의-본질">6) Redis로 직접 at-least-once 큐 만들 때의 본질</h1>
<ul>
<li><p><strong>수신/확인 분리</strong>: <code>BRPOPLPUSH queue → inprogress</code>로 <strong>유실 방지</strong>(워커 크래시 시 inprogress 스캔).</p>
</li>
<li><p><strong>하트비트</strong>: 처리 중 <code>task:&lt;id&gt;.lastBeat</code> 갱신 → <strong>Reaper CronJob</strong>이 타임아웃 항목을 <strong>원 큐로 복원</strong>.</p>
</li>
<li><p><strong>종료 시맨틱</strong>:</p>
<ul>
<li>Deployment 워커: 재큐 후 <strong>0</strong>(교체 신속).</li>
<li>Job 워커: 미완료면 <strong>non-zero</strong>로 컨트롤러 재시도.</li>
</ul>
</li>
</ul>
<h1 id="7-gitops에서-안전장치의-위치">7) GitOps에서 안전장치의 위치</h1>
<ul>
<li><strong>폴더 = 네임스페이스 바인딩</strong>(하드코딩 금지, 파이프라인에서 주입).</li>
<li><strong>공통 패치로 기본 가드 주입</strong>: <code>ttlSecondsAfterFinished</code>, <code>backoffLimit</code>, <code>activeDeadlineSeconds</code>(Kustomize/Helm).</li>
<li><strong>드리프트 억제</strong>: <code>kubectl diff</code> / server-side apply / <strong>prune</strong>.</li>
<li><strong>HistoryLimit</strong>로 컨트롤러 히스토리 관리(관측성 + 청결 균형).</li>
</ul>
<h2 id="현업에서-가장-효과-큰-5가지">현업에서 가장 효과 큰 5가지</h2>
<ol>
<li><strong>CronJob 겹침 방지</strong> 안 하면 데이터 이중처리 난리 난다.</li>
<li><strong>startingDeadlineSeconds</strong> 없으면 스케줄 유실이 “조용히” 지나간다.</li>
<li><strong>Job Indexed</strong>는 대규모 배치 추적/리트라이 단위의 사실상 표준.</li>
<li><strong>TTL + HistoryLimit</strong>로 잡 잔해를 자동 청소하라.</li>
<li><strong>143은 정상, 137은 위험 신호</strong>—알림 룰을 분리하라.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[PlyerController]]></title>
            <link>https://velog.io/@charlese_note/PlyerController</link>
            <guid>https://velog.io/@charlese_note/PlyerController</guid>
            <pubDate>Thu, 23 Oct 2025 04:56:32 GMT</pubDate>
            <description><![CDATA[<p>BP_PlayerController 블루프린트</p>
<ul>
<li>블로그 글1</li>
</ul>
<p>1인칭 슈팅을 만들거고 TPS 형식으로 만들어 볼 것.</p>
<p>그러기 위해선 마우스의 좌표를 받아서 회전하게끔 수정.</p>
<p>edit에서 회전을 담당할 Mouse X, Y를 설정</p>
<p><img src="https://blog.kakaocdn.net/dna/bFaJ0E/btsE0sRLlNK/AAAAAAAAAAAAAAAAAAAAAHl3ZFAHry6K0bEKPKFPQm-6ukKj0sxjBl70xQ7ZoSwa/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1761922799&allow_ip=&allow_referer=&signature=GZzN48b7TcP0QOL%2BfzcOHGiPNlY%3D" alt=""></p>
<p><img src="https://blog.kakaocdn.net/dna/bzqNKD/btsE8A1wODx/AAAAAAAAAAAAAAAAAAAAAB5TaZNHj4YyrIx02HO1HW4v7EvYPrbp3lLr6sPRwt4P/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1761922799&allow_ip=&allow_referer=&signature=8cJIA3E40N%2B1Mvz%2FCHp%2Fyeg4tdg%3D" alt=""></p>
<p>만약 Use Controller Rotation Pitch를 활성화하면 아래와 같이, 플레이어가 이상하게 회전한다.</p>
<p>일반적인 TPS게임이면 회전하는 것은 맞는데 위로 볼 때, 캐릭터가 저런식으로 회전하는 것이 아니라 카메라가 그 쪽을 주시하고, 조준하는 총만 위로 올리는 개념이여야 한다. 플레이어 자체가 움직이진 않는다.</p>
<p><img src="https://blog.kakaocdn.net/dna/z1NO7/btsE9I58ivF/AAAAAAAAAAAAAAAAAAAAAB3pUr-Z-ZTJ31HnN-LRePyxipZAUECeS2356pEz3gy_/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1761922799&allow_ip=&allow_referer=&signature=VSUvp8JTx4YSMMDj88mSHpVnh1s%3D" alt=""></p>
<p><img src="https://blog.kakaocdn.net/dna/b5mBvZ/btsE98cpBLd/AAAAAAAAAAAAAAAAAAAAAO2Ewv44go0hTw2Mbv4OXDAFYRk_mo9etKgxFOusmJbi/img.gif?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1761922799&allow_ip=&allow_referer=&signature=OCmfJ%2B5fcEmhlSyTpc%2FRO6W%2FuME%3D" alt=""></p>
<p>그럼 다시 Pawn의 Use Controller Rotation Pitch를 비활성화하고,</p>
<p>Spring Arm을 보면 Pawn Control Rotation을 사용하겠다는 옵션이 있다.</p>
<p><img src="https://blog.kakaocdn.net/dna/bpazJj/btsE9Snn4EB/AAAAAAAAAAAAAAAAAAAAAFDjNifd0p8cFLyPb2TgMulCa_CKTVQlri6QZQoMpV3E/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1761922799&allow_ip=&allow_referer=&signature=91ygpvkeJi2a4bEQqS0LbM6HoWY%3D" alt=""></p>
<p>활성화를 해주고, 그럼 플레이어 자체가 회전하는 것이 아니라, 카메라가 플레이어의 회전 값에 맞춰 회전하게 된다.</p>
<p><img src="https://blog.kakaocdn.net/dna/d4VNr4/btsE90lb9Yx/AAAAAAAAAAAAAAAAAAAAAF235jtbQiDAWb5Sh11Jg8Ch2AgsMcxv8zz46Lv-U-hz/img.gif?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1761922799&allow_ip=&allow_referer=&signature=o%2FWYK2X8acle80LLiBJtNRDAp%2F8%3D" alt=""></p>
<p>아래의 코드를 Player 안에다 입력 코드를 작성했는데, 틀린 방법은 아니다. 하지만 만약 플레이어의 코드량이 많아진다거나 아니면 특정 상황에 따라서 행동이 바뀌기를 원하면 플레이어에서 제어하기 보다는 플레이어의 입력을 케어하는 코드이기 때문에, Player Controller에다 넣는 것도 하나의 방법이다.</p>
<p><img src="https://blog.kakaocdn.net/dna/cGFonv/btsE8MA1vzL/AAAAAAAAAAAAAAAAAAAAAD5ioGE4UjWPMUXSg7jH0dsz5drGe9NpbXFqPxTBhvJU/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1761922799&allow_ip=&allow_referer=&signature=eBcZQL0My01boWKU3U6TAukZLnw%3D" alt=""></p>
<p>Player Controller로 이전한 코드</p>
<p><img src="https://blog.kakaocdn.net/dna/dGIw6j/btsE3nvKggD/AAAAAAAAAAAAAAAAAAAAAPQA9K7BSt9FD0W3EcRZ2fyrtyh1Cf43HeYstleDnfny/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1761922799&allow_ip=&allow_referer=&signature=CsIf7L8p6ISS18FNylULW%2BPECQY%3D" alt=""></p>
<p>그리고, Jump를 구현해야 한다고 하면 다른 엔진의 경우는 물리공식을 이용하는 등 직접 구현해야 되겠지만, 이 Movement Component에 다양한 기능이 들어가 있다. 언리얼 엔진의 슈팅 게임에 맞춰져있는 엔진이라서 Jump라던지 기어가는 거라던지 기본적인 동작에 대한 함수가 미리 만들어져있다.</p>
<p><img src="https://blog.kakaocdn.net/dna/11uk6/btsE9Ok1QHw/AAAAAAAAAAAAAAAAAAAAALuJeEQFmQd51bBHD1SgC5pBtaRw3FAOWYuxe5tC6fNE/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1761922799&allow_ip=&allow_referer=&signature=G%2FQB76kBtcHLAtl60kL%2BxUJV01Y%3D" alt=""></p>
<p><img src="https://blog.kakaocdn.net/dna/bkEFr4/btsE7u8tyOm/AAAAAAAAAAAAAAAAAAAAADLKDjeiiqrSjvUQPK6WkgnLdRs6zP8z1i8_tJ1BMmit/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1761922799&allow_ip=&allow_referer=&signature=VhKOGXw%2Fk4J5Y9yvjLSCd%2FRarlE%3D" alt=""></p>
<p>예시</p>
<p>-블로그 글 2</p>
<h3 id="bp_playercontroller-생성"><strong>BP_PlayerController 생성</strong></h3>
<p>Blueprint Class - Player Controller - <strong>BP_PlayerController</strong> 생성</p>
<p><img src="https://blog.kakaocdn.net/dna/snZ8A/btrWbViEhwE/AAAAAAAAAAAAAAAAAAAAAIhhvKwrDeLroYAF2cnetS6Afuck-xSYxRhlxTM8CuhI/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1761922799&allow_ip=&allow_referer=&signature=%2FIpQmZvn8XK8mgSb%2F715YtPtdpk%3D" alt=""></p>
<p><img src="https://blog.kakaocdn.net/dna/bLa6Lq/btrWc2BsU94/AAAAAAAAAAAAAAAAAAAAAJUoVRXootWvKTAB5W03sDDUMaYAH4NlmAiCYDcfbVdA/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1761922799&allow_ip=&allow_referer=&signature=Cj3zSGoWn%2FY5hwSiWVp7q6OmlAM%3D" alt=""></p>
<ul>
<li>BP_Player에 있던 액션맵핑 다 옮겨줌</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[20250903]]></title>
            <link>https://velog.io/@charlese_note/20250903</link>
            <guid>https://velog.io/@charlese_note/20250903</guid>
            <pubDate>Wed, 03 Sep 2025 14:05:15 GMT</pubDate>
            <description><![CDATA[<h2 id="계획">계획</h2>
<h2 id="rookiss">Rookiss</h2>
<ul>
<li>정수의 원리<h2 id="얌얌코딩">얌얌코딩</h2>
</li>
<li>변수, cout, debug 복습<h2 id="혼자-공부하는-c언어">혼자 공부하는 C언어</h2>
</li>
<li>다양한 파일 입출력 함수</li>
</ul>
<h2 id="정수란">정수란</h2>
<ul>
<li>정수는 <strong>소수점이 없는 수</strong>로, <strong>양수, 음수, 0</strong>을 포함</li>
<li>컴퓨터는 정수를 <strong>2진수(Binary)</strong>로 변환하여 저장하고 처리</li>
<li>ex) 10진수 5 → 2진수 00000101 (8비트 기준)</li>
</ul>
<h2 id="정수의-표현-방식">정수의 표현 방식</h2>
<p><img src="https://velog.velcdn.com/images/charlese_note/post/f0413965-737b-429a-a9be-4625141e661b/image.png" alt=""></p>
<ul>
<li>부호화 크기 방식<ul>
<li>MSB(가장 왼쪽 비트)를 <strong>부호 비트</strong>로 사용<ul>
<li><code>0</code>: 양수, <code>1</code>: 음수</li>
</ul>
</li>
<li>나머지 비트는 크기 정보</li>
<li><strong>+0과 -0이 중복 표현</strong>됨 → 비효율적, 실사용 거의 없음</li>
</ul>
</li>
<li>1의 보수<ul>
<li>모든 비트를 반전시켜 음수 표현<ul>
<li>예: <code>5</code> → <code>00000101</code>, <code>5</code> → <code>11111010</code></li>
</ul>
</li>
<li>여전히 <code>+0</code>, <code>0</code>이 존재함 → 사용 잘 안 함</li>
</ul>
</li>
<li>2의 보수<ul>
<li>현재 컴퓨터에서 <strong>표준으로 사용하는 음수 표현 방식</strong></li>
<li>방법:<ul>
<li>숫자의 이진수를 반전 (1의 보수)</li>
<li>거기에 <code>+1</code>을 더함</li>
</ul>
</li>
<li>예:<code>5</code> = <code>00000101</code>반전 → <code>11111010</code>+1 → <code>11111011</code> → <code>5</code></li>
<li><strong>장점</strong>:<ul>
<li><code>+0</code>, <code>0</code>이 하나로 통합</li>
<li>덧셈/뺄셈 연산 회로를 하나로 통합 가능 → 효율성 ↑</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="데이터-타입과-저장-범위">데이터 타입과 저장 범위</h2>
<ul>
<li><p><code>signed</code>: 부호 있음 → 음수 + 양수</p>
</li>
<li><p><code>unsigned</code>: 양수만 → 더 넓은 양의 값 표현 가능</p>
</li>
<li><p>타입 변환 시 <strong>손실 발생 가능</strong> → 주의 필요</p>
<ul>
<li><p>예: <code>int</code> → <code>short</code> → 상위 비트 손실</p>
<table>
<thead>
<tr>
<th>타입</th>
<th>크기(Byte)</th>
<th>Signed 범위</th>
<th>Unsigned 범위</th>
</tr>
</thead>
<tbody><tr>
<td>char</td>
<td>1</td>
<td>-128 ~ 127</td>
<td>0 ~ 255</td>
</tr>
<tr>
<td>short</td>
<td>2</td>
<td>-32,768 ~ 32,767</td>
<td>0 ~ 65,535</td>
</tr>
<tr>
<td>int</td>
<td>4</td>
<td>-2,147,483,648 ~ 2,147,483,647</td>
<td>0 ~ 4,294,967,295</td>
</tr>
<tr>
<td>long long</td>
<td>8</td>
<td>-9경 ~ 9경 (±9,223,372조)</td>
<td>0 ~ 18,446경</td>
</tr>
</tbody></table>
</li>
</ul>
</li>
</ul>
<h2 id="진법과-변환">진법과 변환</h2>
<ul>
<li><p>2진수 16진수는 4비트 단위로 나뉘어져 있어 매우 친화적</p>
<ul>
<li><p>2진수 4자리 = 16진수 1자리</p>
<table>
<thead>
<tr>
<th>진법</th>
<th>설명</th>
<th>코드 표현</th>
</tr>
</thead>
<tbody><tr>
<td>2진수 (BIN)</td>
<td>컴퓨터 내부 기본 표현</td>
<td><code>0b1100</code></td>
</tr>
<tr>
<td>10진수 (DEC)</td>
<td>사람이 일상 사용하는 표현</td>
<td>기본 숫자</td>
</tr>
<tr>
<td>16진수 (HEX)</td>
<td>디버깅/주소 표현에 유용</td>
<td><code>0xF</code></td>
</tr>
<tr>
<td>8진수 (OCT)</td>
<td>예전 시스템에서 사용</td>
<td>거의 사용 안 함</td>
</tr>
</tbody></table>
</li>
</ul>
</li>
</ul>
<h2 id="정수-연산">정수 연산</h2>
<ul>
<li>덧셈</li>
</ul>
<pre><code>| A | B | A+B | Carry |
| --- | --- | --- | --- |
| 0 | 0 | 0 | 0 |
| 1 | 0 | 1 | 0 |
| 1 | 1 | 0 | 1 (올림 발생) |
- 예: `5 + 3`
    - `5`: `00000101`
    - `3`: `00000011`
    - 결과: `00001000` → `8`</code></pre><ul>
<li>뺄셈<ul>
<li>뺄셈은 <strong>2의 보수 덧셈</strong>으로 처리</li>
<li>예: <code>5 - 3</code> = <code>5 + (-3)</code><ul>
<li><code>3</code>의 2의 보수: <code>11111101</code></li>
<li><code>5</code> = <code>00000101</code></li>
<li>결과 = <code>00000010</code> → <code>2</code></li>
</ul>
</li>
</ul>
</li>
<li>오버플로우<ul>
<li>표현 가능한 최대값을 초과<ul>
<li>예: <code>2147483647 + 1</code> → <code>2147483648</code></li>
</ul>
</li>
</ul>
</li>
<li>언더플로우<ul>
<li>표현 가능한 최소값보다 작음<ul>
<li>예: <code>2147483648 - 1</code> → <code>2147483647</code></li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="메모리에-저장되는-방식">메모리에 저장되는 방식</h2>
<ul>
<li>리틀 엔디안<ul>
<li><strong>하위 바이트(LSB)</strong>부터 메모리에 저장</li>
<li>예: <code>0x12345678</code> → 메모리: <code>78 56 34 12</code></li>
<li>인텔 아키텍처에서 기본</li>
</ul>
</li>
<li>빅 엔디안<ul>
<li><strong>상위 바이트(MSB)</strong>부터 저장</li>
<li>네트워크 통신 프로토콜에서 많이 사용</li>
</ul>
</li>
</ul>
<h2 id="code">CODE</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

// 정수의 원리
// 비트  0,1 데이터의 최소 단위
// 바이트
// 1 바이트 -&gt; 8bit
// 컴퓨터는 전기 신호로 숫자를 만들어줌
// 최상위 비트는 -를 담당함
// 1바이트의 가장 큰 값을 01111111 : 127
// 11111111 = 1

// 복습
int hp;
// 데이터 범위
short mp;

// 진법
// 0,1,2,3,4,5,6,7,8,9 -&gt; 10 (1과 0으로 표현) 조합하면서 무한대 숫자를 만들 수 있음\
// 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F 16 진법
// why? 16 진법
// 2진법과 궁합이 잘맞음
// 

int main()
{
    hp = 0xFF/*306189112*/;

    mp = /*(short)*/hp;    // 값을 꺼내옴 // 다른 숫자가 나옴 범위 밖의 숫자가 날아감
                    // 형변환이 필요함            
    cout &lt;&lt; hp;

    return 0;
}</code></pre>
<h2 id="문제-1">문제 1</h2>
<ul>
<li>1주 동안 운동 횟수를 입력 받고</li>
<li>칭찬 메시지 출력</li>
</ul>
<h3 id="입력-예시">입력 예시</h3>
<pre><code class="language-cpp">5</code></pre>
<h3 id="출력-예시">출력 예시</h3>
<pre><code class="language-cpp">멋지군요!! 칭찬합니다</code></pre>
<h3 id="풀이">풀이</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

int main()
{

    int a;
    cin &gt;&gt; a;

    if (a)
    {
        cout &lt;&lt; &quot;멋지군요!! 칭찬합니다&quot; &lt;&lt; endl;
    }

    return 0;
}</code></pre>
<h2 id="문제-2">문제 2</h2>
<ul>
<li>숫자 하나를 입력 받음</li>
<li>입력 받은 숫자를 그대로 출력</li>
<li>뒤에 입력하셨군요 라는 글씨 출력</li>
</ul>
<h3 id="입력-예시-1">입력 예시</h3>
<pre><code class="language-cpp">3</code></pre>
<h3 id="출력-예시-1">출력 예시</h3>
<pre><code class="language-cpp">3 입력하셨군요</code></pre>
<h3 id="풀이-1">풀이</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

int main()
{

    int a;
    cin &gt;&gt; a;

    cout &lt;&lt; a &lt;&lt; &quot; 입력하셨군요&quot; &lt;&lt; endl;

    return 0;
}</code></pre>
<h2 id="문제-3">문제 3</h2>
<ul>
<li>숫자를 하나 입력 받음</li>
<li>숫자를 세번 출력</li>
<li>cin과 cout만 이용</li>
</ul>
<h3 id="입력-예시-2">입력 예시</h3>
<pre><code class="language-cpp">3</code></pre>
<h3 id="출력-예시-2">출력 예시</h3>
<pre><code class="language-cpp">3 3 3</code></pre>
<h3 id="풀이-2">풀이</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

int main()
{

    int a;
    cin &gt;&gt; a;

    cout &lt;&lt; a &lt;&lt; &quot; &quot; &lt;&lt; a &lt;&lt; &quot; &quot; &lt;&lt; a &lt;&lt; endl;

    return 0;
}</code></pre>
<h2 id="문제-4">문제 4</h2>
<ul>
<li>숫자 3개를 변수 a,b,c이 입력 받음</li>
<li>a 3번 출력, b 3번 출력, c 3번 출력</li>
</ul>
<h3 id="입력-예시-3">입력 예시</h3>
<pre><code class="language-cpp">3 5 9</code></pre>
<h3 id="출력-예시-3">출력 예시</h3>
<pre><code class="language-cpp">333
555
999</code></pre>
<h3 id="풀이-3">풀이</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

int main()
{

    int a, b, c;
    cin &gt;&gt; a &gt;&gt; b &gt;&gt; c;

    cout &lt;&lt; a &lt;&lt; &quot;&quot; &lt;&lt; a &lt;&lt; &quot;&quot; &lt;&lt; a &lt;&lt; endl;
    cout &lt;&lt; b &lt;&lt; &quot;&quot; &lt;&lt; b &lt;&lt; &quot;&quot; &lt;&lt; b &lt;&lt; endl;
    cout &lt;&lt; c &lt;&lt; &quot;&quot; &lt;&lt; c &lt;&lt; &quot;&quot; &lt;&lt; c &lt;&lt; endl;

    return 0;
}</code></pre>
<h2 id="문제-5">문제 5</h2>
<ul>
<li>숫자 2개 입력 받음</li>
<li>앞 숫자 -  뒷 숫자의 차를 구해서 출력</li>
</ul>
<h3 id="입력-예시-4">입력 예시</h3>
<pre><code class="language-cpp">30 10</code></pre>
<h3 id="출력-예시-4">출력 예시</h3>
<pre><code class="language-cpp">두 숫자의 차는 20 입니다.</code></pre>
<h3 id="풀이-4">풀이</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

int main()
{

    int a, b;
    cin &gt;&gt; a &gt;&gt; b;

    cout &lt;&lt; &quot;두 숫자의 차는 &quot; &lt;&lt; a - b &lt;&lt; &quot; 입니다.&quot; &lt;&lt; endl;

    return 0;
}</code></pre>
<h2 id="문제-6">문제 6</h2>
<ul>
<li>숫자 두개 입력 받고 덧셈, 곱셈, 나눗셈 출력</li>
</ul>
<h3 id="입력-예시-5">입력 예시</h3>
<pre><code class="language-cpp">5 2</code></pre>
<h3 id="출력-예시-5">출력 예시</h3>
<pre><code class="language-cpp">5 + 2 = 7
5 * 2 = 10
5 / 2 = 2</code></pre>
<h3 id="풀이-5">풀이</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

int main()
{

    int a, b;
    cin &gt;&gt; a &gt;&gt; b;

    cout &lt;&lt; a &lt;&lt; &quot;+&quot; &lt;&lt; b &lt;&lt; &quot;=&quot; &lt;&lt;a + b &lt;&lt; endl;
    cout &lt;&lt; a &lt;&lt; &quot;*&quot; &lt;&lt; b &lt;&lt; &quot;=&quot; &lt;&lt;a * b &lt;&lt; endl;
    cout &lt;&lt; a &lt;&lt; &quot;/&quot; &lt;&lt; b &lt;&lt; &quot;=&quot; &lt;&lt;a / b &lt;&lt; endl;

    return 0;
}</code></pre>
<h2 id="문제-7">문제 7</h2>
<ul>
<li>변수 a,b에 숫자를 입력 받음</li>
<li>변수 a가 b보다 크면 a가 b보다 크다</li>
<li>그렇지 않으면 b가 a보다 같거나 크다를 출력</li>
</ul>
<h3 id="입력-예시-6">입력 예시</h3>
<pre><code class="language-cpp">4 3</code></pre>
<h3 id="출력-예시-6">출력 예시</h3>
<pre><code class="language-cpp">a가 b보다 크다</code></pre>
<h3 id="풀이-6">풀이</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

int main()
{

    int a, b;
    cin &gt;&gt; a &gt;&gt; b;

    if (a &gt; b)
    {
        cout &lt;&lt; &quot;a가 b보다 크다&quot; &lt;&lt; endl;
    }
    else
    {
        cout &lt;&lt; &quot;b가 a보다 같거나 크다&quot; &lt;&lt; endl;

    }

    return 0;
}</code></pre>
<h2 id="문제-8">문제 8</h2>
<ul>
<li>숫자 2개를 입력</li>
<li>둘 중 큰 수를 4번 출력</li>
</ul>
<h3 id="입력-예시-7">입력 예시</h3>
<pre><code class="language-cpp">3 5</code></pre>
<h3 id="출력-예시-7">출력 예시</h3>
<pre><code class="language-cpp">5555</code></pre>
<h3 id="풀이-7">풀이</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

int main()
{

    int a, b;
    cin &gt;&gt; a &gt;&gt; b;

    if (a &gt; b)
    {
        cout &lt;&lt; a &lt;&lt; a &lt;&lt; a &lt;&lt; a &lt;&lt; endl;
    }
    else if(b &gt; a)
    {
        cout &lt;&lt; b &lt;&lt; b &lt;&lt; b &lt;&lt; b &lt;&lt; endl;

    }
    else
    {

    }

    return 0;
}</code></pre>
<h2 id="문제-9">문제 9</h2>
<ul>
<li>숫자 1개를 변수 a에 입력 받음</li>
<li>5를 입력함</li>
<li>a++을 수행하면 6이 됨</li>
</ul>
<h3 id="입력-예시-8">입력 예시</h3>
<pre><code class="language-cpp">5</code></pre>
<h3 id="출력-예시-8">출력 예시</h3>
<pre><code class="language-cpp">5를 입력함
a++을 수행하면 6이 됩니다</code></pre>
<h3 id="풀이-8">풀이</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

int main()
{

    int a;
    cin &gt;&gt; a;

    cout &lt;&lt; a &lt;&lt; &quot; 를 입력함&quot; &lt;&lt; endl;
    a++;
    cout &lt;&lt; &quot;a++을 수행하면 &quot; &lt;&lt; a &lt;&lt; &quot;이 됩니다&quot; &lt;&lt; endl;

    return 0;
}</code></pre>
<h2 id="문제-10">문제 10</h2>
<ul>
<li>숫자 1개를 변수 input에 입력</li>
<li>숫자가 3보다 크면 1을 더하고 출력</li>
<li>그렇지 않으면 1을 빼고 출력</li>
</ul>
<h3 id="입력-예시-9">입력 예시</h3>
<pre><code class="language-cpp">5</code></pre>
<h3 id="출력-예시-9">출력 예시</h3>
<pre><code class="language-cpp">6</code></pre>
<h3 id="풀이-9">풀이</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

int main()
{

    int input;
    cin &gt;&gt; input;

    if (input &gt; 3)
    {
        input++;
        cout &lt;&lt; input &lt;&lt; endl;
    }
    else if (input &lt;= 3)
    {
        input--;
        cout &lt;&lt; input &lt;&lt; endl;
    }

    return 0;
}</code></pre>
<h2 id="문제-11">문제 11</h2>
<ul>
<li>숫자 1개를 변수 num에 입력</li>
<li>숫자가 양수라면</li>
</ul>
<pre><code class="language-cpp">###
###
###</code></pre>
<ul>
<li>숫자가 음수라면</li>
</ul>
<pre><code class="language-cpp">$$$
$$$
$$$</code></pre>
<ul>
<li>숫자가 0이면 출력하지 않음</li>
</ul>
<h3 id="입력-예시-10">입력 예시</h3>
<pre><code class="language-cpp">3</code></pre>
<h3 id="출력-예시-10">출력 예시</h3>
<pre><code class="language-cpp">###
###
###</code></pre>
<h3 id="풀이-10">풀이</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

int main()
{

    int num;
    cin &gt;&gt; num;

    if (num &gt; 0)
    {
        cout &lt;&lt; &quot;###&quot; &lt;&lt; endl;
        cout &lt;&lt; &quot;###&quot; &lt;&lt; endl;
        cout &lt;&lt; &quot;###&quot; &lt;&lt; endl;
    }
    else if (num &lt; 0)
    {
        cout &lt;&lt; &quot;$$$&quot; &lt;&lt; endl;
        cout &lt;&lt; &quot;$$$&quot; &lt;&lt; endl;
        cout &lt;&lt; &quot;$$$&quot; &lt;&lt; endl;
    }
    else
    {

    }

    return 0;
}</code></pre>
<h2 id="문제-12">문제 12</h2>
<ul>
<li>숫자 3개 입력</li>
<li>세 수의 합이 세 수의 곱보다 같거나 행운의 수 출력</li>
<li>아니면 소소한 수</li>
</ul>
<h3 id="입력-예시-11">입력 예시</h3>
<pre><code class="language-cpp">1 2 3</code></pre>
<h3 id="출력-예시-11">출력 예시</h3>
<pre><code class="language-cpp">행운의 수</code></pre>
<h3 id="풀이-11">풀이</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

int main()
{

    int a, b, c;
    cin &gt;&gt; a &gt;&gt; b &gt;&gt; c;

    if ((a + b + c) &gt;= (a * b * c))
    {
        cout &lt;&lt; &quot;행운의 수&quot; &lt;&lt; endl;
    }
    else
    {
        cout &lt;&lt; &quot;소소한 수&quot; &lt;&lt; endl;
    }

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[20250902]]></title>
            <link>https://velog.io/@charlese_note/20250902</link>
            <guid>https://velog.io/@charlese_note/20250902</guid>
            <pubDate>Wed, 03 Sep 2025 14:03:57 GMT</pubDate>
            <description><![CDATA[<h1 id="part-1-객관식-step-1-함수">Part 1. 객관식 (Step 1: 함수)</h1>
<h2 id="1-1-quiz-함수의-주된-사용-목적은-무엇일까요">1-1. [Quiz] 함수의 주된 사용 목적은 무엇일까요?</h2>
<p>① 코드 실행 속도 향상</p>
<p>② 변수 선언 없이 사용</p>
<p>③ 코드 재사용성 및 관리 용이성 증대</p>
<p>④ 컴파일 오류 방지</p>
<hr>
<h2 id="1-2-quiz-함수의-반환-타입이나-매개변수-목록에-void-키워드를-사용하는-것은-무엇을-의미할까요">1-2. [Quiz] 함수의 반환 타입이나 매개변수 목록에 &#39;void&#39; 키워드를 사용하는 것은 무엇을 의미할까요?</h2>
<p>① 매개변수나 반환값이 임시 메모리에 저장된다</p>
<p>② 함수가 아무런 매개변수를 받지 않거나, 아무런 값을 반환하지 않는다</p>
<p>③ 함수가 전역 변수만 사용한다</p>
<p>④ 함수 실행 중 오류가 발생할 수 있다</p>
<hr>
<h2 id="1-3-quiz-함수-내에서-선언된-지역-변수는-프로그램-실행-중-주로-메모리의-어느-영역에-할당될까요">1-3. [Quiz] 함수 내에서 선언된 지역 변수는 프로그램 실행 중 주로 메모리의 어느 영역에 할당될까요?</h2>
<p>① 힙 (Heap)</p>
<p>② 코드 섹션 (Code section)</p>
<p>③ 스택 (Stack)</p>
<p>④ 데이터 섹션 (Data section)</p>
<hr>
<h2 id="1-4-함수-선언declaration과-정의definition의-차이로-옳은-것은">1-4. 함수 선언(Declaration)과 정의(Definition)의 차이로 옳은 것은?</h2>
<p>① 선언은 .cpp에, 정의는 .h에 작성한다</p>
<p>② 선언은 실제 구현을 포함하고, 정의는 시그니처만 가진다</p>
<p>③ 선언은 시그니처만(세미콜론으로 끝), 정의는 실제 구현(<code>{}</code> 안에 코드)</p>
<p>④ 선언 없이 정의만 있으면 컴파일이 더 빠르다</p>
<hr>
<h2 id="1-5-함수-오버로딩이-성립하는-조건으로-옳은-것은">1-5. 함수 오버로딩이 성립하는 조건으로 옳은 것은?</h2>
<p>① 함수 이름만 같으면 된다</p>
<p>② 매개변수 개수나 타입이 달라야 한다</p>
<p>③ 반환 타입만 다르면 된다</p>
<p>④ 같은 .cpp 파일에 있어야 한다</p>
<hr>
<h2 id="1-6-c에서-함수-호출-전에-선언이-먼저-있어야-하는-이유는">1-6. C++에서 함수 호출 전에 선언이 먼저 있어야 하는 이유는?</h2>
<p>① 실행 속도를 높이기 위해</p>
<p>② C++는 위에서 아래로 분석하므로, 호출 시점에 해당 함수의 존재를 알아야 함</p>
<p>③ 메모리 절약을 위해</p>
<p>④ 링커가 연결하기 위해</p>
<hr>
<h2 id="1-7-전역-변수와-지역-변수의-차이로-옳은-것은">1-7. 전역 변수와 지역 변수의 차이로 옳은 것은?</h2>
<p>① 전역 변수는 스택에, 지역 변수는 Data 영역에 저장된다</p>
<p>② 전역 변수는 Data 영역·프로그램 전체 유효, 지역 변수는 스택·함수 내 유효</p>
<p>③ 지역 변수는 함수 종료 후에도 값이 유지된다</p>
<p>④ 전역 변수를 사용하는 것이 항상 권장된다</p>
<hr>
<h1 id="part-2-객관식-step-23-스택-스택-프레임">Part 2. 객관식 (Step 2~3: 스택, 스택 프레임)</h1>
<h2 id="2-1-스택-메모리의-특징으로-옳은-것은">2-1. 스택 메모리의 특징으로 옳은 것은?</h2>
<p>① FIFO(선입선출) 구조이다</p>
<p>② LIFO(후입선출) 구조이며, 가장 나중에 호출된 함수가 먼저 종료된다</p>
<p>③ 프로그램 종료 시까지 데이터가 유지된다</p>
<p>④ 힙보다 크기가 크다</p>
<hr>
<h2 id="2-2-스택-오버플로우가-발생하는-주된-원인은">2-2. 스택 오버플로우가 발생하는 주된 원인은?</h2>
<p>① 전역 변수를 너무 많이 사용할 때</p>
<p>② 재귀 함수의 종료 조건 누락 등으로 스택 프레임이 무한히 쌓일 때</p>
<p>③ 지역 변수를 선언할 때</p>
<p>④ #include를 많이 할 때</p>
<hr>
<h2 id="2-3-스택-프레임에-포함되지-않는-것은">2-3. 스택 프레임에 포함되지 않는 것은?</h2>
<p>① 매개변수</p>
<p>② 반환 주소</p>
<p>③ 지역 변수</p>
<p>④ 전역 변수</p>
<hr>
<h2 id="2-4-다음-코드의-출력-결과는">2-4. 다음 코드의 출력 결과는?</h2>
<pre><code class="language-cpp">void AddHp(int hp, int value) { hp += value; }
int main() {
    int hp = 100;
    AddHp(hp, 20);
    cout &lt;&lt; hp &lt;&lt; endl;
}</code></pre>
<p>① 120</p>
<p>② 100</p>
<p>③ 20</p>
<p>④ 컴파일 에러</p>
<hr>
<h2 id="2-5-다음-코드의-출력-결과는">2-5. 다음 코드의 출력 결과는?</h2>
<pre><code class="language-cpp">int Test(int&amp; a) { a += 10; return a; }
int main() {
    int x = 5;
    Test(x);
    cout &lt;&lt; x &lt;&lt; endl;
}</code></pre>
<p>① 5</p>
<p>② 15</p>
<p>③ 10</p>
<p>④ 컴파일 에러</p>
<hr>
<h2 id="2-6-복사-전달call-by-value과-참조-전달call-by-reference의-차이로-옳은-것은">2-6. 복사 전달(Call by Value)과 참조 전달(Call by Reference)의 차이로 옳은 것은?</h2>
<p>① 복사 전달은 원본을 수정할 수 있고, 참조 전달은 불가능하다</p>
<p>② 복사 전달은 값만 복사되어 원본 영향 없음, 참조 전달은 원본 직접 수정 가능</p>
<p>③ 참조 전달은 <code>int a</code> 형태로 받는다</p>
<p>④ 복사 전달이 항상 더 빠르다</p>
<hr>
<h1 id="part-3-객관식-step-4-디버깅">Part 3. 객관식 (Step 4: 디버깅)</h1>
<h2 id="3-1-quiz-디버깅-시-중단점breakpoint을-설정하는-주된-목적은-무엇일까요">3-1. [Quiz] 디버깅 시 &#39;중단점(Breakpoint)&#39;을 설정하는 주된 목적은 무엇일까요?</h2>
<p>① 프로그램의 전체 실행 시간을 측정하기 위해</p>
<p>② 특정 코드 줄에서 프로그램 실행을 일시 중지시키기 위해</p>
<p>③ 코드의 문법 오류를 자동으로 수정하기 위해</p>
<p>④ 다른 함수를 호출하는 것을 방지하기 위해</p>
<hr>
<h2 id="3-2-visual-studio에서-브레이크포인트를-설정해제하는-단축키는">3-2. Visual Studio에서 브레이크포인트를 설정/해제하는 단축키는?</h2>
<p>① F5</p>
<p>② F9</p>
<p>③ F10</p>
<p>④ F11</p>
<hr>
<h2 id="3-3-f10step-over과-f11step-into의-차이로-옳은-것은">3-3. F10(Step Over)과 F11(Step Into)의 차이로 옳은 것은?</h2>
<p>① F10은 함수 내부로 진입하고, F11은 그렇지 않다</p>
<p>② F10은 현재 줄만 실행하고 함수 안으로 들어가지 않음, F11은 함수 내부로 진입</p>
<p>③ F10은 프로그램을 종료하고, F11은 재시작한다</p>
<p>④ 둘은 동일하다</p>
<hr>
<h2 id="3-4-호출-스택call-stack-창의-역할로-옳은-것은">3-4. 호출 스택(Call Stack) 창의 역할로 옳은 것은?</h2>
<p>① 변수 값을 수정한다</p>
<p>② 현재까지 호출된 함수들의 순서를 추적한다</p>
<p>③ 컴파일 에러를 표시한다</p>
<p>④ 실행 속도를 측정한다</p>
<hr>
<h2 id="3-5-조건부-브레이크포인트의-용도로-옳은-것은">3-5. 조건부 브레이크포인트의 용도로 옳은 것은?</h2>
<p>① 모든 줄에서 멈춘다</p>
<p>② 특정 조건(예: hp &lt;= 0)이 만족될 때만 정지한다</p>
<p>③ 컴파일 시점에만 작동한다</p>
<p>④ 링킹 오류를 수정한다</p>
<hr>
<h2 id="3-6-조사식watch-창에서-할-수-있는-것은">3-6. 조사식(Watch) 창에서 할 수 있는 것은?</h2>
<p>① 소스 코드를 수정한다</p>
<p>② 변수나 수식(hp + 200 등)을 등록해 실시간으로 값 추적</p>
<p>③ 브레이크포인트를 자동 설정한다</p>
<p>④ 실행 파일을 생성한다</p>
<hr>
<h1 id="part-4-객관식-step-56-textrpg-파일-분할">Part 4. 객관식 (Step 5~6: TextRPG, 파일 분할)</h1>
<h2 id="4-1-quiz-c에서-코드를-여러-파일로-분할할-때-헤더-파일h-또는-hpp의-주된-역할은-무엇일까요">4-1. [Quiz] C++에서 코드를 여러 파일로 분할할 때, 헤더 파일(.h 또는 .hpp)의 주된 역할은 무엇일까요?</h2>
<p>① 함수의 실제 구현 내용을 담는다</p>
<p>② 전역 변수나 상수 값을 저장한다</p>
<p>③ 다른 파일에서 사용할 함수나 변수 등의 선언을 제공한다</p>
<p>④ 프로그램 실행에 필요한 라이브러리를 모두 포함시킨다</p>
<hr>
<h2 id="4-2-textrpg의-게임-흐름-순서로-옳은-것은">4-2. TextRPG의 게임 흐름 순서로 옳은 것은?</h2>
<p>① main → EnterBattle → EnterField → SelectPlayer</p>
<p>② main → EnterField → EnterLobby → CreateRandomMonster</p>
<p>③ main → EnterLobby → SelectPlayer → EnterField → CreateRandomMonster → EnterBattle</p>
<p>④ main → CreateRandomMonster → EnterBattle → EnterLobby</p>
<hr>
<h2 id="4-3-extern-int-gtest의-의미로-옳은-것은">4-3. <code>extern int GTest;</code>의 의미로 옳은 것은?</h2>
<p>① GTest 메모리를 이 파일에서 정의한다</p>
<p>② GTest는 다른 파일에서 정의되어 있다고 선언한다</p>
<p>③ GTest를 반드시 사용해야 한다</p>
<p>④ GTest를 삭제한다</p>
<hr>
<h2 id="4-4-pragma-once의-역할은">4-4. <code>#pragma once</code>의 역할은?</h2>
<p>① 컴파일 속도를 높인다</p>
<p>② 헤더 파일이 중복으로 포함되지 않도록 한다</p>
<p>③ extern을 대체한다</p>
<p>④ 링킹을 수행한다</p>
<hr>
<h2 id="4-5-컴파일·링킹-흐름-순서로-옳은-것은">4-5. 컴파일·링킹 흐름 순서로 옳은 것은?</h2>
<p>① 링킹 → 전처리 → 컴파일 → 어셈블</p>
<p>② 전처리 → 컴파일 → 어셈블 → 링킹</p>
<p>③ 컴파일 → 링킹 → 전처리 → 어셈블</p>
<p>④ 어셈블 → 링킹 → 컴파일 → 전처리</p>
<hr>
<h2 id="4-6-lnk-확인할-수-없는-외부-기호-에러의-원인은">4-6. &#39;LNK: 확인할 수 없는 외부 기호&#39; 에러의 원인은?</h2>
<p>① #include 누락</p>
<p>② 선언만 있고 정의(구현)가 없음</p>
<p>③ #pragma once 누락</p>
<p>④ 매개변수 타입 불일치</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[연습문제 1]]></title>
            <link>https://velog.io/@charlese_note/20250901</link>
            <guid>https://velog.io/@charlese_note/20250901</guid>
            <pubDate>Wed, 03 Sep 2025 14:02:45 GMT</pubDate>
            <description><![CDATA[<h1 id="part-1-객관식-step-13-컴퓨터-구조-프로그래밍-데이터와-로직">Part 1. 객관식 (Step 1~3: 컴퓨터 구조, 프로그래밍, 데이터와 로직)</h1>
<h2 id="1-1-cpu에-대한-설명으로-옳은-것은">1-1. CPU에 대한 설명으로 옳은 것은?</h2>
<p>① CPU는 데이터를 영구적으로 저장할 수 있다.</p>
<p>② CPU는 연산 속도가 느리지만 기억력이 좋다.</p>
<p>③ CPU는 연산을 담당하며, 기억력이 짧아 RAM을 활용한다.</p>
<p>④ CPU 쿨러는 전원 공급을 담당한다.</p>
<hr>
<h2 id="1-2-ram의-4가지-영역-중-함수-호출-정보가-저장되는-영역은">1-2. RAM의 4가지 영역 중 &#39;함수 호출 정보&#39;가 저장되는 영역은?</h2>
<p>① Code (Text)</p>
<p>② Data</p>
<p>③ Heap</p>
<p>④ Stack</p>
<hr>
<h2 id="1-3-ssdhdd에-대한-설명으로-옳지-않은-것은">1-3. SSD/HDD에 대한 설명으로 <strong>옳지 않은</strong> 것은?</h2>
<p>① 전원이 꺼져도 데이터가 유지된다.</p>
<p>② SSD는 RAM보다 접근 속도가 빠르다.</p>
<p>③ 게임 설치 파일은 SSD에 저장된다.</p>
<p>④ 프로그램 실행 시 SSD에서 RAM으로 복사(로드)된다.</p>
<hr>
<h2 id="1-4-컴파일에-대한-설명으로-옳은-것은">1-4. 컴파일에 대한 설명으로 옳은 것은?</h2>
<p>① 컴파일은 프로그래밍 언어 코드를 기계어로 번역하는 과정이다.</p>
<p>② 컴파일러 없이도 CPU가 직접 C++ 코드를 이해할 수 있다.</p>
<p>③ 세미콜론을 생략해도 컴파일이 성공한다.</p>
<p>④ 컴파일과 빌드는 서로 다른 과정이다.</p>
<hr>
<h2 id="1-5-프로그램의-핵심-요소가-아닌-것은">1-5. 프로그램의 핵심 요소가 아닌 것은?</h2>
<p>① 데이터</p>
<p>② 로직</p>
<p>③ CPU</p>
<p>④ (없음 - ①②가 핵심)</p>
<hr>
<h2 id="1-6-quiz-컴퓨터의-핵심-부품인-cpu와-ram의-주된-역할-관계는-무엇인가">1-6. [Quiz] 컴퓨터의 핵심 부품인 CPU와 RAM의 주된 역할 관계는 무엇인가?</h2>
<p>① CPU는 데이터를 저장하고, RAM은 복잡한 계산을 처리한다.</p>
<p>② CPU는 명령을 계산/실행하고, RAM은 데이터를 일시적으로 저장한다.</p>
<p>③ CPU는 프로그램을 영구 저장하고, RAM은 전원을 공급한다.</p>
<p>④ CPU는 화면에 결과만 출력하고, RAM은 모든 입력을 관리한다.</p>
<hr>
<h1 id="part-2-객관식-step-49-변수-타입-main-maxhp">Part 2. 객관식 (Step 4~9: 변수, 타입, main, maxHp)</h1>
<h2 id="2-1-변수-사용-3단계가-아닌-것은">2-1. 변수 사용 3단계가 아닌 것은?</h2>
<p>① 할당 (공간 확보)</p>
<p>② 쓰기 (값 넣기)</p>
<p>③ 읽기 (값 꺼내기)</p>
<p>④ 삭제 (메모리 해제)</p>
<hr>
<h2 id="2-2-hp--50에서-의-의미로-옳은-것은">2-2. <code>hp = 50;</code>에서 <code>=</code>의 의미로 옳은 것은?</h2>
<p>① 양쪽이 같다.</p>
<p>② 오른쪽 값을 왼쪽 변수에 대입한다.</p>
<p>③ 50을 비교한다.</p>
<p>④ hp와 50을 교환한다.</p>
<hr>
<h2 id="2-3-int-타입의-바이트-크기는">2-3. int 타입의 바이트 크기는?</h2>
<p>① 1</p>
<p>② 2</p>
<p>③ 4</p>
<p>④ 8</p>
<hr>
<h2 id="2-4-전역-변수에-대한-설명으로-옳은-것은">2-4. 전역 변수에 대한 설명으로 옳은 것은?</h2>
<p>① main() 안에 선언한다.</p>
<p>② Stack 영역에 할당된다.</p>
<p>③ main() 밖에 선언하며 Data 영역에 할당된다.</p>
<p>④ 함수 내부에서만 사용 가능하다.</p>
<hr>
<h2 id="2-5-maxhp를-사용해-hp를-복구할-때-올바른-코드는">2-5. maxHp를 사용해 HP를 복구할 때 올바른 코드는?</h2>
<p>① <code>hp = 100;</code></p>
<p>② <code>hp = maxHp;</code></p>
<p>③ <code>maxHp = hp;</code></p>
<p>④ <code>hp == maxHp;</code></p>
<hr>
<h2 id="2-6-quiz-프로그래밍에서-변수variable를-사용하는-가장-중요한-이유는-무엇인가">2-6. [Quiz] 프로그래밍에서 &#39;변수(Variable)&#39;를 사용하는 가장 중요한 이유는 무엇인가?</h2>
<p>① 코드의 줄 수를 줄여서 프로그램을 짧게 만들려고</p>
<p>② 메모리 공간에 이름을 붙여 데이터를 편리하게 저장하고 사용하려고</p>
<p>③ 프로그램 실행 속도를 무조건 빠르게 만들려고</p>
<p>④ 컴퓨터의 운영체제를 설치하기 위해</p>
<hr>
<h1 id="part-3-객관식-step-1011-정수·비트-데이터-타입">Part 3. 객관식 (Step 10~11: 정수·비트, 데이터 타입)</h1>
<h2 id="3-1-1바이트는-몇-비트인가">3-1. 1바이트는 몇 비트인가?</h2>
<p>① 4</p>
<p>② 8</p>
<p>③ 16</p>
<p>④ 32</p>
<hr>
<h2 id="3-2-2의-보수로--43을-구하는-방법은-43이-주어졌을-때">3-2. 2의 보수로 -43을 구하는 방법은? (43이 주어졌을 때)</h2>
<p>① 비트 반전</p>
<p>② 비트 반전 후 +1</p>
<p>③ -1 후 비트 반전</p>
<p>④ 그대로 - 부호 붙이기</p>
<hr>
<h2 id="3-3-0xff의-10진수-값은">3-3. <code>0xFF</code>의 10진수 값은?</h2>
<p>① 15</p>
<p>② 16</p>
<p>③ 255</p>
<p>④ 256</p>
<hr>
<h2 id="3-4-char-타입으로-a의-ascii-값을-출력하려면">3-4. char 타입으로 &#39;A&#39;의 ASCII 값을 출력하려면?</h2>
<p>① <code>cout &lt;&lt; ch;</code></p>
<p>② <code>cout &lt;&lt; (int)ch;</code></p>
<p>③ <code>cout &lt;&lt; int(ch);</code></p>
<p>④ ②, ③ 모두 가능</p>
<hr>
<h2 id="3-5-float-리터럴을-사용할-때-필요한-접미사는">3-5. float 리터럴을 사용할 때 필요한 접미사는?</h2>
<p>① L</p>
<p>② f</p>
<p>③ d</p>
<p>④ u</p>
<hr>
<h2 id="3-6-quiz-정수형-변수char-short-int-long-long의-크기가-1바이트-2바이트-등으로-다른-주된-이유와-결과는-무엇인가">3-6. [Quiz] 정수형 변수(char, short, int, long long)의 크기가 1바이트, 2바이트 등으로 다른 주된 이유와 결과는 무엇인가?</h2>
<p>① 크기가 클수록 변수의 이름을 더 길게 지을 수 있다.</p>
<p>② 크기에 따라 사용할 수 있는 연산자의 종류가 달라진다.</p>
<p>③ 크기가 클수록 더 넓은 범위의 정수를 표현하고 저장할 수 있다.</p>
<p>④ 크기가 작을수록 음수는 저장할 수 없게 된다.</p>
<hr>
<h1 id="part-4-객관식-step-1213-연산자-비교·논리">Part 4. 객관식 (Step 12~13: 연산자, 비교·논리)</h1>
<h2 id="4-1-10--3의-결과는">4-1. <code>10 % 3</code>의 결과는?</h2>
<p>① 0</p>
<p>② 1</p>
<p>③ 3</p>
<p>④ 3.333</p>
<hr>
<h2 id="4-2-a--hp-실행-후-a에-들어가는-값은">4-2. <code>a = hp++;</code> 실행 후, a에 들어가는 값은?</h2>
<p>① hp 증가 후의 값</p>
<p>② hp 증가 전의 값</p>
<p>③ 0</p>
<p>④ 정의되지 않음</p>
<hr>
<h2 id="4-3-8--1의-결과는">4-3. <code>8 &lt;&lt; 1</code>의 결과는?</h2>
<p>① 4</p>
<p>② 8</p>
<p>③ 16</p>
<p>④ 64</p>
<hr>
<h2 id="4-4-와-의-우선순위-중-더-높은-것은">4-4. <code>&amp;&amp;</code>와 <code>||</code>의 우선순위 중 더 높은 것은?</h2>
<p>① <code>||</code></p>
<p>② <code>&amp;&amp;</code></p>
<p>③ 같음</p>
<p>④ 상황에 따라 다름</p>
<hr>
<h2 id="4-5-100--2--5--2의-결과는">4-5. <code>100 * (2 + 5) / 2</code>의 결과는?</h2>
<p>① 350</p>
<p>② 202</p>
<p>③ 3500</p>
<p>④ 45</p>
<hr>
<h2 id="4-6-quiz-두-개-이상의-조건이-모두-참true이어야만-결과가-참이-되는-논리-연산자는-무엇인가">4-6. [Quiz] 두 개 이상의 조건이 &#39;모두 참(True)&#39;이어야만 결과가 참이 되는 논리 연산자는 무엇인가?</h2>
<p>① NOT 연산자 (<code>!</code>)</p>
<p>② AND 연산자 (<code>&amp;&amp;</code>)</p>
<p>③ OR 연산자 (<code>||</code>)</p>
<p>④ XOR 연산자 (<code>^</code>)</p>
<hr>
<h1 id="part-5-객관식-step-1416-조건문-반복문">Part 5. 객관식 (Step 14~16: 조건문, 반복문)</h1>
<h2 id="5-1-switch-case에서-break를-생략하면">5-1. switch-case에서 break를 생략하면?</h2>
<p>① 컴파일 에러</p>
<p>② fall-through (다음 case까지 실행)</p>
<p>③ 해당 case만 실행</p>
<p>④ 무한 루프</p>
<hr>
<h2 id="5-2-for-int-i--0-i--5-i에서-반복-횟수는">5-2. <code>for (int i = 0; i &lt; 5; i++)</code>에서 반복 횟수는?</h2>
<p>① 4회</p>
<p>② 5회</p>
<p>③ 6회</p>
<p>④ 무한</p>
<hr>
<h2 id="5-3-continue의-역할은">5-3. continue의 역할은?</h2>
<p>① 반복문을 즉시 종료</p>
<p>② 현재 반복 건너뛰고 다음 반복으로</p>
<p>③ break와 동일</p>
<p>④ 조건식을 건너뜀</p>
<hr>
<h2 id="5-4-switch-case와-if-else-if를-선택할-때-switch-case가-적합한-경우는">5-4. switch-case와 if-else if를 선택할 때, switch-case가 적합한 경우는?</h2>
<p>① 범위 비교 (예: hp &lt;= 30)</p>
<p>② 정수 값 하나로 분기</p>
<p>③ 복잡한 논리식</p>
<p>④ 문자열 비교</p>
<hr>
<h2 id="5-5-rand--3의-결과-범위는">5-5. <code>rand() % 3</code>의 결과 범위는?</h2>
<p>① 0 ~ 2</p>
<p>② 1 ~ 3</p>
<p>③ 0 ~ 3</p>
<p>④ 0 ~ 대략 3만</p>
<hr>
<h2 id="5-6-quiz-프로그램이-실행될-때-특정-조건에-따라-코드의-실행-경로를-여러-갈래로-나누어-처리하게-만드는-문법-구조를-무엇이라고-하는가">5-6. [Quiz] 프로그램이 실행될 때, 특정 조건에 따라 코드의 실행 경로를 여러 갈래로 &#39;나누어&#39; 처리하게 만드는 문법 구조를 무엇이라고 하는가?</h2>
<p>① 반복문 (Loop)</p>
<p>② 산술 연산 (Arithmetic Operation)</p>
<p>③ 분기문 (Branching Statement)</p>
<p>④ 변수 선언 (Variable Declaration)</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[LV19]]></title>
            <link>https://velog.io/@charlese_note/LV19</link>
            <guid>https://velog.io/@charlese_note/LV19</guid>
            <pubDate>Sat, 07 Jun 2025 09:46:36 GMT</pubDate>
            <description><![CDATA[<h2 id="연습문제">연습문제</h2>
<h3 id="문제-1">문제 1</h3>
<ul>
<li>풀이<h3 id="문제-2">문제 2</h3>
</li>
<li>풀이<h3 id="문제-3">문제 3</h3>
</li>
<li>풀이<h3 id="문제-4">문제 4</h3>
</li>
<li>풀이<h3 id="문제-5">문제 5</h3>
</li>
<li>풀이<h3 id="문제-6">문제 6</h3>
</li>
<li>풀이<h3 id="문제-7">문제 7</h3>
</li>
<li>풀이<h3 id="문제-8">문제 8</h3>
</li>
<li>풀이<h3 id="문제-9">문제 9</h3>
</li>
<li>풀이<h3 id="문제-10">문제 10</h3>
</li>
<li>풀이</li>
</ul>
<hr>
<h2 id="복습문제">복습문제</h2>
<h3 id="문제-1-1">문제 1</h3>
<ul>
<li>풀이<h3 id="문제-2-1">문제 2</h3>
</li>
<li>풀이<h3 id="문제-3-1">문제 3</h3>
</li>
<li>풀이<h3 id="문제-4-1">문제 4</h3>
</li>
<li>풀이<h3 id="문제-5-1">문제 5</h3>
</li>
<li>풀이<h3 id="문제-6-1">문제 6</h3>
</li>
<li>풀이<h3 id="문제-7-1">문제 7</h3>
</li>
<li>풀이<h3 id="문제-8-1">문제 8</h3>
</li>
<li>풀이<h3 id="문제-9-1">문제 9</h3>
</li>
<li>풀이</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[LV18]]></title>
            <link>https://velog.io/@charlese_note/LV18</link>
            <guid>https://velog.io/@charlese_note/LV18</guid>
            <pubDate>Sat, 07 Jun 2025 09:43:08 GMT</pubDate>
            <description><![CDATA[<h2 id="연습문제">연습문제</h2>
<h3 id="문제-1">문제 1</h3>
<ul>
<li>풀이<h3 id="문제-2">문제 2</h3>
</li>
<li>풀이<h3 id="문제-3">문제 3</h3>
</li>
<li>풀이<h3 id="문제-4">문제 4</h3>
</li>
<li>풀이<h3 id="문제-5">문제 5</h3>
</li>
<li>풀이<h3 id="문제-6">문제 6</h3>
</li>
<li>풀이<h3 id="문제-7">문제 7</h3>
</li>
<li>풀이<h3 id="문제-8">문제 8</h3>
</li>
<li>풀이<h3 id="문제-9">문제 9</h3>
</li>
<li>풀이<h3 id="문제-10">문제 10</h3>
</li>
<li>풀이</li>
</ul>
<hr>
<h2 id="복습문제">복습문제</h2>
<h3 id="문제-1-1">문제 1</h3>
<ul>
<li>풀이<h3 id="문제-2-1">문제 2</h3>
</li>
<li>풀이<h3 id="문제-3-1">문제 3</h3>
</li>
<li>풀이<h3 id="문제-4-1">문제 4</h3>
</li>
<li>풀이<h3 id="문제-5-1">문제 5</h3>
</li>
<li>풀이<h3 id="문제-6-1">문제 6</h3>
</li>
<li>풀이<h3 id="문제-7-1">문제 7</h3>
</li>
<li>풀이<h3 id="문제-8-1">문제 8</h3>
</li>
<li>풀이<h3 id="문제-9-1">문제 9</h3>
</li>
<li>풀이<h3 id="문제-10-1">문제 10</h3>
</li>
<li>풀이<h3 id="문제-11">문제 11</h3>
</li>
<li>풀이<h3 id="문제-12">문제 12</h3>
</li>
<li>풀이</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[LV17]]></title>
            <link>https://velog.io/@charlese_note/LV17</link>
            <guid>https://velog.io/@charlese_note/LV17</guid>
            <pubDate>Sat, 07 Jun 2025 09:41:17 GMT</pubDate>
            <description><![CDATA[<h2 id="연습문제">연습문제</h2>
<h3 id="문제-1">문제 1</h3>
<ul>
<li>풀이<h3 id="문제-2">문제 2</h3>
</li>
<li>풀이<h3 id="문제-3">문제 3</h3>
</li>
<li>풀이<h3 id="문제-4">문제 4</h3>
</li>
<li>풀이<h3 id="문제-5">문제 5</h3>
</li>
<li>풀이<h3 id="문제-6">문제 6</h3>
</li>
<li>풀이<h3 id="문제-7">문제 7</h3>
</li>
<li>풀이<h3 id="문제-8">문제 8</h3>
</li>
<li>풀이<h3 id="문제-9">문제 9</h3>
</li>
<li>풀이<h3 id="문제-10">문제 10</h3>
</li>
<li>풀이<h3 id="문제-11">문제 11</h3>
</li>
<li>풀이<h3 id="문제-12">문제 12</h3>
</li>
<li>풀이</li>
</ul>
<hr>
<h2 id="복습문제">복습문제</h2>
<h3 id="문제-1-1">문제 1</h3>
<ul>
<li>풀이<h3 id="문제-2-1">문제 2</h3>
</li>
<li>풀이<h3 id="문제-3-1">문제 3</h3>
</li>
<li>풀이<h3 id="문제-4-1">문제 4</h3>
</li>
<li>풀이<h3 id="문제-5-1">문제 5</h3>
</li>
<li>풀이<h3 id="문제-6-1">문제 6</h3>
</li>
<li>풀이<h3 id="문제-7-1">문제 7</h3>
</li>
<li>풀이<h3 id="문제-8-1">문제 8</h3>
</li>
<li>풀이<h3 id="문제-9-1">문제 9</h3>
</li>
<li>풀이</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[LV16]]></title>
            <link>https://velog.io/@charlese_note/LV16</link>
            <guid>https://velog.io/@charlese_note/LV16</guid>
            <pubDate>Sat, 07 Jun 2025 09:38:53 GMT</pubDate>
            <description><![CDATA[<h2 id="연습문제">연습문제</h2>
<h3 id="문제-1">문제 1</h3>
<ul>
<li>풀이<h3 id="문제-2">문제 2</h3>
</li>
<li>풀이<h3 id="문제-3">문제 3</h3>
</li>
<li>풀이<h3 id="문제-4">문제 4</h3>
</li>
<li>풀이<h3 id="문제-5">문제 5</h3>
</li>
<li>풀이<h3 id="문제-6">문제 6</h3>
</li>
<li>풀이<h3 id="문제-7">문제 7</h3>
</li>
<li>풀이<h3 id="문제-8">문제 8</h3>
</li>
<li>풀이<h3 id="문제-9">문제 9</h3>
</li>
<li>풀이</li>
</ul>
<hr>
<h2 id="복습문제">복습문제</h2>
<h3 id="문제-1-1">문제 1</h3>
<ul>
<li>풀이<h3 id="문제-2-1">문제 2</h3>
</li>
<li>풀이<h3 id="문제-3-1">문제 3</h3>
</li>
<li>풀이<h3 id="문제-4-1">문제 4</h3>
</li>
<li>풀이<h3 id="문제-5-1">문제 5</h3>
</li>
<li>풀이<h3 id="문제-6-1">문제 6</h3>
</li>
<li>풀이<h3 id="문제-7-1">문제 7</h3>
</li>
<li>풀이<h3 id="문제-8-1">문제 8</h3>
</li>
<li>풀이<h3 id="문제-9-1">문제 9</h3>
</li>
<li>풀이<h3 id="문제-10">문제 10</h3>
</li>
<li>풀이</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[LV15]]></title>
            <link>https://velog.io/@charlese_note/LV15</link>
            <guid>https://velog.io/@charlese_note/LV15</guid>
            <pubDate>Sat, 07 Jun 2025 09:36:19 GMT</pubDate>
            <description><![CDATA[<h2 id="연습문제">연습문제</h2>
<h3 id="문제-1">문제 1</h3>
<ul>
<li>풀이<h3 id="문제-2">문제 2</h3>
</li>
<li>풀이<h3 id="문제-3">문제 3</h3>
</li>
<li>풀이<h3 id="문제-4">문제 4</h3>
</li>
<li>풀이<h3 id="문제-5">문제 5</h3>
</li>
<li>풀이<h3 id="문제-6">문제 6</h3>
</li>
<li>풀이<h3 id="문제-7">문제 7</h3>
</li>
<li>풀이<h3 id="문제-8">문제 8</h3>
</li>
<li>풀이<h3 id="문제-9">문제 9</h3>
</li>
<li>풀이<h3 id="문제-10">문제 10</h3>
</li>
<li>풀이<h3 id="문제-11">문제 11</h3>
</li>
<li>풀이</li>
</ul>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[LV14]]></title>
            <link>https://velog.io/@charlese_note/LV14</link>
            <guid>https://velog.io/@charlese_note/LV14</guid>
            <pubDate>Sat, 07 Jun 2025 09:35:29 GMT</pubDate>
            <description><![CDATA[<h2 id="연습문제">연습문제</h2>
<h3 id="문제-1">문제 1</h3>
<ul>
<li>풀이<h3 id="문제-2">문제 2</h3>
</li>
<li>풀이<h3 id="문제-3">문제 3</h3>
</li>
<li>풀이<h3 id="문제-4">문제 4</h3>
</li>
<li>풀이<h3 id="문제-5">문제 5</h3>
</li>
<li>풀이<h3 id="문제-6">문제 6</h3>
</li>
<li>풀이<h3 id="문제-7">문제 7</h3>
</li>
<li>풀이<h3 id="문제-8">문제 8</h3>
</li>
<li>풀이<h3 id="문제-9">문제 9</h3>
</li>
<li>풀이<h3 id="문제-10">문제 10</h3>
</li>
<li>풀이<h3 id="문제-11">문제 11</h3>
</li>
<li>풀이<h3 id="문제-12">문제 12</h3>
</li>
<li>풀이<h3 id="문제-13">문제 13</h3>
</li>
<li>풀이<h3 id="문제-14">문제 14</h3>
</li>
<li>풀이</li>
</ul>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[LV13]]></title>
            <link>https://velog.io/@charlese_note/LV13</link>
            <guid>https://velog.io/@charlese_note/LV13</guid>
            <pubDate>Sat, 07 Jun 2025 09:34:56 GMT</pubDate>
            <description><![CDATA[<h2 id="연습문제">연습문제</h2>
<h3 id="문제-1">문제 1</h3>
<ul>
<li>풀이<h3 id="문제-2">문제 2</h3>
</li>
<li>풀이<h3 id="문제-3">문제 3</h3>
</li>
<li>풀이<h3 id="문제-4">문제 4</h3>
</li>
<li>풀이<h3 id="문제-5">문제 5</h3>
</li>
<li>풀이<h3 id="문제-6">문제 6</h3>
</li>
<li>풀이<h3 id="문제-7">문제 7</h3>
</li>
<li>풀이<h3 id="문제-8">문제 8</h3>
</li>
<li>풀이<h3 id="문제-9">문제 9</h3>
</li>
<li>풀이<h3 id="문제-10">문제 10</h3>
</li>
<li>풀이<h3 id="문제-11">문제 11</h3>
</li>
<li>풀이<h3 id="문제-12">문제 12</h3>
</li>
<li>풀이</li>
</ul>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[LV12]]></title>
            <link>https://velog.io/@charlese_note/LV12</link>
            <guid>https://velog.io/@charlese_note/LV12</guid>
            <pubDate>Sat, 07 Jun 2025 09:31:44 GMT</pubDate>
            <description><![CDATA[<h2 id="연습문제">연습문제</h2>
<h3 id="문제-1">문제 1</h3>
<ul>
<li>풀이<h3 id="문제-2">문제 2</h3>
</li>
<li>풀이<h3 id="문제-3">문제 3</h3>
</li>
<li>풀이<h3 id="문제-4">문제 4</h3>
</li>
<li>풀이<h3 id="문제-5">문제 5</h3>
</li>
<li>풀이<h3 id="문제-6">문제 6</h3>
</li>
<li>풀이<h3 id="문제-7">문제 7</h3>
</li>
<li>풀이<h3 id="문제-8">문제 8</h3>
</li>
<li>풀이<h3 id="문제-9">문제 9</h3>
</li>
<li>풀이<h3 id="문제-10">문제 10</h3>
</li>
<li>풀이</li>
</ul>
<hr>
<h2 id="복습-문제">복습 문제</h2>
<h3 id="문제-1-1">문제 1</h3>
<ul>
<li>풀이<h3 id="문제-2-1">문제 2</h3>
</li>
<li>풀이<h3 id="문제-3-1">문제 3</h3>
</li>
<li>풀이<h3 id="문제-4-1">문제 4</h3>
</li>
<li>풀이<h3 id="문제-5-1">문제 5</h3>
</li>
<li>풀이<h3 id="문제-6-1">문제 6</h3>
</li>
<li>풀이<h3 id="문제-7-1">문제 7</h3>
</li>
<li>풀이<h3 id="문제-8-1">문제 8</h3>
</li>
<li>풀이</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[LV11]]></title>
            <link>https://velog.io/@charlese_note/LV11</link>
            <guid>https://velog.io/@charlese_note/LV11</guid>
            <pubDate>Sat, 07 Jun 2025 06:43:20 GMT</pubDate>
            <description><![CDATA[<h2 id="연습문제">연습문제</h2>
<h3 id="문제-1">문제 1</h3>
<ul>
<li>풀이<h3 id="문제-2">문제 2</h3>
</li>
<li>풀이<h3 id="문제-3">문제 3</h3>
</li>
<li>풀이<h3 id="문제-4">문제 4</h3>
</li>
<li>풀이<h3 id="문제-5">문제 5</h3>
</li>
<li>풀이<h3 id="문제-6">문제 6</h3>
</li>
<li>풀이<h3 id="문제-7">문제 7</h3>
</li>
<li>풀이<h3 id="문제-8">문제 8</h3>
</li>
<li>풀이<h3 id="문제-9">문제 9</h3>
</li>
<li>풀이<h3 id="문제-10">문제 10</h3>
</li>
<li>풀이<h3 id="문제-11">문제 11</h3>
</li>
<li>풀이<h3 id="문제-12">문제 12</h3>
</li>
<li>풀이</li>
</ul>
<hr>
<h2 id="복습-문제">복습 문제</h2>
<h3 id="문제-1-1">문제 1</h3>
<ul>
<li>풀이<h3 id="문제-2-1">문제 2</h3>
</li>
<li>풀이<h3 id="문제-3-1">문제 3</h3>
</li>
<li>풀이<h3 id="문제-4-1">문제 4</h3>
</li>
<li>풀이<h3 id="문제-5-1">문제 5</h3>
</li>
<li>풀이<h3 id="문제-6-1">문제 6</h3>
</li>
<li>풀이<h3 id="문제-7-1">문제 7</h3>
</li>
<li>풀이<h3 id="문제-8-1">문제 8</h3>
</li>
<li>풀이<h3 id="문제-9-1">문제 9</h3>
</li>
<li>풀이<h3 id="문제-10-1">문제 10</h3>
</li>
<li>풀이</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[LV10]]></title>
            <link>https://velog.io/@charlese_note/LV10</link>
            <guid>https://velog.io/@charlese_note/LV10</guid>
            <pubDate>Sat, 07 Jun 2025 06:42:58 GMT</pubDate>
            <description><![CDATA[<h2 id="연습문제">연습문제</h2>
<h3 id="문제-1">문제 1</h3>
<ul>
<li>풀이<h3 id="문제-2">문제 2</h3>
</li>
<li>풀이<h3 id="문제-3">문제 3</h3>
</li>
<li>풀이<h3 id="문제-4">문제 4</h3>
</li>
<li>풀이<h3 id="문제-5">문제 5</h3>
</li>
<li>풀이<h3 id="문제-6">문제 6</h3>
</li>
<li>풀이<h3 id="문제-7">문제 7</h3>
</li>
<li>풀이<h3 id="문제-8">문제 8</h3>
</li>
<li>풀이<h3 id="문제-9">문제 9</h3>
</li>
<li>풀이<h3 id="문제-10">문제 10</h3>
</li>
<li>풀이<h3 id="문제-11">문제 11</h3>
</li>
<li>풀이<h3 id="문제-12">문제 12</h3>
</li>
<li>풀이</li>
</ul>
<hr>
<h2 id="복습-문제">복습 문제</h2>
<h3 id="문제-1-1">문제 1</h3>
<ul>
<li>풀이<h3 id="문제-2-1">문제 2</h3>
</li>
<li>풀이<h3 id="문제-3-1">문제 3</h3>
</li>
<li>풀이<h3 id="문제-4-1">문제 4</h3>
</li>
<li>풀이<h3 id="문제-5-1">문제 5</h3>
</li>
<li>풀이<h3 id="문제-6-1">문제 6</h3>
</li>
<li>풀이<h3 id="문제-7-1">문제 7</h3>
</li>
<li>풀이<h3 id="문제-8-1">문제 8</h3>
</li>
<li>풀이<h3 id="문제-9-1">문제 9</h3>
</li>
<li>풀이</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>