<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>GRIT.log</title>
        <link>https://velog.io/</link>
        <description>백엔드 개발자 꿈나무</description>
        <lastBuildDate>Tue, 04 Mar 2025 16:39:18 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>GRIT.log</title>
            <url>https://velog.velcdn.com/images/jojehuni_9759/profile/d931ead8-77a0-4a46-ac35-4faa84f94b9c/social_profile.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. GRIT.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jojehuni_9759" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[CS 전공지식 정리 - 네트워크 심화]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%8B%AC%ED%99%94</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%8B%AC%ED%99%94</guid>
            <pubDate>Tue, 04 Mar 2025 16:39:18 GMT</pubDate>
            <description><![CDATA[<p><strong>대규모 트래픽으로 인한 서버 과부하 해결방법</strong>에 대해 알아보자.</p>
<h1 id="서버-과부하">서버 과부하</h1>
<p>서버가 리소스를 소진하여 들어오는 요청을 처리하지 못할 때 발생한다.</p>
<p>이 때 서버는 사용자의 웹요청을 처리하지 못해 응답없음이 뜨게 된다.</p>
<hr>
<h1 id="해결방법">해결방법</h1>
<h2 id="모니터링을-통한-자원-할당">모니터링을 통한 자원 할당</h2>
<p>서버가 응답없음이 뜨는 것은 여러가지 이유가 있지만 그 중 하나가 바로 <code>자원의 한계점 도달</code> 이다.</p>
<p>보통 서버의 CPU 사용량이 80-90%에 도달하거나 메모리가 부족해 계속해서 스와핑이 발생하면 과부화 상태가 됩니다.</p>
<blockquote>
<p><strong>스와핑에 대해</strong></p>
<p>가상 메모리는 존재하는데 실제 메모리인 RAM 에는 현재 없는 데이터 or 코드에 접근하는 경우
-&gt; 페이지 폴트 발생</p>
</blockquote>
<p><strong>스와핑</strong> : 메모리에서 당장 사용하지 않는 영역을 하드디스크로 옮기고 하드디스크의 일부를 메모리처럼 불러와 쓰는 것</p>
<blockquote>
</blockquote>
<p>마치 <strong>페이지 폴트가 발생하지 않은 것처럼</strong> 만든다.</p>
<p>이를 <strong>모니터링을 통한 자원의 적절한 할당으로 해결</strong>할 수 있다.</p>
<p>자원에 속하는 것들</p>
<ul>
<li>CPU</li>
<li>메모리</li>
<li>대역폭</li>
</ul>
<hr>
<h3 id="aws-오토스케일링">AWS 오토스케일링</h3>
<p><strong>AWS 오토스케일링</strong>이란 인스턴스가 있을 때 사용자가 몰리게 돼서 서비스 이용 불가능 상태 발생하기 이전에 <code>cloud watch</code>가 계속해서 모니터링하여 서버 대수를 늘려주는 방법입니다.</p>
<p><code>AWS Auto Scaling</code>은 애플리케이션을 자동으로 모니터링하고 자원의 용량을 자동으로 조정한다.</p>
<hr>
<h3 id="netdata를-이용한-모니터링">netdata를 이용한 모니터링</h3>
<p>만약 AWS를 사용하지 않는다고 했을 때 무료 모니터링 서비스도 있다.</p>
<p><a href="https://github.com/netdata/netdata">https://github.com/netdata/netdata</a>
이를 기반으로 지속적인 모니터링, 그리고 이를 기반으로 자원할당을 해서 해결할 수도
있다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/65a79f84-6a78-445b-976f-be68e48ba8c4/image.png" alt=""></p>
<p>위와 같은 화면은 slack 과 연동해 임계치를 기반으로 알림 서비스 또한 구축 가능하다.</p>
<hr>
<h3 id="모니터링-하는-이유">모니터링 하는 이유</h3>
<blockquote>
<p><strong>모니터링을 왜 할까?</strong></p>
</blockquote>
<p>먼저 서버과부화로 인해 서버 중지에 대한 대처를 할 수 있다.</p>
<ol>
<li>어떤 페이지에 어떤트래픽이 얼마나 발생했느냐. </li>
<li>어떤 네트워크에서 병목현상이 일어났냐.</li>
</ol>
<p>등을 모니터링에서는 알려준다.</p>
<p>또한 모니터링을 하면 활용도가 낮은 페이지, 높은 페이지를 파악할 수 있어 나중에 서비스 개선에도 도움이 된다.</p>
<p><strong>즉, 해결하기 위한 문제점을 파악하기 위해 모니터링은 필수</strong></p>
<p>또 일부 서비스는 모니터링한 결과물을 알려주면서 서비스의 중단 등의 여부를 사용자에게 알려주기도 한다.</p>
<p>ex) cloudflare -&gt; <a href="https://www.cloudflarestatus.com/">https://www.cloudflarestatus.com/</a></p>
<hr>
<h2 id="로드밸런서">로드밸런서</h2>
<p>앞서 설명한 AWS 오토스케일링은 빠르긴 하나 구성에 시간이 걸리기 때문에 앞단에 로드밸런서를 통해 트래픽을 분산해야 한다.</p>
<p>또한, 로드밸런서는 한 서버에 장애가 발생하면 로드 밸런서는 트래픽을 다른 기능 서버로 리디렉션하여 시스템 중단을 방지할 수도 있다.</p>
<hr>
<h2 id="블랙스완-프로토콜">블랙스완 프로토콜</h2>
<blockquote>
<p><strong>블랙스완</strong> : 예측할 수 없는 사고</p>
</blockquote>
<p>중요한 것은 이러한 블랙스완은 매번 일어나기 때문에 이에 따라 대비를 해야 한다.</p>
<p>구글의 블랙스완이 발생 시 수칙</p>
<ol>
<li>영향을 받은 시스템과 각 시스템의 상대적 위험 수준을 확인</li>
</ol>
<ul>
<li>체계적으로 데이터를 수집하고 원인에 대한 가설을 수립한 후 이를 테스팅</li>
</ul>
<ol start="2">
<li>잠재적으로 영향을 받을 수 있는 내부의 모든 팀에 연락</li>
<li>최대한 빨리 취약점에 영향을 받는 모든 시스템을 업데이트</li>
<li>복원계획을 포함한 우리의 대응 과정을 파트너와 고객 등 외부에 전달</li>
</ol>
<hr>
<h2 id="서킷-브레이커">서킷 브레이커</h2>
<blockquote>
<p>서비스 장애를 감지하고 연쇄적으로 생기는 에러를 방지하는 기법</p>
</blockquote>
<p>서비스와 서비스 사이에 서킷브레이커 계층을 두고 미리 설정해놓은 <code>timeout</code> <strong>임계값에 도달하면</strong> 서킷브레이커가 그 이후의 <strong>추가 호출에 무조건 에러를 반환</strong></p>
<p>만약 서비스 A, B, C가 있고 결제 서비스라고 했을 때 A는 개인정보, B는 장바구니, C는 미리 결정해둔 카드 정보들을 관리. 그리고 A, B, C 끼리 HTTP로 통신한다고 하자.</p>
<p>만약 스레드가 100개 중 98개는 A에 요청, 나머지 2개는 각각 B, C에 요청한다고 하자.</p>
<p>근데 A가 고장나버린다면.. 기다리는 동안 B와 C에 대해서도 스레드가 차단될 수도 있다.</p>
<blockquote>
<p>이것을 <code>스레드 차단</code>이라고 한다.</p>
</blockquote>
<p>혹은 </p>
<ul>
<li>A &lt;-&gt; B</li>
<li>B &lt;-&gt; C</li>
</ul>
<p>가 연결돼 있는데 A가 고장나버리면 B가 멈추게 되고, 연쇄적으로 C도 멈추게 된다.</p>
<blockquote>
<p>이것을 <code>계단식 에러</code>라고 한다.</p>
</blockquote>
<p>이럴 때를 대비해서 서비스 사이에 서킷 브레이커를 두고 에러를 방지하는 것이다.</p>
<blockquote>
<p>에러가 고쳐질 때까지 기다리는게 뭐가 어때서? 라고 생각한다면.</p>
<p><strong>사용자 입장에서 응답을 오래 기다려야 하는 것은 좋은 UX가 아니다. 성공인지 실패인지는 중요하지 않다. 중요한 것은 사용자가 기다리지 않아야 한다는 점이다.</strong></p>
</blockquote>
<hr>
<h3 id="동작과정">동작과정</h3>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/5707f406-89d0-45ab-ac4b-e298c20d412b/image.png" alt=""></p>
<p>이렇게 정상적으로 작동하던 서비스가 있다고 가정했을 때</p>
<p>아래 사진처럼 Supplier Microservice 가 고장나게 된다면 바로 에러를 반환한다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/f98747e7-ebe2-48f3-9102-860c79c795cb/image.png" alt=""></p>
<p>서킷브레이커는 <code>closed</code>, <code>open</code>, <code>half_open</code> 의 상태값을 가진다.</p>
<ul>
<li><code>closed</code>[정상] : 네트워크 요청의 실패율이 임계치보다 낮음</li>
<li><code>open</code>[에러] : 임계치이상의 상태를 말합니다. 요청을 서비스로 전송하지 않고 바로 오류를 반환합니다. 이를 <code>fail fast</code>라고 한다.</li>
<li><code>half_open</code>[확인중] : <code>open</code> 상태에서 일정 <code>timeout</code>으로 설정된 시간이 지나면 장애가 해결되었는지 확인하기 위해 <code>half_open</code> 상태로 전환됩니다. 
여기서 요청을 전송하여 응답을 확인. 
장애가 풀리는지를 확인해서 성공하면 <code>closed</code>, 실패하면 다시 <code>open</code>으로 변경</li>
</ul>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/081d6216-64ba-4a64-a912-7b877e83ae55/image.png" alt=""></p>
<hr>
<h3 id="장점">장점</h3>
<p>연속적인 에러 발생을 막아주며 일부서비스가 종료되더라도 다른 서비스들은 이상없이 동작하게 만들 수 있으며 사용자 경험을 높여준다.</p>
<hr>
<p>이미 서킷브레이커는 구현된 라이브러리가 있는데, Netflix의 <code>Hystrix</code> 그리고 <code>Resilience4j</code> 가 대표적이다.</p>
<p><a href="https://github.com/Netflix/Hystrix">https://github.com/Netflix/Hystrix</a>
<a href="https://github.com/resilience4j/resilience4j">https://github.com/resilience4j/resilience4j</a></p>
<hr>
<h2 id="컨텐츠-관리">컨텐츠 관리</h2>
<h3 id="불필요한-컨텐츠-제거">불필요한 컨텐츠 제거</h3>
<p>인프런의 장애 복구 사례를 예를 들어보자.
-&gt; 불필요한 쿼리 등을 제거한다.</p>
<p><a href="https://tech.inflab.com/202201-event-postmortem/">https://tech.inflab.com/202201-event-postmortem/</a></p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/cdfe6b11-27f0-43f9-ba05-b703130d3f21/image.png" alt=""></p>
<p>사용하지 않는 컬럼들도 가져온다든지 그런 것들을 제거해서 컨텐츠의 크기를 줄이거나 할 수 있다.</p>
<hr>
<h3 id="cdn을-통한-컨텐츠-제공">CDN을 통한 컨텐츠 제공</h3>
<p>CDN을 통해 사용자 가까이, 그리고 분산된 대규모 서버 네트워크를 기반으로 컨텐츠를 제공해서 메인 서버에 대한 부하를 줄인다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/a456e90f-2090-453b-9bb2-70f136444bd5/image.png" alt=""></p>
<p>MainServer 에서 사용자가 원하면 데이터를 줄텐데 변하지 않는 Image, js, css, html 과 같은 정적 자원들은 MainServer가 주는 것이 CDN을 통해 주므로 비용을 줄일 수 있다.</p>
<p>ex) cpu의 10%를 해당 장적 자원들을 제공하는데 사용하고 있었다면 해당 비용을 줄일 수 있다.</p>
<hr>
<h3 id="컨텐츠-캐싱">컨텐츠 캐싱</h3>
<p>네트워크 트래픽을 해결하는 가장 좋은 방법은 해당 트래픽이 발생하지 않도록 하는 것이다.</p>
<p>브라우저 캐시(쿠키, 로컬저장소, 세션저장소)를 통해 해당 요청에 관한 항목을 캐시에서 응답을 읽어 네트워크 요청에 관한 비용을 모두 제거한다.</p>
<hr>
<h3 id="컨텐츠-압축">컨텐츠 압축</h3>
<p>텍스트 기반 리소스는 <code>gzip</code> 또는 <code>Brotli</code>를 통해 압축해야 한다. 압축하면 70% 정도까지 압축할 수 있습니다. 
다만 압축했기 때문에 압축을 풀기위해 서버에서 자원(CPU)를 사용하는 양까지 고려해야 한다.</p>
<blockquote>
<p>보통은 압축하면 좋다.</p>
</blockquote>
<hr>
<h3 id="컨텐츠의-우하한-저하-미리-준비된-응답하기">컨텐츠의 우하한 저하 (미리 준비된 응답하기)</h3>
<p>시스템의 과도한 부하를 줄이기 위해 제공하는 컨텐츠 및 기능을 일시적으로 줄이는 전략이다.</p>
<p>예를 들어 정적 텍스트 페이지를 제공하거나, 검색을 비활성화하거나 더 적은 수의 검색 결과를 반환하거나, 필수적이지 않은 기능을 비활성화한다.</p>
<blockquote>
<p>중요한 일이 생겼을 때 뉴스와 같은 홈페이지는 이미지, 영상, 지도와 같은 것들을 삭제하고
내용 전달에 중점을 두고 경량화된 컨텐츠를 제공한다.</p>
<p>일본 NHK 웹의 <strong>정상 화면의 경우</strong>
<img src="https://velog.velcdn.com/images/jojehuni_9759/post/7cb70ce6-e069-43c4-8c90-90fd0685be75/image.png" alt=""></p>
<p><strong>서울 대피 당시 화면의 경우</strong>
<img src="https://velog.velcdn.com/images/jojehuni_9759/post/84e4fca8-726c-40b6-96a9-49cb928c8f64/image.png" alt=""></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공 지식 정리 - 웹브라우저의 캐시 3. 로그인 방식]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5-%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9B%B9%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-%EC%BA%90%EC%8B%9C-3.-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EB%B0%A9%EC%8B%9D</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5-%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9B%B9%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-%EC%BA%90%EC%8B%9C-3.-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EB%B0%A9%EC%8B%9D</guid>
            <pubDate>Tue, 04 Mar 2025 14:21:08 GMT</pubDate>
            <description><![CDATA[<p>로그인은 세션기반과 토큰기반의 인증방식이 있다.</p>
<h1 id="세션기반-인증방식">세션기반 인증방식</h1>
<p>HTTP의 특징 중 하나는 상태없음(stateless) 하다라는 것인데</p>
<p>즉, HTTP 요청을 통해 데이터를 주고 받을 때 요청이 끝나면 요청한 사용자의 정보 등을 유지하지 않는 특징이 있다. (이전부터 CS 공부하면서 아는 내용)</p>
<p><strong>그럼 로그인 상태는 어떻게 유지하는걸까?</strong></p>
<ul>
<li><strong>세션</strong> : 서버와 클라이언트의 연결이 활성화된 상태를 의미합니다.</li>
<li><strong>세션ID</strong> : 웹 서버 또는 DB에 저장되는 클라이언트에 대한 유니크한 ID</li>
</ul>
<h2 id="세션기반-로그인-과정">세션기반 로그인 과정</h2>
<ol>
<li>처음 로그인 &gt;&gt; 세션ID가 생성됨 &gt;&gt; 서버에서 세션ID를 쿠키로 설정해서 클라이언트에 전달</li>
<li>클라이언트가 서버에 요청을 보낼 때 해당 세션ID를 쿠키로 담아서 전에 로그인했던 아이디인지 확인</li>
<li>로그인을 유지</li>
</ol>
<p>다른 페이지를 넘어가더라도 쿠키에 있는 세션ID를 보고 해당 ID가 이미 유효하기 때문에 로그인 상태가 유지되는 것이다.</p>
<h3 id="단점">단점</h3>
<ol>
<li>사용자의 상태에 관한 데이터를 서버에 저장했을 때 로그인 중인 유저의 수가 늘어난다면?<ul>
<li>서버의 메모리 과부화가 일어날 수 있다.</li>
</ul>
</li>
<li>DB 중 RDBMS에 저장한다면, <strong>직렬화 및 역직렬화</strong>에 관한 오버헤드가 발생</li>
</ol>
<p>MySQL 같은 곳에 저장한다면 (아마 VARCHAR 형태로 저장될 것)</p>
<p>이 때 직렬화와 역직렬화에 대한 단점을 굳이 꼽아볼 수 있다.</p>
<hr>
<h1 id="토큰기반-인증방식">토큰기반 인증방식</h1>
<p>acceess 토큰, refresh 토큰, JWT 토큰에 대해서는 들어봤을 것이다.</p>
<p>토큰기반 인증방식에 대해 알아보자.</p>
<p>토큰기반 인증방식은 <code>state</code>를 모두 토큰 자체만으로 처리하며 토큰을 처리하는 한 서버를 두고 다른 컨텐츠를 제공하는 서버는 모두 <code>stateless</code>하게 만들자는 이론이 담긴 방식이다.</p>
<p><strong>왜</strong> 토큰을 관리하는 서버는 따로 두어야 할까?</p>
<p>이는 여러 개의 서버를 운용한다라고 했을 때 </p>
<ul>
<li>토큰기반 인증 + A도메인을 처리하는 서버로
구축할 경우</li>
</ul>
<p>A도메인에서 에러가 발생이 되면, 인증에 관한 기능이 마비되고 이는 B, C, D 등의 도메인 기능이 연쇄적으로 마비될 수 있기 때문이다.</p>
<p>토큰은 주로 JWT 토큰이 활용된다.</p>
<ol>
<li>인증로직 &gt;&gt; JWT 토큰 생성(<code>access 토큰</code>, <code>refresh 토큰</code>)</li>
<li>사용자가 이후에 <code>access 토큰</code>을 <code>HTTP Header - Authorization</code> 또는 <code>HTTP Header</code></li>
</ol>
<ul>
<li><code>Cookie</code>에 담아 인증이 필요한 서버에 요청해 원하는 컨텐츠를 가져온다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/72e05fb9-6725-4d2b-a1b5-a9b41bb41b1e/image.png" alt=""></p>
<hr>
<h2 id="jwt">JWT</h2>
<p>JWT는 JSON Web Token을 의미하며 헤더, 페이로드, 서명으로 이루어져 있으며 JSON 객체로 인코딩되며 메시지 인증, 암호화에 사용됩니다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/4d1bb276-fc2a-4987-96d5-658b6ce55d51/image.png" alt=""></p>
<p><strong>Header</strong></p>
<ul>
<li>토큰 유형과 서명 알고리즘, base64URI로 인코딩 됩니다.</li>
</ul>
<p><strong>Payload</strong></p>
<ul>
<li><strong>데이터</strong>, 토큰 발급자, 토큰 유효기간, base64URI로 인코딩 됩니다.</li>
</ul>
<p><strong>Signature</strong></p>
<ul>
<li>(인코딩된 header + payload) + 비밀키를 기반으로 헤더에 명시된 알고리즘으로 다시
생성한 서명값.</li>
</ul>
<p><a href="https://jwt.io/">https://jwt.io/</a></p>
<p>여기로 가서 보면 Header랑 Payload 를 base64UrlEncode 하고 <img src="https://velog.velcdn.com/images/jojehuni_9759/post/87000570-ed5d-4fb8-b4e4-3f8ee60b7b38/image.png" alt=""></p>
<p>비밀키 기반으로 서명 알고리즘을 통해 만들어진다. 그것을 왼쪽에서 확인 가능할 것이다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/52d42b06-c07c-4624-8973-27bbe81b9a44/image.png" alt=""></p>
<h3 id="장점">장점</h3>
<ol>
<li>사용자 인증에 필요한 모든 정보는 토큰 자체에 포함하기 때문에 별도의 인증저장소가 필요 X</li>
<li>다른 유형의 토큰과 비교했을 때 경량화되어있습니다. SAML(Security Assertion Markup Language Tokens)이란 토큰이 있지만 이에 비해 훨씬 경량화되어 있음.</li>
<li>디코딩했을 때 JSON이 나오기 때문에 JSON을 기반으로 쉽게 직렬화, 역직렬화가
가능하다.</li>
</ol>
<h3 id="단점-1">단점</h3>
<ol>
<li>토큰이 비대해질 경우 당연히 서버과부화에 영향을 줄 수 있다.</li>
<li>토큰을 탈취당할 경우 디코딩했을 때 데이터를 볼 수 있다.</li>
</ol>
<hr>
<h2 id="access-토큰-refresh-토큰">Access 토큰, Refresh 토큰</h2>
<p><code>access토큰</code>의 수명은 짧게, <code>refresh토큰</code>의 수명은 길게 한다.</p>
<p><code>refresh</code>토큰은 <code>access토큰</code>이 만료되었을 때 다시 <code>access 토큰</code>을 얻기 위해 사용되는
토큰이다.</p>
<p>이를 통해 <code>access토큰</code>이 만료될 때마다 인증에 관한 비용이 줄어들게 된다.</p>
<hr>
<p>로그인을 하게 되면 access 토큰과 refresh 토큰 두개를 얻는데</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/86787d50-4a42-4511-bee4-d53fab34923c/image.png" alt=""></p>
<p>access 토큰이 만료되거나 사용자가 새로고침을 할 때 refresh 토큰을 기반으로 새로운 access token을 얻는다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/b7e8df88-582d-421c-890b-37a699727f36/image.png" alt=""></p>
<p>왜 나눠서 할까?</p>
<p><code>access 토큰</code> : 인증용 토큰이다.</p>
<p>해커가 access 토큰을 탈취해 로그인한다면? -&gt; 안 되기 때문에 만료기한을 적게 해야 한다.</p>
<p>만료기한이 지나면 이후에는 사용 못하기 때문에 해커도 탈취해서 사용하기 힘들다.</p>
<p><code>refresh 토큰</code> : 갱신용 토큰</p>
<p>access 토큰이 짧은 만큼 refresh 토큰은 갱신 기간을 둬서 갱신 가능하게끔 해주는 것이다.</p>
<h3 id="주의할-점">주의할 점</h3>
<p>이렇게 access토큰을 얻었다면 그 이후에 요청을 할 때는 HTTP Header - Authorization 또는 HTTP Header - Cookie에 담아 요청을 하게 되는데 이 때 다음과 같은 규칙을
지키는 것이 좋다.</p>
<ul>
<li><code>Bearer &lt;token&gt;</code> 으로 <code>&quot;Bearer &quot; (띄어쓰기 포함)</code> 을 앞에 둬서 토큰기반인증방식이라는 것을 알려줘야 한다.</li>
<li><code>https</code>를 사용해야 한다.</li>
<li>쿠키에 저장한다면 <code>sameSite: &#39;Strict&#39;</code>을 써야 한다.</li>
<li>수명이 짧은 <code>access token</code>을 발급해야 한다.</li>
<li>url에 토큰을 전달하지 말아야 한다.</li>
</ul>
<hr>
<h3 id="토큰을-탈취당하는-것을-대비하는-방법">토큰을 탈취당하는 것을 대비하는 방법</h3>
<ol>
<li>먼저 Access Token의 수명을 짧게 설정하여 탈취된 토큰의 유효 기간을 최소화. 짧은 수명의 Access Token을 사용하고, 필요할 때만 Refresh Token을 통해 새로운 Access Token을 발급</li>
<li>Refresh Token을 사용하여 민감한 작업을 수행하려고 할 때 추가적인 사용자 인증
단계를 요구한다.</li>
</ol>
<ul>
<li>예를 들어, IP주소, 디바이스 정보등을 이용하거나 google authentifactor를 이용한 2단계 인증을 사용한다.</li>
</ul>
<ol start="3">
<li>쿠키에 HttpOnly 및 Secure 을 걸어서 관리</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공 지식 정리 - 웹브라우저의 캐시 2. 세션스토리지와 쿠키]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5-%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9B%B9%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-%EC%BA%90%EC%8B%9C-2.-%EC%84%B8%EC%85%98%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80%EC%99%80-%EC%BF%A0%ED%82%A4</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5-%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9B%B9%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-%EC%BA%90%EC%8B%9C-2.-%EC%84%B8%EC%85%98%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80%EC%99%80-%EC%BF%A0%ED%82%A4</guid>
            <pubDate>Tue, 04 Mar 2025 13:40:35 GMT</pubDate>
            <description><![CDATA[<h1 id="세션-스토리지">세션 스토리지</h1>
<p>세션 스토리지는 로컬 스토리지와 굉장히 유사하다.</p>
<blockquote>
<p>웹 스토리지 객체로 브라우저 내에 { key : value } 형태로 오리진에
종속되어 저장되는 데이터</p>
</blockquote>
<ul>
<li>하나의 키, 하나의 값 저장</li>
<li>최대 저장 용량은 5MB</li>
</ul>
<h2 id="로컬스토리지와-차이점">로컬스토리지와 차이점</h2>
<ul>
<li>동일한 오리진이어도 브라우저의 각 탭마다 독립적으로 저장된다.</li>
</ul>
<blockquote>
<p>즉, 다른 탭에서 세션 스토리지에 저장된 데이터에 접근할 수 없다.</p>
</blockquote>
<ul>
<li>사용자가 브라우저에서 탭을 닫으면 데이터가 만료된다.</li>
</ul>
<hr>
<h2 id="사용법">사용법</h2>
<ul>
<li>설정 : sessionStorage.setItem(key, value);</li>
<li>탐색 : sessionStorage.getItem(key);</li>
<li>제거 : sessionStorage.removeItem(key);</li>
<li>전체제거 : sessionStorage.clear()</li>
</ul>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/71b75328-ae54-4a74-bfaa-2eefa805dfd7/image.png" alt=""></p>
<p>위와 같이 Console 창에 했을 때</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/8a9a358b-1957-4a6d-9855-c4956abbdbd8/image.png" alt=""></p>
<p>해당 탭의 Session storage 에 저장된 것을 볼 수 있지만</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/2a045f38-7490-40f1-b0ab-659985a66877/image.png" alt=""></p>
<p>다른 탭에서는 없는걸 볼 수 있다.</p>
<p>그런 차이가 있다.</p>
<blockquote>
<p>보통 세션스토리지보다 로컬스토리지를 많이 쓴다.</p>
</blockquote>
<hr>
<h1 id="쿠키">쿠키</h1>
<blockquote>
<p>브라우저에 저장된 데이터 조각</p>
</blockquote>
<p>클라이언트에서 먼저 설정할 수도 있고, 서버에서 먼저 설정할 수도 있다.</p>
<p>거의 보통은 서버에서 먼저 설정해서 쿠키를 만드는게 일반적이다.</p>
<ol>
<li>서버에서 응답헤더로 <code>Set-Cookie</code> 로 설정해서 쿠키를 보낸다.</li>
<li>클라이언트에서 요청헤더 <code>Cookie</code> 에 설정돼 자동으로 서버에 전달되게 돼 브라우저에 저장되게 한다.</li>
</ol>
<blockquote>
<p>참고 : HTTP 헤더를 통해 Client or Server 가 HTTP 요청, 응답할 때 추가 정보를 전달할 수 있다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/e2eecb8f-3daa-4ba9-a575-44bbc29c7c7b/image.png" alt=""></p>
<p>클라이언트와 서버 둘 다 조작이 가능하지만 <strong>보통 서버에서 만료기한</strong> 등을 설정 및
컨트롤한다.</p>
<p>저장용량은 <strong>최대 4KB</strong></p>
<ul>
<li>로그인</li>
<li>장바구니</li>
<li>사용자 커스터마이징</li>
<li>사용자 행동분석 (주로 개인화된 광고에 활용되는 것)</li>
</ul>
<p>위와 같은 것들에 사용된다.</p>
<h2 id="클라이언트에서도-설정가능한-쿠키-권장-x">클라이언트에서도 설정가능한 쿠키 (권장 X)</h2>
<p>클라이언트에서 자바스크립트 - <code>document.cookie</code>를 통해 쿠키를 설정할 수 있고 보낼 때도 이런 식으로 <code>header</code> - <code>Cookie</code>에 값을 정해서 보낼 수도 있다. </p>
<p>하지만 이를 권장 X</p>
<pre><code class="language-javascript">axios.get(url, {
    headers: {
        Cookie: &quot;cookie1=value; cookie2=value; cookie3=value;&quot;
    }
}).then</code></pre>
<p>이렇게 되면 쿠키에 대한 제어권을 클라이언트에게 두게 되는데, 쿠키에는 보통 민감한 정보들이 담길 수도 있기 때문에 이 제어권에 관한 것을 <strong>클라이언트가 아닌 서버</strong>가 가지고 있게 해야 한다.</p>
<hr>
<h2 id="세션-쿠키">세션 쿠키</h2>
<p><code>Expires</code> 또는 <code>Max-Age</code> 속성을 지정하지 않은 것을 말한다.</p>
<p>브라우저가 종료되면 쿠키도 사라진다.</p>
<hr>
<h2 id="영구-쿠키">영구 쿠키</h2>
<p><code>Expires</code> 또는 <code>Max-Age</code> 속성을 지정해서 특정 날짜 또는 일정 기간이 지나면 삭제되게 만든 쿠키로, 브라우저를 닫을 때 만료되지 않는다.</p>
<hr>
<h2 id="문법">문법</h2>
<pre><code>Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;
Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;; Expires=&lt;date&gt;
Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;; Max-Age=&lt;non-zero-digit&gt;
Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;; Domain=&lt;domain-value&gt;
Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;; Path=&lt;path-value&gt;
Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;; Secure
Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;; HttpOnly
Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;; SameSite=Strict</code></pre><h3 id="secure">secure</h3>
<p>쿠키에 이 옵션을 추가하면 https로만 쿠키를 주고받을 수 있게 하는 옵션이다.</p>
<p>하지만 Chrome v89 및 Firefox v75이상부터 localhost에서는 이 사양을 무시합니다.</p>
<blockquote>
<p>즉, Chrome v89 및 Firefox v75이상의 <code>localhost</code>에서는 <code>secure</code> 옵션을 걸어도 <code>http</code>로 쿠키를 주고받을 수 있어 쉽게 테스팅이 가능</p>
</blockquote>
<h3 id="httponly">httponly</h3>
<p>공격자가 쿠키를 자바스크립트로 빼낼 수 없게 만든다. (document.cookie로 접근 불가)</p>
<h3 id="samesite">samesite</h3>
<p>요청이 동일한 도메인에서 시작된 경우에만 쿠키가 애플리케이션으로 전송되도록 허용</p>
<h3 id="실습">실습</h3>
<pre><code>const http = require(&#39;http&#39;);
const hostname = &#39;127.0.0.1&#39;;
const port = 3000;
const server = http.createServer((req, res) =&gt; {
    res.setHeader(&#39;Content-Type&#39;, &#39;text/plain; charset=utf-8&#39;);
    res.setHeader(&#39;Set-Cookie&#39;, [&#39;cookie1 = httponlycookie; httponly&#39;, &#39;cookie2 = securecookie; Secure&#39;]);
    res.end(&#39;end\n&#39;);
});
server.listen(port, hostname, () =&gt; {
    console.log(`Server running at http://${hostname}:${port}/`);
});</code></pre><p>http 서버, 호스트명은 localhost, 포트는 3000</p>
<p><code>res.setHeader(&#39;Content-Type&#39;, &#39;text/plain; charset=utf-8&#39;);</code> 라고 하는 형태로 보내지만</p>
<p>쿠키는
<code>res.setHeader(&#39;Set-Cookie&#39;, [&#39;cookie1 = httponlycookie; httponly&#39;, &#39;cookie2 = securecookie; Secure&#39;]);</code>
이렇게 만든다.</p>
<p>js 파일에서 만든 뒤 <code>node script.js</code> 로 실행하면 3000번 포트에 서버가 구동된걸 볼 수 있고,</p>
<p>개발자 도구의 Application -&gt; Cookies 를 보면 들어간 것도 볼 수 있을 것이다.</p>
<ol>
<li>httponly와 secure 에도 차이가 있는걸 볼 수 있을 것이다.</li>
</ol>
<blockquote>
<p>내가 https가 아닌 http인데 secure가 보이는 이유? -&gt; 크롬 89 이상과 firefox 75 이상이기 때문일 것이다.</p>
</blockquote>
<ul>
<li>테스트할 때만 로컬에서 볼 수 있게 한시적으로 허용해준다.</li>
</ul>
<ol start="2">
<li><code>document.cookie</code> 를 검색해보면 <code>&#39;cookie2 : securecookie</code> 만 나오는 것을 볼 수 있을 것이다.</li>
</ol>
<p>httponly는 나오지 않기 때문이다. (조금 더 안전해진다.)</p>
<hr>
<p>즉, 쿠키의 시큐어코딩에 대해 알아보자.</p>
<p><strong>쿠키 - 세션으로 로그인을 처리한다면</strong> 다음과 같은 시큐어 코딩을 해야 한다.</p>
<ol>
<li><code>cookie</code>에 <code>세션ID</code>를 담을 때 이 <code>세션ID</code>기반으로 클라이언트의 개인정보를 유추할 수
없게 해야 한다.</li>
<li>자바스크립트로는 파악할 수 없게 <code>http only</code> 옵션을 걸고, <code>https</code>로만 쿠키를 주고받을
수 있게 <code>secure</code> 옵션을 걸어야 한다.</li>
<li>일정시간의 <strong>세션 타임아웃</strong>을 걸어야 한다.</li>
</ol>
<hr>
<h3 id="사례">사례</h3>
<blockquote>
<p><strong>세션 타임아웃 사례</strong> : upbit의 세션타임아웃으로 공격자의 접근을 차단할 수 있다.</p>
</blockquote>
<p>-&gt; 로그인 해두고 뭐 자리를 비웠을 때 타임아웃이 된 후에는 공격자가 접근할 수 없게끔 하는 것이다.</p>
<hr>
<blockquote>
<p><strong>쿠키 허용 관련 알림창 사례</strong></p>
</blockquote>
<p>서비스 운용시 쿠키를 사용한다면 쿠키허용관련 알림창을 만들어야 한다. 
방문 기록을 추적할 때 쿠키가 사용되기 때문이다. 이는 사용자의 데이터 간접수집에 해당하며 거기에 해당하는 KISA 지침을 준수해야 하기 때문.</p>
<hr>
<h1 id="로컬스토리지-세션스토리지-쿠키의-공통점-차이점">로컬스토리지, 세션스토리지, 쿠키의 공통점 차이점</h1>
<p>이전 로컬스토리지에 이어서 봤던 웹브라우저의 캐시들의 공통점, 차이점을 알아보자.</p>
<p><strong>공통점</strong></p>
<ol>
<li>브라우저에 캐싱을 함으로써 <strong>서버에 대한 요청을 줄여 서버부하를 방지</strong>할 수 있다.</li>
<li>캐싱으로 인해 다운로드 하는 컨텐츠가 줄어들어 <strong>웹사이트의 컨텐츠를 더 빨리 다운로드</strong>가 가능합니다.</li>
<li>사이트 <strong>기본 설정 커스터마이징(색상, 글꼴 크기 등)을 저장</strong>하거나 <strong>로그인 상태를 유지</strong>할 때 사용될 수 있습니다</li>
</ol>
<p><strong>차이점</strong>
<img src="https://velog.velcdn.com/images/jojehuni_9759/post/59a4f208-33ad-4f64-8bbf-cc989c4cd60c/image.png" alt=""></p>
<p>-&gt; 쿠키, 로컬스토리지는 오리진이 같은 여러 탭을 닫아도 유지가 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공 지식 정리 - 웹브라우저의 캐시 1. 로컬스토리지]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5-%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9B%B9%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-%EC%BA%90%EC%8B%9C-1.-%EB%A1%9C%EC%BB%AC%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5-%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9B%B9%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-%EC%BA%90%EC%8B%9C-1.-%EB%A1%9C%EC%BB%AC%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80</guid>
            <pubDate>Tue, 04 Mar 2025 10:39:29 GMT</pubDate>
            <description><![CDATA[<p><a href="https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-2.-%EB%A9%94%EB%AA%A8%EB%A6%AC">운영체제 2. 메모리</a></p>
<p>위 링크에서도 아주 간단하게 웹 브라우저의 캐시를 알아봤었는데 이번엔 사용법도 같이 알아보고자 한다.</p>
<hr>
<h1 id="로컬스토리지">로컬스토리지</h1>
<blockquote>
<p>Web Storage 객체로 브라우저 내에 키:값 형태로 origin 에 종속돼 저장되는 데이터이다.</p>
</blockquote>
<ul>
<li>키:값 형태이므로 하나의 키에는 오로지 하나의 값만 저장된다.<ul>
<li>추가로 넣고 싶다면 배열 형태로 넣는 수밖에 없다.</li>
</ul>
</li>
<li>웹 브라우저에서 데이터를 <strong>수동</strong>으로 삭제하지 않는 한 로컬 저장소에 저장되며, 만료 날짜가 없다.<ul>
<li>창이나 탭을 닫는다고 만료되는 것이 아니다.</li>
</ul>
</li>
<li>최대 용량은 5MB 이다.</li>
<li>로그인을 유지하기 위한 값, 사용자의 행위를 기억할 때 사용된다.<ul>
<li>예를 들면 1, 2, 3번 총 3개의 탭이 있을 때 2번 탭에서 한 행위는 기억된다.<ul>
<li>ex) 네이버 쇼핑에서 필터링을 걸어두는 행위 -&gt; 새로고침해도 유지됨</li>
</ul>
</li>
</ul>
</li>
<li>데이터는 자동으로 서버로 전송되지 않는다.</li>
</ul>
<blockquote>
<p>추가로 작성할 개념인 <strong>쿠키</strong>는 자동 전송되니까 차이를 알아두자.</p>
</blockquote>
<h2 id="사용법">사용법</h2>
<ul>
<li>설정 : <code>localStorage.setItem(key, value);</code></li>
<li>key에 해당하는 value가져오기 : <code>localStorage.getItem(key);</code></li>
<li>제거 : <code>localStorage.removeItem(key);</code></li>
<li>전체제거 : <code>localStorage.clear()</code></li>
</ul>
<p>개발자 도구 -&gt; <code>console</code>
<img src="https://velog.velcdn.com/images/jojehuni_9759/post/cb7a683c-0ebf-4da1-8e72-5af8bd21096d/image.png" alt=""></p>
<p>개발자 도구 -&gt; <code>application</code>
<img src="https://velog.velcdn.com/images/jojehuni_9759/post/ba3b0c33-a80c-46c0-8660-3405008334ad/image.png" alt=""></p>
<p>이런 형태로 설정도 가능하고 제거도 가능하다.</p>
<hr>
<h2 id="로컬스토리지와-오리진">로컬스토리지와 오리진</h2>
<p>위의 개념에서 로컬스토리지는 키:값 형태로 <strong>origin 에 종속돼 저장되는 데이터</strong>라고 했는데 <strong>오리진이란?</strong></p>
<p>오리진은 <code>https://www.naver.com</code> 을 예시를 들어 설명하면</p>
<ol>
<li>https: -&gt; <code>protocol</code></li>
<li><a href="http://www.naver.com">www.naver.com</a> -&gt; <code>hostname</code></li>
<li>443 포트가 있지만 생략돼 있다. -&gt; <code>port</code></li>
</ol>
<blockquote>
<p>참고) <a href="https://www.naver.com:443">https://www.naver.com:443</a> 해도 똑같이 naver가 되는 것을 알 수 있다.
-&gt; https 의 기본 포트 번호이기 때문.</p>
</blockquote>
<p>위에서 말한 <strong>protocol, hostname, port</strong> 를 묶어서 <strong>오리진</strong>이라고 한다.</p>
<p>벨로그를 예를 들면 해당 페이지는</p>
<p><code>https://velog.io</code> 까지가 <strong>오리진</strong>
물음표 이후의 <code>id=983888e3-bb05-4eb6-9aab-b93f4c09a7c5</code> 부분은 <strong>query String</strong> 이다.</p>
<p>그래서 같은 오리진이 같다면 로컬 스토리지에 저장되기 때문에 필터링을 걸어둔 &quot;행위&quot;가 기억되는 것이다.</p>
<hr>
<p>그래서 로그인 유지할 때도 사용한다.</p>
<ul>
<li>토큰 기반 방식</li>
<li>세션 기반 방식</li>
</ul>
<p>2가지가 있는데 토큰 먼저 알아보자.</p>
<p><strong>토큰 기반 방식</strong></p>
<ol>
<li>사용자 아이디 패스워드 입력 -&gt; 서버에 로그인 요청</li>
<li>서버가 <code>DB</code>를 통해 로그인 성공 시 <code>token</code> (반환)</li>
<li>이 <code>token</code> 은 <code>LocalStorage</code>에 저장된다.</li>
<li>이 저장된 <code>token</code>을 보통 <code>header-authorization</code> 이라는 <code>header</code>에 담아서 보내면 로그인이 유지될 수 있는 것이다.</li>
</ol>
<hr>
<h2 id="활용-사례--캐싱">활용 사례 : 캐싱</h2>
<p>로그인 유지뿐 아닌 추가로 더 알아보자.</p>
<p>우리가 이전에 입력했던 것들을 입력하지 않아도 <strong>자동완성</strong>으로 저장돼 있는 경우가 있다.</p>
<p>이것으로 다시 입력할 필요 없이 수고를 덜 수 있다. =&gt; <strong>UX가 좋아진다(개선된다)</strong></p>
<p>텍스트 창을 만든 뒤에 script 에</p>
<pre><code class="language-html">&lt;body&gt;
    &lt;div&gt;
        &lt;input type=&quot;text&quot; id=&quot;field&quot; /&gt;
        &lt;input type=&quot;button&quot; class=&quot;button-62&quot; value=&quot;검색&quot; id=&quot;save&quot; /&gt;
        &lt;input type=&quot;button&quot; class=&quot;button-62&quot; value=&quot;조회&quot; id=&quot;read&quot; /&gt;
        &lt;input type=&quot;button&quot; class=&quot;button-62&quot; value=&quot;삭제&quot; id=&quot;clear&quot; /&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;script&gt;
    window.onload = async () =&gt; {
        const field = document.getElementById(&quot;field&quot;),
            save = document.getElementById(&quot;save&quot;),
            read = document.getElementById(&quot;read&quot;),
            clear = document.getElementById(&quot;clear&quot;)

        save.addEventListener(&quot;click&quot;, e =&gt; localStorage.setItem(&quot;입력값&quot;, field.value))
        read.addEventListener(&quot;click&quot;, e =&gt; alert(window.localStorage[&quot;입력값&quot;]))
        clear.addEventListener(&quot;click&quot;, e =&gt; {
            window.localStorage.clear()
            field.value = &quot;&quot;
        })
        if (window.localStorage[&quot;입력값&quot;]) {
            field.value = window.localStorage[&quot;입력값&quot;]
        }
    }
&lt;/script&gt;</code></pre>
<p>이런 식으로 해서 자동완성에도 사용 가능하다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공지식 정리 - 자료구조 3. 비선형 자료구조]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-3.-%EB%B9%84%EC%84%A0%ED%98%95-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-3.-%EB%B9%84%EC%84%A0%ED%98%95-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0</guid>
            <pubDate>Tue, 21 Jan 2025 17:25:52 GMT</pubDate>
            <description><![CDATA[<h2 id="비선형-자료구조">비선형 자료구조</h2>
<blockquote>
<p><strong>비선형 자료구조</strong> : 일렬로 나열하지 않고 자료 순서, 관계가 복잡한 구조</p>
</blockquote>
<h3 id="그래프">그래프</h3>
<blockquote>
<p><strong>그래프</strong> : 정점 (vertex) 와 간선 (edge)로 이루어진 자료구조</p>
</blockquote>
<h4 id="가중치">가중치</h4>
<blockquote>
<p>가중치 : 정점과 간선 사이에 드는 비용</p>
</blockquote>
<p>그럼 그래프에 속하는 것 중 하나인 트리에 대해 알아보자.</p>
<hr>
<h2 id="트리">트리</h2>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/6e2e8da9-edaa-45e1-9e1a-863024b733cb/image.png" alt=""></p>
<ul>
<li><strong>루트 노드</strong> : 가장 위에 있는 노드</li>
<li><strong>내부 노드</strong> : 루트 노드와 리프 노드를 제외한 노드</li>
<li><strong>리프 노드</strong> : 자식 노드가 없는 노드</li>
</ul>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/4d1d79a6-3c57-4bdc-9408-8e0a3ab16f74/image.png" alt=""></p>
<p><strong>깊이</strong> : 루트 노드 ~ 특정 노드까지 최단 거리로 갔을 때의 거리</p>
<ul>
<li>각 노드마다 트리의 깊이가 다르다.</li>
</ul>
<p><strong>레벨</strong> : 보통 &#39;깊이&#39;와 같은 의미를 가진다.</p>
<ul>
<li>1번 노드가 0레벨 =&gt; 2번, 3번 노드는 1레벨</li>
</ul>
<p><strong>높이</strong> : 루트 노드 ~ 리프 노드까지의 거리 중 가장 긴 거리</p>
<p><strong>서브트리</strong> : 트리 내의 하위 집합 (부분 집합)</p>
<hr>
<h3 id="이진-트리">이진 트리</h3>
<blockquote>
<p>이진 트리 : 자식 노드의 수가 2개 이하인 트리</p>
</blockquote>
<h4 id="이진-트리의-종류">이진 트리의 종류</h4>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/97b0874b-6c03-4d55-b52f-e770c7c05013/image.png" alt=""></p>
<ul>
<li><p><strong>정이진 트리</strong> (full binary tree): 자식 노드가 0 또는 2개인 이진 트리를 의미한다.</p>
</li>
<li><p><strong>완전 이진 트리</strong> (complete binary tree): 왼쪽에서부터 채워져 있는 이진 트리를 의미한다.</p>
<ul>
<li>마지막 레벨을 제외하고는 모든 레벨이 완전히 채워져 있으며, 마지막 레벨의 경우 왼쪽부터 채워져 있다.</li>
</ul>
</li>
<li><p><strong>변질 이진 트리</strong> (degenerate binary tree): 자식 노드가 하나밖에 없는 이진 트리를 의미한다.</p>
</li>
<li><p><strong>포화 이진 트리</strong> (perfect binary tree): 모든 노드가 꽉 차 있는 이진 트리를 의미한다.</p>
</li>
<li><p><strong>균형 이진 트리</strong> (balanced binary tree): 왼쪽과 오른쪽 노드의 높이 차이가 1 이하인 이진 트리를 의미한다.</p>
<ul>
<li><code>map</code>, <code>set</code>을 구성하는 레드 블랙 트리는 균형 이진 트리 중 하나입니다.</li>
</ul>
</li>
</ul>
<hr>
<h3 id="이진-탐색-트리-bst-binary-search-tree">이진 탐색 트리 (BST, Binary Search Tree)</h3>
<blockquote>
<p><strong>이진 탐색 트리</strong> : 노드의 오른쪽 하위 트리에는 &#39;노드 값보다 큰 값&#39;만 들어 있고, 왼쪽 하위 트리에는 &#39;노드 값보다 작은 값&#39;만 들어 있는 트리</p>
</blockquote>
<p>그래서 검색할 때 용이하다</p>
<p>요소에 접근 시 평균적으로는 $O(logn)$ 소요, 최악의 경우에는 $O(n)$ 소요하며, 삽입 순서에 따라 구조가 선형적일 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/e5b2fd21-3953-4880-89c2-be1b24a39a45/image.png" alt=""></p>
<hr>
<h3 id="avl-트리-adelson-velsky-and-landis-tree">AVL 트리 (Adelson-Velsky and Landis tree)</h3>
<blockquote>
<p><strong>AVL 트리</strong> : 선형적인 트리가 되는 최악의 경우를 방지하고, 스스로 균형을 잡는 이진 탐색 트리</p>
</blockquote>
<p>두 자식 서브트리의 높이 =&gt; 항상 최대 1만큼 차이난다는 특징이 있다.</p>
<p>삽입, 삭제 시마다 균형을 맞추기 위해 트리의 일부를 왼쪽 또는 오른쪽으로 회전시킨다.</p>
<ul>
<li>탐색, 삽입, 삭제 =&gt; $O(logn)$ 소요</li>
</ul>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/9a148c4a-87b3-4f83-b939-7df24d7a73bd/image.png" alt=""></p>
<hr>
<h3 id="레드-블랙-트리">레드 블랙 트리</h3>
<blockquote>
<p><strong>레드 블랙 트리</strong> : 균형 이진 탐색 트리로 탐색, 삽입, 삭제 모두 시간 복잡도가 $O(logn)$</p>
</blockquote>
<p>각 노드에 빨간색 또는 검은색의 색을 저장하는 추가 비트를 저장하고
이는 곧 삽입, 삭제 중 트리가 균형을 유지하는데 사용된다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/d2e55e3d-b990-4dd2-923d-e8b70a3186c1/image.png" alt=""></p>
<hr>
<h2 id="힙-우선순위-큐">힙, 우선순위 큐</h2>
<p>힙과 우선순위 큐에 대해서는 정리된 것을 보자.</p>
<p><a href="https://velog.io/@jojehuni_9759/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%ED%9E%99-heap-Java">자료구조 - 힙 heap (Java)</a></p>
<p><a href="https://velog.io/@jojehuni_9759/Java-%EC%8A%A4%ED%83%9D-%ED%81%90-Stack-Queue">우선순위 큐</a></p>
<p>우선순위 큐에 대해서는 아래로 내려보면 정리를 해뒀다.</p>
<hr>
<h2 id="맵-해시-테이블">맵, 해시 테이블</h2>
<p><a href="https://velog.io/@jojehuni_9759/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-Hash-Java-HashMap">Hash, HashTable</a></p>
<blockquote>
<p><strong>맵</strong> : 특정 순서에 따라 키에 매핑된 값의 조합 (키-값) 으로 구성된 자료구조</p>
<ul>
<li>레드 블랙 트리 자료구조 기반으로 형성된다.</li>
<li>삽입 시 자동으로 정렬된다.</li>
<li>해시 테이블 구현 시 사용한다.<ul>
<li><code>unordered_map</code> : 정렬 보장 X</li>
<li><code>map</code> : 정렬 보장 O</li>
</ul>
</li>
</ul>
</blockquote>
<p><code>map&lt;string, int&gt;</code> 형태로 구현하며 아래와 같은 기능들이 있는데 </p>
<ul>
<li><code>clear()</code> : 맵에 있는 모든 요소 삭제</li>
<li><code>size()</code> : map의 크기 구함</li>
<li><code>erase()</code> : 해당 키와 키에 매핑된 값 삭제</li>
</ul>
<p>Java에서의 <code>HashMap</code> 메서드도 위 링크에 정리를 해놨다.</p>
<hr>
<blockquote>
<p>해시 테이블 : 무한에 가까운 데이터를 유한한 개수의 해시 값으로 매핑한 테이블
<code>unordered_map</code>으로 구현</p>
</blockquote>
<p>삽입, 삭제, 탐색 =&gt; 평균적으로 $O(1)$ 소요</p>
<hr>
<h2 id="셋-set">셋 (set)</h2>
<blockquote>
<p><strong>Set</strong> : 특정 순서에 따라 고유한 요소 저장하는 컨테이너</p>
</blockquote>
<p>중복되는 요소 없이 <code>unique</code> 값만 저장한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공지식 정리 - 자료구조 2. 선형 자료구조]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-2.-%EC%84%A0%ED%98%95-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-2.-%EC%84%A0%ED%98%95-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0</guid>
            <pubDate>Tue, 21 Jan 2025 16:37:55 GMT</pubDate>
            <description><![CDATA[<h1 id="선형-자료-구조">선형 자료 구조</h1>
<p>요소가 일렬로 나열돼 있는 자료구조로</p>
<ul>
<li>연결 리스트</li>
<li>배열</li>
<li>벡터</li>
<li>스택</li>
<li>큐</li>
</ul>
<p>에 대해 알아보자.</p>
<h2 id="연결-리스트">연결 리스트</h2>
<p>이전에 Java의 컬렉션을 정리하면서 리스트 관련은 정리한 것이 있다.</p>
<p><a href="https://velog.io/@jojehuni_9759/Java-Collection-%EC%BB%AC%EB%A0%89%EC%85%98">Java - Collection (List - ArrayList)</a></p>
<p><a href="https://velog.io/@jojehuni_9759/Java-Collection-List-LinkedList">Java - Collection (List - LinkedList)</a></p>
<blockquote>
<p><strong>연결 리스트</strong></p>
</blockquote>
<ul>
<li>싱글 연결 리스트 : next 포인터만 가지는 것</li>
<li>이중 연결 리스트 : next, prev 포인터를 가지는 것</li>
<li>원형 이중 연결 리스트 : 이중 연결 리스트와 같은데 추가로 마지막 노드의 next 포인터가 헤드 노드를 가리키는 것</li>
</ul>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/8fb69e7c-39df-4c5d-9c39-f91652f26851/image.png" alt=""></p>
<blockquote>
<p>연결 리스트의 함수</p>
</blockquote>
<ul>
<li><code>push_front()</code>: 앞에서부터 요소 추가</li>
<li><code>push_back()</code>: 뒤에서부터 요소 추가</li>
<li><code>insert()</code>: 중간에 요소 추가</li>
</ul>
<hr>
<h2 id="배열">배열</h2>
<p>같은 타입의 변수, 지정된 크기, 인접한 메모리 위치에 있는 데이터를 모아둔 집합이다.
중복을 허용하며 순서가 있다.</p>
<p>정적 배열을 기반으로 알아보자.
우선 배열의 접근에는 $O(1)$의 복잡도를 가지고 랜덤 접근이 가능하다.
삽입과 삭제에는 $O(n)$이 걸린다.</p>
<p>그래서 추가/삭제 시에는 연결 리스트를 사용하고, 접근(참조)을 하는 것은 배열이 좋다.
그런 이유는 아래 비교에서 알아보자.</p>
<blockquote>
<p><strong>랜덤 접근 (random access)</strong>
순차적인 데이터가 있을 때 임의의 인덱스에 해당하는 데이터에 접근할 수 있는 기능</p>
<p><strong>순차적 접근</strong>
저장된 순서대로 데이터를 접근해야 함</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/f03d92ab-f028-49f4-abf6-0fcf4036b5da/image.png" alt=""></p>
</blockquote>
<hr>
<h3 id="배열-연결-리스트-비교">배열, 연결 리스트 비교</h3>
<ul>
<li>배열은 인덱스 번호만 알아도 해당 값을 얻을 수 있다.</li>
<li>연결 리스트는 순차 접근이 불가능하여 찾고자 하는 해당 위치까지 탐색을 해야 한다.</li>
</ul>
<blockquote>
<p>즉, 배열은 참조나 탐색하기엔 연결리스트보다 빠르다.
하지만 삽입, 삭제에서는 연결리스트에서는 next, prev 선만 변경하면 가능하기 때문에 연결리스트를 선택하는 것이 좋다.</p>
</blockquote>
<hr>
<h2 id="벡터">벡터</h2>
<blockquote>
<p>벡터 : 동적으로 요소 할당 가능한 <strong>동적 배열</strong>이다.</p>
</blockquote>
<ul>
<li>파일 시점에 요소의 개수를 모른다면 벡터 사용해야 한다.</li>
<li>중복 허용, 순서 있음, 랜덤 접근 가능</li>
</ul>
<p><strong>탐색</strong>하는 것과 <strong>맨 뒤의 요소에 삽입/삭제하는 것</strong>에는 $O(1)$이 걸리고
그렇지 않은 요소에 삽입/삭제 하는 것은 $O(n)$의 시간이 걸린다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/565f5de3-c4f9-47ac-b8a2-c244964f2d1c/image.png" alt=""></p>
<p>2의 제곱승 + 1 (3, 5, 9 ...) 일 때마다 크기를 2배로 늘리는 것을 알 수 있다.</p>
<blockquote>
<p>벡터의 함수</p>
</blockquote>
<ul>
<li><code>push_back()</code>: 뒤에서부터 요소 추가</li>
<li><code>pop_back()</code>: 맨 뒤부터 요소 삭제</li>
<li><code>erase()</code>: 요소 삭제</li>
<li><code>find()</code>: 요소 탐색</li>
<li><code>clear()</code>: 배열 초기화</li>
</ul>
<hr>
<h2 id="스택-큐">스택, 큐</h2>
<p>스택과 큐는 이전에 정리했던 것을 봐도 충분할 것이다.</p>
<p><a href="https://velog.io/@jojehuni_9759/Java-%EC%8A%A4%ED%83%9D-%ED%81%90-Stack-Queue">스택, 큐</a></p>
<p>다음은 비선형 자료 구조에 대해 알아보자.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공지식 정리 - 자료구조 1. 복잡도]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-1.-%EB%B3%B5%EC%9E%A1%EB%8F%84</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-1.-%EB%B3%B5%EC%9E%A1%EB%8F%84</guid>
            <pubDate>Tue, 21 Jan 2025 16:08:33 GMT</pubDate>
            <description><![CDATA[<h1 id="자료구조">자료구조</h1>
<p>자료구조란, 효율적으로 데이터를 관리하고 수정, 삭제, 탐색, 저장할 수 있는 데이터 집합이다.</p>
<h2 id="복잡도">복잡도</h2>
<h3 id="시간-복잡도">시간 복잡도</h3>
<blockquote>
<p><strong>시간 복잡도</strong> : 입력 크기에 대해 어떠한 알고리즘이 실행되는데 걸리는 시간
주요 로직의 반복 횟수를 중점으로 측정된다. 보통 <strong>빅오 표기법</strong>으로 표현</p>
</blockquote>
<h4 id="빅오-표기법">빅오 표기법</h4>
<blockquote>
<p>빅오 표기법 : 입력 범위 n을 기준으로 해서 로직이 몇 번 반복되는지 나타내는 것</p>
</blockquote>
<p>입력 크기가 커질 수록 연산량이 가장 많이 커지는 항 (ex. $n^2$ 항) 과 달리 다른 것은 연산량의 증가가 미미하기 때문에 그것만 신경쓰면 된다.</p>
<p><strong>시간 복잡도가 존재하는 이유</strong>
시간 복잡도를 더욱 효율적인 코드로 개선할 수 있는 척도로 이용
소요 시간: $O(n^2)$ &gt; $O(n)$ &gt; $O(1)$</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/8ddaa5bc-f470-472b-b619-7d84d51fefaa/image.png" alt=""></p>
<p>즉, $O(n^2)$ 보다는 $O(n)$, $O(n)$보다도 $O(1)$을 지향해야 한다.</p>
<hr>
<h3 id="자료구조에서의-시간-복잡도">자료구조에서의 시간 복잡도</h3>
<p>거의 평균 시간 복잡도와 최악의 시간 복잡도를 고려하면서 쓴다.</p>
<h4 id="1-평균-시간-복잡도">1) 평균 시간 복잡도</h4>
<table>
<thead>
<tr>
<th>자료 구조</th>
<th>접근</th>
<th>탐색</th>
<th>삽입</th>
<th>삭제</th>
</tr>
</thead>
<tbody><tr>
<td>배열</td>
<td>O(1)</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(n)</td>
</tr>
<tr>
<td>스택</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(1)</td>
<td>O(1)</td>
</tr>
<tr>
<td>큐</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(1)</td>
<td>O(1)</td>
</tr>
<tr>
<td>이중 연결 리스트</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(1)</td>
<td>O(1)</td>
</tr>
<tr>
<td>해시 테이블</td>
<td>O(1)</td>
<td>O(1)</td>
<td>O(1)</td>
<td>O(1)</td>
</tr>
<tr>
<td>이진 탐색 트리</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
</tr>
<tr>
<td>AVL 트리</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
</tr>
<tr>
<td>레드 블랙 트리</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
</tr>
</tbody></table>
<h4 id="2-최악의-시간-복잡도">2) 최악의 시간 복잡도</h4>
<table>
<thead>
<tr>
<th>자료 구조</th>
<th>접근</th>
<th>탐색</th>
<th>삽입</th>
<th>삭제</th>
</tr>
</thead>
<tbody><tr>
<td>배열</td>
<td>O(1)</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(n)</td>
</tr>
<tr>
<td>스택</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(1)</td>
<td>O(1)</td>
</tr>
<tr>
<td>큐</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(1)</td>
<td>O(1)</td>
</tr>
<tr>
<td>이중 연결 리스트</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(1)</td>
<td>O(1)</td>
</tr>
<tr>
<td>해시 테이블</td>
<td>O(1)</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(n)</td>
</tr>
<tr>
<td>이진 탐색 트리</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(n)</td>
<td>O(n)</td>
</tr>
<tr>
<td>AVL 트리</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
</tr>
<tr>
<td>레드 블랙 트리</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
<td>O(logn)</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공지식 정리 - 데이터베이스 3. 트랜잭션과 무결성 (격리성 2)]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-3.-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98%EA%B3%BC-%EB%AC%B4%EA%B2%B0%EC%84%B1-%EA%B2%A9%EB%A6%AC%EC%84%B1-2</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-3.-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98%EA%B3%BC-%EB%AC%B4%EA%B2%B0%EC%84%B1-%EA%B2%A9%EB%A6%AC%EC%84%B1-2</guid>
            <pubDate>Tue, 14 Jan 2025 16:50:42 GMT</pubDate>
            <description><![CDATA[<h2 id="repeatable-read">Repeatable Read</h2>
<blockquote>
<p>MySQL에서는 트랜잭션마다 트랜잭션 ID를 부여하여 트랜잭션 ID보다 작은 트랜잭션 번호에서 변경한 것만 읽게 된다.</p>
</blockquote>
<p>아래에서 할 예시들은 트랜잭션 번호를 생략해두고 진행했다.</p>
<hr>
<blockquote>
<p><code>Repeatable Read</code> 에서는 다른 트랜잭션 격리수준인 <code>Read Uncommitted</code> 나 <code>Read Committed</code> 에서와 달리 <code>Non-Repeatable Read</code> *<em>현상이 발생하지 않는다. *</em></p>
</blockquote>
<blockquote>
<p><strong>Non-Repeatable Read</strong> : 하나의 트랜잭션에서 같은 값을 두 번 select 했을 때 각각 다른 값이 읽히는 현상</p>
</blockquote>
<p>이게 무슨 소리냐면</p>
<ul>
<li>똑같은 레코드를 2번 조회하는 트랜잭션 A</li>
<li>해당 레코드를 수정하고 커밋하는 트랜잭션 B</li>
</ul>
<ol>
<li>트랜잭션 A의 1번째 조회가 진행</li>
<li>트랜잭션 B가 해당 레코드 수정 -&gt; 커밋</li>
<li>트랜잭션 A의 2번째 조회가 진행 == <strong>데이터가 변경돼 Non-Repeatable Read 발생</strong></li>
</ol>
<p>위 순서대로 진행이 된다면 데이터가 변경돼 Non-Repeatable Read 발생한다는 것이다.</p>
<p>그럼 문득 &quot;<strong>하나의 트랜잭션에서 같은 데이터의 조회를 2번 할 일이 없다면?</strong>&quot; 이라고 생각이 들 수도 있다.</p>
<blockquote>
<p>MySQL InnoDB 스토리지 엔진의 기본 트랜잭션 격리수준으로 <code>Repeatable Read</code> 을 설정한 이유가 뭘까?</p>
</blockquote>
<hr>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/ec8d7ba0-15e0-4923-ac25-9c78ca8cfba6/image.png" alt=""></p>
<p>위 사진은 MySQL docs에서 Repeatable Read를 정의한 내용으로</p>
<p>첫 줄의 &quot;Consistent reads within the same transaction read the snapshot established by the first read.&quot; </p>
<p>= 동일한 트랜잭션 내에서의 일관된 조회는 첫 번째 조회에 의해 설정된 스냅샷을 읽는다. 는 뜻이다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/7570d58b-5c29-4cf7-97e6-6923f34e0cfe/image.png" alt=""></p>
<p><strong>스냅샷</strong> : &quot;일관된 조회를 위해 특정 격리 수준에서 사용되는 것으로서 다른 트랜잭션에 의해 변경 사항이 커밋되더라도 동일하게 유지되는 특정 시간의 데이터 표현&quot;</p>
<p>이번엔 다른 형태의 트랜잭션을 가정을 들어 설명하겠다.</p>
<ul>
<li>각자 다른 테이블에 대해 1번씩 조회하는 트랜잭션 C</li>
<li>C가 2번째로 조회하는 테이블의 레코드를 수정 후 커밋하는 트랜잭션 D</li>
</ul>
<ol>
<li>트랜잭션 C의 1번째 테이블의 특정 레코드 조회가 진행</li>
<li>트랜잭션 D가 2번째 테이블의 특정 레코드 수정 -&gt; 커밋</li>
<li>트랜잭션 C의 2번째 테이블의 해당 레코드 조회가 진행</li>
</ol>
<p>위 과정을 겪으면 어떻게 될까?</p>
<ol>
<li>C는 한 트랜잭션에서 1, 2번째 조회를 하기 때문에 D가 수정하기 전의 2번째 테이블 속 레코드를 읽기</li>
<li>C는 2번째 조회 시 D가 수정한 레코드의 데이터로 읽기</li>
</ol>
<p>정답은 바로 1번이다. 말이 길어져서 간단히 그림으로 설명하면</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/8cf3c50b-73ca-4a5c-bfa7-a6c2535b5637/image.png" alt=""></p>
<p>이렇게 plan을 C 중간에 수정하고 커밋하더라도 before이었던 레코드가 그대로 출력된다는 뜻이다.</p>
<p>트랜잭션 격리수준이 <code>Repeatable Read</code> 라면 한 트랜잭션 내에서 동일한 select 를 2번 이상 시도해도 동일한 결과가 반환된다.</p>
<p>다른 테이블 데이터 역시 최초 조회(first read) 시점에서의 데이터가 마치 스냅샷(snapshot)처럼 유지되어 있던 것이다.</p>
<hr>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/13567f7b-2d06-4d27-aa0b-e3ca49e5a74e/image.png" alt=""></p>
<p>그렇게 할 수 있는 이유는 </p>
<blockquote>
<p><strong>일관된 조회</strong> : <strong>조회한 시점</strong>을 기준으로 쿼리 결과를 표시하는 스냅샷 정보를 사용하는 것</p>
</blockquote>
<p>2번째 줄의 <code>If queried ~</code> 로 시작하는 문구를 보면 <strong>&quot;조회된 데이터(queried data)가 다른 트랜잭션에 의해 변경되었다면 본래 데이터는 undo log 의 내용을 통해 재구성된다.&quot;</strong> 라는 뜻인데</p>
<p>트랜잭션 C는 D가 수정한 데이터의 원본 데이터가 undo log 에 들어갔고 이 undo log 로부터 해당 데이터를 가져왔다는 것을 알 수 있다.</p>
<blockquote>
<p><strong>언두 로그</strong> : 활성 트랜잭션에 의해 수정된 데이터의 복사본을 보관하는 저장 영역</p>
<p>즉, 수정하기 전 원본 데이터가 저장되는 영역</p>
</blockquote>
<hr>
<p>대신 Phantom Read 라고 하는 현상이 발생하기도 한다.</p>
<h3 id="phantom-read">Phantom Read</h3>
<p><strong>Phantom Read</strong> : 한 트랜잭션 내에서 동일한 쿼리를 보냈을 때 해당 조회 결과가 다른 경우</p>
<blockquote>
<ul>
<li><strong>Phantom Read와 Non-Repeatable Read의 차이??</strong></li>
</ul>
</blockquote>
<ul>
<li>Non-Repeatable Read는 1개의 Row의 데이터의 값이 변경되는 것이며 (Update 또는 Delete)</li>
<li>Phantom Read는 다수의 건을 요청하는 것에 대해서 데이터의 값이 변경되는 것<blockquote>
<p>즉, Non-Repeatable Read는 위에서 봤다시피 1개의 Row의 데이터를 2번 조회하는 트랜잭션 내에서 다른 트랜잭션에 의해 update나 delete로 하나의 데이터가 변경됐을 때 언두 로그로 인해 변경되기 전의 데이터를 조회할 수 있다는 것이다.</p>
</blockquote>
</li>
</ul>
<p><code>Phantom Read</code>를 예를 들어 설명하면</p>
<ul>
<li>member라는 테이블을 select로 다 조회하는 트랜잭션 E<pre><code class="language-sql">select * from member</code></pre>
</li>
</ul>
<p>E는 위와 같은 쿼리문이 2번 사용되는 트랜잭션이라고 생각하면 된다.</p>
<ul>
<li>member라는 테이블에 Insert와 같이 데이터를 하나 추가 후 commit 하는 트랜잭션 F<pre><code class="language-sql">INSERT INTO member (member_id, member_name) 
VALUES (70, &#39;Jehun&#39;)</code></pre>
<pre><code class="language-sql">commit</code></pre>
</li>
</ul>
<ol>
<li>E에서 1번째 select =&gt; Jehun이라는 멤버가 추가되기 전 데이터들이 조회</li>
<li>F에서 Insert 후 commit =&gt; member 테이블에 Jehun 추가</li>
<li>E에서 2번째 select =&gt; Jehun이라는 멤버가 추가된 후 데이터들이 조회 =&gt; 이 때 <code>Phantom Read</code>가 발생하는 것이다.</li>
</ol>
<hr>
<p>기존에 Real MySQL 8.0 책을 정리했을 때 언두 로그를 활용한 Repeatable Read에 대해서 잘 몰랐는데 이제 어느 정도 이해가 된 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공지식 정리 - 데이터베이스 3. 트랜잭션과 무결성 (격리성 1)]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-3.-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98%EA%B3%BC-%EB%AC%B4%EA%B2%B0%EC%84%B1-%EA%B2%A9%EB%A6%AC%EC%84%B1-1</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-3.-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98%EA%B3%BC-%EB%AC%B4%EA%B2%B0%EC%84%B1-%EA%B2%A9%EB%A6%AC%EC%84%B1-1</guid>
            <pubDate>Tue, 14 Jan 2025 16:31:57 GMT</pubDate>
            <description><![CDATA[<h1 id="트랜잭션과-무결성---격리성">트랜잭션과 무결성 - 격리성</h1>
<p>트랜잭션과 무결성파트의 <strong>격리성</strong>에 대해 다뤄볼까 한다.</p>
<p>여러 개의 격리 수준이 있는데 내용이 어려워서 직접 정리를 하면서 봐야 알 수 있지 않을까 싶어서 해본다.</p>
<blockquote>
<p><strong>격리성</strong> : 트랜잭션 수행 시 서로 끼어들지 못하는 것</p>
</blockquote>
<p>여러 개의 병렬 트랜잭션은 서로 격리돼 순차적으로 실행되는 것처럼 작동돼야 한다.</p>
<p>그리고 데이터베이스는 여러 사용자가 같은 데이터에 접근할 수 있어야 한다.</p>
<p>순차적으로 접근할 수 있게 하면 쉽겠지만 성능이 별로기 때문에 여러 개의 격리 수준으로 나눠 격리성을 보장한다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/9d32a9eb-3ed3-4992-be25-1071755d04a0/image.png" alt=""></p>
<ul>
<li>READ UNCOMMITED</li>
<li>READ COMMITTED</li>
<li>REPEATABLE READ</li>
<li>SERIALIZABLE</li>
</ul>
<p>순서가 위로 갈수록 동시성이 강하면서 / 격리성은 약해진다.</p>
<hr>
<h2 id="serializable">SERIALIZABLE</h2>
<p>가장 엄격한 격리 수준이다.
<code>SERIALIZABLE</code>에서 <strong>여러 트랜잭션이 동일한 레코드에 동시 접근 불가, 어떠한 데이터 부정합 문제도 발생 X</strong> 
하지만 트랜잭션이 순차적으로 처리되어야 하므로 동시 처리 성능이 매우 떨어진다.</p>
<blockquote>
<p>MySQL에서 <code>SELECT FOR SHARE/UPDATE</code>는 대상 레코드에 각각 읽기/쓰기 잠금을 거는 것이다.
하지만 순수한 <code>SELECT</code> 작업은 아무런 레코드 잠금 없이 실행된다.</p>
</blockquote>
<ul>
<li><code>잠금 없는 일관된 읽기(Non-locking consistent read)</code> : 순수한 <code>SELECT</code> 문을 통한 잠금 없는 읽기를 의미하는 것</li>
</ul>
<p><strong>그럼에도</strong> <code>SERIALIZABLE</code>는 순수한 SELECT 작업에서도 대상 레코드에 넥스트 키 락을 읽기 잠금(공유락, Shared Lock)으로 건다.</p>
<p>따라서 한 트랜잭션에서 넥스트 키 락이 걸린 레코드를 다른 트랜잭션에서는 절대 추가/수정/삭제할 수 없다.</p>
<blockquote>
<p>참고로, 스프링이 제공하는 트랜잭션 AOP 기능은 개발자가 별도로 트랜잭션 격리수준을 설정하지 않을 경우 데이터소스의 기본 트랜잭션 격리수준을 따르게 된다.</p>
<p>즉, 따로 격리수준을 설정하면 <code>SERIALIZABLE</code> 로도 격리수준 설정이 가능하다.</p>
<p>설정하지 않고 MySQL InnoDB 스토리지 엔진 기반의 테이블을 사용한다면 <code>Repeatable Read</code> 격리 수준을 따르게 된다.</p>
</blockquote>
<h3 id="동시성-이슈">동시성 이슈</h3>
<p><strong>그럼 동시성 이슈(Lost Update)를 해결하기 위해서 SERIALIZABLE를 적용해야 할까?</strong></p>
<p>동시성 이슈에 대한 대표적인 사례인 &#39;재고 이슈&#39;를 보면</p>
<p>ex) 어느 하나의 재고에 대해 n개가 있는데 변경 작업(재고 1 감소)을 시도하는 A 트랜잭션이 종료되기 전 B 트랜잭션이 실행된다면?</p>
<ul>
<li><strong>SERIALIZABLE 적용 전</strong></li>
</ul>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/b5f6f908-f701-4fa5-884b-41b539aa920d/image.png" alt=""></p>
<p>A 트랜잭션에서 n개 -&gt; n - 1개로 줄이는 과정에서
B 트랜잭션이 시도돼 n개로 알고 있지만 실제로는 A에서 재고 변경이 일어나면서 n - 1개가 된 상태일 때.</p>
<p>트랜잭션 A 와 트랜잭션 B 가 거의 동시에 처리될 때, 트랜잭션 B 의 변경작업이 유실(Lost Update)되는 이슈가 발생한다는 것을 예측할 수 있다.</p>
<hr>
<ul>
<li><strong>SERIALIZABLE 적용 후</strong></li>
</ul>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/65e25a02-9cbb-4f37-99c5-a75af0060bfa/image.png" alt=""></p>
<p>SELECT 작업 시 공유 잠금을 사용하고 있는 것을 볼 수 있다.</p>
<p>한 트랜잭션에서 특정 레코드에 공유 잠금을 걸었다면 -&gt; 다른 트랜잭션에서는 해당 레코드를 조회하거나 공유 잠금을 걸 수는 있으나, 쓰기 잠금이나 변경 작업은 할 수 없게 된다. <strong>(Lock waiting)</strong></p>
<p>그래서 트랜잭션 A 가 해당하는 레코드에 대해 공유 잠금을 동반한 읽기를 하면, 트랜잭션 B 역시 해당 레코드에 대해 공유 잠금을 동반한 읽기를 할 수는 있다.</p>
<hr>
<p>하지만 변경을 하게 된다면?</p>
<p>트랜잭션 B 가 건 공유 잠금 때문에 <code>Lock waiting</code> 에 빠지게 되며, 트랜잭션 B 역시 변경 작업 수행 시 앞서 트랜잭션 A 가 건 공유 잠금 때문에 <code>Lock waiting</code> 에 빠지게 된다. <strong>즉, 데드락(Dead-lock)이 발생하게 된다.</strong></p>
<p>MySQL의 InnoDB 스토리지 엔진의 경우, 내부적으로 잠금이 교착 상태에 빠지지 않았는지 체크하기 위해 잠금 대기 목록(Wait for list)을 관리한다.</p>
<p>이 때, <strong>별도의 데드락 감지 스레드가 주기적으로 해당 잠금 대기 목록을 검사해 교착 상태에 빠진 트랜잭션들을 찾아서 그 중 하나(또는 여러개)를 강제로 종료</strong>한다.</p>
<blockquote>
<p>어느 트랜잭션을 먼저 강제 종료할 것인지를 판단하는 기준은 트랜잭션의 언두 로그 양인데, <strong>적은 언두 로그 양을 가진 트랜잭션을 우선적으로 롤백</strong>시킨다.</p>
</blockquote>
<p>결론적으로, 트랜잭션 격리수준을 <code>Serializable</code> 로 했을 때, <strong>데드락을 발생시키고 다른 트랜잭션을 롤백시킴으로써 Lost Update 를 방지할 수는 있게 된다.</strong></p>
<hr>
<h4 id="데드락을-발생시키고-다른-트랜잭션을-롤백시킴으로써-lost-update-를-방지하는-것이-동시성-이슈를-해결하는-좋은-방안일까">데드락을 발생시키고 다른 트랜잭션을 롤백시킴으로써 Lost Update 를 방지하는 것이 동시성 이슈를 해결하는 좋은 방안일까?</h4>
<p>예시로 들었던 동시성 이슈의 근본적 원인은 <strong>어떤 트랜잭션이 작업 중인 레코드에 대해 다른 트랜잭션에서도 동시 조회를 허용했기 때문</strong>이며,</p>
<p><code>Serializable</code>로 하더라도 다른 트랜잭션에서 공유 잠금이 걸린 레코드를 조회할 수 있기에 이 데이터를 기반으로 <code>Update</code> 하는 행위 자체는 여전히 가능한 것이다.</p>
<p>이미 한 트랜잭션에서 조회, 수정하는 절차를 하고 있다면 그 해당하는 재고 데이터는 불확실한 상황이기 때문에 다른 트랜잭션이 접근을 하게 해서는 안 되는 것이다.</p>
<p>-&gt; <strong>해당 데이터를 읽고 그 다음 작업들까지 수행할 수 있기 때문에 불필요한 서버 리소스를 낭비하는 것</strong></p>
<p>추가로 <strong>데드락으로 인해 롤백되어 희생되는 트랜잭션(= victim)</strong>이 발생하는 것도 서버 입장에서 데드락으로 인해 해당 트랜잭션이 롤백되었을 때 발생하는 예외를 별도로 처리해주어야 하기 때문에 고민거리이다.</p>
<hr>
<h3 id="동시성-이슈-해결책">동시성 이슈 해결책</h3>
<blockquote>
<p><strong>배타 잠금(exclusive lock)</strong> : 공유 잠금과 마찬가지로 SELECT 작업 시 사용하는 것</p>
<ul>
<li>공유 잠금과 달리 배타 잠금이 걸린 레코드에는 다른 트랜잭션에서 쓰기 작업뿐만 아니라 조회 작업도 허용하지 않는다.</li>
<li>추가로, 공유 잠금과 배타 잠금을 걸 수도 없다.</li>
</ul>
</blockquote>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/cd7e4b5e-9473-49ea-9ed3-f4105e887e35/image.png" alt=""></p>
<p>사진은 배타 잠금을 적용한 이후의 상황이다.</p>
<p>트랜잭션 격리수준을 Serializable 로 적용했을 때와 달리</p>
<p>트랜잭션 B는 불필요한 작업을 수행하지 않으며, 데드락을 유도하지 않아 둘 중 한 트랜잭션이 롤백될 일도 없다. </p>
<blockquote>
<p>즉, 서버 리소스를 보다 효율적으로 사용할 수 있게 되는 것</p>
</blockquote>
<blockquote>
<p>공유 잠금이나 배타 잠금은 MySQL 수준에서 제공하는 잠금 기능으로 비관적 락(Pessimistic lock)이라고도 부른다.</p>
</blockquote>
<p>다음은 Repeatable Read에 대해 정리해보겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공지식 정리 - 운영체제 4. CPU 스케줄링 알고리즘]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-4.-CPU-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-4.-CPU-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</guid>
            <pubDate>Tue, 07 Jan 2025 16:55:45 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/e3142c4c-0f35-4e8b-afc1-88ad13d1e124/image.png" alt=""></p>
<p>CPU 스케줄러는 <strong>CPU 스케줄링 알고리즘에 따라 프로세스에서 해야 하는 일을 스레드 단위로 CPU에 할당</strong>한다.</p>
<p>CPU 스케줄링 알고리즘이 어떤 프로그램에 CPU 소유권을 줄지 결정하는데</p>
<blockquote>
<ul>
<li>CPU 이용률은 높게</li>
</ul>
</blockquote>
<ul>
<li>주어진 시간에 많은 일을 하게</li>
<li>준비 큐에 있는 프로세스는 적게</li>
<li>응답 시간은 짧게</li>
</ul>
<hr>
<h2 id="비선점형-방식">비선점형 방식</h2>
<blockquote>
<p>프로세스 스스로 CPU 소유권을 포기하는 방식이며, 강제로 프로세스를 중지하지 않는다.
컨텍스트 스위칭으로 인한 부하가 적다.</p>
</blockquote>
<h3 id="fcfs">FCFS</h3>
<p>FCFS는 First Come, First Served 로 <strong>가장 먼저 온 것을 가장 먼저 처리하는 알고리즘</strong></p>
<p><strong>단점</strong></p>
<ul>
<li><strong>길게 수행되는 프로세스 때문에 준비 큐에서 오래 기다리는 현상</strong> (Convoy effect)이 발생하기도 한다.</li>
</ul>
<hr>
<h3 id="sjf">SJF</h3>
<p>SJF는 Shortest Job First로 <strong>실행 시간이 가장 짧은 것을 가장 먼저 실행하는 알고리즘</strong></p>
<p><strong>장점</strong></p>
<ul>
<li>평균 대기 시간이 가장 짧은 알고리즘</li>
</ul>
<p><strong>단점</strong></p>
<ul>
<li><strong>긴 시간을 가진 프로세스가 실행되는 않는 현상</strong> (Starvation)이 발생하기도 한다.</li>
</ul>
<p>위와 같은 장점이 있기도 하지만, 실제로는 실행 시간을 알 수 없어 과거에 실행했던 시간을 토대로 추측해서 사용한다.</p>
<hr>
<h3 id="우선순위">우선순위</h3>
<p>기존 SJF 스케줄링의 경우 긴 시간을 가진 프로세스가 실행되지 않는 현상이 있었다.</p>
<p><strong>오래된 작업일수록 우선 순위를 높이는 방식을 통해 위에 알고리즘에 단점을 보완한 방식</strong></p>
<hr>
<h2 id="선점형-방식">선점형 방식</h2>
<p>이는 현대 운영체제가 쓰는 방식</p>
<blockquote>
<p>지금 사용하고 있는 프로세스를 알고리즘에 의해 중단 시켜 버리고, 강제로 다른 프로세스에 CPU 소유권을 할당하는 방식</p>
</blockquote>
<p>라운드 로빈, SRF, 다단계 큐와 같은 것들이 있다. 알아보자.</p>
<hr>
<h3 id="라운드-로빈">라운드 로빈</h3>
<p>이는 현대 컴퓨터가 쓰고 있는 스케줄링인 우선순위 스케줄링의 일종</p>
<blockquote>
<p>각 프로세스는 동일한 할당 시간을 주고 그 시간 안에 끝나지 못하면 다시 준비 큐 뒤로 가는 알고리즘</p>
</blockquote>
<p>시간 할당량을 q 라고 했을 때 N개의 프로세스가 운영된다고 하면 (N-1) * q 시간이 지났을 때 자신의 차례가 된다.</p>
<p>할당 시간 q가 너무 크면 FCFS가 되고, 짧으면 컨텍스트 스위칭이 잦아지면서 오버헤드 -&gt; 비용이 커진다.</p>
<p>일반적으로 전체 작업 시간은 길어지지만 평균 응답 시간은 짧아진다는 특징이 있다.</p>
<blockquote>
<p>로드밸런서에서 트래픽 분산 알고리즘으로도 쓰인다.</p>
</blockquote>
<hr>
<h3 id="srf">SRF</h3>
<p>SJK는 실행 시간이 더 짧은게 들어와도 기존 작업을 모두 수행하고 그 다음 짧은 작업을 이어간다.</p>
<p>하지만 SRF(Shortest Remaining Time First)는 <strong>중간에 더 짧은 작업이 들어오면 수행하던 프로세스를 중지하고 해당 프로세스를 수행하는 알고리즘</strong></p>
<hr>
<h3 id="다단계-큐">다단계 큐</h3>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/f10b113f-7d67-4805-9bc5-b9ca6d38c689/image.png" alt=""></p>
<blockquote>
<p>우선순위에 따른 준비 큐를 여러 개 사용하고, 큐마다 라운드 로빈이나 FCFS 등 다른 스케줄링 알고리즘을 적용한 것</p>
</blockquote>
<p>큐 간의 프로세스 이동이 안되므로 스케줄링 부담이 적지만 유연성이 그만큼 떨어진다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공지식 정리 - 운영체제 3. 프로세스와 스레드]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-3.-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EC%8A%A4%EB%A0%88%EB%93%9C</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-3.-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EC%8A%A4%EB%A0%88%EB%93%9C</guid>
            <pubDate>Tue, 07 Jan 2025 16:18:13 GMT</pubDate>
            <description><![CDATA[<p><strong>프로세스</strong> : 컴퓨터에서 실행되고 있는 프로그램
CPU 스케줄링의 대상이 되는 작업이라는 용어와 거의 같은 의미로 쓰인다.</p>
<p><strong>스레드</strong> : 프로세스 내 작업의 흐름</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/c6381944-ed1a-492d-a659-b4ec4508793b/image.png" alt="">
프로그램이 메모리에 올라가면 인스턴스화된 것이 프로세스이다.
운영체제의 CPU 스케줄러에 따라 CPU가 프로세스를 실행한다.</p>
<hr>
<h2 id="프로세스와-컴파일-과정">프로세스와 컴파일 과정</h2>
<blockquote>
<p><strong>컴파일(Compile)</strong> : 소스코드를 컴퓨터가 이해할 수 있는 기계어로 번역하여 실행할 수 있는 파일을 만드는 작업</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/96c1a806-27f9-4a80-bf3f-c9fd5b304947/image.png" alt=""></p>
<p>위는 프로그램 컴파일 과정 사진이다.</p>
<ul>
<li><p>전처리</p>
<ul>
<li>소스 코드의 주석 제거, #include 등 헤더 파일을 병합하여 매크로를 치환</li>
</ul>
</li>
<li><p>컴파일러</p>
<ul>
<li>오류 처리, 코드 최적화 작업, 어셈블리어로 변환</li>
</ul>
</li>
<li><p>어셈블러</p>
<ul>
<li>어셈블리어를 목적 코드로 변환</li>
</ul>
</li>
<li><p>링커</p>
<ul>
<li>프로그램 내에 있는 라이브러리 함수 또는 다른 파일들과 목적 코드로 결합하여 실행 파일을 만듦</li>
<li>실행 파일의 확장자는 .exe또는 .out</li>
</ul>
</li>
</ul>
<hr>
<h2 id="프로세스의-상태">프로세스의 상태</h2>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/221d3c82-57c3-47e6-a7e9-e2132ea25568/image.png" alt=""></p>
<h3 id="생성create">생성(create)</h3>
<p>프로세스가 생성된 상태를 의미하며, <code>fork()</code> 또는 <code>exec()</code> 함수를 통해 생성 -&gt; 이 때 PCB가 할당된다.</p>
<blockquote>
<p><strong>PCB(Process Control Block)</strong>?</p>
<ul>
<li>프로세스의 메타데이터들이 저장되어 관리되는 영역</li>
<li>프로세스의 중요한 정보를 포함하고 있기 때문에 일반 사용자가 접근하지 못하도록 커널 스택의 가장 앞부분에서 관리됨</li>
<li>프로세스 스케줄링 상태, 프로세스 ID 정보등을 관리</li>
</ul>
</blockquote>
<p>PCB에 대해서는 아래에서 더 다룰 것이다.</p>
<h3 id="대기ready">대기(ready)</h3>
<p>메모리 공간이 충분하면 메모리를 할당 받고, 아니면 아닌 상태로 대기하고 있으며 CPU 스케줄러부터 CPU 소유권이 넘어오기를 기다리는 상태</p>
<h3 id="대기-중단ready-suspended">대기 중단(ready suspended)</h3>
<p>메모리 부족으로 일시 중단된 상태</p>
<h3 id="실행running">실행(running)</h3>
<p>CPU 소유권과 메모리를 할당받고 인스트럭션을 수행 중인 상태</p>
<h3 id="중단blocked">중단(blocked)</h3>
<p>어떤 이벤트가 발생한 이후 기다리며 프로세스가 차단된 상태
ex) 프린트 인쇄 버튼을 눌렀을 때 프로세스가 잠깐 멈추는 현상</p>
<h3 id="일시중단blocked-suspended">일시중단(blocked suspended)</h3>
<p>중단된 상태에서 프로세스가 실행되려고 했지만 메모리 부족으로 일시 중단된 상태</p>
<h3 id="종료terminated">종료(terminated)</h3>
<p>메모리와 CPU 소유권을 모두 놓고 종료되는 상태</p>
<hr>
<h2 id="프로세스의-메모리-구조">프로세스의 메모리 구조</h2>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/641e77eb-b818-4f46-b66f-1e5486f1003f/image.png" alt=""></p>
<p>프로세스의 메모리 구조 사진이다.</p>
<h3 id="스택-힙">스택, 힙</h3>
<p>스택과 힙은 동적 할당이 되며, <code>동적 할당</code>이란 <strong>런타임 단계에서 메모리를 할당받는 것</strong>을 말한다.</p>
<ul>
<li><p><strong>스택</strong> : 지역 변수, 매개 변수, 실행되는 함수에 의해 늘거나 줄어드는 메모리 영역이다. 함수가 호출될 때마다 호출될 때의 환경 등 특정 정보가 스택에 게속해서 저장된다.</p>
</li>
<li><p><strong>힙</strong> : 동적으로 할당되는 변수들을 담는다. 동적으로 관리되는 자료 구조의 경우 힙 영역을 사용한다. 예를 들어 vector는 내부적으로 힙 영역을 사용한다.</p>
</li>
</ul>
<h3 id="데이터-영역과-코드-영역">데이터 영역과 코드 영역</h3>
<p>데이터 영역과 코드 영역은 정적 할당되는 영역이다.
<code>정적 할당</code> 은 컴파일 단계에서 메모리를 할당하는 것을 말한다. 여기서 데이터 영역은 BBS segment와 Data segment, code/text segment로 나뉘어서 저장하게 된다.</p>
<ul>
<li><p>BBS segment 는 전역 변수 또는 static, const로 선언되어 있고, 0으로 초기화 또는 초기화가 어떤 값으로도 되어 있지 않은 변수들이 이 메모리 영역에 할당된다.</p>
</li>
<li><p>Data segment 는 전역 변수 또는 static, const로 선언되어 있고 0이 아닌 값으로 초기화된 변수를 이 메모리에 할당한다.</p>
</li>
<li><p>code segment 는 프로그램의 코드가 들어간다.</p>
</li>
</ul>
<hr>
<h2 id="pcb">PCB</h2>
<p>위에서 일부 작성했던 PCB에 대해서 더 다뤄보자.</p>
<blockquote>
<p><strong>PCB(Process Control Block)</strong>?</p>
<ul>
<li>프로세스의 메타데이터들이 저장되어 관리되는 영역</li>
<li>프로세스의 중요한 정보를 포함하고 있기 때문에 일반 사용자가 접근하지 못하도록 커널 스택의 가장 앞부분에서 관리됨</li>
<li>프로세스 스케줄링 상태, 프로세스 ID 정보등을 관리</li>
</ul>
</blockquote>
<h3 id="pcb의-구조">PCB의 구조</h3>
<ul>
<li>프로세스 스케줄링 상태: &#39;준비&#39;,&#39;일시중단&#39;등 프로세스가 CPU에 대한 소유권을 얻은 이후의 상태</li>
<li>프로세스 ID: 프로세스 ID, 해당 프로세스의 자식 프로세스 ID</li>
<li>프로세스 권한: 컴퓨터 자원 또는 I/O 디바이스에 대한 권한 정보</li>
<li>프로그램 카운터: 프로세스에서 실행해야 할 다음 명령어의 주소에 대한 포인터</li>
<li>CPU 레지스터: 프로세스를 실행하기 위해 저장해야 할 레지스터에 대한 정보</li>
<li>CPU 스케줄링 정보: CPU 스케줄러에 의해 중단된 시간 등에 대한 정보</li>
<li>계정 정보: 프로세스 실행에 사용된 CPU 사용량, 실행한 유저의 정보</li>
<li>I/O 상태 정보: 프로세스에 할당된 I/O 디바이스 목록</li>
</ul>
<hr>
<h3 id="컨텍스트-스위칭">컨텍스트 스위칭</h3>
<p>PCB를 기반으로 프로세스의 상태를 저장하고 로드시키는 과정으로, PCB를 교환하는 과정이라고 보면 된다.</p>
<p>한 프로세스에 할당된 시간이 끝나거나 인터럽트에 의해 발생한다.</p>
<p>컴퓨터는 여러 프로그램을 동시에 실행하는 것이 아니라 단 한 개만을 실행하고 있다.</p>
<ul>
<li>이 또한 현대는 멀티코어의 CPU기 때문에 지금이랑은 다르다.</li>
</ul>
<p>싱글코어라고 생각하고 보자.</p>
<p>싱글코어일 때도 우리가 여러 개가 동시에 돌아간다고 생각하고 있는 이유는 이 컨텍스트 스위칭이 매우 빠르게 실행되고 있기 때문이다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/5f0919a6-5700-44cd-b90d-4abb5d2fdaae/image.png" alt=""></p>
<p>A프로세스가 실행하다 멈추고 A의 PCB를 저장하고 B프로세스를 로드하여 실행한다.</p>
<p>그리고 B PCB에 저장하고 A PCB를 다시 불러오는 방식이다.
이때 컨텍스트 스위칭이 일어날 때 대기하는 유효기간이 발생한다.</p>
<p>이뿐만 아니라 더 드는 비용이 있는데, 바로 <code>캐시미스</code>이다.
-&gt; 프로세스가 가지고 있는 메모리 주소가 그대로 있으면 잘못된 주소 변환이 생기므로 캐시클리어 과정을 겪게 되는데, 이때 <code>캐시미스</code> 가 발생한다.</p>
<hr>
<h2 id="멀티프로세싱">멀티프로세싱</h2>
<blockquote>
<p>프로세스를 여러 개 수행하는 것</p>
</blockquote>
<p><strong>장점</strong></p>
<ul>
<li>하나 이상의 일을 병렬로 처리할 수 있다.</li>
<li>특정 프로세스의 메모리, 프로세스 중 문제가 생겨도 다른 프로세스로 처리 가능해 신뢰성이 높다.</li>
</ul>
<h3 id="웹-브라우저">웹 브라우저</h3>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/ddb28ea7-0a22-46a6-864a-d35d11ab59cc/image.png" alt=""></p>
<ol>
<li>브라우저 프로세스: 주소 표시줄, 북마크 막대, 뒤로 가기 버튼, 앞으로 가기 버튼 등을 담당하며 네트워크 요청이나 파일 접근 같은 권한을 담당한다.</li>
<li>렌더러 프로세스: 웹 사이트가 &#39;보이는&#39; 부분의 모든 것을 제어한다.</li>
<li>플러그인 프로세스: 웹 사이트에서 사용하는 플러그인을 제어한다.</li>
<li>GPU 프로세스: GPU를 이용해서 화면을 그리는 부분을 제어한다.</li>
</ol>
<hr>
<h3 id="ipc">IPC</h3>
<blockquote>
<p>프로세스끼리 데이터를 주고 받고, 공유 데이터를 관리하는 매커니즘</p>
</blockquote>
<p>멀티프로세스는 IPC가 가능하다.</p>
<p>ex) 클라이언트와 서버
클라이언트 : 데이터를 요청
서버 : 클라이언트 요청에 응답</p>
<p>종류들에 대해서도 알아보자.</p>
<ul>
<li>공유 메모리</li>
<li>파일</li>
<li>소켓</li>
<li>익명 파이프</li>
<li>명명 파이프</li>
<li>메시지 큐</li>
</ul>
<p>메모리를 완전히 공유하는 스레드보다는 속도가 떨어지는데 스레드에 대해서도 이후에 알아보자.</p>
<hr>
<h4 id="공유-메모리">공유 메모리</h4>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/cbddfc68-64fd-40e5-b2c7-f7c1cfa50966/image.png" alt=""></p>
<blockquote>
<p>여러 프로세스가 동일한 메모리 블록에 대한 접근 권한이 부여돼 프로세스가 공유된 메모리에서 서로 통신하는 방식</p>
</blockquote>
<p><strong>장점</strong>
메모리 자체를 공유하기 때문에 불필요한 데이터 복사의 오버헤드가 발생하지 않아 가장 빠르다. </p>
<p><strong>장점에 의한 고려사항</strong>
같은 메모리 영역을 공유하기 때문에 동기화 작업이 필요하다.</p>
<hr>
<h4 id="파일">파일</h4>
<blockquote>
<p>디스크에 저장된 데이터 또는 파일 서버에서 제공한 데이터를 말한다.</p>
</blockquote>
<hr>
<h4 id="소켓">소켓</h4>
<blockquote>
<p>동일한 컴퓨터의 다른 프로세스나 네트워크의 다른 컴퓨터로 네트워크 인터페이스를 통해 전송하는 데이터를 의미한다.</p>
</blockquote>
<p>예시로는 TCP, UDP가 있다.</p>
<hr>
<h4 id="익명-파이프">익명 파이프</h4>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/8c80baf8-02e6-4aa3-a5c9-38772f4cd739/image.png" alt=""></p>
<blockquote>
<p>프로세스 간에 FIFO 방식으로 읽히는 임시 공간인 파이프를 기반으로 데이터를 주고 받으며, <strong>단방향 방식</strong> 의 읽기 전용, 쓰기 전용 파이프를 만들어서 작동하는 방식</p>
</blockquote>
<hr>
<h4 id="명명된-파이프">명명된 파이프</h4>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/d3af1ede-f94e-4073-8687-15abce7e65d8/image.png" alt=""></p>
<blockquote>
<p>파이프 서버와 하나 이상의 파이프 클라이언트 간의 통신을 위한 <strong>명명된 단방향 or 양방향 파이프</strong></p>
</blockquote>
<p>클라이언트/서버 통신을 위한 별도의 파이프를 제공하며, 여러 파이프를 동시에 사용할 수 있다.</p>
<p>이를 통해 컴퓨터의 프로세스끼리 또는 다른 네트워크 상의 컴퓨터와도 통신을 할 수 있다.</p>
<hr>
<h4 id="메시지-큐">메시지 큐</h4>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/3cf8a076-e560-4faf-bcce-6f035eb7bb7f/image.png" alt=""></p>
<blockquote>
<p>메시지를 큐에 형태로 관리하는 것을 의미한다.</p>
</blockquote>
<p>커널의 전역변수 형태 등 커널에서 전역적으로 관리된다.</p>
<p><strong>장점</strong></p>
<ul>
<li>매우 직관적이며, 간단하다.</li>
<li>다른 코드의 수정 없이 단지 몇 줄의 코드를 추가시켜 간단하게 접근할 수 있다</li>
</ul>
<hr>
<h2 id="스레드와-멀티스레딩">스레드와 멀티스레딩</h2>
<h3 id="스레드">스레드</h3>
<blockquote>
<p>프로세스의 실행 가능한 가장 작은 단위</p>
</blockquote>
<p>프로세스는 여러 스레드를 가질 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/db9d7a62-9571-48f2-b1ca-9f58f648963c/image.png" alt=""></p>
<p><strong>프로세스와 스레드의 차이점</strong>
프로세스는 코드, 데이터, 스택, 힙 영역을 각각 생성
스레드는 코드, 데이터 힙 영역을 서로 공유한다. 그 외의 영역은 각각 생성된다.</p>
<hr>
<h3 id="멀티스레딩">멀티스레딩</h3>
<blockquote>
<p>이는 프로세스 내 작업을 여러 개의 스레드, 멀티 스레드로 처리하는 기법을 말한다.</p>
</blockquote>
<p><strong>장점</strong></p>
<ul>
<li>스레드끼리 자원을 서로 공유하기 때문에 효율성이 높다.</li>
<li>동시성도 큰 장점이 있다.</li>
</ul>
<p><strong>단점</strong>
한 스레드가 문제가 생기면 다른 스레드도 영향을 끼친다는 단점이 있다.</p>
<blockquote>
<p><strong>동시성</strong>이란? : 서로 독립적인 작업들을 작은 단위로 나누고 동시에 실행되는 것처럼 보여주는 것</p>
</blockquote>
<hr>
<h2 id="공유-자원과-임계-영역">공유 자원과 임계 영역</h2>
<h3 id="공유-자원">공유 자원</h3>
<blockquote>
<p>시스템 안에서 각 프로세스, 스레드가 함께 접근할 수 있는 모니터, 프린터, 메모리, 파일, 데이터 등의 자원이나 변수 등을 의미</p>
</blockquote>
<p>이 공유 자원을 두 개 이상의 프로세스가 동시에 읽거나 쓰이는 상황을 <code>경쟁 상태</code> 라고 한다.</p>
<p>이 때문에 접근의 타이밍이나 순서 등이 결과값에 영향을 준다.</p>
<p>예시 사진
<img src="https://velog.velcdn.com/images/jojehuni_9759/post/eb6d054b-1dc3-4917-9e27-4d67eb8f8a2e/image.png" alt=""></p>
<hr>
<h3 id="임계-영역">임계 영역</h3>
<blockquote>
<p>둘 이상의 프로세스, 스레드가 공유 자원에 접근할 때 순서 등의 이유로 결과가 달라지는 코드 영역</p>
</blockquote>
<p>이를 해결하기 위해선 크게 뮤텍스, 세마포어, 모니터 세 가지가 있다.</p>
<p>이 방법 모두 <code>상호 배제</code>, <code>한정 대기</code>, <code>융통성</code>이라는 조건을 만족하며</p>
<p>위 3가지 방법에 토대가 되는 메커니즘은 <strong>잠금(lock)</strong> 이다.</p>
<p>ex) 화장실 사용 시 문 잠그고 사용한 뒤 나오면 다음 사람이 사용하는 것</p>
<ul>
<li>상호배제 : 한 프로세스가 임계 영역에 들어갔을 때 다른 프로세스는 들어갈 수 없다.</li>
<li>한정 대기 : 특정 프로세스가 영원히 임계 영역에 들어가지 못하면 안 된다.</li>
<li>융통성 : 한 프로세스가 다른 프로세스의 일을 방해해서는 안 된다.</li>
</ul>
<hr>
<h4 id="뮤텍스">뮤텍스</h4>
<p>프로세스나 스레드가 공유 자원을 <code>lock()</code>을 통해 잠금 설정하고 사용한 후에는 <code>unlock()</code>을 통해 잠금 해제하는 방식</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/92951ca8-478d-442f-83ed-dcc7c6c46e60/image.png" alt=""></p>
<hr>
<h4 id="세마포어">세마포어</h4>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/116f9d61-ee7e-4086-9c72-0dc5c960a5eb/image.png" alt=""></p>
<p>일반화된 뮤텍스로, 간단한 정수 값과 두 가지 함수 <code>wait</code> 함수, <code>signal</code> 함수로 공유 자원에 대한 접근을 처리한다.</p>
<p><code>wait()</code>는 자신의 차례가 올때까지 기다리는 함수이며, <code>signal()</code>은 다음 프로세스 순서로 넘겨주는 함수를 말한다.</p>
<p>공유 자원에 접근하려면, 세마포어에서 wait()를 수행하고 공유 자원을 해제하면 signal() 작업을 수행한다.</p>
<p><strong>세마포어의 종류</strong></p>
<ul>
<li><p><strong>바이너리 세미포어</strong>
0과 1의 두가지 값만 가질 수 있는 세마포어이다. 이는 신호 메커니즘으로 신호를 기반으로 일어난다.</p>
</li>
<li><p><strong>카운팅 세마포어</strong>
이는 여러 개의 값을 가질 수 있는 세마포어이다. 여러 자원에 대한 접근을 제어하는데 사용된다.</p>
</li>
</ul>
<hr>
<h4 id="모니터">모니터</h4>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/6ad67e6b-6e7b-4cf7-afc3-35df905576bf/image.png" alt=""></p>
<p>둘 이상의 스레드나 프로세스가 공유 자원에 안전하게 접근할 수 있도록 공유자원을 숨기고, 해당 접근에 대해 인터페이스만을 제공한다.</p>
<p><strong>모니터와 세마포어의 차이점</strong></p>
<ul>
<li>모니터는 세마포어보다 구현하기 쉽고, 상호 배제는 자동</li>
<li>세마포어는 상호 배제를 명시적으로 구현해야 한다.</li>
</ul>
<hr>
<h2 id="교착-상태">교착 상태</h2>
<blockquote>
<p><strong>교착 상태</strong> : 두 개 이상의 프로세스들이 서로가 가진 자원을 기다리며 중단된 상태</p>
</blockquote>
<h3 id="원인">원인</h3>
<ul>
<li><strong>상호 배제</strong> : 한 프로세스가 자원을 독점하고 있으며 다른 프로세스는 접근이 불가능하다.</li>
<li><strong>점유 대기</strong> : 특정 프로세스가 점유한 자원을 다른 프로세스가 요청하는 상태</li>
<li><strong>비선점</strong> : 다른 프로세스의 자원을 강제적으로 가져올 수 없다.</li>
<li><strong>환형 대기</strong> : 프로세스 A는 프로세스 B의 자원을 요구하고, 프로세스 B는 프로세스 A의 자원을 요구하는 등 서로가 서로의 자원을 요구하는 상황</li>
</ul>
<h3 id="해결방법">해결방법</h3>
<ol>
<li>자원을 할당할 때 애초에 조건이 성립되지 않도록 설계한다.</li>
<li>교착 상태 가능성이 없을 때만 자원 할당되며, 프로세스당 요청할 자원들의 최대치를 통해 자원 할당 가능 여부를 파악하는 <code>은행원 알고리즘</code> 을 쓴다.</li>
</ol>
<blockquote>
<p>은행원 알고리즘
총 자원의 양과 현재 할당한 양을 기준으로 안정 또는 불안정 상태로 나누고 안정 상태로 가도록 자원을 할당하는 알고리즘</p>
</blockquote>
<ol start="3">
<li>교착 상태가 발생하면 사이클이 있는지 찾아보고 이에 관련된 프로세스를 한 개씩 지운다.</li>
<li>교착 상태는 매우 드물게 일어나고 비용이 크기 때문에 현대 운영체제에서는 사용자가 작업을 종료하는 방법을 채택했다.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공지식 정리 - 운영체제 2. 메모리]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-2.-%EB%A9%94%EB%AA%A8%EB%A6%AC</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-2.-%EB%A9%94%EB%AA%A8%EB%A6%AC</guid>
            <pubDate>Mon, 06 Jan 2025 18:20:31 GMT</pubDate>
            <description><![CDATA[<h1 id="메모리">메모리</h1>
<p>CPU는 메모리에 올라와 있는 프로그램의 명령어를 실행할 뿐이며, 메모리 계층과 메모리 관리에 대해 알아보자.</p>
<h2 id="메모리-계층">메모리 계층</h2>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/be31ad3f-ed74-4abc-9584-2e461ba8a931/image.png" alt=""></p>
<ul>
<li>레지스터 : CPU 안에 있는 가장 작은 메모리<ul>
<li>휘발성</li>
<li>속도 가장 빠름</li>
<li>용량 가장 작음</li>
</ul>
</li>
<li>캐시 : L1, L2 캐시를 지칭한다.<ul>
<li>휘발성</li>
<li>속도 빠름</li>
<li>용량 작음</li>
</ul>
</li>
<li>주기억장치 (RAM)<ul>
<li>휘발성</li>
<li>속도 보통</li>
<li>용량 보통</li>
</ul>
</li>
<li>보조기억장치 (HDD, SSD)<ul>
<li>비휘발성</li>
<li>속도 낮음</li>
<li>용량 큼</li>
</ul>
</li>
</ul>
<h3 id="캐시">캐시</h3>
<p>데이터를 미리 복사해놓는 임시 저장소로 빠른 장치와 느린 장치의 속도 차이에 따른 병목 현상을 줄이기 위한 메모리이다.</p>
<p>메모리와 CPU의 속도 차이가 너무 커 중간에 레지스터 계층을 둬 속도 차이를 해결하는데, 이 때 속도 차이를 해결하기 위해서 계층과 계층 사이에 있는 것을 <code>캐싱 계층</code>이라고 한다.</p>
<p>ex) 캐시 메모리 &lt;-&gt; 보조기억장치 사이에 있는 주기억장치 : 보조기억장치의 캐싱 계층</p>
<hr>
<h3 id="지역성의-원리">지역성의 원리</h3>
<blockquote>
<p>캐싱 계층을 두는 것이 아닌 직접 캐시를 설정할 때 : 자주 사용하는 데이터를 기반으로 캐시를 설정해야 한다.</p>
<p>자주 사용하는 데이터라는 개념의 근거? : <code>지역성</code></p>
<ul>
<li>시간 지역성</li>
<li>공간 지역성</li>
</ul>
</blockquote>
<h4 id="시간-지역성">시간 지역성</h4>
<blockquote>
<p>최근 사용한 데이터에 다시 접근하려는 특성</p>
</blockquote>
<p>ex) for 반복문으로 이루어진 코드 안의 변수 i 에 계속 접근하게 될텐데 반복하면서 최근에 사용한 i에 계속 접근해 +1 시켜서 반복하는 것을 생각해볼 수 있다.</p>
<h4 id="공간-지역성">공간 지역성</h4>
<blockquote>
<p>최근 접근한 데이터를 이루고 있는 공간이나 그 가까운 공간에 접근하는 특성</p>
</blockquote>
<hr>
<h3 id="캐시히트와-캐시미스">캐시히트와 캐시미스</h3>
<blockquote>
<p><strong>캐시히트</strong> : 캐시에서 원하는 데이터를 찾는 것
<strong>캐시미스</strong> : 캐시에 원하는 데이터가 없어 주 메모리에서 찾아오는 것</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/48cbc5c6-c34e-4564-ac15-ce14534f7b30/image.png" alt=""></p>
<p>캐시히트를 하게 되면 해당 데이터를 제어장치를 거쳐 가져오게 된다.</p>
<p>캐시히트는 비교적 위치가 가깝고 <code>CPU 내부 버스</code>를 기반으로 작동해 빠르다.</p>
<p>하지만, 캐시미스가 발생하면 <code>시스템 버스</code>를 기반으로 작동해 느리다.</p>
<h4 id="캐시미스의-종류">캐시미스의 종류</h4>
<blockquote>
<ol>
<li><p>컴펄서리 미스(Compulsory Miss) : 처음으로 접근하는 데이터 때문에 발생하는 미스
어떤 데이터가 처음 캐시에 로드될 때 발생</p>
</li>
<li><p>캐피시티 미스(Capacity Miss) : 캐시의 크기가 작아서 발생하는 미스
캐시에 데이터가 너무 많이 들어가면 오래된 데이터가 제거되고, 나중에 다시 그 데이터가 필요하면 미스가 발생</p>
</li>
<li><p>컨플릭트 미스(Conflict Miss) : 캐시 라인에 여러 데이터가 매핑되어 충돌이 발생할 때 생기는 미스
이는 주로 캐시의 매핑 정책과 관련</p>
</li>
</ol>
</blockquote>
<hr>
<h3 id="캐시매핑">캐시매핑</h3>
<blockquote>
<p>캐시매핑 : 캐시가 히트되기 위해 매핑하는 방법</p>
</blockquote>
<ol>
<li><strong>직접 매핑</strong> : 메모리의 특정 블록은 특정 캐시라인에만 매핑할 수 있는 것</li>
<li><strong>연관 매핑</strong> : 순서를 일치시키지 않고 관련 있는 캐시와 메모리를 매핑하는 것 메모리의 컨텐츠가 캐시의 어느 위치에도 올라갈 수 있는 방법이다.</li>
<li><strong>집합 연관 매핑</strong> : 직접 매핑과 연관 매핑을 합쳐 놓은 것으로, 집합을 나누고 각 집합에 직접 매핑을 사용하는 것</li>
</ol>
<p>캐시 매핑 방식에 대해서 잘 정리해두신 분을 보고 참고하려는 목적으로 링크를 남기고자 한다..</p>
<p><a href="https://velog.io/@ssongjh55/%EC%BA%90%EC%8B%9C%EB%A7%A4%ED%95%91">캐시 매핑 분류</a></p>
<hr>
<p>다음은 웹 브라우저의 캐시를 알아보자.</p>
<h3 id="쿠키">쿠키</h3>
<blockquote>
<p><code>만료기한</code>이 있는 키-값 저장소다.</p>
</blockquote>
<p>이전에 쿠키를 사용했을 때 <code>same site</code> 옵션을 <code>strict</code> 방식으로 사용해야지만 다른 도메인에서 요청했을 때 자동 전송이 되지 않게 제한을 걸 수 있었다.</p>
<p>4KB까지 저장 가능하며, 위에서 말한 것처럼 만료기한도 설정 가능하다.</p>
<p>그리고 document cookie로 쿠키를 볼 수 없게 <code>httponly</code> 옵션 또한 걸어둬야 한다.</p>
<p>보통 서버에서 만료기한을 설정한다.</p>
<hr>
<h3 id="로컬-스토리지">로컬 스토리지</h3>
<blockquote>
<p>만료기한이 없는 키-값 저장소다.</p>
</blockquote>
<p>5MB까지 저장 가능하며, 웹 브라우저를 닫아도 유지된다.</p>
<p>그리고 HTML5를 지원하지 않는 웹 브라우저라면 사용 불가능, 클라이언트에서만 수정 가능하다.</p>
<hr>
<h3 id="세션-스토리지">세션 스토리지</h3>
<blockquote>
<p>만료기한이 없는 키-값 저장소다.</p>
</blockquote>
<p>탭 단위로 세션 스토리지를 생성하고, 탭을 닫을 때 데이터가 삭제된다.</p>
<p>로컬 스토리지와 마찬가지로 5MB까지 저장 가능하고 HTML5를 지원하지 않는 웹 브라우저라면 사용 불가능, 클라이언트에서만 수정 가능하다.</p>
<hr>
<h3 id="데이터베이스의-캐싱-계층">데이터베이스의 캐싱 계층</h3>
<p>메인 데이터베이스 위에 redis를 활용해 캐싱 계층으로 활용하기도 한다.</p>
<p>로그인 기능을 할 때 주로 사용했었다.</p>
<ol>
<li>데이터를 레디스에 쓴다.
2 - 1. 앱은 redis로부터 데이터가 있다면(캐시히트) 읽어온다.
2 - 2. 없다면 (캐시미스) 메인 데이터베이스로부터 가져온다.</li>
</ol>
<hr>
<h2 id="메모리-관리">메모리 관리</h2>
<p>OS의 대표적인 할 일인 메모리 관리에 대해 알아보자.</p>
<h3 id="가상-메모리">가상 메모리</h3>
<blockquote>
<p>실제로 이용 가능한 메모리 자원을 추상화 해 이를 사용하는 사용자들에게 매우 큰 메모리로 보이게 만드는 것</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/9c1f7ccd-63ce-4d7a-a3cb-9014d5364fe5/image.png" alt=""></p>
<p>가상 메모리에는 가상 주소와 실제 주소가 매핑돼 있고, 프로세스의 주소 정보가 있는 <code>페이지 테이블</code>로 관리된다.</p>
<p>가상 주소는 <code>메모리관리장치(MMU)</code>에 의해 실제 주소로 변환돼 그로 인해 사용자는 실제 주소를 의식할 필요 없이 프로그램을 구축할 수 있다.</p>
<p>이 때 속도 향상을 위해서는 TLB를 사용하는데</p>
<blockquote>
<p>TLB : 메모리와 CPU 사이에 있는 주소 변환을 위한 캐시
페이지 테이블에 있는 리스트를 보관하여 CPU가 페이지 테이블까지 가지 않도록 해 속도를 향상시킬 수 있다.</p>
</blockquote>
<hr>
<h4 id="스와핑">스와핑</h4>
<p>가상 메모리는 존재하는데 실제 메모리인 RAM 에는 현재 없는 데이터 or 코드에 접근하는 경우
-&gt; <strong>페이지 폴트 발생</strong></p>
<blockquote>
<p><strong>스와핑</strong> : 메모리에서 당장 사용하지 않는 영역을 하드디스크로 옮기고 하드디스크의 일부를 메모리처럼 불러와 쓰는 것</p>
<p><strong>마치 페이지 폴트가 발생하지 않은 것처럼 만든다.</strong></p>
</blockquote>
<hr>
<h4 id="페이지-폴트">페이지 폴트</h4>
<blockquote>
<p>프로세스의 주소 공간에는 존재하지만 RAM에는 없는 데이터에 접근했을 경우에 발생</p>
</blockquote>
<p>위 스와핑, 페이지 폴트는 아래 과정으로 이루어진다.</p>
<ol>
<li>어떤 명령어가 유효한 가상 주소에 접근했는데 <code>페이지</code>가 없을 때</li>
</ol>
<p>-&gt; 트랩 발생 -&gt; OS가 알게 된다.
2. OS는 실제 디스크로부터 사용하지 않은 <code>프레임</code>을 찾는다.
3. 해당 프레임을 실제 메모리에 가져와서 <code>페이지 교체 알고리즘</code>을 기반으로 특정 페이지와 교체한다.</p>
<ul>
<li>이 때 <code>스와핑</code>이 발생<ol start="4">
<li>페이지 테이블을 갱신시킨 후 해당 명령어를 다시 시작</li>
</ol>
</li>
</ul>
<ul>
<li>페이지 : 가상 메모리를 사용하는 최소 크기 단위</li>
<li>프레임 : 실제 메모리를 사용하는 최소 크기 단위</li>
</ul>
<hr>
<h3 id="스레싱">스레싱</h3>
<blockquote>
<p>스레싱 (thrashing) : 메모리의 페이지 폴트율이 높은 것</p>
</blockquote>
<p>스레싱은 메모리에 너무 많은 프로세스가 동시에 올라가게 되면 스와핑이 많이 일어나서 발생한다.</p>
<p>페이지 폴트가 일어나면 CPU 이용률이 낮아짐 -&gt; 이용률이 낮아지면 컴퓨터는 CPU 가용성을 더 높이기 위해 더 많은 프로세스를 메모리에 올림 -&gt; 악순환.. (= 스레싱)</p>
<p><strong>해결방법</strong></p>
<ol>
<li>메모리 늘리기</li>
<li>HDD 사용 시 -&gt; SSD로 바꾸기</li>
<li>작업 세트</li>
<li>PFF</li>
</ol>
<p>작업 세트부터 알아보자.</p>
<hr>
<h4 id="작업-세트">작업 세트</h4>
<blockquote>
<p>작업 세트 : 지역성 (프로세스의 과거 사용 이력)을 통해 결정된 페이지 집합을 만들어 미리 메모리에 로드하는 것</p>
</blockquote>
<p>미리 메모리에 로드하면 좋은 점</p>
<ul>
<li>탐색에 비용 줄이기</li>
<li>스와핑 줄이기</li>
</ul>
<hr>
<h4 id="pff">PFF</h4>
<blockquote>
<p>PFF (Page Fault Frequency) : 페이지 폴트 빈도를 조절하는 방법으로 상한선, 하한선을 만드는 방법</p>
</blockquote>
<p>상한선에 도달하면 프레임을 늘리고, 하한선에 도달하면 줄이는 방식이다.</p>
<hr>
<h3 id="메모리-할당">메모리 할당</h3>
<p>메모리에 프로그램을 할당할 때는 시작 메모리 위치, 메모리 할당 크기를 기반으로 할당한다.</p>
<p>이것을 <code>연속 할당</code>, <code>불연속 할당</code>으로 나눈다.</p>
<h4 id="연속-할당">연속 할당</h4>
<blockquote>
<p>메모리에 <strong>연속적으로</strong> 공간을 할당하는 것</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/d3e25a4c-209a-4914-a9cf-7df2a2b2149d/image.png" alt=""></p>
<p>위와 같이 순차적으로 공간에 할당할 수 있다.</p>
<p>방식이 2가지가 있는데</p>
<ol>
<li><p><strong>고정 분할 방식</strong> : 메모리를 미리 나누어 관리하는 방식</p>
<ul>
<li>메모리가 미리 나눠져 있어 융통성이 없고, 내부 단편화가 발생한다.</li>
</ul>
</li>
<li><p><strong>가변 분할 방식</strong> : 매 시점 프로그램의 크기에 맞게 메모리를 분할해 사용하는 방식</p>
<ul>
<li>외부 단편화 발생</li>
</ul>
</li>
</ol>
<p>가변 분할 방식의 종류</p>
<ul>
<li>최초 적합 (first fit) : 위쪽 or 아래쪽부터 시작해 홀을 찾으면 바로 할당</li>
<li>최적 적합 (best fit) : 프로세스의 크기 이상인 공간 중 가장 작은 홀부터 할당</li>
<li>최악 적합 (worst fit) : 프로세스의 크기와 가장 많이 차이나는 홀에 할당</li>
</ul>
<blockquote>
<p><strong>내부 단편화</strong> : 메모리를 나눈 크기보다 프로그램이 작아 들어가지 못하는 공간이 많이 발생하는 현상</p>
<p><strong>외부 단편화</strong> : 메모리를 나눈 크기보다 프로그램이 커서 들어가지 못하는 공간이 많이 발생하는 현상</p>
<p><strong>홀</strong> : 할당할 수 있는 비어 있는 메모리 공간</p>
</blockquote>
<hr>
<h4 id="불연속-할당">불연속 할당</h4>
<p>현대 운영체제가 쓰는 방법으로 <strong>페이징 기법</strong>이 있다.</p>
<p>추가로 <strong>세그멘테이션</strong>, <strong>페이지드 세그멘테이션</strong> 기법들도 있다.</p>
<h3 id="페이징">페이징</h3>
<blockquote>
<p><strong>페이징 기법</strong> : 메모리를 동일한 크기의 페이지로 나누고 프로그램마다 페이지 테이블을 둬 메모리에 프로그램을 할당하는 것</p>
</blockquote>
<hr>
<h3 id="세그멘테이션">세그멘테이션</h3>
<blockquote>
<p><strong>세그멘테이션</strong> : 페이지 단위가 아닌 의미 단위인 세그먼트로 나누는 방식이다.</p>
</blockquote>
<p>프로세스를 이루는 메모리는 아래 4개 영역으로 나뉜다.</p>
<ul>
<li>코드 영역</li>
<li>데이터 영역</li>
<li>스택 영역</li>
<li>힙 영역</li>
</ul>
<p>세그먼트로 나눈다는 것은 위의 영역에서도 코드와 데이터로 나누거나, 코드 내의 작은 함수와 같은 것들을 세그먼트로 놓고 나눌 수도 있다.</p>
<p><strong>공유와 보안 측면</strong>에서 장점 / <strong>홀 크기가 균일하지 않다</strong>는 단점</p>
<hr>
<h3 id="페이지드-세그멘테이션">페이지드 세그멘테이션</h3>
<blockquote>
<p><strong>페이지드 세그멘테이션</strong> : <strong>의미 단위인 세그먼트로 나누는 방식</strong>으로, 세그멘테이션과는 임의의 길이가 아닌 <strong>동일한 크기의 페이지 단위로 나누는 것</strong>에 차이가 있다.</p>
</blockquote>
<hr>
<h3 id="페이지-교체-알고리즘">페이지 교체 알고리즘</h3>
<p>메모리는 한정돼 있어 스와핑이 많이 일어나는데, 많이 일어나지 않기 위해 설계되는 페이지 교체 알고리즘이 있다.</p>
<p>이러한 알고리즘에 따라 스와핑이 생기는 것이다.</p>
<hr>
<h4 id="fifo-first-in-first-out">FIFO (First In First Out)</h4>
<blockquote>
<p>가장 먼저 온 페이지를 교체 영역에 가장 먼저 놓는 방법</p>
</blockquote>
<h4 id="lru-least-recently-used">LRU (Least Recently Used)</h4>
<blockquote>
<p>참조가 가장 오래된 페이지를 바꾼다. <strong>오래된 것</strong>을 파악하기 위해 각 페이지마다 계수기, 스택을 두어야 하는 문제점이 있다.</p>
</blockquote>
<h4 id="nurnot-used-recently">NUR(Not Used Recently)</h4>
<p>LRU에서 발전한 알고리즘이다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/517fb88a-5157-46be-aaa7-73e5ccfb0247/image.png" alt=""></p>
<p><code>clock 알고리즘</code> 이라고 하며 먼저 0과 1을 가진 비트를 둔다.
1은 최근에 참조되었고, 0은 참조되지 않음을 의미한다.
시계 방향으로 돌면서 0을 찾고 0을 찾은 순간 해당 프로세스를 교체하고, 해당 부분을 1로 바꾸는 알고리즘이다.</p>
<h4 id="lfuleast-frequently-used">LFU(Least Frequently Used)</h4>
<p>가장 참조 횟수가 적은 페이지를 교체한다. 즉, 많이 사용하지 않은 것을 교체한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공지식 정리 - 운영체제 1. 운영체제와 컴퓨터]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-1.-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EC%99%80-%EC%BB%B4%ED%93%A8%ED%84%B0</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-1.-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EC%99%80-%EC%BB%B4%ED%93%A8%ED%84%B0</guid>
            <pubDate>Mon, 06 Jan 2025 12:27:37 GMT</pubDate>
            <description><![CDATA[<h1 id="운영체제">운영체제</h1>
<p>운영체제 (OS, Operating System) 은 간단하게 사용자가 컴퓨터를 쉽게 다루게 해주는 인터페이스로 한정된 메모리, 자원을 효율적으로 분배하는 것이다.</p>
<p>비슷한 것으로 <strong>펌웨어</strong> (firmware) 라는 것이 있는데 펌웨어는 소프트웨어를 추가로 설치할 수 없다는 차이가 있다.</p>
<hr>
<h1 id="운영체제와-컴퓨터">운영체제와 컴퓨터</h1>
<ul>
<li>하드웨어와 소프트웨어를 관리하는 운영체제</li>
<li>CPU, 메모리 등으로 이루어진 컴퓨터</li>
</ul>
<p>위 2가지를 알아보자.</p>
<h2 id="운영체제-역할과-구조">운영체제 역할과 구조</h2>
<h3 id="운영체제의-역할">운영체제의 역할</h3>
<p>운영체제의 역할을 알아보자.</p>
<ol>
<li>CPU 스케줄링, 프로세스 관리 : <strong>CPU 소유권을 어떤 프로세스에 할당할 지</strong>, 프로세스의 생성과 삭제, 자원 할당 및 반환 관리</li>
<li>메모리 관리 : <strong>한정된 메모리</strong>를 <strong>어떤 프로세스에</strong> <strong>얼만큼 할당</strong>해야 하는지 관리</li>
<li>디스크 파일 관리 : 어떠한 방법으로 디스크 파일을 보관할 지 관리</li>
<li>I/O 디바이스 관리 : I/O 디바이스 (마우스, 키보드와 같은) 와 컴퓨터 간 데이터 주고 받는 것 관리</li>
</ol>
<hr>
<h3 id="운영체제의-구조">운영체제의 구조</h3>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/93f43564-3314-42eb-928e-c8bb39bc06b9/image.png" alt=""></p>
<p>사진과 같이 맨 위에 소프트웨어 ~ 맨 아래에 하드웨어가 있는 구조인데, 중간에 표시한 부분이 운영체제 부분이다.</p>
<p>GUI가 없고 CUI만 있는 리눅스 서버도 있긴 하다.</p>
<blockquote>
<p><strong>GUI (Graphical User Interface)</strong> : 아이콘을 마우스로 클릭하는 것 같이 명령어를 입력해서 상호작용하는 것이 아닌 단순한 동작으로 컴퓨터와 상호작용할 수 있는 사용자 인터페이스의 형태</p>
<p><strong>드라이버</strong> : 하드웨어를 제어하기 위한 소프트웨어</p>
<p><strong>CUI</strong> : 명령어로 처리하는 인터페이스</p>
</blockquote>
<hr>
<h3 id="시스템-호출-시스템-콜">시스템 호출 (시스템 콜)</h3>
<blockquote>
<p>운영체제가 커널에 접근하기 위한 인터페이스</p>
<p>소프트웨어가 운영체제의 서비스를 받기 위해 커널 함수를 호출할 때 사용한다.</p>
</blockquote>
<p>소프트웨어가 I/O 요청으로 트랙을 발동하면 올바른 I/O 요청인지 확인 후 유저 모드였던 시스템 콜이 커널 모드로 변환돼 요청에 맞춰 파일 시스템에 영향을 준다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/629f264b-4af9-4f52-a3be-e5d8ce1135f1/image.png" alt=""></p>
<p><a href="https://c4u-rdav.tistory.com/85">참고 링크</a></p>
<blockquote>
<p>ex) <code>fs.readFile()</code>라는 파일 시스템 파일을 읽는 함수가 있다면 커널 모드로 읽고 유저 모드로 돌아가 소프트웨어의 로직 수행</p>
</blockquote>
<p>이 과정으로 컴퓨터 자원에 직접 접근하는 것을 차단할 수도 있고, 프로그램을 다른 프로그램으로부터 보호할 수 있다.</p>
<p>프로세스 or 스레드에서 OS로 어떠한 요청을 한다면 시스템 콜 인터페이스와 커널을 거쳐 운영체제에 전달된다.</p>
<p>시스템 콜은 하나의 추상화 계층이기 때문에 아래와 같은 장점이 있다.</p>
<p><strong>장점</strong>
유저 프로그램은 시스템 콜을 기반으로 커널과 분리가 된다. 
즉, 유저 프로그램은 복잡한 파일 시스템, 프로세스 생성 등과 같은 내부 동작을 신경 쓸 필요 없다.
또, OS의 관리 하에 프로그램이 운영되기 때문에 시스템의 안정성, 보안이 강화된다.</p>
<p>ex) 공격자가 만든 카메라 앱 프로그램이 아무 제약 없이 커널에 접근할 수 있다면, 카메라와 관련된 메모리가 오염돼 사용자의 의도와 관계 없이 카메라가 켜지거나 사생활 노출이 될 수 있다.</p>
<p>그래서 유저 모드에서 시스템 콜로만 커널 모드에 진입할 수 있게 한 것이다.</p>
<p>쉽게 이야기하면 아래와 같다.</p>
<ul>
<li>네트워크 통신이나 DB같은 낮은 단계의 영역 처리에 대한 부분을 많이 신경쓰지 않고 프로그램 구현할 수 있다.</li>
</ul>
<hr>
<h4 id="modebit">modebit</h4>
<p>시스템 콜은 작동될 때 <code>modebit</code> 를 참고해서 유저 모드와 커널 모드를 구분한다.</p>
<p>0은 커널 모드, 1은 유저 모드로 무조건 이 플래그 변수로 작동해야 한다.</p>
<p>유저 모드를 기반으로 프로그램이 작동되면 공격자가 악의적인 행위를 할 수 있게 된다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/4124224f-48df-4dc7-95d2-cb93d9ac96ee/image.png" alt=""></p>
<p>ex) 카메라를 키는 프로그램을 예시로 든 사진이다.</p>
<hr>
<h2 id="컴퓨터하드웨어-의-요소">컴퓨터(하드웨어) 의 요소</h2>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/732b30e4-c7f1-466b-b13e-0ea05ffd7fab/image.png" alt=""></p>
<h3 id="cpu">CPU</h3>
<blockquote>
<p>CPU (Central Processing Unit) : 산술논리연산장치, 제어장치, 레지스터로 구성된 장치</p>
</blockquote>
<p>CPU는 인터럽트에 의해 메모리에 존재하는 명령어를 해석해서 실행하는 역할을 한다.</p>
<p>관리자의 역할을 하는 운영체제의 커널이 프로그램을 메모리에 올려 프로세스로 만들면 CPU가 처리한다.</p>
<h4 id="산술논리연산장치">산술논리연산장치</h4>
<blockquote>
<p>산술논리연산장치 (Arithmetic Logic Unit) : 덧셈, 뺄셈 같은 산술 연산과 배타적 논리합, 논리곱 같은 논리 연산을 계산하는 디지털 회로다.</p>
</blockquote>
<h4 id="제어장치-cu">제어장치 (CU)</h4>
<blockquote>
<p>제어장치 (Control Unit) : 프로세스 조작을 지시하는 부품
I/O 장치 간 통신을 제어하고 명령어를 읽고 해석하며 데이터 처리를 위한 순서를 결정</p>
</blockquote>
<h4 id="레지스터">레지스터</h4>
<blockquote>
<p>레지스터 : CPU 안에 있는 매우 빠른 임시 기억 장치
연산 속도가 메모리보다 월등히 빠르며, CPU에 자체적으로 데이터를 저장할 방법이 없어 레지스터를 거쳐 데이터를 전달한다.</p>
</blockquote>
<hr>
<h3 id="cpu-연산-처리">CPU 연산 처리</h3>
<p>위 장치들을 통해 연산하는 예시는 아래와 같다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/5f56281b-2b20-4871-afa8-b9b48c8c9aec/image.png" alt=""></p>
<p><a href="https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;blogId=dufvndrnjs&amp;logNo=70152020258">참고 링크</a></p>
<ol>
<li>제어장치가 메모리와 레지스터에 계산할 값을 로드한다.</li>
<li>제어장치가 레지스터에 있는 값을 계산하라고 산술논리연산장치에 명령하면</li>
<li>제어장치가 계산된 값을 다시 레지스터 -&gt; 메모리로 계산한 값을 저장한다.</li>
</ol>
<h4 id="인터럽트">인터럽트</h4>
<p>어떤 신호가 왔을 때 CPU를 잠깐 정지시키는 것을 말한다.</p>
<p>인터럽트가 발생하면 인터럽트 핸들러 함수가 모여있는 인터럽트 벡터로 가서 핸들러 함수를 실행한다.</p>
<p>물론 인터럽트 간에는 우선순위가 있어서 그것에 따라 실행되고, 하드웨어/소프트웨어 인터럽트 2가지가 있다.</p>
<blockquote>
<p>인터럽트 핸들러 함수 : 인터럽트가 발생할 때 이를 핸들링하기 위한 함수</p>
</blockquote>
<hr>
<h3 id="하드웨어-인터럽트">하드웨어 인터럽트</h3>
<blockquote>
<p>키보드를 연결하거나 마우스를 연결하는 것처럼 I/O 디바이스에서 발생하는 인터럽트</p>
</blockquote>
<p>ex) 마우스 클릭, 디스크에서 파일 읽기/쓰기 작업이 완료됐을 때 발동</p>
<hr>
<h3 id="소프트웨어-인터럽트">소프트웨어 인터럽트</h3>
<blockquote>
<p><strong>트랩</strong>이라고도 하며 프로세스 오류 등으로 프로세스가 시스템콜을 호출할 때 발동한다.</p>
</blockquote>
<p>하드웨어 인터럽트보다 우선순위가 높다.</p>
<h4 id="dma-컨트롤러">DMA 컨트롤러</h4>
<p>I/O 디바이스가 메모리에 직접 접근할 수 있도록 하는 하드웨어 장치를 뜻한다.</p>
<p>CPU에 너무 많은 인터럽트 요청이 들어오는데 그로 인한 부하를 DMA 컨트롤러가 막아준다.</p>
<ul>
<li>CPU와 DMA 컨트롤러가 동시에 같은 작업을 하는 것도 방지한다.</li>
</ul>
<hr>
<h4 id="메모리">메모리</h4>
<blockquote>
<p>전자회로에서 데이터나 상태, 명령어 등을 기록하는 장치</p>
</blockquote>
<p>보통 RAM을 메모리라고도 한다.</p>
<p>CPU 가 계산을 한다면, 메모리는 기억을 담당한다.</p>
<hr>
<h4 id="타이머">타이머</h4>
<blockquote>
<p>특정 프로그램에 시간 제한을 다는 역할</p>
</blockquote>
<p>만약 프로그램이 무한 루프에 빠지게 된다면 그 프로그램때문에 컴퓨터 자원을 많이 소모하기 때문에 시간 제한이 필요하다. 그것을 위해 타이머가 존재한다.</p>
<hr>
<h4 id="디바이스-컨트롤러">디바이스 컨트롤러</h4>
<blockquote>
<p>컴퓨터와 연결돼 있는 I/O 디바이스들의 작은 CPU라고 보면 된다.
옆에 붙어 있는 <strong>로컬 버퍼</strong>는 각 디바이스에서 데이터를 임시로 저장하기 위한 작은 메모리 역할이다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공지식 정리 - 네트워크 5. HTTP]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-5.-HTTP</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-5.-HTTP</guid>
            <pubDate>Thu, 02 Jan 2025 02:20:45 GMT</pubDate>
            <description><![CDATA[<h1 id="http">HTTP</h1>
<p>HTTP는 애플리케이션 계층으로서 웹 서비스 통신에 사용된다.</p>
<p>지금은 3버전이며 1.0버전부터 차례대로 알아보자.</p>
<hr>
<h2 id="http10">HTTP/1.0</h2>
<p>설계할 때부터 <strong>한 연결 당 1개의 요청을 처리</strong>하도록 만들어졌는데</p>
<p>이는 곧 RTT 증가를 불러왔다.</p>
<h3 id="rtt-증가">RTT 증가</h3>
<blockquote>
<p>RTT : 패킷이 목적지에 도달한 뒤 다시 출발지로 돌아올 때까지의 시간
즉, 패킷 왕복 시간</p>
</blockquote>
<p>TCP의 3-way handshake 방식으로는 RTT가 계속 일어나게 된다.</p>
<ol>
<li>클라이언트 - TCP 연결 초기화</li>
<li>클라이언트 - 파일 요청<ul>
<li>서버 - 파일 전송</li>
</ul>
</li>
<li>전체 파일 수신</li>
</ol>
<p>위 3가지 과정 동안 2번의 RTT가 일어나게 된다.</p>
<hr>
<h3 id="rtt-증가를-해결하는-방법">RTT 증가를 해결하는 방법</h3>
<p>HTTP/1.0 때는 매번 연결할 때마다 RTT가 증가하기 때문에</p>
<ul>
<li>서버의 부담</li>
<li>사용자 응답시간 증가</li>
</ul>
<p>위 2가지 단점이 있었기에 해결하기 위해</p>
<ul>
<li>이미지 스플리팅</li>
<li>코드 압축</li>
<li>이미지 Base64 인코딩</li>
</ul>
<p>3가지 방식을 사용하곤 했다.</p>
<hr>
<h4 id="이미지-스플리팅">이미지 스플리팅</h4>
<p>많은 이미지를 다운로드 받는 방식 -&gt; 과부하를 야기</p>
<p>위 문제로 인해 <strong>많은 이미지가 합쳐져 있는 하나의 이미지를 다운로드하는 방식</strong>으로, 이를 통해 <code>background-image</code> 의 <code>position</code>을 이용해 이미지를 표기하는 방법이다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/6c03baff-1ff2-4cd4-a4d3-b706a6a580dc/image.png" alt=""></p>
<p><strong>장점</strong></p>
<ul>
<li>서버의 요청 수를 줄여 로딩 시간을 단축할 수 있다.</li>
<li>스프라이트 이미지 파일만을 관리하기에 관리에 용이하다.</li>
</ul>
<p><strong>단점</strong></p>
<ul>
<li>스프라이트의 이미지에서 사용하려는 이미지의 정확한 position 값을 알아야 한다.</li>
<li>스프라이트 이미지 내에서 특정 이미지를 변경해야 할 때, 단일 파일보다 수정이 번거롭다.</li>
</ul>
<hr>
<h4 id="코드-압축">코드 압축</h4>
<p>코드를 압축해 개행 문자, 빈칸을 없애서 코드의 크기를 최소화하는 방법이다.</p>
<p>가독성을 위해서는 좋은 방식인지 잘 모르겠다.</p>
<hr>
<h4 id="이미지-base64-인코딩">이미지 Base64 인코딩</h4>
<blockquote>
<p>이미지 파일을 64진법으로 이루어진 문자열로 인코딩하는 방법</p>
</blockquote>
<p><strong>장점</strong></p>
<ul>
<li>서버와의 연결을 열고 이미지에 대해 서버에 HTTP 요청을 할 필요 없다.</li>
</ul>
<p><strong>단점</strong></p>
<ul>
<li>Base64 문자열로 변환할 경우 37% 정도 크기가 더 커진다..</li>
</ul>
<blockquote>
<p>인코딩 : 정보의 형태나 형식을 표준화, 보안, 처리 속도 향상, 저장 공간 절약을 위해 다른 형태로 변환하는 처리 방식</p>
</blockquote>
<hr>
<h2 id="http11">HTTP/1.1</h2>
<p>1.0에서 발전한 것이 1.1이다.</p>
<p>매번 TCP 연결을 하는 것이 아닌, TCP 초기화 이후 <code>keep-alive</code> 옵션으로 여러 개의 파일을 송수신할 수 있게 바뀌었다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/076340d5-c175-482a-9344-21e153cc87e1/image.png" alt=""></p>
<p>HTTP/1.0과 HTTP/1.1의 비교 사진으로 왼쪽이 1.0, 오른쪽이 1.1이다.</p>
<p>1.1부터는 1번 TCP 3-way handshake가 발생하면 다음부터 발생하지 않는 것을 볼 수 있다.</p>
<p>하지만 이 또한 아래와 같이 단점들이 있다.</p>
<blockquote>
<ul>
<li>다수의 리소스를 처리하려면 요청할 리소스 개수에 비례해 대기 시간이 길어진다.</li>
<li>HOL Blocking </li>
<li>무거운 헤더 구조 : HTTP/1.1의 헤더에는 쿠키 등 많은 메타데이터가 들어 있고 압축이 되지 않아 무겁다.</li>
</ul>
</blockquote>
<hr>
<h3 id="hol-blocking">HOL Blocking</h3>
<blockquote>
<p>HOL Blocking (Head Of Line Blocking) : 네트워크에서 같은 큐에 있는 패킷이 그 첫 번째 패킷에 의해 지연될 때 발생하는 성능 저하 현상</p>
</blockquote>
<p>만약 image.jpg, styles.css, data.xml 이라는 리소스를 다운로드할 때 순차적으로 받아지긴 하지만, <strong>첫 번째 패킷이 다운로드 시간이 길어지게 된다면 다운로드 시간이 지연되는 상태가 되는데</strong> 이 때를 HOL Blocking 현상이라고 한다.</p>
<hr>
<h2 id="http2">HTTP/2</h2>
<p>1.x 보다 지연 시간을 줄이고 응답 시간을 더 빠르게 하여</p>
<ul>
<li>멀티플렉싱</li>
<li>헤더 압축</li>
<li>서버 푸시</li>
<li>요청의 우선순위 처리</li>
</ul>
<p>위 4가지를 지원하는 프로토콜이다.</p>
<h3 id="멀티플렉싱">멀티플렉싱</h3>
<blockquote>
<p>여러 개의 스트림을 사용하여 송수신하는 것으로, 하나의 통신 채널을 통해서 둘 이상의 데이터를 전송하는데 사용되는 기술</p>
<p>특정 스트림의 패킷이 손실되었어도 해당 스트림에만 영향을 미치고 나머지 스트림은 정상적으로 동작할 수 있다.</p>
</blockquote>
<ul>
<li><strong>스트림</strong> : 시간이 지남에 따라 사용할 수 있게 되는 일련의 데이터 요소를 가리키는 데이터 흐름</li>
</ul>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/7f73f3e4-91f2-4f73-9b95-ae94a22bed78/image.png" alt=""></p>
<hr>
<h3 id="헤더-압축">헤더 압축</h3>
<p>HTTP/2에서는 헤더 압축을 써서 HTTP/1.x에서의 무거운 헤더 구조의 단점을 해결했는데,
허프만 코딩 압축 알고리즘을 사용하는 HPACK 압축 형식을 활용했다.</p>
<ul>
<li><strong>허프만 코딩</strong> : 문자열을 문자 단위로 쪼개 빈도수를 세어 <strong>빈도가 높은 정보는 적은 비트 수</strong>를 사용하여 표현하고, <strong>빈도가 낮은 정보는 비트 수를 많이 사용</strong>하여 표현해서 전체 데이터의 표현에 <strong>필요한 비트양을 줄이는 원리</strong></li>
</ul>
<hr>
<h3 id="서버-푸시">서버 푸시</h3>
<p>HTTP/1.1에서는 파일을 다운로드하려면 클라이언트가 서버에 요청을 해야 한다.</p>
<p>HTTP/2는 클라이언트 요청 없이 서버가 바로 리소스를 푸시할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/85205b29-d5dd-42b9-bdec-0a476090a855/image.png" alt=""></p>
<p>html에는 css나 js 파일이 포함되기 마련인데, html을 읽으면서 안에 있는 css 파일을 서버에 푸시해 클라이언트에 먼저 줄 수 있다.</p>
<hr>
<h2 id="https">HTTPS</h2>
<p>HTTP/2는 HTTPS 위에서 동작한다.</p>
<blockquote>
<p><strong>HTTPS</strong> : 애플리케이션 계층과 전송 계층 사이에 <strong>신뢰 계층인 SSL/TLS 계층</strong>을 넣어서 신뢰할 수 있는 HTTP 요청을 말한다. -&gt; <strong>통신을 암호화</strong>한다.</p>
</blockquote>
<h3 id="ssltls">SSL/TLS</h3>
<blockquote>
<p>전송 계층에서 보안을 제공하는 프로토콜
클라이언트와 서버가 통신을 할 때 SSL/TLS를 통해 제3자가 메시지를 도청하거나 변조하지 못하도록 한다.</p>
</blockquote>
<p>SSL(Secure Socket Layer)은 SSL 1.0부터 시작해서 TLS(Transport Layer Security Protocol)로 명칭이 변경되었으나 보통 <strong>SSL/TLS</strong>이라고 한다.</p>
<p>보안 세션을 기반으로 데이터를 암호화하며 <strong>보안 세션이 만들어질 때 인증 메커니즘, 키 교환 암호화 알고리즘, 해싱 알고리즘이 사용</strong>된다.</p>
<ul>
<li><strong>세션</strong> : 운영체제가 어떤 사용자로부터 자신의 자산 이용을 허락하는 일정한 기간<ul>
<li>즉, 사용자는 일정 기간 동안 응용 프로그램, 자원 등을 사용할 수 있다.</li>
</ul>
</li>
</ul>
<hr>
<h2 id="http3">HTTP/3</h2>
<p>HTTP/3 는 TCP 위에서 돌아갔던 HTTP/2와 다르게 <strong>QUIC 라는 계층 위에서 돌아간다.</strong></p>
<ul>
<li>추가로 <strong>UDP 기반으로 돌아간다.</strong></li>
</ul>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/b69f91e2-5fb1-4c49-8f3f-a645464d2c8c/image.png" alt=""></p>
<p><a href="https://www.keysight.com/blogs/en/tech/nwvs/2022/07/08/http3-and-quic-prepare-your-network-for-the-most-important-transport-change-in-decades">참고 링크</a></p>
<p><strong>장점</strong></p>
<ul>
<li>HTTP/2에서 장점이었던 멀티플렉싱</li>
<li>초기 연결 설정 시 지연 시간 감소</li>
</ul>
<hr>
<h3 id="초기-연결-설정-시-지연-시간-감소">초기 연결 설정 시 지연 시간 감소</h3>
<p>QUIC는 TCP를 사용하지 않기 때문에 통신을 시작할 때 번거로운 3-way handshake 과정을 거치지 않아도 된다.</p>
<p>QUIC는 첫 연결 설정에 1-RTT(Round Trip Time, 왕복 시간)만 소요되고, 클라이언트가 보낸 어떠한 신호에 서버가 응답한다면 바로 통신을 할 수 있다.</p>
<hr>
<p>Reference</p>
<ul>
<li><a href="https://www.informit.com/">https://www.informit.com/</a></li>
<li><a href="https://babbab2.tistory.com/7">https://babbab2.tistory.com/7</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공지식 정리 - 네트워크 4. IP 주소]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-4.-IP-%EC%A3%BC%EC%86%8C</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-4.-IP-%EC%A3%BC%EC%86%8C</guid>
            <pubDate>Wed, 01 Jan 2025 16:37:36 GMT</pubDate>
            <description><![CDATA[<h1 id="ip-주소">IP 주소</h1>
<p>인터넷 계층에 있는 IP 주소에 대해 좀 더 자세히 알아보자.</p>
<h2 id="arp">ARP</h2>
<blockquote>
<p>IP 주소로부터 MAC 주소를 구하는 IP와 MAC 주소의 다리 역할을 하는 프로토콜</p>
</blockquote>
<p>ARP를 통해 가상 주소인 IP 주소를 실제 주소인 MAC 주소로 변환한다.</p>
<p>반대로 RARP를 통해 실제 주소인 MAC 주소를 가상 주소인 IP 주소로 변환하기도 한다.</p>
<p>예시를 들어서 어느 하나의 1번 장치가 있다면, </p>
<ol>
<li>ARP Request 브로드캐스트를 보내서 해당 가상 주소 IP주소에 해당하는 MAC 주소를 찾는다.</li>
<li>해당 주소에 맞는 2번 장치에서 ARP Reply 유니캐스트를 통해 MAC 주소를 반환하는 과정을 거져 IP 주소에 맞는 MAC 주소를 찾게 된다.</li>
</ol>
<blockquote>
<p><strong>브로드캐스트</strong> : 송신 호스트가 전송한 데이터가 네트워크에 연결된 모든 호스트에 전송되는 방식
<strong>유니캐스트</strong> : 고유 주소로 식별된 하나의 네트워크 목적에 1:1로 데이터를 전송하는 방식</p>
</blockquote>
<hr>
<h2 id="홉바이홉-통신-hop-by-hop">홉바이홉 통신 (Hop by Hop)</h2>
<blockquote>
<p>IP 주소를 통해 통신하는 과정</p>
<ul>
<li>hop : 건너뛴다는 개념</li>
</ul>
</blockquote>
<p>통신망에서 각 패킷이 여러 개의 라우터를 건너가는 모습을 비유적으로 표현한 것이다.</p>
<p>통신 장치에 있는 <strong>라우팅 테이블</strong>의 IP를 통해 시작 주소부터 시작해 다음 IP로 계속해서 이동하는 <strong>라우팅</strong> 과정을 거쳐 패킷이 최종 목적지까지 도달하는 통신을 뜻한다.</p>
<h3 id="라우팅-테이블">라우팅 테이블</h3>
<blockquote>
<p>송신지에서 수신지까지 도달하기 위해 사용하며 라우터에 들어 있는 목적지 정보들과 해당 목적지로 가기 위한 방법이 들어 있는 리스트</p>
</blockquote>
<p>라우팅 테이블에는 <strong>게이트웨이</strong>와 모든 목적지에 대해 해당 목적지에 도달하기 위해 거쳐야 할 다음 라우터의 정보를 가지고 있다.</p>
<hr>
<h3 id="게이트웨이">게이트웨이</h3>
<blockquote>
<p>서로 다른 네트워크 간 통신을 가능하게 하는 관문</p>
</blockquote>
<p>사용자는 인터넷에 접속하기 위해서 수많은 게이트웨이를 거쳐야 한다.</p>
<p>통신을 가능하게 해준다는 것은 즉, <strong>서로 다른 네트워크 상의 통신 프로토콜을 변환해주는 역할</strong></p>
<blockquote>
<p>게이트웨이 확인 방법
라우팅 테이블을 통해 볼 수 있다.</p>
<ul>
<li>라우팅 테이블은 <code>netstat -r</code> 명령어를 실행해 확인 가능
IPv4 경로 테이블, IPv6 경로 테이블이 있는데 이것이 라우팅 테이블이다.</li>
</ul>
</blockquote>
<hr>
<h2 id="ip-주소-체계">IP 주소 체계</h2>
<ol>
<li><p><strong>IPv4</strong>
32비트를 8비트 단위로 점을 찍어서 표기 -&gt; ex) <code>123.45.67.89</code></p>
</li>
<li><p><strong>IPv6</strong>
64비트를 16비트 단위로 점을 찍어서 표기 -&gt; ex) <code>2001:db8::ff00:12:3456</code></p>
</li>
</ol>
<p>추세는 IPv6로 가고 있긴 하지만 가장 많이 쓰이는건 IPv4이다.</p>
<hr>
<h3 id="클래스-기반-할당-방식">클래스 기반 할당 방식</h3>
<p>네트워크 ID(네트워크 주소)와 호스트 ID(호스트 주소)를 먼저 알아보자.</p>
<p>Network ID, Host ID
하나의 네트워크 주소에는 Network ID와 Host ID
즉, 네트워크 주소와 호스트 주소가 있다.</p>
<blockquote>
<p>네트워크 주소란?
인터넷 상에서 모든 host들을 전부하기 힘들기 때문에 한 네트워크의 범위를 지정하여 관리하기 쉽게 만든 것.</p>
</blockquote>
<blockquote>
<p>호스트 주소란?
호스트를 개별적으로 관리하기 위해 사용하게 된 것.</p>
</blockquote>
<p><strong>클래스 기반 할당 방식</strong>
A, B, C, D, E 이렇게 다섯개의 클래스로 구분하는 할당 방식을 쓴다.</p>
<p>앞의 부분을 네트워크 주소, 그 뒤를 컴퓨터에 부여하는 호스트 주소로 사용한다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/8cb3f102-9032-41e7-8212-bf89472e7821/image.png" alt=""></p>
<ul>
<li>클래스 A, B, C는 <strong>일대일 통신</strong>으로 사용</li>
<li>클래스 D는 <strong>멀티캐스트 통신</strong></li>
<li>클래스 E는 미래에 사용하기 위한 <strong>예비용 클래스</strong>로 사용</li>
</ul>
<blockquote>
<p>클래스 A
처음 1바이트(8비트)가 네트워크 주소이며, 나머지 3바이트(24비트)는 호스트 주소이다.
맨 왼쪽에 있는 구분 비트는 0으로 시작하고 네트워크 할당은 0~127 이다.</p>
</blockquote>
<blockquote>
<p>클래스 B
처음 2바이트(16비트)가 네트워크 주소이며, 나머지 2바이트(16비트)는 호스트 주소이다.
맨 왼쪽에 있는 구분 비트는 10으로 시작하고, 네트워크 할당은 128~191 이다.</p>
</blockquote>
<blockquote>
<p>클래스 C
처음 3바이트(24비트)가 네트워크 주소이며, 나머지 1바이트(8비트)는 호스트 주소이다.
맨 왼쪽에 있는 구분 비트는 110으로 시작하고, 네트워크 할당은 192~223 이다.</p>
</blockquote>
<hr>
<h4 id="클래스-구분-방법">클래스 구분 방법</h4>
<p>간단하게 첫번째 Octet으로 구분할 수 있으며,
첫번째 Octet에서 0~255 까지의 숫자를 5개로 나눠서 구분하면 된다.</p>
<p><strong>클래스 A</strong> 는 0~255 (총 256개의 절반 128) -&gt; 0부터 시작이므로 <strong>127</strong></p>
<ul>
<li>(0.0.0.0 ~ 127.255.255.255)</li>
</ul>
<p><strong>클래스 B</strong> 는 128~255 (총 128개의 절반 64) -&gt; 0부터 시작이므로 <strong>191</strong></p>
<ul>
<li>(128.0.0.0 ~ 191.255.255.255)</li>
</ul>
<p><strong>클래스 C</strong> 는 192~255 (총 64개의 절반 32) -&gt; 0부터 시작이므로 <strong>223</strong></p>
<ul>
<li>(192.0.0.0 ~ 233.255.255.255)</li>
</ul>
<p><strong>클래스 D</strong> 는 224~255 (총 32개의 절반 16) -&gt; 0부터 시작이므로 <strong>239</strong></p>
<ul>
<li>(234.0.0.0 ~ 239.255.255.255)</li>
</ul>
<p><strong>클래스 E</strong> 는 240~255 (총 16개) -&gt; 0부터 시작이므로 <strong>127</strong></p>
<ul>
<li>(240.0.0.0 ~ 255.255.255.255)</li>
</ul>
<hr>
<h4 id="네트워크-주소">네트워크 주소</h4>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/c5ac30a1-2bfa-43d9-94c9-a5ae24f28958/image.png" alt=""></p>
<p><strong>네트워크 구별 주소 (= 네트워크 주소)</strong>
네트워크 구별 주소는 가장 첫번째 주소이며, 네트워크 주소로 사용된다.</p>
<p>⇀ 클래스 A의 120.0.0.0 이라는 네트워크를 부여받은 경우, 120.0.0.0 이 네트워크 구별 주소이다.</p>
<p><strong>호스트 주소</strong>
호스트 주소는 첫번째 주소와 마지막 주소를 제외한 나머지 주소를 말하며, 컴퓨터에 부여할 수 있는 주소이다.</p>
<p>⇀ 120.0.0.1 ~ 120.255.255.254 가 해당된다.</p>
<p><strong>브로드캐스트 주소</strong>
브로드캐스트 주소는 가장 마지막 주소를 말하며, 네트워크에 속해 있는 모든 컴퓨터에 데이터를 보내는 주소이다.</p>
<p>⇀ 120.255.255.255 가 여기에 속한다.</p>
<hr>
<p>클래스 기반 할당 방식은 <strong>사용하는 주소보다 버리는 주소가 많다는 단점</strong>이 있다.</p>
<p>그래서 DHCP, IPv6, NAT 이 나오게 된다.</p>
<hr>
<h3 id="dhcp">DHCP</h3>
<blockquote>
<p>IP 주소 및 기타 통신 매개변수를 자동으로 할당하기 위한 네트워크 관리 프로토콜</p>
</blockquote>
<p>이것을 통해 IP 주소를 수동으로 설정할 필요 없이 인터넷에 접속할 때마다 자동으로 IP 주소를 할당할 수 있다.</p>
<p>많은 라우터와 게이트웨이 장비에 DHCP 기능이 있고, 대부분의 가정용 네트워크에서 IP 주소를 할당한다.</p>
<hr>
<h3 id="nat-network-address-translation">NAT (Network Address Translation)</h3>
<blockquote>
<p>패킷이 라우팅 장치를 통해 전송되는 동안 패킷의 IP 주소 정보를 수정해 IP 주소를 다른 주소로 매핑하는 방법</p>
</blockquote>
<p>IPv4 주소 체계만으로는 수많은 주소들을 모두 감당하지 못한다. 그래서 NAT로 공인 IP 와 사설 IP로 나눠서 많은 주소를 처리한다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/a695ef56-ca66-4b9e-8fae-2b888df5e557/image.png" alt=""></p>
<p><strong>NAT의 단점</strong></p>
<ul>
<li>여러 명이 동시에 인터넷에 접속하기 때문에 실제 접속 호스트 숫자에 따라 접속 속도가 느려질 수 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공지식 정리 - 네트워크 3. 네트워크 기기]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-3.-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EA%B8%B0</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-3.-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EA%B8%B0</guid>
            <pubDate>Wed, 01 Jan 2025 16:01:30 GMT</pubDate>
            <description><![CDATA[<p>AWS를 하면서도 많이 볼 수 있는 라우터, 로드밸런서와 같이 네트워크 기기와 같은 개념들도 알아보자.</p>
<h1 id="네트워크-기기">네트워크 기기</h1>
<h2 id="네트워크-기기의-처리-범위">네트워크 기기의 처리 범위</h2>
<ul>
<li>애플리케이션 계층 : L7 스위치</li>
<li>인터넷 계층 : 라우터, L3 스위치</li>
<li>데이터 링크 계층 : L2 스위치, 브릿지</li>
<li>물리 계층 : NIC, 리피터, AP</li>
</ul>
<p>애플리케이션 계층을 처리하는 기기부터 보자.</p>
<hr>
<h2 id="애플리케이션-계층-처리-기기">애플리케이션 계층 처리 기기</h2>
<h3 id="l7-스위치">L7 스위치</h3>
<blockquote>
<p>스위치 : 여러 장비를 연결하고 데이터 통신을 중재하며 목적지가 연결된 포트로만 전기 신호를 보내 데이터를 전송하는 통신 네트워크 장비</p>
</blockquote>
<p>L7 스위치는 <strong>로드밸런서</strong> 라고도 한다. 서버의 부하를 분산하는 기기로, 클라이언트로부터 오는 요청들을 분산시켜 여러 서버로 보내는 역할을 한다.</p>
<p><strong>목표</strong> : 시스템이 처리할 수 있는 트래픽 증가</p>
<ul>
<li>URL, 서버, 캐시, 쿠키들을 기반으로 트래픽을 분산한다.</li>
<li>바이러스나 불필요한 외부 데이터 등을 걸러내는 필터링 기능도 한다.</li>
<li>응용 프로그램 수준의 트래픽 모니터링도 가능</li>
</ul>
<p>장애가 발생한 서버가 있는 경우에는 트래픽 분산 대상에서 제외해야 하는데, <strong>정기적인 헬스 체크 (Health Check)를 이용</strong>해 감시하면서 이뤄진다.</p>
<h2 id="전송-계층-처리-기기">전송 계층 처리 기기</h2>
<h3 id="l4-스위치">L4 스위치</h3>
<p>로드밸런서의 특징인 트래픽 분산 등을 할 수 있습니다. <code>패킷의 IP주소</code>와 <code>Port번호</code>를 참고해서 적절히 트래픽분산을 할 수 있다.
또한 전송계층의 TCP, UDP 등의 헤더를 기반으로 우선순위를 판단해서 분산이 가능합니다.
L7스위치와 똑같이 헬스체크가 가능합니다.</p>
<blockquote>
<p><strong>L4 스위치와 L7 스위치의 차이</strong>
로드밸런서로는 위 2가지가 있는데, L4 스위치는 전송 계층을 처리하는 기기로 스트리밍 관련 서비스에서는 사용할 수 없다. 그리고 메시지 기반이 아닌 IP와 포트를 기반으로 (주로 포트 기반) 트래픽을 분산한다.
L7 스위치는 IP, 포트 외 URL, HTTP, 헤더, 쿠키 등을 기반으로 트래픽을 분산한다.</p>
</blockquote>
<p>처음에 말했던 것처럼 AWS와 같은 클라우드 서비스에서는 L7 스위치를 이용한 로드밸런싱은 ALB (Application Load Balancer) 컴포넌트</p>
<p>L4 스위치를 이용한 로드밸런싱은 NLB (Network Load Balancer) 컴포넌트</p>
<p>트래픽 분산이기 때문에 로드밸런서를 운용하기 위해서는 2대 이상의 서버가 필수적이다.
에러가 발생해 서버 1대가 다운돼도 서비스는 안정적으로 운용돼야 하기 때문이다.</p>
<hr>
<h2 id="인터넷-계층을-처리하는-기기">인터넷 계층을 처리하는 기기</h2>
<h3 id="라우터">라우터</h3>
<p>라우터는 여러 개의 네트워크를 연결, 분할, 구분하는 역할이다.
<img src="https://velog.velcdn.com/images/jojehuni_9759/post/5bc65011-6804-4922-a423-36a955faa87b/image.png" alt=""></p>
<blockquote>
<p><strong>라우팅</strong> : 하나 이상의 네트워크에서 경로를 선택하는 프로세스</p>
</blockquote>
<p>다른 네트워크에 존재하는 장치끼리 서로 데이터를 주고 받을 때 패킷 소모를 최소화, 경로를 최적화 해서 최소 경로로 패킷을 Forwarding 하는 라우팅을 하는 장비이다.</p>
<hr>
<h3 id="l3-스위치">L3 스위치</h3>
<p>L2 스위치의 기능 + 라우팅 기능을 갖춘 장비를 말하는데, 데이터 링크 계층 기기를 설명할 때 L2 스위치 기능을 작성하겠다.</p>
<p>라우팅 테이블을 참조해서 IP 패킷에 IP 주소를 담아보낸다.</p>
<p>그래서 L3 스위치는 라우터라고 해도 무방하다.</p>
<p>라우터는 소프트웨어 기반의 라우팅하는 것과 하드웨어 기반의 라우팅하는 것으로 나눠진다면,</p>
<p>하드웨어 기반의 라우팅을 하는 것이 L3 스위치 담당이다.</p>
<hr>
<p>TCP계층에서는 데이터 링크 계층 + 물리 계층 = 링크계층 이라고 했지만</p>
<p>네트워크 개념으로 다룰 때는 나눌 수 있다.</p>
<h2 id="링크-계층">링크 계층</h2>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/010aa136-88a7-4e50-a803-fa85c4bc9643/image.png" alt=""></p>
<ul>
<li>데이터 링크 계층은 <code>이더넷 프레임</code>을 통해 에러 확인, 흐름 제어, 접근 제어를 담당하는 계층을 말한다.</li>
<li>물리 계층은 무선 LAN과 유선 LAN을 통해 0과 1로 이루어진 데이터를 보내는 계층을 말한다.</li>
</ul>
<hr>
<h2 id="데이터-링크-계층을-처리하는-기기">데이터 링크 계층을 처리하는 기기</h2>
<h3 id="l2-스위치">L2 스위치</h3>
<p>장치들의 MAC 주소를 MAC 주소 테이블을 통해 관리하며,  인터넷계층에서 받은 패킷을 기반으로 이더넷프레임을 만들어 목적지 MAC주소로 패킷을 보내주는 역할</p>
<p>-&gt; 즉, 연결된 장치로부터 패킷이 왔을 때 패킷 전송을 담당한다.</p>
<blockquote>
<p><strong>L3 스위치</strong>는 라우팅 테이블을 참조해서 IP 패킷에 IP 주소를 담아보낸다고 위에 작성했었다. 
<strong>L2 스위치</strong>는 Mac 주소 테이블을 참조해서 Mac 주소를 담당하여 이더넷</p>
</blockquote>
<p>IP 주소는 이해 불가능하기 때문에 IP 주소 기반 라우팅은 불가능하다.</p>
<p>패킷의 MAC 주소를 읽어 스위칭하는 역할만 한다.</p>
<blockquote>
<p>만약에 MAC 주소 테이블이 없다면 -&gt; 전체 포트에 전달 후 MAC 주소 테이블의 주소는 일정 시간 이후 삭제하는 기능도 있다.</p>
</blockquote>
<hr>
<h3 id="브릿지-bridge">브릿지 (Bridge)</h3>
<p>2개의 근거리 통신망인 LAN을 상호 접속할 수 있도록 하는 통신망 연결 장치로 통신망의 범위를 확장하고 서로다른 LAN을 기반으로 하나의 통신망을 구축할 때 쓰인다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/1de2f6ca-6e51-4243-ab7d-c0fb10e8c72f/image.png" alt=""></p>
<p>포트와 포트 사이의 다리 역할을 하고, 장치에서 받아온 MAC 주소를 MAC 주소 테이블로 관리한다.</p>
<hr>
<h2 id="물리-계층을-처리하는-기기">물리 계층을 처리하는 기기</h2>
<h3 id="nic">NIC</h3>
<blockquote>
<p>LAN 카드라고 하는 NIC (네트워크 인터페이스 카드) 는 2대 이상의 컴퓨터 네트워크를 구성하는 데 사용한다.</p>
</blockquote>
<p>네트워크와 빠른 속도로 데이터를 송수신할 수 있도록 컴퓨터 내에 설치하는 확장 카드다.</p>
<p>각각 LAN 카드에는 주민등록번호와 같은 고유의 식별번호인 MAC 주소가 있다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/d828b748-8cdc-44cf-ae18-5099dee9992c/image.png" alt=""></p>
<hr>
<h3 id="리피터-repeater">리피터 (repeater)</h3>
<blockquote>
<p>들어오는 약해진 신호 정도를 증폭해 다른 쪽으로 전달하는 장치를 말한다.</p>
</blockquote>
<p>신호를 증폭하기에 패킷이 더 멀리 갈 수 있다.</p>
<blockquote>
<p>광케이블이 보급되면서는 잘 쓰이지 않는 장치다.</p>
</blockquote>
<hr>
<h3 id="ap-access-point">AP (Access Point)</h3>
<p><strong>패킷을 복사</strong>하는 기기로 유선 LAN을 연결한 후 다른 장치에서 무선 LAN 기술 (와이파이) 을 사용해 무선 네트워크 연결을 할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공지식 정리 - 네트워크 2. TCP/IP 4계층 모델]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-2.-TCPIP-4%EA%B3%84%EC%B8%B5-%EB%AA%A8%EB%8D%B8</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-2.-TCPIP-4%EA%B3%84%EC%B8%B5-%EB%AA%A8%EB%8D%B8</guid>
            <pubDate>Wed, 01 Jan 2025 14:50:27 GMT</pubDate>
            <description><![CDATA[<h1 id="tcpip-4계층-모델">TCP/IP 4계층 모델</h1>
<p><code>인터텟 프로토콜 스위트</code> : 인터넷에서 컴퓨터들이 서로 정보를 주고받는 데 쓰이는 프로토콜의 집합이다.</p>
<p>TCP/IP 4계층 모델 or OSI 7계층 모델로 설명한다. TCP/IP 4계층을 보자.</p>
<hr>
<h2 id="2---5-계층-구조">2 - 5. 계층 구조</h2>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/753e6288-3576-4751-9843-2b8433bb30ff/image.png" alt=""></p>
<p>위와 같이 비교할 수 있다.</p>
<p>애플리케이션 계층부터 보자.</p>
<hr>
<h3 id="애플리케이션-계층">애플리케이션 계층</h3>
<p>FTP, HTTP, SSH, SMTP, DNS 등 응용 프로그램이 사용되는 프로토콜 계층이다.</p>
<blockquote>
<ul>
<li><strong>FTP</strong> : 장치와 장치 간의 파일을 전송하는 데 사용되는 표준 통신 프로토콜</li>
<li><strong>HTTP</strong> : World Wide Web (www) 을 위한 데이터 통신의 기초이자 웹 사이트를 이용하는 데 쓰는 프로토콜</li>
<li><strong>SSH</strong> : 보안되지 않은 네트워크에서 안전하게 서비스 운영을 하기 위해 사용하는 암호화 네트워크 프로토콜</li>
<li><strong>SMTP</strong> : 이메일 전송과 같이 전자 메일 전송을 위한 인터넷 표준 통신 프로토콜</li>
<li><strong>DNS</strong> : 도메인 이름과 IP 주소를 매핑해주는 서버. IP 주소가 바뀌어도 도메인 주소로 서비스할 수 있다.</li>
</ul>
</blockquote>
<hr>
<h3 id="전송-계층">전송 계층</h3>
<p>송신자와 수신자를 연결하는 통신 서비스를 제공한다.
연결 지향 데이터 스트림 지원, 신뢰성, 흐름 제어를 제공할 수 있다.</p>
<ul>
<li>애플리케이션 계층과 인터넷 계층 사이의 데이터가 전달될 때 중계 역할을 한다.</li>
</ul>
<p>TCP, UDP, QUIC 가 있다.</p>
<blockquote>
<ul>
<li>TCP : 패킷 사이의 순서를 보장하고 연결 지향 프로토콜을 사용해 연결하기 때문에 신뢰성을 구축해 수신 여부를 확인할 수 있다. <code>가상회선 패킷 교환 방식</code>을 사용한다.</li>
<li>UDP : 순서를 보장하지 않고 수신 여부도 확인하지 않는다. 단순히 데이터만 주는 <code>데이터그램 패킷 교환 방식</code>을 사용한다.</li>
</ul>
</blockquote>
<p><code>가상회선 패킷 교환 방식</code>과 <code>데이터그램 패킷 교환 방식</code> 을 알아보자.</p>
<h4 id="가상회선-패킷-교환-방식">가상회선 패킷 교환 방식</h4>
<p>각 패킷에는 가상회선 식별자가 포함돼 모든 패킷을 전송하면 가상회선이 해제되고 패킷들은 전송된 <strong>순서대로</strong> 도착한다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/b62f09c1-d32b-4180-8431-ffa9f23c1fcd/image.png" alt=""></p>
<hr>
<h4 id="데이터그램-패킷-교환-방식">데이터그램 패킷 교환 방식</h4>
<p>패킷이 독립적으로 이동해 최적의 경로를 선택해서 간다.
하나의 메시지에서 분할된 여러 패킷은 서로 다른 경로로 전송될 수 있어서 보낸 메시지의 <strong>순서가 다르게</strong> 도착할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/87fb2be9-f45f-4096-ad33-e14455e227c3/image.png" alt=""></p>
<hr>
<h4 id="tcp-연결-성립-과정">TCP 연결 성립 과정</h4>
<p>TCP는 신뢰성을 확보할 때 <strong>3-way handshake</strong> 라는 작업을 진행한다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/e51b3ce1-04ed-4ffa-990b-f64414034712/image.png" alt=""></p>
<ol>
<li><strong>SYN 단계</strong> : 클라이언트는 서버에 클라이언트의 ISN을 담아 보낸다.<ul>
<li>ISN : 새로운 TCP 연결의 첫 번째 패킷에 할당된 임의의 시퀀스 번호</li>
</ul>
</li>
<li><strong>SYN + ACK 단계</strong> : 서버는 클라이언트의 SYN을 수신하고 서버의 ISN을 보내며 승인번호로는 ISN + 1 값을 보낸다.</li>
<li><strong>ACK 단계</strong> : 그 승인번호를 클라이언트가 담아 ACK 서버에 보낸다.</li>
</ol>
<blockquote>
<ul>
<li>SYN : 연결 요청 플래그</li>
<li>ACK : 응답 플래그</li>
<li>ISN : 초기 네트워크 연결할 때 할당된 32비트 고유 시퀀스 번호</li>
</ul>
</blockquote>
<p>TCP는 <strong>3-way handshake</strong> 로 인해 신뢰성이 있는 계층으로 볼 수 있다.</p>
<hr>
<h4 id="tcp-연결-해제-과정">TCP 연결 해제 과정</h4>
<p>연결을 해제할 때는 <strong>4-way handshake</strong> 과정을 진행한다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/97d02436-d0f6-4351-b95d-1e7c7fefc978/image.png" alt=""></p>
<ol>
<li><p>클라이언트가 연결을 닫으려고 할 때 <code>FIN</code> 으로 설정된 세그먼트를 보낸다.</p>
<ul>
<li>클라이언트는 <code>FIN_WAIT_1</code> 상태로 들어가 서버의 응답을 기다린다.</li>
</ul>
</li>
<li><p>서버는 클라이언트로 <code>ACK</code>라는 승인 세그먼트를 보낸다.</p>
<ul>
<li>서버도 <code>CLOSE_WAIT</code> 상태로 들어간다.</li>
<li>클라이언트가 세그먼트를 받으면 <code>FIN_WAIT_2</code> 상태로 들어간다.</li>
</ul>
</li>
<li><p>서버는 <code>ACK</code>를 보내고 일정 시간이 지난 뒤 클라이언트에 <code>FIN</code>이라는 세그먼트를 보낸다.</p>
</li>
<li><p>클라이언트는 <code>TIME_WAIT</code> 상태가 되고 다시 서버로 <code>ACK</code>를 보내 서버는 <code>CLOSED</code> 상태가 된다.
이후 클라이언트는 <strong>어느 정도의 시간을 대기한 뒤</strong> 연결이 닫히고 모든 자원의 연결이 해제된다.</p>
</li>
</ol>
<blockquote>
<p>어느 정도의 시간을 대기한 뒤에 닫는 이유?</p>
</blockquote>
<ol>
<li>지연 패킷이 발생할 경우를 대비하기 위해<ul>
<li>그냥 연결을 닫앗다가 패킷이 뒤늦게 도착해 처리하지 못하면 데이터 무결성 문제가 발생한다.</li>
</ul>
</li>
<li>두 장치가 연결이 닫혔는지 확인하기 위해<ul>
<li><code>LAST_ACK</code> 상태에서 닫히게 되면 다시 새로운 연결을 하려고 할 때 장치는 줄곧 <code>LAST_ACK</code>로 돼 있어 접속 오류가 생긴다.</li>
</ul>
</li>
</ol>
<blockquote>
<p>데이터 무결성 : 데이터의 정확성과 일관성을 유지하고 보증하는 것</p>
</blockquote>
<hr>
<h3 id="인터넷-계층">인터넷 계층</h3>
<blockquote>
<p>장치로부터 받은 네트워크 패킷을 IP 주소로 지정된 목적지로 전송하기 위해 사용하는 계층</p>
</blockquote>
<p>IP, ARP, ICMP 등이 있고 패킷을 수신해야 할 상대의 주소를 지정해 데이터를 전달한다.</p>
<p>상대방이 제대로 수신했는지에 대해서는 보장하지 않는 <strong>비연결형</strong>이라는 특징을 가지고 있다.</p>
<hr>
<h3 id="링크-계층-네트워크-접근-계층">링크 계층 (네트워크 접근 계층)</h3>
<blockquote>
<p>전선, 광섬유, 무선 등으로 실질적으로 데이터를 전달하며 장치 간 신호를 주고 받는 <strong>규칙</strong>을 정하는 계층</p>
</blockquote>
<p>링크 계층을 물리 계층 / 데이터 링크 계층 으로 나누기도 한다.</p>
<ul>
<li>물리 계층 : 무선 LAN 과 유선 LAN을 통해 0 과 1로 이루어진 데이터를 보내는 계층</li>
<li>데이터 링크 계층 : <code>이더넷 프레임</code>을 통해 에러 확인, 흐름 제어, 접근 제어를 담당하는 계층</li>
</ul>
<blockquote>
<p><strong>이더넷 프레임</strong> : 데이터 링크 계층은 이더넷 프레임을 통해 데이터의 에러를 검출하고 캡슐화해 아래 구조를 갖는다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/930528da-2c45-42b3-a0f6-736c1e68545d/image.png" alt=""></p>
<ul>
<li>Preamble : 이더넷 프레임이 시작임을 알리는 것</li>
<li>SFD : 다음 바이트부터 MAC 주소 필드가 시작됨을 알리는 것</li>
<li>DMAC, SMAC : 수신, 송신 MAC 주소를 말하는 것</li>
<li>EtherType : 데이터 계층 위의 계층인 IP 프로토콜을 정의한다.<ul>
<li>IPv4 or IPv6</li>
</ul>
</li>
<li>Payload : 전달받은 데이터</li>
<li>CRC : 에러 확인 비트</li>
</ul>
</blockquote>
<blockquote>
<p><strong>MAC 주소</strong> : 컴퓨터, 노트북 등 각 장치에는 네트워크에 연결하기 위한 장치 (LAN 카드)가 있는데 구별하기 위한 식별번호를 말한다.</p>
</blockquote>
<hr>
<p>다음 게시글은 네트워크 계층 별 장치들에 대해서 알아볼 것이고, 유선 LAN 관련해서 알아보자.</p>
<h1 id="유선-lan">유선 LAN</h1>
<blockquote>
<p><strong>전이중화(full duplex) 통신</strong> : 양쪽 장치가 동시에 송수신할 수 있는 방식</p>
</blockquote>
<p>동축케이블, 광케이블 등을 기반으로 만들어진유선 LAN을 이루는 이더넷은 <code>IEEE802.3</code> 이라는 프로토콜을 따르며 전이중화 통신을 쓴다.</p>
<blockquote>
<p><strong>IEEE802.3</strong> : 이더넷프레임은 어떤 구조를 기반으로 할 것인지, 케이블의 최대 전송량,
어떤 케이블만이 가능하도록 할 것인지 등을 정한 규칙</p>
</blockquote>
<p>그럼 전이중화 통신에 대해서도 알아보자.</p>
<hr>
<h2 id="전이중화-통신">전이중화 통신</h2>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/0f679a90-b4b2-4de2-a5ef-a62f26cc3b21/image.png" alt=""></p>
<p>송신로, 수신로로 나눠서 데이터를 주고 받으며 현대의 고속 이더넷은 이 방식으로 통신한다.</p>
<hr>
<h2 id="반이중화-통신-중-csmacd">반이중화 통신 중 CSMA/CD</h2>
<blockquote>
<p><strong>반이중화 통신</strong> : 양쪽 장치가 통신은 가능하지만, 동시에는 불가능해 한 번에 한 방향만 통신할 수 있는 방식을 말한다.</p>
</blockquote>
<p>이전에는 유선 LAN에다가 반이중화 통신 중 하나인 CSMA/CD 방식을 사용했다.</p>
<blockquote>
<p><strong>CSMA/CD</strong> : 회선을 사용하는지를 파악한 후 사용하지 않는다면 데이터를 보내고 충돌이 발생한다면 일정 시간 이후 재전송하는 방식
<img src="https://velog.velcdn.com/images/jojehuni_9759/post/25906231-c7f1-4de7-abf2-bd69b8fff0f7/image.png" alt=""></p>
</blockquote>
<p>이전에는 송신로, 수신로가 따로 있던 전이중화 방식이 아닌, 하나의 회선으로 주고 받았다.</p>
<p>그럼 양쪽에서 데이터를 보내게 되면 충돌이 발생할 것이고 그것을 예방하기 위해 사용하는 방식이 CSMA/CD 방식인 것이다.</p>
<hr>
<h2 id="케이블">케이블</h2>
<h3 id="트위스트페어케이블">트위스트페어케이블</h3>
<ul>
<li>쉴드 처리를 한 케이블 : STP</li>
<li>안 한 케이블 : UTP
<img src="https://velog.velcdn.com/images/jojehuni_9759/post/e79d80c8-785b-4f25-b98e-bffb2dc7c932/image.png" alt=""></li>
</ul>
<p>이 UTP 케이블이 바로 LAN 선이다.</p>
<hr>
<h2 id="광섬유-케이블">광섬유 케이블</h2>
<blockquote>
<p>레이저를 이용해 통신하며 보통 100Gbps의 데이터를 전송하는 케이블</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/736753ff-a270-4006-8902-787dc9d52409/image.png" alt=""></p>
<p>빛의 굴절률이 높은 부분을 코어, 낮은 부분을 클래딩 이렇게 다른 밀도를 가지는 유리나
플라스틱 섬유를 기반으로 제작한다.</p>
<p>한 번 들어간 빛이 내부에서 계속해서 반사하며
전진하여 반대편 끝까지 가는 원리를 이용한 것이다.</p>
<hr>
<h1 id="무선-lan">무선 LAN</h1>
<p>유선 LAN은 <code>IEEE802.3</code> 표준 규격을 따랐다면, 무선 LAN 은 <code>IEEE802.11</code> 표준규격을 따르며, 반이중화 통신을 따랐다.</p>
<h2 id="반이중화-통신">반이중화 통신</h2>
<blockquote>
<p><strong>반이중화 통신(half duplex)</strong> : 양쪽 장치는 서로 통신할 수 있지만, 동시에는 통신할 수 없으며 한 번에 한 방향만 통신할 수 있는 방식</p>
</blockquote>
<h3 id="csmaca">CSMA/CA</h3>
<blockquote>
<p>CSMA/CD 와 다르다.</p>
</blockquote>
<p>장치에서 데이터를 보내기 전에 일련의 과정을 기반으로 사전에 가능한 한 충돌을 방지하는 방식</p>
<ol>
<li>사용중인 채널이 있다면 다른 채널을 감지하다가 유후 상태인 채널을 발견한다.</li>
<li>프레임 간 공간 시간인 <code>IFS(InterFrame Space)</code>시간만큼 기다린다. </li>
</ol>
<ul>
<li><code>IFS</code>는 프레임의
우선순위를 정의할 때도 사용된다. </li>
<li><code>IFS</code>가 낮으면 우선순위가 높다.</li>
</ul>
<ol start="3">
<li>프레임을 보내기전 $0$ ~ $2^k - 1$ 사이에서 결정된 랜덤상수를 기반으로 결정된 시간만큼 기다린 뒤 프레임을 보낸다.
프레임을 보낸 뒤 제대로 송신이 되었고 ACK 세그먼트를 받았다면 끝. 
그러나 받지 못했다면, $k = k + 1$ 을 하며 이 과정을 반복
반복하다 $k$가 정해진 $Kmax$ 보다 더 커진다면 해당 프레임전송은 버린다. (abort)</li>
</ol>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/b0a88c92-926b-4bc9-b5e4-7840ebbe89ad/image.png" alt=""></p>
<hr>
<h2 id="대표-기술">대표 기술</h2>
<h3 id="wifi">Wifi</h3>
<p>와이파이는 전자기기들이 무선 LAN 신호에 연결할 수 있게 하는 기술</p>
<p>근거리 무선망이라고 하면 <strong>틀린 개념</strong>이다.
<strong>근거리 무선망에 속하는 것</strong></p>
<ul>
<li>블루투스</li>
<li>지그비</li>
</ul>
<h2 id="주파수-24ghz-5ghz의-차이">주파수, 2.4GHz, 5GHz의 차이</h2>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/02734d43-41ca-4a17-b53a-2c73b4eed27b/image.png" alt=""></p>
<p>간단하게 말하면 2.4GHz 는 장애물이 많은 곳에서 좋다. (속도는 조금 느리다.)
5GHz 는 뻥 뚫린 곳에서 좋다. (속도가 2.4GHz 보다 빠르기 때문에)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공지식 정리 - 네트워크 1. 네트워크의 기초]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-1.-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC%EC%9D%98-%EA%B8%B0%EC%B4%88</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-1.-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC%EC%9D%98-%EA%B8%B0%EC%B4%88</guid>
            <pubDate>Wed, 01 Jan 2025 12:46:57 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>네트워크</strong> : 컴퓨터 등 장치들이 통신 기술을 통해 구축하는 연결망을 지칭하는 용어</p>
</blockquote>
<h1 id="2-네트워크의-기초">2. 네트워크의 기초</h1>
<blockquote>
<p><strong>네트워크</strong> : 노드 &lt;-&gt; 링크가 서로 연결돼 있거나, 연결돼 리소스를 공유하는 집합</p>
</blockquote>
<ul>
<li>노드 : 서버, 라우터, 스위치 등 네트워크 장치들</li>
<li>링크 : 유선 or 무선 연결 방식</li>
</ul>
<h2 id="2---1-처리량-지연-시간">2 - 1. 처리량, 지연 시간</h2>
<blockquote>
<p><strong>좋은 네트워크의 개념</strong></p>
</blockquote>
<ul>
<li>많은 처리량을 처리 가능</li>
<li>지연 시간이 짧음</li>
<li>장애 빈도 낮음</li>
<li>좋은 보안을 갖춤</li>
</ul>
<h3 id="처리량">처리량</h3>
<blockquote>
<p>처리량 링크 내에서 성공적으로 전달된 데이터의 양
얼마만큼의 트래픽을 처리했는지 나타낸다.</p>
</blockquote>
<p><strong>처리량의 단위</strong> -&gt; bps(bits per second) : 초당 전송 or 수신되는 bit 수</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/87dc0313-e3fb-4981-af02-f077ae21518c/image.png" alt=""></p>
<h4 id="트래픽-처리량-의미-차이">트래픽, 처리량 의미 차이</h4>
<ul>
<li>트래핑이 많아짐 =&gt; &quot;<strong>흐르는 데이터</strong>가 많아졌다.&quot;</li>
<li>처리량이 많아짐 =&gt; &quot;<strong>처리되는 트래픽</strong>이 많아졌다.&quot;</li>
</ul>
<blockquote>
<p><strong>대역폭</strong> : 주어진 시간 동안 네트워크 연결을 통해 흐를 수 있는 최대 bit 수</p>
</blockquote>
<hr>
<h3 id="지연-시간">지연 시간</h3>
<blockquote>
<p>요청이 처리되는 시간을 의미한다.</p>
</blockquote>
<p>지연 시간에 영향을 주는 것</p>
<ul>
<li>매체 타입 (무선, 유선)</li>
<li>패킷 크기</li>
<li>라우터의 패킷 처리 시간</li>
</ul>
<hr>
<h2 id="2---2-네트워크-토폴로지-병목-현상">2 - 2. 네트워크 토폴로지, 병목 현상</h2>
<blockquote>
<p>네트워크 토폴로지 : 노드와 링크가 어떻게 배치돼 있는지에 대한 방식이자 연결 형태</p>
</blockquote>
<h3 id="트리-토폴로지">트리 토폴로지</h3>
<p>&#39;계층형 토폴로지&#39; 라고도 하며 트리 형태로 배치한 네트워크 구조
<img src="https://velog.velcdn.com/images/jojehuni_9759/post/217dae2a-35b1-4a9e-b0bd-54fffa957630/image.png" alt=""></p>
<ul>
<li>노드의 추가, 삭제가 쉽다</li>
<li>특정 노드에 트래픽이 집중될 때 하위 노드에 영향을 줄 수 있다.</li>
</ul>
<hr>
<h3 id="버스-토폴로지">버스 토폴로지</h3>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/06b3831f-3eae-42a7-92ca-19e1c53fe94e/image.png" alt=""></p>
<p>중앙 통신 회선 하나에 여러 개의 노드가 연결돼 공유하는 네트워크 구성
근거리 통신망 (LAN)에서 사용한다.</p>
<p><strong>장점</strong></p>
<ul>
<li>설치 비용이 적다</li>
<li>신뢰성이 우수하다.</li>
<li>중앙 통신 회선에 노드 추가, 삭제가 쉽다.</li>
</ul>
<p><strong>단점</strong></p>
<ul>
<li>스푸핑이 가능한 문제점이 있다.</li>
</ul>
<blockquote>
<p>스푸핑 : LAN 상에서 송신부의 패킷을 송신과 관련 없는 다른 호스트에 가지 않도록 하는 스위칭 기능을 속이거나 마비시켜 특정 노드에 해당 패킷이 오도록 처리하는 것이다.</p>
</blockquote>
<p>중앙 통신 회선 하나에 여러 개의 노드가 연결돼 있기 때문에 스위칭 기능을 속이게 되면 스푸핑이 가능해진다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/891c0401-7899-4925-afad-61066d1a9eee/image.png" alt=""></p>
<hr>
<h3 id="스타-토폴로지">스타 토폴로지</h3>
<p>중앙에 있는 노드에 모두 연결된 네트워크 구성
<img src="https://velog.velcdn.com/images/jojehuni_9759/post/cd317b03-62b6-4158-b6de-603307a695eb/image.png" alt=""></p>
<p><strong>장점</strong></p>
<ul>
<li>노드를 추가하기 쉽다</li>
<li>에러를 탐지하기 쉽다</li>
<li>패킷의 충돌 가능성이 적다.</li>
<li>장애 노드가 중앙 노드가 아닌 경우 다른 노드에 영향을 끼치는 것이 적다.</li>
</ul>
<p><strong>단점</strong></p>
<ul>
<li>중앙 노드에 장애 발생 시 전체 네트워크를 사용할 수 없다.</li>
<li>설치 비용이 많이 나간다.</li>
</ul>
<hr>
<h3 id="링형-토폴로지">링형 토폴로지</h3>
<p>각각의 노드가 양 옆의 1개씩 노드들과 연결돼 고리 (반지) 형태로 연속돼 통신하는 망 구성 방식
<img src="https://velog.velcdn.com/images/jojehuni_9759/post/a467b030-58ac-40bf-939c-492e007c4ce1/image.png" alt=""></p>
<p><strong>장점</strong></p>
<ul>
<li>노드의 개수가 증가해도 네트워크 상 손실이 거의 없다.</li>
<li>충돌이 발생될 가능성이 적다.</li>
<li>노드 고장 발견을 쉽게 찾을 수 있다.</li>
</ul>
<p><strong>단점</strong></p>
<ul>
<li>네트워크 구성 변경이 어렵다.</li>
<li>회선에 장애가 발생 시 전체 네트워크에 영향을 크게 끼칠 수 있다.</li>
</ul>
<hr>
<h3 id="메시-토폴로지-망형-토폴로지">메시 토폴로지 (망형 토폴로지)</h3>
<p>메시(mesh)는 그물망처럼 돼 있는걸 의미한다.
<img src="https://velog.velcdn.com/images/jojehuni_9759/post/df547f63-aa5b-4f3c-ac81-dd660abe4031/image.png" alt=""></p>
<p><strong>장점</strong></p>
<ul>
<li>하나의 장치에 장애가 발생해도 여러 개의 경로가 존재해 네트워크를 지속적으로 사용 가능하다.</li>
<li>추가로 트래픽 분산 처리도 가능하다.</li>
</ul>
<p><strong>단점</strong></p>
<ul>
<li>노드의 추가가 어렵다.</li>
<li>구축 비용, 운용 비용이 많이 든다.</li>
</ul>
<hr>
<h3 id="병목-현상">병목 현상</h3>
<blockquote>
<p><strong>병목 현상</strong> : 전체 시스템의 성능이나 용량이 하나의 구성 요소로 인해 제한을 받는 현상</p>
<p>예시로는 공간이 엄청 넓더라도 만약 출입문의 개수가 적거나 작다면 유동 유동의 흐름에 문제가 생길 수 있다.
서비스에서 이벤트를 열었을 때 트래픽이 많이 생기고, 트래픽을 잘 관리하지 못 하면 병목 현상이 생겨 사용자는 웹 사이트로 들어가지 못하게 된다.</p>
</blockquote>
<p>위 병목 현상을 찾을 때 중요한 기준이 될 수 있기 때문에 토폴로지가 중요하다.</p>
<hr>
<h2 id="2---3-네트워크-분류">2 - 3. 네트워크 분류</h2>
<ol>
<li>LAN (Local Area Network) : 규모가 작아서 개인적으로 소유 가능한 규모</li>
<li>MAN (Metropolitan Area Network) : 서울시 와 같이 시 규모</li>
<li>WAN (Wide Area Network) : 세계 규모</li>
</ol>
<ul>
<li>규모가 커질 수록 전송 속도는 느려지고, 혼잡스러워진다.</li>
</ul>
<hr>
<h2 id="2---4-네트워크-성능-분석-명령어">2 - 4. 네트워크 성능 분석 명령어</h2>
<p>애플리케이션 코드 상으로 문제가 없는데도 사용자가 서비스로부터 데이터를 못 가져올 때 네트워크 병목 현상일 가능성이 있다.</p>
<p>주된 원인으로는</p>
<ul>
<li>네트워크 대역폭</li>
<li>네트워크 토폴로지</li>
<li>서버 CPU, 메모리 사용량</li>
<li>비효율적인 네트워크 구성</li>
</ul>
<p>이런 원인들이 있으며 성능 분석을 위해 사용하는 명령어들을 알아보자.</p>
<h3 id="ping">ping</h3>
<blockquote>
<p>ping (<strong>P</strong>acket <strong>IN</strong>ternet <strong>G</strong>roper) : 네트워크 상태를 확인하려는 대상 노드를 향해 일정 크기의 패킷을 전송하는 명령어</p>
</blockquote>
<ul>
<li>해당 노드의 패킷 수신 상태</li>
<li>도달하기까지의 시간</li>
<li>네트워크가 잘 연결돼 있는지</li>
</ul>
<p>위와 같은 데이터를 얻을 수 있다.</p>
<p><strong>ping은 TCP/IP 프로토콜 중 ICMP 프로토콜을 통해 동작</strong>한다.
그래서 ICMP 프로토콜을 지원하지 않는 기기를 대상으로는 실행할 수 없거나 네트워크 정책 상 ICMP나 traceroute를 차단하는 경우 테스팅 불가능하다.</p>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/39711d61-627e-4c82-b1e0-0a3f9c355cdd/image.jpg" alt=""></p>
<p>-n 12 옵션을 넣어 12번의 패킷을 보내고 12번 받는 것을 볼 수 있다.</p>
<p>명령 프롬프트에서 해볼 수 있다.</p>
<hr>
<h3 id="netstat">netstat</h3>
<blockquote>
<p>netstat : 접속돼 있는 서비스들의 네트워크 상태를 표시하는 데 사용되는 명령어</p>
</blockquote>
<p>네트워크 접속, 라우팅 테이블, 네트워크 프로토콜 등 리스트를 보여준다.</p>
<p>주로 서비스의 포트가 열려 있는지 확인할 때 쓴다.</p>
<hr>
<h3 id="nslookup">nslookup</h3>
<blockquote>
<p>nslookup : DNS에 관련된 내용을 확인하기 위해 쓰는 명령어</p>
</blockquote>
<p>특정 도메인에 매핑된 IP를 확인하기 위해 사용한다.</p>
<hr>
<h3 id="tracert-윈도우-traceroute-리눅스">tracert (윈도우), traceroute (리눅스)</h3>
<blockquote>
<p>tracert : 목적지 노드까지 네트워크 경로를 확인할 때 쓰는 명령어</p>
</blockquote>
<p>목적지 노드까지 구간들 중 어느 구간에서 응답 시간이 느려지는지 등을 확인할 수 있다.</p>
<hr>
<h2 id="네트워크-프로토콜-표준화">네트워크 프로토콜 표준화</h2>
<blockquote>
<p>네트워크 프로토콜 : 다른 장치들끼리 데이터를 주고받기 위해 설정된 공통된 인터페이스</p>
<p>IEEE 또는 IETF 라는 표준화 단체가 정한다.</p>
</blockquote>
<p><code>IEEE802.3</code> : 유선 LAN 프로토콜로, 유선으로 LAN을 구축할 때 쓰이는 프로토콜이다. 기업이 다른 장치라도 서로 데이터를 수신할 수 있는 것이다.</p>
<p>예시로는 HTTP가 있는데, HTTP 라는 프로토콜을 통해 노드들은 웹 서비스를 기반으로 데이터를 주고 받을 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공지식 정리 - 디자인 패턴과 프로그래밍 패러다임 4. 프로그래밍 패러다임]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EA%B3%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84-4.-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EA%B3%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84-4.-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84</guid>
            <pubDate>Thu, 26 Dec 2024 11:35:18 GMT</pubDate>
            <description><![CDATA[<h1 id="프로그래밍-패러다임">프로그래밍 패러다임</h1>
<blockquote>
<p>프로그래머에게 프로그래밍의 관점을 갖게 해주는 역할을 하는 개발 방법론</p>
</blockquote>
<p>간단하게 알아보면 프로그래밍 패러다임은 크게 <code>선언형</code> / <code>명령형</code> 2가지로 나눠지며
추가적으로는</p>
<ul>
<li>선언형<ul>
<li><code>함수형</code></li>
</ul>
</li>
<li>명령형<ul>
<li><code>객체지향형</code></li>
<li><code>절차지향형</code></li>
</ul>
</li>
</ul>
<p>위와 같이 나눠진다.</p>
<h2 id="선언형과-함수형-프로그래밍">선언형과 함수형 프로그래밍</h2>
<p>선언형 프로그래밍 : &#39;무엇을&#39; 풀어내는가 &lt;- 이것에 집중하는 패러다임</p>
<ul>
<li>&quot;프로그램은 함수로 이루어진 것이다&quot; 라는 명제가 담겨있다.</li>
</ul>
<p>함수형 프로그래밍은 선언형 프로그래밍의 일종이다.</p>
<p>배열 속에서 최댓값을 찾기 위해서는 로직을 구성하는데</p>
<pre><code class="language-javascript">const ret = [1, 2, 3, 4, 5, 6, 7]
.reduce((max, num) =&gt; num &gt; max ? num : max, 0)
console.log(ret) // 7</code></pre>
<p><code>reduce()</code>는 &#39;배열&#39;만 받아서 누적한 결과값을 반환하는 순수 함수로, </p>
<p>함수형 프로그래밍은 &#39;순수 함수&#39;들을 블록처럼 쌓아 로직을 구현하고 &#39;고차 함수&#39;를 통해 재사용성을 높인 프로그래밍 패러다임이다.</p>
<p><strong>JavaScript는</strong> 함수가 일급 객체이기 때문에 -&gt; 객체지향보다는 <strong>함수형 프로그래밍 방식이 선호된다.</strong></p>
<blockquote>
<p><strong>순수 함수</strong> : 출력이 입력에만 의존하는 것</p>
</blockquote>
<blockquote>
<p><strong>고차 함수</strong> : 함수가 함수를 값처럼 매개변수로 받아 로직을 생성할 수 있는 것
일급 객체의 특징
• 변수나 메서드에 함수를 할당할 수 있습니다.
• 함수 안에 함수를 매개변수로 담을 수 있습니다.
• 함수가 함수를 반환할 수 있습니다.</p>
</blockquote>
<hr>
<h2 id="객체지향-프로그래밍">객체지향 프로그래밍</h2>
<blockquote>
<p>객체들의 집합으로 프로그램의 상호 작용을 표현하며 데이터를 객체로 취급하여 객체 내부에 선언된 메서드를 활용하는 방식</p>
</blockquote>
<pre><code class="language-javascript">const ret = [1, 2, 3, 4, 5, 6, 7]
class List {
    constructor(list) {
        this.list = list
        this.mx = list.reduce((max, num) =&gt; num &gt; max ? num : max, 0)
    }
    getMax() {
        return this.mx
    }
}
const a = new List(ret)
console.log(a.getMax()) // 7</code></pre>
<p>List 라는 클래스를 만들어 a 라는 객체를 만들 때 최댓값을 추출하는 메서드의 예제이다.</p>
<hr>
<h3 id="객체지향-프로그래밍-특징">객체지향 프로그래밍 특징</h3>
<p><a href="https://velog.io/@jojehuni_9759/java-%ED%81%B4%EB%9E%98%EC%8A%A4-%EA%B0%9D%EC%B2%B4-%EA%B0%9D%EC%B2%B4%EB%B0%B0%EC%97%B4">추상화, 캡슐화</a></p>
<p><a href="https://velog.io/@jojehuni_9759/Java-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EC%9D%98-%ED%8A%B9%EC%A7%95-%EC%83%81%EC%86%8D-%EB%8B%A4%ED%98%95%EC%84%B1">상속성</a></p>
<p><a href="https://velog.io/@jojehuni_9759/Java-%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5%EC%9D%98-%ED%8A%B9%EC%A7%95-%EB%8B%A4%ED%98%95%EC%84%B1">다형성</a></p>
<p>오버로딩과 오버라이딩에 대해서는 각각 추상화, 캡슐화 / 상속성에 대해 정리할 때 적어뒀으니 참고하면 좋을 것 같다.</p>
<hr>
<h3 id="객체지향-프로그래밍-설계-원칙">객체지향 프로그래밍 설계 원칙</h3>
<ul>
<li><p>단일 책임 원칙</p>
<blockquote>
<p>단일 책임 원칙(SRP, Single Responsibility Principle) :모든 클래스는 각각 하나의 책임만 가져야 하는 원칙</p>
<p>예를 들어 A라는 로직이 존재한다면 어떠한 클래스는 A에 관한 클래스여야 하고 이를 수정한다고 했을 때도 A와 관련된 수정이어야 한다.</p>
</blockquote>
</li>
<li><p>개방-폐쇄 원칙</p>
<blockquote>
<p>개방-폐쇄 원칙(OCP, Open Closed Principle)은 유지 보수 사항이 생긴다면 코드를 쉽게 확장할 수 있도록 하고 수정할 때는 닫혀 있어야 하는 원칙 </p>
<p>즉, 기존의 코드 변경은 줄이고, 확장성은 있게끔</p>
</blockquote>
</li>
<li><p>리스코프 치환 원칙</p>
<blockquote>
<p>리스코프 치환 원칙(LSP, Liskov Substitution Principle)은 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 하는 것</p>
<p>클래스는 상속이 되기 마련이고 부모, 자식이라는 계층 관계가 만들어지는데, 이 때 부모 객체에 자식 객체를 넣어도 시스템이 문제없이 돌아가게 만드는 것이다.</p>
</blockquote>
</li>
<li><p>인터페이스 분리 원칙</p>
<blockquote>
<p>인터페이스 분리 원칙(ISP, Interface Segregation Principle)은 하나의 일반적인 인터페이스보다 구체적인 여러 개의 인터페이스를 만들어야 하는 원칙</p>
</blockquote>
</li>
<li><p>의존 역전 원칙</p>
<blockquote>
<p>의존 역전 원칙(DIP, Dependency Inversion Principle)은 자신보다 변하기 쉬운 것에 의존하던 것을 추상화된 인터페이스나 상위 클래스를 두어 변하기 쉬운 것의 변화에 영향받지 않게 하는 원칙</p>
<p>ex) 타이어를 갈아끼울 수 있는 틀을 만들어 놓은 후 다양한 타이어를 교체할 수 있어야 한다. 즉, 상위 계층은 하위 계층의 변화에 대한 구현으로부터 독립</p>
</blockquote>
</li>
</ul>
<hr>
<h2 id="절차형-프로그래밍">절차형 프로그래밍</h2>
<p>로직이 수행되어야 할 연속적인 계산 과정으로 이루어져 있다.</p>
<p>코드를 구현하기만 하면 되기 때문에 코드의 가독성이 좋으며 실행 속도가 빠른 편이다.</p>
<pre><code class="language-javascript">const ret = [1, 2, 3, 4, 5, 6, 7]
let a = 0
for (let i = 0; i &lt; ret.length; i++) {
    a = Math.max(ret[i], a)
}
console.log(a) // 7</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 전공지식 정리 - 디자인 패턴과 프로그래밍 패러다임 3. 프록시 패턴, 이터레이터 패턴, 노출모듈 패턴, MVC / MVP / MVVM 패턴]]></title>
            <link>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EA%B3%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84-3.-%ED%94%84%EB%A1%9D%EC%8B%9C-%ED%8C%A8%ED%84%B4-%EC%9D%B4%ED%84%B0%EB%A0%88%EC%9D%B4%ED%84%B0-%ED%8C%A8%ED%84%B4-%EB%85%B8%EC%B6%9C%EB%AA%A8%EB%93%88-%ED%8C%A8%ED%84%B4-MVC-MVP-MVVM-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@jojehuni_9759/CS-%EC%A0%84%EA%B3%B5%EC%A7%80%EC%8B%9D-%EC%A0%95%EB%A6%AC-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EA%B3%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84-3.-%ED%94%84%EB%A1%9D%EC%8B%9C-%ED%8C%A8%ED%84%B4-%EC%9D%B4%ED%84%B0%EB%A0%88%EC%9D%B4%ED%84%B0-%ED%8C%A8%ED%84%B4-%EB%85%B8%EC%B6%9C%EB%AA%A8%EB%93%88-%ED%8C%A8%ED%84%B4-MVC-MVP-MVVM-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Thu, 26 Dec 2024 10:27:39 GMT</pubDate>
            <description><![CDATA[<h1 id="프록시-패턴">프록시 패턴</h1>
<blockquote>
<p>객체에 접근하기 전 그 접근에 대한 흐름을 가로채 대상 객체 앞단의 인터페이스 역할을 하는 디자인 패턴</p>
</blockquote>
<p> 객체의 속성, 변환 등을 보완하며 보안, 데이터 검증, 캐싱, 로깅에 사용한다.</p>
<p> 이 패턴은 프록시 객체, 프록시 서버로 활용된다.</p>
<p> <strong>프록시 서버에서의 캐싱</strong>
캐시 안에 정보를 담아두고, 캐시 안에 있는 정보를 요구하는 요청에 대해 서버에 요청하지 않고 캐시 안에 있는 데이터를 활용하는 것
-&gt; 이는 곧 트래픽을 줄일 수 있다는 장점으로 이어진다.</p>
<hr>
<h2 id="프록시-서버">프록시 서버</h2>
<blockquote>
<p>서버와 클라이언트 사이에서 클라이언트가 자신을 통해 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 컴퓨터 시스템이나 응용 프로그램</p>
</blockquote>
<h3 id="nginx">nginx</h3>
<p>첫 번째 예시로는 nginx 가 있다.
<code>nginx</code> : 비동기 이벤트 기반의 구조와 다수의 연결을 처리 가능한 웹 서버</p>
<p>주로 Node.js 서버의 앞단 프록시 서버로 활용된다. -&gt; 버퍼 오버플로우 취약점 예방을 위해</p>
<p>익명 사용자의 직접적인 서버로의 접근을 차단하고 간접적으로 한 단계를 더 거침으로써 보안성을 더욱 강화할 수 있어서 사용한다.</p>
<ul>
<li>프록시 서버를 nginx로 둬서 실제 포트를 숨기기</li>
<li>정적 자원을 gzip 압축하기</li>
<li>메인 서버 앞단에서의 로깅</li>
</ul>
<p>위와 같은 방식들이 있다.</p>
<blockquote>
<p>버퍼 오버플로우 : <code>버퍼</code>는 보통 데이터가 저장되는 메모리 공간으로 이 공간을 벗어나는 경우를 뜻하는데 사용되지 않아야 할 영역에 데이터가 덮어씌워져 주소, 값을 바꾸는 공격이 발생하게 된다.</p>
</blockquote>
<hr>
<h3 id="cloudflare">CloudFlare</h3>
<p>전 세계적으로 분산된 서버가 있고 이를 통해 어떠한 시스템의 콘텐츠 전달을 빠르게 할 수 있는 CDN 서비스으로 추가적인 장점들도 있다.</p>
<blockquote>
<p>CDN(Content Delivery Network)
각 사용자가 인터넷에 접속하는 곳과 가까운 곳에서 콘텐츠를 캐싱 또는 배포하는 서버 네트워크
사용자가 웹 서버로부터 콘텐츠를 다운로드하는 시간을 줄일 수 있다.</p>
</blockquote>
<ul>
<li>HTTPS 구축</li>
<li>DDOS 방어</li>
</ul>
<p>사용자, 크롤러, 공격자가 웹 사이트에 접속하게 됐을 때 CloudFlare를 통해 공격자로부터 보호가 가능하다.</p>
<h4 id="https-구축">HTTPS 구축</h4>
<p>서버에서 HTTPS를 구축할 때 인증서를 기반으로 구축 가능한데
CloudFlare를 사용하면 인증서 설치 없이 좀 더 쉽게 가능하다.</p>
<h4 id="ddos-공격-방어">DDOS 공격 방어</h4>
<p>DDOS : 짧은 기간 동안 네트워크에 많은 요청을 보내 네트워크를 마비시켜 웹 사이트의 가용성을 방해하는 사이버 공격 유형</p>
<p>CloudFlare는 의심스러운 트래픽, 특히 사용자가 접속하는 것이 아닌 시스템을 통해 오는 트래픽을 자동으로 차단해서 DDOS 공격으로부터 보호한다.</p>
<hr>
<h3 id="cors---프론트엔드의-프록시-서버">CORS - 프론트엔드의 프록시 서버</h3>
<blockquote>
<p>CORS(Cross-Origin Resource Sharing) :
서버가 웹 브라우저에서 리소스를 로드할 때 다른 오리진을 통해 로드하지 못하게 하는 HTTP 헤더 기반 메커니즘</p>
<ul>
<li>오리진 : 프로토콜과 호스트 이름, 포트의 조합</li>
</ul>
</blockquote>
<p>프론트엔드의 오리진과 백엔드 서버의 오리진이 다르면 (거의 포트번호가 다른 경우로 받아들이면 된다.) CORS 에러가 발생한다.</p>
<p>이 때는 프론트엔드 서버 앞단에 프록시 서버를 둬서 문제를 해결할 수 있다.</p>
<p>요청이 들어왔을 때 해당 API 서버 통신을 매끄럽게 해주기 때문이다.</p>
<hr>
<h1 id="이터레이터-패턴">이터레이터 패턴</h1>
<blockquote>
<p>이터레이터(iterator)를 사용하여 컬렉션(collection)의 요소들에 접근하는 디자인 패턴</p>
</blockquote>
<p>순회할 수 있는 여러 가지 자료형의 구조와 상관없이 (= 다른 객체여도) 이터레이터라는 하나의 인터페이스로 순회가 가능하다.</p>
<pre><code class="language-javascript">const map = new Map()
map.set(&#39;a&#39;, 1)
map.set(&#39;b&#39;, 2)
map.set(&#39;c&#39;, 3)

const set = new Set()
set.add(1)
set.add(2)
set.add(3)

for (let a of map) console.log(a)
for (let a of set) console.log(a)

/*
[ &#39;a&#39;, 1 ]
[ &#39;b&#39;, 2 ]
[ &#39;c&#39;, 3 ]
1
2
3
*/</code></pre>
<p>다른 자료 구조인 <code>set</code>과 <code>map</code>임에도 똑같은 <code>for a of b</code>라는 이터레이터 프로토콜을 통해 순회한다.</p>
<blockquote>
<p>이터레이터 프로토콜 : iterable 한 객체들을 순회할 때 쓰이는 규칙</p>
</blockquote>
<blockquote>
<p>itreable 한 객체 : 반복 가능한 객체로, 배열을 일반화한 객체를 뜻한다.</p>
</blockquote>
<hr>
<h1 id="노출모듈-패턴">노출모듈 패턴</h1>
<blockquote>
<p>즉시 실행 함수를 통해 <code>private</code>, <code>public</code> 같은 접근 제어자를 만드는 패턴</p>
</blockquote>
<p>JavaScript는 private나 public 같은 접근 제어자가 존재하지 않고 전역 범위에서 스크립트가 실행된다. </p>
<p>그래서 노출모듈 패턴을 통해 private와 public 접근 제어자를 구현하기도 한다.</p>
<pre><code class="language-javascript">const revealing = (() =&gt; {
    const a = 1
    const b = () =&gt; 2
    const public = {
        c : 2, 
        d : () =&gt; 3
    }
    return public
})()
console.log(revealing)
console.log(revealing.a)
// { c: 2, d: [Function: d] }
// undefined</code></pre>
<p>a와 b는 다른 모듈에서 사용할 수 있는 변수나 함수인 private 범위여서 다른 모듈에서 접근할 수 없다.</p>
<p>c와 d는 다른 모듈에서 사용할 수 있는 변수나 함수인 public 범위여서 접근 가능하다.</p>
<blockquote>
<p>즉시 실행 함수 :
함수를 정의하자마자 바로 호출하는 함수. 초기화 코드, 라이브러리 내 전역 변수의 충돌 방지 등에 사용한다.</p>
</blockquote>
<hr>
<h1 id="mvc-패턴">MVC 패턴</h1>
<p><a href="https://velog.io/@jojehuni_9759/Spring-Spring-MVC-%ED%8C%A8%ED%84%B4%EC%9D%98-%EC%9A%94%EC%B2%AD-%EC%B2%98%EB%A6%AC-%EA%B3%BC%EC%A0%95">Spring MVC 패턴의 요청 처리 과정</a></p>
<p>이전에 MVC 패턴에 배우면서 간단하게 처리 과정에 대해서 정리한 적이 있어 그 글도 함께 보면 좋을 것 같다.</p>
<blockquote>
<p>MVC 패턴 : 모델(Model), 뷰(View), 컨트롤러(Controller)로 이루어진 디자인 패턴</p>
</blockquote>
<p>애플리케이션의 구성 요소를 세 가지 역할로 구분해 개발 프로세스에서 각각의 구성 요소에만 집중해서 개발할 수 있다.</p>
<ul>
<li>재사용성과 확장성이 용이하다는 <strong>장점</strong></li>
<li>애플리케이션이 복잡해질수록 모델과 뷰의 관계가 복잡해지는 <strong>단점</strong></li>
</ul>
<h2 id="용어">용어</h2>
<ol>
<li>Model : 애플리케이션의 데이터인 데이터베이스, 상수, 변수 등을 뜻한다.</li>
</ol>
<p>사각형 모양의 박스 안에 글자가 들어 있다면 그 사각형 모양의 박스 위치 정보, 글자 내용, 글자 위치, 글자 포맷(utf-8 등)에 관한 정보를 다 가지고 있어야 한다.</p>
<p>View 에서 데이터를 생성 or 수정하면 Controller 를 통해 Model을 생성하거나 갱신한다.</p>
<ol start="2">
<li>View : inputbox, checkbox, textarea 등 사용자 인터페이스 요소로 Model을 기반으로 사용자가 볼 수 있는 화면을 뜻한다.</li>
</ol>
<p>화면에 표시하는 정보만 가지고 있어야 하고, 변경이 생기면 Controller에 전달해줘야 한다.</p>
<ol start="3">
<li>Controller : 하나 이상의 Model과 View를 잇는 다리 역할. 이벤트와 같은 메인 로직을 담당한다.</li>
</ol>
<p>Model과 View의 생명주기 관리도 하고 변경이 되는 경우에 각각의 구성 요소에 해석한 내용을 알려준다.</p>
<hr>
<h1 id="mvp-패턴">MVP 패턴</h1>
<blockquote>
<p>MVC 패턴으로부터 파생된 패턴으로, Controller -&gt; Presenter로 교체된 패턴이다.</p>
<p>View 와 Presenter는 1:1 관계로 MVC 패턴보다 더 강한 결합을 지닌 디자인 패턴이다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/e7ce270d-aa7b-40d7-afa3-b2acd2f38a8d/image.png" alt=""></p>
<hr>
<h1 id="mvvm-패턴">MVVM 패턴</h1>
<blockquote>
<p> MVC의 C에 해당하는 컨트롤러가 뷰모델(view model)로 바뀐 패턴</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/jojehuni_9759/post/8e53d228-c5d1-4b2f-9384-320304f2b77b/image.png" alt=""></p>
<p>View Model은 View를 더 추상화한 계층이며 이 패턴은 커맨드와 데이터 바인딩을 가지는 것이 특징이다.</p>
<p>뷰와 뷰모델 사이의 양방향 데이터 바인딩을 지원하며 UI를 별도의 코드 수정 없이 재사용할 수 있고 단위 테스팅하기 쉽다는 장점이 있다.</p>
<p>예시로는 Vue.js가 있다.</p>
<blockquote>
<p>커맨드 :
여러 가지 요소에 대한 처리를 하나의 액션으로 처리할 수 있게 하는 기법이다.</p>
</blockquote>
<blockquote>
<p>데이터 바인딩 :
화면에 보이는 데이터와 웹 브라우저의 메모리 데이터를 일치시키는 기법으로, 뷰모델을 변경하면 뷰가 변경된다.</p>
</blockquote>
<h2 id="vuejs">Vue.js</h2>
<p>Vue.js는 반응형이 특징인 프런트엔드 프레임워크로, <code>watch</code>와 <code>computed</code> 등으로 쉽게 반응형적인 값들을 구축할 수 있다.</p>
<p>함수를 사용하지 않고 값 대입만으로도 변수가 변경되며 <code>양방향 바인딩</code>, <code>html</code>을 토대로 컴포넌트를 구축할 수 있다는 점이 특징이다.</p>
<p>재사용 가능한 컴포넌트도 정의할 수 있다. 이것을 기반으로 UI를 구축할 수 있다.</p>
]]></description>
        </item>
    </channel>
</rss>