<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://leeyujoo.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://leeyujoo.com/" rel="alternate" type="text/html" /><updated>2026-01-29T12:04:06+00:00</updated><id>https://leeyujoo.com/feed.xml</id><title type="html">YUJOOLOG</title><subtitle>배우는 게 너무 즐거운 유주에용</subtitle><author><name>YUJOO-LEE</name></author><entry><title type="html">오늘의 질문 - 유닉스 시스템 구조와 통신 장치, 다중화 방식</title><link href="https://leeyujoo.com/note/2025/06/15/unix-comm-mux.html" rel="alternate" type="text/html" title="오늘의 질문 - 유닉스 시스템 구조와 통신 장치, 다중화 방식" /><published>2025-06-15T06:58:00+00:00</published><updated>2025-06-15T06:58:00+00:00</updated><id>https://leeyujoo.com/note/2025/06/15/unix-comm-mux</id><content type="html" xml:base="https://leeyujoo.com/note/2025/06/15/unix-comm-mux.html"><![CDATA[<h2 id="-chatgpt-오늘의-질문--정리-모음">📚 ChatGPT 오늘의 질문 &amp; 정리 모음</h2>

<hr />

<h2 id="-유닉스에서-커널은-어떤-역할을-하는가">❓ 유닉스에서 커널은 어떤 역할을 하는가?</h2>

<p><strong>답변</strong>:<br />
커널은 운영체제의 핵심으로, 하드웨어 자원을 직접 제어하며 사용자 프로그램이 요청하는 시스템 기능을 수행한다. 메모리 관리, 프로세스 스케줄링, 입출력 제어, 파일 시스템 등이 모두 커널이 담당하는 영역이다.</p>

<hr />

<h2 id="-쉘은-무엇이며-커널과-어떤-관계에-있는가">❓ 쉘은 무엇이며, 커널과 어떤 관계에 있는가?</h2>

<p><strong>답변</strong>:<br />
쉘은 사용자의 명령을 받아 해석하고, 이를 커널에 전달해 실제 실행이 이뤄지게 한다. 사용자는 쉘을 통해 간접적으로 커널 기능을 사용할 수 있다.</p>

<hr />

<h2 id="-유닉스-파일-시스템에서-모든-것을-파일로-추상화-한다는-것은-무슨-의미인가">❓ 유닉스 파일 시스템에서 ‘모든 것을 파일로 추상화’ 한다는 것은 무슨 의미인가?</h2>

<p><strong>답변</strong>:<br />
유닉스는 하드웨어 장치, 디렉토리, 소켓 등 다양한 자원을 전부 파일처럼 접근할 수 있게 만든다. 이는 인터페이스를 통일시켜 사용자와 프로그램이 복잡한 장치 제어를 몰라도 쉽게 사용할 수 있게 하기 위함이다.</p>

<hr />

<h2 id="-유닉스-파일의-inode에서-보호-비트는-무엇을-의미하는가">❓ 유닉스 파일의 inode에서 보호 비트는 무엇을 의미하는가?</h2>

<p><strong>답변</strong>:<br />
보호 비트는 해당 파일의 접근 권한을 나타내는 비트로, 읽기(r), 쓰기(w), 실행(x)에 대한 권한을 사용자(owner), 그룹(group), 기타(other)로 나누어 9비트로 표현한다.</p>

<hr />

<h2 id="-통신-시스템에서-사용되는-주요-신호-변환-장치에는-어떤-것들이-있는가">❓ 통신 시스템에서 사용되는 주요 신호 변환 장치에는 어떤 것들이 있는가?</h2>

<p><strong>답변</strong>:</p>

<table>
  <thead>
    <tr>
      <th>장치</th>
      <th>기능</th>
      <th>사용 예</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>모뎀</td>
      <td>디지털 ↔ 아날로그 변환</td>
      <td>전화선 기반 통신</td>
    </tr>
    <tr>
      <td>코덱</td>
      <td>디지털 ↔ 디지털 (압축/복호화)</td>
      <td>영상·음성 전송</td>
    </tr>
    <tr>
      <td>ADC/DAC</td>
      <td>아날로그 ↔ 디지털 변환</td>
      <td>센서, 마이크, 스피커</td>
    </tr>
    <tr>
      <td>트랜시버</td>
      <td>디지털 ↔ 무선 주파수(RF) 변환</td>
      <td>무선 LAN, 위성 통신</td>
    </tr>
    <tr>
      <td>MUX/DEMUX</td>
      <td>신호 병합/분리</td>
      <td>회선 절약, 전송 효율 향상</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="-dsudigital-service-unit는-어떤-장치인가">❓ DSU(Digital Service Unit)는 어떤 장치인가?</h2>

<p><strong>답변</strong>:<br />
DSU는 디지털 전용 회선에 적합하도록 디지털 신호를 부호화/복호화하는 장치다. 유니폴라 데이터를 바이폴라 부호화 방식으로 변환해 송수신에 적합하게 만든다.</p>

<hr />

<h2 id="-유니폴라와-바이폴라-신호는-어떤-차이가-있는가">❓ 유니폴라와 바이폴라 신호는 어떤 차이가 있는가?</h2>

<p><strong>답변</strong>:</p>
<ul>
  <li>유니폴라: 0V와 +V만 사용 → 직류 성분이 많아 장거리 전송에 부적합</li>
  <li>바이폴라: +V와 -V를 번갈아 사용 → DC 성분 제거, 노이즈에 강함</li>
</ul>

<hr />

<h2 id="-dsu는-유니폴라-신호를-바이폴라로-변환하기도-하는가">❓ DSU는 유니폴라 신호를 바이폴라로 변환하기도 하는가?</h2>

<p><strong>답변</strong>:<br />
그렇다. DSU는 입력되는 유니폴라 디지털 신호를 회선 전송에 적합한 바이폴라 방식으로 변환한다.</p>

<hr />

<h2 id="-모뎀이-처리하는-아날로그-데이터란-무엇인가">❓ 모뎀이 처리하는 아날로그 데이터란 무엇인가?</h2>

<p><strong>답변</strong>:<br />
모뎀이 다루는 아날로그 데이터는 사람의 음성, 연속 센서 신호와 같은 연속된 파형이다. 모뎀은 이를 디지털 장치에서 이해할 수 있도록 변환하고, 반대로도 수행한다.</p>

<hr />

<h2 id="-코덱과-모뎀은-어떤-차이가-있는가">❓ 코덱과 모뎀은 어떤 차이가 있는가?</h2>

<p><strong>답변</strong>:</p>
<ul>
  <li>코덱: 디지털 신호를 압축하거나 복호화 → 디지털 ↔ 디지털 변환</li>
  <li>모뎀: 디지털 데이터를 아날로그 회선으로 변환 → 디지털 ↔ 아날로그 변환</li>
</ul>

<hr />

<h2 id="-pcmpulse-code-modulation은-어떤-방식인가">❓ PCM(Pulse Code Modulation)은 어떤 방식인가?</h2>

<p><strong>답변</strong>:<br />
PCM은 아날로그 신호를 일정 간격으로 샘플링하고, 각 샘플을 정수 값으로 양자화한 후 이를 2진수로 부호화하여 디지털 데이터로 전환하는 방식이다.</p>

<hr />

<h2 id="-코덱은-pcm을-어떻게-활용하는가">❓ 코덱은 PCM을 어떻게 활용하는가?</h2>

<p><strong>답변</strong>:<br />
코덱은 PCM 방식으로 음성을 디지털화한 뒤, 압축을 적용하거나 그대로 전송하고 수신 측에서 복호화해 원래 음성으로 되돌린다.</p>

<hr />

<h2 id="-itu-t-v-시리즈와-x-시리즈는-각각-어떤-표준을-다루는가">❓ ITU-T V 시리즈와 X 시리즈는 각각 어떤 표준을 다루는가?</h2>

<p><strong>답변</strong>:</p>

<table>
  <thead>
    <tr>
      <th>시리즈</th>
      <th>내용</th>
      <th>예시</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>V 시리즈</td>
      <td>모뎀, 전화 기반 통신, 속도, 에러제어</td>
      <td>V.90, V.42</td>
    </tr>
    <tr>
      <td>X 시리즈</td>
      <td>데이터 통신, 보안, 인증, 디렉토리 서비스</td>
      <td>X.25, X.509, X.500</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="-rs-232c는-어떤-표준이며-왜-많이-사용되는가">❓ RS-232C는 어떤 표준이며 왜 많이 사용되는가?</h2>

<p><strong>답변</strong>:<br />
RS-232C는 EIA에서 제정한 직렬 통신 표준으로, 컴퓨터와 모뎀, 장치 간 통신을 위해 고안됐다. 최대 115.2kbps의 속도로 DB-9 또는 DB-25 포트를 통해 데이터를 주고받는다. 단순하고 안정적인 구조로 인해 산업계에서 널리 사용된다.</p>

<hr />

<h2 id="-다중화기mux는-어떤-장치이며-왜-사용하는가">❓ 다중화기(MUX)는 어떤 장치이며 왜 사용하는가?</h2>

<p><strong>답변</strong>:<br />
다중화기는 여러 개의 입력 신호를 하나의 전송 회선으로 통합하는 장치다. 이를 통해 회선 수를 줄이고, 전송 효율을 높일 수 있다. 반대 역할을 하는 장치는 DEMUX(역다중화기)다.</p>

<hr />

<h2 id="-시분할-다중화기tdm에는-어떤-방식이-있는가">❓ 시분할 다중화기(TDM)에는 어떤 방식이 있는가?</h2>

<p><strong>답변</strong>:</p>

<table>
  <thead>
    <tr>
      <th>방식</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>동기식 TDM</td>
      <td>각 채널에 고정 시간 슬롯을 주기적으로 할당. 데이터가 없어도 전송됨</td>
    </tr>
    <tr>
      <td>비동기식 TDM</td>
      <td>실제 데이터가 존재하는 채널에만 슬롯을 동적으로 할당. 효율적이지만 구현 복잡</td>
    </tr>
  </tbody>
</table>

<ul>
  <li>동기식: 단순하지만 비효율</li>
  <li>비동기식: 효율적이지만 채널 식별 정보 필요</li>
</ul>

<hr />]]></content><author><name>YUJOO-LEE</name></author><category term="Note" /><category term="SW기초" /><summary type="html"><![CDATA[📚 ChatGPT 오늘의 질문 &amp; 정리 모음]]></summary></entry><entry><title type="html">오늘의 질문 - 분산 시스템과 자원 관리</title><link href="https://leeyujoo.com/note/2025/06/03/distributed-system-and-resource-control.html" rel="alternate" type="text/html" title="오늘의 질문 - 분산 시스템과 자원 관리" /><published>2025-06-03T13:51:00+00:00</published><updated>2025-06-03T13:51:00+00:00</updated><id>https://leeyujoo.com/note/2025/06/03/distributed-system-and-resource-control</id><content type="html" xml:base="https://leeyujoo.com/note/2025/06/03/distributed-system-and-resource-control.html"><![CDATA[<h2 id="-chatgpt-오늘의-질문--정리-모음">📚 ChatGPT 오늘의 질문 &amp; 정리 모음</h2>

<hr />

<h3 id="-파일-디스크립터란">❓ 파일 디스크립터란?</h3>

<p>운영체제가 파일, 소켓, 파이프 등 입출력 자원을 관리하기 위해 부여하는 정수 ID.<br />
파일 디스크립터는 실제 파일 정보를 가리키는 핸들 역할을 하며, 커널 내부 자료구조와 연결된다.</p>

<hr />

<h3 id="-파일을-구성하는-레코드-편성-방식">❓ 파일을 구성하는 레코드 편성 방식?</h3>

<p>레코드들이 보조기억장치에 저장되는 방식에는 다음이 있다:</p>

<ul>
  <li><strong>순차 편성</strong>: 순서대로 저장, 전체 읽기에 적합</li>
  <li><strong>색인 순차 편성</strong>: 색인 테이블을 두어 빠른 검색 가능</li>
  <li><strong>해싱 편성 (또는 Direct 편성)</strong>: 해시 함수로 직접 위치 계산</li>
</ul>

<hr />

<h3 id="-해싱-편성과-direct-편성은-같은-말인가">❓ 해싱 편성과 Direct 편성은 같은 말인가?</h3>

<p>거의 같은 의미다.<br />
둘 다 해시 함수를 통해 레코드의 저장 위치를 계산하여 직접 접근하는 방식이며, 용어만 문맥에 따라 다르게 사용된다.</p>

<hr />

<h3 id="-색인-순차-파일의-색인-영역-분류">❓ 색인 순차 파일의 색인 영역 분류</h3>

<ul>
  <li><strong>트랙 색인 영역</strong>: 트랙 내부 레코드의 위치 정보</li>
  <li><strong>실린더 색인 영역</strong>: 트랙 색인들을 참조</li>
  <li><strong>마스터 색인 영역</strong>: 실린더 색인들을 통합적으로 참조</li>
</ul>

<hr />

<h3 id="-디렉터리란">❓ 디렉터리란?</h3>

<p>파일에 대한 정보를 담고 있는 특수한 형태의 파일이며,<br />
디렉터리 안에는 파일명, inode 번호 등 메타정보가 포함됨.</p>

<hr />

<h3 id="-디렉터리-구조의-종류는">❓ 디렉터리 구조의 종류는?</h3>

<ul>
  <li>단일 레벨</li>
  <li>2단계 구조</li>
  <li>트리 구조</li>
  <li>비순환 그래프 구조</li>
  <li>일반 그래프 구조 (순환 허용)</li>
</ul>

<hr />

<h3 id="-심볼릭-링크와-순환이란">❓ 심볼릭 링크와 순환이란?</h3>

<ul>
  <li><strong>심볼릭 링크</strong>: 다른 경로를 가리키는 포인터 파일</li>
  <li><strong>순환(cycle)</strong>: 링크를 따라가다 다시 자기 자신에 도달하는 구조 → 무한 루프 위험</li>
</ul>

<hr />

<h3 id="-일반-그래프-디렉터리-예시는">❓ 일반 그래프 디렉터리 예시는?</h3>

<p>예: <code class="language-plaintext highlighter-rouge">/a → /b</code>, <code class="language-plaintext highlighter-rouge">/b → /a</code>와 같이 서로를 참조하는 심볼릭 링크<br />
→ <code class="language-plaintext highlighter-rouge">find</code> 같은 순회 명령어에서 무한 반복 발생 가능</p>

<hr />

<h3 id="-접근-제어-방식-4가지">❓ 접근 제어 방식 4가지</h3>

<table>
  <thead>
    <tr>
      <th>방식</th>
      <th>기준</th>
      <th>설명</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>

<hr />

<h3 id="-어떤-방식이-실제로-가장-많이-사용되나">❓ 어떤 방식이 실제로 가장 많이 사용되나?</h3>

<p>→ <strong>접근 제어 리스트(ACL)</strong><br />
파일 중심의 접근 제어가 현실적인 운영체제 설계와 잘 맞기 때문</p>

<hr />

<h3 id="-멀티프로세서란">❓ 멀티프로세서란?</h3>

<p>하나의 컴퓨터에 <strong>두 개 이상의 CPU</strong>가 장착된 구조.<br />
병렬 처리와 성능 향상에 유리함.</p>

<hr />

<h3 id="-듀얼코어는-2개의-프로세서인가">❓ 듀얼코어는 2개의 프로세서인가?</h3>

<p>아니오.<br />
<strong>듀얼코어는 CPU 1개에 코어가 2개 있는 구조</strong>.<br />
멀티프로세서는 물리적 CPU 자체가 2개 이상.<br />
멀티프로세서는 실제로 <strong>CPU 소켓에 2개 이상의 물리 CPU를 장착</strong>하는 구조다.</p>

<hr />

<h3 id="-주종-처리기란">❓ 주종 처리기란?</h3>

<p>비대칭 멀티프로세서(AMP) 구조에서 사용되는 방식.</p>
<ul>
  <li>마스터 CPU: 전체 제어 및 운영체제 실행</li>
  <li>슬레이브 CPU: 명령 받은 작업만 수행</li>
</ul>

<hr />

<h3 id="-분리-실행-처리기란">❓ 분리 실행 처리기란?</h3>

<p><strong>Loosely Coupled System</strong>이라고도 불리며,<br />
각 프로세서가 자신의 메모리와 자원을 가지고 독립적으로 실행.<br />
→ 메시지 전송 방식으로만 통신하며 확장성과 고장 허용성이 뛰어남.</p>

<hr />

<h3 id="-위상에-따른-분산-처리-시스템-분류">❓ 위상에 따른 분산 처리 시스템 분류</h3>

<ul>
  <li><strong>중앙집중형</strong>: 하나의 컴퓨터가 모든 처리</li>
  <li><strong>계층형</strong>: 상위/하위 노드로 명령 전달</li>
  <li><strong>분산형(P2P)</strong>: 노드들이 동등하며 자율 통신</li>
</ul>

<hr />

<h3 id="-분산-시스템의-연결-구조-topologies">❓ 분산 시스템의 연결 구조 (Topologies)</h3>

<ul>
  <li><strong>스타형</strong>: 중앙 허브를 통해 연결 (SPOF 있음)</li>
  <li><strong>완전 연결형</strong>: 모든 노드가 직접 연결됨 (복잡도 높음)</li>
  <li><strong>부분 연결형</strong>: 일부 노드만 직접 연결 (유연함)</li>
  <li><strong>트리형</strong>: 계층적 부모-자식 구조</li>
  <li><strong>링형</strong>: 원형으로 연결, 단일 장애에 취약</li>
  <li><strong>버스형</strong>: 공유 버스를 통해 통신, 충돌과 병목 가능성</li>
</ul>

<hr />]]></content><author><name>YUJOO-LEE</name></author><category term="Note" /><category term="SW기초" /><summary type="html"><![CDATA[📚 ChatGPT 오늘의 질문 &amp; 정리 모음]]></summary></entry><entry><title type="html">오늘의 질문 - 디스크 구조와 스케줄링 알고리즘</title><link href="https://leeyujoo.com/note/2025/05/26/disk-scheduling.html" rel="alternate" type="text/html" title="오늘의 질문 - 디스크 구조와 스케줄링 알고리즘" /><published>2025-05-26T14:46:05+00:00</published><updated>2025-05-26T14:46:05+00:00</updated><id>https://leeyujoo.com/note/2025/05/26/disk-scheduling</id><content type="html" xml:base="https://leeyujoo.com/note/2025/05/26/disk-scheduling.html"><![CDATA[<h2 id="-chatgpt-오늘의-질문--정리-모음">📚 ChatGPT 오늘의 질문 &amp; 정리 모음</h2>

<hr />

<h3 id="-디스크-스케줄링이란">❓ 디스크 스케줄링이란?</h3>

<p>디스크 I/O 요청들을 처리하는 순서를 정하는 알고리즘
목적은 디스크 헤드의 이동을 최소화해서 전체 응답 시간을 줄이는 것</p>

<table>
  <thead>
    <tr>
      <th>알고리즘</th>
      <th>설명</th>
      <th>특징</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>FCFS</td>
      <td>First Come First Serve</td>
      <td>순서대로 처리, 비효율적</td>
    </tr>
    <tr>
      <td>SSTF</td>
      <td>Shortest Seek Time First</td>
      <td>가장 가까운 요청부터 처리, 효율적이지만 <strong>기아 발생 가능</strong></td>
    </tr>
    <tr>
      <td>SCAN</td>
      <td>헤드가 끝까지 갔다가 반대로 이동</td>
      <td>“엘리베이터 방식”, 고른 처리</td>
    </tr>
    <tr>
      <td>LOOK</td>
      <td>요청이 있는 트랙까지만 이동</td>
      <td>불필요한 이동 줄임</td>
    </tr>
    <tr>
      <td>C-SCAN</td>
      <td>한 방향으로만 이동 후 되돌아감</td>
      <td>응답 시간 균일화</td>
    </tr>
    <tr>
      <td>C-LOOK</td>
      <td>요청 있는 곳까지만 이동 후 순환</td>
      <td>최적화 + 균일한 처리</td>
    </tr>
  </tbody>
</table>

<hr />

<h3 id="-디스크의-헤드란">❓ 디스크의 헤드란?</h3>

<p>디스크 표면에서 데이터를 읽고 쓰는 물리적인 장치
회전하는 플래터 위를 움직이며 데이터를 처리함</p>

<hr />

<h3 id="-트랙이란">❓ 트랙이란?</h3>

<p>디스크 플래터에 그려진 동심원 형태의 선
하나의 트랙은 같은 반지름에 위치한 데이터 저장 구역을 의미함</p>

<hr />

<h3 id="-디스크-오버헤드란">❓ 디스크 오버헤드란?</h3>

<p>디스크에서 데이터를 실제로 전송하기 전 발생하는 부가 시간
주로 다음 세 가지로 구성됨:</p>
<ul>
  <li>탐색 시간 (헤드가 트랙으로 이동)</li>
  <li>회전 지연 (섹터가 헤드 아래 올 때까지 기다림)</li>
  <li>컨트롤러 처리 시간</li>
</ul>

<hr />

<h3 id="-sstf는-왜-기아-현상이-발생하나">❓ SSTF는 왜 기아 현상이 발생하나?</h3>

<p>가까운 요청이 계속 들어오면, 멀리 있는 요청은 계속 무시됨
결과적으로 어떤 요청은 <strong>무기한 대기</strong> 상태에 빠질 수 있음</p>

<hr />

<h3 id="-scan-look은-무엇의-약자인가">❓ SCAN, LOOK은 무엇의 약자인가?</h3>

<p>둘 다 약자가 아님
SCAN은 디스크 끝까지 왕복하며 스캔하는 동작에서,<br />
LOOK은 요청이 있는 곳까지만 이동하는 동작에서 이름이 유래됨</p>

<hr />

<h3 id="-hdd는-무엇의-약자인가">❓ HDD는 무엇의 약자인가?</h3>

<p>Hard Disk Drive
회전하는 플래터와 기계식 헤드로 구성된 저장 장치</p>

<hr />

<h3 id="-ssd는-무엇의-약자인가">❓ SSD는 무엇의 약자인가?</h3>

<p>Solid State Drive
반도체 기반 플래시 메모리로 데이터를 저장하는 장치. 움직이는 부품이 없음</p>

<hr />

<h3 id="-ssd-내부는-어떻게-생겼나">❓ SSD 내부는 어떻게 생겼나?</h3>

<p>기본 구성 요소는 다음과 같음:</p>
<ul>
  <li>NAND 플래시 메모리: 데이터를 저장하는 반도체</li>
  <li>컨트롤러: 데이터 입출력, 오류 수정 등을 담당</li>
  <li>DRAM 캐시: 속도 향상을 위한 임시 저장소 (일부 모델에만 존재)</li>
  <li>인터페이스: SATA, PCIe, M.2 등 연결 방식</li>
</ul>

<hr />]]></content><author><name>YUJOO-LEE</name></author><category term="Note" /><category term="SW기초" /><summary type="html"><![CDATA[📚 ChatGPT 오늘의 질문 &amp; 정리 모음]]></summary></entry><entry><title type="html">오늘의 질문 - 가상 기억장치와 메모리 관리 개념</title><link href="https://leeyujoo.com/note/2025/05/23/virtual-memory.html" rel="alternate" type="text/html" title="오늘의 질문 - 가상 기억장치와 메모리 관리 개념" /><published>2025-05-23T17:07:05+00:00</published><updated>2025-05-23T17:07:05+00:00</updated><id>https://leeyujoo.com/note/2025/05/23/virtual-memory</id><content type="html" xml:base="https://leeyujoo.com/note/2025/05/23/virtual-memory.html"><![CDATA[<h2 id="-chatgpt-오늘의-질문--정리-모음">📚 ChatGPT 오늘의 질문 &amp; 정리 모음</h2>

<hr />

<h3 id="-단편화에-대해서-설명해줘">❓ 단편화에 대해서 설명해줘</h3>

<p><strong>✅ 요약</strong></p>
<ul>
  <li><strong>내부 단편화</strong>: 고정 크기 블록을 할당했을 때 일부가 사용되지 않고 낭비됨</li>
  <li><strong>외부 단편화</strong>: 연속되지 않은 빈 공간들이 흩어져 있어 필요한 메모리를 할당하지 못하는 현상</li>
  <li><strong>해결책</strong>: 압축(compaction), 페이징, 가변 크기 할당</li>
</ul>

<hr />

<h3 id="-a-010kb-b-1018kb로-연속-배치하면-빈-공간이-뒤로-몰리지-않나">❓ A: 0~10KB, B: 10~18KB로 연속 배치하면 빈 공간이 뒤로 몰리지 않나?</h3>

<p><strong>✅ 요약</strong></p>
<ul>
  <li>이론적으로는 맞음: 연속된 공간에 넣으면 단편화가 줄어듦</li>
  <li>하지만 현실에서는 <strong>실행 중인 프로세스는 이동 불가하고</strong>,<br />
주소 참조 문제가 있어 OS가 임의로 위치를 조정하지 못함</li>
  <li>그래서 <strong>압축(compaction)</strong> 같은 비용이 큰 작업이 필요함</li>
</ul>

<hr />

<h3 id="-x가-먼저-16kb-쓰고-종료해서-빈공간이-생겼고-a가-그-자리에-10kb-들어가서-6kb-남은-거라고-이해해도-돼">❓ X가 먼저 16KB 쓰고 종료해서 빈공간이 생겼고, A가 그 자리에 10KB 들어가서 6KB 남은 거라고 이해해도 돼?</h3>

<p><strong>✅ 요약</strong></p>
<ul>
  <li>✅ 정확한 이해!</li>
  <li>이 흐름은 외부 단편화가 발생하는 실제 원인을 설명하는 이상적인 시나리오</li>
  <li>A는 D가 쓰던 자리에 들어가며 6KB가 남게 되고, 그 공간은 <strong>조각난 채로</strong> 남아 있게 됨</li>
  <li>이후 필요한 연속 공간이 부족하면 <strong>페이지 교체 or 압축 필요</strong></li>
</ul>

<hr />

<h3 id="-가상-기억장치는-뭐야">❓ 가상 기억장치는 뭐야?</h3>

<p><strong>✅ 요약</strong></p>
<ul>
  <li>실제 RAM보다 큰 메모리처럼 보이게 하는 OS 기능</li>
  <li>필요한 페이지만 RAM에 올리고 나머지는 디스크(swap)에 둠</li>
  <li>장점: 확장성, 보호, 효율성</li>
</ul>

<hr />

<h3 id="-어떤-페이지가-필요한지-os는-어떻게-알아">❓ 어떤 페이지가 필요한지 OS는 어떻게 알아?</h3>

<p><strong>✅ 요약</strong></p>
<ul>
  <li>CPU가 접근 시도 → RAM에 없으면 <strong>페이지 폴트 발생</strong></li>
  <li>그 순간 디스크에서 해당 페이지를 로딩 → <strong>요구 페이징(Demand Paging)</strong></li>
</ul>

<hr />

<h3 id="-페이지-단위는-누가-정해">❓ 페이지 단위는 누가 정해?</h3>

<p><strong>✅ 요약</strong></p>
<ul>
  <li>CPU + OS가 결정 (보통 4KB 고정)</li>
  <li>프로그램은 이 단위로 나뉘어 올라감</li>
  <li>빈공간이 있어도 페이지 단위에 못 미치면 사용 불가</li>
</ul>

<hr />

<h3 id="-가상-기억장치-크기는-고정이야-유동이야">❓ 가상 기억장치 크기는 고정이야? 유동이야?</h3>

<p><strong>✅ 요약</strong></p>
<ul>
  <li><strong>가상 주소 공간</strong>: CPU 구조에 따라 고정됨 (예: 32bit → 4GB)</li>
  <li><strong>스왑 공간(디스크)</strong>: OS 정책에 따라 유동적으로 설정 가능</li>
</ul>

<hr />

<h3 id="-프로그램이-종료되면-메모리는-다-회수돼">❓ 프로그램이 종료되면 메모리는 다 회수돼?</h3>

<p><strong>✅ 요약</strong></p>
<ul>
  <li>종료 시 OS가 가상 주소 공간, 물리 메모리(RAM, swap) 모두 회수함</li>
  <li>종료하지 않으면 메모리는 계속 점유된 상태로 유지됨</li>
</ul>

<hr />

<h3 id="-세그먼테이션-기법이-뭐야">❓ 세그먼테이션 기법이 뭐야?</h3>

<p><strong>✅ 요약</strong></p>
<ul>
  <li>프로그램을 의미 단위(코드, 데이터, 스택 등)로 나눔</li>
  <li>각 세그먼트는 가변 크기</li>
  <li>단점: 외부 단편화 발생 가능</li>
</ul>

<hr />

<h3 id="-세그먼트-안에서-다시-페이지로-나눠">❓ 세그먼트 안에서 다시 페이지로 나눠?</h3>

<p><strong>✅ 요약</strong></p>
<ul>
  <li>맞음. 세그먼트를 다시 페이지로 나누는 구조도 있음</li>
  <li>이걸 <strong>세그먼트 기반 페이징</strong>이라 하며, 실무에서 많이 쓰임</li>
</ul>

<hr />

<h3 id="-워킹셋은-자주-사용하는-페이지-집합이라던데-자주의-기준은">❓ 워킹셋은 자주 사용하는 페이지 집합이라던데, ‘자주’의 기준은?</h3>

<p><strong>✅ 요약</strong></p>
<ul>
  <li>일정 시간(Δ) 동안 접근된 페이지들</li>
  <li>이 시간 창(Δ)은 OS가 정책적으로 정함</li>
  <li>워킹셋만 메모리에 유지하면 스래싱 방지 가능</li>
</ul>

<hr />

<h3 id="-벨레이디의-모순이-뭐야">❓ 벨레이디의 모순이 뭐야?</h3>

<p><strong>✅ 요약</strong></p>
<ul>
  <li>FIFO처럼 단순한 페이지 교체 알고리즘에서<br />
<strong>프레임 수가 늘었는데도 페이지 폴트가 증가</strong>하는 현상</li>
  <li>LRU, Optimal 등 <strong>스택 알고리즘</strong>에서는 발생하지 않음</li>
</ul>

<hr />

<h3 id="-not-used-recently란">❓ Not Used Recently란?</h3>

<p><strong>✅ 요약</strong></p>
<ul>
  <li>최근에 접근되지 않은 페이지 (R 비트 = 0)</li>
  <li>NRU 알고리즘 등에서 교체 후보로 사용됨</li>
</ul>

<hr />

<h3 id="-수정되었다는-건-무슨-뜻이야">❓ 수정되었다는 건 무슨 뜻이야?</h3>

<p><strong>✅ 요약</strong></p>
<ul>
  <li>해당 페이지에 CPU가 <code class="language-plaintext highlighter-rouge">write</code> 연산을 수행했는가?</li>
  <li>수정됨(M 비트 = 1)이면 디스크에 저장 후 교체 필요 → 비용 큼</li>
  <li>수정되지 않았으면 그냥 제거 가능</li>
</ul>]]></content><author><name>YUJOO-LEE</name></author><category term="Note" /><category term="SW기초" /><summary type="html"><![CDATA[📚 ChatGPT 오늘의 질문 &amp; 정리 모음]]></summary></entry><entry><title type="html">eslint 사용 환경에서 no-unused-vars 에러 -&amp;gt; 경고로 설정 변경</title><link href="https://leeyujoo.com/note/2023/08/12/no-unused-vars.html" rel="alternate" type="text/html" title="eslint 사용 환경에서 no-unused-vars 에러 -&amp;gt; 경고로 설정 변경" /><published>2023-08-12T15:03:24+00:00</published><updated>2023-08-12T15:03:24+00:00</updated><id>https://leeyujoo.com/note/2023/08/12/no-unused-vars</id><content type="html" xml:base="https://leeyujoo.com/note/2023/08/12/no-unused-vars.html"><![CDATA[<p><br /></p>

<h4 id="tsconfigjson">tsconfig.json</h4>

<p><code class="language-plaintext highlighter-rouge">noUnusedLocals</code>, <code class="language-plaintext highlighter-rouge">noUnusedParameters</code> 를 false 로 변경</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"compilerOptions"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"noUnusedLocals"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
    </span><span class="nl">"noUnusedParameters"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p><br /></p>

<h4 id="eslintrccjs">.eslintrc.cjs</h4>

<p><code class="language-plaintext highlighter-rouge">rules</code> 하위의 <code class="language-plaintext highlighter-rouge">no-unused-vars</code> 는 <code class="language-plaintext highlighter-rouge">off</code>로, <code class="language-plaintext highlighter-rouge">@typescript-eslint/no-unused-vars</code> 를 <code class="language-plaintext highlighter-rouge">warn</code> 으로 변경</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">rules</span><span class="p">:</span> <span class="p">{</span>
    <span class="dl">'</span><span class="s1">no-unused-vars</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">off</span><span class="dl">'</span><span class="p">,</span>
    <span class="dl">'</span><span class="s1">@typescript-eslint/no-unused-vars</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">warn</span><span class="dl">'</span><span class="p">,</span>
  <span class="p">},</span>
<span class="p">}</span>
</code></pre></div></div>

<p><br /></p>]]></content><author><name>YUJOO-LEE</name></author><category term="Note" /><category term="IDE" /><category term="typescript" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">vite 환경에서 환경변수 사용</title><link href="https://leeyujoo.com/note/2023/08/12/vite-use-env.html" rel="alternate" type="text/html" title="vite 환경에서 환경변수 사용" /><published>2023-08-12T12:41:05+00:00</published><updated>2023-08-12T12:41:05+00:00</updated><id>https://leeyujoo.com/note/2023/08/12/vite-use-env</id><content type="html" xml:base="https://leeyujoo.com/note/2023/08/12/vite-use-env.html"><![CDATA[<h4 id="용도-별-env-파일-생성">용도 별 env 파일 생성</h4>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.env                # 모든 상황에서 사용될 환경 변수
.env.local          # 모든 상황에서 사용되나, 로컬 개발 환경에서만 사용될(Git에 의해 무시될) 환경 변수
.env.[mode]         # 특정 모드에서만 사용될 환경 변수
.env.[mode].local   # 특정 모드에서만 사용되나, 로컬 개발 환경에서만 사용될(Git에 의해 무시될) 환경 변수
</code></pre></div></div>

<p><br /></p>

<h4 id="환경변수-생성">환경변수 생성</h4>

<p>vite 환경에서 사용할 변수는 앞에 <code class="language-plaintext highlighter-rouge">VITE_</code> 를 붙인다.</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>VITE_TEXT_A=aaa
</code></pre></div></div>

<p><br /></p>

<h4 id="사용">사용</h4>

<ul>
  <li>
    <p>javascript</p>

    <ul>
      <li><code class="language-plaintext highlighter-rouge">import.meta.env.VITE_TEXT_A</code> 으로 사용</li>
      <li>env 파일 내 해당 변수가 없으면 <code class="language-plaintext highlighter-rouge">undefined</code> 반환</li>
    </ul>
  </li>
  <li>
    <p>html</p>

    <ul>
      <li><code class="language-plaintext highlighter-rouge">%VITE_TEXT_A%</code> 으로 사용</li>
      <li>env 파일 내 해당 변수가 있어야 대체되며, 없으면 일반 텍스트로 노출됨</li>
    </ul>
  </li>
</ul>

<p><br /></p>

<h4 id="참고-vite-공식-가이드">참고 (vite 공식 가이드)</h4>

<p>https://ko.vitejs.dev/guide/env-and-mode.html</p>]]></content><author><name>YUJOO-LEE</name></author><category term="Note" /><category term="vite" /><summary type="html"><![CDATA[용도 별 env 파일 생성]]></summary></entry><entry><title type="html">download Blob file</title><link href="https://leeyujoo.com/note/2023/07/30/response_type_blob.html" rel="alternate" type="text/html" title="download Blob file" /><published>2023-07-30T00:59:05+00:00</published><updated>2023-07-30T00:59:05+00:00</updated><id>https://leeyujoo.com/note/2023/07/30/response_type_blob</id><content type="html" xml:base="https://leeyujoo.com/note/2023/07/30/response_type_blob.html"><![CDATA[<p>excel 파일을 blob 형태로 다운로드 받아야 하는데, 할 줄 몰라서 헤맴…</p>

<p>blob 데이터 다운로드 시 header 에 response type 을 blob 으로 지정해 요청한다.</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">post</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span><span class="p">(</span><span class="nx">url</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">data</span><span class="p">:</span> <span class="nx">T</span><span class="p">,</span> <span class="nx">isResponseTypeBlob</span><span class="p">?:</span> <span class="nx">boolean</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">config</span><span class="p">:</span> <span class="nx">AxiosRequestConfig</span> <span class="o">=</span> <span class="p">{</span>
<span class="na">baseURL</span><span class="p">:</span> <span class="nx">API_ROOT</span><span class="p">,</span>
<span class="p">};</span>

<span class="k">if</span> <span class="p">(</span><span class="nx">isResponseTypeBlob</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">config</span><span class="p">.</span><span class="nx">responseType</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">blob</span><span class="dl">'</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">return</span> <span class="nx">axios</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">data</span><span class="p">,</span> <span class="nx">config</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>blob 다운로드 시에만 해당 헤더를 보내도록 했다.</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">const</span> <span class="nx">downloadResponseTypeBlobFile</span> <span class="o">=</span> <span class="p">(</span><span class="nx">data</span><span class="p">:</span> <span class="kr">any</span><span class="p">,</span> <span class="nx">filename</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">contentType</span><span class="p">?:</span> <span class="kr">string</span><span class="p">):</span> <span class="k">void</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">url</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">URL</span><span class="p">.</span><span class="nx">createObjectURL</span><span class="p">(</span><span class="k">new</span> <span class="nx">Blob</span><span class="p">([</span><span class="nx">data</span><span class="p">],</span> <span class="p">{</span> <span class="na">type</span><span class="p">:</span> <span class="nx">contentType</span> <span class="p">}));</span>
  <span class="kd">const</span> <span class="nx">link</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">a</span><span class="dl">'</span><span class="p">);</span>
  <span class="nx">link</span><span class="p">.</span><span class="nx">href</span> <span class="o">=</span> <span class="nx">url</span><span class="p">;</span>
  <span class="nx">link</span><span class="p">.</span><span class="nx">setAttribute</span><span class="p">(</span><span class="dl">'</span><span class="s1">download</span><span class="dl">'</span><span class="p">,</span> <span class="nx">filename</span><span class="p">);</span>

  <span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">link</span><span class="p">);</span>
  <span class="nx">link</span><span class="p">.</span><span class="nx">click</span><span class="p">();</span>
  <span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">removeChild</span><span class="p">(</span><span class="nx">link</span><span class="p">);</span>
<span class="p">};</span>
</code></pre></div></div>]]></content><author><name>YUJOO-LEE</name></author><category term="Note" /><category term="axios" /><summary type="html"><![CDATA[excel 파일을 blob 형태로 다운로드 받아야 하는데, 할 줄 몰라서 헤맴…]]></summary></entry><entry><title type="html">SVG 아이콘 background-image 로 사용하기</title><link href="https://leeyujoo.com/note/2023/01/31/svg_icon.html" rel="alternate" type="text/html" title="SVG 아이콘 background-image 로 사용하기" /><published>2023-01-31T00:25:14+00:00</published><updated>2023-01-31T00:25:14+00:00</updated><id>https://leeyujoo.com/note/2023/01/31/svg_icon</id><content type="html" xml:base="https://leeyujoo.com/note/2023/01/31/svg_icon.html"><![CDATA[<p>APP UI에 SVG 아이콘을 css의 background-image 로 썻는데 꽤 편리하고 괜찮은 것 같아서 남겨둔다.</p>

<p>SVG 코드를 <a href="https://yoksel.github.io/url-encoder/">URL-encoder for SVG</a> 페이지의 Insert SVG: 부분에 입력하면 아래 Ready for CSS: 부분에 인코딩되어 출력된다.</p>

<p>SVG 아이콘은 그때그때 검색해서 <a href="https://www.flaticon.com/kr/icon-fonts-most-downloaded">flaticon</a> 등의 사이트에서 찾아서 사용한다.</p>

<p><br /></p>

<p>SVG 이미지를 css에서 다루면서 가장 유용했던 부분은 체크박스 커스텀이었다.</p>

<p>button이나 textarea, 특히 타입이 여러개로 나뉘는 Input 은 컴포넌트화 해서 사용하는 편인데, 체크박스나 라디오 타입은 커스터마이징 하기 번거로운 편이다.</p>

<p><code class="language-plaintext highlighter-rouge">appearance: none;</code> 을 주고 다 안보이게 한 다음에 새로 만들어야 하는데, 이 때 체크 모양의 SVG 아이콘을 배경이미지로 하여 유용하게 사용했다.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">Checkbox</span> <span class="o">=</span> <span class="p">(</span><span class="nx">props</span> <span class="p">:</span> <span class="nx">InputHTMLAttributes</span><span class="o">&lt;</span><span class="nx">HTMLInputElement</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="k">return</span> <span class="p">(</span>
    <span class="o">&lt;</span><span class="nx">Styled</span><span class="p">.</span><span class="nx">Checkbox</span> <span class="p">{...</span><span class="nx">props</span><span class="p">}</span> <span class="sr">/</span><span class="err">&gt;
</span>  <span class="p">)</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">Styled</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">Checkbox</span><span class="p">:</span> <span class="nx">styled</span><span class="p">.</span><span class="nx">input</span><span class="s2">`
    appearance: none;
    border: 1px solid #ddd;
    background-color: #f6f6f6;
    border-radius: 5px;
    width: 20px;
    height: 20px;
    cursor: pointer;

    &amp;:checked{
      border-color: transparent;
      background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M5.707 7.293a1 1 0 0 0-1.414 1.414l2 2a1 1 0 0 0 1.414 0l4-4a1 1 0 0 0-1.414-1.414L7 8.586 5.707 7.293z'/%3e%3c/svg%3e");
      background-size: 100% 100%;
      background-position: 50%;
      background-repeat: no-repeat;
      background-color: #900000;
    }
  `</span><span class="p">,</span>
<span class="p">}</span>
</code></pre></div></div>]]></content><author><name>YUJOO-LEE</name></author><category term="Note" /><category term="svg" /><category term="css" /><summary type="html"><![CDATA[APP UI에 SVG 아이콘을 css의 background-image 로 썻는데 꽤 편리하고 괜찮은 것 같아서 남겨둔다.]]></summary></entry><entry><title type="html">README 파일내 뱃지 아이콘 추가</title><link href="https://leeyujoo.com/note/2023/01/31/readme_icon.html" rel="alternate" type="text/html" title="README 파일내 뱃지 아이콘 추가" /><published>2023-01-31T00:05:04+00:00</published><updated>2023-01-31T00:05:04+00:00</updated><id>https://leeyujoo.com/note/2023/01/31/readme_icon</id><content type="html" xml:base="https://leeyujoo.com/note/2023/01/31/readme_icon.html"><![CDATA[<p>매번 검색하기 번거로워서 남겨두는 글.</p>

<p><br /></p>

<p>README 파일 작성하면서 사용한 라이브러리/프레임워크를 뱃지 형태의 이미지로 나열했는데,</p>

<p><a href="https://shields.io/">shields.io</a> 에서 제공하는 url 로 원하는 뱃지를 만들어 사용할 수 있다.</p>

<p><br /></p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">"https://img.shields.io/badge/{표시텍스트}-{컬러코드}?style=flat-square&amp;logo={로고}&amp;logoColor=white"</span><span class="nt">/&gt;</span> 
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">{}</code> 표시 한 부분만 수정해서 사용한다.</p>

<p><br /></p>

<p><code class="language-plaintext highlighter-rouge">{컬러코드}</code> : HexCode 형태의 컬러코드</p>

<p><code class="language-plaintext highlighter-rouge">{로고}</code> : 표시할 라이브러리 이름</p>

<p><code class="language-plaintext highlighter-rouge">{표시텍스트}</code> : 뱃지에 표시할 텍스트 (라이브러리 이름을 동일하게 기재)</p>

<p><br /></p>

<p>정확한 로고 출력용 라이브러리 이름과 컬러코드는 <a href="https://simpleicons.org/">simpleicons.org</a> 사이트에서 손쉽게 찾을 수 있다.</p>

<p><br /></p>

<p>아래는 기존에 사용한 뱃지들이다.</p>

<p><img src="https://img.shields.io/badge/Vite-646CFF?style=flat-square&amp;logo=Vite&amp;logoColor=white" />  <code class="language-plaintext highlighter-rouge">&lt;img src="https://img.shields.io/badge/Vite-646CFF?style=flat-square&amp;logo=Vite&amp;logoColor=white"/&gt;</code></p>

<p><img src="https://img.shields.io/badge/Next.js-000000?style=flat-square&amp;logo=Next.js&amp;logoColor=white" /> <code class="language-plaintext highlighter-rouge">&lt;img src="https://img.shields.io/badge/Next.js-000000?style=flat-square&amp;logo=Next.js&amp;logoColor=white"/&gt;</code></p>

<p><img src="https://img.shields.io/badge/React-61DAFB?style=flat-square&amp;logo=react&amp;logoColor=white" /> <code class="language-plaintext highlighter-rouge">&lt;img src="https://img.shields.io/badge/React-61DAFB?style=flat-square&amp;logo=react&amp;logoColor=white"/&gt; </code></p>

<p><img src="https://img.shields.io/badge/TypeScript-3178C6?style=flat-square&amp;logo=typeScript&amp;logoColor=white" /> <code class="language-plaintext highlighter-rouge">&lt;img src="https://img.shields.io/badge/TypeScript-3178C6?style=flat-square&amp;logo=typeScript&amp;logoColor=white"/&gt;</code></p>

<p><img src="https://img.shields.io/badge/ReactQuery-FF4154?style=flat-square&amp;logo=ReactQuery&amp;logoColor=white" /> <code class="language-plaintext highlighter-rouge">&lt;img src="https://img.shields.io/badge/ReactQuery-FF4154?style=flat-square&amp;logo=ReactQuery&amp;logoColor=white"/&gt;</code></p>

<p><img src="https://img.shields.io/badge/Styled-components-DB7093?style=flat-square&amp;logo=styled-components&amp;logoColor=white" /> <code class="language-plaintext highlighter-rouge">&lt;img src="https://img.shields.io/badge/Styled-components-DB7093?style=flat-square&amp;logo=styled-components&amp;logoColor=white"/&gt;</code></p>

<p><img src="https://img.shields.io/badge/ChakraUI-319795?style=flat-square&amp;logo=ChakraUI&amp;logoColor=white" /> <code class="language-plaintext highlighter-rouge">&lt;img src="https://img.shields.io/badge/ChakraUI-319795?style=flat-square&amp;logo=ChakraUI&amp;logoColor=white"/&gt;</code></p>

<p><img src="https://img.shields.io/badge/Web3.js-F16822?style=flat-square&amp;logo=Web3.js&amp;logoColor=white" /> <code class="language-plaintext highlighter-rouge">&lt;img src="https://img.shields.io/badge/Web3.js-F16822?style=flat-square&amp;logo=Web3.js&amp;logoColor=white"/&gt;</code></p>

<p><img src="https://img.shields.io/badge/Electron-47848F?style=flat-square&amp;logo=Electron&amp;logoColor=white" /> <code class="language-plaintext highlighter-rouge">&lt;img src="https://img.shields.io/badge/Electron-47848F?style=flat-square&amp;logo=Electron&amp;logoColor=white"/&gt;</code></p>

<p><img src="https://img.shields.io/badge/Firebase-FFCA28?style=flat-square&amp;logo=Firebase&amp;logoColor=white" /> <code class="language-plaintext highlighter-rouge">&lt;img src="https://img.shields.io/badge/Firebase-FFCA28?style=flat-square&amp;logo=Firebase&amp;logoColor=white"/&gt;</code></p>]]></content><author><name>YUJOO-LEE</name></author><category term="Note" /><category term="markdown" /><category term="github" /><summary type="html"><![CDATA[매번 검색하기 번거로워서 남겨두는 글.]]></summary></entry><entry><title type="html">그림으로 쉽게 배우는 자료구조와 알고리즘 (기본편)</title><link href="https://leeyujoo.com/review/2023/01/01/datastructure_algorithm.html" rel="alternate" type="text/html" title="그림으로 쉽게 배우는 자료구조와 알고리즘 (기본편)" /><published>2023-01-01T11:53:05+00:00</published><updated>2023-01-01T11:53:05+00:00</updated><id>https://leeyujoo.com/review/2023/01/01/datastructure_algorithm</id><content type="html" xml:base="https://leeyujoo.com/review/2023/01/01/datastructure_algorithm.html"><![CDATA[<p>인프런 강의 <a href="https://www.inflearn.com/course/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EA%B8%B0%EB%B3%B8">그림으로 쉽게 배우는 자료구조와 알고리즘 (기본편)</a> 수강내용 정리</p>

<p><br /></p>

<h3 id="시간복잡도">시간복잡도</h3>

<p>특정 알고리즘이 어떤 문제를 해결하는 데 걸리는 시간을 표현하는 방법이다.</p>

<p>반복문은 코드 성능에 많은 영향을 준다.</p>

<p>반복문이 여러 번 반복될수록 실행시간이 길어진다.</p>

<p>따라서 특정 알고리즘의 성능을 평가할 때 해당 알고리즘의 반복문을 보고 성능을 평가한다.</p>

<p><br /></p>

<h4 id="big-ω-빅-오메가">Big-Ω (빅 오메가)</h4>

<p>알고리즘의 최선의 시간 복잡도를 나타낸다.</p>

<p>즉, 알고리즘의 수행 시간이 가장 짧은 경우를 표기한다.</p>

<p><br /></p>

<h4 id="big-o-빅-오">Big-O (빅 오)</h4>

<p>알고리즘의 최악의 시간복잡도를 나타낸다.</p>

<p>즉, 알고리즘의 수행 시간이 가장 오래 걸리는 경우를 표기한다.</p>

<p><br /></p>

<h4 id="big-θ-빅-세타">Big-θ (빅 세타)</h4>

<p>특정 알고리즘의 범위를 나타낸다.</p>

<p>알고리즘의 수행 시간이 A보다는 크고 B보다는 작다고 표기하는 표현법이다.</p>

<p>빅세타는 일종의 평균값과 유사한데, 평균값이 높은 정확성을 얻기 위해서는 많은 경우의 수가 필요하다.</p>

<p>또한 때로는 구하기 어려울 수도 있으며 공학적인 신뢰도는 평균보다는 최악의 값이 더 높기 때문에 빅세타보다 빅오를 가장 흔하게 사용한다.</p>

<p><br /></p>

<h3 id="배열">배열</h3>

<p>일반적으로 프로그래밍 언어에서 배열을 선언할 때에는 배열의 크기를 알려주어야 한다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">arr</span><span class="p">[</span><span class="mi">10</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">};</span>
</code></pre></div></div>

<p>위와 같이 선언하면 운영체제는 메모리에서 숫자 10개가 들어갈 연속된 빈 공간을 찾아서 1, 2, 3, 4, 5 를 할당하고, 배열의 시작 주소만 기억한다.</p>

<p>프로그램에서 배열의 세 번째 원소에 접근하고 싶다면 <code class="language-plaintext highlighter-rouge">arr[2]</code> 와 같이 인덱스로 한번에 접근한다.</p>

<p>인덱스 참조는 길이에 상관 없이 한 번에 가져오기 때문에 O(1) 의 성능을 가진다.</p>

<p>따라서 배열은 참조에서 좋은 성능을 보인다.</p>

<p>하지만 데이터 삽입, 삭제의 성능은 좋지 않다.</p>

<p>운영체제는 처음에 요청한 길이 만큼의 메모리만 할당했기 때문에, 데이터가 추가된다면 추가된 길이를 포함한 전체 길이 만큼의 메모리를 다시 찾아서 새로 할당해야 하기 때문이다.</p>

<p>하지만 자바스크립트에서 배열은 상황에 따라서 연속적, 불연속적으로 메모리를 할당한다.</p>

<p>불연속적으로 메모리를 할당한 후 내부적으로 연결해서 사용자에게 연속된 것처럼 보이도록 한다.</p>

<p><br /></p>

<h3 id="연결리스트">연결리스트</h3>

<p>배열의 단점을 개선하기 위해 나온 방법으로, 저장하려는 데이터를 메모리 공간에 분산해서 할당하고 이 데이터들을 서로 연결해주는 방법이다.</p>

<p>데이터를 담는 변수와 다음 데이터를 가리키는 노드(Node) 를 만들어서 수행한다.</p>

<p>연결리스트는 첫 노드의 주소만 알고 있으면 다른 모든 노드에 접근할 수 있다.</p>

<p>또한 데이터를 삽입할 때 빈 메모리 공간 아무 곳에 추가되는 데이터를 생성하고 기존 리스트에 연결해주면 되기 때문에 삽입, 삭제의 성능이 좋다.</p>

<p>하지만 배열처럼 메모리에 연속적으로 저장되어 있지 않기 때문에 데이터 참조 시에는 첫번째 노드에서 참조 해당 노드까지 하나씩 찾아야 하기 때문에 O(n) 의 성능을 가진다.</p>

<p><br /></p>

<h3 id="스택">스택</h3>

<p>먼저 들어간 데이터가 나중에 나오는 규칙이 있는 자료구조이다.</p>

<p>head 에만 삽입, 제거한다.</p>

<p><br /></p>

<h3 id="큐">큐</h3>

<p>먼저 들어간 데이터가 먼저 나오는 규칙이 있는 자료구조이다.</p>

<p>head 에서 삽입하고 tail 에서 제거한다.</p>

<p><br /></p>

<h3 id="덱">덱</h3>

<p>데이터의 삽입, 제거를 head 와 tail 에서 선택해 자유롭게 할 수 있는 자료구조이다.</p>

<p><br /></p>

<h3 id="해시테이블">해시테이블</h3>

<p>해시(Hash), 맵(Map), 해시맵(HashMap), 딕셔너리(Dictionary) 라고도 불린다.</p>

<p>일정한 계산을 하는 해시 함수를 거쳐서 테이블에 Key, Value 의 형태로 데이터를 저장하는 자료구조이다.</p>

<p>저장할때 동일 Key 에 여러개의 Value 가 들어가 충돌이 날 것을 대비해 Value 를 연결리스트로 구성한다.</p>

<p>Key 만 알면 Value 에 O(1)의 성능으로 읽기, 삽입, 수정, 삭제가 가능하다.</p>

<p>자바스크립트의 객체는 해시테이블이다.</p>

<p><br /></p>

<h3 id="셋">셋</h3>

<p>데이터의 중복을 허용하지 않는 자료구조이다.</p>

<p>해시테이블을 이용해서 구현하기 때문에 해시셋이라고도 한다.</p>

<p>셋 구현시에는 해시테이블의 Key 만 사용하고 Value 는 사용하지 않는다.</p>

<p>Key 가 Key 임과 동시에 Value 의 역할도 하기 때문이다.</p>

<p><br /></p>

<h3 id="재귀함수">재귀함수</h3>

<p>자기 자신을 참조하는 함수이다.</p>

<p>무한반복 되지 않도록 기저 조건(탈출 조건)을 반드시 설정한다.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">recursion</span><span class="p">(</span><span class="nx">number</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="nx">number</span> <span class="o">&gt;</span> <span class="mi">10</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>  <span class="c1">// 기저 조건</span>

  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">number</span><span class="p">);</span>
  <span class="nx">recursion</span><span class="p">(</span><span class="nx">number</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>  <span class="c1">// 자기 자신 호출</span>
<span class="p">}</span>

<span class="nx">recursion</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</code></pre></div></div>

<p>위 코드 실행 시 함수를 1 으로 시작해 해당 숫자를 콘솔에 표시하고, 해당 숫자에 1을 더해 반복한 후, 숫자가 10 보다 커지면 종료한다.</p>

<p>재귀는 두가지 패턴을 가진다.</p>

<p>첫번째는 위와 같이 단순히 반복 실행을 하는 것이다.</p>

<p>이 경우 일반적인 반복문과 비교해 이점이 되는 부분이 없고 오히려 성능은 for 문보다 좋지 않다.</p>

<p><br /></p>

<p>두번째 패턴은 하위 문제의 결과를 기반으로 현재 문제를 계산하는 것이다.</p>

<p>재귀의 위력은 이러한 하향식 계산에 있다.</p>

<p>아래 팩토리얼을 구하는 함수로 하향식 계산을 이해할 수 있다.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">factorial</span><span class="p">(</span><span class="nx">number</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="nx">number</span> <span class="o">===</span> <span class="mi">1</span> <span class="o">||</span> <span class="nx">number</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
  
  <span class="k">return</span> <span class="nx">number</span> <span class="o">*</span> <span class="nx">factorial</span><span class="p">(</span><span class="nx">number</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>

<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">factorial</span><span class="p">(</span><span class="mi">5</span><span class="p">));</span>
</code></pre></div></div>

<p>위 코드의 <code class="language-plaintext highlighter-rouge">number * factorial(number - 1)</code> 이 하위 문제인 <code class="language-plaintext highlighter-rouge">factorial(number - 1)</code> 부분이 이미 계산되었음을 예상하고 해당 값으로 현재 문제를 계산하는 부분이다.</p>

<p><br /></p>

<h3 id="정렬">정렬</h3>

<p>배열에 무작위로 섞인 숫자를 정렬하는 방법은 여러가지가 있다.</p>

<p><br /></p>

<h4 id="버블-정렬">버블 정렬</h4>

<p>서로 인접한 두 원소를 검사하여 정렬하는 알고리즘으로, 인접한 2개의 데이터를 비교하여 크기가 순서대로 되어 있지 않으면 서로 교환한다.</p>

<p>이해와 구현이 간단하지만 성능이 O(n2) 으로 좋지 않다.</p>

<p><br /></p>

<h4 id="선택-정렬">선택 정렬</h4>

<p>정렬되지 않은 영역의 첫 번째 원소를 시작으로, 마지막 원소까지 비교 후, 가장 작은 값을 첫 번째 원소로 가져오는 것을 반복하는 알고리즘이다.</p>

<p>버블 정렬과 마찬가지로 이해와 구현이 간단하지만 성능이 O(n2) 으로 좋지 않다.</p>

<p><br /></p>

<h4 id="삽입-정렬">삽입 정렬</h4>

<p>정렬되지 않은 영역에서 데이터를 하나씩 꺼내서 정렬된 영역 내 알맞은 위치에 삽입해서 정렬하는 알고리즘이다.</p>

<p>버블 정렬, 선택 정렬과 마찬가지로 이해와 구현이 간단하지만 성능이 O(n2) 으로 좋지 않다.</p>

<p><br /></p>

<h4 id="병합-정렬">병합 정렬</h4>

<p>하나의 리스트를 반으로 쪼개고 분할된 부분 리스트를 정렬한 다음, 두 개의 정렬된 부분 리스트를 병합하여 전체가 정렬된 리스트가 되게 하는 방법으로, 재귀를 통해 구현하는 정렬 알고리즘이다.</p>

<p>이해와 구현이 다소 어려울 수 있지만, O(nlogn) 으로 성능이 좋다.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">merge</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">leftIndex</span><span class="p">,</span> <span class="nx">midIndex</span><span class="p">,</span> <span class="nx">rightIndex</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">let</span> <span class="nx">leftAreaIndex</span> <span class="o">=</span> <span class="nx">leftIndex</span><span class="p">;</span>
  <span class="kd">let</span> <span class="nx">rightAreaIndex</span> <span class="o">=</span> <span class="nx">midIndex</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
  <span class="kd">const</span> <span class="nx">tempArr</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">(</span><span class="nx">rightIndex</span> <span class="o">+</span> <span class="mi">1</span><span class="p">).</span><span class="nx">fill</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
  <span class="kd">let</span> <span class="nx">tempArrIndex</span> <span class="o">=</span> <span class="nx">leftIndex</span><span class="p">;</span>

  <span class="k">while</span> <span class="p">(</span><span class="nx">leftAreaIndex</span> <span class="o">&lt;=</span> <span class="nx">midIndex</span> <span class="o">&amp;&amp;</span> <span class="nx">rightAreaIndex</span> <span class="o">&lt;=</span> <span class="nx">rightIndex</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">arr</span><span class="p">[</span><span class="nx">leftAreaIndex</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="nx">arr</span><span class="p">[</span><span class="nx">rightAreaIndex</span><span class="p">])</span> <span class="p">{</span>
      <span class="nx">tempArr</span><span class="p">[</span><span class="nx">tempArrIndex</span><span class="p">]</span> <span class="o">=</span> <span class="nx">arr</span><span class="p">[</span><span class="nx">leftAreaIndex</span><span class="o">++</span><span class="p">];</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
      <span class="nx">tempArr</span><span class="p">[</span><span class="nx">tempArrIndex</span><span class="p">]</span> <span class="o">=</span> <span class="nx">arr</span><span class="p">[</span><span class="nx">rightAreaIndex</span><span class="o">++</span><span class="p">];</span>
    <span class="p">}</span>
    <span class="nx">tempArrIndex</span><span class="o">++</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="k">if</span> <span class="p">(</span><span class="nx">leftAreaIndex</span> <span class="o">&gt;</span> <span class="nx">midIndex</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">i</span> <span class="o">=</span> <span class="nx">rightAreaIndex</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;=</span> <span class="nx">rightIndex</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">tempArr</span><span class="p">[</span><span class="nx">tempArrIndex</span><span class="o">++</span><span class="p">]</span> <span class="o">=</span> <span class="nx">arr</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
    <span class="p">}</span>
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">i</span> <span class="o">=</span> <span class="nx">leftAreaIndex</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;=</span> <span class="nx">midIndex</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">tempArr</span><span class="p">[</span><span class="nx">tempArrIndex</span><span class="o">++</span><span class="p">]</span> <span class="o">=</span> <span class="nx">arr</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
    <span class="p">}</span>
  <span class="p">}</span>

  <span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">i</span> <span class="o">=</span> <span class="nx">leftIndex</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;=</span> <span class="nx">rightIndex</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">arr</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="nx">tempArr</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nx">mergeSort</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">leftIndex</span><span class="p">,</span> <span class="nx">rightIndex</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="nx">leftIndex</span> <span class="o">&lt;</span> <span class="nx">rightIndex</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">midIndex</span> <span class="o">=</span> <span class="nb">parseInt</span><span class="p">((</span><span class="nx">leftIndex</span> <span class="o">+</span> <span class="nx">rightIndex</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">);</span>
    <span class="nx">mergeSort</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">leftIndex</span><span class="p">,</span> <span class="nx">midIndex</span><span class="p">);</span>
    <span class="nx">mergeSort</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">midIndex</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">rightIndex</span><span class="p">);</span>
    <span class="nx">merge</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">leftIndex</span><span class="p">,</span> <span class="nx">midIndex</span><span class="p">,</span> <span class="nx">rightIndex</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">arr</span> <span class="o">=</span> <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">6</span><span class="p">];</span>

<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">===== 정렬 전 =====</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">arr</span><span class="p">);</span>

<span class="nx">mergeSort</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">arr</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">==== 정렬 후 =====</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">arr</span><span class="p">);</span>
</code></pre></div></div>

<p><br /></p>

<h4 id="퀵-정렬">퀵 정렬</h4>

<p>병합 정렬과 같이 재귀를 사용하는 분할 정복 알고리즘이다.</p>

<p>정렬하기 전, 배열에 있는 숫자 중 하나를 피벗으로 설정한다.</p>

<p>그 피벗을 기준으로 두 개의 비균등한 크기로 분할하고 분할된 부분 리스트를 정렬한 다음, 두 개의 정렬된 부분 리스트를 합하여 전체가 정렬된 리스트가 되게 한다.</p>

<p>고른 피벗의 값에 따라서 성능이 달라질 수 있다.</p>

<p>평균적으로 θ(nlogn), 최악의 경우 O(n2)의 성능을 갖는데, 실제로 병합 정렬과 비교하면 퀵정렬이 더 적은 비교와 메모리 공간을 차지하기 때문에 더 좋은 알고리즘으로 평가된다.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">quickSort</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">left</span><span class="p">,</span> <span class="nx">right</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="nx">left</span> <span class="o">&lt;=</span> <span class="nx">right</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">pivot</span> <span class="o">=</span> <span class="nx">divide</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">left</span><span class="p">,</span> <span class="nx">right</span><span class="p">);</span>
    <span class="nx">quickSort</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">left</span><span class="p">,</span> <span class="nx">pivot</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
    <span class="nx">quickSort</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">pivot</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">right</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nx">divide</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">left</span><span class="p">,</span> <span class="nx">right</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">let</span> <span class="nx">pivot</span> <span class="o">=</span> <span class="nx">arr</span><span class="p">[</span><span class="nx">left</span><span class="p">];</span>
  <span class="kd">let</span> <span class="nx">leftStartIndex</span> <span class="o">=</span> <span class="nx">left</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
  <span class="kd">let</span> <span class="nx">rightStartIndex</span> <span class="o">=</span> <span class="nx">right</span><span class="p">;</span>

  <span class="k">while</span> <span class="p">(</span><span class="nx">leftStartIndex</span> <span class="o">&lt;=</span> <span class="nx">rightStartIndex</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">while</span> <span class="p">(</span><span class="nx">leftStartIndex</span> <span class="o">&lt;=</span> <span class="nx">right</span> <span class="o">&amp;&amp;</span> <span class="nx">pivot</span> <span class="o">&gt;=</span> <span class="nx">arr</span><span class="p">[</span><span class="nx">leftStartIndex</span><span class="p">])</span> <span class="p">{</span>
      <span class="nx">leftStartIndex</span><span class="o">++</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">while</span> <span class="p">(</span><span class="nx">rightStartIndex</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="nx">left</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="nx">pivot</span> <span class="o">&lt;=</span> <span class="nx">arr</span><span class="p">[</span><span class="nx">rightStartIndex</span><span class="p">])</span> <span class="p">{</span>
      <span class="nx">rightStartIndex</span><span class="o">--</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">if</span> <span class="p">(</span><span class="nx">leftStartIndex</span> <span class="o">&lt;=</span> <span class="nx">rightStartIndex</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">swap</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">leftStartIndex</span><span class="p">,</span> <span class="nx">rightStartIndex</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span>

  <span class="nx">swap</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">left</span><span class="p">,</span> <span class="nx">rightStartIndex</span><span class="p">);</span>
  <span class="k">return</span> <span class="nx">rightStartIndex</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nx">swap</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">index1</span><span class="p">,</span> <span class="nx">index2</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">temp</span> <span class="o">=</span> <span class="nx">arr</span><span class="p">[</span><span class="nx">index1</span><span class="p">];</span>
  <span class="nx">arr</span><span class="p">[</span><span class="nx">index1</span><span class="p">]</span> <span class="o">=</span> <span class="nx">arr</span><span class="p">[</span><span class="nx">index2</span><span class="p">];</span>
  <span class="nx">arr</span><span class="p">[</span><span class="nx">index2</span><span class="p">]</span> <span class="o">=</span> <span class="nx">temp</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">arr</span> <span class="o">=</span> <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">6</span><span class="p">];</span>

<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">===== 정렬 전 =====</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">arr</span><span class="p">);</span>

<span class="nx">quickSort</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">arr</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">==== 정렬 후 =====</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">arr</span><span class="p">);</span>
</code></pre></div></div>

<p>참고로 <a href="https://search.shopping.naver.com/book/catalog/32472713016">베스트셀러모던 자바스크립트 Deep Dive</a> 에 의하면 자바스크립트의 <code class="language-plaintext highlighter-rouge">Array.sort()</code> 메서드는 퀵정렬을 사용했었다.</p>

<p>하지만 중복 값이 있을 때 불안정하다는 점이 있어서 ECMAScript 2019(ES10) 에서 timsort 알고리즘을 사용하도록 변경되었다고 한다.</p>

<p><br /></p>

<h4 id="팀-정렬">팀 정렬</h4>

<p>강의 내용에는 없었지만 자바스크립트에서 사용한다는 알고리즘이라고 하니 개인적으로 궁금해져서 찾아봤다.</p>

<p>소프트웨어 엔지니어 Tim Peters에 의해 만들어진 알고리즘이다.</p>

<p>삽입 정렬과 병합 정렬을 결합하여 병합 정렬을 최적화했다.</p>

<p>팀 정렬은 일정 사이즈의 부분 리스트를 얻고(divide), 각각의 부분리스트들에 대해 삽입정렬을 수행하며 정렬을 하며(sort), 정렬 된 부분리스트들을 다시 합치는 방식(conqure)을 사용한다.</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/NVIjHj-lrT4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p><br /></p>

<h3 id="메모이제이션">메모이제이션</h3>

<p>하향식 계산 시 동일한 연산의 반복으로 연산 속도가 느려지는 것을 방지하기 위해 연산을 한번 실행한 값을 저장해두고 재연산을 하지 않고 저장값을 사용하는 방법이다.</p>

<p>중복 계산을 하지 않아서 속도가 빠르며, 하향식 계산 방식의 재귀 처리로 어려운 문제를 간단하게 해결할 수 있다.</p>

<p>속도를 위해 메모리를 사용하는 방법으로, 대표적으로 메모리와 CPU의 속도차이를 극복하기 위해 만들어진 캐시가 있다.</p>

<p>아래 두 함수는 피보나치 수열의 특정 위치의 값을 구하는 함수인데, 첫번째는 모든 연산을 진행하고, 두번째는 중복되는 연산은 저장값을 사용하는 방식이다.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">fibonacci1</span><span class="p">(</span><span class="nx">n</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="nx">n</span> <span class="o">===</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">n</span> <span class="o">===</span> <span class="mi">1</span><span class="p">)</span> <span class="k">return</span> <span class="nx">n</span><span class="p">;</span>
  <span class="k">return</span> <span class="nx">fibonacci1</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="nx">fibonacci1</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nx">fibonacci2</span><span class="p">(</span><span class="nx">n</span><span class="p">,</span> <span class="nx">memo</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="nx">n</span> <span class="o">===</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">n</span> <span class="o">===</span> <span class="mi">1</span><span class="p">)</span> <span class="k">return</span> <span class="nx">n</span><span class="p">;</span>

  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">memo</span><span class="p">[</span><span class="nx">n</span><span class="p">])</span> <span class="p">{</span>
    <span class="nx">memo</span><span class="p">[</span><span class="nx">n</span><span class="p">]</span> <span class="o">=</span> <span class="nx">fibonacci2</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">2</span><span class="p">,</span> <span class="nx">memo</span><span class="p">)</span> <span class="o">+</span> <span class="nx">fibonacci2</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">memo</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="k">return</span> <span class="nx">memo</span><span class="p">[</span><span class="nx">n</span><span class="p">];</span>
<span class="p">}</span>

<span class="kd">let</span> <span class="nx">start</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">();</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">fibonacci1</span><span class="p">(</span><span class="mi">40</span><span class="p">));</span>
<span class="kd">let</span> <span class="nx">end</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">();</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">`fibonacci1 실행시간 : </span><span class="p">${</span><span class="nx">end</span> <span class="o">-</span> <span class="nx">start</span><span class="p">}</span><span class="s2">ms`</span><span class="p">);</span>

<span class="nx">start</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">();</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">fibonacci2</span><span class="p">(</span><span class="mi">40</span><span class="p">,</span> <span class="p">{}));</span>
<span class="nx">end</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">();</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">`fibonacci2 실행시간 : </span><span class="p">${</span><span class="nx">end</span> <span class="o">-</span> <span class="nx">start</span><span class="p">}</span><span class="s2">ms`</span><span class="p">);</span>
</code></pre></div></div>

<p><br /></p>

<h3 id="타뷸레이션">타뷸레이션</h3>

<p>메모이제이션과 반대로 상향식 계산 방식을 통해 계산에 필요한 모든 값을 전부 계산 후 테이블에 저장해두고, 계산된 값 중에서 필요한 값을 사용해 계산하는 방식이다.</p>

<p>아래는 위의 피보나치 함수를 타뷸레이션 방식으로 구현한 것이다.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">fibonacci3</span><span class="p">(</span><span class="nx">n</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="nx">n</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">)</span> <span class="k">return</span> <span class="nx">n</span><span class="p">;</span>

  <span class="kd">let</span> <span class="nx">table</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">];</span>

  <span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;=</span> <span class="nx">n</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">table</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="nx">table</span><span class="p">[</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">2</span><span class="p">]</span> <span class="o">+</span> <span class="nx">table</span><span class="p">[</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">];</span>
  <span class="p">}</span>

  <span class="k">return</span> <span class="nx">table</span><span class="p">[</span><span class="nx">n</span><span class="p">];</span>
<span class="p">}</span>

<span class="nx">start</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">();</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">fibonacci3</span><span class="p">(</span><span class="mi">40</span><span class="p">,</span> <span class="p">{}));</span>
<span class="nx">end</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">();</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">`fibonacci3 실행시간 : </span><span class="p">${</span><span class="nx">end</span> <span class="o">-</span> <span class="nx">start</span><span class="p">}</span><span class="s2">ms`</span><span class="p">);</span>
</code></pre></div></div>

<p><br /></p>]]></content><author><name>YUJOO-LEE</name></author><category term="Review" /><category term="datastructure" /><category term="algorithm" /><summary type="html"><![CDATA[인프런 강의 그림으로 쉽게 배우는 자료구조와 알고리즘 (기본편) 수강내용 정리]]></summary></entry></feed>