한 줄 요약: 송신 측에서는 데이터가 계층을 내려가면서 헤더 등을 추가하는 캡슐화 가 이루어지고, 수신 측에서는 계층을 올라가면서 이를 제거하는 역캡슐화 가 이루어진다. 캡슐화와 역캡슐화 이전 강의에서 네트워크 통신 과정을 여러 계층(Layer) 으로 나누어 볼 수 있다고 배웠다. 실제로 메시지가 네트워크를 통해 전달될 때도 이러한 계층을 이동한다. 송신 측 수신 측 상위 계층 상위 계층 ↓ ↑ ↓ 네트워크 전송 ↑ ↓ ─────────────────→ ↑ 하위 계층 하위 계층 여기서 송신 과정과 수신 과정의 방향이 반대라는 것이 중요하다. 1. 캡슐화(Encapsulation) 송신 측에서 데이터는 상위 계층 → 하위 계층 순서로 이동한다. 이 과정에서 각 계층은 자신의 프로토콜에 필요한 헤더 또는 트레일러를 추가 한다. 이 과정을 캡슐화 라고 한다. 상위 계층 [Data] ↓ Header 추가 [Header][Data] ↓ Header 추가 [Header][Header][Data] ↓ 하위 계층 각 계층의 프로토콜은 목적과 특징이 다르기 때문에 필요한 정보도 다르다. 따라서 계층을 내려갈 때마다 해당 계층에서 필요한 정보가 추가될 수 있다. 캡슐화 = 데이터를 계층 아래로 내려보내면서 각 계층에 필요한 정보를 덧붙이는 과정 상위 계층의 패킷은 Payload가 된다 캡슐화에서 중요한 개념이다. 상위 계층에서 만들어진 전체 패킷은 하위 계층으로 내려가면 Payload 로 취급된다. 예를 들어 상위 계층 [Header A][Data] 가 하위 계층으로 내려가면 하위 계층 [Header B][Header A][Data] └──── Payload ────┘ 처럼 볼 수 있다. 즉, 현재 계층 입장에서는 상위 계층에서 전달받은 데이터 전체가 자신의 Payload가 된다. 그리고 자신의 프로토콜에 필요한 헤더 등을 추가한다. 2. 역캡슐화(Decapsulation) 수신 측에서는 반대 과정이 이루어진다. 데이터가 하위 계층 → 상위 계층 순서로 이동하면서 각 계층이 자신의 Header 또는 Trailer 를 확인한 뒤 제거한다. 이를 역캡슐화 라고 한다. 하위 계층 [Header C][Header B][Header A][Data] ↓ Header 제거 [Header B][Header A][Data] ↓ Header 제거 [Header A][Data] ↓ Header 제거 [Data] 상위 계층 송신 측에서 추가했던 정보를 수신 측에서 하나씩 제거한다고 생각하면 이해하기 쉽다. 역캡슐화 = 계층을 올라가면서 각 계층의 헤더 등을 확인하고 제거하는 과정 캡슐화 vs 역캡슐화 구분 캡슐화 역캡슐화 위치 송신 측 수신 측 방향 상위 → 하위 하위 → 상위 주요 작업 헤더 등을 추가 헤더 등을 확인·제거 목적 전송에 필요한 정보 추가 원래 데이터를 전달 가장 간단하게는 다음처럼 기억하면 된다. 송신 Data ↓ Header + Data ↓ Header + Header + Data ↓ 전송 ──────────────────────→ 수신 Header + Header + Data ↓ Header + Data ↓ Data PDU(Protocol Data Unit) 계층별로 송수신되는 메시지의 단위를 PDU(Protocol Data Unit) 라고 한다. 중요한 점은 계층에 따라 PDU를 부르는 이름이 달라진다는 것 이다. OSI 계층 PDU 응용·표현·세션 계층 데이터(Data) 전송 계층 세그먼트(Segment) / 데이터그램(Datagram) 네트워크 계층 패킷(Packet) 데이터 링크 계층 프레임(Frame) 물리 계층 비트(Bit) 흐름으로 보면 다음과 같다. 응용 계층 Data ↓ 전송 계층 Segment / Datagram ↓ 네트워크 계층 Packet ↓ 데이터 링크 계층 Frame ↓ 물리 계층 Bit 수신 측에서는 반대 방향으로 올라간다. Bit ↑ Frame ↑ Packet ↑ Segment / Datagram ↑ Data PDU와 캡슐화의 관계 현재 계층의 PDU는 기본적으로 상위 계층에서 받은 데이터 + 현재 계층의 Header / Trailer 라고 이해할 수 있다. 예를 들어 상위 계층 PDU ↓ Payload + 현재 계층 Header ↓ 현재 계층 PDU 가 되는 것이다. 따라서 캡슐화와 PDU는 서로 연결해서 이해하는 것이 중요하다. 오늘의 정리 송신 측의 메시지는 상위 계층에서 하위 계층으로 이동 한다. 각 계층에서 프로토콜에 필요한 헤더 등을 추가하는 과정이 캡슐화 이다. 상위 계층의 패킷은 하위 계층에서 Payload 가 된다. 수신 측에서는 하위 계층에서 상위 계층으로 이동 한다. 각 계층의 헤더 등을 확인하고 제거하는 과정이 역캡슐화 이다. 계층별로 송수신되는 메시지 단위를 PDU 라고 한다. Data → Segment/Datagram → Packet → Frame → Bit 순서를 기억하자. 핵심 암기: 송신 = 내려가며 붙인다(캡슐화) / 수신 = 올라가며 뗀다(역캡슐화)
지난 글 에서는 codeme 를 왜 만들었는지를 적었습니다. 이번 글은 그 반대편, 실제로 어떻게 쓰는지 입니다. 설명만으로는 감이 안 오니, 작은 결제 API 저장소( payments-api ) 하나를 열어 두고 할 일 세 개를 한꺼번에 처리하는 장면을 처음부터 끝까지 찍었습니다. 글에 나오는 화면은 전부 실제 앱이고, 화면 속 코드 변경도 전부 Claude Code 가 실제로 만든 것입니다 — 연출한 diff 는 없습니다. 오늘의 할 일은 이렇습니다. 웹훅 재시도를 지수 백오프 + jitter 로 바꾸고, 한도를 넘기면 dead letter 로 환불이 누적으로 청구액을 넘지 않게 막기 README 에 API 엔드포인트와 환경 변수 정리 평소라면 브랜치 하나 만들고, 에이전트에게 맡기고, 끝나면 브랜치 갈아타고... 를 세 번 반복했을 겁니다. codeme 에서는 이 셋을 나란히 둡니다. 1. 할 일마다 worktree, worktree 마다 에이전트 왼쪽 목록의 카드 하나가 worktree 하나입니다. feat/webhook-retry , fix/refund-limit , main ... 각자 자기 폴더와 자기 터미널을 가지고 있어서, 한쪽 에이전트가 파일을 고치는 동안 다른 쪽은 전혀 영향을 받지 않습니다. 브랜치를 갈아탈 일이 없습니다. 세 worktree 에서 각각 Claude Code 를 띄워 두고 다른 일을 했습니다. 돌아와서 보면 목록만 훑어도 상황이 보입니다. M2 · M1 U1 — 그 worktree 에서 수정된 파일 / 새 파일 수 ✧ 14k — 그 worktree 의 에이전트가 쓴 토큰 claude · 작업 중 / 완료 — 지금 돌고 있는지, 나를 기다리는지 카드를 누르면 그 worktree 로 넘어가고, 시작 화면에는 「하던 것 이어서」 가 뜹니다. 방금 에이전트에게 무엇을 시켰는지가 거기 남아 있어서, 한 번 누르면 그 대화로 돌아갑니다. 에이전트가 나를 기다리기 시작하면 다른 앱을 보고 있어도 알림이 옵니다. 창이 앞에 있으면 구석의 토스트로, 자리를 비웠으면 OS 알림으로. 그래서 셋을 띄워 놓고 정말로 다른 일을 할 수 있습니다. 2. 끝났으면, 무엇을 바꿨는지부터 에이전트가 「다 했습니다」라고 하면 가장 먼저 여는 것이 에이전트 변경 패널 ( ⌃⇧X )입니다. 위쪽에는 내가 무엇을 요청했고 에이전트가 무엇이라 답했는지 , 바로 아래에는 그래서 실제로 바뀐 코드 가 붙어 있습니다. 요청과 답변과 diff 를 따로 찾아다니지 않아도 됩니다. 이 패널에서 제일 중요한 건 기준점 입니다. diff 는 HEAD 가 아니라 에이전트가 시작한 순간 을 기준으로 계산합니다. 그래서 에이전트를 띄우기 전에 내가 손대 둔 편집은 여기에 섞이지 않습니다 — 보이는 것은 정확히 에이전트가 한 일뿐입니다. 다 읽었으면 「검토함으로 표시」로 기준점을 앞으로 옮기고, 에이전트에게 다음 일을 시키면 그다음 변경만 새로 쌓입니다. 이번 재시도 작업에서 에이전트는 이렇게 끝을 맺었습니다. 요청하신 대로 패키지 설치와 테스트 실행은 하지 않았습니다. 테스트는 아직 한 번도 돌려 보지 않았습니다. 정직한 답이고, 동시에 사람이 diff 를 읽어야 하는 이유 이기도 합니다. retryDelay 가 [0, min(60000, 1000·2^(n-1))] 범위의 full jitter 로 바뀌었고, 재귀 호출이 for 루프로 바뀌었고, deadLetter 콜백이 새로 생겼다는 것 — 이걸 확인하는 데 1분이면 충분했습니다. 한 줄 보기와 좌우 보기를 오갈 수 있고, 접힌 문맥은 펼쳐서 「이 세 줄이 어느 함수 안인지」까지 볼 수 있습니다. 3. 머지하기 전에, 흐름을 한 번 리뷰가 끝난 갈래를 합치기 전에 히스토리를 엽니다. 브랜치가 어디서 갈라져서 어디서 합쳐졌는지가 그래프로 보이고, 각 커밋 옆에는 어느 브랜치·worktree 가 그 커밋을 가리키는지 태그가 붙습니다. 커밋을 누르면 아래에 바뀐 파일과 diff 가 바로 열립니다. 위 화면은 fix(billing): round KRW/JPY without minor units 를 누른 상태 — git log --graph 와 git show 를 번갈아 치던 일이 클릭 한 번이 됐습니다. 여기서 커밋을 다른 worktree 로 복사 하거나 되돌리기 도 할 수 있습니다. 그리고 이 diff 는 2번의 에이전트 변경 패널과 같은 리더 로 그립니다. 어느 패널에서 보든 하이라이트·접기·좌우 보기가 똑같이 동작합니다. 4. 코드 옆에 데이터도 환불 로직을 고쳤으니 실제 데이터가 어떻게 생겼는지 봐야 합니다. 예전 같으면 DB 클라이언트를 켜고, 접속 정보를 다시 입력하고... 했을 겁니다. codeme 의 데이터베이스 패널은 프로젝트 폴더에서 DB 를 알아서 찾습니다. docker compose 의 컨테이너, .env 나 jdbc: URL, 저장소 안의 sqlite 파일까지. 이번에는 data/payments.db 를 찾아 바로 목록에 올려 줬습니다. 테이블을 누르면 행이 표로 나오고, WHERE 로 거르고, 행을 골라 그 자리에서 고치고 저장 합니다. 위 화면은 1003 번 청구서의 status 를 open → paid 로 바꾸는 중입니다 (「1개 변경」). 드라이버를 번들하지 않고 머신에 이미 있는 CLI( psql , mysql , sqlite3 , duckdb ...)를 씁니다. 그래서 앱은 가볍게 남고, 비밀번호는 값이 아니라 어디서 읽었는지(출처)만 저장합니다. 5. 서버를 띄웠다면, 포트까지 마지막으로 로컬에서 서버를 띄워 확인합니다. 그리고 늘 겪는 그 문제 — EADDRINUSE: address already in use :::3000 . 포트 패널은 이 머신에 열린 포트를 한 목록으로 보여 주는데, 이 프로젝트가 띄운 것부터 위에 올립니다. 어떤 명령으로 떴는지, 어느 폴더에서 떴는지도 함께 보입니다. 여기서 바로 열기 · 재시작 · 정지 . 정지는 신호만 보내고 끝나지 않습니다. 포트가 정말 풀릴 때까지 기다립니다. 그래야 다음 실행이 같은 에러로 죽지 않습니다. 그리고 그 서버를 띄웠던 명령을 프로젝트별로 기억해 두었다가, 재시작하면 터미널에 그대로 다시 타이핑해 줍니다. 정리 — 다섯 창이 아니라 한 창 돌아보면 오늘 한 일은: 단계 예전 codeme 할 일 셋 동시 진행 브랜치 갈아타기 × 3 worktree 셋을 나란히 에이전트 결과 확인 터미널 스크롤 + git diff 에이전트 변경 패널 (시작 시점 기준) 머지 전 흐름 확인 git log --graph , git show 히스토리 그래프 + 커밋 diff 데이터 확인·수정 별도 DB 클라이언트 데이터베이스 패널 서버·포트 정리 lsof -i :3000 , kill 포트 패널 지난 글에서 말했듯 codeme 는 IDE 를 대체하려는 앱이 아닙니다. LSP·디버거가 필요한 깊은 작업은 쓰던 IDE 에서 하고, 그 옆에 두고 worktree 를 만들고, 에이전트를 붙이고, 결과를 보는 흐름 을 여기서 끝내는 앱입니다. 그리고 이 모든 게 내 머신에서만 돕니다. 서버도, 계정도 없습니다. 다운로드: codeme.team/download (macOS, 서명·공증된 유니버설 DMG) 피드백: codeme.team/feedback
코드잇 데이터분석가 부트캠프를 통해 배우고 느낀 것을 적습니다. 강의/미션/위클리페이퍼/프로젝트로 나누어 작성합니다. 📅 2026.04.30 | 🗺️ 과정: 1개월차 ▓░░░░░░ | 📖 커리큘럼: Excel로 하는 데이터 분석 입학식을 마치고 엑셀 수업을 시작했다. 스프레드시트의 개념, 엑셀 화면과 표의 구조, 기본 기능 여섯 가지, 수식과 참조, 함수 다섯 종류까지 다루었다. 🗓️ 오늘의 일정 교시 시간 내용 1~3교시 09:00~12:00 입학식 (11시부터) 4~7교시 13:00~17:00 데이터 분석 오버뷰, Excel로 하는 데이터 분석 8~9교시 17:00~19:00 Excel로 하는 데이터 분석 오늘 수업의 학습 목차는 세 부분이다. 01 Excel이란, 02 Excel 기본, 03 Excel 실전. 오늘은 01과 02의 앞부분(엑셀 기초, 데이터 다루기)까지 진행했고, 나머지는 다음 수업에서 이어진다. 1️⃣ 엑셀이란 1-1. 엑셀과 스프레드시트 엑셀과 스프레드시트는 같은 말이 아니다. 스프레드시트는 프로그램의 종류를 가리키고, 엑셀은 그 종류에 속하는 하나의 제품 이름이다. 엑셀 Excel: Microsoft가 개발한 스프레드시트 프로그램 스프레드시트 Spreadsheet: 행과 열로 구성된 표 구조에서 데이터를 입력, 계산, 분석, 정리하는 프로그램 정의에서 핵심은 네 가지 동작이다. 입력, 계산, 분석, 정리. 스프레드시트는 표에 데이터를 적어 넣는 데서 끝나지 않고, 그 값을 수식으로 계산하고 분석하는 단계까지 한 화면에서 처리하는 도구이다. 이 점이 워드프로세서나 메모장과 다르다. 1-2. 엑셀과 구글 스프레드시트의 차이 같은 종류의 프로그램으로 구글 스프레드시트가 있다. 강의에서는 두 프로그램의 특징을 세 가지 관점으로 비교했다. 구분 엑셀 Microsoft Excel 구글 스프레드시트 Google Sheets 비용 데스크톱 버전은 유료 기반 기본적으로 무료 사용 가능 기능 고급 함수, 매크로 등 다양한 기능 제공 클라우드 기반 서비스 강점 대용량 데이터 처리와 연산 속도에 강점 실시간 공동 작업에 용이 정리하면 데이터의 크기가 크고 복잡한 계산이 필요하면 엑셀, 여러 사람이 같은 파일을 동시에 편집해야 하면 구글 스프레드시트가 적합하다. 두 프로그램은 함수 이름과 사용법이 대부분 겹치므로, 하나를 익히면 다른 하나로 옮겨 가기 쉽다. 1-3. 엑셀 사용 방법 강의에서는 엑셀을 사용하는 두 가지 방법을 안내했다. 데스크톱용 엑셀 설치: 1개월 무료 체험을 제공한다. 웹용 엑셀 사용: 설치 없이 브라우저에서 사용한다. 💭 엑셀과 구글 시트를 같은 프로그램으로 생각하고 있었다. 대용량 처리와 협업이라는 기준으로 나누어 보니 용도가 분명하게 갈렸다. 2️⃣ 엑셀 화면 구성 엑셀 화면은 처음 보면 복잡하지만, 분석에서 자주 쓰는 영역은 정해져 있다. 상단 기본 버튼 문서 제목, 저장, 실행 취소, 다시 실행이 화면 맨 위에 있다. 실행 취소는 직전 작업을 되돌리고, 다시 실행은 되돌린 작업을 다시 적용한다. 데이터를 다룰 때 실수를 바로 복구할 수 있으므로 가장 자주 쓰게 된다. 리본 메뉴 기능이 탭별로 모여 있는 영역이다. 홈 탭에는 글꼴, 맞춤, 표시 형식, 조건부 서식, 정렬 및 필터처럼 자주 쓰는 기능이 있고, 그 외 탭에는 삽입, 수식, 데이터, 보기 등이 있다. 원하는 기능이 어느 탭에 있는지 아는 것이 작업 속도를 좌우한다. 이름 상자 현재 선택한 셀의 주소를 표시한다. 열 문자와 행 번호를 합쳐 A1, B3 같은 형태로 나타낸다. 이름 상자에 주소를 직접 입력하면 해당 셀로 바로 이동한다. 수식 입력줄 선택한 셀에 입력된 수식이나 값을 확인하고 수정하는 곳이다. 셀에는 수식의 계산 결과만 보이기 때문에, 그 값이 어떻게 만들어졌는지는 수식 입력줄에서 확인해야 한다. 시트 화면 하단의 탭이다. 하나의 파일 안에 여러 개의 표를 시트별로 나누어 저장할 수 있다. 예를 들어 예약 정보와 고객 정보를 서로 다른 시트에 두고 필요할 때 연결해 쓰는 식이다. 셀 주소와 범위 셀의 위치는 열 문자와 행 번호로 표기한다. A열 1행의 셀은 A1이다. 여러 셀을 함께 가리킬 때는 콜론(:)을 사용해 범위로 표기한다. 표기 의미 A1 A열 1행의 셀 하나 A1:A5 A열 1행부터 5행까지의 세로 범위 A1:C1 1행의 A열부터 C열까지의 가로 범위 A1:C5 A1을 왼쪽 위, C5를 오른쪽 아래로 하는 사각형 범위 이 표기법은 뒤에서 다루는 수식과 함수에서 계속 사용된다. 3️⃣ 표의 구조 3-1. 기본 용어 테이블 Table: 데이터가 기록되어 있는 행과 열의 모음 행 Row: 가로 방향의 줄 하나하나. 하나의 개체에 대한 다양한 정보 열 Column: 세로 방향의 줄 하나하나. 특정 속성에 대한 정보 셀 Cell: 행과 열이 만나는 칸 하나하나. 정보를 저장하는 기본 단위 3-2. 직원 표로 보는 구조 강의에서는 직원 정보 표를 예시로 사용했다. 직원 이름 입사 일자 팀 직위 직책 나이 연봉 만원 김지훈 2005.3.15 영업팀 부장 팀장 48 12000 이민서 2018.7.1 영업팀 대리 30 4800 박혜진 2013.6.5 마케팅팀 과장 38 6700 이 표에서 한 행은 직원 한 명에 대한 정보 전체이다. 김지훈이라는 개체의 이름, 입사 일자, 팀, 직위, 직책, 나이, 연봉이 한 줄에 담긴다. 한 열은 모든 직원에 대해 같은 속성을 기록한다. 나이 열에는 세 명의 나이가, 연봉 열에는 세 명의 연봉이 들어 있다. 셀은 이 둘이 만나는 지점이므로, 김지훈의 나이는 김지훈 행과 나이 열이 만나는 셀에 있다. 3-3. 분석하기 좋은 표의 형태 데이터 분석에 쓰는 표는 다음 형태를 유지해야 이후의 필터, 정렬, 함수, 피벗 테이블이 오류 없이 동작한다. 첫 행에 열 이름(머리글)을 둔다. 한 행은 하나의 개체를 나타낸다. 한 열에는 한 가지 속성과 한 가지 타입의 값만 넣는다. 표 중간에 빈 행이나 빈 열을 두지 않는다. 셀 병합은 피한다. 병합된 셀은 정렬과 필터에서 문제를 일으킨다. 💡 표를 열면 한 행이 무엇을 의미하는지부터 확인해야 한다. 한 행이 사람인지, 주문인지, 예약인지에 따라 개수를 세는 방식과 집계 기준이 달라진다. 4️⃣ 엑셀 기초 엑셀 기초에서 다룬 항목은 여섯 가지이다. 데이터 정리, 셀 꾸미기, 데이터 타입, 필터와 정렬, 틀 고정, 조건부 서식. 4-1. 데이터 정리 데이터를 입력하고 다듬는 기본 작업이다. 열 너비 조절: 열 머리글의 경계선을 더블클릭하면 내용에 맞게 너비가 자동으로 조절된다. 행과 열의 삽입, 삭제: 표 구조를 바꿔야 할 때 사용한다. 자동 채우기: 셀 오른쪽 아래 모서리의 채우기 핸들을 끌면 값이나 수식이 인접 셀로 복사된다. 숫자나 날짜는 규칙에 따라 연속된 값으로 채워진다. 복사와 붙여넣기: 붙여넣기 옵션에 따라 값만, 서식만, 수식만 선택해서 붙여넣을 수 있다. 수식 결과를 고정된 값으로 바꿀 때는 값만 붙여넣기를 쓴다. 4-2. 셀 꾸미기 표를 읽기 쉽게 만드는 작업이다. 글꼴과 글자 크기, 굵기 채우기 색: 머리글 행에 색을 입혀 데이터 영역과 구분한다. 테두리: 표의 경계를 명확하게 한다. 맞춤: 가운데 맞춤, 왼쪽 맞춤 등 셀 안의 정렬 방향을 지정한다. 표시 형식: 값은 그대로 두고 화면에 보이는 모양만 바꾼다. 천 단위 구분 기호, 소수점 자리수, 날짜 형식이 여기에 속한다. 서식은 값 자체를 바꾸지 않는다. 표시 형식으로 소수점 한 자리만 보이게 해도 셀 안의 실제 값은 그대로 남아 있고, 수식은 실제 값으로 계산한다. 4-3. 데이터 타입 엑셀은 셀에 입력된 값을 타입으로 구분한다. 타입 설명 기본 정렬 숫자 계산이 가능한 값 오른쪽 텍스트 글자로 취급되는 값. 계산에 사용할 수 없다. 왼쪽 날짜 날짜로 인식된 값. 내부적으로는 일련번호로 저장되어 날짜끼리 계산할 수 있다. 오른쪽 논리값 TRUE 또는 FALSE 가운데 타입은 계산 결과를 좌우한다. 숫자처럼 보이는 값이 텍스트로 저장되어 있으면 합계나 평균 계산에서 빠지거나 오류가 발생한다. 날짜도 마찬가지로 텍스트로 입력되면 연도나 월을 추출하는 함수가 동작하지 않는다. 셀의 정렬 방향은 타입을 확인하는 단서가 된다. 숫자인데 왼쪽으로 정렬되어 있으면 텍스트로 저장된 것을 의심한다. 4-4. 필터와 정렬 정렬 값을 순서대로 배열하는 기능이다. 오름차순은 작은 값에서 큰 값 순서이고, 내림차순은 그 반대이다. 텍스트는 가나다순, 날짜는 과거에서 최근 순서로 정렬된다. 기준을 여러 개 지정하는 다중 정렬도 가능하다. 팀 기준으로 먼저 정렬하고, 같은 팀 안에서 연봉 순으로 정렬하는 식이다. 필터 조건에 맞는 행만 화면에 표시하는 기능이다. 조건에 맞지 않는 행은 삭제되는 것이 아니라 숨겨진다. 필터를 해제하면 원래 상태로 돌아온다. 열의 타입에 따라 텍스트 필터, 숫자 필터, 날짜 필터의 조건이 달라진다. 주의점 정렬할 때는 표 전체 범위가 선택되어 있어야 한다. 한 열만 선택하고 정렬하면 그 열의 값만 움직여 행 단위로 묶여 있던 정보가 어긋난다. 표 안의 셀 하나를 선택한 상태에서 정렬하면 엑셀이 표 전체를 자동으로 인식한다. 4-5. 틀 고정 행이나 열을 고정해서 스크롤해도 화면에 계속 보이게 하는 기능이다. 보기 탭에서 설정한다. 첫 행 고정: 머리글 행이 항상 화면 위에 남는다. 첫 열 고정: 첫 번째 열이 항상 화면 왼쪽에 남는다. 틀 고정: 선택한 셀의 위쪽 행과 왼쪽 열을 함께 고정한다. 행이 많은 표에서 아래로 스크롤하면 머리글이 화면 밖으로 나가 각 열이 무엇을 뜻하는지 알 수 없게 된다. 틀 고정은 이 문제를 해결한다. 4-6. 조건부 서식 셀의 값이 지정한 조건을 만족하면 서식을 자동으로 적용하는 기능이다. 값이 바뀌면 서식도 자동으로 따라 바뀐다. 셀 강조 규칙: 특정 값보다 크거나 작은 셀, 특정 텍스트를 포함하는 셀, 중복된 값을 색으로 강조한다. 상위와 하위 규칙: 상위 몇 개, 평균 이상 같은 조건으로 강조한다. 데이터 막대: 셀 안에 값의 크기에 비례하는 막대를 표시한다. 색조: 값의 크기에 따라 색의 농도를 다르게 한다. 아이콘 집합: 값의 구간에 따라 화살표나 신호등 같은 아이콘을 표시한다. 숫자를 하나씩 읽지 않아도 눈에 띄는 값의 위치를 바로 파악할 수 있다. 값의 크기 비교, 이상한 값 탐색에 유용하다. 💭 조건부 서식이 가장 실용적으로 느껴졌다. 숫자로만 채워진 표에서 색이 칠해진 셀만 보면 되니, 이상한 값을 찾는 시간이 크게 줄어들 것 같다. 5️⃣ 데이터 다루기 5-1. 수식 엑셀에서 계산은 등호(=)로 시작한다. 등호 뒤에 오는 내용을 엑셀은 수식으로 인식하고 계산한다. 산술 연산자 연산자 의미 예시 + 더하기 =A1+B1 - 빼기 =A1-B1 * 곱하기 =A1*B1 / 나누기 =A1/B1 ^ 거듭제곱 =A1^2 연산 순서는 수학과 같다. 곱하기와 나누기가 더하기와 빼기보다 먼저 계산되고, 괄호 안의 식이 가장 먼저 계산된다. 수식에는 값을 직접 입력하기보다 셀 주소를 사용한다. =3000+2000 처럼 값을 직접 넣으면 값이 바뀔 때 수식을 고쳐야 하지만, =B2+C2 처럼 셀 주소를 사용하면 B2나 C2의 값이 바뀔 때 결과가 자동으로 갱신된다. 5-2. 참조 수식에서 셀 주소를 가리키는 방식을 참조라 한다. 수식을 다른 셀로 복사할 때 주소가 어떻게 바뀌는지에 따라 세 가지로 나뉜다. 참조 방식 표기 복사할 때 상대 참조 B2 복사한 위치에 따라 주소가 함께 이동한다. 절대 참조 $B$2 어디로 복사해도 주소가 고정된다. 혼합 참조 $B2 또는 B$2 열만 고정하거나 행만 고정한다. =B2+C2 ' 상대 참조: 아래로 복사하면 B3+C3, B4+C4로 바뀜 =$B$2 ' 절대 참조: 어디로 복사해도 B2 셀만 계속 가리킴 =$B2 ' 혼합 참조: 열(B)은 고정, 행은 복사 위치에 따라 이동 =B$2 ' 혼합 참조: 행(2)은 고정, 열은 복사 위치에 따라 이동 $ 는 바로 뒤에 오는 열 문자나 행 번호를 고정하는 기호이다. 수식을 입력한 뒤 참조 전환 단축키를 누르면 상대, 절대, 혼합 참조가 차례로 바뀐다. 상대 참조는 같은 계산을 여러 행에 반복 적용할 때 유용하고, 절대 참조는 기준이 되는 값 하나를 여러 행에서 반복해서 참조할 때 필요하다. 예를 들어 환율이 B1 셀에 있고 여러 행의 금액에 환율을 곱해야 한다면 =A5*$B$1 처럼 환율 셀을 절대 참조로 고정해야 한다. 💡 절대 참조를 쓰지 않고 수식을 아래로 복사하면 기준 셀의 주소도 함께 밀려 내려가 엉뚱한 셀을 참조하게 된다. 기준값을 반복 참조할 때는 항상 $ 를 붙인다. 5-3. 함수 함수는 엑셀이 미리 만들어 둔 계산 도구이다. 수식을 직접 길게 쓰는 대신 함수 이름과 인수를 지정하면 결과가 계산된다. =함수명(인수1, 인수2, ...) 함수명 뒤에 괄호를 열고 인수를 쉼표로 구분해 입력한다. 인수에는 값, 셀 주소, 범위, 다른 함수가 들어갈 수 있다. 범위는 콜론으로 표기한다. I2:I4 는 I2부터 I4까지이다. 수업에서는 함수를 용도에 따라 다섯 종류로 분류했다. 집계 함수, 수학 함수, 순서 함수, 텍스트 함수, 날짜 및 시간 함수. 아래 예시는 앞에서 본 직원 표를 기준으로 하며, 표는 A열부터 이름, 입사 일자, 주소, 전화번호, 팀, 직위, 직책, 나이, 연봉 순서이다. 따라서 팀은 E열, 나이는 H열, 연봉은 I열이다. 집계 함수 여러 값을 하나의 값으로 요약한다. =SUM(I2:I4) ' 범위의 합계. 연봉 합계는 23500 =AVERAGE(H2:H4) ' 범위의 평균. 나이 평균은 약 38.7 =COUNT(H2:H4) ' 숫자가 들어 있는 셀의 개수. 결과는 3 =COUNTA(E2:E4) ' 비어 있지 않은 셀의 개수. 텍스트도 센다. 결과는 3 COUNT는 숫자만 세고 COUNTA는 값이 있는 셀을 모두 센다. 텍스트 열의 개수를 셀 때는 COUNTA를 사용해야 한다. 수학 함수 값을 계산하고 가공한다. =ROUND(AVERAGE(H2:H4), 1) ' 반올림. 평균 나이를 소수 첫째 자리까지, 결과는 38.7 =ROUNDUP(38.61, 0) ' 올림. 결과는 39 =ROUNDDOWN(38.61, 0) ' 내림. 결과는 38 =ABS(-4800) ' 절댓값. 결과는 4800 =INT(38.9) ' 소수점 아래를 버리고 정수만. 결과는 38 ROUND 계열의 두 번째 인수는 자릿수이다. 0이면 정수, 1이면 소수 첫째 자리, -1이면 일의 자리에서 반올림한다. 순서 함수 크기와 순위를 다룬다. =MAX(I2:I4) ' 최댓값. 가장 높은 연봉은 12000 =MIN(I2:I4) ' 최솟값. 가장 낮은 연봉은 4800 =LARGE(I2:I4, 2) ' 두 번째로 큰 값. 결과는 6700 =SMALL(I2:I4, 2) ' 두 번째로 작은 값. 결과는 6700 =RANK(I2, $I$2:$I$4) ' 순위. 김지훈의 연봉 순위는 1 RANK의 첫 번째 인수는 순위를 구할 값이고, 두 번째 인수는 비교 대상 범위이다. 수식을 아래 행으로 복사해서 모든 직원의 순위를 구하려면 비교 범위가 움직이면 안 되므로 $I$2:$I$4 처럼 절대 참조로 고정해야 한다. 앞에서 배운 절대 참조가 실제로 쓰이는 경우이다. 고정하지 않으면 복사할 때 범위가 함께 밀려 순위가 잘못 계산된다. 텍스트 함수 문자열을 추출하고 가공한다. =LEFT(E2, 2) ' 왼쪽에서 두 글자. "영업팀"에서 "영업" =RIGHT(E2, 1) ' 오른쪽에서 한 글자. "영업팀"에서 "팀" =MID(A2, 2, 1) ' 두 번째 글자부터 한 글자. "김지훈"에서 "지" =LEN(E2) ' 글자 수. "영업팀"은 3 =TRIM(E2) ' 앞뒤 불필요한 공백 제거 =A2&" "&F2 ' 문자열 연결. "김지훈 부장" 텍스트 함수는 이름과 직위를 합치거나 코드에서 앞 몇 글자를 떼어 구분값으로 쓰는 등 데이터를 정리할 때 자주 쓰인다. 날짜 및 시간 함수 날짜에서 필요한 요소를 꺼내거나 오늘 날짜를 사용한다. =TODAY() ' 오늘 날짜. 파일을 열 때마다 갱신된다 =NOW() ' 오늘 날짜와 현재 시각 =YEAR(B2) ' 연도 추출. 입사 연도 =MONTH(B2) ' 월 추출. 입사 월 =DAY(B2) ' 일 추출. 입사 일 =DATE(2026,4,30) ' 연, 월, 일을 조합해 날짜 생성 날짜 함수는 셀의 값이 날짜 타입일 때만 동작한다. 앞에서 정리한 데이터 타입 확인이 여기에서 필요해진다. 입사 일자가 텍스트로 저장되어 있으면 YEAR 함수는 오류를 반환한다. 5-4. 참고: 엑셀 단축키 수업 자료에는 단축키와 함수 치트시트가 참고 자료로 제공되었다. 데이터를 다룰 때 자주 쓰는 단축키를 정리하면 다음과 같다. 동작 Windows Mac 복사 Ctrl + C Command + C 붙여넣기 Ctrl + V Command + V 실행 취소 Ctrl + Z Command + Z 데이터 끝 셀로 이동 Ctrl + 방향키 Command + 방향키 필터 켜기와 끄기 Ctrl + Shift + L Command + Shift + F 참조 방식 전환 F4 Command + T 데이터 끝 셀로 이동하는 단축키는 빈 셀을 확인할 때도 쓴다. 열을 따라 이동하다가 예상보다 일찍 멈추면 그 지점에 빈 셀이 있다는 뜻이다. 💭 함수 이름이 많아서 처음에는 구분이 어려웠다. 그런데 집계, 수학, 순서, 텍스트, 날짜 및 시간으로 용도별로 묶어서 보니 정리가 되었다. 함수 전체를 외우기보다 용도로 분류해 두고, 필요할 때 찾아 쓰는 방식이 맞다고 판단했다. 💡 엑셀의 함수는 대부분 같은 구조를 따른다. 함수명, 괄호, 인수, 그리고 범위 표기가 동일하기 때문에, 하나의 함수를 정확히 익히면 나머지는 인수의 의미만 확인하면 된다. 📝 오늘의 정리 소목차 키워드 중요한 부분 1-1. 엑셀과 스프레드시트 스프레드시트, 엑셀, 입력, 계산, 분석, 정리 스프레드시트는 프로그램의 종류이고 엑셀은 그중 하나이다. 입력에서 그치지 않고 계산과 분석까지 처리한다. 1-2. 엑셀과 구글 스프레드시트의 차이 유료와 무료, 대용량 처리, 실시간 공동 작업 대용량 데이터와 고급 기능은 엑셀, 협업은 구글 스프레드시트가 유리하다. 1-3. 엑셀 사용 방법 데스크톱 설치, 웹용 엑셀 데스크톱은 1개월 무료 체험이 가능하고, 웹용은 설치 없이 브라우저에서 사용한다. 2. 엑셀 화면 구성 리본 메뉴, 이름 상자, 수식 입력줄, 시트 셀에는 결과만 표시되므로 값의 생성 과정은 수식 입력줄에서 확인한다. 2. 셀 주소와 범위 A1, 콜론, 범위 열 문자와 행 번호로 셀을 가리키고, 콜론으로 범위를 지정한다. 3-1. 기본 용어 테이블, 행, 열, 셀 행은 하나의 개체, 열은 하나의 속성이다. 3-2. 직원 표로 보는 구조 개체, 속성 표를 볼 때 한 행이 무엇을 뜻하는지부터 확인한다. 3-3. 분석하기 좋은 표의 형태 머리글, 빈 행, 병합 셀 첫 행에 머리글을 두고, 한 열에는 한 타입만 넣고, 빈 행과 병합 셀은 피한다. 4-1. 데이터 정리 자동 채우기, 값만 붙여넣기 수식 결과를 고정된 값으로 바꿀 때 값만 붙여넣기를 쓴다. 4-2. 셀 꾸미기 채우기 색, 테두리, 표시 형식 표시 형식은 화면 모양만 바꾸고 실제 값은 그대로이다. 4-3. 데이터 타입 숫자, 텍스트, 날짜, 논리값 타입에 따라 계산 가능 여부가 달라진다. 숫자가 왼쪽 정렬이면 텍스트로 저장된 것을 의심한다. 4-4. 필터와 정렬 오름차순, 내림차순, 다중 정렬 정렬은 표 전체가 선택된 상태에서 해야 행이 어긋나지 않는다. 필터는 삭제가 아니라 숨김이다. 4-5. 틀 고정 첫 행 고정, 첫 열 고정 스크롤해도 머리글이 화면에 남도록 고정한다. 4-6. 조건부 서식 셀 강조 규칙, 데이터 막대, 색조 조건에 맞는 셀에 서식이 자동 적용되어 눈에 띄는 값을 바로 찾을 수 있다. 5-1. 수식 등호, 연산자, 셀 주소 값을 직접 넣지 않고 셀 주소를 쓰면 원본이 바뀔 때 결과가 자동으로 갱신된다. 5-2. 참조 상대 참조, 절대 참조, 혼합 참조, $ 기준값을 여러 행에서 반복 참조할 때는 $로 주소를 고정한다. 5-3. 함수 집계, 수학, 순서, 텍스트, 날짜 및 시간 함수는 =함수명(인수) 구조이다. 용도별로 분류해 기억하고, 날짜 함수는 날짜 타입에서만 동작한다. 5-4. 단축키 데이터 끝 이동, 필터 전환, 참조 전환 데이터 끝으로 이동하는 단축키로 빈 셀의 위치를 확인할
백업은 "했다"가 중요한 게 아니라 "복구할 수 있다" 가 중요합니다. 이 글에서는 백업의 기본 개념부터 3-2-1 원칙, 랜섬웨어 시대의 백업 전략, 그리고 많은 조직이 놓치는 복구 테스트 까지 정리합니다. 1. 백업이 필요한 이유 서버 데이터가 사라지는 원인은 생각보다 다양합니다. ▶ 표 1. 데이터 손실의 주요 원인 원인 예시 하드웨어 장애 디스크 고장, 스토리지 장애 사람의 실수 실수로 파일·DB 삭제, 잘못된 설정 변경 소프트웨어 오류 패치 실패, 데이터 손상 악성 행위 랜섬웨어, 내부자의 고의 삭제 재해 화재, 침수, 정전, 지진 같은 서버 안에 이중화(RAID, 클러스터)가 있어도 삭제·손상·랜섬웨어는 그대로 복제 됩니다. 이중화는 백업을 대체하지 못합니다. 2. 헷갈리는 개념 구분: 백업 vs 복제 vs 스냅샷 vs RAID ▶ 표 2. 비슷해 보이지만 다른 기술들 기술 목적 실수로 삭제한 데이터 복구 랜섬웨어 대응 RAID 디스크 고장 대비 불가 불가 복제 (Replication) 다른 곳에 실시간·주기적 사본 유지 (DR, 이중화) 삭제도 복제되므로 어려움 감염도 복제될 수 있음 스냅샷 특정 시점 상태 보존 (같은 스토리지 내) 가능 (보관 기간 내) 스토리지 자체가 공격당하면 위험 백업 별도 저장소 에 시점별 사본 보관 가능 격리·불변 설정 시 가능 3. 핵심 지표: RPO와 RTO 백업 전략은 이 두 가지 질문에서 시작합니다. ▶ 그림 1. RPO와 RTO 마지막 백업 장애 발생 서비스 복구 │ │ │ ──────●─────────────────✕─────────────────────●──────▶ 시간 │◀───── RPO ─────▶│◀────── RTO ────────▶│ (얼마나 데이터를 (얼마나 오래 잃어도 되나?) 멈춰도 되나?) ▶ 표 3. RPO / RTO 정의 지표 질문 의미 예시 RPO (Recovery Point Objective) 데이터를 얼마 전 시점까지 복구해야 하나? 허용 가능한 데이터 손실 범위 RPO 24시간 → 하루 1회 백업이면 충족 RTO (Recovery Time Objective) 서비스를 얼마 안에 되살려야 하나? 허용 가능한 중단 시간 RTO 4시간 → 4시간 내 복구 가능해야 함 RPO와 RTO가 짧을수록 비용이 급격히 올라갑니다. 시스템 중요도별로 다르게 정해야 합니다. (모든 서버를 최고 등급으로 할 필요는 없어요) 4. 백업 방식: 전체 / 증분 / 차등 ▶ 그림 2. 세 가지 백업 방식 일 월 화 수 목 전체 ■ ■ ■ ■ ■ 매번 전부 백업 증분 ■ ▪ ▪ ▪ ▪ 직전 백업 이후 변경분만 차등 ■ ▪ ▪▪ ▪▪▪ ▪▪▪▪ 전체 백업 이후 누적 변경분 ■ = 전체 백업 ▪ = 변경된 데이터 ▶ 표 4. 방식별 비교 방식 설명 백업 속도 저장 용량 복구 전체 백업 모든 데이터를 통째로 느림 큼 가장 간단·빠름 증분 백업 직전 백업 이후 변경분만 빠름 작음 전체 + 모든 증분 필요, 복잡 차등 백업 마지막 전체 백업 이후 변경분 중간 중간 전체 + 최신 차등 1개면 가능 실무 패턴 예시 : 주 1회 전체 백업 + 매일 증분(또는 차등) 백업 5. 3-2-1 백업 원칙 가장 널리 알려진 백업 원칙입니다. 3 개의 사본을 만들고 2 가지 서로 다른 매체(저장소)에 보관하며 1 개는 물리적으로 떨어진 곳(오프사이트)에 둔다 ▶ 그림 3. 3-2-1 구성 예시 1 운영 데이터 (원본) ← 사본 1 │ ├──▶ 2 로컬 백업 (디스크/백업 장비) ← 사본 2 (매체 A) │ └──▶ 3 원격 백업 (다른 사이트 / 클라우드) ← 사본 3 (매체 B, 오프사이트) ▶ 표 5. 각 숫자가 막아주는 위험 숫자 막아주는 위험 3개 사본 하나가 손상되어도 다른 사본으로 복구 2개 매체 특정 저장 매체·기술의 결함이 동시에 영향을 주는 상황 방지 1개 오프사이트 화재·침수 등 사이트 전체 재해 대비 랜섬웨어 시대의 확장: 3-2-1-1-0 ▶ 표 6. 3-2-1-1-0 원칙 숫자 의미 3-2-1 기본 원칙과 동일 +1 사본 하나는 오프라인(에어갭)이거나 변경·삭제가 불가능한(Immutable) 상태로 보관 0 백업 검증 결과 오류 0건 (복구 가능성을 확인) 랜섬웨어는 백업 서버와 백업 파일까지 노려서 암호화·삭제 합니다. 그래서 공격자가 건드릴 수 없는 사본이 하나는 있어야 합니다. 6. 랜섬웨어 대응 백업 체크포인트 ▶ 표 7. 백업 시스템 보호 방법 대응 설명 불변 스토리지 (Immutable) 보관 기간 동안 수정·삭제가 불가능하도록 설정 (WORM 방식 등) 오프라인·에어갭 사본 네트워크와 분리된 매체 (예: 분리 보관되는 테이프·외장 저장소) 백업 망 분리 운영망과 백업망을 분리, 백업 서버 접근 IP 제한 계정 분리 백업 관리자 계정을 운영 서버·AD 계정과 분리, MFA 적용 최소 권한 백업 저장소 삭제 권한을 최소한의 인원에게만 백업 암호화 저장·전송 시 암호화, 암호 키 별도 보관 이상 징후 알림 백업 용량 급감·대량 삭제·백업 실패 알림 7. 무엇을 백업할까? (대상 선정) ▶ 표 8. 서버 백업 대상 예시 대상 내용 데이터 DB, 파일 서버 데이터, 업로드 파일 설정 서버 설정 파일, 애플리케이션 설정, 인증서 시스템 이미지 OS 포함 서버 전체 이미지 또는 VM 백업 디렉터리·인증 정보 AD, LDAP 등 계정·권한 데이터 스크립트·코드 운영 스크립트, 배포 자동화, IaC 코드 문서 구성도, 절차서 (복구할 때 꼭 필요!) 복구 문서와 암호 키도 백업 대상 입니다. 정작 복구할 때 절차서가 백업 서버 안에만 있으면 낭패입니다. DB 백업은 "그냥 파일 복사"가 아닙니다 DB는 운영 중에 데이터가 계속 바뀌므로 파일을 그냥 복사하면 일관성이 깨진 백업 이 될 수 있습니다. DB 전용 백업 도구나 일관성 있는 스냅샷 기능을 사용해야 합니다. 8. 보관 정책 (Retention) ▶ 표 9. 보관 정책 예시 (조직 정책에 맞게 조정) 주기 보관 예시 일간 백업 최근 7~14일 보관 주간 백업 최근 4~8주 보관 월간 백업 6~12개월 보관 연간 백업 법적·감사 요건에 따라 장기 보관 랜섬웨어 감염은 한참 뒤에 발견되기도 하므로, 너무 짧은 보관은 위험합니다. 감염 이전 시점의 사본이 남아 있어야 합니다. 법령·내부 규정의 보관 의무 기간 을 반드시 확인하세요. 개인정보가 포함된 백업은 파기 기준 도 함께 관리해야 합니다. 9. 복구 테스트: 백업의 진짜 완성 "테스트하지 않은 백업은 백업이 아니라 희망 사항이다." 백업 작업이 "성공"으로 표시되어도, 실제로 복구가 안 되는 경우가 있습니다. ▶ 표 10. 복구 실패의 흔한 원인 원인 설명 백업 파일 손상 저장 중 오류, 매체 결함 필요한 데이터 누락 백업 대상 지정 실수 암호·키 분실 암호화 백업의 키를 찾을 수 없음 절차 미숙 복구 순서, 의존 관계(예: AD 먼저)를 모름 호환성 문제 복구 환경과 버전 불일치 시간 초과 복구에 걸리는 시간이 RTO를 초과 복구 테스트 방법 ▶ 그림 4. 복구 테스트 흐름 1 테스트 대상 선정 (중요 시스템 우선) ↓ 2 격리된 테스트 환경에 복구 (운영 환경을 건드리지 않게!) ↓ 3 서비스 기동 및 데이터 정합성 확인 ↓ 4 걸린 시간 측정 → RTO와 비교 ↓ 5 문제점 기록, 절차서 보완 ↓ 6 정기적으로 반복 ▶ 표 11. 복구 테스트 수준 수준 내용 권장 주기(예시) 파일 단위 복구 임의 파일 1~2개를 골라 복구해 보기 월간 시스템 복구 VM·서버를 통째로 복구해 기동 확인 분기~반기 DR 훈련 장애 시나리오를 가정해 전체 절차 실행 연 1회 이상 10. 백업 운영 체크리스트 ▶ 표 12. 체크리스트 점검 항목 확인 시스템별 RPO/RTO가 정의되어 있는가? ☐ 3-2-1 원칙(사본 3, 매체 2, 오프사이트 1)을 만족하는가? ☐ 변경·삭제 불가 또는 오프라인 사본이 있는가? ☐ 백업 성공·실패를 매일 확인하고 알림을 받는가? ☐ 백업 서버와 저장소가 운영망과 분리되어 있는가? ☐ 백업 데이터가 암호화되어 있고, 키는 별도 보관되는가? ☐ 정기적으로 복구 테스트를 수행하고 시간을 기록하는가? ☐ 복구 절차서가 최신이고 백업 시스템 밖에도 있는가? ☐ 보관 기간이 법규·내부 정책에 맞는가? ☐ 백업 용량 증가 추세를 모니터링하는가? ☐ 11. 정리 ▶ 표 13. 핵심 키워드 요약 키워드 한 줄 요약 백업 ≠ RAID·복제 삭제·손상·랜섬웨어는 별도 백업만 막아줌 RPO / RTO 얼마나 잃어도 되나 / 얼마나 멈춰도 되나 전체·증분·차등 속도·용량·복구 편의성의 트레이드오프 3-2-1 사본 3개, 매체 2종, 오프사이트 1곳 3-2-1-1-0 + 불변/오프라인 사본 1개, + 검증 오류 0건 복구 테스트 백업의 진짜 완성, 정기적으로 반복 "백업은 보험이고, 복구 테스트는 그 보험금이 실제로 나오는지 확인하는 일이다." 시리즈 마무리 이번 글로 서버 인프라 시리즈의 기본 흐름을 정리했습니다. 서버란 무엇인가 (구성, 종류, 이중화, 운영) 가상화: 하이퍼바이저와 VM의 원리 서버 모니터링 백업 전략 다음에는 네트워크 기본(스위치, 라우터, VLAN) , Active Directory와 인증 인프라 같은 주제로 이어갈 수 있습니다. 읽어주셔서 감사합니다. 궁금한 점은 댓글로 남겨주세요! 🙌
막어는 막화장실 고유의 언어로, 그냥 들으면 한국어나 영어와 비슷하게 들릴 수 있지만 대부분 전혀 다른 의미를 가지고 있습니다. 그리고 막화장실 내에서 구역 별로 사투리도 존재하며, 특히 막화장실 위험구역 1번 라인에서의 사투리가 가장 한국어와 비슷합니다. 막화장실 위험구역 8번 라인 막터파크의 사투리가 가장 알아듣기 힘듭니다. 전설의 아담이 맨 처음 막화장실에 들어왔을때 이곳에서 거주했었기 때문에 아담이도 가끔 이 사투리를 사용합니다. 지금 현재 밝혀진 구역별 막어 사투리는 약 407만개 정도이고, 미확인 구역에는 훨씬 더 많은 사투리와 독창적인 언어가 있을 것으로 추정됩니다. 대부분 당당인들은 막어를 사용하지만 일부 당당인들은 당당어라는 특이한 언어로 말하기도 합니다. 전설의 탈북인은 막화장실의 가장 북쪽 미확인 구역에서 왔기 때문에 현재 전북(전설의 탈북인)이 말하는 것을 분석하여 연구중입니다.
10. 대기이벤트 대기 이벤트가 많이 잡혔다고 해서 무조건 병목이라고 보면 안 되는 이유? 대기 이벤트에는 실제 병목뿐 아니라, 할 일이 없어서 쉬거나 다음 요청을 기다리는 정상적인 Idle 대기도 포함되기 때문에 많이 잡혔다고 해서 무조건 병목은 아니다. ** 래치를 처음 못 잡았다고 해서 바로 Sleep으로 내려가는 건 아니다. 그 사이에 어떤 과정을 거치나?** 래치를 처음 못 잡으면 바로 Sleep하지 않고 먼저 Spin하면서 다시 획득을 시도한다. Spin 중에 잡으면 그대로 진행하고, 정해진 횟수만큼 Spin해도 못 잡으면 Sleep 상태로 내려가 대기한다. 11. Shared Pool Dictionary Cache랑 Library Cache 차이 Dictionary Cache = 테이블, 인덱스 같은 DB 메타정보/오브젝트 정보를 캐싱 Library Cache* = SQL과 하드 파싱 결과(실행계획 등) 를 캐싱해서 재사용
2026.3.20 에 작성한 글을 옮깁니다. ClickHouse JDBC 드라이버의 로드밸런싱은 기대한 대로 동작하지 않는다 TL;DR load_balancing_policy=roundRobin 을 걸어도 INSERT 는 첫 번째 노드로 쏠렸다. 로드밸런싱은 쿼리 단위가 아니라 커넥션 생성 시점 에만 동작한다. 커넥션 풀이 재사용되는 순간 분산은 멈춘다. failover 는 잘 되지만, 내렸던 노드를 복구해도 원래 노드로 자동 복귀하지 않는다. 앱 재기동이 필요하다. 실시간 균등 분산이 필요하면 HAProxy 같은 프록시 를 두는 게 맞다. 배치성 적재라면 JDBC 멀티호스트로도 충분하다. 1. 테스트 환경 항목 내용 ClickHouse 노드 ch-test-01 (192.168.0.11), ch-test-02 (192.168.0.12) ClickHouse Keeper ch-test-01 (192.168.0.11), ch-test-02 (192.168.0.12), ch-test-03 (192.168.0.13) JDBC 드라이버 com.clickhouse:clickhouse-jdbc:0.6.5 커넥션 풀 HikariCP jdbc:clickhouse://192.168.0.11:8123,192.168.0.12:8123/test_db ?load_balancing_policy=roundRobin &health_check_interval=2000 &failover=1 &check_all_nodes=true 배치 애플리케이션이 두 노드에 INSERT 를 분산하도록 구성한 뒤, 노드를 하나씩 내렸다 올리면서 동작을 관찰했다. 2. 기대한 결과 vs 실제 결과 문서만 보고 예상한 동작과 실제 동작이 꽤 달랐다. 두 정책을 각각 돌려봤다. 2.1 roundRobin 시나리오 기대 결과 실제 결과 앱 기동 시 01, 02 균등 INSERT ❌ 01번에만 INSERT 집중 01번 중지 시 failover 02번으로 자동 failover ✅ 02번으로 전환됨 01번 중지 중 트래픽 01번 시도하다 02번 폴백 01번을 계속 시도하다 02번 폴백 (01번 복구 전까지 에러 로그 계속 발생) 01번 복구 후 다시 01번으로 복귀 ❌ 02번에 계속 INSERT check_all_nodes=true 추가 균등 분산 분산은 되나 균등하지는 않음 2.2 firstAlive 시나리오 기대 결과 실제 결과 앱 기동 시 01번(첫 alive) 우선 사용 ✅ 01번으로 INSERT 01번 중지 시 failover 02번으로 자동 failover ✅ 02번으로 전환됨 01번 중지 중 트래픽 02번으로 100% 이동 01번을 계속 시도하다 02번 폴백 (01번 복구 전까지 에러 로그 계속 발생) 01번 복구 후 다시 01번으로 복귀 ❌ 02번에 계속 INSERT check_all_nodes=true 추가 01번 우선 사용 ✅ 01번 우선 사용 앱 재시작 후 01번으로 복귀 ✅ 01번으로 복귀됨 두 정책 모두 failover 는 되는데 fallback(원복)이 안 된다 는 점이 공통이다. 3. 발견된 이슈 이슈 1 roundRobin 로드밸런싱이 사실상 동작하지 않음 현상 : load_balancing_policy=roundRobin 을 걸었는데도 INSERT 가 항상 첫 번째 노드로 집중된다. 원인 : clickhouse-jdbc 0.6.x 의 client-v2 는 단일 타깃 호스트에만 연결하는 구조 로 설계되어 있어, 클라이언트 사이드 로드밸런싱이 실질적으로 동작하지 않는다. 추가 원인 : HikariCP 커넥션 풀 초기화 시 roundRobin 카운터의 race condition 때문에 대부분의 커넥션이 첫 번째 호스트로 생성된다. 그리고 가장 중요한 부분은 이거다. 커넥션 풀이 한번 만들어지면 → 계속 재사용 → 재사용 중에는 roundRobin 이 동작하지 않음 → 같은 노드로만 감 새 커넥션 생성 시점에만 → 01, 02 번갈아 배정 결론 : roundRobin 은 커넥션 생성 시점 에만 동작한다. 한번 생성된 커넥션은 재사용되므로 쿼리 레벨의 분산은 불가능 하다. 이슈 2 failover 후 원래 노드로 복귀하지 않음 현상 : 01번 노드를 내리면 02번으로 failover 는 정상 동작하는데, 01번을 복구해도 계속 02번으로만 INSERT 된다. 원인 : firstAlive , roundRobin 두 정책 모두 마지막으로 성공한 노드를 유지 하는 방식이라, 복구된 노드로 자동 복귀하지 않는다. 즉 노드 한 대에 잠깐 문제가 생기면, 그 뒤로는 앱을 재기동하기 전까지 트래픽이 한쪽으로 몰린 채 유지된다. 4. 임시 조치와 그 한계 check_all_nodes=true 를 추가하면 양쪽 노드에 INSERT 가 들어가는 것은 확인된다. jdbc:clickhouse://192.168.0.11:8123,192.168.0.12:8123/test_db ?load_balancing_policy=roundRobin &health_check_interval=2000 &failover=1 &check_all_nodes=true 다만 균등 분산까지는 아니다. 커넥션이 언제 생성되느냐에 따라 비율이 달라지는 한계는 그대로 남는다. 5. 정리 — JDBC 드라이버의 구조적 한계 항목 내용 로드밸런싱 단위 쿼리(요청)가 아닌 커넥션 생성 시점 기준 자동 복귀 failover 후 원래 노드로 자동 복귀 불가 (앱 재기동 필요) 균등 분산 커넥션 풀 재사용 구조상 쿼리 레벨 균등 분산 불가 드라이버 방향성 공식 이슈에서도 클라이언트 사이드 로드밸런싱보다 프록시 사용을 권장 이건 설정을 잘못한 문제가 아니라 커넥션 풀 + 클라이언트 사이드 LB 조합의 구조적 특성 에 가깝다. 커넥션을 오래 들고 쓰는 게 풀의 존재 이유인데, 로드밸런싱은 커넥션을 새로 만들 때만 개입하니 둘이 정면으로 어긋난다. 6. 권장 아키텍처 실시간 트래픽을 받는 서비스 Application → HAProxy → ClickHouse ch-test-01 → ClickHouse ch-test-02 HAProxy 가 쿼리 레벨에서 균등 분산과 자동 복귀를 처리한다. 노드 중지/복구와 무관하게 라우팅이 안정적으로 유지된다. 배치 / 조회용 데이터 적재 Batch Application → JDBC (멀티호스트) → ClickHouse ch-test-01 → ClickHouse ch-test-02 실시간 균등 분산이 필수가 아닌 배치성 INSERT/SELECT 라면 JDBC 만으로도 충분하다. failover=1 , check_all_nodes=true 조합으로 단일 노드 중지 시 자동 전환은 보장된다. 7. 테스트 결과에 따른 판단 배치를 통한 조회용 데이터 적재 구조라면, 실시간 균등 분산보다 안정적인 적재 가 우선이므로 JDBC 멀티호스트 구성으로도 문제가 없다는 판단이다. 다만 아래 세 가지는 팀 전체가 인지한 상태로 써야 한다. JDBC 로드밸런싱은 완전한 균등 분산을 보장하지 않는다. failover 후 수동 개입(앱 재시작) 없이는 원래 노드로 복귀하지 않는다. 실시간 트래픽을 받는 구성으로 바꾼다면 HAProxy 도입이 필요하다. 그래서 최종적으로는 분산 흉내를 내는 roundRobin 보다, 동작이 예측 가능한 firstAlive 쪽을 택했다. 어차피 균등 분산이 안 될 거라면 어느 노드를 쓰는지 명확한 편 이 운영하기 낫다는 이유다. jdbc:clickhouse://192.168.0.11:8123,192.168.0.12:8123/test_db ?load_balancing_policy=firstAlive &health_check_interval=5000 &failover=1 &check_all_nodes=true 본 글은 개인 테스트 환경(ClickHouse 2노드 + Keeper 3노드)에서 직접 재현·확인한 내용을 정리한 것입니다.
기준일: 2026-09-30 이 문서는 수강생이 수업 전에 준비할 프로그램과 장비별 설치 순서를 정리한다. 명령은 코드 블록에 명시한 운영체제에서 실행한다. 설치 완료와 로봇·시뮬레이터 연동 완료는 별도로 확인한다. 설치 대상 한눈에 보기 설치 위치 프로그램 구분 사용 목적 / 완료 기준 Windows 11 RTX PC NVIDIA 그래픽 드라이버 필수 선택한 Isaac Sim 릴리스 요구사항을 충족하고 nvidia-smi 가 GPU를 표시한다. Windows 11 RTX PC Isaac Sim 6.1.0 설치 후보 Compatibility Checker와 headless 시작을 확인한다. Lyrical 연동은 별도 검증 대상이다. Windows PC OpenSSH Server 원격 실행 시 필수 Ubuntu에서 공개키 인증으로 접속하고 서버 키를 확인한다. Linux 노트북 Ubuntu 24.04 + ROS 2 Lyrical Desktop 필수 Lyrical 환경에서 talker/listener 송수신을 확인한다. Linux 노트북 Git, curl, 빌드 도구, ros-dev-tools 필수 소스 관리, 패키지 설치 및 ROS 작업공간 빌드에 사용한다. Linux 노트북 Python 3, venv, NumPy, OpenCV 필수 좌표 계산·RGB-D 처리에 사용한다. Linux 노트북 imageio, imageio-ffmpeg, FFmpeg 필수 실제 시뮬레이션 프레임을 H.264 MP4로 저장한다. Linux 노트북 OpenSSH Client 필수 Windows 시뮬레이션 PC에 접속한다. Linux GPU 장비 PyTorch / CUDA 런타임 GPU 확장 선택한 PyTorch 배포와 드라이버의 호환성을 확인한다. 지원되는 Linux GPU 장비 Docker, NVIDIA Container Toolkit, Isaac ROS GPU 확장 해당 Isaac ROS 릴리스의 OS·ROS·CUDA 지원 조합을 따른다. 개발 PC VS Code 등 편집기 선택 Python·ROS 코드를 편집한다. 개발 PC Codex, Claude CLI 선택 구현·검토 자동화에 사용한다. 계정과 사용 권한이 필요하다. PhysX, Replicator, Isaac Sim Camera API, USD 관련 기능은 Isaac Sim에 포함된 구성 요소를 사용한다. 별도로 임의 버전의 패키지를 설치하지 않는다. JSON, hashlib(SHA-256), unittest.mock은 Python 표준 라이브러리이므로 pip 설치 대상이 아니다. 환경 주의: Lyrical용 Ubuntu 26.04 환경과 Isaac ROS의 지원 환경을 동일하다고 가정하지 않는다. Isaac Sim 버전 상승만으로 Lyrical ROS Bridge 호환성이 보장되지는 않는다. 이 문서는 설치 절차이며, 실제 장비에서 설치·연동이 완료되었다는 결과 보고서가 아니다. 권장 설치 순서 장비의 OS·GPU·디스크 여유 공간을 확인한다. Windows에 지원 드라이버와 Isaac Sim을 설치하고 로컬 headless 시작을 확인한다. Ubuntu에 ROS 2 Lyrical과 개발 도구를 설치하고 로컬 메시지 송수신을 확인한다. 아래의 Python 관측·영상 처리 환경을 설치한다. SSH 공개키 인증과 서버 키 확인을 구성한다. 원격 실행과 ROS 메시지 연결을 분리하여 검증한다. 기본 경로가 동작한 후 GPU 확장 도구를 설치한다. Python·영상 처리 도구 설치 — Ubuntu 터미널 ROS·Isaac Sim 본체 설치는 아래의 장비별 상세 절차를 따른다. 다음 명령은 Ubuntu 관측·데이터 처리 환경을 준비한다. sudo apt update sudo apt install -y git curl build-essential python3-venv python3-pip \ ffmpeg openssh-client mkdir -p "$HOME/pa-course" cd "$HOME/pa-course" python3 -m venv .venv source .venv/bin/activate python -m pip install --upgrade pip python -m pip install numpy opencv-python-headless imageio imageio-ffmpeg python -m pip freeze > requirements.lock.txt GUI 없이 영상 처리가 가능하도록 opencv-python-headless 를 사용한다. 같은 가상환경에 opencv-python 과 중복 설치하지 않는다. 화면을 띄우는 cv2.imshow() 대신 이미지 파일 또는 MP4로 결과를 확인한다. source "$HOME/pa-course/.venv/bin/activate" python - <<'PY' import cv2 import numpy as np import imageio.v2 as imageio import imageio_ffmpeg import hashlib, json from pathlib import Path out = Path.home() / 'pa-course' / 'install-check' out.mkdir(parents=True, exist_ok=True) frame = np.zeros((240, 320, 3), dtype=np.uint8) frame[80:160, 100:220] = (0, 0, 255) # RGB의 파랑 video = out / 'video_check.mp4' with imageio.get_writer(str(video), fps=10, codec='libx264') as writer: for _ in range(10): writer.append_data(frame) assert video.stat().st_size > 0 print('OpenCV:', cv2.__version__) print('NumPy:', np.__version__) print('FFmpeg:', imageio_ffmpeg.get_ffmpeg_exe()) print('MP4:', video) print('SHA-256:', hashlib.sha256(video.read_bytes()).hexdigest()) print('PYTHON_VIDEO_INSTALL_OK') PY ffmpeg -version 위 영상은 설치 확인용 합성 영상이다. 프로젝트 성과 영상으로 제출하지 않는다. 실제 성과 영상은 Isaac Sim의 관측 프레임으로 생성한다. Python 실행 환경 구분 일반 데이터 처리: ~/pa-course/.venv/bin/python 을 사용한다. ROS 노드: ROS 패키지를 설치한 시스템 Python 환경을 기본으로 사용한다. 위 독립 가상환경에서 rclpy 가 자동으로 사용 가능하다고 가정하지 않는다. Isaac Sim 스크립트: Windows 설치 폴더의 python.bat 를 사용한다. 시스템 Python으로 Isaac Sim 모듈을 임의 실행하지 않는다. CUDA·PyTorch: 별도 GPU 환경을 사용한다. Isaac Sim에 포함된 PyTorch·NumPy를 임의로 업그레이드하지 않는다. GPU 확장 도구 설치 기준 PyTorch 공식 설치 선택기 에서 Linux·Pip·Python과 장비 드라이버에 맞는 CUDA 배포를 선택한다. 선택기에 표시되는 명령을 전용 가상환경에서 실행하고 해당 명령과 버전을 기록한다. CPU 설치 결과를 GPU 설치 성공으로 판정하지 않는다. python3 -m venv "$HOME/pa-course/.venv-gpu" source "$HOME/pa-course/.venv-gpu/bin/activate" python -m pip install --upgrade pip # 이 위치에서 공식 선택기가 제시한 PyTorch 설치 명령을 실행한다. # 설치 후 확인: python -c "import torch; print(torch.__version__, torch.version.cuda); assert torch.cuda.is_available(), 'CUDA unavailable'; print(torch.cuda.get_device_name(0))" python -m pip freeze > "$HOME/pa-course/requirements-gpu.lock.txt" PyTorch 바이너리 사용만을 위해 CUDA Toolkit 전체 설치가 항상 필요한 것은 아니다. CUDA 소스 빌드가 필요한 단계에서 해당 버전의 Toolkit을 추가한다. nvidia-smi 의 CUDA 표시는 드라이버가 지원하는 CUDA 수준이며 설치된 Toolkit 버전과 동일한 의미가 아니다. Isaac ROS Isaac ROS 공식 시작 가이드 의 선택 릴리스 요구사항을 먼저 확인한다. 지원 OS·GPU·드라이버를 확인한 뒤 공식 순서대로 Docker, NVIDIA Container Toolkit, 개발 컨테이너와 이미지 처리 패키지를 준비한다. 현재 수업의 Ubuntu 26.04 + Lyrical 조합에 맞춘 설치 명령으로 임의 치환하지 않는다. 지원 조합이 다르면 별도 Linux GPU 환경을 사용한다. 설치 기록에는 릴리스·컨테이너 태그·ROS 배포판을 남긴다. 완료 기준은 컨테이너 실행뿐 아니라 실제 Resize 노드의 입력·출력 영상과 CameraInfo 확인까지이다. 장비별 상세 설치 및 연결 절차 아래 절차는 기존 설치·실행 가이드와 같은 기준으로 정리한 내용이다. 확인일: 2026-09-30. 이 문서는 수강생이 환경을 준비하고 단계별 결과를 확인하기 위한 가이드다. 명령은 해당 장비에서 실행하며, 문서 작성 과정에서 장비 설치나 로봇 실행을 수행한 것은 아니다. 1. 환경 구성과 지원 범위 장비 구성 역할 Windows 지원되는 RTX GPU·드라이버, Isaac Sim PhysX·로봇 장면·RGB-D 생성·headless 실행 Linux 노트북 Ubuntu 26.04, ROS 2 Lyrical 관측 처리·기구학·작업 시퀀스·상태 통신 Linux GPU 환경 선택한 Isaac ROS 릴리스의 지원 조합 GPU Resize 노드 검증 공식 다운로드 페이지는 Isaac Sim 6.1.0 을 제공한다. 설치 설명의 예시는 이 배포본을 기준으로 한다. 그러나 같은 버전의 ROS 설치 안내는 Humble·Jazzy를 공식 시험 대상으로 제시하며, Windows에서는 Jazzy/Pixi 경로를 안내한다. 6.1.0 설치 성공과 Lyrical 원격 연동 성공은 별개의 검증 항목 이다. Lyrical 직접 연결 또는 별도 어댑터는 실제 메시지·시각·QoS 시험을 통과한 뒤 수업 실행 경로로 채택한다. 미검증 어댑터를 이미 구현된 기능처럼 취급하지 않는다. Lyrical의 Ubuntu 바이너리 대상은 26.04다. Ubuntu 22.04나 24.04에 이 명령을 그대로 적용하지 않는다. 기존 OS를 임의로 업그레이드하는 절차는 이 가이드에 포함하지 않는다. 2. Windows에 Isaac Sim 설치 2.1 배포본과 장비 확인 공식 요구사항 에서 해당 릴리스의 GPU·VRAM·메모리·Windows·드라이버 지원을 확인한다. 다운로드 페이지 의 Windows standalone 배포본을 내려받는다. 파일명·버전·게시된 체크섬을 기록한다. ZIP과 압축 해제 파일을 위한 디스크 공간을 확보한다. Quick Install은 최소 50GB 여유 공간을 안내하며, 장면·에피소드·영상 저장 공간은 별도로 필요하다. GPU 상태를 nvidia-smi 로 확인한다. 장치가 표시된다는 사실만으로 렌더링 호환성이 검증되지는 않는다. 2.2 압축 해제와 설치 후 처리 아래는 Windows PowerShell 명령이다. 다운로드 파일명이 다른 경우 실제 파일명으로 바꾼다. 기존 설치 폴더에 다른 버전을 덮어쓰지 않도록 버전별 폴더를 사용한다. $simRoot = 'C:\isaacsim-6.1.0' $simZip = Join-Path $env:USERPROFILE 'Downloads\isaac-sim-standalone-6.1.0-windows-x86_64.zip' Test-Path $simZip Get-FileHash -LiteralPath $simZip -Algorithm MD5 New-Item -ItemType Directory -Path $simRoot tar -xf $simZip -C $simRoot Set-Location $simRoot .\post_install.bat .\isaac-sim.compatibility_check.bat Test-Path 가 False이면 다운로드 위치부터 수정한다. 게시된 MD5와의 비교는 배포본 전송 오류 확인에 사용한다. 출처 확인은 공식 HTTPS 다운로드 경로를 기준으로 한다. 호환성 검사에서 실패한 항목은 실행 전에 해결한다. 라이선스 확인이 표시되는 경우 내용을 읽고 설치 사용자가 직접 판단한다. 2.3 GUI 없는 최소 실행 다음 파일을 C:\pa-course\headless_check.py 로 저장한다. 폴더가 없다면 먼저 생성한다. from isaacsim import SimulationApp app = SimulationApp({'headless': True}) try: for _ in range(10): app.update() print('HEADLESS_STARTUP_OK') finally: app.close() Set-Location C:\isaacsim-6.1.0 .\python.bat C:\pa-course\headless_check.py 이 시험은 프로세스 초기화·업데이트·종료만 확인한다. 카메라 출력·물리 집기·ROS 연동을 검증하지 않는다. app.update() 를 순수 렌더 호출로 가정하지 않는다. 실제 수업에서는 명시적인 물리 step과 센서 수집 시점을 사용한다. GUI 화면이 필요한 진단에서만 .\isaac-sim.bat 를 사용한다. OT의 GUI 이미지는 NVIDIA 문서의 참고 화면이며 수업의 주 실행 방식은 headless다. 3. Ubuntu 26.04에 ROS 2 Lyrical 설치 3.1 OS·locale·저장소 준비 아래는 Linux Bash 명령이다. 먼저 /etc/os-release 에서 Ubuntu 26.04인지 확인한다. cat /etc/os-release locale sudo apt update sudo apt install locales software-properties-common curl sudo locale-gen en_US en_US.UTF-8 sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 export LANG=en_US.UTF-8 sudo add-apt-repository universe 다음은 공식 ros2-apt-source 패키지를 사용하는 저장소 설정이다. 이미 UTF-8 locale과 저장소가 정상적으로 설정된 환경에서는 중복 설정 여부를 확인한다. ROS_APT_SOURCE_VERSION=$(curl -fsSL https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | awk -F '"' '/tag_name/ {print $4; exit}') test -n "$ROS_APT_SOURCE_VERSION" || { echo 'release version lookup failed'; exit 1; } ROS_UBUNTU_CODE=$(. /etc/os-release; echo "${UBUNTU_CODENAME:-${VERSION_CODENAME}}") curl -fL -o /tmp/ros2-apt-source.deb "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.${ROS_UBUNTU_CODE}_all.deb" sudo dpkg -i /tmp/ros2-apt-source.deb curl이 실패한 경우 다음 설치 명령으로 진행하지 않고 네트워크와 파일을 확인한다. 사용한 ros2-apt-source 버전은 환경 기록에 남긴다. 3.2 패키지 설치와 로컬 통신 시험 sudo apt update sudo apt upgrade sudo apt install ros-lyrical-desktop ros-dev-tools source /opt/ros/lyrical/setup.bash printenv ROS_DISTRO ros2 doctor --report 서로 다른 두 터미널에서 다음 명령을 실행한다. 각 터미널에서 source 를 수행한다. # 터미널 A source /opt/ros/lyrical/setup.bash ros2 run demo_nodes_cpp talker # 터미널 B source /opt/ros/lyrical/setup.bash ros2 run demo_nodes_py listener listener에 증가하는 메시지가 수신되면 로컬 ROS 통신의 최소 시험을 통과한 것이다. 원격 Windows나 Isaac Sim 연동 성공을 의미하지 않는다. 종료는 각 터미널에서 Ctrl+C를 사용한다. 4. SSH 원격 실행 Windows OpenSSH Server의 설치·sshd 실행·수업 네트워크 허용 범위를 먼저 준비한다. Microsoft 공식 서버 가이드 와 키 인증 가이드 를 따른다. 일반 사용자와 Administrators 그룹 사용자의 authorized_keys 경로가 다르므로 계정 유형을 확인한다. Linux에서 전용 키를 생성하고 공개키만 Windows 계정의 올바른 authorized_keys 파일에 등록한다. 기존 키가 있으면 덮어쓰지 않는다. ssh-keygen -t ed25519 -f ~/.ssh/pa_sim_ed25519 서버 키 지문을 관리자가 전달한 신뢰 가능한 값과 대조한 뒤 known_hosts 에 등록한다. ssh-keyscan 으로 받은 값만 믿고 서버를 신뢰하지 않는다. 이후 ~/.ssh/config 의 별칭을 사용한다. 다음 HOST_ADDRESS와 WINDOWS_ACCOUNT는 실제 값으로 바꾸어야 한다. Host pa-sim HostName HOST_ADDRESS User WINDOWS_ACCOUNT IdentityFile ~/.ssh/pa_sim_ed25519 IdentitiesOnly yes StrictHostKeyChecking yes ssh pa-sim hostname ssh pa-sim 'C:\isaacsim-6.1.0\python.bat C:\pa-course\headless_check.py' 첫 명령으로 의도한 서버인지 확인하고, 두 번째 명령으로 원격 실행을 시험한다. 인용 방식은 서버의 기본 셸에 따라 달라질 수 있으므로 경로에 공백이 없는 수업 폴더를 사용한다. 비밀키·암호·토큰을 저장소에 올리지 않는다. 5. ROS 연동의 검증 순서 Lyrical의 로컬 talker/listener 통신을 확인한다. Isaac Sim의 공식 지원 ROS 환경에서 브리지 자체를 확인한다. 두 장비의 주소·방화벽·RMW·ROS_DOMAIN_ID·발견 설정·QoS를 확인한다. 방화벽을 통째로 끄는 방법을 사용하지 않는다. Lyrical 직접 연결을 시험하거나 명시적인 어댑터를 구현한다. 지원표에 없는 배포판 간 연결은 시험 결과로만 판단한다. 제어 명령을 허용하기 전에 /clock , 관절 상태, RGB·Depth·CameraInfo·TF의 값·시각·단위·frame을 확인한다. ros2 node list ros2 topic list -t ros2 topic info /clock --verbose ros2 topic echo /clock --once /clock 은 시뮬레이터가 해당 토픽을 발행하도록 구성된 경우에만 확인할 수 있다. 이미지·관절·제어 토픽 이름은 실제 노드 설정을 사용하며 이 가이드에서 존재하지 않는 토픽을 임의로 가정하지 않는다. 각 노드의 use_sim_time 설정을 일관되게 맞춘다. SSH 연결만으로 DDS가 터널링되지는 않는다. 6. 전체 워크플로우 환경 확인 → 버전 고정 → 로컬 최소 시험 → 원격 통신 시험 ↓ URDF/USD 로드 → 질량·관절·충돌·좌표 확인 → 물
1. 전체 탐색 공간의 분할 (Partitioning) 길이가 $n$인 배열 $A$에서 만들 수 있는 연속 부분 배열의 개수는 총 $\frac{n(n+1)}{2}$개입니다. 이 전체 부분 배열들의 집합을 "어느 인덱스에서 끝나는가?"를 기준으로 $n$개의 서로소 부분집합(Disjoint Sets)으로 나눕니다. $S_0$: 인덱스 $0$에서 끝나는 부분 배열들의 집합 $S_1$: 인덱스 $1$에서 끝나는 부분 배열들의 집합 $\dots$ $S_j$: 인덱스 $j$에서 끝나는 부분 배열들의 집합 ($0 \le j < n$) 모든 연속 부분 배열은 반드시 $0$부터 $n-1$ 중 단 하나의 끝점 을 가지므로, 전체 부분 배열 중 최대합(전역 최적해)은 각 집합의 최댓값들 중 가장 큰 값과 같습니다. $$\text{Global Max} = \max_{0 \le j < n} \Big( \max(S_j) \Big)$$ 2. 점화식의 수학적 유도 (최적 부분 구조) 이제 문제를 "$j$번째 원소로 끝나는 부분 배열 중 최대합 $M[j]$를 어떻게 구할 것인가?"로 좁힐 수 있습니다. 수학적으로 $M[j]$는 다음과 같이 정의됩니다. $$M[j] = \max_{0 \le i \le j} \sum_{k=i}^j A[k]$$ 이 식에서 시작 인덱스 $i$의 경우의 수를 $i = j$인 경우(원소 1개짜리)와 $i < j$인 경우(길이가 2 이상인 경우)로 분리합니다. $$M[j] = \max \left( A[j],; \max_{0 \le i \le j-1} \left( \sum_{k=i}^{j-1} A[k] + A[j] \right) \right)$$ 여기서 $A[j]$는 $i$와 무관한 공통 덧셈 상수이므로 밖으로 묶어낼 수 있습니다. $$M[j] = \max \left( A[j],; \left( \max_{0 \le i \le j-1} \sum_{k=i}^{j-1} A[k] \right) + A[j] \right)$$ 괄호 안의 $\max_{0 \le i \le j-1} \sum_{k=i}^{j-1} A[k]$는 정확히 이전 단계의 정의인 $M[j-1]$입니다. 따라서 다음과 같은 전형적인 동적 계획법의 점화식이 도출됩니다. $$M[j] = \max(A[j],; M[j-1] + A[j])$$ 식을 $A[j]$를 기준으로 정리하면 더욱 직관적인 형태가 됩니다. $$M[j] = A[j] + \max(0,; M[j-1])$$ $M[j-1] > 0$이면 : 이전 누적합을 붙이는 것이 이득이므로 $M[j-1] + A[j]$ 선택 $M[j-1] \le 0$이면 : 이전까지의 최적합이 음수이므로, 이전 기록을 버리고 $A[j]$ 단독으로 새로 시작하는 것이 무조건 이득 3. 메모리 최적화 ($O(N) \to O(1)$ 공간) 점화식 $M[j] = \max(A[j], M[j-1] + A[j])$를 보면, $M[j]$를 계산할 때 필요한 이전 값은 오직 직전 값인 $M[j-1]$ 하나뿐 입니다. $M[j-2], M[j-3]$ 등 그 이전의 값들은 알 필요가 없습니다. 따라서 $N$ 크기의 배열 $M[\ ]$을 메모리에 유지할 필요 없이, 단 하나의 변수( currentSum )만 계속 덮어쓰면서 갱신하면 충분하므로 공간 복잡도가 $O(1)$이 됩니다.