<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>taeyul_de.log</title>
        <link>https://velog.io/</link>
        <description>이래서 되겠나 싶은 개발지망생</description>
        <lastBuildDate>Tue, 25 Mar 2025 04:50:23 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>taeyul_de.log</title>
            <url>https://velog.velcdn.com/images/taeyul_de/profile/78e101cc-86d5-4d99-9462-10257c84e7d8/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. taeyul_de.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/taeyul_de" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[전송 계층 - TCP/UDP]]></title>
            <link>https://velog.io/@taeyul_de/%EC%A0%84%EC%86%A1-%EA%B3%84%EC%B8%B5-TCPUDP</link>
            <guid>https://velog.io/@taeyul_de/%EC%A0%84%EC%86%A1-%EA%B3%84%EC%B8%B5-TCPUDP</guid>
            <pubDate>Tue, 25 Mar 2025 04:50:23 GMT</pubDate>
            <description><![CDATA[<p>✅ 1. 전송 계층이란?</p>
<p><strong>전송 계층(OSI 7계층의 4계층)</strong>은 말 그대로 데이터를 전송하는 계층이다.
바로 아래의 <strong>네트워크 계층(IP)</strong>이 주소를 따라 어디까지 갈지를 결정한다면,
전송 계층은 그 안에서 “어떤 앱이 데이터를 보냈고, 어떻게 보낼지”를 책임진다.</p>
<p>📌 쉽게 말하면:</p>
<p>IP가 집 주소라면, TCP/UDP는 편지의 내용과 주고받는 방식이다.</p>
<hr>
<p>✅ 2. TCP와 UDP란?</p>
<p>구분    TCP    UDP
이름    Transmission Control Protocol    User Datagram Protocol
목적    신뢰성 있는 전송    빠른 전송
연결 방식    연결 지향(Connection-oriented)    비연결형(Connectionless)
특징    순서 보장, 손실 복구, 흐름 제어, 혼잡 제어    순서 보장 안 됨, 손실 복구 안 됨
사용 예시    웹브라우저(HTTP), 이메일, 파일 전송    게임, 영상 스트리밍, 음성 통화</p>
<p>⸻</p>
<p>✅ 3. TCP (Transmission Control Protocol)</p>
<p>📌 핵심 개념</p>
<p><strong>“신뢰성 있는 통신”</strong>을 위한 프로토콜.
데이터가 순서대로 도착하고, 손실 없이 정확하게 전달되도록 보장해줌.</p>
<hr>
<p>⚙️ 동작 방식: 3-Way Handshake</p>
<p>Client ------&gt; Server : SYN (접속 요청)
Client &lt;------ Server : SYN-ACK (승인 + 응답)
Client ------&gt; Server : ACK (응답 확인)</p>
<p>📦 연결 완료!</p>
<p>💡 이걸 3-Way Handshake라고 한다. 연결 전에 서로 약속을 맺는 절차라고 보면 된다.</p>
<hr>
<p>📌 데이터 전송
    •    데이터를 작은 세그먼트(Segment) 단위로 쪼개서 보냄.
    •    각각의 세그먼트에는 <strong>순서 번호(Sequence Number)</strong>가 붙음.
    •    수신 측은 <strong>ACK(응답)</strong>을 보내서 잘 받았는지 확인함.
    •    도중에 패킷이 유실되면 자동으로 재전송함.
    •    수신 속도가 느리면 흐름 제어로 속도를 조절함.</p>
<hr>
<p>⚙️ 연결 종료: 4-Way Handshake</p>
<p>Client ------&gt; Server : FIN (나 그만할래)
Client &lt;------ Server : ACK
Client &lt;------ Server : FIN (나도 이제 그만)
Client ------&gt; Server : ACK</p>
<p>📦 연결 종료!</p>
<hr>
<p>✅ TCP의 장점
    •    순서 보장
    •    신뢰성 (오류 감지, 재전송)
    •    흐름 제어 (수신 속도에 맞춰 보냄)
    •    혼잡 제어 (네트워크 상태에 따라 속도 조절)</p>
<p>❌ 단점
    •    속도 느림
    •    오버헤드(검사, 제어 기능 많음)
    •    실시간성이 필요한 서비스엔 부적합</p>
<hr>
<p>✅ TCP를 사용하는 사례</p>
<p>서비스    설명
HTTP/HTTPS    웹 페이지 요청/응답
FTP    파일 업로드/다운로드
SMTP/IMAP/POP3    이메일 송수신
SSH    원격 접속</p>
<hr>
<p>✅ 4. UDP (User Datagram Protocol)</p>
<p>📌 핵심 개념</p>
<p><strong>“속도가 중요한 통신”</strong>을 위한 프로토콜.
신뢰성은 낮지만 빠르게 전송됨.
연결 없이 그냥 던지고 마는 느낌이라 <strong>“비연결형 프로토콜”</strong>이라고 부른다.</p>
<hr>
<p>⚙️ 동작 방식
    •    HandShake 없음 → 연결 X
    •    <strong>데이터그램(datagram)</strong>이라는 단위로 바로 전송
    •    순서 보장 X
    •    응답(ACK) 없음
    •    재전송 없음</p>
<hr>
<p>✅ UDP의 장점
    •    빠름 (지연 없음)
    •    오버헤드 적음 (검사 기능 최소화)
    •    실시간에 적합</p>
<p>❌ 단점
    •    순서 바뀔 수 있음
    •    중간에 유실돼도 모름
    •    재전송도 없음</p>
<hr>
<p>✅ UDP를 사용하는 사례</p>
<p>서비스    설명
온라인 게임    반응 속도가 가장 중요!
유튜브/넷플릭스    영상은 중간에 조금 끊겨도 됨
VoIP (음성 통화)    실시간 통화에서 속도가 중요
DNS 요청    단순한 요청–응답 처리</p>
<hr>
<p>✅ 5. TCP와 UDP 구조 비교</p>
<p>🔸 TCP 헤더 구조 (복잡함)</p>
<p>| Source Port | Destination Port |
| Sequence Number |
| Acknowledgment Number |
| Flags (SYN, ACK, FIN 등) |
| Window Size |
| Checksum |
| Data |</p>
<p>🔸 UDP 헤더 구조 (간단함)</p>
<p>| Source Port | Destination Port |
| Length | Checksum |
| Data |</p>
<hr>
<p>✅ 6. 둘 중 뭐를 써야 할까?</p>
<p>상황    TCP    UDP
데이터 정확성이 중요함    ✅    ❌
속도가 가장 중요함    ❌    ✅
순서대로 받아야 함    ✅    ❌
네트워크 상태가 불안정함    ✅    ❌
대용량 파일 전송    ✅    ❌
게임, 스트리밍, 통화    ❌    ✅</p>
<hr>
<p>💡 비유로 정리하면</p>
<p>비유    TCP    UDP
택배    📦 택배 회사: 배송 추적, 도착 확인, 정확    🛵 배달 오토바이: 빠르지만 잃어버릴 수도 있음
문자 메시지    카톡: 읽음 확인, 순서 보장    알림톡: 빠르지만 순서, 응답 없음</p>
<hr>
<p>✅ 최종 요약</p>
<p>항목    TCP    UDP
연결 방식    연결 지향    비연결형
신뢰성    O (재전송, 순서 보장)    X (빠르게 던지고 끝)
속도    느림    빠름
오버헤드    큼    작음
사용처    웹, 이메일, 파일    게임, 영상, 음성</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[네트워크 계층 - IP]]></title>
            <link>https://velog.io/@taeyul_de/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B3%84%EC%B8%B5-IP</link>
            <guid>https://velog.io/@taeyul_de/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B3%84%EC%B8%B5-IP</guid>
            <pubDate>Tue, 25 Mar 2025 04:45:45 GMT</pubDate>
            <description><![CDATA[<p><strong>🌍 네트워크 계층(Network Layer) - IP(Internet Protocol)</strong></p>
<p><strong>네트워크 계층(Network Layer, 3계층)</strong>은 데이터를 목적지까지 <strong>올바른 경로(Routing)를 통해 전달</strong>하는 역할을 한다.</p>
<p>이 계층에서 가장 중요한 프로토콜이 바로 <strong>IP(Internet Protocol)</strong>이다.</p>
<hr>
<p><strong>1️⃣ 네트워크 계층의 역할</strong></p>
<p>네트워크 계층의 핵심 역할은 크게 두 가지다.</p>
<p><strong>✅ 1. 논리적 주소 지정 (Logical Addressing)</strong></p>
<p>• <strong>각 장치에 고유한 주소(IP 주소)를 할당하여 통신할 수 있도록 함.</strong></p>
<p>• 물리적인 위치(예: MAC 주소)와 달리, <strong>IP 주소는 네트워크 상황에 따라 변경 가능</strong>.</p>
<p>• 패킷을 목적지까지 정확하게 전달하는 역할.</p>
<p><strong>✅ 2. 라우팅(Routing)</strong></p>
<p>• 패킷이 출발지에서 목적지까지 가는 최적의 경로를 찾음.</p>
<p>• <strong>라우터(Router)</strong>가 경로를 결정하고 패킷을 전달함.</p>
<hr>
<p><strong>2️⃣ IP (Internet Protocol)</strong></p>
<p>IP는 <strong>인터넷에서 장치 간 데이터를 전달하는 핵심 프로토콜</strong>이다.</p>
<p><strong>✅ IP의 주요 기능</strong></p>
<p>• 데이터를 <strong>패킷(Packet) 단위로 나누어 전송</strong>.</p>
<p>• 목적지의 IP 주소를 보고 <strong>최적의 경로를 찾아 이동</strong>.</p>
<p>• 장치 간 <strong>논리적 주소 할당(IP 주소)</strong>을 담당.</p>
<p><strong>✅ IP의 특징</strong></p>
<p>• <strong>비연결형(Connectionless)</strong> → 데이터가 목적지에 도착할지 보장하지 않음.</p>
<p>• <strong>신뢰성 없음(Unreliable)</strong> → 패킷이 중간에 유실될 수도 있음.</p>
<p>• <strong>최선형 전달(Best-effort Delivery)</strong> → 오류 검출이나 재전송 기능이 없음.</p>
<p>(💡 신뢰성 있는 데이터 전송을 위해 <strong>TCP(전송 계층)</strong>과 함께 사용됨!)</p>
<hr>
<p><strong>3️⃣ IP 주소 (IP Address)</strong></p>
<p>IP 주소는 <strong>네트워크에서 장치를 식별하는 고유한 주소</strong>다.</p>
<p>현재 사용되는 IP 주소 체계는 <strong>IPv4</strong>와 <strong>IPv6</strong> 두 가지가 있음.</p>
<p><strong>✅ IPv4 (Internet Protocol version 4)</strong></p>
<p>• <strong>32비트 주소 체계</strong> (예: 192.168.1.1)</p>
<p>• 약 <strong>43억 개</strong>의 주소 제공 (부족 문제 발생)</p>
<p>• <strong>10진수 점(.)으로 구분된 4개 옥텟(Octet)</strong></p>
<p>• 예: 192.168.0.1</p>
<p><strong>IPv4 주소 체계 (A~E 클래스)</strong></p>
<table>
<thead>
<tr>
<th><strong>클래스</strong></th>
<th><strong>시작 주소 범위</strong></th>
<th><strong>사용 예</strong></th>
</tr>
</thead>
<tbody><tr>
<td>A</td>
<td>1.0.0.0 ~ 126.255.255.255</td>
<td>대형 네트워크 (기업, 기관)</td>
</tr>
<tr>
<td>B</td>
<td>128.0.0.0 ~ 191.255.255.255</td>
<td>중간 규모 네트워크</td>
</tr>
<tr>
<td>C</td>
<td>192.0.0.0 ~ 223.255.255.255</td>
<td>소규모 네트워크 (일반 가정, 회사)</td>
</tr>
<tr>
<td>D</td>
<td>224.0.0.0 ~ 239.255.255.255</td>
<td>멀티캐스트 (특정 그룹 전송)</td>
</tr>
<tr>
<td>E</td>
<td>240.0.0.0 ~ 255.255.255.255</td>
<td>실험용 (미사용)</td>
</tr>
</tbody></table>
<p><strong>✅ IPv6 (Internet Protocol version 6)</strong></p>
<p>• <strong>128비트 주소 체계</strong> (예: 2001:db8::ff00:42:8329)</p>
<p>• 주소 공간이 <strong>무한에 가깝게 많음</strong></p>
<p>• <strong>16진수(:)로 구분된 8개 그룹</strong></p>
<p>• 예: 2001:0db8:85a3:0000:0000:8a2e:0370:7334</p>
<p>💡 IPv4 주소 부족 문제를 해결하기 위해 등장했으며, 현재 점점 IPv6로 전환 중.</p>
<hr>
<p><strong>4️⃣ 공인 IP vs 사설 IP</strong></p>
<p>IP 주소는 크게 <strong>공인 IP</strong>와 <strong>사설 IP</strong>로 나뉜다.</p>
<p><strong>✅ 공인 IP (Public IP)</strong></p>
<p>• 인터넷에 직접 연결되는 IP 주소.</p>
<p>• 전 세계에서 유일하게 배정됨.</p>
<p>• ISP(인터넷 서비스 제공 업체)에서 제공.</p>
<p><strong>✅ 사설 IP (Private IP)</strong></p>
<p>• 내부 네트워크에서만 사용되는 IP 주소.</p>
<p>• 인터넷과 직접 연결되지 않으며 <strong>NAT(Network Address Translation)</strong>를 통해 공인 IP로 변환.</p>
<p>• IPv4에서 <strong>주소 부족 문제를 해결하기 위해 사용</strong>됨.</p>
<p><strong>사설 IP 주소 범위:</strong></p>
<table>
<thead>
<tr>
<th><strong>클래스</strong></th>
<th><strong>주소 범위</strong></th>
</tr>
</thead>
<tbody><tr>
<td>A</td>
<td>10.0.0.0 ~ 10.255.255.255</td>
</tr>
<tr>
<td>B</td>
<td>172.16.0.0 ~ 172.31.255.255</td>
</tr>
<tr>
<td>C</td>
<td>192.168.0.0 ~ 192.168.255.255</td>
</tr>
</tbody></table>
<p>(💡 우리가 <strong>Wi-Fi에 연결된 기기</strong>들은 일반적으로 <strong>사설 IP</strong>를 사용함.)</p>
<hr>
<p><strong>5️⃣ IP 패킷 구조</strong></p>
<p>IP는 데이터를 <strong>패킷(Packet)</strong> 단위로 나누어 전송한다.</p>
<p>IP 패킷은 크게 <strong>헤더(Header)와 페이로드(Payload)</strong>로 구성된다.</p>
<p><strong>✅ IP 패킷의 구조</strong></p>
<table>
<thead>
<tr>
<th><strong>필드</strong></th>
<th><strong>설명</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>버전(Version)</strong></td>
<td>IPv4(4) 또는 IPv6(6)</td>
</tr>
<tr>
<td><strong>헤더 길이(Header Length)</strong></td>
<td>헤더 크기</td>
</tr>
<tr>
<td><strong>서비스 유형(Type of Service)</strong></td>
<td>패킷 우선순위</td>
</tr>
<tr>
<td><strong>전체 길이(Total Length)</strong></td>
<td>전체 패킷 크기</td>
</tr>
<tr>
<td><strong>식별자(Identification)</strong></td>
<td>패킷을 구별하는 ID</td>
</tr>
<tr>
<td><strong>플래그(Flags)</strong></td>
<td>패킷 분할 여부</td>
</tr>
<tr>
<td><strong>TTL(Time To Live)</strong></td>
<td>패킷이 이동할 수 있는 최대 홉(Hop) 수</td>
</tr>
<tr>
<td><strong>프로토콜(Protocol)</strong></td>
<td>상위 계층 프로토콜 (TCP, UDP 등)</td>
</tr>
<tr>
<td><strong>헤더 체크섬(Header Checksum)</strong></td>
<td>오류 검출</td>
</tr>
<tr>
<td><strong>출발지 IP(Source IP Address)</strong></td>
<td>송신자의 IP 주소</td>
</tr>
<tr>
<td><strong>목적지 IP(Destination IP Address)</strong></td>
<td>수신자의 IP 주소</td>
</tr>
<tr>
<td><strong>데이터(Payload)</strong></td>
<td>실제 데이터</td>
</tr>
</tbody></table>
<p>(💡 <strong>TTL(Time To Live)</strong>: 패킷이 네트워크를 몇 번 통과할 수 있는지 제한하는 값. 0이 되면 폐기됨.)</p>
<hr>
<p><strong>6️⃣ IP와 함께 사용하는 프로토콜</strong></p>
<p>IP는 혼자서는 신뢰성 있는 통신을 보장하지 않기 때문에, 다음 프로토콜들과 함께 사용된다.</p>
<table>
<thead>
<tr>
<th><strong>프로토콜</strong></th>
<th><strong>역할</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>ICMP (Internet Control Message Protocol)</strong></td>
<td>네트워크 오류 메시지 전달 (예: ping 명령어)</td>
</tr>
<tr>
<td><strong>ARP (Address Resolution Protocol)</strong></td>
<td>IP 주소 ↔ MAC 주소 변환</td>
</tr>
<tr>
<td><strong>RARP (Reverse ARP)</strong></td>
<td>MAC 주소 → IP 주소 변환</td>
</tr>
<tr>
<td><strong>NAT (Network Address Translation)</strong></td>
<td>사설 IP ↔ 공인 IP 변환</td>
</tr>
<tr>
<td><strong>DHCP (Dynamic Host Configuration Protocol)</strong></td>
<td>동적으로 IP 주소 할당</td>
</tr>
</tbody></table>
<hr>
<p><strong>💡 정리</strong></p>
<p>✅ <strong>네트워크 계층은 데이터가 최적의 경로로 목적지까지 도달하도록 관리</strong></p>
<p>✅ <strong>IP(Internet Protocol)</strong>은 네트워크에서 데이터를 패킷으로 분할해 전달하는 핵심 프로토콜</p>
<p>✅ <strong>IPv4(32비트) vs IPv6(128비트)</strong> → IPv6는 주소 부족 문제 해결</p>
<p>✅ <strong>공인 IP vs 사설 IP</strong> → 사설 IP는 NAT를 통해 인터넷 연결</p>
<p>✅ <strong>IP 패킷 구조</strong> → TTL, 출발지 IP, 목적지 IP 등의 정보 포함</p>
<p>✅ <strong>ICMP, ARP, NAT, DHCP 같은 보조 프로토콜과 함께 사용됨</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[물리 계층과 데이터 링크 계층]]></title>
            <link>https://velog.io/@taeyul_de/%EB%AC%BC%EB%A6%AC-%EA%B3%84%EC%B8%B5%EA%B3%BC-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%A7%81%ED%81%AC-%EA%B3%84%EC%B8%B5</link>
            <guid>https://velog.io/@taeyul_de/%EB%AC%BC%EB%A6%AC-%EA%B3%84%EC%B8%B5%EA%B3%BC-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%A7%81%ED%81%AC-%EA%B3%84%EC%B8%B5</guid>
            <pubDate>Tue, 25 Mar 2025 04:35:55 GMT</pubDate>
            <description><![CDATA[<p><strong>📌 물리 계층(Physical Layer)과 데이터 링크 계층(Data Link Layer)</strong></p>
<p>네트워크의 기본 구조를 이해하려면 <strong>OSI 7계층 모델</strong>을 알아야 하는데, 그중에서도 <strong>1계층(물리 계층)과 2계층(데이터 링크 계층)</strong>은 네트워크의 <strong>하드웨어적 요소</strong>와 관련이 깊다</p>
<hr>
<p><strong>1️⃣ 물리 계층 (Physical Layer)</strong></p>
<blockquote>
<p>네트워크에서 데이터를 전기 신호, 빛 신호, 무선 신호 등의 형태로 변환하여 <strong>전송하는 역할</strong>을 함.</p>
</blockquote>
<p><strong>✅ 주요 기능</strong></p>
<p>• 데이터를 <strong>0과 1(비트, Bit)</strong> 형태로 변환하여 전송</p>
<p>• <strong>전송 매체(케이블, 광섬유, 전파 등)를 통해 데이터 이동</strong></p>
<p>• <strong>전송 속도, 신호의 세기, 전압 수준, 주파수, 변조 방식 등 정의</strong></p>
<p>• 네트워크 장비 간 <strong>물리적 연결(플러그, 커넥터, 케이블 등) 담당</strong></p>
<p><strong>✅ 대표적인 장비 &amp; 기술</strong></p>
<table>
<thead>
<tr>
<th><strong>장비/기술</strong></th>
<th><strong>역할</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>허브(Hub)</strong></td>
<td>데이터를 연결된 모든 장치에 전달 (브로드캐스트 방식)</td>
</tr>
<tr>
<td><strong>리피터(Repeater)</strong></td>
<td>신호를 증폭하여 먼 거리까지 전달</td>
</tr>
<tr>
<td><strong>모뎀(Modem)</strong></td>
<td>아날로그 ↔ 디지털 신호 변환</td>
</tr>
<tr>
<td><strong>광섬유(Fiber Optic)</strong></td>
<td>빛을 이용한 초고속 데이터 전송</td>
</tr>
<tr>
<td><strong>이더넷 케이블(Ethernet Cable)</strong></td>
<td>유선 네트워크에서 데이터 전송</td>
</tr>
<tr>
<td><strong>Wi-Fi, Bluetooth</strong></td>
<td>무선 네트워크 기술</td>
</tr>
</tbody></table>
<p><strong>✅ 데이터 전송 방식</strong></p>
<p>• <strong>단방향(Simplex)</strong>: 한 방향으로만 데이터 전송 (TV 방송, 라디오)</p>
<p>• <strong>반이중(Half-duplex)</strong>: 양방향 전송 가능하지만 한 번에 한 방향만 가능 (무전기)</p>
<p>• <strong>전이중(Full-duplex)</strong>: 양방향 동시 전송 가능 (전화 통화)</p>
<hr>
<p><strong>2️⃣ 데이터 링크 계층 (Data Link Layer)</strong></p>
<blockquote>
<p>물리 계층을 통해 전송된 데이터를 <strong>오류 없이 안정적으로 전달</strong>하는 역할을 함.</p>
</blockquote>
<blockquote>
<p>네트워크에서 <strong>MAC 주소를 이용해 장치 간 데이터 전송을 제어</strong>하고, 충돌을 방지함.</p>
</blockquote>
<p><strong>✅ 주요 기능</strong></p>
<p>• <strong>프레임(Frame) 단위로 데이터 전송</strong></p>
<p>• <strong>MAC 주소를 이용한 장치 식별</strong></p>
<p>• <strong>오류 감지 및 재전송 기능</strong></p>
<p>• <strong>흐름 제어(Flow Control)</strong>: 송신 속도가 너무 빠르면 조절</p>
<p>• <strong>충돌 방지(Collision Handling)</strong></p>
<p>• 네트워크를 <strong>논리적 링크(LAN, VLAN)로 분할</strong>하는 역할</p>
<p><strong>✅ 대표적인 장비 &amp; 기술</strong></p>
<table>
<thead>
<tr>
<th><strong>장비/기술</strong></th>
<th><strong>역할</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>스위치(Switch)</strong></td>
<td>MAC 주소를 기반으로 데이터 전송</td>
</tr>
<tr>
<td><strong>브리지(Bridge)</strong></td>
<td>LAN을 분할하여 트래픽 제어</td>
</tr>
<tr>
<td><strong>MAC 주소(MAC Address)</strong></td>
<td>네트워크 인터페이스 카드(NIC)에 부여된 고유 주소</td>
</tr>
<tr>
<td><strong>ARP(Address Resolution Protocol)</strong></td>
<td>IP 주소 ↔ MAC 주소 변환</td>
</tr>
<tr>
<td><strong>CSMA/CD (유선), CSMA/CA (무선)</strong></td>
<td>충돌 감지/회피 방식</td>
</tr>
</tbody></table>
<p><strong>✅ 데이터 링크 계층의 하위 계층</strong></p>
<p>데이터 링크 계층은 <strong>두 개의 하위 계층</strong>으로 나뉨.</p>
<table>
<thead>
<tr>
<th><strong>하위 계층</strong></th>
<th><strong>역할</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>MAC (Media Access Control) 계층</strong></td>
<td>장치 간 <strong>데이터 전송 제어</strong> 및 <strong>충돌 방지</strong></td>
</tr>
<tr>
<td><strong>LLC (Logical Link Control) 계층</strong></td>
<td>흐름 제어 및 오류 감지</td>
</tr>
</tbody></table>
<p><strong>✅ MAC 주소 vs IP 주소</strong></p>
<table>
<thead>
<tr>
<th><strong>구분</strong></th>
<th><strong>MAC 주소</strong></th>
<th><strong>IP 주소</strong></th>
</tr>
</thead>
<tbody><tr>
<td>역할</td>
<td>장치의 물리적 식별자</td>
<td>네트워크에서 위치 식별</td>
</tr>
<tr>
<td>형태</td>
<td>48비트 (예: 00:1A:2B:3C:4D:5E)</td>
<td>IPv4 (32비트), IPv6 (128비트)</td>
</tr>
<tr>
<td>변경 여부</td>
<td>하드웨어에 고정됨 (변경 불가)</td>
<td>네트워크에 따라 변경 가능</td>
</tr>
<tr>
<td>사용 계층</td>
<td>데이터 링크 계층</td>
<td>네트워크 계층</td>
</tr>
</tbody></table>
<hr>
<p><strong>3️⃣ 물리 계층과 데이터 링크 계층 비교</strong></p>
<table>
<thead>
<tr>
<th><strong>구분</strong></th>
<th><strong>물리 계층 (1계층)</strong></th>
<th><strong>데이터 링크 계층 (2계층)</strong></th>
</tr>
</thead>
<tbody><tr>
<td>역할</td>
<td>신호를 변환하여 전송</td>
<td>신호를 데이터로 변환하여 안정적으로 전달</td>
</tr>
<tr>
<td>데이터 단위</td>
<td>비트(Bit)</td>
<td>프레임(Frame)</td>
</tr>
<tr>
<td>주요 장비</td>
<td>허브, 리피터, 모뎀, 케이블</td>
<td>스위치, 브리지, NIC</td>
</tr>
<tr>
<td>주요 기술</td>
<td>전압, 주파수, 광섬유, 무선</td>
<td>MAC 주소, CSMA/CD, ARP</td>
</tr>
<tr>
<td>주요 기능</td>
<td>0과 1의 신호를 주고받음</td>
<td>오류 감지, MAC 주소 기반 데이터 전송</td>
</tr>
</tbody></table>
<hr>
<p><strong>💡 정리</strong></p>
<p>✅ <strong>물리 계층(1계층)</strong>: 데이터를 신호로 변환하여 전송하는 역할</p>
<p>✅ <strong>데이터 링크 계층(2계층)</strong>: MAC 주소를 이용하여 신뢰성 있게 데이터 전송</p>
<p>✅ <strong>물리 계층</strong>은 <strong>비트(Bit) 단위</strong>, <strong>데이터 링크 계층</strong>은 <strong>프레임(Frame) 단위</strong>로 데이터 처리</p>
<p>✅ <strong>물리 계층의 장비</strong>: 허브, 리피터, 모뎀, 케이블</p>
<p>✅ <strong>데이터 링크 계층의 장비</strong>: 스위치, 브리지, 네트워크 인터페이스 카드(NIC)</p>
<p>✅ <strong>MAC 주소 vs IP 주소</strong>: MAC 주소는 하드웨어 고유 주소, IP 주소는 네트워크에서 변경 가능</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[네트워크의 큰 그림]]></title>
            <link>https://velog.io/@taeyul_de/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC%EC%9D%98-%ED%81%B0-%EA%B7%B8%EB%A6%BC</link>
            <guid>https://velog.io/@taeyul_de/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC%EC%9D%98-%ED%81%B0-%EA%B7%B8%EB%A6%BC</guid>
            <pubDate>Tue, 25 Mar 2025 04:34:49 GMT</pubDate>
            <description><![CDATA[<p>네트워크의 기본 구조</p>
<p>네트워크는 노드와 간선으로 이루어진 자료구조라는 점에서 그래프의 형태를 띈다고 할수있다.</p>
<p>네트워크 기기 - 노드 
랜선 or WIFI - 간선 </p>
<p>네트워크의 기본 구조는 데이터를 송수신하는 기기들과 이를 연결하는 방식으로 구성된다. 크게 보면 네트워크는 <strong>노드(Node)</strong>, <strong>링크(Link)</strong>, <strong>프로토콜(Protocol)</strong> 로 이루어진다.</p>
<hr>
<p><strong>네트워크의 기본 구성 요소</strong></p>
<p><strong>🔹 노드(Node)</strong></p>
<p>네트워크에서 데이터를 주고받는 모든 장치를 노드라고 한다.</p>
<p>예를 들어:</p>
<p>• <strong>호스트(Host)</strong>: 컴퓨터, 스마트폰, 서버 등</p>
<p>• <strong>네트워크 장비</strong>: 라우터, 스위치, 허브 등</p>
<p><strong>🔹 링크(Link)</strong>  </p>
<p>노드 간에 데이터를 주고받을 수 있도록 연결하는 물리적 또는 논리적 경로.</p>
<p>• <strong>유선(Wired)</strong>: 이더넷(Ethernet) 케이블, 광케이블</p>
<p>• <strong>무선(Wireless)</strong>: Wi-Fi, LTE, 5G</p>
<p><strong>🔹 프로토콜(Protocol)</strong></p>
<p>네트워크에서 데이터를 송수신하는 규칙과 절차를 정의한 것.</p>
<p>대표적인 프로토콜:</p>
<p>• <strong>IP(Internet Protocol)</strong>: 장치에 주소를 부여하고 데이터를 전달하는 규칙</p>
<p>• <strong>TCP(Transmission Control Protocol)</strong>: 신뢰성 있는 데이터 전송</p>
<p>• <strong>UDP(User Datagram Protocol)</strong>: 빠르지만 신뢰성이 낮은 데이터 전송</p>
<hr>
<p><strong>네트워크의 계층 구조 (OSI 7계층 &amp; TCP/IP 4계층)</strong></p>
<p>네트워크는 데이터를 효율적으로 전달하기 위해 계층 구조를 가진다.</p>
<p>🔸 OSI 7계층 모델과 실제로 많이 쓰이는 TCP/IP 4계층 모델을 살펴보자.</p>
<p><strong>🔸 OSI 7계층 (이론적인 네트워크 모델)</strong></p>
<table>
<thead>
<tr>
<th><strong>계층</strong></th>
<th><strong>역할</strong></th>
<th><strong>프로토콜 예시</strong></th>
</tr>
</thead>
<tbody><tr>
<td>7. 응용 계층</td>
<td>사용자와 직접 상호작용</td>
<td>HTTP, FTP, SMTP</td>
</tr>
<tr>
<td>6. 표현 계층</td>
<td>데이터 인코딩 및 암호화</td>
<td>SSL, JPEG, PNG</td>
</tr>
<tr>
<td>5. 세션 계층</td>
<td>세션 설정 및 유지</td>
<td>RPC, NetBIOS</td>
</tr>
<tr>
<td>4. 전송 계층</td>
<td>데이터 흐름 제어, 신뢰성 보장</td>
<td>TCP, UDP</td>
</tr>
<tr>
<td>3. 네트워크 계층</td>
<td>IP 주소 할당 및 경로 설정</td>
<td>IP, ICMP, ARP</td>
</tr>
<tr>
<td>2. 데이터 링크 계층</td>
<td>MAC 주소를 이용한 데이터 전송</td>
<td>Ethernet, Wi-Fi</td>
</tr>
<tr>
<td>1. 물리 계층</td>
<td>물리적 전송 매체 (케이블, 전파 등)</td>
<td>UTP, 광섬유, 무선</td>
</tr>
</tbody></table>
<p><strong>🔸 TCP/IP 4계층 (실제 인터넷에서 쓰이는 모델)</strong></p>
<table>
<thead>
<tr>
<th><strong>계층</strong></th>
<th><strong>역할</strong></th>
<th><strong>프로토콜 예시</strong></th>
</tr>
</thead>
<tbody><tr>
<td>4. 응용 계층</td>
<td>OSI의 5~7계층 역할</td>
<td>HTTP, FTP, SMTP</td>
</tr>
<tr>
<td>3. 전송 계층</td>
<td>신뢰성 있는 데이터 전송</td>
<td>TCP, UDP</td>
</tr>
<tr>
<td>2. 인터넷 계층</td>
<td>주소 지정 및 패킷 전달</td>
<td>IP, ICMP</td>
</tr>
<tr>
<td>1. 네트워크 액세스 계층</td>
<td>물리적 전송 및 MAC 주소 활용</td>
<td>Ethernet, Wi-Fi</td>
</tr>
</tbody></table>
<hr>
<p><strong>네트워크의 유형</strong></p>
<p><strong>🏠 LAN (Local Area Network) - 근거리 네트워크</strong></p>
<p>• 작은 범위(가정, 회사)에서 사용</p>
<p>• 빠른 속도(Ethernet, Wi-Fi)</p>
<p><strong>🌎 WAN (Wide Area Network) - 광역 네트워크</strong></p>
<p>• 여러 도시, 국가 간 연결 (ex. 인터넷)</p>
<p>• 라우터, 광섬유 케이블을 사용</p>
<p><strong>🔄 VPN (Virtual Private Network) - 가상 사설망</strong></p>
<p>• 공용 네트워크를 사용하지만, 보안이 강화된 사설 네트워크처럼 동작</p>
<p>• 터널링(Tunneling) 기법을 사용해 데이터 암호화</p>
<hr>
<p><strong>네트워크의 기본 동작 방식</strong></p>
<p><strong>✔ 패킷(Packet) 기반 통신</strong></p>
<p>네트워크에서는 데이터를 작은 조각(패킷)으로 나누어 전송한다.</p>
<p>패킷은 <strong>출발지 주소</strong>, <strong>목적지 주소</strong>, <strong>데이터</strong> 등을 포함한다.</p>
<p><strong>✔ 라우팅(Routing)</strong></p>
<p>패킷이 출발지에서 목적지까지 가는 경로를 찾는 과정.</p>
<p>• <strong>라우터(Router)</strong>가 경로를 결정하고 패킷을 전달한다.</p>
<p>• <strong>IP 주소</strong>와 <strong>서브넷 마스크</strong>를 이용해 네트워크를 구분한다.</p>
<p><strong>✔ DNS(Domain Name System)</strong></p>
<p>• 우리가 흔히 사용하는 웹사이트 주소(예: google.com)를 실제 IP 주소(예: 142.250.190.78)로 변환하는 역할.</p>
<hr>
<p><strong>5. 네트워크의 핵심 장비</strong></p>
<table>
<thead>
<tr>
<th><strong>장비</strong></th>
<th><strong>역할</strong></th>
</tr>
</thead>
<tbody><tr>
<td>📌 <strong>라우터(Router)</strong></td>
<td>네트워크 간의 데이터 경로를 결정</td>
</tr>
<tr>
<td>📌 <strong>스위치(Switch)</strong></td>
<td>같은 네트워크 내에서 데이터 패킷을 전달</td>
</tr>
<tr>
<td>📌 <strong>허브(Hub)</strong></td>
<td>네트워크 신호를 단순히 복사하여 전달</td>
</tr>
<tr>
<td>📌 <strong>모뎀(Modem)</strong></td>
<td>인터넷 신호(광신호/아날로그)를 디지털 신호로 변환</td>
</tr>
</tbody></table>
<hr>
<p><strong>6. 네트워크 보안 개념</strong></p>
<p><strong>🔐 방화벽(Firewall)</strong></p>
<p>• 외부에서 내부 네트워크로의 접근을 차단하거나 제한하는 보안 장비.</p>
<p><strong>🔐 IDS/IPS (침입 탐지/방지 시스템)</strong></p>
<p>• IDS(침입 탐지 시스템): 비정상적인 트래픽을 감지</p>
<p>• IPS(침입 방지 시스템): 감지 후 공격을 차단</p>
<p><strong>🔐 HTTPS (Hypertext Transfer Protocol Secure)</strong></p>
<p>• SSL/TLS 암호화를 통해 HTTP 통신을 안전하게 보호</p>
<hr>
<p><strong>💡 정리</strong></p>
<p>✅ 네트워크는 <strong>노드(Node), 링크(Link), 프로토콜(Protocol)</strong>로 구성됨</p>
<p>✅ 계층 구조는 <strong>OSI 7계층 모델</strong>과 <strong>TCP/IP 4계층 모델</strong>이 있음</p>
<p>✅ 네트워크는 <strong>패킷(Packet) 기반으로 동작</strong>하고 <strong>라우팅(Routing)</strong>을 통해 경로를 찾음</p>
<p>✅ <strong>LAN/WAN/VPN</strong> 같은 네트워크 유형이 있으며, <strong>라우터/스위치/허브</strong> 등의 장비가 있음</p>
<p>✅ 보안을 위해 <strong>방화벽, IDS/IPS, HTTPS</strong> 등의 기술이 사용됨</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[트리(Tree )]]></title>
            <link>https://velog.io/@taeyul_de/%ED%8A%B8%EB%A6%ACTree</link>
            <guid>https://velog.io/@taeyul_de/%ED%8A%B8%EB%A6%ACTree</guid>
            <pubDate>Mon, 17 Mar 2025 08:56:57 GMT</pubDate>
            <description><![CDATA[<h1 id="🌳-트리tree">🌳 트리(Tree)</h1>
<h3 id="트리tree란"><strong>트리(Tree)란?</strong></h3>
<p>트리는 <strong>계층적인 관계</strong>를 표현하는 자료구조다. 여러 개의 데이터를 <strong>부모-자식 관계</strong>로 연결하여 저장하는 방식.</p>
<h3 id="예시"><strong>예시</strong></h3>
<ul>
<li><strong>가족 족보</strong> → 조상이 있고, 그 아래로 자식, 손자가 계층적으로 이어짐.</li>
<li><strong>회사 조직도</strong> → CEO가 있고, 그 아래로 부서장이 있고, 부서장 아래에 직원들이 있음.</li>
<li><strong>폴더 구조</strong> → 컴퓨터에서 하나의 폴더 안에 여러 파일과 하위 폴더가 포함될 수 있음.</li>
</ul>
<p>트리는 <strong>한 개의 최상위 노드(루트)에서 시작해서 가지처럼 뻗어나가는 구조</strong>이다.</p>
<hr>
<h2 id="트리의-기본-개념"><strong>트리의 기본 개념</strong></h2>
<h3 id="트리의-구성-요소"><strong>트리의 구성 요소</strong></h3>
<table>
<thead>
<tr>
<th>용어</th>
<th>설명</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td><strong>노드(Node)</strong></td>
<td>데이터를 저장하는 기본 단위</td>
<td>사람, 폴더, 회사 부서</td>
</tr>
<tr>
<td><strong>루트(Root) 노드</strong></td>
<td>트리의 최상위 노드</td>
<td>가족 족보에서 가장 윗사람</td>
</tr>
<tr>
<td><strong>부모(Parent) 노드</strong></td>
<td>자식 노드를 가지는 노드</td>
<td>아버지, 회사 팀장</td>
</tr>
<tr>
<td><strong>자식(Child) 노드</strong></td>
<td>부모 노드 아래에 있는 노드</td>
<td>아들, 팀원</td>
</tr>
<tr>
<td><strong>리프(Leaf) 노드</strong></td>
<td>자식이 없는 노드</td>
<td>최하위 직원, 파일</td>
</tr>
<tr>
<td><strong>간선(Edge)</strong></td>
<td>노드를 연결하는 선</td>
<td>가족 관계, 조직도</td>
</tr>
<tr>
<td><strong>깊이(Depth)</strong></td>
<td>루트에서 특정 노드까지의 거리</td>
<td>조직에서 사장 → 부장 → 팀장 → 직원까지 몇 단계인지</td>
</tr>
<tr>
<td><strong>높이(Height)</strong></td>
<td>특정 노드에서 가장 깊은 리프 노드까지의 거리</td>
<td>트리의 최대 깊이</td>
</tr>
</tbody></table>
<h3 id="트리의-특징"><strong>트리의 특징</strong></h3>
<p>1️⃣ 루트에서 시작해 여러 개의 <strong>자식 노드</strong>로 가지를 뻗어나간다. 2️⃣ 하나의 노드는 <strong>한 개의 부모 노드만 가질 수 있다</strong> (단, 루트 노드는 부모가 없음). 3️⃣ 트리는 <strong>사이클이 없다</strong> (순환 구조가 불가능함). 4️⃣ 깊이(depth)와 높이(height) 개념이 존재한다.</p>
<hr>
<h2 id="트리의-종류"><strong>트리의 종류</strong></h2>
<h3 id="1️⃣-일반-트리-general-tree"><strong>1️⃣ 일반 트리 (General Tree)</strong></h3>
<ul>
<li>하나의 부모가 여러 개의 자식을 가질 수 있는 트리.</li>
<li>예시: <strong>회사 조직도, 족보, 폴더 구조</strong>.</li>
</ul>
<h3 id="2️⃣-이진-트리-binary-tree"><strong>2️⃣ 이진 트리 (Binary Tree)</strong></h3>
<ul>
<li>모든 노드가 <strong>최대 2개의 자식 노드</strong>만 가질 수 있는 트리.</li>
<li>예시: <strong>이진 검색 트리(Binary Search Tree, BST), 힙(Heap)</strong></li>
</ul>
<h3 id="3️⃣-이진-탐색-트리-bst-binary-search-tree"><strong>3️⃣ 이진 탐색 트리 (BST, Binary Search Tree)</strong></h3>
<ul>
<li>왼쪽 자식은 부모보다 작은 값, 오른쪽 자식은 부모보다 큰 값을 가지는 이진 트리.</li>
<li>데이터 검색, 정렬에 효율적 (O(log n) 시간복잡도).</li>
<li><strong>예시:</strong> 검색 엔진 자동완성 기능, 데이터베이스 인덱스.</li>
</ul>
<h3 id="4️⃣-균형-트리-balanced-tree"><strong>4️⃣ 균형 트리 (Balanced Tree)</strong></h3>
<ul>
<li>높이가 일정하게 유지되도록 자동 정렬되는 트리.</li>
<li><strong>예시:</strong> AVL 트리, 레드-블랙 트리 (빠른 검색을 위해 사용됨).</li>
</ul>
<h3 id="5️⃣-힙heap-트리"><strong>5️⃣ 힙(Heap) 트리</strong></h3>
<ul>
<li>부모가 항상 자식보다 크거나(최대 힙), 작도록(최소 힙) 정렬되는 트리.</li>
<li><strong>예시:</strong> 우선순위 큐 (Priority Queue), 작업 스케줄링 시스템.</li>
</ul>
<h3 id="6️⃣-b-tree--btree"><strong>6️⃣ B-Tree / B+Tree</strong></h3>
<ul>
<li><strong>데이터베이스 인덱스 구조</strong>로 사용되는 트리. 검색 속도를 빠르게 하기 위해 설계됨.</li>
<li><strong>예시:</strong> MySQL, MongoDB 같은 데이터베이스에서 사용.</li>
</ul>
<hr>
<h2 id="트리의-활용-예시"><strong>트리의 활용 예시</strong></h2>
<h3 id="1️⃣-파일-시스템"><strong>1️⃣ 파일 시스템</strong></h3>
<ul>
<li>📁 폴더 안에 여러 개의 파일과 하위 폴더가 포함되는 구조.</li>
<li>트리 구조로 구성되어 있어 탐색이 편리함.</li>
</ul>
<h3 id="2️⃣-검색-엔진-자동완성"><strong>2️⃣ 검색 엔진 자동완성</strong></h3>
<ul>
<li>🔎 구글 검색창에서 &quot;hello&quot;를 입력하면 &quot;hello world&quot; 같은 추천 단어가 뜨는 기능.</li>
<li>Trie(트라이) 트리라는 자료구조를 활용하여 빠르게 단어 검색 가능.</li>
</ul>
<h3 id="3️⃣-게임-ai--의사결정-트리"><strong>3️⃣ 게임 AI &amp; 의사결정 트리</strong></h3>
<ul>
<li>🤖 체스 AI가 다음 수를 결정할 때 트리 탐색을 이용해 최적의 선택을 찾음.</li>
<li>🎮 RPG 게임에서 퀘스트 분기점을 결정할 때도 사용됨.</li>
</ul>
<h3 id="4️⃣-데이터베이스-인덱스-b-tree-btree"><strong>4️⃣ 데이터베이스 인덱스 (B-Tree, B+Tree)</strong></h3>
<ul>
<li>📊 데이터베이스에서 데이터를 빠르게 찾기 위해 사용됨.</li>
<li>대용량 데이터 검색을 최적화하는 역할.</li>
</ul>
<h3 id="5️⃣-네트워크-라우팅-인터넷-패킷-전달"><strong>5️⃣ 네트워크 라우팅 (인터넷 패킷 전달)</strong></h3>
<ul>
<li>🌐 인터넷에서 데이터가 목적지까지 갈 때 최적의 경로를 찾기 위해 라우팅 트리를 사용함.</li>
</ul>
<hr>
<h2 id="트리-탐색-알고리즘"><strong>트리 탐색 알고리즘</strong></h2>
<h3 id="1️⃣-dfs-depth-first-search-깊이-우선-탐색"><strong>1️⃣ DFS (Depth First Search, 깊이 우선 탐색)</strong></h3>
<ul>
<li>한 방향으로 깊이 탐색한 후, 더 이상 갈 곳이 없으면 돌아옴.</li>
<li><strong>예시:</strong> 미로 찾기, 퍼즐 게임에서 경로 찾기.</li>
</ul>
<pre><code class="language-js">function dfs(node) {
    if (!node) return;
    console.log(node.value); // 방문한 노드 출력
    dfs(node.left);
    dfs(node.right);
}</code></pre>
<h3 id="2️⃣-bfs-breadth-first-search-너비-우선-탐색"><strong>2️⃣ BFS (Breadth First Search, 너비 우선 탐색)</strong></h3>
<ul>
<li>같은 레벨의 노드를 먼저 탐색한 후, 다음 레벨로 이동.</li>
<li><strong>예시:</strong> 최단 거리 찾기 (네비게이션, AI 경로 탐색).</li>
</ul>
<pre><code class="language-js">function bfs(root) {
    let queue = [root];
    while (queue.length) {
        let node = queue.shift();
        console.log(node.value);
        if (node.left) queue.push(node.left);
        if (node.right) queue.push(node.right);
    }
}</code></pre>
<hr>
<h2 id="마무리"><strong>마무리</strong></h2>
<p>1️⃣ 트리는 <strong>부모-자식 관계를 가지는 계층적 자료구조</strong>이다. 
2️⃣ <strong>이진 탐색 트리(BST)</strong>는 검색이 빠른 트리 구조이다. 
3️⃣ <strong>DFS / BFS 탐색 알고리즘</strong>이 있다 (미로 찾기, AI 등에서 활용). 
4️⃣ 트리는 <strong>파일 시스템, 데이터베이스, AI, 검색 엔진 등 실생활에서 다양하게 활용된다.</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[그래프]]></title>
            <link>https://velog.io/@taeyul_de/%EA%B7%B8%EB%9E%98%ED%94%84</link>
            <guid>https://velog.io/@taeyul_de/%EA%B7%B8%EB%9E%98%ED%94%84</guid>
            <pubDate>Mon, 17 Mar 2025 08:56:08 GMT</pubDate>
            <description><![CDATA[<h2 id="그래프graph-완벽-정리"><strong>그래프(Graph) 완벽 정리</strong></h2>
<p>그래프(Graph)는 <strong>여러 개의 노드(Node, 정점)들이 연결된 자료구조</strong>다.</p>
<p>트리가 부모-자식 관계로 연결된 <strong>계층적 구조</strong>였다면, 그래프는 좀 더 <strong>자유로운 연결 구조</strong>를 갖고 있다</p>
<p>즉, <strong>어떤 데이터들이 서로 연결될 수 있는지 표현하는 강력한 자료구조</strong>.</p>
<hr>
<p><strong>✅ 그래프란?</strong></p>
<p>그래프는 <strong>노드(Node, 정점)</strong>  들과 이들을 연결하는 <strong>간선(Edge)</strong> 들로 이루어진 자료구조이다.</p>
<p>각 노드는 여러 개의 다른 노드와 연결될 수 있으며, <strong>연결의 방향과 유무에 따라 그래프의 종류가 달라진다</strong>.</p>
<p>  <strong>쉽게 비유하면?</strong></p>
<p>• <strong>도시 지도</strong> : 각 도시(노드)들이 도로(간선)로 연결된 모습
• <strong>SNS 친구 관계</strong> : 유저(노드)들이 서로 친구 요청(간선)을 보내서 연결된 모습</p>
<hr>
<h2 id="그래프의-기본-용어"><strong>그래프의 기본 용어</strong></h2>
<table>
<thead>
<tr>
<th><strong>용어</strong></th>
<th><strong>설명</strong></th>
<th><strong>예시</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>노드(Node, 정점)</strong></td>
<td>그래프에서 하나의 개체(점)</td>
<td>도시, SNS 사용자</td>
</tr>
<tr>
<td><strong>간선(Edge)</strong></td>
<td>노드들을 연결하는 선</td>
<td>도로, 친구 관계</td>
</tr>
<tr>
<td><strong>가중치(Weight)</strong></td>
<td>간선의 비용(거리, 시간 등)</td>
<td>서울↔부산 거리 400km</td>
</tr>
<tr>
<td><strong>차수(Degree)</strong></td>
<td>한 노드에 연결된 간선 개수</td>
<td>한 사람이 가진 친구 수</td>
</tr>
</tbody></table>
<p><strong>노드(Node)와 간선(Edge)</strong></p>
<p>A, B, C 세 개의 노드가 있다고 가정해보자.</p>
<p>A ↔ B, B ↔ C로 연결되어 있다면?</p>
<p><strong>A - B - C</strong> (연결 상태)</p>
<p>여기서 <strong>A, B, C는 노드(Node), A-B, B-C는 간선(Edge)</strong></p>
<hr>
<h2 id="그래프의-종류"><strong>그래프의 종류</strong></h2>
<p>그래프는 <strong>방향성과 가중치</strong>에 따라 여러 가지로 나뉜다.</p>
<p><strong>1️⃣ 방향 그래프(Directed Graph) vs 무방향 그래프(Undirected Graph)</strong></p>
<ol>
<li><strong>무방향 그래프 (Undirected Graph)</strong></li>
</ol>
<p>• 간선에 방향이 없음</p>
<p>• A ↔ B (A에서 B로 갈 수도 있고, B에서 A로도 갈 수 있음)</p>
<p>• <strong>예시:</strong> SNS 친구 관계, 도로 양방향 통행</p>
<pre><code>A - B - C</code></pre><p>여기서 A-B, B-C는 서로 <strong>양방향 연결</strong>이 가능</p>
<ol start="2">
<li><strong>방향 그래프 (Directed Graph, Digraph)</strong></li>
</ol>
<p>• 간선에 방향이 있음 (한쪽으로만 이동 가능)</p>
<p>• A → B (A에서 B로 갈 수 있지만, B에서 A로 못 감)</p>
<p>• <strong>예시:</strong> 트위터 팔로우, 도로 일방통행</p>
<pre><code>A → B → C</code></pre><p>A에서 B로 갈 수 있지만, B에서 A로 돌아올 수 없음.</p>
<hr>
<p><strong>2️⃣ 가중치 그래프(Weighted Graph) vs 비가중치 그래프(Unweighted Graph)</strong></p>
<ol>
<li><strong>비가중치 그래프</strong></li>
</ol>
<p>• 간선에 가중치가 없음 (연결 유무만 중요)</p>
<p>• <strong>예시:</strong> SNS 친구 관계 (그냥 친구 여부만 중요)</p>
<ol start="2">
<li><strong>가중치 그래프 (Weighted Graph)</strong></li>
</ol>
<p>• 간선에 비용이 있음 (거리, 시간 등)</p>
<p>• <strong>예시:</strong> 지도에서 도시 간의 거리(서울↔부산 400km, 서울↔대전 140km)</p>
<pre><code>A --(4)--&gt; B --(2)--&gt; C</code></pre><p>여기서 A→B 가중치는 4, B→C 가중치는 2</p>
<hr>
<h2 id="그래프의-표현-방법"><strong>그래프의 표현 방법</strong></h2>
<p>그래프를 코드로 표현하는 방법은 여러 가지가 있다</p>
<p>주로 <strong>인접 행렬(Adjacency Matrix)</strong> 과 <strong>인접 리스트(Adjacency List)</strong> 두 가지 방식이 많이 쓰인다.</p>
<p><strong>1️⃣ 인접 행렬 (Adjacency Matrix)</strong></p>
<p>• 그래프를 <strong>2차원 배열</strong>로 표현</p>
<p>• <strong>노드 개수 n이면, n×n 행렬(배열)을 사용</strong></p>
<p>• <strong>공간 복잡도: O(n²)</strong> (노드 개수가 많으면 메모리 낭비 심함)</p>
<p>• <strong>탐색 속도 빠름 (O(1))</strong></p>
<pre><code class="language-javascript">// 3개의 노드(A, B, C)
const graph = [
  [0, 1, 0],  // A → B
  [1, 0, 1],  // B → A, B → C
  [0, 1, 0]   // C → B
];

console.log(graph[0][1]); // 1 (A→B 연결됨)
console.log(graph[0][2]); // 0 (A→C 연결 안 됨)</code></pre>
<p><strong>행렬에서 1이면 연결됨, 0이면 연결되지 않음</strong></p>
<hr>
<p><strong>2️⃣ 인접 리스트 (Adjacency List)</strong></p>
<p>• 노드별로 <strong>연결된 노드 리스트</strong>를 저장</p>
<p>• <strong>공간 효율적 (O(V + E), 노드+간선 개수만큼)</strong></p>
<p>• <strong>탐색 속도는 다소 느릴 수 있음 (O(V))</strong></p>
<pre><code class="language-javascript">const graph = {
  A: [&quot;B&quot;],
  B: [&quot;A&quot;, &quot;C&quot;],
  C: [&quot;B&quot;]
};

console.log(graph[&quot;A&quot;]); // [&#39;B&#39;] (A는 B와 연결됨)
console.log(graph[&quot;B&quot;]); // [&#39;A&#39;, &#39;C&#39;] (B는 A, C와 연결됨)</code></pre>
<p><strong>각 노드별로 연결된 노드를 리스트로 저장하는 방식</strong></p>
<hr>
<h2 id="그래프-탐색-graph-traversal"><strong>그래프 탐색 (Graph Traversal)</strong></h2>
<p>그래프에서 <strong>모든 노드 방문하기</strong> 위해 DFS와 BFS 탐색 방법이 사용됨</p>
<p><strong>1️⃣ DFS (깊이 우선 탐색, Depth First Search)</strong></p>
<p>• 한 갈래를 끝까지 탐색한 후 돌아오는 방식</p>
<p>• <strong>재귀(Recursive) 또는 스택(Stack) 사용</strong></p>
<p>• <strong>주로 경로 찾기 문제에 사용</strong></p>
<pre><code class="language-javascript">const graph = {
  A: [&quot;B&quot;, &quot;C&quot;],
  B: [&quot;A&quot;, &quot;D&quot;, &quot;E&quot;],
  C: [&quot;A&quot;, &quot;F&quot;],
  D: [&quot;B&quot;],
  E: [&quot;B&quot;, &quot;F&quot;],
  F: [&quot;C&quot;, &quot;E&quot;]
};

function dfs(node, visited = new Set()) {
  if (visited.has(node)) return;
  console.log(node); // 방문 출력
  visited.add(node);

  for (let neighbor of graph[node]) {
    dfs(neighbor, visited);
  }
}

dfs(&quot;A&quot;); // A → B → D → E → F → C</code></pre>
<hr>
<p><strong>2️⃣ BFS (너비 우선 탐색, Breadth First Search)</strong></p>
<p>• 같은 레벨의 노드들을 먼저 탐색</p>
<p>• <strong>큐(Queue) 사용</strong></p>
<p>• <strong>최단 경로 문제에 자주 사용</strong></p>
<pre><code class="language-javascript">function bfs(start) {
  let queue = [start];
  let visited = new Set();

  while (queue.length &gt; 0) {
    let node = queue.shift();
    if (visited.has(node)) continue;
    console.log(node); // 방문 출력
    visited.add(node);

    for (let neighbor of graph[node]) {
      queue.push(neighbor);
    }
  }
}

bfs(&quot;A&quot;); // A → B → C → D → E → F</code></pre>
<p><strong>BFS는 큐(Queue)를 이용해 같은 레벨 노드를 먼저 방문한다.</strong></p>
<p><strong>최단 경로 문제(미로 찾기, 지도 길 찾기)에 자주 사용됨</strong></p>
<hr>
<h2 id="그래프-활용-예제"><strong>그래프 활용 예제</strong></h2>
<p>✔ <strong>네트워크 연결</strong>: 컴퓨터 네트워크, 친구 관계, 추천 시스템</p>
<p>✔ <strong>SNS 관계 분석</strong>: 페이스북, 인스타그램의 친구 추천</p>
<p>✔ <strong>지도 및 길 찾기</strong>: 네비게이션, 지하철 노선도</p>
<p>✔ <strong>웹 크롤링</strong>: 페이지 간의 링크 구조 분석</p>
<p>✔ <strong>AI &amp; 경로 탐색</strong>: 최적 경로 찾기 (A* 알고리즘)</p>
<hr>
<h2 id="마무리"><strong>마무리</strong></h2>
<p>✅ <strong>그래프는 노드(Node)와 간선(Edge)로 이루어진 자료구조</strong></p>
<p>✅ <strong>방향 그래프 / 무방향 그래프, 가중치 그래프 / 비가중치 그래프가 있음</strong></p>
<p>✅ <strong>그래프 표현 방식: 인접 행렬 vs 인접 리스트</strong></p>
<p>✅ <strong>탐색 방법: DFS(깊이 우선 탐색), BFS(너비 우선 탐색)</strong></p>
<p>✅ <strong>실생활에서 다양한 문제 해결에 사용됨</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[tree 와 set ]]></title>
            <link>https://velog.io/@taeyul_de/tree-%EC%99%80-set</link>
            <guid>https://velog.io/@taeyul_de/tree-%EC%99%80-set</guid>
            <pubDate>Tue, 11 Mar 2025 16:32:31 GMT</pubDate>
            <description><![CDATA[<h1 id="🌳-트리tree와-집합set">🌳 트리(Tree)와 집합(Set)</h1>
<h2 id="1️⃣-트리tree란">1️⃣ 트리(Tree)란?</h2>
<h3 id="✅-트리의-개념">✅ <strong>트리의 개념</strong></h3>
<p>트리는 <strong>계층적인 구조를 가진 비선형 자료구조</strong>입니다. 일반적으로 <strong>부모-자식 관계</strong>를 가지며, <strong>루트 노드(Root Node)</strong>에서 시작해 <strong>여러 개의 자식 노드(Child Node)</strong>로 분기된다.</p>
<h3 id="✅-트리의-주요-특징">✅ <strong>트리의 주요 특징</strong></h3>
<ul>
<li><strong>계층적 구조</strong>: 부모-자식 관계를 가짐.</li>
<li><strong>사이클 없음</strong>: 트리는 <strong>비순환 그래프(Directed Acyclic Graph, DAG)</strong>.</li>
<li><strong>노드(Node)와 간선(Edge)으로 구성</strong>: 한 노드는 여러 개의 자식을 가질 수 있음.</li>
<li><strong>트리는 하나의 루트(Root) 노드에서 시작</strong>: 모든 노드는 하나의 부모를 가짐 (예외: 루트 노드)</li>
<li><strong>트리의 깊이(Depth)와 높이(Height) 개념 중요</strong><ul>
<li><strong>깊이(Depth)</strong>: 루트 노드에서 특정 노드까지의 거리</li>
<li><strong>높이(Height)</strong>: 특정 노드에서 가장 깊은 리프 노드까지의 거리</li>
</ul>
</li>
</ul>
<h3 id="✅-트리-용어-정리">✅ <strong>트리 용어 정리</strong></h3>
<table>
<thead>
<tr>
<th>용어</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><strong>루트(Root) 노드</strong></td>
<td>트리의 최상위 노드 (부모가 없음)</td>
</tr>
<tr>
<td><strong>부모(Parent) 노드</strong></td>
<td>다른 노드를 가리키는 노드</td>
</tr>
<tr>
<td><strong>자식(Child) 노드</strong></td>
<td>부모 노드에서 연결된 노드</td>
</tr>
<tr>
<td><strong>형제(Sibling) 노드</strong></td>
<td>같은 부모를 가진 노드들</td>
</tr>
<tr>
<td><strong>리프(Leaf) 노드</strong></td>
<td>자식이 없는 노드</td>
</tr>
<tr>
<td><strong>서브트리(Subtree)</strong></td>
<td>하나의 노드를 기준으로 형성된 작은 트리</td>
</tr>
<tr>
<td><strong>깊이(Depth)</strong></td>
<td>루트에서 특정 노드까지의 거리</td>
</tr>
<tr>
<td><strong>높이(Height)</strong></td>
<td>특정 노드에서 가장 깊은 노드까지의 거리</td>
</tr>
<tr>
<td><strong>차수(Degree)</strong></td>
<td>특정 노드가 가진 자식 노드의 개수</td>
</tr>
</tbody></table>
<h3 id="✅-트리의-종류">✅ <strong>트리의 종류</strong></h3>
<ol>
<li><p><strong>일반 트리 (General Tree)</strong></p>
<ul>
<li>자식 노드의 개수에 제한이 없는 트리.</li>
</ul>
</li>
<li><p><strong>이진 트리(Binary Tree)</strong></p>
<ul>
<li>각 노드가 <strong>최대 두 개의 자식</strong>을 가질 수 있는 트리.</li>
<li>예제 코드 (JavaScript):</li>
</ul>
<pre><code class="language-javascript">class Node {
    constructor(value) {
        this.value = value;
        this.left = null;
        this.right = null;
    }
}

const root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);</code></pre>
</li>
<li><p><strong>이진 탐색 트리(Binary Search Tree, BST)</strong></p>
<ul>
<li>왼쪽 자식 노드는 부모보다 작고, 오른쪽 자식 노드는 부모보다 큼.</li>
<li>예제 코드 (JavaScript):</li>
</ul>
<pre><code class="language-javascript">class BST {
    constructor(value) {
        this.value = value;
        this.left = null;
        this.right = null;
    }

    insert(value) {
        if (value &lt; this.value) {
            if (this.left === null) {
                this.left = new BST(value);
            } else {
                this.left.insert(value);
            }
        } else {
            if (this.right === null) {
                this.right = new BST(value);
            } else {
                this.right.insert(value);
            }
        }
    }
}

const root = new BST(10);
root.insert(5);
root.insert(15);</code></pre>
</li>
<li><p><strong>균형 트리 (Balanced Tree)</strong></p>
<ul>
<li><strong>AVL 트리</strong>: 노드의 균형을 유지하기 위해 <strong>회전 연산(Rotation)을 수행</strong>하는 트리.</li>
<li><strong>레드-블랙 트리 (Red-Black Tree)</strong>: 삽입 및 삭제 연산 시 균형을 유지하는 이진 탐색 트리.</li>
</ul>
</li>
<li><p><strong>힙(Heap) 트리</strong></p>
<ul>
<li>최대 힙(Max Heap) → 부모 노드가 항상 자식보다 큼.</li>
<li>최소 힙(Min Heap) → 부모 노드가 항상 자식보다 작음.</li>
</ul>
</li>
</ol>
<h3 id="✅-트리-순회-방법-tree-traversal">✅ <strong>트리 순회 방법 (Tree Traversal)</strong></h3>
<p>트리의 노드를 탐색하는 방법에는 <strong>DFS(깊이 우선 탐색)</strong>과 <strong>BFS(너비 우선 탐색)</strong>이 있다.</p>
<ol>
<li><p><strong>DFS (Depth First Search, 깊이 우선 탐색)</strong></p>
<ul>
<li><strong>전위 순회 (Preorder Traversal)</strong>: 루트 → 왼쪽 → 오른쪽</li>
<li><strong>중위 순회 (Inorder Traversal)</strong>: 왼쪽 → 루트 → 오른쪽</li>
<li><strong>후위 순회 (Postorder Traversal)</strong>: 왼쪽 → 오른쪽 → 루트</li>
</ul>
<pre><code class="language-javascript">function inorderTraversal(node) {
    if (node !== null) {
        inorderTraversal(node.left);
        console.log(node.value);
        inorderTraversal(node.right);
    }
}
inorderTraversal(root);</code></pre>
</li>
<li><p><strong>BFS (Breadth First Search, 너비 우선 탐색)</strong></p>
<ul>
<li>큐(Queue)를 이용하여 레벨 단위로 탐색함.</li>
</ul>
<pre><code class="language-javascript">function bfsTraversal(root) {
    let queue = [root];
    while (queue.length &gt; 0) {
        let node = queue.shift();
        console.log(node.value);
        if (node.left) queue.push(node.left);
        if (node.right) queue.push(node.right);
    }
}
bfsTraversal(root);</code></pre>
</li>
</ol>
<h3 id="✅-트리의-활용-예시">✅ <strong>트리의 활용 예시</strong></h3>
<ul>
<li><strong>파일 시스템 (디렉토리 구조)</strong></li>
<li><strong>데이터베이스 인덱싱 (B-Tree, B+Tree)</strong></li>
<li><strong>HTML DOM 구조</strong></li>
<li><strong>AI, 게임에서의 의사결정 트리</strong></li>
<li><strong>네트워크 라우팅 (최단 경로 탐색)</strong></li>
</ul>
<hr>
<h2 id="3️⃣-집합set의-내부-동작"><strong>3️⃣ 집합(Set)의 내부 동작</strong></h2>
<h3 id="✅-javascript의-set-객체-내부-원리">✅ <strong>JavaScript의 Set 객체 내부 원리</strong></h3>
<ul>
<li>JavaScript의 <code>Set</code>은 <strong>해시 테이블(Hash Table)</strong>을 기반으로 동작한다.</li>
<li>해시 테이블은 <strong>키-값(Key-Value) 구조</strong>를 사용하여 <strong>O(1)</strong> 시간 복잡도로 데이터를 찾을 수 있다.</li>
<li>즉, <code>Set.has(value)</code> 연산은 매우 빠르게 수행된다.</li>
</ul>
<pre><code class="language-javascript">const mySet = new Set();
mySet.add(1);
mySet.add(2);
mySet.add(3);
console.log(mySet.has(2)); // true
console.log(mySet.size); // 3</code></pre>
<h3 id="✅-set을-이용한-중복-제거">✅ <strong>Set을 이용한 중복 제거</strong></h3>
<pre><code class="language-javascript">const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // [1, 2, 3, 4, 5]</code></pre>
<hr>
<p>트리와 집합의 기본적인 개념은 직관적이라 쉬웠지만.. 조금만 파고들어가니 아니나 다를까 이건 또 뭔소리인가 싶었다. </p>
<p>트리는 예를 들자면 족보나 폴더 구조를 떠올려보면 쉽게 이해 할 수 있고 집합은 쇼핑할 때 장바구니나 누군가의 버킷리스트를 떠올려보면 쉽게 이해 할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[파일 시스템]]></title>
            <link>https://velog.io/@taeyul_de/%ED%8C%8C%EC%9D%BC-%EC%8B%9C%EC%8A%A4%ED%85%9C</link>
            <guid>https://velog.io/@taeyul_de/%ED%8C%8C%EC%9D%BC-%EC%8B%9C%EC%8A%A4%ED%85%9C</guid>
            <pubDate>Tue, 25 Feb 2025 19:12:32 GMT</pubDate>
            <description><![CDATA[<h2 id="🗂️-1-파일-시스템file-system이란"><strong>🗂️ 1. 파일 시스템(File System)이란?</strong></h2>
<p>파일 시스템은 <strong>운영체제가 보조기억장치에 있는 데이터를 파일과 디렉터리 형태로 관리하는 체계다.</strong></p>
<p>• 데이터가 <strong>무질서하게 저장</strong>되면 <strong>찾기 힘들고 관리도 어려움</strong>
• 파일 시스템이 <strong>이름, 경로, 속성</strong> 등으로 데이터를 <strong>효율적으로 관리</strong>
• <strong>손상 방지</strong>, <strong>빠른 접근성</strong>, <strong>데이터 보안</strong>까지 가능하다</p>
<table>
<thead>
<tr>
<th>운영체제</th>
<th>파일 시스템 종류</th>
</tr>
</thead>
<tbody><tr>
<td>Windows</td>
<td><strong>NTFS, FAT32</strong></td>
</tr>
<tr>
<td>Linux</td>
<td><strong>EXT4, XFS</strong></td>
</tr>
<tr>
<td>macOS</td>
<td><strong>APFS</strong></td>
</tr>
</tbody></table>
<hr>
<h3 id="2-파일과-디렉터리"><strong>2. 파일과 디렉터리</strong></h3>
<p><strong>2-1. 파일(File)</strong></p>
<p>파일은 <strong>데이터를 저장하는 기본 단위</strong>.</p>
<p>구성 요소:</p>
<p>• <strong>파일 이름</strong>: 사용자가 파일을 구별하는 이름
• <strong>메타데이터(Metadata)</strong>: 파일의 속성 정보 (파일 크기, 위치, 생성일, 수정일, 권한 등)
• <strong>데이터(Data)</strong>: 실제 내용 (문서, 이미지, 실행 파일 등)</p>
<p><strong>메타데이터가 왜 중요하냐</strong></p>
<p>• 파일 검색 속도 증가
• 보안 설정 가능 (읽기/쓰기 권한 등)
• 수정 및 접근 이력 관리</p>
<p><strong>2-2. 디렉터리(Directory)</strong></p>
<p>디렉터리는 <strong>파일과 다른 디렉터리를 조직적으로 모아 놓은 컨테이너</strong>.</p>
<p> Windows: <strong>폴더</strong> 
 Mac,Linux: <strong>디렉터리</strong>라고 부른다</p>
<p><strong>디렉터리 구조</strong></p>
<p>• <strong>트리 구조(Tree Structure)</strong>: 계층적인 구조
• <strong>루트 디렉터리(/)</strong>: 최상위 폴더
• <strong>서브 디렉터리</strong>: 하위 폴더</p>
<p><strong>경로(Path)</strong></p>
<p>• <strong>절대 경로</strong>: 루트(/)부터 시작 → /home/user/docs/file.txt
• <strong>상대 경로</strong>: 현재 위치 기준 → ../docs/file.txt</p>
<p><strong>중요! 디렉터리도 결국 “파일”이다</strong></p>
<p>• 디렉터리 = <strong>파일 목록을 담고 있는 특별한 파일</strong>
• <strong>디렉터리 엔트리(Directory Entry)</strong> 에 <strong>파일 이름 + 파일 위치 정보</strong> 포함</p>
<hr>
<h3 id="3-파일-디스크립터file-descriptor와-시스템-콜"><strong>3. 파일 디스크립터(File Descriptor)와 시스템 콜</strong></h3>
<p><strong>3-1. 파일 디스크립터(File Descriptor)</strong></p>
<p>파일을 사용할 때 <strong>운영체제가 파일을 식별하기 위해 부여하는 정수 값</strong>이다.</p>
<p>• Linux/Unix: <strong>파일 디스크립터</strong>
• Windows: <strong>파일 핸들(File Handle)</strong></p>
<p><strong>대표적인 파일 디스크립터 번호</strong></p>
<table>
<thead>
<tr>
<th><strong>번호</strong></th>
<th><strong>의미</strong></th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>0</td>
<td>표준 입력(stdin)</td>
<td>사용자 입력 처리</td>
</tr>
<tr>
<td>1</td>
<td>표준 출력(stdout)</td>
<td>화면 출력</td>
</tr>
<tr>
<td>2</td>
<td>표준 오류(stderr)</td>
<td>오류 메시지 출력</td>
</tr>
</tbody></table>
<p><strong>3-2. 시스템 콜(System Call)</strong></p>
<p><strong>응용 프로그램이 운영체제의 자원을 요청</strong>할 때 사용하는 인터페이스.</p>
<p><strong>파일 관련 주요 시스템 콜:</strong></p>
<p>• <strong>open()</strong>: 파일 열기 → 파일 디스크립터 반환
• <strong>write()</strong>: 파일 쓰기 → 디스크립터 필요
• <strong>read()</strong>: 파일 읽기
• <strong>close()</strong>: 파일 닫기</p>
<p><strong>왜 시스템 콜을 사용하냐</strong></p>
<p>• 사용자 프로그램이 <strong>직접 메모리나 하드 접근 못하게</strong> 막아서 보안 강화
• <strong>운영체제가 권한 관리</strong>하고 <strong>자원 낭비 방지</strong></p>
<hr>
<h3 id="4-파일-할당-방식-보조기억장치에-파일-저장-방법"><strong>4. 파일 할당 방식 (보조기억장치에 파일 저장 방법)</strong></h3>
<p><strong>4-1. 블록 단위 저장</strong></p>
<p>• <strong>보조기억장치 → 블록(Block)</strong> 단위로 데이터를 저장
• <strong>블록 크기</strong>: 보통 <strong>4KB</strong>
• <strong>하나의 파일 = 여러 블록에 분산 저장 가능</strong></p>
<p><strong>4-2. 파일 할당 기법</strong></p>
<p><strong>(1) 연속 할당(Contiguous Allocation)</strong></p>
<p>• <strong>연속된 블록에 파일을 저장</strong></p>
<p>장점: 빠른 접근</p>
<p>단점: <strong>외부 단편화 발생</strong>, 파일 크기 예측 어려움</p>
<hr>
<p><strong>(2) 연결 할당(Linked Allocation)</strong></p>
<p>• 각 블록에 <strong>다음 블록의 주소 저장</strong></p>
<p>장점: 단편화 해결</p>
<p>단점: <strong>임의 접근 속도 느림</strong> (순차 접근만 빠름)</p>
<hr>
<p><strong>(3) 색인 할당(Indexed Allocation)</strong></p>
<p>• <strong>모든 블록 주소를 색인 블록에 저장</strong></p>
<p>장점: <strong>빠른 임의 접근 가능</strong></p>
<p>단점: 색인 블록이 커질 수 있음</p>
<hr>
<h3 id="5-아이노드inode와-ext4-파일-시스템"><strong>5. 아이노드(Inode)와 EXT4 파일 시스템</strong></h3>
<p><strong>5-1. 아이노드(Inode)란?</strong></p>
<p>Linux와 macOS 같은 시스템에서는 <strong>아이노드</strong>라는 구조체로 파일 정보를 관리한다.</p>
<p><strong>아이노드에 저장된 정보:</strong></p>
<p>• 파일 크기, 생성일, 수정일
• 파일 권한 및 소유자
• <strong>데이터 블록 주소(중요!)</strong></p>
<p><strong>아이노드에는 “파일 이름”이 없음</strong></p>
<p>→ 파일 이름은 <strong>디렉터리 엔트리</strong>에서 관리</p>
<p><strong>5-2. EXT4 파일 시스템 구조</strong></p>
<p>EXT4는 Linux에서 <strong>가장 널리 쓰이는 파일 시스템</strong></p>
<p><strong>구성 요소</strong></p>
<table>
<thead>
<tr>
<th><strong>구성 요소</strong></th>
<th><strong>설명</strong></th>
</tr>
</thead>
<tbody><tr>
<td>슈퍼 블록(Superblock)</td>
<td>파일 시스템 전체 정보 (크기, 상태, 버전)</td>
</tr>
<tr>
<td>블록 그룹(Block Group)</td>
<td>데이터 블록 묶음</td>
</tr>
<tr>
<td>아이노드 테이블(Inode Table)</td>
<td>파일의 메타데이터 저장</td>
</tr>
<tr>
<td>데이터 블록(Data Block)</td>
<td>실제 파일 내용 저장</td>
</tr>
<tr>
<td>블록 비트맵(Block Bitmap)</td>
<td>사용 중인 블록 여부 추적</td>
</tr>
</tbody></table>
<p><strong>5-3. 아이노드와 디렉터리 관계</strong></p>
<p><strong>디렉터리 엔트리 구조</strong></p>
<table>
<thead>
<tr>
<th><strong>항목</strong></th>
<th><strong>설명</strong></th>
</tr>
</thead>
<tbody><tr>
<td>파일 이름</td>
<td>파일 구분을 위한 이름</td>
</tr>
<tr>
<td>아이노드 번호(Inode Number)</td>
<td>파일 위치 및 속성 찾기 위한 열쇠</td>
</tr>
</tbody></table>
<p><strong>디렉터리는 결국 “아이노드 번호 목록”을 가진 파일</strong>이라고 보면 된다.</p>
<hr>
<h2 id="-아이노드와-파일-디스크립터-비교">?? 아이노드와 파일 디스크립터 비교</h2>
<p><strong>아이노드(Inode) vs 파일 디스크립터(File Descriptor)</strong></p>
<p><strong>아이노드와 파일 디스크립터, 둘 다 “파일과 관련된 정보”지만 역할이 완전히 다르다</strong></p>
<table>
<thead>
<tr>
<th><strong>구분</strong></th>
<th><strong>아이노드(Inode)</strong></th>
<th><strong>파일 디스크립터(File Descriptor)</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>정의</strong></td>
<td><strong>파일의 메타데이터(속성 정보)</strong>를 담은 데이터 구조체</td>
<td><strong>프로세스가 파일을 열 때 운영체제가 부여하는 식별 번호</strong></td>
</tr>
<tr>
<td><strong>저장 위치</strong></td>
<td>디스크(보조기억장치)에 저장</td>
<td>운영체제(커널)의 메모리 공간에 저장</td>
</tr>
<tr>
<td><strong>역할</strong></td>
<td>파일의 크기, 권한, 생성일, 수정일, 데이터 위치 정보 제공</td>
<td>열려 있는 파일을 프로세스가 사용할 수 있도록 식별 및 관리</td>
</tr>
<tr>
<td><strong>파일 이름 포함?</strong></td>
<td>❌ 포함하지 않음 (이름은 디렉터리 엔트리가 관리)</td>
<td>❌ 이름 포함 없음 (아이노드와 연결된 내부 정보만 참조)</td>
</tr>
<tr>
<td><strong>언제 사용?</strong></td>
<td><strong>파일 자체 정보 확인이나 저장 시 사용</strong></td>
<td><strong>프로세스가 파일을 읽거나 쓸 때 사용</strong></td>
</tr>
<tr>
<td><strong>수명</strong></td>
<td><strong>파일이 존재하는 동안 계속 유지</strong></td>
<td><strong>파일 열 때 생성, 닫으면 사라짐</strong></td>
</tr>
<tr>
<td><strong>비유</strong></td>
<td><strong>책의 도서관 카드 (책 위치와 정보 기록)</strong></td>
<td><strong>도서관에서 책을 빌릴 때 받는 대출 번호표 (임시로 사용하는 표)</strong></td>
</tr>
<tr>
<td><strong>관계</strong></td>
<td>아이노드는 파일에 대한 <strong>정적 정보(속성)</strong> 제공</td>
<td>파일 디스크립터는 <strong>프로세스가 파일을 조작할 때 임시로 생성되는 번호</strong></td>
</tr>
</tbody></table>
<p>• <strong>아이노드:</strong> 파일의 <strong>영구적인 정보</strong> (크기, 위치, 권한 등)를 관리
• <strong>디스크립터:</strong> 파일을 <strong>현재 열고 있는 프로세스가 사용하기 위한 임시 번호</strong></p>
<p><strong>쉽게 정리하자면</strong></p>
<p>• <strong>아이노드:</strong> 파일의 <strong>주민등록번호 카드</strong> → <strong>항상 존재 &amp; 영구 정보</strong>
• <strong>디스크립터:</strong> 파일 열 때 받는 <strong>일회용 번호표</strong> → <strong>작업 끝나면 사라짐</strong></p>
<p>커피를 고를 때 메뉴판 보고 주문하면 진동벨을 받는 것처럼
아이노드로 파일 위치를 확인하고 디스크립터로 파일을 다룬다.</p>
<hr>
<h3 id="6-링크-파일-하드-링크-vs-심볼릭-링크"><strong>6. 링크 파일: 하드 링크 vs 심볼릭 링크</strong></h3>
<p><strong>6-1. 하드 링크(Hard Link)</strong></p>
<p>• <strong>같은 아이노드를 공유하는 다른 이름의 파일</strong>
• <strong>원본 삭제 시에도 데이터 유지</strong> (링크가 남아 있으면 파일 유효)</p>
<p><strong>6-2. 심볼릭 링크(Symbolic Link)</strong></p>
<p>• <strong>원본 파일 경로를 저장한 파일</strong> (Windows 바로가기 개념)
• <strong>원본 삭제 시 링크 깨짐</strong></p>
<table>
<thead>
<tr>
<th><strong>링크 종류</strong></th>
<th><strong>아이노드 공유</strong></th>
<th><strong>원본 삭제 시</strong></th>
<th><strong>특징</strong></th>
</tr>
</thead>
<tbody><tr>
<td>하드 링크(Hard Link)</td>
<td>공유</td>
<td>데이터 유지</td>
<td>같은 파일, 다른 이름</td>
</tr>
<tr>
<td>심볼릭 링크(Symbolic Link)</td>
<td>미공유</td>
<td>링크 깨짐</td>
<td>경로만 참조 (바로가기)</td>
</tr>
</tbody></table>
<hr>
<h3 id="7-마운트mount"><strong>7. 마운트(Mount)</strong></h3>
<p><strong>7-1. 마운트란?</strong></p>
<p>• <strong>외부 저장장치(USB, 외장하드 등)를 운영체제에 연결해 사용하는 과정</strong></p>
<p>예: USB 연결 시 /mnt/usb 경로에서 접근 가능</p>
<p><strong>자동 마운트 vs 수동 마운트</strong></p>
<table>
<thead>
<tr>
<th><strong>구분</strong></th>
<th><strong>자동 마운트</strong></th>
<th><strong>수동 마운트</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>작동 방식</strong></td>
<td>USB 꽂으면 <strong>자동 연결</strong></td>
<td>사용자가 직접 <strong>명령어 입력 필요</strong></td>
</tr>
<tr>
<td><strong>사용 환경</strong></td>
<td>Windows, macOS 데스크탑</td>
<td>Linux 서버, 전문가용 환경에서 사용</td>
</tr>
<tr>
<td><strong>편의성</strong></td>
<td>✅ 편리함 (초보자 친화적)</td>
<td>❌ 불편하지만 세밀한 설정 가능</td>
</tr>
<tr>
<td><strong>예시</strong></td>
<td>USB 꽂자마자 <strong>자동 인식</strong></td>
<td>mount 명령어로 수동 연결 필요</td>
</tr>
</tbody></table>
<p><strong>마운트와 링크 파일의 차이</strong></p>
<table>
<thead>
<tr>
<th><strong>비교 항목</strong></th>
<th><strong>마운트(Mount)</strong></th>
<th><strong>링크 파일(하드/심볼릭)</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>역할</strong></td>
<td><strong>외부 장치를 시스템에 연결</strong></td>
<td><strong>다른 파일을 참조하거나 여러 이름으로 접근</strong></td>
</tr>
<tr>
<td><strong>적용 대상</strong></td>
<td>USB, 외장하드, CD 등 <strong>저장장치 연결</strong></td>
<td>파일 또는 디렉터리 <strong>내부 참조</strong></td>
</tr>
<tr>
<td><strong>연결 해제 시</strong></td>
<td><strong>umount 하면 접근 불가</strong></td>
<td>하드 링크는 <strong>삭제해도 작동</strong>, 심볼릭 링크는 <strong>깨짐</strong></td>
</tr>
<tr>
<td><strong>비유</strong></td>
<td><strong>새로운 방에 들어가는 문을 만들기</strong></td>
<td><strong>집에 출입문 추가(하드 링크)</strong> or <strong>표지판 설치(심볼릭)</strong></td>
</tr>
</tbody></table>
<hr>
<p>마무리.</p>
<table>
<thead>
<tr>
<th>** 개념**</th>
<th><strong>설명</strong></th>
</tr>
</thead>
<tbody><tr>
<td>파일 시스템</td>
<td>보조기억장치를 파일 및 디렉터리로 관리하는 체계</td>
</tr>
<tr>
<td>파일</td>
<td>이름, 메타데이터, 실제 데이터로 구성</td>
</tr>
<tr>
<td>디렉터리</td>
<td>파일 목록을 가진 특수 파일, 트리 구조로 계층 관리</td>
</tr>
<tr>
<td>파일 디스크립터</td>
<td>운영체제가 파일을 식별하기 위해 부여하는 정수</td>
</tr>
<tr>
<td>할당 방식</td>
<td>연속 할당, 연결 할당, 색인 할당 등 다양한 방식으로 블록 관리</td>
</tr>
<tr>
<td>아이노드</td>
<td>파일의 메타데이터와 데이터 블록 주소를 저장, 이름은 디렉터리 관리</td>
</tr>
<tr>
<td>링크 파일</td>
<td>하드 링크: 같은 아이노드, 심볼릭 링크: 경로 참조</td>
</tr>
<tr>
<td>마운트</td>
<td>외부 파일 시스템을 내부 파일 시스템에 연결</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[가상 메모리]]></title>
            <link>https://velog.io/@taeyul_de/%EA%B0%80%EC%83%81-%EB%A9%94%EB%AA%A8%EB%A6%AC</link>
            <guid>https://velog.io/@taeyul_de/%EA%B0%80%EC%83%81-%EB%A9%94%EB%AA%A8%EB%A6%AC</guid>
            <pubDate>Tue, 25 Feb 2025 19:11:40 GMT</pubDate>
            <description><![CDATA[<h2 id="물리-주소와-논리-주소">물리 주소와 논리 주소</h2>
<ol>
<li>논리 주소(Logical Address)
 CPU가 생성한 주소로 가상주소 라고도 불린다. 
 프로세스는 메모리 할당 시 실제 물리주소를 직접 알지 못한다.
 이 논리 주소는 CPU 내부의 레지스터에서 생성된다.</li>
<li>물리주소(Physical Address)
 실제 RAM에서 데이터가 저장되는 위치의 주소
 논리 주소와 달리, 메모리 컨트롤러가 실제 메모리 접근에 사용된다.</li>
</ol>
<h3 id="주소-변환-과정-mmu의-역할">주소 변환 과정 (MMU의 역할)</h3>
<p>MMU (Memory Management Unit) 는 논리 주소를 물리 주소로 변환하는 장치다.</p>
<h3 id="동적정적-주소-바인딩">동적/정적 주소 바인딩</h3>
<ul>
<li>정적 바인딩 : 컴파일 시 주소 결정 (물리적 이동 불가능)</li>
<li>동적 바인딩 : 실행 시 주소 결정 (가상 메모리 구현 가능)
가상 메모리 -&gt; 동적 주소 바인딩이 필수다.</li>
</ul>
<hr>
<h2 id="스와핑과-연속-메모리-할당">스와핑과 연속 메모리 할당</h2>
<p>스와핑은 프로세스를 메모리에서 디스크로 내보냈다가 필요 시 다시 불러오는 것이다.
스와핑을 사용하는 이유는 <strong>메모리 공간 확보</strong> 와 <strong>CPU 유휴 방지</strong> 로 사용한다.</p>
<h4 id="스와핑-과정">스와핑 과정</h4>
<blockquote>
<ol>
<li>메모리에 공간 부족 -&gt; 실행 중인 프로세스 중 비활성 상태 찾음</li>
<li>해당 프로세스를 디스크에 저장</li>
<li>새 프로세스가 메모리에 올라감</li>
<li>이전 프로세스 필요 시 다시 메모리로 불러오기</li>
</ol>
</blockquote>
<h4 id="스레싱">스레싱</h4>
<p>스와핑이 지나치게 자주 발생하면 시스템 성능이 급격하게 저하된다.</p>
<h3 id="연속-메모리-할당-contiquous-memory-allocation">연속 메모리 할당 (Contiquous Memory Allocation)</h3>
<p>프로세스가 메모리에 연속된 블록으로 할당받는 방식이다.
주소 계산이 간단해 빠른 접근이 가능하고 하드웨어 구현이 쉽지만
메모리의 빈 공간이 작은 조각들로 흩어져 큰 프로세스 수용이 불가하고 내부 단편화로 
할당된 메모리보다 작은 프로세스가 공간 낭비.</p>
<hr>
<h2 id="페이징을-통한-가상-메모리-관리">페이징을 통한 가상 메모리 관리</h2>
<p>페이징 기법이란 가상 메모리와 물리 메모리를 같은 크기의 블록으로 나누어 관리하는 방법이다.</p>
<ul>
<li>가상 메모리 = 페이지(Page)</li>
<li>물리 메모리 = 프레임(Frame)
페이지와 프레임 크기가 같아서, 페이지가 프레임에 딱 맞게 들어간다.</li>
</ul>
<h4 id="페이징-과정">페이징 과정</h4>
<ol>
<li>가상 주소 = 페이지 번호 + 오프셋 -&gt; 페이지 테이블 확인 = 해당 페이지의 물리적 프레임 찾기. </li>
</ol>
<p>-&gt; 물리 주소 = 프레임 번호 + 오프셋</p>
<h4 id="페이지-테이블과-주소-변환">페이지 테이블과 주소 변환</h4>
<blockquote>
<p>페이지 테이블 (Page Table)
페이지 번호와 해당 프레임 번호를 매핑
프로세스 마다 자신만의 페이지 테이블을 가진다</p>
</blockquote>
<h4 id="페이지부재page-fault">페이지부재(Page Fault)</h4>
<p>CPU가 참조하려는 페이지가 메모리에 없을 때 발생한다.</p>
<hr>
<h2 id="페이지-교체-알고리즘">페이지 교체 알고리즘</h2>
<h4 id="페이지-교체가-왜-필요할까">페이지 교체가 왜 필요할까?</h4>
<p>메모리 공간이 가득 찼는데 새로운 페이지가 필요하면 기존 페이지 중 하나를 제거해야 한다. 여기서
어떤 페이지를 제거할지 결정하는게 페이지 교체 알고리즘.</p>
<h4 id="교체-알고리즘-종류">교체 알고리즘 종류</h4>
<ol>
<li>FIFO (Forst In First Out)
 가장 먼저 들어온 페이지 제거
 단순하지만, Belady의 이상현상 발생 가능 </li>
<li>LRU (Least Recently Used)
 가장 오래 사용되지 않은 페이지 제거
 과거 사용 패턴 기반이라 현실적이지만, 최근 사용 기록 관비 비용이 크다.</li>
<li>Optimal (최적 교체)
 앞으로 가장 오랫동안 사용되지 않을 페이지 제거
 이론적으로 최적
 미래참조를 예측할 수 없어 실전 사용불가</li>
<li>Second Chance (Clock Algorithm)
 FIFO 개선 버전
 각 페이지에 참조 비트가 1이면 다시 기회 부여
 참조 비트가 0이면 제거</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[CPU 스케줄링]]></title>
            <link>https://velog.io/@taeyul_de/CPU-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81</link>
            <guid>https://velog.io/@taeyul_de/CPU-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81</guid>
            <pubDate>Tue, 25 Feb 2025 19:10:26 GMT</pubDate>
            <description><![CDATA[<p><strong>CPU 스케줄링이란?</strong></p>
<p>CPU 스케줄링은 <strong>운영체제가 CPU를 여러 프로세스에 어떻게 할당할지 결정하는 과정</strong>이다.</p>
<p>• 다수의 프로세스가 동시에 실행될 때, CPU는 한 번에 <strong>하나의 프로세스만 실행</strong>할 수 있기 때문에 <strong>효율적 할당</strong>이 중요.</p>
<p>• 스케줄링 알고리즘을 통해 <strong>응답 시간</strong>, <strong>처리량</strong>, <strong>공정성</strong> 등을 최적화한다.</p>
<hr>
<h2 id="cpu-스케줄링의-목적"><strong>CPU 스케줄링의 목적</strong></h2>
<p>✅ <strong>CPU 사용률 최대화:</strong> CPU가 가능한 한 놀지 않도록 유지</p>
<p>✅ <strong>처리량(Throughput) 증가:</strong> 단위 시간당 완료된 작업 수 증가</p>
<p>✅ <strong>대기 시간 최소화:</strong> 프로세스가 대기 큐에서 기다리는 시간 감소</p>
<p>✅ <strong>응답 시간 개선:</strong> 사용자 요청에 대한 빠른 응답 제공</p>
<p>✅ <strong>공정성 보장:</strong> 모든 프로세스에 공평한 CPU 할당</p>
<p><strong>스케줄링이 필요한 이유</strong></p>
<p>• <strong>멀티태스킹:</strong> 여러 프로그램을 동시에 실행할 때, CPU는 프로세스 간 빠르게 전환해야 함</p>
<p>• <strong>리소스 최적화:</strong> CPU 자원을 효율적으로 사용하여 시스템 성능 향상</p>
<p>• <strong>사용자 경험 개선:</strong> 빠른 프로그램 반응으로 사용자 만족도 증가</p>
<hr>
<p><strong>CPU 스케줄링의 기본 개념</strong></p>
<p><strong>프로세스 상태 (Process States)</strong></p>
<ol>
<li><p><strong>Ready:</strong> CPU 할당을 기다림</p>
</li>
<li><p><strong>Running:</strong> CPU를 할당받아 실행 중</p>
</li>
<li><p><strong>Waiting:</strong> I/O 작업 등으로 대기 중</p>
</li>
<li><p><strong>Terminated:</strong> 실행 완료</p>
</li>
</ol>
<p> <strong>스케줄러(Scheduler)</strong> 는 Ready 상태의 프로세스 중 하나를 선택해 CPU 할당</p>
<hr>
<h2 id="cpu-스케줄링-알고리즘-종류"><strong>CPU 스케줄링 알고리즘 종류</strong></h2>
<p><strong>1️⃣ FCFS (First-Come, First-Served)</strong></p>
<p>• <strong>가장 먼저 도착한 프로세스부터 처리</strong>
• <strong>비선점형(Non-Preemptive)</strong> 방식</p>
<p>✅ <strong>장점:</strong> 구현이 쉽고 공정함
⚠️ <strong>단점:</strong> 평균 대기 시간이 길어질 수 있음 (Convoy Effect 발생)</p>
<p>📝 <strong>예시:</strong></p>
<p>프로세스 도착 순서: P1(도착0, 실행4), P2(도착1, 실행3), P3(도착2, 실행2)
스케줄링 순서: P1 → P2 → P3</p>
<p><strong>2️⃣ SJF (Shortest Job First)</strong></p>
<p>• <strong>실행 시간이 가장 짧은 프로세스부터 처리</strong>
• <strong>비선점형/선점형(Preemptive) 둘 다 가능</strong></p>
<p>✅ <strong>장점:</strong> 평균 대기 시간 최소화
⚠️ <strong>단점:</strong> 긴 작업이 계속 대기할 수 있음 (Starvation 문제)</p>
<p><strong>3️⃣ Round Robin (RR)</strong></p>
<p>• 각 프로세스에 <strong>동일한 시간 할당량(Quantum)</strong> 부여
• <strong>선점형</strong> 방식 → 시간 초과 시 다음 프로세스로 전환</p>
<p>✅ <strong>장점:</strong> 공정성 보장, 반응 시간 개선
⚠️ <strong>단점:</strong> Quantum 설정이 너무 짧으면 과도한 컨텍스트 스위치 발생</p>
<p>📝 <strong>비유:</strong></p>
<p>놀이공원에서 <strong>회전목마</strong>에 한 번씩 돌아가며 타는 것과 유사</p>
<p><strong>4️⃣ Priority Scheduling</strong></p>
<p>• <strong>우선순위가 높은 프로세스부터 실행</strong>
• <strong>선점형/비선점형 모두 가능</strong></p>
<p>✅ <strong>장점:</strong> 중요한 작업 우선 처리 가능
⚠️ <strong>단점:</strong> 낮은 우선순위 프로세스가 무한 대기 (Starvation)  </p>
<p>💡 <strong>해결책:</strong> 우선순위에 <strong>노화(Aging)</strong> 기법 적용 (시간 경과 시 우선순위 상승)</p>
<p><strong>5️⃣ Multilevel Queue Scheduling</strong></p>
<p>• <strong>프로세스를 여러 큐로 분류</strong> (예: 시스템 프로세스, 사용자 프로세스)
• 각 큐마다 <strong>다른 스케줄링 알고리즘</strong> 적용</p>
<p>✅ <strong>장점:</strong> 프로세스 특성에 맞는 스케줄링 가능
⚠️ <strong>단점:</strong> 큐 간 이동이 제한적일 수 있음</p>
<hr>
<h2 id="📊-스케줄링-성능-지표"><strong>📊 스케줄링 성능 지표</strong></h2>
<table>
<thead>
<tr>
<th><strong>지표</strong></th>
<th><strong>설명</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>CPU 사용률</strong></td>
<td>CPU가 사용 중인 시간 비율</td>
</tr>
<tr>
<td><strong>처리량(Throughput)</strong></td>
<td>단위 시간당 완료된 프로세스 수</td>
</tr>
<tr>
<td><strong>대기 시간(Waiting Time)</strong></td>
<td>프로세스가 Ready 상태에서 대기한 총 시간</td>
</tr>
<tr>
<td><strong>응답 시간(Response Time)</strong></td>
<td>요청 → 첫 응답까지 걸린 시간</td>
</tr>
<tr>
<td><strong>턴어라운드 시간(Turnaround Time)</strong></td>
<td>작업 시작 → 완료까지 걸린 시간</td>
</tr>
</tbody></table>
<p><strong>💻 Round Robin 간단 코드 예시 (JavaScript)</strong></p>
<pre><code class="language-javascript">function roundRobin(processes, quantum) {
  let time = 0;
  const queue = [...processes];

  while (queue.length) {
    const process = queue.shift();
    if (process.burstTime &lt;= quantum) {
      time += process.burstTime;
      console.log(`${process.name} 완료 at time ${time}`);
    } else {
      time += quantum;
      process.burstTime -= quantum;
      queue.push(process); // 남은 작업 재삽입
    }
  }
}

const processes = [
  { name: &#39;P1&#39;, burstTime: 5 },
  { name: &#39;P2&#39;, burstTime: 3 },
  { name: &#39;P3&#39;, burstTime: 1 },
];

roundRobin(processes, 2);</code></pre>
<p>✅ <strong>코드 설명:</strong></p>
<p>• 각 프로세스에 시간 할당량(Quantum)을 주고 실행</p>
<p>• 시간이 남으면 다시 큐에 추가하여 공정성 유지</p>
<p><strong>🧭 스케줄링 알고리즘 비교</strong></p>
<table>
<thead>
<tr>
<th><strong>알고리즘</strong></th>
<th><strong>선점 여부</strong></th>
<th><strong>특징</strong></th>
<th><strong>장점</strong></th>
<th><strong>단점</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>FCFS</strong></td>
<td>비선점형</td>
<td>도착 순서대로 실행</td>
<td>구현 쉬움, 공정함</td>
<td>긴 평균 대기 시간</td>
</tr>
<tr>
<td><strong>SJF</strong></td>
<td>둘 다 가능</td>
<td>짧은 작업 우선 처리</td>
<td>평균 대기 시간 최소화</td>
<td>긴 작업 지연 (Starvation)</td>
</tr>
<tr>
<td><strong>Round Robin</strong></td>
<td>선점형</td>
<td>일정 시간 할당, 순환 실행</td>
<td>공정성, 응답 시간 개선</td>
<td>과도한 컨텍스트 스위치 가능</td>
</tr>
<tr>
<td><strong>Priority</strong></td>
<td>둘 다 가능</td>
<td>높은 우선순위 먼저 실행</td>
<td>중요한 작업 우선 처리</td>
<td>낮은 우선순위 작업 무시 위험</td>
</tr>
<tr>
<td><strong>Multilevel</strong></td>
<td>상황에 따라</td>
<td>프로세스 분류 및 다중 큐 사용</td>
<td>특성별 최적화 가능</td>
<td>구현 복잡</td>
</tr>
</tbody></table>
<h2 id="정리하자면">정리하자면</h2>
<p>✅ <strong>CPU 스케줄링은 시스템 성능과 사용자 경험에 직결됩니다.</strong></p>
<p>✅ <strong>공정성, 빠른 응답, 처리량</strong>을 모두 고려해 적절한 알고리즘 선택이 중요!</p>
<p>✅ <strong>실생활 비유:</strong></p>
<p>• <strong>FCFS:</strong> 식당 줄 서기</p>
<p>• <strong>Round Robin:</strong> 놀이공원 회전목마</p>
<p>• <strong>Priority:</strong> VIP 고객 우선 입장</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[큐(Queue)와 해시(Hash)]]></title>
            <link>https://velog.io/@taeyul_de/%ED%81%90Queue%EC%99%80-%ED%95%B4%EC%8B%9CHash</link>
            <guid>https://velog.io/@taeyul_de/%ED%81%90Queue%EC%99%80-%ED%95%B4%EC%8B%9CHash</guid>
            <pubDate>Tue, 25 Feb 2025 16:49:05 GMT</pubDate>
            <description><![CDATA[<h2 id="큐queue"><strong>큐(Queue)</strong></h2>
<p>JS 엔진은 큐를 가지고있다. 
JS 동작원리 중 스택을 실행 하기 위해 큐를 사용한다.(Callback Queue)</p>
<p>데이터를 순차적으로 처리함. 
사용 예로는 티켓예매 사이트를 예로 들수있다
티켓을 예매하기 위해 우선적으로 예매 버튼을 클릭한 사람에게 판매할수있는..? 
선입선출 (FIFO)!!</p>
<h3 id="1️⃣-shift-메서드-사용하기">1️⃣ <strong>shift() 메서드 사용하기</strong></h3>
<ul>
<li><strong>shift()</strong> 메서드는 배열의 첫 번째 요소를 제거하고 반환한다.</li>
<li>큐의 <strong>dequeue</strong> 동작과 동일한 원리.</li>
</ul>
<pre><code class="language-javascript">const queue = [1, 2, 3, 4];
console.log(queue.shift()); // 1 (제거된 값)
console.log(queue); // [2, 3, 4]</code></pre>
<p>✅ <strong>장점:</strong> 간단하고 코드가 직관적임<br>⚠️ <strong>단점:</strong> 배열 요소 이동으로 시간 복잡도 O(n)</p>
<hr>
<h3 id="2️⃣-배열을-이용하는-방식">2️⃣ <strong>배열을 이용하는 방식</strong></h3>
<ul>
<li>큐를 배열로 구현할 때 <strong>push()</strong> 와 <strong>shift()</strong> 를 사용한다.</li>
<li><strong>삽입:</strong> push() – O(1)</li>
<li><strong>삭제:</strong> shift() – O(n) (앞의 요소들이 한 칸씩 이동해야 함)</li>
</ul>
<pre><code class="language-javascript">class Queue {
  constructor() {
    this.items = [];
  }

  enqueue(element) {
    this.items.push(element);
  }

  dequeue() {
    return this.items.shift();
  }

  front() {
    return this.items[0];
  }

  isEmpty() {
    return this.items.length === 0;
  }
}</code></pre>
<p>✅ <strong>장점:</strong> 코드가 간단하고 이해하기 쉬움<br>⚠️ <strong>단점:</strong> 대규모 데이터 처리 시 비효율적</p>
<hr>
<h3 id="3️⃣-연결-리스트를-이용하는-방식">3️⃣ <strong>연결 리스트를 이용하는 방식</strong></h3>
<ul>
<li><strong>연결 리스트(Linked List)</strong> 를 사용하면 <strong>shift()</strong> 시 발생하는 문제를 해결할 수 있다.</li>
<li>삽입과 삭제 모두 O(1)의 시간 복잡도를 가진다.</li>
</ul>
<pre><code class="language-javascript">class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
  }
}

class LinkedListQueue {
  constructor() {
    this.front = null;
    this.rear = null;
  }

  enqueue(value) {
    const newNode = new Node(value);
    if (!this.front) this.front = newNode;
    else this.rear.next = newNode;
    this.rear = newNode;
  }

  dequeue() {
    if (!this.front) return null;
    const value = this.front.value;
    this.front = this.front.next;
    if (!this.front) this.rear = null;
    return value;
  }
}</code></pre>
<p>✅ <strong>장점:</strong> 삽입과 삭제 시 빠름<br>⚠️ <strong>단점:</strong> 메모리 사용량 증가</p>
<hr>
<h2 id="🔑-해시hash">🔑 <strong>해시(Hash)</strong></h2>
<h3 id="1️⃣-해시의-개념">1️⃣ <strong>해시의 개념</strong></h3>
<ul>
<li><strong>해시(Hash)</strong> 란 데이터를 고정된 크기의 해시 값으로 변환하여 저장하고 빠르게 검색할 수 있는 방법이다.</li>
<li>&quot;사물함 번호로 물건 찾기&quot;와 유사한 개념이다.</li>
</ul>
<hr>
<h3 id="2️⃣-해시의-특징">2️⃣ <strong>해시의 특징</strong></h3>
<ul>
<li><strong>빠른 검색:</strong> 평균 O(1)의 시간 복잡도</li>
<li><strong>효율적인 데이터 관리:</strong> 큰 데이터 집합에서 유용</li>
<li><strong>충돌 발생 가능성:</strong> 서로 다른 키가 같은 해시 값을 가질 수 있음</li>
</ul>
<hr>
<h3 id="3️⃣-해시-함수">3️⃣ <strong>해시 함수</strong></h3>
<ul>
<li>입력 데이터를 고정된 크기의 해시 값으로 변환하는 함수.</li>
<li><strong>좋은 해시 함수의 조건:</strong><ul>
<li>빠른 계산 속도</li>
<li>균등한 값 분포</li>
<li>충돌 최소화</li>
</ul>
</li>
</ul>
<pre><code class="language-javascript">function simpleHash(key, size) {
  let hashValue = 0;
  for (let char of key) {
    hashValue += char.charCodeAt(0);
  }
  return hashValue % size;
}</code></pre>
<hr>
<h3 id="4️⃣-해시-함수를-구현할-때-고려할-내용">4️⃣ <strong>해시 함수를 구현할 때 고려할 내용</strong></h3>
<ul>
<li>해시 충돌 가능성 최소화</li>
<li>계산 속도와 해시 테이블 크기 균형</li>
<li>해시 값의 균등한 분포</li>
</ul>
<hr>
<h3 id="5️⃣-자주-사용하는-해시-함수-알아보기">5️⃣ <strong>자주 사용하는 해시 함수 알아보기</strong></h3>
<ul>
<li><strong>Division Method:</strong> <code>hash = key % tableSize</code></li>
<li><strong>Multiplication Method:</strong> <code>hash = floor((key * A) % 1 * tableSize)</code></li>
<li><strong>JavaScript 내장 함수:</strong> 객체의 속성 접근 시 내부적으로 해시 사용</li>
</ul>
<hr>
<h3 id="6️⃣-충돌-처리">6️⃣ <strong>충돌 처리</strong></h3>
<ul>
<li><strong>충돌(Collision)</strong>: 서로 다른 두 입력이 같은 해시 값을 가질 때 발생한다.</li>
<li>해결 방법:<ul>
<li><strong>체이닝(Chaining)</strong></li>
<li><strong>개방 주소법(Open Addressing)</strong></li>
</ul>
</li>
</ul>
<hr>
<h3 id="7️⃣-체이닝으로-처리하기">7️⃣ <strong>체이닝으로 처리하기</strong></h3>
<ul>
<li>같은 인덱스에 여러 값을 <strong>연결 리스트</strong>로 저장한다.</li>
<li>간단하고 구현이 쉬움</li>
</ul>
<pre><code class="language-javascript">class HashTable {
  constructor(size = 50) {
    this.table = new Array(size);
  }

  hash(key) {
    let hashValue = 0;
    for (let char of key) {
      hashValue += char.charCodeAt(0);
    }
    return hashValue % this.table.length;
  }

  set(key, value) {
    const index = this.hash(key);
    if (!this.table[index]) {
      this.table[index] = [];
    }
    this.table[index].push([key, value]);
  }

  get(key) {
    const index = this.hash(key);
    if (this.table[index]) {
      for (let [storedKey, value] of this.table[index]) {
        if (storedKey === key) return value;
      }
    }
    return undefined;
  }
}</code></pre>
<p>✅ <strong>장점:</strong> 충돌 처리 시 연결 리스트 사용으로 유연함<br>⚠️ <strong>단점:</strong> 추가 메모리 사용</p>
<hr>
<h3 id="8️⃣-개방-주소-법으로-처리하기">8️⃣ <strong>개방 주소 법으로 처리하기</strong></h3>
<ul>
<li>충돌 발생 시 <strong>빈 인덱스</strong>를 찾아 데이터를 저장.</li>
<li>방식 종류:<ul>
<li><strong>선형 탐사(Linear Probing):</strong> 한 칸씩 이동하며 탐색</li>
<li><strong>이차 탐사(Quadratic Probing):</strong> 일정한 간격으로 탐색</li>
<li><strong>더블 해싱(Double Hashing):</strong> 두 번째 해시 함수를 사용</li>
</ul>
</li>
</ul>
<pre><code class="language-javascript">class OpenAddressHashTable {
  constructor(size = 50) {
    this.table = new Array(size).fill(null);
  }

  hash(key) {
    let hashValue = 0;
    for (let char of key) {
      hashValue += char.charCodeAt(0);
    }
    return hashValue % this.table.length;
  }

  set(key, value) {
    let index = this.hash(key);
    while (this.table[index] !== null) {
      index = (index + 1) % this.table.length; // 선형 탐사
    }
    this.table[index] = [key, value];
  }

  get(key) {
    let index = this.hash(key);
    while (this.table[index] !== null) {
      if (this.table[index][0] === key) return this.table[index][1];
      index = (index + 1) % this.table.length;
    }
    return undefined;
  }
}</code></pre>
<p>✅ <strong>장점:</strong> 추가 데이터 구조 필요 없음<br>⚠️ <strong>단점:</strong> 탐색 시간 증가 가능성</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[JS의 중요한 세 가지 기둥]]></title>
            <link>https://velog.io/@taeyul_de/JS%EC%9D%98-%EC%A4%91%EC%9A%94%ED%95%9C-%EC%84%B8-%EA%B0%80%EC%A7%80-%EA%B8%B0%EB%91%A5</link>
            <guid>https://velog.io/@taeyul_de/JS%EC%9D%98-%EC%A4%91%EC%9A%94%ED%95%9C-%EC%84%B8-%EA%B0%80%EC%A7%80-%EA%B8%B0%EB%91%A5</guid>
            <pubDate>Thu, 20 Feb 2025 10:12:21 GMT</pubDate>
            <description><![CDATA[<p>자바스크립트를 이해하는 데 중요한 세 가지 기둥은 <strong>스코프와 클로저, 프로토타입, 그리고 타입과 타입 강제 변환</strong>이다.
이 개념들을 제대로 이해하면 <strong>코드의 작동 방식</strong>을 훨씬 깊이 이해할 수 있다.</p>
<h2 id="첫-번째-기둥-스코프와-클로저"><strong>첫 번째 기둥: 스코프와 클로저</strong></h2>
<blockquote>
<p><strong>스코프(Scope)</strong></p>
</blockquote>
<p>스코프는 <strong>변수에 접근할 수 있는 범위</strong>를 의미한다.</p>
<p><strong>양동이</strong> = 스코프 
<strong>구슬</strong> = 변수</p>
<p>• 양동이(스코프)에 구슬(변수)을 넣어둔다.
• 특정 구슬을 찾으려면 <strong>같은 색의 양동이부터 찾는다.</strong></p>
<pre><code class="language-javascript">let globalBall = &quot;전역 구슬&quot;; // 전역 스코프 양동이

function outerBucket() {
  let outerBall = &quot;바깥 양동이 구슬&quot;; // 함수 스코프 양동이

  function innerBucket() {
    let innerBall = &quot;안쪽 양동이 구슬 &quot;; // 내부 양동이
    console.log(globalBall); //  찾음!
    console.log(outerBall);  //  찾음!
    console.log(innerBall);  //  찾음!
  }

  innerBucket();
}

outerBucket();</code></pre>
<p>✅ <strong>중요 포인트:</strong></p>
<p>• 내부 양동이(스코프)는 <strong>바깥 양동이 구슬을 쉽게 찾을 수 있지만</strong>,
• 바깥 양동이는 <strong>내부 양동이 구슬을 못 찾는다</strong></p>
<hr>
<blockquote>
<p><strong>렉시컬 스코프(Lexical Scope)</strong></p>
</blockquote>
<p>스코프는 <strong>함수가 정의될 때</strong> 결정.</p>
<p><strong>“함수가 어디서 작성됐는지”</strong> 가 중요하지, <strong>“어디서 호출됐는지”</strong> 는 중요하지 않다.</p>
<p>함수를 <strong>건물 설계도</strong> 에 비유해보면</p>
<p>• 설계도를 만든 위치에서 <strong>어떤 방을 연결할지</strong> 미리 결정하고</p>
<p>• 나중에 어디서 불러도 <strong>이미 설계된 대로만</strong> 연결하면 된다.</p>
<pre><code class="language-javascript">const outerCode = &quot;외부 코드 &quot;;

function outer() {
  const innerCode = &quot;내부 코드 &quot;;

  function inner() {
    console.log(outerCode); //  접근 가능 (설계도에서 연결)
    console.log(innerCode); //  접근 가능
  }

  inner();
}

outer();</code></pre>
<p>✅ <strong>중요 포인트:</strong></p>
<p>• inner 함수는 <strong>outer에서 정의됐기 때문에 outerCode에 접근 가능</strong></p>
<p>• 어디서 호출하든 <strong>함수가 만들어질 때의 스코프가 중요</strong></p>
<hr>
<blockquote>
<p><strong>클로저(Closure)</strong></p>
</blockquote>
<p>클로저는 <strong>함수가 외부 변수(환경)를 기억해서 나중에도 사용할 수 있는 기능</strong>이다.</p>
<p>스코프가 <strong>일시적인 양동이</strong>라면,
클로저는 <strong>양동이를 집에 영구적으로 보관</strong>하는 것과 같다.</p>
<p>엄마가 <strong>냉장고에 메모를 붙여 놨을때</strong></p>
<p>“우유 사와!” </p>
<p>• 냉장고(함수)에 메모(변수)를 붙이면
• <strong>엄마가 집을 나가도 메모는 남아있음.</strong></p>
<p>클로저도 똑같다</p>
<p><strong>함수 실행 후에도 외부 변수를 기억</strong>하고 있다가 <strong>필요할 때 꺼내 쓸 수 있음.</strong></p>
<p><strong>다른 예로 비밀 금고에 비유 할 수 있다</strong></p>
<pre><code class="language-javascript">function safe() {
  let secret = &quot;비밀 코드 🔐&quot;; // 외부 변수

  return function revealSecret() {
    console.log(`비밀은 ${secret}입니다!`);
  };
}

const openSafe = safe(); // 금고 열쇠 받기
openSafe(); // &quot;비밀은 🔐입니다!&quot;</code></pre>
<p>✅ <strong>중요 포인트:</strong></p>
<p>• secret 변수는 외부에서 접근 못한다.</p>
<p>• <strong>금고 열쇠(openSafe)</strong> 를 통해서만 비밀을 열 수 있다.</p>
<p><strong>클로저 실전 예시: 카운터 만들기</strong></p>
<pre><code class="language-javascript">function makeCounter() {
  let count = 0; // 외부 변수 (초기값 저장)

  return function () {
    count += 1; // 외부 변수 접근
    return count;
  };
}

const counter = makeCounter();

console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3</code></pre>
<p>✅ <strong>왜 유용할까?</strong></p>
<p>• <strong>데이터 보호:</strong> 외부에서 count를 직접 변경 못함
• <strong>상태 유지:</strong> 함수 호출마다 <strong>값을 기억하고 누적</strong></p>
<hr>
<h2 id="두-번째-기둥-프로토타입prototype"><strong>두 번째 기둥: 프로토타입(Prototype)</strong></h2>
<blockquote>
<p><strong>프로토타입이란?</strong></p>
</blockquote>
<p>자바스크립트는 <strong>클래스 없이도 객체를 만들고 상속할 수 있는 몇 안되는 언어라고 한다.</strong></p>
<p>모든 객체는 <strong>프로토타입이라는 레시피 책(프로토타입 체인)</strong>을 갖고 있다.</p>
<p>객체에 없는 기능을 찾을 때, <strong>레시피 책(프로토타입 체인)</strong>에서 찾아서 사용한다.</p>
<p><strong>예를 들어 요리사와 레시피 책</strong></p>
<p>• 나(객체)는 쿠키를 만들고 싶은데 방법을 모른다.
• 레시피 책(프로토타입)에 bake 만드는 법이 있다.
• 나는 책을 보고 <strong>구워낼 수 있다</strong> </p>
<p><strong>💻 코드 예시</strong></p>
<pre><code class="language-javascript">function CookieMaker(flavor) {
  this.flavor = flavor; // 쿠키 맛
}

// 🍪 쿠키 굽기 레시피 추가!
CookieMaker.prototype.bake = function () {
  console.log(`${this.flavor} 쿠키 완성! 🍪`);
};

const chocoCookie = new CookieMaker(&quot;초코&quot;);
chocoCookie.bake(); // &quot;초코 쿠키 완성! 🍪&quot;</code></pre>
<p>✅ <strong>작동 원리:</strong></p>
<p>• chocoCookie는 bake 메서드를 모른다.</p>
<p>• <strong>CookieMaker.prototype</strong>(레시피 책)을 찾아서 사용</p>
<br/>

<p><strong>다른 예로 유전자 상속이 있다.</strong></p>
<p>• 부모(프로토타입) → “운전 가능” 유전자 보유</p>
<p>• 나(객체) → 운전 못 배웠지만 <strong>유전자 덕에 운전 가능</strong></p>
<pre><code class="language-javascript">const parent = { canDrive: true };
const child = Object.create(parent);

console.log(child.canDrive); // true (부모한테 상속받음!)</code></pre>
<p>✅ <strong>중요:</strong></p>
<p>• <strong>프로토타입 체인</strong>을 통해 <strong>속성이나 메서드를 상속</strong></p>
<p>• 찾을 때까지 부모 → 조부모 → 최상위까지 올라감</p>
<hr>
<h2 id="🔄-세-번째-기둥-타입과-타입-강제-변환"><strong>🔄 세 번째 기둥: 타입과 타입 강제 변환</strong></h2>
<blockquote>
<p><strong>타입(Type)이란?</strong></p>
</blockquote>
<p>값의 <strong>데이터 종류</strong>를 뜻한다.</p>
<p>• 숫자: 123
• 문자열: &quot;hello&quot;
• 불린: true / false</p>
<blockquote>
<p><strong>타입 강제 변환(Type Coercion)</strong></p>
</blockquote>
<p>자바스크립트는 <strong>필요할 때 알아서 타입을 변환해준다.</strong></p>
<p>이게 바로 <strong>암시적 변환(자동 변환)</strong>이다.</p>
<br/>

<p><strong>예를 들어 만능 요리사 vs 실수 많은 점원</strong></p>
<p><strong>만능 요리사 (암시적 변환)</strong></p>
<p>내가 “밥 + 물” 요청하면
= <strong>죽 만들어줌</strong> 🍚+💧=🥣</p>
<pre><code class="language-javascript">&quot;5&quot; + 2; // &quot;52&quot; (문자열 붙이기)
&quot;5&quot; - 2; // 3 (숫자 계산 필요 → 숫자로 변환)
true + 1; // 2 (true → 1 변환)</code></pre>
<p>✅ <strong>중요 포인트:</strong></p>
<p>• <strong>+ 연산자는 문자열이면 문자 붙이기</strong>
• <strong>- 연산자는 숫자 계산을 위해 변환</strong></p>
<p><strong>실수 많은 점원 (헷갈리는 변환)</strong></p>
<pre><code class="language-javascript">&quot;5&quot; == 5;  // true (자동 변환!)
&quot;5&quot; === 5; // false (타입까지 비교!)</code></pre>
<p>✅ <strong>비교할 때는?</strong></p>
<p>== : 대충 맞으면 같다고 판단</p>
<p>=== : <strong>타입과 값 모두 비교</strong> (안전 추천)</p>
<p><strong>명시적 변환 (직접 변환)</strong></p>
<pre><code class="language-javascript">Number(&quot;123&quot;); // 123
String(456);   // &quot;456&quot;
Boolean(0);    // false</code></pre>
<p>✅ <strong>포인트:</strong></p>
<p><strong>명시적 변환을 사용하면 에러 방지 가능</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[동기화와 교착상태]]></title>
            <link>https://velog.io/@taeyul_de/%EB%8F%99%EA%B8%B0%ED%99%94%EC%99%80-%EA%B5%90%EC%B0%A9%EC%83%81%ED%83%9C</link>
            <guid>https://velog.io/@taeyul_de/%EB%8F%99%EA%B8%B0%ED%99%94%EC%99%80-%EA%B5%90%EC%B0%A9%EC%83%81%ED%83%9C</guid>
            <pubDate>Tue, 18 Feb 2025 12:08:47 GMT</pubDate>
            <description><![CDATA[<h2 id="동기화와-교착-상태">동기화와 교착 상태</h2>
<p>컴퓨터 시스템에서 여러 개의 프로세스나 스레드가 <strong>공유 자원</strong>에 동시에 접근하는 상황은 흔히 발생한다. 이때 <strong>데이터의 일관성</strong>과 <strong>프로그램의 안정성</strong>을 유지하기 위해 <strong>동기화</strong>라는 개념이 필요하며, 이와 관련된 문제점인 <strong>교착 상태</strong>에 대해 알아보자.</p>
<h3 id="1-동기화-synchronization">1. 동기화 (Synchronization)</h3>
<ul>
<li><strong>정의:</strong> 여러 개의 프로세스 또는 스레드가 공유 자원에 <strong>동시에 접근하는 것을 방지</strong>하고, <strong>실행 순서를 제어</strong>하여 데이터의 일관성을 유지하는 것을 의미한다.</li>
<li><strong>목적:*</strong><ul>
<li><strong>데이터 일관성 유지:</strong> 공유 데이터가 여러 프로세스/스레드에 의해 동시에 변경되는 경우 발생할 수 있는 데이터 불일치 문제를 해결.</li>
<li><strong>경쟁 조건 방지:</strong> 여러 프로세스/스레드가 공유 자원을 차지하기 위해 경쟁하는 상황에서 예상치 못한 결과를 방지.</li>
<li><strong>프로세스/스레드 협력:</strong> 여러 프로세스/스레드가 특정 작업을 함께 수행해야 할 때, 실행 순서를 조절하여 효율적인 협업을 가능하게 한다.</li>
</ul>
</li>
</ul>
<h3 id="2-교착-상태-deadlock">2. 교착 상태 (Deadlock)</h3>
<ul>
<li><strong>정의:</strong> 두 개 이상의 프로세스 또는 스레드가 <strong>서로 필요한 자원을 점유</strong>하고 <strong>상대방의 자원 반납을 기다리는 상태</strong>를 의미.</li>
<li><strong>발생 조건:*</strong><ul>
<li><strong>상호 배제 (Mutual Exclusion):</strong> 공유 자원은 한 번에 하나의 프로세스/스레드만 사용할 수 있다.</li>
<li><strong>점유 및 대기 (Hold and Wait):</strong> 프로세스/스레드가 자원을 점유한 상태에서 다른 자원을 기다린다.</li>
<li><strong>비선점 (No Preemption):</strong> 프로세스/스레드가 점유한 자원을 강제로 빼앗을 수 없다.</li>
<li><strong>순환 대기 (Circular Wait):</strong> 프로세스/스레드들이 서로의 자원을 요구하며 순환 형태로 대기한다.</li>
</ul>
</li>
<li><strong>문제점:*</strong><ul>
<li><strong>시스템 멈춤:</strong> 교착 상태에 빠진 프로세스/스레드들은 작업을 진행하지 못하고, 시스템 전체가 멈추는 상황이 발생할 수 있다.</li>
<li><strong>자원 낭비:</strong> 교착 상태에 빠진 프로세스/스레드들이 점유한 자원은 다른 프로세스/스레드들이 사용할 수 없게 되어 자원 낭비가 발생한다.</li>
</ul>
</li>
</ul>
<h3 id="3-동기화-기법">3. 동기화 기법</h3>
<ul>
<li><strong>뮤텍스 (Mutex):</strong> 공유 자원에 대한 접근을 제한하는 잠금 메커니즘이다.</li>
<li><strong>세마포어 (Semaphore):</strong> 공유 자원에 접근할 수 있는 프로세스/스레드의 수를 제한하는 카운터다.</li>
<li><strong>모니터 (Monitor):</strong> 공유 자원과 이를 접근하는 함수들을 묶어 관리하는 동기화 기법이다.</li>
</ul>
<h3 id="4-교착-상태-해결-방법">4. 교착 상태 해결 방법</h3>
<ul>
<li><strong>교착 상태 예방:</strong> 교착 상태 발생 조건을 사전에 제거한다. (예: 상호 배제 조건 완화, 점유 및 대기 방지 등)</li>
<li><strong>교착 상태 회피:</strong> 시스템의 상태를 감시하며 교착 상태 발생 가능성이 있는 자원 할당을 피한다. (예: 은행원 알고리즘)</li>
<li><strong>교착 상태 탐지 및 복구:</strong> 교착 상태 발생 여부를 탐지하고, 관련된 프로세스/스레드를 강제 종료하거나 자원을 선점하여 교착 상태를 해결한다.</li>
</ul>
<h3 id="결론">결론</h3>
<p>동기화는 멀티 프로세스/스레드 환경에서 데이터 일관성을 유지하고 프로그램의 안정성을 높이는 데 필수적인 개념이다. 하지만 잘못된 동기화는 교착 상태를 유발할 수 있으므로, 동기화 기법을 올바르게 이해하고 사용하는 것이 중요하다.</p>
<hr>
<h2 id="세마포">세마포</h2>
<p><strong>세마포</strong>는 컴퓨터 시스템에서 여러 프로세스나 스레드가 <strong>공유 자원</strong>에 접근할 때, <strong>접근 가능한 개수를 제한</strong>하는 동기화 기법이다. 마치 <strong>주차장의 주차 가능 대수</strong>와 비슷하다고 생각하면 된다.</p>
<h3 id="핵심-개념">핵심 개념</h3>
<ul>
<li><strong>카운터</strong>: 세마포는 <strong>정수 값</strong>을 가지는 카운터로, 공유 자원에 접근 가능한 프로세스/스레드의 수를 나타낸다.</li>
<li><strong>P 연산 (wait):</strong> 프로세스/스레드가 공유 자원에 접근하려고 할 때, 세마포 카운터 값을 <strong>1 감소</strong>시킨다. 만약 카운터 값이 0이라면, 해당 프로세스/스레드는 <strong>대기</strong>한다.</li>
<li><strong>V 연산 (signal):</strong> 프로세스/스레드가 공유 자원 사용을 마치면, 세마포 카운터 값을 <strong>1 증가</strong>시킨다. 대기 중인 프로세스/스레드가 있다면, 그중 하나를 깨워 공유 자원에 접근할 수 있도록 한다.</li>
</ul>
<h3 id="작동-방식">작동 방식</h3>
<ol>
<li><strong>세마포 초기화:</strong> 공유 자원에 접근 가능한 최대 개수로 세마포 카운터를 초기화한다.</li>
<li><strong>P 연산:</strong> 프로세스/스레드가 공유 자원에 접근하기 전에 P 연산을 수행한다.</li>
<li><strong>공유 자원 접근:</strong> P 연산 후, 해당 프로세스/스레드는 공유 자원에 접근하여 작업을 수행한다.</li>
<li><strong>V 연산:</strong> 공유 자원 사용을 마치면 V 연산을 수행하여 세마포 카운터를 증가시킨다.</li>
</ol>
<h3 id="종류">종류</h3>
<ul>
<li><strong>이진 세마포 (Binary Semaphore):</strong> 카운터 값이 0 또는 1인 세마포이다. 주로 <strong>뮤텍스</strong>와 같이 상호 배제를 구현하는 데 사용된다.</li>
<li><strong>계수 세마포 (Counting Semaphore):</strong> 카운터 값이 1 이상인 세마포이다. <strong>유한한 자원</strong>의 개수를 관리하는 데 사용된다.</li>
</ul>
<h3 id="장점">장점</h3>
<ul>
<li><strong>간단함:</strong> 이해하고 구현하기 쉽다.</li>
<li><strong>유연성:</strong> 다양한 상황에 맞게 카운터 값을 조절하여 사용할 수 있다.</li>
<li><strong>효율성:</strong> 대기 큐를 사용하여 자원 접근을 효율적으로 관리한다.</li>
</ul>
<h3 id="단점">단점</h3>
<ul>
<li><strong>데드락 가능성:</strong> 잘못된 세마포 사용은 데드락을 유발할 수 있다.</li>
<li><strong>우선순위 역전:</strong> 우선순위가 낮은 프로세스/스레드가 자원을 독점하여 우선순위가 높은 프로세스/스레드가 대기하는 상황이 발생할 수 있다.</li>
</ul>
<h3 id="활용-예시">활용 예시</h3>
<ul>
<li><strong>프린터 공유:</strong> 여러 대의 컴퓨터가 한 대의 프린터를 공유할 때, 세마포어를 사용하여 프린터 접근을 제한할 수 있다.</li>
<li><strong>데이터베이스 연결:</strong> 제한된 수의 데이터베이스 연결을 여러 사용자가 공유할 때, 세마포어를 사용하여 동시 접속자 수를 제한할 수 있다.</li>
</ul>
<h3 id="결론-1">결론</h3>
<p>세마포는 공유 자원 접근을 효율적으로 관리하고 동기화 문제를 해결하는 데 유용한 도구이다. 하지만 데드락 및 우선순위 역전과 같은 문제점을 야기할 수 있으므로, 세마포 사용 시 주의해야 한다.</p>
<hr>
<h2 id="조건-변수-모니터-스레드-안전">조건 변수, 모니터, 스레드 안전</h2>
<h3 id="1-조건-변수-condition-variable">1. 조건 변수 (Condition Variable)</h3>
<ul>
<li><strong>정의:</strong> 특정 조건이 만족될 때까지 스레드를 대기시키거나, 대기 중인 스레드를 깨우는 데 사용되는 동기화 기법이다.</li>
<li><strong>역할:</strong> 공유 자원에 대한 접근 순서를 제어하고, 스레드 간 협력을 효율적으로 관리한다.</li>
<li><strong>메커니즘:</strong><ul>
<li><strong>wait():</strong> 스레드를 대기 상태로 만들고, 조건 변수에 연결된 뮤텍스를 해제한다.</li>
<li><strong>signal():</strong> 대기 중인 스레드 중 하나를 깨운다.</li>
<li><strong>broadcast():</strong> 대기 중인 모든 스레드를 깨운다.</li>
</ul>
</li>
<li><strong>사용 예시:</strong> 생산자-소비자 문제에서, 소비자는 큐가 비어있으면 대기하고, 생산자는 큐에 데이터를 추가하면 대기 중인 소비자를 깨운다.</li>
</ul>
<h3 id="2-모니터-monitor">2. 모니터 (Monitor)</h3>
<ul>
<li><strong>정의:</strong> 공유 자원과 해당 자원에 대한 접근을 제어하는 함수들을 묶어 관리하는 동기화 기법이다.</li>
<li><strong>특징:</strong><ul>
<li><strong>상호 배제:</strong> 모니터 내에서는 한 번에 하나의 스레드만 접근할 수 있다.</li>
<li><strong>조건 변수:</strong> 모니터 내에서 조건 변수를 사용하여 스레드 간 동기화를 구현한다.</li>
</ul>
</li>
<li><strong>구현:</strong><ul>
<li><strong>뮤텍스:</strong> 공유 자원에 대한 접근을 제한하는 잠금 역할을 한다.</li>
<li><strong>조건 변수:</strong> 특정 조건이 충족될 때까지 스레드를 대기시키거나 깨우는 역할을 한다.</li>
</ul>
</li>
<li><strong>장점:</strong><ul>
<li><strong>안전성:</strong> 공유 자원에 대한 동시 접근을 방지하여 데이터 일관성을 유지한다.</li>
<li><strong>편의성:</strong> 모니터 내에서 동기화 관련 코드를 캡슐화하여 코드의 가독성과 유지 보수성을 높인다.</li>
</ul>
</li>
</ul>
<h3 id="3-스레드-안전-thread-safety">3. 스레드 안전 (Thread Safety)</h3>
<ul>
<li><strong>정의:</strong> 여러 개의 스레드가 공유 자원에 동시에 접근해도 데이터 손상이나 예기치 않은 오류 없이 프로그램이 정상적으로 동작하는 것을 의미한다.</li>
<li><strong>조건:</strong><ul>
<li><strong>경쟁 조건 (Race Condition) 방지:</strong> 여러 스레드가 공유 자원에 동시에 접근하여 결과를 예측할 수 없는 상황을 방지한다.</li>
<li><strong>원자성 (Atomicity) 보장:</strong> 특정 작업이 중간에 중단되지 않고 완벽하게 수행되도록 보장한다.</li>
<li><strong>가시성 (Visibility) 확보:</strong> 스레드 간 변경된 데이터가 서로에게 제대로 반영되도록 보장한다.</li>
</ul>
</li>
<li><strong>스레드 안전한 코드 작성 방법:</strong><ul>
<li><strong>뮤텍스/세마포어 사용:</strong> 공유 자원에 대한 접근을 제한한다.</li>
<li><strong>불변 객체 (Immutable Object) 사용:</strong> 값이 변경되지 않는 객체를 사용하여 동시 접근 문제를 방지한다.</li>
<li><strong>스레드 로컬 저장소 (Thread-Local Storage) 사용:</strong> 각 스레드마다 독립적인 저장 공간을 제공하여 공유 자원 접근을 최소화한다.</li>
</ul>
</li>
</ul>
<h3 id="핵심-요약">핵심 요약</h3>
<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>여러 스레드가 공유 자원에 동시에 접근해도 프로그램이 정상적으로 동작하는 것</td>
</tr>
</tbody></table>
<h3 id="결론-2">결론</h3>
<p>조건 변수, 모니터, 스레드 안전은 멀티 스레드 환경에서 공유 자원을 안전하게 관리하고 프로그램의 안정성을 높이는 데 필수적인 개념이다. 이러한 개념들을 제대로 이해하고 활용하여 안전하고 효율적인 프로그램을 개발할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로세스와 스레드, 그리고 운영체제의 역할]]></title>
            <link>https://velog.io/@taeyul_de/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EC%8A%A4%EB%A0%88%EB%93%9C-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EC%9D%98-%EC%97%AD%ED%95%A0</link>
            <guid>https://velog.io/@taeyul_de/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EC%8A%A4%EB%A0%88%EB%93%9C-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EC%9D%98-%EC%97%AD%ED%95%A0</guid>
            <pubDate>Tue, 18 Feb 2025 12:06:48 GMT</pubDate>
            <description><![CDATA[<h3 id="1-프로세스-및-스레드-관리"><strong>1. 프로세스 및 스레드 관리</strong></h3>
<p><strong>프로세스(Process)와 스레드(Thread)의 개념</strong></p>
<p>• <strong>프로세스(Process)</strong>: 실행 중인 프로그램의 인스턴스이다.
• <strong>스레드(Thread)</strong>: 프로세스 내부에서 실행되는 <strong>작업의 흐름</strong>으로, 여러 스레드가 하나의 프로세스 내에서 동작할 수 있다.</p>
<br/>


<p><strong>주요 역할</strong></p>
<ol>
<li><strong>프로세스 생성과 종료</strong></li>
</ol>
<p>• 새로운 프로그램 실행 시 <strong>운영체제(OS)</strong>가 프로세스를 생성하고, 종료 시 자원을 반환한다.</p>
<ol start="2">
<li><strong>프로세스 상태 관리</strong></li>
</ol>
<p>• 실행(Running), 준비(Ready), 대기(Waiting) 등의 상태를 관리한다.</p>
<ol start="3">
<li><strong>프로세스 스케줄링</strong></li>
</ol>
<p>• CPU를 효율적으로 사용하기 위해 <strong>어떤 프로세스를 실행할지 결정</strong>한다.</p>
<ol start="4">
<li><strong>문맥 교환(Context Switching)</strong></li>
</ol>
<p>• CPU가 다른 프로세스로 전환될 때 <strong>CPU 레지스터와 메모리 상태를 저장하고 복원</strong>한다.</p>
<hr>
<br/>

<h3 id="2-자원-할당-및-관리"><strong>2. 자원 할당 및 관리</strong></h3>
<p>운영체제는 <strong>컴퓨터 자원(CPU, 메모리, 디스크 등)을 각 프로세스가 원활하게 사용할 수 있도록 할당하고 회수</strong>한다.</p>
<p>자원을 효율적으로 나누어 사용하도록 관리하여 <strong>성능을 최적화</strong>한다.</p>
<hr>
<br/>

<h3 id="3-cpu-관리-cpu-스케줄링"><strong>3. CPU 관리: CPU 스케줄링</strong></h3>
  <br/>

<h4 id="cpu-스케줄링이란"><strong>CPU 스케줄링이란?</strong></h4>
<p>CPU 스케줄링은 <strong>운영체제가 어떤 프로세스에게 CPU를 할당할지 결정하는 과정</strong>이다.</p>
<p>컴퓨터 시스템의 효율성을 극대화하고 사용자에게 빠른 응답성을 제공하는 것이 목표이다.</p>
  <br/>

<h4 id="cpu-스케줄링의-중요성"><strong>CPU 스케줄링의 중요성</strong></h4>
<br/>

<blockquote>
<p><strong>시스템 효율성 향상</strong></p>
</blockquote>
<pre><code>• CPU가 유휴 상태로 낭비되는 시간을 최소화하고, 최대한 많은 프로세스를 처리하여 전체 시스템의 효율성을 높인다.</code></pre><blockquote>
<p><strong>사용자 응답성 향상</strong></p>
</blockquote>
<pre><code>• 사용자의 요청에 빠르게 응답하여 사용자 경험을 개선한다.</code></pre><blockquote>
<p><strong>공정성 확보</strong></p>
</blockquote>
<pre><code>• 모든 프로세스에게 공평하게 CPU 사용 기회를 제공하여 특정 프로세스가 불이익을 받지 않도록 한다.</code></pre><br/>


<p><strong>주요 CPU 스케줄링 알고리즘</strong></p>
<table>
<thead>
<tr>
<th><strong>알고리즘</strong></th>
<th><strong>설명</strong></th>
<th><strong>장점</strong></th>
<th><strong>단점</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>FCFS (First Come, First Served)</strong></td>
<td>먼저 도착한 프로세스부터 CPU를 할당하는 방식</td>
<td>구현이 간단하고 공정하다</td>
<td>긴 작업이 짧은 작업을 기다리게 되어 비효율적일 수 있다 (Convoy Effect)</td>
</tr>
<tr>
<td><strong>SJF (Shortest Job First)</strong></td>
<td>실행 시간이 가장 짧은 프로세스부터 CPU를 할당하는 방식</td>
<td>평균 대기 시간을 최소화할 수 있다</td>
<td>실행 시간을 미리 예측하기 어렵다</td>
</tr>
<tr>
<td><strong>RR (Round Robin)</strong></td>
<td>모든 프로세스에게 일정한 시간(타임 슬라이스) 동안 CPU를 할당하는 방식</td>
<td>응답 시간이 빠르고 공정하다</td>
<td>타임 슬라이스가 너무 짧으면 오버헤드가 증가할 수 있다</td>
</tr>
<tr>
<td><strong>Priority Scheduling</strong></td>
<td>우선순위가 높은 프로세스에게 CPU를 먼저 할당하는 방식</td>
<td>중요한 작업을 먼저 실행할 수 있다</td>
<td>낮은 우선순위의 프로세스가 계속 대기할 수 있음 (기아 상태)</td>
</tr>
</tbody></table>
<p> <strong>운영체제는 상황에 따라 적절한 스케줄링 알고리즘을 선택하여 사용한다.</strong></p>
<hr>
 <br/>

<h3 id="4-멀티-프로세스와-멀티-스레드"><strong>4. 멀티 프로세스와 멀티 스레드</strong></h3>
<p>현대 컴퓨터 시스템은 <strong>멀티태스킹</strong>을 통해 여러 작업을 동시에 처리한다.</p>
<p>이때 사용되는 핵심 개념이 <strong>멀티 프로세스</strong>와 <strong>멀티 스레드</strong>이다.</p>
<p>두 방식 모두 동시에 여러 작업을 처리하지만, 작동 방식과 장단점에 차이가 있다.</p>
  <br/>

<p><strong>📌 1. 멀티 프로세스 (Multi-Process)</strong></p>
<p>• <strong>각 프로세스는 독립적인 메모리 공간을 가지며, 서로 간섭 없이 작업을 수행한다.</strong></p>
<p>• <strong>프로세스 간 통신(IPC, Inter-Process Communication)</strong>이 필요할 때, 오버헤드가 발생할 수 있다.</p>
<p>✅ <strong>장점</strong></p>
<p>• <strong>안정성</strong>: 하나의 프로세스가 오류가 나도 다른 프로세스에 영향을 주지 않는다.</p>
<p>• <strong>병렬 처리 가능</strong>: 여러 개의 CPU 코어를 활용하여 작업을 병렬로 실행할 수 있다.</p>
<p>❌ <strong>단점</strong></p>
<p>• <strong>오버헤드 발생</strong>: 프로세스를 생성하고 관리하는 데 많은 비용이 발생한다.</p>
<p>• <strong>자원 사용량 증가</strong>: 독립적인 메모리 공간을 사용하므로 메모리 사용량이 많다.</p>
  <br/>

<p><strong>📌 2. 멀티 스레드 (Multi-Thread)</strong></p>
<p>• 하나의 프로세스 내에서 여러 개의 <strong>스레드를 생성하여 작업을 병렬로 실행</strong>하는 방식이다.</p>
<p>• 모든 스레드는 <strong>공유 메모리 공간을 사용</strong>하므로, 스레드 간 통신이 빠르다.</p>
<p>✅ <strong>장점</strong></p>
<p>• <strong>자원 효율성 증가</strong>: 프로세스 내에서 메모리를 공유하므로 메모리 사용량이 적다.</p>
<p>• <strong>빠른 응답성</strong>: 여러 작업을 동시에 수행할 수 있어 프로그램의 응답성이 향상된다.</p>
<p>❌ <strong>단점</strong></p>
<p>• <strong>안정성 문제</strong>: 하나의 스레드가 오류가 나면 전체 프로세스가 영향을 받을 수 있다.</p>
<p>• <strong>동기화 문제 발생 가능</strong>: 공유 자원에 여러 스레드가 접근하면 <strong>데이터 충돌</strong>이 발생할 수 있다.</p>
<hr>
  <br/>

<p><strong>멀티 프로세스 vs 멀티 스레드 비교</strong></p>
<table>
<thead>
<tr>
<th><strong>구분</strong></th>
<th><strong>멀티 프로세스 (Multi-Process)</strong></th>
<th><strong>멀티 스레드 (Multi-Thread)</strong></th>
</tr>
</thead>
<tbody><tr>
<td>메모리 공간</td>
<td>프로세스마다 독립적인 메모리 사용</td>
<td>모든 스레드가 같은 메모리 공간을 공유</td>
</tr>
<tr>
<td>자원 소모</td>
<td>높음 (프로세스 간 통신 비용 발생)</td>
<td>낮음 (메모리 공유로 오버헤드 적음)</td>
</tr>
<tr>
<td>안정성</td>
<td>높음 (프로세스 간 격리)</td>
<td>낮음 (하나의 스레드 오류가 전체에 영향)</td>
</tr>
<tr>
<td>속도</td>
<td>느림 (프로세스 생성 비용)</td>
<td>빠름 (스레드 전환 비용 적음)</td>
</tr>
</tbody></table>
<p><strong>웹 브라우저, 게임 엔진 등에서는 멀티 스레드를, 서버 관리 등에서는 멀티 프로세스를 활용한다.</strong></p>
<br/>

<h4 id="프로세스-메모리-영역"><strong>프로세스 메모리 영역</strong></h4>
<p>운영체제는 프로세스가 실행될 때 <strong>코드, 데이터, 스택, 힙</strong> 영역으로 메모리를 관리한다.</p>
<table>
<thead>
<tr>
<th><strong>영역</strong></th>
<th><strong>설명</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>코드(Code) 영역</strong></td>
<td>프로그램의 실행 코드(명령어)가 저장되는 공간</td>
</tr>
<tr>
<td><strong>데이터(Data) 영역</strong></td>
<td>전역 변수 및 정적 변수(static 변수)가 저장되는 공간</td>
</tr>
<tr>
<td><strong>스택(Stack) 영역</strong></td>
<td>함수 호출 시 지역 변수와 매개변수가 저장되는 공간 (후입선출 구조)</td>
</tr>
<tr>
<td><strong>힙(Heap) 영역</strong></td>
<td>동적으로 할당된 메모리가 저장되는 공간 (가비지 컬렉터가 자동 관리)</td>
</tr>
</tbody></table>
<p><strong>힙(Heap) 영역을 많이 사용하면 메모리 누수가 발생할 수 있다.</strong></p>
<h3 id="🔥-결론"><strong>🔥 결론</strong></h3>
<p>• <strong>운영체제는 프로세스와 스레드를 관리하며, CPU 스케줄링을 통해 최적의 성능을 제공한다.</strong></p>
<p>• <strong>멀티 프로세스는 안정성이 높고 멀티 스레드는 효율성이 높다.</strong></p>
<p>• <strong>프로세스는 메모리 영역(코드, 데이터, 스택, 힙)을 사용하며, 효율적인 메모리 관리가 필요하다.</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[배열과 스택]]></title>
            <link>https://velog.io/@taeyul_de/%EB%B0%B0%EC%97%B4%EA%B3%BC-%EC%8A%A4%ED%83%9D</link>
            <guid>https://velog.io/@taeyul_de/%EB%B0%B0%EC%97%B4%EA%B3%BC-%EC%8A%A4%ED%83%9D</guid>
            <pubDate>Tue, 18 Feb 2025 11:38:17 GMT</pubDate>
            <description><![CDATA[<h2 id="font-colore36c09font-colorfac08f배열이란fontfont"><strong><font color="#e36c09"><font color="#fac08f">배열이란?</font></font></strong></h2>
<p>배열은 <strong>순서가 있는 데이터 저장소</strong>이다.</p>
<p>각 요소는 <strong>인덱스(index)</strong> 를 통해 접근할 수 있으며, 데이터를 연속된 메모리 공간에 저장한다.</p>
<p>JavaScript에서 배열은 동적 배열로 구현되어 있으며, 크기가 자동으로 조정된다.</p>
<p>배열은 다양한 메서드를 제공하여 데이터를 쉽게 추가, 삭제, 정렬할 수 있다.</p>
<hr>
<h3 id="배열의-특징"><strong>배열의 특징</strong></h3>
<ol>
<li><strong>인덱스를 사용하여 빠르게 접근할 수 있다.</strong></li>
</ol>
<p>• arr[0], arr[1]과 같은 방식으로 요소를 가져올 수 있다.</p>
<ol start="2">
<li><strong>배열의 크기는 동적으로 변경된다.</strong></li>
</ol>
<p>• 새로운 요소를 추가하면 크기가 자동으로 늘어나고, 요소를 삭제하면 줄어든다.</p>
<ol start="3">
<li><strong>배열의 중간 요소를 삭제하면 재정렬이 필요하다.</strong></li>
</ol>
<p>• 특정 요소를 삭제하면 뒤에 있는 요소들이 한 칸씩 앞으로 이동해야 한다.</p>
<ol start="4">
<li><strong>배열은 객체로 구현되어 있다.</strong></li>
</ol>
<p>• JavaScript의 배열은 실제로 객체이며, length 속성과 다양한 메서드를 제공한다.</p>
<hr>
<h3 id="배열의-주요-메서드"><strong>배열의 주요 메서드</strong></h3>
<table>
<thead>
<tr>
<th><strong>메서드</strong></th>
<th><strong>설명</strong></th>
<th><strong>시간 복잡도</strong></th>
</tr>
</thead>
<tbody><tr>
<td>push(value)</td>
<td>배열의 끝에 값을 추가한다</td>
<td>O(1)</td>
</tr>
<tr>
<td>pop()</td>
<td>배열의 끝 값을 제거한다</td>
<td>O(1)</td>
</tr>
<tr>
<td>unshift(value)</td>
<td>배열의 앞에 값을 추가한다</td>
<td>O(n)</td>
</tr>
<tr>
<td>shift()</td>
<td>배열의 앞 값을 제거한다</td>
<td>O(n)</td>
</tr>
<tr>
<td>splice(index, count)</td>
<td>특정 위치의 요소를 추가 또는 삭제한다</td>
<td>O(n)</td>
</tr>
<tr>
<td>slice(start, end)</td>
<td>특정 범위의 요소를 복사하여 새로운 배열을 만든다</td>
<td>O(n)</td>
</tr>
<tr>
<td>map(callback)</td>
<td>배열의 각 요소에 콜백 함수를 적용한 새로운 배열을 반환한다</td>
<td>O(n)</td>
</tr>
<tr>
<td>filter(callback)</td>
<td>특정 조건을 만족하는 요소만을 포함하는 새로운 배열을 반환한다</td>
<td>O(n)</td>
</tr>
<tr>
<td>reduce(callback, initialValue)</td>
<td>배열을 순회하며 누적 연산을 수행한다</td>
<td>O(n)</td>
</tr>
</tbody></table>
<hr>
<h3 id="배열의-내부-동작"><strong>배열의 내부 동작</strong></h3>
<p>배열은 연속된 메모리 공간에 데이터를 저장하지만, JavaScript의 배열은 동적 배열이므로</p>
<p>공간이 부족할 경우 <strong>새로운 메모리를 할당하고 기존 데이터를 복사하는 과정</strong>이 발생한다.</p>
<p>배열의 <strong>인덱스 접근</strong>은 O(1)의 시간 복잡도를 가지지만, <strong>중간 삽입 및 삭제는 O(n)</strong> 이 된다.</p>
<pre><code class="language-javascript">const arr = [&quot;🍎&quot;, &quot;🍌&quot;, &quot;🍇&quot;]; // 메모리 구조 예시
// 메모리 구조:
// 0x100 -&gt; &quot;🍎&quot;
// 0x104 -&gt; &quot;🍌&quot;
// 0x108 -&gt; &quot;🍇&quot;</code></pre>
<p>배열의 길이를 초과하여 요소를 추가하면 <strong>새로운 메모리를 할당하고 데이터를 복사하는 작업</strong>이 발생한다.</p>
<hr>
<h3 id="배열의-활용-예시"><strong>배열의 활용 예시</strong></h3>
<ol>
<li><strong>데이터 저장 및 관리</strong></li>
</ol>
<p>• JSON 데이터 구조를 다룰 때 배열을 사용한다.</p>
<ol start="2">
<li><strong>UI 요소 관리</strong></li>
</ol>
<p>• React와 같은 프레임워크에서 상태(state) 관리 시 배열을 사용한다.</p>
<ol start="3">
<li><strong>정렬 및 검색</strong></li>
</ol>
<p>• 배열을 정렬(sort())하거나 특정 조건에 맞는 요소를 찾을 때(filter(), find()) 사용한다.</p>
<h3 id="2차원-배열">2차원 배열</h3>
<p>2차원 배열은 1차원 배열을 확장한 것 이다. 2차원 배열은 다음과 같이 선언할수있다.</p>
<pre><code class="language-javascript">//  2 차원 배열을 리터럴로 표현
const arr = l[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]1;

//  arr[2][3] 에 저장된 값을 출력
console. Log(arr [2J[3]); / / 12

//  arr[2][3]에 저장된 값을 15로 변경
arr[2J[3] = 15;

//  변경된 값을 출 력
console. log(arr[2][3]); / / 15</code></pre>
<hr>
<h1 id="font-colorfac08f스택이란font"><strong><font color="#fac08f">스택이란?</font></strong></h1>
<p>스택은 <strong>후입선출(LIFO, Last In First Out)</strong> 방식으로 동작하는 자료구조이다.</p>
<p>데이터의 추가(push())와 제거(pop())가 <strong>맨 위(Top)에서만 이루어진다.</strong></p>
<p>배열을 사용하여 쉽게 구현할 수 있으며, 실행 취소(Undo), 함수 호출 스택(Call Stack) 등 다양한 곳에서 사용된다.</p>
<hr>
<h3 id="스택의-특징"><strong>스택의 특징</strong></h3>
<ol>
<li><strong>후입선출(LIFO) 구조를 가진다.</strong></li>
</ol>
<p>• 마지막에 추가된 요소가 가장 먼저 제거된다.</p>
<ol start="2">
<li><strong>맨 위(Top)에서만 데이터 추가 및 삭제가 가능하다.</strong></li>
</ol>
<p>• 중간의 요소를 제거할 수 없으며, 반드시 마지막 요소부터 제거해야 한다.</p>
<ol start="3">
<li><strong>배열을 사용하여 쉽게 구현할 수 있다.</strong></li>
</ol>
<p>• JavaScript의 push()와 pop()을 활용하면 간단하게 스택을 구현할 수 있다.</p>
<hr>
<h3 id="스택의-주요-메서드"><strong>스택의 주요 메서드</strong></h3>
<table>
<thead>
<tr>
<th><strong>메서드</strong></th>
<th><strong>설명</strong></th>
<th><strong>시간 복잡도</strong></th>
</tr>
</thead>
<tbody><tr>
<td>push(value)</td>
<td>스택의 맨 위에 값을 추가한다</td>
<td>O(1)</td>
</tr>
<tr>
<td>pop()</td>
<td>스택의 맨 위 값을 제거한다</td>
<td>O(1)</td>
</tr>
<tr>
<td>peek()</td>
<td>스택의 맨 위 값을 반환한다 (제거하지 않음)</td>
<td>O(1)</td>
</tr>
<tr>
<td>isEmpty()</td>
<td>스택이 비어 있는지 확인한다</td>
<td>O(1)</td>
</tr>
<tr>
<td>size()</td>
<td>스택의 크기를 반환한다</td>
<td>O(1)</td>
</tr>
</tbody></table>
<hr>
<h3 id="스택의-내부-동작"><strong>스택의 내부 동작</strong></h3>
<p>스택은 데이터를 <strong>배열의 끝에 추가하고(push()), 끝에서 제거(pop())하는 방식으로 동작</strong>한다.</p>
<p>이로 인해 O(1)의 시간 복잡도를 가지며, 매우 빠른 데이터 추가 및 삭제가 가능하다.</p>
<pre><code class="language-javascript">// 스택 구현 (배열 사용)
const stack = [];

// 데이터 추가
stack.push(&quot;🟥 빨강&quot;);
stack.push(&quot;🟦 파랑&quot;);
stack.push(&quot;🟩 초록&quot;);

console.log(stack); // [&quot;🟥 빨강&quot;, &quot;🟦 파랑&quot;, &quot;🟩 초록&quot;]

// 데이터 제거
const lastItem = stack.pop();
console.log(lastItem); // &quot;🟩 초록&quot; (마지막에 넣은 값이 먼저 나옴)
console.log(stack); // [&quot;🟥 빨강&quot;, &quot;🟦 파랑&quot;]</code></pre>
<hr>
<h3 id="스택의-활용-예시"><strong>스택의 활용 예시</strong></h3>
<ol>
<li><strong>실행 취소(Undo) 기능</strong></li>
</ol>
<p>• 문서 편집기에서 실행 취소할 때 마지막 작업을 먼저 제거하는 방식으로 동작한다.</p>
<ol start="2">
<li><strong>브라우저 뒤로 가기(History) 관리</strong></li>
</ol>
<p>• 사용자가 방문한 페이지를 스택에 저장하고, “뒤로 가기” 버튼을 누르면 최근 페이지부터 제거하는 방식이다.</p>
<ol start="3">
<li><strong>함수 호출 스택(Call Stack)</strong></li>
</ol>
<p>• JavaScript의 함수 실행 과정에서 <strong>콜 스택(Call Stack)</strong>이 사용되며, 후입선출 방식으로 실행된다.</p>
<pre><code class="language-javascript">function first() {
  console.log(&quot;첫 번째 실행&quot;);
  second();
}

function second() {
  console.log(&quot;두 번째 실행&quot;);
  third();
}

function third() {
  console.log(&quot;세 번째 실행&quot;);
}

first();</code></pre>
<hr>
<h3 id="실행-과정"><strong>실행 과정</strong></h3>
<ol>
<li>first() 실행 → 스택에 first() 추가</li>
<li>first() 안에서 second() 실행 → 스택에 second() 추가</li>
<li>second() 안에서 third() 실행 → 스택에 third() 추가</li>
<li>third() 실행 완료 → 스택에서 제거</li>
<li>second() 실행 완료 → 스택에서 제거</li>
<li>first() 실행 완료 → 스택에서 제거</li>
</ol>
<p>이처럼 <strong>실행이 끝난 함수는 마지막 실행된 함수부터 제거되며, 후입선출(LIFO) 방식으로 동작한다.</strong></p>
<h3 id="배열-vs-스택-비교"><strong>배열 vs 스택 비교</strong></h3>
<table>
<thead>
<tr>
<th><strong>개념</strong></th>
<th><strong>배열(Array)</strong></th>
<th><strong>스택(Stack)</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>구조</strong></td>
<td>순차적으로 데이터를 저장</td>
<td>후입선출 (LIFO)</td>
</tr>
<tr>
<td><strong>추가 방식</strong></td>
<td>push(), unshift() 등 자유롭게 가능</td>
<td>push() (맨 위에서만 추가)</td>
</tr>
<tr>
<td><strong>제거 방식</strong></td>
<td>pop(), shift(), splice() 등 가능</td>
<td>pop() (맨 위에서만 제거)</td>
</tr>
<tr>
<td><strong>접근 방식</strong></td>
<td>index를 사용하여 특정 요소 접근 가능</td>
<td>맨 위 요소(top)만 접근 가능</td>
</tr>
<tr>
<td><strong>사용 예시</strong></td>
<td>리스트, 데이터 관리</td>
<td>실행 취소(Undo), 콜 스택(Call Stack)</td>
</tr>
</tbody></table>
<p>배열과 스택의 개념을 깊이 이해하면, 다양한 알고리즘과 데이터 구조를 쉽게 이해할 수 있다.</p>
<p>배열은 데이터 저장과 검색에 유용하고, 스택은 후입선출 방식이 필요한 곳에서 강력한 성능을 발휘한다.</p>
<hr>
<h3 id="추상-자료형--adtabstract-data-type">추상 자료형 = ADT(Abstract Data Type)</h3>
<p>ADT는 자료구조를 어떻게 구현할지보다는, 무엇을 할 수 있는지를 정의하는 개념적인 모델이다.
어떤 연산을 제공해야 하는지 명확하게 정의하는 것이 핵심이며, 내부 구현 방식은 중요하지 않다.</p>
<p>쉬운 예로 자동차와 운전자의 관계를 들수있다. 
자동차를 운전할 때 자동차의 내부 엔진 구조를 몰라도 엑셀을 밟으면 가속하고, 브레이크를 밟으면 멈춘다는 기능만 알면된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[클로저와 this]]></title>
            <link>https://velog.io/@taeyul_de/%ED%81%B4%EB%A1%9C%EC%A0%80%EC%99%80-this</link>
            <guid>https://velog.io/@taeyul_de/%ED%81%B4%EB%A1%9C%EC%A0%80%EC%99%80-this</guid>
            <pubDate>Thu, 13 Feb 2025 10:36:49 GMT</pubDate>
            <description><![CDATA[<h2 id="font-colorf796461-클로저closure란font"><strong><font color="#f79646">1. 클로저(Closure)란?</font></strong></h2>
<p><strong>클로저는 “내부 함수가 외부 함수의 변수를 기억하는 현상”이다.</strong>
<strong>함수 안에서 만든 내부 함수가, 자신을 감싸는 함수의 변수를 기억하는 것</strong></p>
<pre><code class="language-javascript">function outer() {
  let count = 0;  // 외부 함수의 변수

  return function inner() { // 내부 함수 (클로저)
    count++;  // 외부 함수의 변수 접근 가능!
    console.log(count);
  };
}

const closureFunc = outer(); // outer 실행 → 내부 함수 반환
closureFunc(); // 1
closureFunc(); // 2
closureFunc(); // 3</code></pre>
<p><strong>왜 클로저가 중요할까?</strong></p>
<p>✔ <strong>상태 유지:</strong> count 값이 초기화되지 않고 계속 유지됨
✔ <strong>데이터 은닉:</strong> count는 outer() 바깥에서 직접 접근할 수 없음.
✔ <strong>함수형 프로그래밍에서 많이 사용</strong></p>
<p><strong>클로저가 없으면 어떻게 될까?</strong></p>
<pre><code class="language-javascript">function noClosure() {
  let count = 0;
  count++;
  console.log(count);
}

noClosure(); // 1
noClosure(); // 1 (다시 초기화됨!)</code></pre>
<p> <strong>클로저 없이 함수 실행하면 count가 초기화되지만, 클로저를 사용하면 값이 유지된다</strong></p>
<h2 id="font-colorf796462-this-키워드란font"><strong><font color="#f79646">2. this 키워드란?</font></strong></h2>
<p><strong>this는 “함수가 실행될 때 결정되는 ’실행 컨텍스트(Execution Context)’를 가리키는 키워드” 이다.</strong></p>
<p><strong>this가 가리키는 값은 ‘함수가 호출되는 방식’에 따라 달라진다</strong></p>
<ul>
<li><strong>this 키워드 동작 방식 (중요한 4가지 규칙)</strong></li>
</ul>
<table>
<thead>
<tr>
<th><strong>상황</strong></th>
<th><strong>this가 가리키는 값</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>1️. 일반 함수 호출</strong></td>
<td>undefined (엄격 모드) 또는 window (브라우저)</td>
</tr>
<tr>
<td><strong>2️. 객체의 메서드 호출</strong></td>
<td>메서드를 호출한 <strong>객체</strong></td>
</tr>
<tr>
<td><strong>3️. new 키워드 사용 (생성자 함수)</strong></td>
<td>새로 생성된 <strong>인스턴스 객체</strong></td>
</tr>
<tr>
<td><strong>4️. 화살표 함수 사용</strong></td>
<td>this를 <strong>부모 스코프(외부 함수)의 this</strong>로 고정</td>
</tr>
</tbody></table>
<p><strong><font color="#c3d69b">1. 일반 함수 호출</font></strong></p>
<pre><code class="language-javascript">function sayHello() {
  console.log(this);
}

sayHello(); // 일반 함수 실행 → this는 window (또는 undefined)</code></pre>
<p>브라우저 환경에서는 window 객체를 가리킴.</p>
<pre><code class="language-javascript">&quot;use strict&quot;; // 엄격 모드 활성화

function sayHello() {
  console.log(this);
}

sayHello(); // undefined</code></pre>
<p><strong>strict mode(&quot;use strict&quot;)에서는 undefined가 된다.</strong></p>
<p><strong><font color="#c3d69b">2️. 객체의 메서드 호출</font></strong></p>
<pre><code class="language-javascript">const person = {
  name: &quot;료니&quot;,
  greet() {
    console.log(this.name);
  }
};

person.greet(); // &quot;료니&quot;  (this는 person 객체)</code></pre>
<p>this는 <strong>이 메서드를 호출한 객체</strong>를 가리킴.</p>
<p><strong><font color="#c3d69b">3️. 생성자 함수 (new 키워드 사용)</font></strong></p>
<pre><code class="language-javascript">function Person(name) {
  this.name = name;
}

const me = new Person(&quot;료니&quot;);
console.log(me.name); // &quot;료니&quot;</code></pre>
<p>new 키워드를 쓰면 <strong>새로운 객체</strong>가 생성되고, this가 그 객체를 가리킴.</p>
<p><strong><font color="#c3d69b">4️. 화살표 함수 (this 바인딩)</font></strong></p>
<pre><code class="language-javascript">const obj = {
  name: &quot;료니&quot;,
  greet: () =&gt; {
    console.log(this.name);
  }
};

obj.greet(); // undefined (this는 obj가 아니라 window)</code></pre>
<p><strong>화살표 함수는 this를 자신을 감싸는 부모 스코프의 this로 고정한다.</strong></p>
<p>즉, obj.greet() 안의 this는 obj가 아니라 전역 객체(window)를 가리킴.</p>
<h2 id="font-colore36c093-프로토타입prototype이란font"><strong><font color="#e36c09">3. 프로토타입(Prototype)이란?</font></strong></h2>
<p><strong>프로토타입은 “객체가 상속받을 수 있는 속성과 메서드들을 저장하는 공간”이다.</strong></p>
<p><strong>“모든 객체는 숨겨진 <strong>proto</strong>(프로토타입 링크)를 가지고 있으며, 이걸 통해 상속을 구현한다.”</strong></p>
<p><strong>프로토타입 기본 개념</strong></p>
<pre><code class="language-javascript">function Person(name) {
  this.name = name;
}

Person.prototype.sayHello = function() {
  console.log(`안녕! 나는 ${this.name}이야.`);
};

const me = new Person(&quot;료니&quot;);
me.sayHello(); // &quot;안녕! 나는 료니야.&quot;</code></pre>
<p>me 객체에는 sayHello 메서드가 없음</p>
<p>하지만 Person.prototype에 있기 때문에 <strong>proto</strong>를 통해 접근 가능</p>
<p><strong>프로토타입 체인 (Prototype Chain)</strong></p>
<pre><code class="language-javascript">console.log(me.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true</code></pre>
<p>모든 객체는 <strong>proto</strong>를 따라 위쪽으로 상속 구조(체인)를 따라가며 프로퍼티를 찾음.</p>
<p>최종적으로 Object.prototype까지 올라감.</p>
<h2 id="font-colore36c094-객체-연결-장치-prototype-chainfont"><strong><font color="#e36c09">4. 객체 연결 장치 (Prototype Chain)</font></strong></h2>
<p><strong>객체 연결 장치는 “프로토타입 체인을 따라 상속되는 구조” 이다.</strong></p>
<p><strong>객체가 자신의 프로퍼티를 찾을 때 없으면 <strong>proto</strong>를 따라가서 부모 객체에서 찾는다</strong></p>
<p><strong>객체 연결 장치 예제</strong></p>
<pre><code class="language-javascript">const parent = {
  hello() {
    console.log(&quot;안녕, 나는 부모야!&quot;);
  }
};

const child = Object.create(parent); // parent를 상속받는 객체 생성
child.hello(); // &quot;안녕, 나는 부모야!&quot;</code></pre>
<p>child 객체에는 hello() 메서드가 없음.</p>
<p>하지만 <strong>proto</strong>를 따라 parent에서 hello()를 찾고 실행한다.</p>
<p><strong>결론적으로</strong></p>
<table>
<thead>
<tr>
<th><strong>개념</strong></th>
<th><strong>역할</strong></th>
<th><strong>핵심 포인트</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>클로저(Closure)</strong></td>
<td>내부 함수가 외부 함수의 변수를 기억</td>
<td>return으로 내부 함수 반환</td>
</tr>
<tr>
<td><strong>this</strong></td>
<td>실행 컨텍스트에 따라 값이 결정</td>
<td>일반 함수, 메서드, new, 화살표 함수에 따라 다름</td>
</tr>
<tr>
<td><strong>프로토타입(Prototype)</strong></td>
<td>객체의 부모 역할, 상속 기능 제공</td>
<td><strong>proto</strong>를 통해 프로퍼티 찾기</td>
</tr>
<tr>
<td><strong>객체 연결 장치(Prototype Chain)</strong></td>
<td>프로토타입을 따라 객체 간 연결</td>
<td>부모 → 자식으로 메서드 상속</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[이터레이션]]></title>
            <link>https://velog.io/@taeyul_de/%EC%9D%B4%ED%84%B0%EB%A0%88%EC%9D%B4%EC%85%98</link>
            <guid>https://velog.io/@taeyul_de/%EC%9D%B4%ED%84%B0%EB%A0%88%EC%9D%B4%EC%85%98</guid>
            <pubDate>Thu, 13 Feb 2025 10:29:00 GMT</pubDate>
            <description><![CDATA[<p>자바스크립트에서 데이터를 순차적으로 처리하는 핵심 개념인 이터레이션과 관련 기술들을 이해하는 것은 매우 중요하다.</p>
<p><strong><font color="#f79646">1. 이터레이션 (Iteration)</font></strong></p>
<p>이터레이션은 데이터를 한 덩어리씩 순회하며 처리하는 과정을 의미한다.
데이터 전체를 한 번에 다루기보다, 한 요소씩 차례대로 접근하여 처리함으로써 효율적이고 유연한 코드 작성을 가능하게 한다.</p>
<p>• <strong>특징</strong></p>
<p>• 데이터를 일정 단위(예: 한 요소씩)로 나누어 처리한다.
• 반복문을 통해 컬렉션 내의 모든 값을 순회한다.</p>
<p>이터레이션은 보통 <strong>이터레이터(Iterator)</strong> 패턴을 사용하여 구현된다.</p>
<p><strong><font color="#f79646">2. 이터레이터 소비하기 (Consuming an Iterator)</font></strong></p>
<p>이터레이터는 데이터를 순차적으로 반환하는 객체이다.
이터레이터를 소비한다는 것은 이터레이터가 제공하는 데이터를 하나씩 받아서 사용하는 것을 의미한다.</p>
<p><strong><font color="#f79646">2.1. 이터레이터의 기본 구조</font></strong></p>
<p><img src="https://velog.velcdn.com/images/taeyul_de/post/45c6ad54-5af1-4d85-bdd3-d1507a4ae829/image.png" alt=""></p>
<p>이터레이터는 일반적으로 next() 메서드를 가지고 있으며, 이 메서드를 호출할 때마다 다음과 같은 형태의 객체를 반환한다.</p>
<pre><code class="language-javascript">{
  value: 현재 처리 중인 값,
  done: 이터레이션이 끝났는지 여부를 나타내는 불리언 값
}</code></pre>
<p>• <strong>value</strong>: 현재 순회 중인 데이터 값을 나타낸다.
• <strong>done</strong>: 이터레이션이 완료되었으면 true가, 아직 진행 중이면 false가 된다.</p>
<p><strong><font color="#f79646">2.2. 이터레이터 소비 방법</font></strong></p>
<p>이터레이터 소비에는 여러 가지 방법이 있으며, 대표적인 방법은 다음과 같다.</p>
<p><strong><font color="#f79646">2.2.1. for...of 반복문 사용</font></strong></p>
<p>for...of 문은 이터러블(Iterator를 소비할 수 있는 객체)을 순회하며 내부적으로 이터레이터 소비 프로토콜을 따른다.</p>
<pre><code class="language-javascript">const array = [1, 2, 3];
for (const value of array) {
  console.log(value); // 1, 2, 3 순서대로 출력된다.
}</code></pre>
<p><strong><font color="#f79646">2.2.2. 전개 구문(Spread Syntax) 사용</font></strong></p>
<p>전개 구문(...)은 이터레이터를 소비하여 배열이나 함수의 인수 목록 등으로 확장한다.</p>
<pre><code class="language-javascript">const iterable = [1, 2, 3];
const arrayCopy = [...iterable];
console.log(arrayCopy); // [1, 2, 3]</code></pre>
<p><strong><font color="#f79646">2.2.3. 나머지 매개변수(Rest Parameter) 사용</font></strong></p>
<p>함수의 매개변수로 나머지 매개변수를 사용하면 전달된 이터러블 객체가 배열로 변환된다.</p>
<pre><code class="language-javascript">function sum(...numbers) {
  return numbers.reduce((acc, cur) =&gt; acc + cur, 0);
}

console.log(sum(1, 2, 3)); // 6</code></pre>
<p><strong><font color="#f79646">3. 이터러블 (Iterable)</font></strong></p>
<p>이터러블은 이터레이터 소비 프로토콜을 준수하는 객체를 의미한다.
즉, 이터러블 객체는 Symbol.iterator 메서드를 가지며, 이를 호출하면 이터레이터를 반환한다.</p>
<p><strong><font color="#f79646">3.1. 기본 이터러블 객체</font></strong></p>
<p>자바스크립트에서는 여러 기본 데이터 구조가 이터러블로 제공된다.</p>
<p>• <strong>배열(Array)</strong></p>
<p>배열은 이터러블하여 for...of 문, 전개 구문 등으로 쉽게 순회할 수 있다.</p>
<p>• <strong>문자열(String)</strong></p>
<p>문자열은 문자 하나하나가 순회 가능한 요소로 취급된다.</p>
<p>• <strong>Map</strong></p>
<p>Map 객체는 [키, 값] 형태의 튜플을 순회할 수 있다.</p>
<p>• <strong>Set</strong></p>
<p>Set 객체는 중복되지 않는 값들의 집합으로 이터러블하다.</p>
<pre><code class="language-javascript">// 배열의 이터러블 예시
const arr = [10, 20, 30];
for (const num of arr) {
  console.log(num);
}

// 문자열의 이터러블 예시
const greeting = &quot;Hello&quot;;
const characters = [...greeting];
console.log(characters); // [&quot;H&quot;, &quot;e&quot;, &quot;l&quot;, &quot;l&quot;, &quot;o&quot;]

// Map의 이터러블 예시
const map = new Map();
map.set(&#39;a&#39;, 1);
map.set(&#39;b&#39;, 2);
for (const [key, value] of map) {
  console.log(key, value);
}</code></pre>
<p><strong><font color="#f79646">3.2. 직접 이터러블 구현하기</font></strong></p>
<p>사용자가 직접 이터러블 객체를 만들고 싶다면, 객체에 Symbol.iterator 메서드를 정의하면 된다.</p>
<pre><code class="language-javascript">const customIterable = {
  data: [1, 2, 3],
  [Symbol.iterator]() {
    let index = 0;
    const data = this.data;
    return {
      next() {
        if (index &lt; data.length) {
          return { value: data[index++], done: false };
        } else {
          return { value: undefined, done: true };
        }
      }
    };
  }
};

for (const value of customIterable) {
  console.log(value); // 1, 2, 3 순서대로 출력된다.
}</code></pre>
<p>• <strong>설명</strong></p>
<p>위 예시에서 customIterable 객체는 Symbol.iterator 메서드를 통해 이터레이터를 반환한다.</p>
<p>이터레이터의 next() 메서드는 현재 인덱스가 배열의 길이보다 작으면 다음 값을 반환하고, 그렇지 않으면 done: true를 반환하여 순회를 종료한다.</p>
<p><strong>정리하자면</strong></p>
<pre><code class="language-javascript">// ✅ 1. 이터러블 객체 (Iterable) - 과자 상자 만들기
const snackBox = {
  snacks: [&quot;🍫 초콜릿&quot;, &quot;🍪 쿠키&quot;, &quot;🍬 사탕&quot;], // 이터러블 대상
  [Symbol.iterator]: function () {
    let index = 0;
    return {
      next: () =&gt; {
        return index &lt; this.snacks.length
          ? { value: this.snacks[index++], done: false } // 과자 반환
          : { value: undefined, done: true }; // 반복 종료
      },
    };
  },
};

// ✅ 2. 이터레이션 (Iteration) - for...of 사용해서 과자 먹기
console.log(&quot;🎯 for...of 반복문 실행 (이터레이션)&quot;);
for (const snack of snackBox) {
  console.log(snack); // 과자를 하나씩 출력
}

// ✅ 3. 이터레이터 직접 사용 (next() 호출)
console.log(&quot;\n🎯 next()를 직접 호출 (이터레이터)&quot;);
const iterator = snackBox[Symbol.iterator]();
console.log(iterator.next()); // { value: &quot;🍫 초콜릿&quot;, done: false }
console.log(iterator.next()); // { value: &quot;🍪 쿠키&quot;, done: false }
console.log(iterator.next()); // { value: &quot;🍬 사탕&quot;, done: false }
console.log(iterator.next()); // { value: undefined, done: true } // 반복 끝

// ✅ 4. 제너레이터 (Generator) 사용해서 쉽게 구현
console.log(&quot;\n🎯 제너레이터 사용해서 과자 자동 나누기&quot;);
function* snackGenerator() {
  yield &quot;🍫 초콜릿&quot;;
  yield &quot;🍪 쿠키&quot;;
  yield &quot;🍬 사탕&quot;;
}

const gen = snackGenerator();
console.log(gen.next()); // { value: &quot;🍫 초콜릿&quot;, done: false }
console.log(gen.next()); // { value: &quot;🍪 쿠키&quot;, done: false }
console.log(gen.next()); // { value: &quot;🍬 사탕&quot;, done: false }
console.log(gen.next()); // { value: undefined, done: true } // 반복 끝</code></pre>
<table>
<thead>
<tr>
<th>개념</th>
<th>의미</th>
<th>역할</th>
<th>예제</th>
</tr>
</thead>
<tbody><tr>
<td>이터레이션 (Iteration)</td>
<td>반복하는 행위 자체</td>
<td>for...of, while 같은 반복 과정</td>
<td>for...of, while</td>
</tr>
<tr>
<td>이터레이터 (Iterator)</td>
<td>반복을 수행하는 도구</td>
<td>next() 를 호출해 값을 하나씩 꺼냄</td>
<td>.next() 메서드 사용</td>
</tr>
<tr>
<td>이터러블 (Iterable)</td>
<td>반복 가능한 객체</td>
<td>for...of에서 사용할 수 있는 객체</td>
<td>배열, 문자열, Set, Map 등</td>
</tr>
<tr>
<td><strong>제너레이터(Generator)</strong></td>
<td>이터레이터를 쉽게 만드는 함수</td>
<td>yield 키워드로 값을 순차적으로 반환</td>
<td>function*, yield 사용</td>
</tr>
</tbody></table>
<p>• <strong>이터레이션</strong>은 데이터를 한 덩어리씩 순회하여 처리하는 방식이다.
• <strong>이터레이터</strong>는 next() 메서드를 통해 순차적으로 데이터를 반환하며, 이터레이터 소비는 이를 활용하는 것이다.
• <strong>이터러블</strong>은 Symbol.iterator 메서드를 가진 객체로, 배열, 문자열, Map, Set 등이 대표적이다.
• yield 키워드를 사용해 next() 를 쉽게 관리 할 수 있는 함수.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[운영체제의 큰 그림]]></title>
            <link>https://velog.io/@taeyul_de/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EC%9D%98-%ED%81%B0-%EA%B7%B8%EB%A6%BC</link>
            <guid>https://velog.io/@taeyul_de/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EC%9D%98-%ED%81%B0-%EA%B7%B8%EB%A6%BC</guid>
            <pubDate>Wed, 12 Feb 2025 11:01:46 GMT</pubDate>
            <description><![CDATA[<p>운영체제는 컴퓨터 자원을 효율적으로 관리하고 사용자와 하드웨어 간의 <strong>중재자 역할</strong>을 하는 소프트웨어다.<br>크게 <strong>커널(Kernel)</strong> 과 <strong>운영체제의 기능</strong>으로 나눌 수 있다.<br>운영체제의 큰 그림과 핵심 개념들을 공부해보자</p>
<hr>
<h2 id="font-color4bacc6커널kernelfont"><font color="#4bacc6">커널(Kernel)</font></h2>
<p>커널은 운영체제의 핵심 부분으로, 하드웨어와 애플리케이션 사이에서 <strong>중재자 역할</strong>을 한다.<br>애플리케이션이 하드웨어에 직접 접근하지 않고, <strong>커널을 통해 간접적으로</strong> 접근하게 하여 <strong>안정성과 보안</strong>을 유지한다.  </p>
<p><img src="https://velog.velcdn.com/images/taeyul_de/post/e0702995-a3fa-43c6-8e68-d0bca2e5f7d0/image.png" alt=""></p>
<h3 id="커널의-주요-역할">커널의 주요 역할</h3>
<ol>
<li><p><strong>프로세스 관리</strong>  </p>
<ul>
<li>여러 프로그램이 동시에 실행될 때 <strong>프로세스를 생성하고 종료</strong>하며, <strong>CPU 시간을 분배</strong>한다.  </li>
<li><strong>문맥 교환(Context Switching)</strong> 을 통해 여러 프로세스가 CPU를 효율적으로 사용할 수 있도록 한다.  </li>
</ul>
</li>
<li><p><strong>메모리 관리</strong>  </p>
<ul>
<li>각 프로세스가 메모리를 안전하고 효율적으로 사용할 수 있게 <strong>메모리 할당 및 회수</strong>를 한다.  </li>
<li><strong>가상 메모리</strong> 기술을 이용해 실제 메모리보다 더 큰 메모리를 사용하는 것처럼 보이게 한다.  </li>
</ul>
</li>
<li><p><strong>디바이스 관리</strong>  </p>
<ul>
<li>키보드, 마우스, 하드디스크 등 <strong>하드웨어 장치에 접근</strong>하고 <strong>입출력(I/O) 작업</strong>을 관리한다.  </li>
<li><strong>디바이스 드라이버</strong>를 통해 하드웨어와 소프트웨어가 원활하게 통신할 수 있도록 한다.  </li>
</ul>
</li>
<li><p><strong>파일 시스템 관리</strong>  </p>
<ul>
<li>데이터를 <strong>파일 단위</strong>로 저장하고 관리한다.  </li>
<li>파일 생성, 삭제, 읽기, 쓰기, 이동 등을 처리한다.  </li>
</ul>
</li>
</ol>
<hr>
<h1 id="font-colorf79646운영체제의-역할font"><font color="#f79646">운영체제의 역할</font></h1>
<p>운영체제는 <strong>컴퓨터 하드웨어와 사용자 간의 중재자</strong> 역할을 한다.<br>하드웨어 자원을 효율적으로 관리하고, 사용자와 애플리케이션이 <strong>편리하고 안전하게</strong> 시스템을 사용할 수 있게 해준다.<br>운영체제의 주요 역할은 다음과 같다.  </p>
<p><img src="https://velog.velcdn.com/images/taeyul_de/post/c7fe8442-d26b-4a88-8f5b-cb2bf306b1e7/image.png" alt=""></p>
<h2 id="1-프로세스-관리">1. 프로세스 관리</h2>
<ul>
<li><strong>프로세스</strong>는 실행 중인 프로그램의 인스턴스다.  </li>
<li>운영체제는 <strong>프로세스를 생성하고 종료</strong>하며, <strong>CPU 시간을 분배</strong>하고 <strong>자원을 할당</strong>한다.  </li>
<li>여러 프로세스가 동시에 실행될 때 <strong>문맥 교환(Context Switching)</strong> 을 통해 <strong>공정하게 CPU를 사용</strong>할 수 있게 한다.  </li>
</ul>
<h3 id="예시-놀이공원에서-놀이기구-타기">예시: 놀이공원에서 놀이기구 타기</h3>
<ul>
<li>여러 사람이 놀이기구를 타려면 <strong>순서를 정해야 한다.</strong>  </li>
<li>각 사람에게 <strong>정해진 시간만큼</strong> 놀이기구를 타게 하고, 순서대로 바꿔가며 탄다.  </li>
<li>운영체제도 여러 프로세스가 <strong>공평하게 CPU를 사용할 수 있도록</strong> 관리한다.  </li>
</ul>
<hr>
<h2 id="2-메모리-관리">2. 메모리 관리</h2>
<ul>
<li>메모리는 <strong>프로그램이 실행되는 공간</strong>으로, RAM을 의미한다.  </li>
<li>운영체제는 <strong>프로세스마다 필요한 메모리를 할당하고, 사용이 끝나면 회수</strong>한다.  </li>
<li><strong>가상 메모리(Virtual Memory)</strong> 기술을 사용해 물리 메모리보다 더 큰 메모리를 <strong>사용하는 것처럼</strong> 보이게 할 수 있다.  </li>
<li><strong>가상 메모리(Virtual Memory)</strong> 는 실제 물리 메모리 크기와 상관없이 <strong>더 큰 메모리 공간</strong>을 사용하는 것처럼 보이게 한다.  </li>
<li><strong>페이징(Paging)</strong> 과 <strong>세그멘테이션(Segmentation)</strong> 기법을 사용해 프로세스에 필요한 메모리만 나누어 할당한다.  </li>
</ul>
<h4 id="페이지-교체-알고리즘">페이지 교체 알고리즘</h4>
<ul>
<li><strong>FIFO (First In First Out):</strong> 가장 먼저 들어온 페이지를 교체한다.  </li>
<li><strong>LRU (Least Recently Used):</strong> 가장 오랫동안 사용하지 않은 페이지를 교체한다.  </li>
<li><strong>LFU (Least Frequently Used):</strong> 사용 빈도가 가장 적은 페이지를 교체한다.  </li>
</ul>
<h3 id="예시-책상-공간-관리">예시: 책상 공간 관리</h3>
<ul>
<li>여러 사람이 한 책상에서 공부할 때, <strong>한 사람씩 필요한 책만 펼치고</strong> 나머지 책은 <strong>책장에 보관</strong>한다.  </li>
<li>필요할 때만 책장에서 가져와 보는 것처럼, 운영체제는 필요한 메모리만 <strong>효율적으로 관리</strong>한다.  </li>
</ul>
<hr>
<h2 id="3-파일-및-디렉터리-관리">3. 파일 및 디렉터리 관리</h2>
<ul>
<li>데이터를 <strong>파일 단위</strong>로 저장하고, <strong>디렉터리(폴더)</strong> 를 통해 체계적으로 관리한다.  </li>
<li><strong>파일 생성, 삭제, 읽기, 쓰기, 복사, 이동</strong> 등을 처리하며, <strong>권한 설정</strong>으로 보안을 강화한다.  </li>
</ul>
<h4 id="파일-시스템-종류">파일 시스템 종류</h4>
<ul>
<li><strong>FAT (File Allocation Table):</strong> DOS와 Windows에서 사용되며, 구조가 단순하지만 대용량 파일 관리에 비효율적이다.  </li>
<li><strong>NTFS (New Technology File System):</strong> Windows NT 계열에서 사용하며, 보안과 대용량 파일 처리가 뛰어나다.  </li>
<li><strong>ext (Extended File System):</strong> 리눅스에서 주로 사용되며, 버전에 따라 성능과 안정성이 다르다.  <h3 id="예시-서류철-관리">예시: 서류철 관리</h3>
</li>
<li>회사에서 문서를 <strong>종류별로 서류철에 정리</strong>하고, 필요할 때 <strong>찾아보고 수정하거나 폐기</strong>한다.  </li>
<li>운영체제도 데이터를 <strong>파일과 디렉터리 구조</strong>로 체계적으로 관리한다.  </li>
</ul>
<hr>
<h2 id="4-장치-관리-입출력-관리">4. 장치 관리 (입출력 관리)</h2>
<ul>
<li>키보드, 마우스, 프린터, 하드디스크 등 <strong>입출력 장치(I/O Device)</strong> 를 관리한다.  </li>
<li><strong>디바이스 드라이버</strong>를 통해 하드웨어와 소프트웨어가 <strong>원활하게 통신</strong>할 수 있게 한다.  </li>
</ul>
<h3 id="예시-공용-장비-예약-시스템">예시: 공용 장비 예약 시스템</h3>
<ul>
<li>회사에서 공용 프린터나 회의실을 <strong>예약하고 사용하는 순서</strong>를 정하는 것처럼,<br>운영체제는 <strong>여러 프로그램이 장치를 사용할 때 충돌 없이 순서대로 사용</strong>하게 관리한다.  </li>
</ul>
<hr>
<h2 id="5-사용자-인터페이스-제공">5. 사용자 인터페이스 제공</h2>
<ul>
<li>사용자가 컴퓨터를 쉽게 사용할 수 있도록 <strong>그래픽 사용자 인터페이스(GUI)</strong> 와 <strong>명령줄 인터페이스(CLI)</strong> 를 제공한다.  </li>
<li>GUI는 아이콘과 창을 사용한 <strong>직관적인 조작</strong>을 가능하게 하고, CLI는 <strong>명령어를 입력</strong>해 작업을 수행한다.  </li>
</ul>
<h3 id="예시-자동차-대시보드">예시: 자동차 대시보드</h3>
<ul>
<li>자동차 대시보드에서 <strong>속도계, 연료 게이지</strong> 등을 보면서 운전자가 쉽게 차량 상태를 확인하고 조작할 수 있다.  </li>
<li>운영체제도 사용자에게 <strong>직관적인 화면</strong>을 제공하여 <strong>컴퓨터를 쉽게 조작</strong>할 수 있게 한다.  </li>
</ul>
<hr>
<h2 id="6-보안-및-권한-관리">6. 보안 및 권한 관리</h2>
<ul>
<li>사용자 계정마다 <strong>권한을 설정</strong>하고, <strong>인증</strong>(로그인)과 <strong>인가</strong>(권한 부여)를 통해 보안을 강화한다.  </li>
<li><strong>악성 코드(바이러스, 해킹)</strong> 로부터 시스템을 보호하고, <strong>데이터 무결성</strong>을 유지한다.  </li>
</ul>
<h3 id="예시-회사-사무실-출입-관리">예시: 회사 사무실 출입 관리</h3>
<ul>
<li>사무실에 들어갈 때 <strong>출입증을 확인하고, 등급에 따라 접근 가능한 방</strong>이 정해져 있다.  </li>
<li>운영체제도 사용자마다 <strong>접근 권한</strong>을 설정해 보안을 강화한다.  </li>
</ul>
<hr>
<h2 id="7-네트워크-관리">7. 네트워크 관리</h2>
<ul>
<li>컴퓨터 간의 <strong>데이터 통신</strong>을 관리하고, <strong>인터넷 연결</strong> 및 <strong>파일 공유</strong> 등을 지원한다.  </li>
<li><strong>프로토콜</strong>(예: TCP/IP)을 통해 <strong>안정적이고 효율적인 데이터 전송</strong>을 가능하게 한다.  </li>
</ul>
<h3 id="예시-우편-시스템-관리">예시: 우편 시스템 관리</h3>
<ul>
<li>우편물을 보내려면 <strong>주소를 확인하고, 정해진 규칙에 따라 배달</strong>해야 한다.  </li>
<li>운영체제는 네트워크 프로토콜을 통해 <strong>데이터가 정확한 주소로 안전하게 전달</strong>되게 한다.  </li>
</ul>
<hr>
<h2 id="font-colorf79646시스템-콜과-이중-모드font"><font color="#f79646">시스템 콜과 이중 모드</font></h2>
<h3 id="1-이중-모드-왕국과-시민의-이야기">1. 이중 모드: 왕국과 시민의 이야기</h3>
<ul>
<li><strong>왕국 (커널 모드):</strong> 운영체제가 사는 곳! 모든 권력을 가지고 있어서 컴퓨터의 모든 자원을 마음대로 사용할 수 있다.</li>
<li><strong>시민 (사용자 모드):</strong> 우리가 사용하는 프로그램들이 사는 곳. 왕국의 허락 없이는 중요한 일을 할 수 없다.</li>
</ul>
<h3 id="왜-이중-모드가-필요할까">왜 이중 모드가 필요할까?</h3>
<p>만약 시민들이 왕국처럼 모든 권력을 가진다면? 컴퓨터는 금방 엉망진창이 될 거다. 그래서 왕국(커널 모드)이 시민(사용자 모드)을 감시하고, 필요한 일만 허락하는 것이다.</p>
<h3 id="2-시스템-콜-시민의-sos-요청">2. 시스템 콜: 시민의 SOS 요청</h3>
<ul>
<li><strong>시스템 콜:</strong> 시민(사용자 모드)이 왕국(커널 모드)에게 도움을 요청하는 방법. &quot;왕님, 저 파일 좀 읽어주세요!&quot; 또는 &quot;왕님, 저 메모리 좀 빌려주세요!&quot;처럼 필요한 일을 부탁하는 거다.</li>
</ul>
<h3 id="시스템-콜은-어떻게-작동할까">시스템 콜은 어떻게 작동할까?</h3>
<ol>
<li><strong>시민의 SOS:</strong> 프로그램이 필요한 작업을 시스템 콜을 통해 왕국에 요청한다.</li>
<li><strong>왕국의 출동:</strong> 왕국(커널 모드)이 시민의 요청을 확인하고, 필요한 일을 처리해준다.</li>
<li><strong>시민의 행복:</strong> 왕국이 일을 마치면 시민(사용자 모드)에게 결과를 알려준다.</li>
</ol>
<h3 id="시스템-콜이-왜-필요할까">시스템 콜이 왜 필요할까?</h3>
<ul>
<li><strong>안전:</strong> 시민들이 직접 왕국의 자원을 사용하면 위험하니까, 왕국을 통해서만 안전하게 사용할 수 있도록 하는 것이다.</li>
<li><strong>효율:</strong> 왕국이 시민들의 요청을 한 번에 처리해주면, 시민들은 더 효율적으로 일할 수 있다.</li>
</ul>
<h2 id="font-colorc0504d시스템-콜system-callfont"><font color="#c0504d">시스템 콜(System Call)</font></h2>
<p>시스템 콜은 <strong>프로그램(애플리케이션)</strong>  이 커널에 요청을 보낼 때 사용하는 <strong>인터페이스</strong> 다.<br>애플리케이션이 직접 하드웨어에 접근할 수 없기 때문에, 시스템 콜을 통해 커널에게 요청하고 <strong>커널이 대신 작업을 수행</strong>한다.  </p>
<h3 id="시스템-콜의-종류-및-예시">시스템 콜의 종류 및 예시</h3>
<ol>
<li><p><strong>프로세스 제어</strong>  </p>
<ul>
<li><code>fork()</code> : 새로운 프로세스를 생성한다.  </li>
<li><code>exec()</code> : 새로운 프로그램을 실행한다.  </li>
<li><code>exit()</code> : 프로세스를 종료한다.  </li>
</ul>
</li>
<li><p><strong>파일 조작</strong>  </p>
<ul>
<li><code>open()</code> : 파일을 연다.  </li>
<li><code>read()</code> : 파일을 읽는다.  </li>
<li><code>write()</code> : 파일을 쓴다.  </li>
<li><code>close()</code> : 파일을 닫는다.  </li>
</ul>
</li>
<li><p><strong>장치 조작</strong>  </p>
<ul>
<li><code>ioctl()</code> : 장치의 제어 및 상태 정보를 얻는다.  </li>
<li><code>read()</code> / <code>write()</code> : 장치에서 데이터를 읽거나 쓴다.  </li>
</ul>
</li>
<li><p><strong>정보 유지</strong>  </p>
<ul>
<li><code>getpid()</code> : 현재 프로세스의 ID를 얻는다.  </li>
<li><code>alarm()</code> : 일정 시간이 지나면 시그널을 보낸다.  </li>
</ul>
</li>
</ol>
<hr>
<h2 id="font-colorf79646소프트웨어-인터럽트-software-interruptfont"><font color="#f79646">소프트웨어 인터럽트 (Software Interrupt)</font></h2>
<p>소프트웨어 인터럽트는 CPU에서 실행 중인 프로그램의 흐름을 <strong>명시적으로</strong> 변경시키는 메커니즘이다. 하드웨어 인터럽트와 달리, 소프트웨어적으로 <strong>특정 명령</strong>이나 <strong>조건</strong>에 의해 발생한다.</p>
<h3 id="주요-특징">주요 특징</h3>
<ul>
<li><strong>동기적 발생:</strong> 특정 프로그램 코드 실행 중 <strong>예측 가능</strong>하게 발생한다.</li>
<li><strong>다양한 목적:</strong> 시스템 호출, 예외 처리, 타이머 이벤트 등 <strong>여러 가지 용도</strong>로 사용된다.</li>
<li><strong>우선순위:</strong> 하드웨어 인터럽트와 마찬가지로 <strong>우선순위</strong>를 가질 수 있다.</li>
</ul>
<h3 id="작동-방식">작동 방식</h3>
<ol>
<li><strong>인터럽트 발생:</strong> 프로그램 실행 중 특정 명령 (예: <code>INT</code> 명령어)이나 조건 (예: 0으로 나누기)이 발생하면 소프트웨어 인터럽트가 <strong>트리거</strong>된다.</li>
<li><strong>인터럽트 벡터:</strong> CPU는 인터럽트 벡터 테이블을 참조하여 해당 인터럽트를 처리하는 <strong>핸들러</strong>의 주소를 찾는다.</li>
<li><strong>핸들러 실행:</strong> CPU는 현재 실행 중인 프로그램의 상태를 저장하고, 해당 인터럽트 핸들러로 <strong>제어 흐름</strong>을 옮겨 인터럽트를 처리한다.</li>
<li><strong>복귀:</strong> 인터럽트 처리가 완료되면, 저장된 상태를 복구하고 원래 프로그램으로 <strong>복귀</strong>하여 실행을 계속한다.</li>
</ol>
<h3 id="주요-용도">주요 용도</h3>
<ul>
<li><strong>시스템 호출 (System Call):</strong> 사용자 프로그램이 운영체제의 기능을 호출할 때 사용된다. (예: 파일 입출력, 네트워크 통신)</li>
<li><strong>예외 처리 (Exception Handling):</strong> 프로그램 실행 중 오류 (예: 0으로 나누기, 잘못된 메모리 접근)가 발생했을 때 처리한다.</li>
<li><strong>타이머 인터럽트 (Timer Interrupt):</strong> 주기적인 작업을 수행하기 위해 특정 시간 간격으로 발생한다.</li>
<li><strong>프로세스 간 통신 (Inter-Process Communication):</strong> 프로세스 간에 데이터를 주고받을 때 사용될 수 있다.</li>
</ul>
<h3 id="장점">장점</h3>
<ul>
<li><strong>유연성:</strong> 다양한 상황에 맞춰 인터럽트 핸들러를 작성하여 처리할 수 있다.</li>
<li><strong>효율성:</strong> 특정 작업을 수행하기 위해 운영체제에 직접 접근하는 것보다 효율적이다.</li>
</ul>
<h3 id="단점">단점</h3>
<ul>
<li><strong>오버헤드:</strong> 인터럽트 발생 및 처리 과정에서 <strong>일정 정도의 오버헤드</strong>가 발생할 수 있다.</li>
</ul>
<p>소프트웨어 인터럽트는 시스템의 효율적인 작동을 위해 <strong>필수적인 메커니즘</strong>이며, 다양한 방식으로 활용된다.</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[앱실론 (EPSILON) 이란?]]></title>
            <link>https://velog.io/@taeyul_de/%EC%95%B1%EC%8B%A4%EB%A1%A0-EPSILON-%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@taeyul_de/%EC%95%B1%EC%8B%A4%EB%A1%A0-EPSILON-%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Tue, 11 Feb 2025 09:33:05 GMT</pubDate>
            <description><![CDATA[<p>📌 Number.EPSILON (앱실론) 심도 있게 이해하기</p>
<ol>
<li>Number.EPSILON이란?</li>
</ol>
<p>Number.EPSILON은 자바스크립트에서 표현할 수 있는 가장 작은 부동소수점 차이값을 나타내는 상수다.
즉, 두 개의 숫자가 같다고 간주할 수 있는 최소한의 차이를 의미한다.</p>
<p>console.log(Number.EPSILON); // 2.220446049250313e-16</p>
<p>✔️ Number.EPSILON의 값은 2.220446049250313e-16 (약 2.22 × 10⁻¹⁶)이다.
이는 1과 1보다 큰 가장 작은 숫자 간의 차이를 의미한다.</p>
<ol start="2">
<li>Number.EPSILON이 필요한 이유</li>
</ol>
<p>자바스크립트에서 숫자는 IEEE 754 부동소수점 방식으로 저장된다.
이 방식은 정확한 소수를 저장하지 못하는 경우가 있다.</p>
<p>🔹 부동소수점 연산 오류 예시</p>
<p>console.log(0.1 + 0.2); // 0.30000000000000004 ❌
console.log(0.1 + 0.7); // 0.7999999999999999 ❌</p>
<p>위 코드에서 기대값은 0.3, 0.8이지만, 부동소수점 방식의 특성상 작은 오차가 발생한다.</p>
<p>이러한 오차 때문에 0.1 + 0.2 === 0.3을 비교하면 false가 나온다.</p>
<p>console.log(0.1 + 0.2 === 0.3); // false ❌</p>
<p>✅ Number.EPSILON을 사용하면 이 문제를 해결할 수 있다.</p>
<ol start="3">
<li>Number.EPSILON을 활용한 오차 보정</li>
</ol>
<p>Number.EPSILON을 사용하면 두 숫자의 차이가 아주 작을 때, 같은 값으로 간주할 수 있다.</p>
<p>🔹 정확한 소수 비교 함수</p>
<p>function isEqual(a, b) {
  return Math.abs(a - b) &lt; Number.EPSILON;
}</p>
<p>console.log(isEqual(0.1 + 0.2, 0.3)); // true ✅
console.log(isEqual(0.1 + 0.7, 0.8)); // true ✅</p>
<p>✅ 이 함수는 두 숫자의 차이가 Number.EPSILON보다 작으면 같은 값으로 판단한다.
✅ 즉, 0.1 + 0.2와 0.3이 같다고 인식하게 된다.</p>
<ol start="4">
<li>Number.EPSILON의 원리</li>
</ol>
<p>자바스크립트의 부동소수점 연산 방식(IEEE 754)에서 숫자는 64비트(8바이트)로 저장된다.
이 중,
    •    1비트 → 부호(Sign)
    •    11비트 → 지수(Exponent)
    •    52비트 → 가수(Fraction)</p>
<p>이런 방식으로 저장되기 때문에 일부 소수를 정확하게 표현할 수 없다.
예를 들어, 0.1은 2진수로 변환하면 무한 반복되는 값이 된다.</p>
<p>0.1(10진수) = 0.00011001100110011...(2진수)</p>
<p>이러한 이유로 0.1과 같은 값을 정확하게 저장할 수 없어 연산 시 오차가 발생한다.
이때, Number.EPSILON을 이용하면 숫자 비교 시 발생하는 오차를 해결할 수 있다.</p>
<ol start="5">
<li>Number.EPSILON이 실제로 사용되는 사례</li>
</ol>
<p>✅ 1) Math.abs()와 함께 사용하여 오차 보정</p>
<p>function isSame(a, b) {
  return Math.abs(a - b) &lt; Number.EPSILON;
}</p>
<p>console.log(isSame(0.1 + 0.2, 0.3)); // true
console.log(isSame(0.15 + 0.15, 0.3)); // true</p>
<p>👉 두 값의 차이가 Number.EPSILON보다 작으면 같다고 간주한다.</p>
<p>✅ 2) 배열에서 특정 값 찾기 (정확한 소수 비교)</p>
<p>const numbers = [0.1, 0.2, 0.3];</p>
<p>console.log(numbers.includes(0.1 + 0.2)); // false (부동소수점 오차 때문)
console.log(numbers.some(n =&gt; isSame(n, 0.1 + 0.2))); // true (오차 보정)</p>
<p>👉 includes()는 오차 때문에 false를 반환하지만, isSame()을 활용하면 정확한 비교가 가능하다.</p>
<ol start="6">
<li>Number.EPSILON의 한계</li>
</ol>
<p>🔹 Number.EPSILON은 아주 작은 값이지만, 모든 부동소수점 오류를 해결하는 것은 아니다.
    •    Number.EPSILON은 1과 1보다 큰 가장 작은 숫자 간의 차이이므로,
더 작은 값들을 비교할 때는 적절하지 않을 수 있다.
    •    값의 크기에 따라 오차가 다를 수 있다.
→ 0.1과 0.2의 비교는 Number.EPSILON으로 해결되지만,
더 큰 수(예: 100000000.1과 100000000.2)는 더 큰 오차를 가질 수 있다.</p>
<p>🔹 오차 범위를 조정하는 방법</p>
<p>오차 범위를 조절하려면 비교하는 값의 크기에 따라 EPSILON을 조정해야 한다.</p>
<p>function isAlmostEqual(a, b, epsilon = Number.EPSILON * Math.max(1, Math.abs(a), Math.abs(b))) {
  return Math.abs(a - b) &lt; epsilon;
}</p>
<p>console.log(isAlmostEqual(100000000.1 + 0.2, 100000000.3)); // true
console.log(isAlmostEqual(0.1 + 0.2, 0.3)); // true</p>
<p>✅ 큰 숫자일수록 EPSILON을 더 크게 조정하여 비교 정확도를 높인다.</p>
<hr>
<h1 id="font-color938953-🫡-numberepsilon-정리font"><font color="#938953" >🫡 Number.EPSILON 정리</font></h1>
<p>자바스크립트에서 아주 작은 숫자 차이를 나타내는 값이다.
숫자로 표현하면 0.000000000000000222 (약 2.22 × 10⁻¹⁶)</p>
<pre><code class="language-javascript">console.log(Number.EPSILON); // 2.220446049250313e-16</code></pre>
<p>✅ 이 값은 자바스크립트가 표현할 수 있는 가장 작은 부동소수점 차이값이다.
✅ 두 숫자가 거의 같은지 비교할 때 사용한다.</p>
<ol start="2">
<li>Number.EPSILON이 왜 필요해?</li>
</ol>
<p>자바스크립트에서 소수점 계산을 하면 정확한 값이 안 나올 수 있다!</p>
<pre><code class="language-javascript">console.log(0.1 + 0.2); // 0.30000000000000004 ❌ (0.3이 아님!)
console.log(0.1 + 0.7); // 0.7999999999999999 ❌ (0.8이 아님!)</code></pre>
<p>✅ 소수점 연산 시 미세한 오차가 발생한다.
✅ 이 문제를 해결하려면 Number.EPSILON을 사용하면 된다!</p>
<ol start="3">
<li>Number.EPSILON을 활용한 오차 해결 방법</li>
</ol>
<p>✅ 정확한 소수점 비교 함수</p>
<pre><code class="language-javascript">function isEqual(a, b) {
  return Math.abs(a - b) &lt; Number.EPSILON;
}

console.log(isEqual(0.1 + 0.2, 0.3)); // true ✅ (정확한 비교 가능!)
console.log(isEqual(0.15 + 0.15, 0.3)); // true ✅</code></pre>
<p>✅ Math.abs(a - b) → 두 숫자의 차이가 Number.EPSILON보다 작으면 같은 값으로 간주한다.
✅ 즉, 0.1 + 0.2를 비교할 때 실제 값이 0.30000000000000004라도 0.3으로 인정해 준다.</p>
<ol start="4">
<li>Number.EPSILON을 실제로 어디에 써?</li>
</ol>
<p>✅ 배열에서 특정 값 찾을 때 (부동소수점 오차 보정)</p>
<pre><code class="language-javascript">const numbers = [0.1, 0.2, 0.3];

console.log(numbers.includes(0.1 + 0.2)); // false ❌ (오차 때문에 찾을 수 없음)
console.log(numbers.some(n =&gt; isEqual(n, 0.1 + 0.2))); // true ✅ (오차 보정으로 찾음)</code></pre>
<p>✅ numbers.includes(0.1 + 0.2) → 부동소수점 오차 때문에 false가 나옴.
✅ isEqual()을 사용하면 정확하게 비교할 수 있다!</p>
<ol start="5">
<li>Number.EPSILON이 항상 정답은 아니야!</li>
</ol>
<p>✅ 큰 숫자 비교할 때는 EPSILON 값을 조정해야 한다.</p>
<pre><code class="language-javascript">function isAlmostEqual(a, b) {
  const epsilon = Number.EPSILON * Math.max(1, Math.abs(a), Math.abs(b));
  return Math.abs(a - b) &lt; epsilon;
}

console.log(isAlmostEqual(100000000.1 + 0.2, 100000000.3)); // true ✅</code></pre>
<p>✅ 큰 숫자는 Number.EPSILON보다 더 큰 오차가 발생할 수 있다.
✅ 비교하는 숫자의 크기에 따라 EPSILON 값을 조정해야 한다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[코딩 테스트 필수 문법]]></title>
            <link>https://velog.io/@taeyul_de/%EC%BD%94%EB%94%A9-%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%95%84%EC%88%98-%EB%AC%B8%EB%B2%95</link>
            <guid>https://velog.io/@taeyul_de/%EC%BD%94%EB%94%A9-%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%95%84%EC%88%98-%EB%AC%B8%EB%B2%95</guid>
            <pubDate>Tue, 11 Feb 2025 09:16:35 GMT</pubDate>
            <description><![CDATA[<p>자바스크립트에는 <strong>기본적으로 제공되는(=빌트인, Built-in)</strong> 데이터 타입이 있다.
이 데이터 타입은 크게 <strong>두 가지</strong>로 나뉜다.</p>
<p>✅ <strong>원시 타입(Primitive Type)</strong> → 값 자체를 저장하는 타입
✅ <strong>참조 타입(Reference Type)</strong> → 객체(Object), 배열(Array), 함수(Function)처럼 
<strong>여러 값을 저장하는 복합적인 값</strong></p>
<h2 id="font-color9389531-원시-타입-primitive-typefont"><strong><font color="#938953">1. 원시 타입 (Primitive Type)</font></strong></h2>
<p>원시 타입은 “단순한 값” 이라고 보면 된다.
이 값들은 <strong>한 번 만들어지면 바꿀 수 없다(Immutable)</strong>.</p>
<p><strong>1) 숫자 (Number)</strong></p>
<p>숫자는 정수, 실수(소수점), 특수 숫자(무한대, NaN)를 포함한다</p>
<pre><code class="language-javascript">let num1 = 42;       // 정수
let num2 = 3.14;     // 실수 (소수점 있는 숫자)
let inf = Infinity;  // 무한대
let nan = NaN;       // 숫자가 아닌 값 (Not a Number)</code></pre>
<p><strong>NaN이 나오는 경우</strong></p>
<pre><code class="language-javascript">console.log(&quot;hello&quot; * 2); // NaN (문자열을 숫자로 곱할 수 없음)</code></pre>
<p><strong>2) 큰 숫자 (BigInt)</strong></p>
<p><strong>Number 타입은 너무 큰 숫자를 못 담는다.</strong>
그래서 BigInt 타입이 생겼다.
숫자 뒤에 n을 붙이면 BigInt가 된다.</p>
<pre><code class="language-javascript">let bigNumber = 123456789012345678901234567890n;
console.log(bigNumber);</code></pre>
<p><strong>3) 문자열 (String)</strong></p>
<p>문자는 &quot; &quot; (쌍따옴표), &#39; &#39; (홑따옴표), ` `` (백틱)으로 감싸면 된다.</p>
<pre><code class="language-javascript">let str1 = &quot;안녕!&quot;;
let str2 = &#39;자바스크립트&#39;;
let str3 = `오늘 날짜는 ${new Date().toLocaleDateString()} 입니다.`;</code></pre>
<p>백틱(<code>``</code>)을 사용하면 <strong>변수를 쉽게 넣을 수 있다!</strong> (${} (템플릿리터널) 활용)</p>
<p><strong>4) 참/거짓 (Boolean)</strong></p>
<p>참(true) 또는 거짓(false)만 가지는 타입이다.</p>
<pre><code class="language-javascript">let isCodingFun = true;
let isTired = false;</code></pre>
<p> <strong>조건문에서 많이 사용됨</strong></p>
<pre><code class="language-javascript">if (isCodingFun) {
  console.log(&quot;코딩은 재미있어!&quot;);
} else {
  console.log(&quot;코딩이 별로야...&quot;);
}</code></pre>
<p><strong>5) 값이 없음 (Undefined)</strong></p>
<p>값을 안 넣은 변수는 undefined가 된다.</p>
<pre><code class="language-javascript">let name;
console.log(name); // undefined (아직 값이 없음)</code></pre>
<p><strong>6) 값이 없음 (Null)</strong></p>
<p>null은 <strong>“아예 비어 있다”</strong> 는 의미다.
undefined와 다른 점은 <strong>“값을 일부러 비운 것”</strong> 이라는 점이다.</p>
<pre><code class="language-javascript">let emptyValue = null;
console.log(emptyValue); // null</code></pre>
<p><strong>undefined vs null 차이</strong></p>
<p>• undefined → <strong>아예 값이 없는 상태</strong> (변수 선언만 하고 값 안 넣음)
• null → <strong>값을 일부러 비운 상태</strong> (의도적으로 비어 있음)</p>
<p><strong>7) 심볼 (Symbol)</strong></p>
<p>Symbol은 <strong>고유한 값(유일한 값)</strong> 을 만들 때 사용한다.
객체의 키(key)로 많이 활용된다.</p>
<pre><code class="language-javascript">let sym1 = Symbol(&quot;id&quot;);
let sym2 = Symbol(&quot;id&quot;);

console.log(sym1 === sym2); // false (항상 서로 다른 값)</code></pre>
<h2 id="font-color9389532-참조-타입-reference-typefont"><strong><font color="#938953">2. 참조 타입 (Reference Type)</font></strong></h2>
<p>참조 타입은 <strong>여러 개의 값을 묶어서 저장할 수 있는 타입</strong>이다.
즉, <strong>변수 하나에 여러 데이터를 저장할 수 있음</strong>.</p>
<p><strong>1) 객체 (Object)</strong></p>
<p>객체는 <strong>{ 키: 값 } 형태</strong>로 데이터를 저장한다.
이렇게 하면 관련 있는 데이터를 하나로 묶을 수 있다.</p>
<pre><code class="language-javascript">let person = {
  name: &quot;철수&quot;,
  age: 25,
  job: &quot;개발자&quot;
};

console.log(person.name); // 철수
console.log(person[&quot;age&quot;]); // 25</code></pre>
<p><strong>2) 배열 (Array)</strong></p>
<p>배열은 여러 개의 데이터를 <strong>순서대로 저장</strong>할 때 사용한다.
배열의 요소는 [ ] 대괄호 안에 넣으면 된다.</p>
<pre><code class="language-javascript">let fruits = [&quot;사과&quot;, &quot;바나나&quot;, &quot;포도&quot;];

console.log(fruits[0]); // 사과
console.log(fruits[1]); // 바나나
console.log(fruits.length); // 3 (배열 길이)</code></pre>
<p><strong>3) 함수 (Function)</strong></p>
<p>자바스크립트에서는 <strong>함수도 데이터 타입</strong>이다.
즉, <strong>함수도 변수에 저장할 수 있다.</strong></p>
<pre><code class="language-javascript">function sayHello() {
  return &quot;안녕하세요!&quot;;
}

let greet = sayHello;
console.log(greet()); // &quot;안녕하세요!&quot;</code></pre>
<p><strong>4) 날짜 (Date)</strong></p>
<p>자바스크립트에서 날짜를 다룰 때 사용하는 타입.</p>
<pre><code class="language-javascript">let today = new Date();
console.log(today.toLocaleDateString()); // 현재 날짜 출력</code></pre>
<p><strong>5) 정규 표현식 (RegExp)</strong></p>
<p>문자열에서 특정 패턴을 찾을 때 사용!</p>
<pre><code class="language-javascript">let pattern = /hello/g;
let text = &quot;hello world! hello!&quot;;
console.log(text.match(pattern)); // [&quot;hello&quot;, &quot;hello&quot;]</code></pre>
<p><strong>6) 오류 (Error)</strong></p>
<p>자바스크립트에서 오류를 다룰 때 사용!</p>
<pre><code class="language-javascript">try {
  throw new Error(&quot;문제가 발생했어요!&quot;);
} catch (err) {
  console.log(err.message);
}</code></pre>
<p><strong>typeof 연산자로 데이터 타입 확인</strong></p>
<pre><code class="language-javascript">console.log(typeof 42); // &quot;number&quot;
console.log(typeof &quot;Hello&quot;); // &quot;string&quot;
console.log(typeof true); // &quot;boolean&quot;
console.log(typeof undefined); // &quot;undefined&quot;
console.log(typeof null); // &quot;object&quot; (버그지만 그대로 유지됨!)
console.log(typeof Symbol()); // &quot;symbol&quot;
console.log(typeof {}); // &quot;object&quot;
console.log(typeof []); // &quot;object&quot; (배열도 객체!)
console.log(typeof function() {}); // &quot;function&quot; (특별하게 &#39;function&#39; 반환)</code></pre>
<p><strong>✅ 1) 같은 객체를 가리킴 (Shallow Copy)</strong></p>
<pre><code class="language-javascript">let obj1 = { value: 100 };
let obj2 = obj1;

obj2.value = 200;

console.log(obj1.value); // 200 (같은 주소를 공유해서 같이 바뀜!)
console.log(obj2.value); // 200</code></pre>
<p><strong>✅ 2) 독립적인 객체를 만들고 싶다면? (Deep Copy)</strong></p>
<p>객체를 복사할 때 <strong>독립적인 새로운 객체</strong>를 만들려면 Object.assign() 또는 spread(...)를 사용하면 된다.</p>
<pre><code class="language-javascript">let obj1 = { value: 100 };
let obj2 = { ...obj1 }; // 새로운 객체로 복사 (spread 연산자)

obj2.value = 200;

console.log(obj1.value); // 100 (원본은 그대로!)
console.log(obj2.value); // 200</code></pre>
<hr>
<h1 id="font-color938953함수-functionfont"><font color="#938953">함수 (Function)</font></h1>
<p>함수는 특정한 동작을 실행하는 코드 블록이다.
즉, 어떤 입력을 받아 처리하고, 결과를 반환하는 역할을 한다.
한 번 정의해두면 필요할 때마다 재 사용 할 수 있다.</p>
<p><strong><font color="orange">함수 호출(Function Call)</font></strong></p>
<p>함수 호출은 <strong>정의된 함수를 실행하는 과정</strong>이다.
함수를 호출하면 함수 내부의 코드가 실행된다.</p>
<p><strong>1) 기본적인 함수 호출</strong></p>
<pre><code class="language-javascript">function greet() {
  console.log(&quot;안녕하세요!&quot;);
}

greet(); // 실행 결과: &quot;안녕하세요!&quot;</code></pre>
<p>✅ greet(); 를 실행하면 함수 내부의 코드가 실행된다.
<strong>✅ 2) 매개변수가 있는 함수 호출</strong></p>
<p>매개변수를 사용하면 <strong>입력값에 따라 다르게 동작하는 함수</strong>를 만들 수 있다.</p>
<pre><code class="language-javascript">function sayHello(name) {
  console.log(&quot;안녕하세요, &quot; + name + &quot;님!&quot;);
}

sayHello(&quot;철수&quot;); // &quot;안녕하세요, 철수님!&quot;
sayHello(&quot;영희&quot;); // &quot;안녕하세요, 영희님!&quot;</code></pre>
<p>✅ 함수 호출 시 sayHello(&quot;이름&quot;) 형태로 값을 전달하면 name에 해당 값이 들어간다.
<strong>✅ 3) 반환값이 있는 함수 호출 (return 사용)</strong></p>
<p>return을 사용하면 함수에서 <strong>결과 값을 반환</strong>할 수 있다.</p>
<pre><code class="language-javascript">function add(a, b) {
  return a + b;
}

let result = add(3, 5);
console.log(result); // 8</code></pre>
<p>✅ return이 없으면 함수는 단순히 실행만 하고 끝난다.
✅ return이 있으면 <strong>값을 돌려주고, 변수에 저장하거나 다른 연산에 사용할 수 있다.</strong></p>
<p><strong><font color="orange">익명 함수(Anonymous Function)</font></strong></p>
<p><strong>익명 함수는 이름이 없는 함수</strong>이다.
보통 변수에 할당해서 사용하거나, 다른 함수의 매개변수로 전달된다.</p>
<p><strong>1) 변수에 저장하는 익명 함수</strong></p>
<pre><code class="language-javascript">let hello = function() {
  console.log(&quot;안녕하세요!&quot;);
};

hello(); // 실행 결과: &quot;안녕하세요!&quot;</code></pre>
<p>✅ 함수에 이름이 없고, hello 변수에 저장하여 호출할 수 있다.</p>
<p><strong>2) 매개변수가 있는 익명 함수</strong></p>
<pre><code class="language-javascript">let add = function(a, b) {
  return a + b;
};

console.log(add(2, 3)); // 5</code></pre>
<p>✅ 일반적인 함수와 동일하게 매개변수를 사용하여 값을 전달할 수 있다.</p>
<p><strong>3) 즉시 실행 함수 (IIFE, Immediately Invoked Function Expression)</strong></p>
<p>익명 함수를 선언하자마자 바로 실행할 수도 있다.</p>
<pre><code class="language-javascript">(function() {
  console.log(&quot;즉시 실행 함수입니다!&quot;);
})();</code></pre>
<p>✅ 함수 선언 후 바로 실행되며, 한 번만 실행되는 용도로 사용된다.</p>
<hr>
<h2 id="font-color938953구조-분해-할당-destructuring-assignmentfont"><font color="#938953">구조 분해 할당 (Destructuring Assignment)</font></h2>
<p><strong>구조 분해 할당</strong>은 배열이나 객체의 값을 쉽게 변수에 할당하는 문법이다.</p>
<p><strong>1) 배열에서 구조 분해 할당</strong></p>
<pre><code class="language-javascript">const fruits = [&quot;사과&quot;, &quot;바나나&quot;, &quot;포도&quot;];

// 배열의 값을 각각 변수에 할당
const [first, second, third] = fruits;

console.log(first);  // &quot;사과&quot;
console.log(second); // &quot;바나나&quot;
console.log(third);  // &quot;포도&quot;</code></pre>
<p><strong>배열의 순서대로 변수에 값을 넣어준다.</strong></p>
<p><strong>2) 객체에서 구조 분해 할당</strong></p>
<pre><code class="language-javascript">const person = { name: &quot;철수&quot;, age: 25 };

// 객체의 키(key) 값을 변수에 할당
const { name, age } = person;

console.log(name); // &quot;철수&quot;
console.log(age);  // 25</code></pre>
<p><strong>객체의 키(key)와 같은 이름의 변수를 만들어 값을 할당한다.</strong></p>
<hr>
<h3 id="🔹-값-교환하기-swap-values"><strong>🔹 값 교환하기 (Swap Values)</strong></h3>
<p><strong>두 변수의 값을 교환할 때 임시 변수를 사용하지 않고, 구조 분해 할당을 활용할 수 있다.</strong></p>
<pre><code class="language-javascript">let a = 1;
let b = 2;

// 구조 분해 할당으로 값 교환
[a, b] = [b, a];

console.log(a); // 2
console.log(b); // 1</code></pre>
<p><strong>[b, a] 형태로 배열을 만들고, 구조 분해 할당을 이용해 값을 바꾼다.</strong></p>
<h3 id="🔹-비구조화-할당-destructuring-assignment"><strong>🔹 비구조화 할당 (Destructuring Assignment)</strong></h3>
<p><strong>비구조화 할당은 구조 분해 할당과 같은 개념이다.</strong></p>
<pre><code class="language-javascript">const user = { id: 1, username: &quot;coding&quot; };

// 객체 비구조화 할당
const { id, username } = user;

console.log(id);       // 1
console.log(username); // &quot;coding&quot;</code></pre>
<p><strong>“비구조화 할당”은 기존 객체의 구조를 벗겨서(해체해서) 변수에 값을 할당하는 것과 같기 때문에, 구조 분해 할당과 같은 개념이다.</strong></p>
<hr>
<h3 id="🔹-스프레드-연산자-spread-operator-"><strong>🔹 스프레드 연산자 (Spread Operator, ...)</strong></h3>
<p><strong>스프레드 연산자</strong>는 배열이나 객체의 요소를 <strong>펼쳐서(복사해서) 사용</strong>할 때 사용된다.  </p>
<p><strong>1) 배열에서 사용</strong></p>
<pre><code class="language-javascript">const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5, 6];

console.log(arr2); // [1, 2, 3, 4, 5, 6]</code></pre>
<p><strong>...arr1을 사용하면 arr1의 모든 요소를 새로운 배열에 복사할 수 있다.</strong></p>
<p><strong>2) 객체에서 사용</strong></p>
<pre><code class="language-javascript">const obj1 = { name: &quot;철수&quot;, age: 25 };
const obj2 = { ...obj1, job: &quot;개발자&quot; };

console.log(obj2); 
// { name: &quot;철수&quot;, age: 25, job: &quot;개발자&quot; }</code></pre>
<p><strong>기존 객체에 새로운 속성을 추가할 때 유용하다.</strong></p>
<hr>
<h3 id="🔹-배열-내-같은-요소-제거하기-remove-duplicates-in-array"><strong>🔹 배열 내 같은 요소 제거하기 (Remove Duplicates in Array)</strong></h3>
<p>배열에서 중복된 요소를 제거하는 방법은 여러 가지가 있다.  </p>
<ul>
<li><strong>Set을 이용한 중복 제거</strong></li>
</ul>
<pre><code class="language-javascript">const numbers = [1, 2, 2, 3, 4, 4, 5];

// Set 객체를 사용하여 중복 제거
const uniqueNumbers = [...new Set(numbers)];

console.log(uniqueNumbers); // [1, 2, 3, 4, 5]</code></pre>
<p><strong>Set은 중복을 허용하지 않는 자료구조이므로, 이를 활용하면 쉽게 중복을 제거할 수 있다.</strong></p>
<h3 id="🔹-와--연산자로-조건문-대체하기"><strong>🔹 &amp;&amp;와 || 연산자로 조건문 대체하기</strong></h3>
<p><strong>조건문을 간결하게 줄이는 방법</strong>으로 &amp;&amp;(AND), ||(OR) 연산자를 사용할 수 있다.  </p>
<p><strong>1) &amp;&amp; 연산자로 조건문 대체하기</strong></p>
<pre><code class="language-javascript">const isLoggedIn = true;

// isLoggedIn이 true일 때만 실행
isLoggedIn &amp;&amp; console.log(&quot;로그인 성공!&quot;);</code></pre>
<p><strong>&amp;&amp; 연산자는 앞의 조건이 true일 때만 뒤의 코드를 실행한다.</strong></p>
<p><strong>(조건이 false면 실행되지 않는다.)</strong></p>
<p><strong>2) || 연산자로 기본값 설정</strong></p>
<pre><code class="language-javascript">const username = null;

// username이 없으면 &quot;Guest&quot;를 기본값으로 사용
const displayName = username || &quot;Guest&quot;;

console.log(displayName); // &quot;Guest&quot;</code></pre>
<p><strong>|| 연산자는 앞의 값이 false일 때(즉, null, undefined, 0, &quot;&quot;일 때) 뒤의 값을 사용한다.</strong></p>
<p></p>
<h1 id="font-colorc0504d🫡마무리font"><font color="#c0504d">🫡마무리</font></h1>
<p><strong>1. 원시 타입 (Primitive Type)</strong></p>
<p>✅ <strong>Number</strong> → 정수, 실수, Infinity, NaN 같은 숫자를 저장하는 타입
✅ <strong>BigInt</strong> → Number보다 더 큰 정수를 다룰 수 있는 타입 (n을 붙여 사용)
✅ <strong>String</strong> → 문자 데이터를 저장하는 타입 (&quot;, &#39;, ` 사용 가능)
✅ <strong>Boolean</strong> → true 또는 false 값을 가지는 타입
✅ <strong>Undefined</strong> → 변수를 선언했지만, 값을 할당하지 않은 상태
✅ <strong>Null</strong> → 의도적으로 값이 비어 있음을 나타내는 타입
✅ <strong>Symbol</strong> → 유일한 값을 생성하는 타입 (객체의 key로 활용 가능)</p>
<p><strong>2. 참조 타입 (Reference Type)</strong></p>
<p>✅ <strong>Object</strong> → 여러 데이터를 key-value 형태로 저장하는 타입
✅ <strong>Array</strong> → 여러 값을 순서대로 저장하는 리스트 구조
✅ <strong>Function</strong> → 실행 가능한 코드 블록도 변수에 저장할 수 있음
✅ <strong>Date</strong> → 날짜와 시간을 다루는 객체
✅ <strong>RegExp</strong> → 정규 표현식을 다룰 때 사용하는 객체
✅ <strong>Error</strong> → 예외 처리를 위해 사용되는 객체</p>
<p><strong>3. 함수 (Function)</strong>  </p>
<p>✅ <strong>함수 호출(Function Call)</strong> → 함수이름() 형태로 실행
✅ <strong>매개변수가 있는 함수</strong> → 함수에 값을 전달하여 다르게 동작하도록 설정
✅ <strong>return을 사용하는 함수</strong> → 결과 값을 반환하고, 다른 연산에 활용 가능
✅ <strong>익명 함수 (Anonymous Function)</strong> → 이름이 없는 함수로 변수에 저장하여 사용
✅ <strong>즉시 실행 함수 (IIFE)</strong> → 선언과 동시에 실행되는 함수</p>
<p><strong>4. 구조 분해 할당 (Destructuring Assignment)</strong></p>
<p>✅ <strong>배열 구조 분해</strong> → [a, b] = 배열 형태로 배열 요소를 변수에 할당
✅ <strong>객체 구조 분해</strong> → { key } = 객체 형태로 객체의 값을 변수에 할당</p>
<p><strong>5. 값 교환하기 (Swap Values)</strong></p>
<p>✅ <strong>구조 분해 할당을 활용해 값 교환</strong> → [a, b] = [b, a]</p>
<p><strong>6. 비구조화 할당 (Destructuring Assignment)</strong></p>
<p>✅ <strong>구조 분해 할당과 같은 개념</strong> → 객체나 배열의 값을 쉽게 변수에 할당</p>
<p><strong>7. 스프레드 연산자 (Spread Operator, ...)</strong></p>
<p>✅ <strong>배열 확장</strong> → ...배열을 사용해 기존 배열을 확장할 수 있음
✅ <strong>객체 확장</strong> → { ...객체, 추가속성 } 형태로 기존 객체를 복사하면서 새로운 속성 추가</p>
<p><strong>8. 배열 내 같은 요소 제거하기</strong></p>
<p>✅ <strong>Set을 활용하여 중복 제거</strong> → [...new Set(배열)]</p>
<p><strong>9. &amp;&amp;와 || 연산자로 조건문 대체하기</strong>  </p>
<p>✅ <strong>&amp;&amp; 연산자</strong> → 앞의 값이 true이면 뒤의 코드 실행 (조건 &amp;&amp; 실행할 코드)
✅ <strong>|| 연산자</strong> → 앞의 값이 false이면 기본값 설정 (변수 || 기본값)</p>
]]></description>
        </item>
    </channel>
</rss>