<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>muntari Log</title>
    <link>https://codermun-log.tistory.com/</link>
    <description>성실과 기본기를 중요시하는 주니어 개발자입니다.</description>
    <language>ko</language>
    <pubDate>Tue, 21 Jul 2026 23:46:04 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>codermun</managingEditor>
    <item>
      <title>[혼자 공부하는 네트워크] 2회독 정리</title>
      <link>https://codermun-log.tistory.com/619</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;01. 컴퓨터 네트워크 시작하기&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;01-1 컴퓨터 네트워크를 알아야 하는 이유&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;컴퓨터 네트워크란?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 장치가 연결되어 서로 정보를 주고받을 수 있는 통신망을 의미.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;인터넷이란?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크를 연결하는 네트워크를 의미.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자가 네트워크를 알아야 하는 이유&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP, UDP, DNS, HTTP, HTTPS 등 &lt;b&gt;네트워크에 대한 이해는 프로그램을 만들고 유지보수하는 과정에 큰 도움&lt;/b&gt;이 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;01-2 네트워크 거시적으로 살펴보기&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;네트워크의 기본 구조&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크는 노드와 간선(링크)로 구성된 그래프 자료구조와 비슷한 구조를 가지고 있다고 이해하며 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 네트워크는 노드, 노드를 연결하는 링크, 노드간 주고받는 메시지로 구성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;노드 = 정보를 주고 받을 수 있는 장치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;링크 = 정보를 주고 받을 수 있는 유무선 통신 매체&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메시지 = 둘 사이에 주고 받는 메시지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호스트 = 네트워크에 가장 자리에 위치한 노드, 네트워크를 통해 흐르는 정보를 최초로 생성 및 송신하고 최종적으로 수신한다.&lt;br /&gt;이는 &lt;b&gt;서버 컴퓨터, 개인 데스크톱, 노트북, 스마트폰&lt;/b&gt; 등 우리가 일상적으로 사용하는 네트워크 기기 대부분이 이에 속하며 네트워크 가장자리에 위치하고 있다는 점에서 &lt;b&gt;종단 시스템(End System)이라고도 불린다.&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;네트워크 장비&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중간 노드 = 네트워크에는 가장 자리에 있는 호스트만 존재하지 않는다. 가장자리에 위치하지 않은 노드 즉, 호스트 간 주고받을 정보가 중간에 거치는 노드 &lt;b&gt;대표적으로 이더넷 허브, 스위치, 라우터, 공유기 등&lt;/b&gt;이 있으며 &lt;b&gt;이를 네트워크 장비라고 통칭&lt;/b&gt;한다.&lt;br /&gt;이러한 네트워크 장비는 &lt;b&gt;호스트 간 주고받는 정보가 원하는 수신지까지 안전하게 전송&lt;/b&gt;될 수 있도록 돕는다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;통신매체&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래프는 노드와 노드를 연결 짓는 간선으로 이루어져 있다. 호스트와 네트워크 장비 또한 유무선 매체를 통해 연결되어 있어야 한다. 이렇게 각 노드를 연결하는 링크가 바로 통신 매체이다. &lt;b&gt;유선 매체, 무선 매체&lt;/b&gt;가 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;메시지&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연결된 노드가 주고 받는 정보. 메시지는 &lt;b&gt;웹 페이지가 될 수도, 파일이 될 수도, 메일&lt;/b&gt;이 될 수도 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;범위에 따른 네트워크 분류&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 처럼 구성된 네트워크의 범위를 가늠해보자.&lt;br /&gt;범위는 일반 가정이 될 수도 있으며 때로는 도시나 국가가 될 수 있다. &lt;b&gt;그만큼 다양하다&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크는 범위에 따라 &lt;b&gt;LAN, WAN으로 구분&lt;/b&gt;한다. 이밖에도 CAN (campus area network) 학교 또는 회사, MAN (metropolitan area network) 도시, 대도시 기준의 범위들이 있다. 집합으로 예시를 든다면 WAN &amp;gt; MAN &amp;gt; CAN &amp;gt; LAN 순으로 정리할 수 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;LAN (local area network)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가까운 거리를 연결하는 &lt;b&gt;근거리 통신망&lt;/b&gt; (스타크래프트의 그 LAN이 맞다)&lt;br /&gt;&lt;b&gt;가정, 기업, 학교 처럼 한정된 공간&lt;/b&gt;에서의 &lt;b&gt;네트워크를 LAN이라 부른다.&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;WAN (wide area network)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼 거리를 연결하는 &lt;b&gt;광역 통신망&lt;/b&gt;&lt;br /&gt;&lt;b&gt;멀리 떨어진 LAN을 연결할 수 있는 네트워크가 바로 WAN&lt;/b&gt;이다. 앞서 &lt;b&gt;인터넷은 네트워크를 연결하는 네트워크&lt;/b&gt;라고 했다. &lt;b&gt;인터넷이 WAN으로 분류가 된다&lt;/b&gt;. 같은 LAN에 속한 호스트끼리 메시지를 주고받을때 WAN은 필요가 없지만, 다른 LAN에 속한 호스트와 메시지를 주고받는 경우 WAN이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 인터넷을 사용하기 위해 접속하는 WAN은 &lt;b&gt;ISP (internet service provider) 라는 인터넷 서비스 업체&lt;/b&gt;가 구축하고 관리한다. &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;(KT, LG, SKT)&lt;/b&gt;&lt;/span&gt; 등이다. &lt;b&gt;ISP는 사용자에게 연결가능한 회선을 임대&lt;/b&gt;하는 등의 서비스를 제공하며 이를 계약하여 이용하고 있는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ISP = KT, LG, SKT&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;메시지 교환 방식에 따른 네트워크 분류&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호스트들은 &lt;b&gt;네트워크를 통해 어떤 방식으로 메시지를 주고 받을까.&amp;nbsp;&lt;br /&gt;&lt;/b&gt;&lt;b&gt;대표적&lt;/b&gt;으로 &lt;b&gt;회선 교환 방식&lt;/b&gt;과 &lt;b&gt;패킷 교환 방식&lt;/b&gt;이 있다. 각각 회선 교환 네트워크, 패킷 교환 네트워크라고 부른다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;회선 교환 방식&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;메시지의 전송로인 회선을 먼저 설정하고 이를 통해 메시지를 주고받는 방식&lt;/b&gt;. 회선을 설정한다의 &lt;b&gt;의미&lt;/b&gt;는 &lt;b&gt;두 호스트를 연결&lt;/b&gt;한다, &lt;b&gt;전송로가 확보되었다&lt;/b&gt; 라는 말과 같으며, 메시지를 주고 받기 전 두 호스트를 연결한 이후 해당 경로를 통해 메시지를 주고 받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회선 교환 네트워크를 올바르게 작동시키기 위해 호스트 간 회서늘 적절히 설정해주는 &lt;b&gt;회선 스위치&lt;/b&gt;라는 네트워크 장비도 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 대한 &lt;b&gt;대표적인 사례가 전통적인 전화망&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;누군가 전화를 걸면 수신자는 전화를 받기 전에 송수신간 연결이 설정되어야 하며 한번 연결이 설정되면 열건된 전송로를 통해서만 통화가 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식에는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;문제점&lt;/b&gt;&lt;/span&gt;이 있다. &lt;b&gt;회선의 이용 효율이 낮다&lt;/b&gt;는 것이다.&lt;br /&gt;&lt;b&gt;가능한 모든 회선에 &lt;span style=&quot;color: #333333;&quot;&gt;끊임없이&lt;/span&gt; 메시지가 흐르고 있어야 이용 효율이 높아&lt;/b&gt;지는데, 반대로 이야기하자면 &lt;b&gt;메시지를 주고받지 않으면서 회선을 점유하면 낭비&lt;/b&gt;라고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A - B 사이에서 연결만 된채 &lt;span style=&quot;color: #333333;&quot;&gt;메시지를&lt;/span&gt; 주고 받고 있지 않는 다면 C -&amp;gt; B에게 메세지를 보내고 싶어도 보낼 수 없는 상황이 발생할 수 있다. 먼저 연결이 되어야만 메시지를 보낼 수 있는데 이미 B는 다른 A와 연결되어 있기 때문이다. 또 메시지를 주고 받고 있지도 않다.&lt;br /&gt;이에 대한&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt; 해결책&lt;/span&gt;으로 패킷 교환 방식&lt;/b&gt;이 등장한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;패킷 교환 방식&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;메시지를 패킷이라는 작은 단위로&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;쪼개어&lt;/span&gt; 전송하는 방식&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;패킷&lt;/b&gt;&lt;/span&gt;이란 &lt;b&gt;네트워크 상에서 송수신 되는 메시지의 단위&lt;/b&gt;이다. 현대 대부분의 인터넷은 패킷 교환 방식을 이용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 2GB 영화를 다운로드 받는다고 한다면 한번에 다 다운받는것이 아닌, 패킷의 크기 만큼 분할되어 전송된다. 이렇게 쪼개진 패킷들은 수신지인 나의 컴퓨터에 도달한 뒤 재조립된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;패킷&lt;/b&gt;은 회선 방식과 달리 &lt;b&gt;두 호스트가 하나의 경로를 점유하지 않는다&lt;/b&gt;. 그렇기에 &lt;b&gt;네트워크 이용 효율이 상대적으로 높다&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정에서 다양한 중간 노드를 거칠 수 있는데,&lt;br /&gt;&lt;b&gt;패킷&lt;/b&gt;이 &lt;b&gt;수신지까지 올바르게 도달 할 수 있도록 최적의 경로를 설정&lt;/b&gt;하거나, &lt;b&gt;패킷의 송수신지를 식별하는 장비로 패킷 스위치&lt;/b&gt;가 위치하는데 패킷 스위치 장비로는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;라우터&lt;/b&gt;&lt;/span&gt;와 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;스위치&lt;/b&gt;&lt;/span&gt;가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패킷을 택배라고 생각해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;택배는 먼저 보내고자 하는 상품을 담고, 어디로 보낼지, 보내는 사람은 누구인지 등의 정보가 있어야 올바르게 전달 될 수 있다.&lt;br /&gt;&lt;b&gt;패킷을 통해 전송하고자 하는 데이터&lt;/b&gt;를 &lt;b&gt;페이로드&lt;/b&gt;라 부른다. 추가로 &lt;b&gt;헤더&lt;/b&gt;와 &lt;b&gt;트레일러&lt;/b&gt; 정보가 포함되기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주소 (Adress)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;헤더에 담기는 대표적인 정보&lt;/b&gt;로는 &lt;b&gt;주소&lt;/b&gt;가 있다. 이는 &lt;b&gt;송수신지를 특정하는 정보&lt;/b&gt;이다. 이러한 주소에는 &lt;b&gt;IP, MAC 주소&lt;/b&gt; 등이 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;송수신지 유형별 전송 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;유니캐스트&lt;/b&gt; 가장 일반적인 송수신 방식으로 &lt;b&gt;일대일로 메시지&lt;/b&gt;를 주고 받는 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;브로드캐스트&lt;/b&gt; &lt;b&gt;자신을 제외한 네트워크상의 모든 호스트에게 메시지를 전송&lt;/b&gt;하는 방식&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;01-3 네트워크 미시적으로 살펴보기&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;프로토콜&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현대 인터넷은 대부분 패킷 교환 방식을 사용한다. 패킷을 택배로 비유했었는데 아래 사황을 봐보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영수에게 책을 택배로 선물하려고 한다. 일단 단편적으로 내가 보내는 책이 만약 불어로 되어있는 책을 선물한다면?&lt;br /&gt;영수는 올바르게 책을 수령해도 읽을 수 없을 것이다. 또한, 택배가 영수에게 잘 배달되려면 택배기사 또한 송수신(송장) 정보를 이해할 수 있는 언어로 적혀있어야 한다. 조금 더 나아가 택배 기사가 여려명이라면 이들끼리도 주고 받는 언어가 통해야한다.&lt;br /&gt;여기서 &quot;언어&quot;는 정보를 올바르게 주고받기 위해 합의된 의사소통 방식이라 볼 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크에서도 이와 유사한 개념이 바로 &lt;b&gt;프로토콜&lt;/b&gt;이다.&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;프로토콜&lt;/b&gt;&lt;/span&gt;은 &lt;b&gt;노드 간 정보를 올바르게 주고 받기 위해 합의된 규칙이나 방법을 의미&lt;/b&gt;한다. 통신 과정에서 하나의 프로토콜만을 사용하지는 않고 여러 프로토콜을 함꼐 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IP (internet protocol) - 패킷을 수신지까지 전달하기 위한 프로토콜&lt;br /&gt;ARP - IP 주소를 MAC로 대응하기 위해 사용되는 프로토콜&lt;br /&gt;HTTP, TCP, UDP 등 &lt;b&gt;모든 프로토콜은 저마다&lt;/b&gt;의 &lt;b&gt;목정과 특징&lt;/b&gt;이 있으며 저마다&lt;b&gt; 다른 패킷&lt;/b&gt;을 가지고 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;네트워크 참조 모델&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;택배를 받으면 물건을 뜯고 확인하는 일련의 과정이 있는 것 처럼 네트워크도 마찬가지이다.&lt;br /&gt;네트워크를 통해 정보를 주고받을때는 정형화된 여러 단계를 거치는데 이를 계층으로 표현할 수 있으며 이렇게 &lt;b&gt;통신이 일어나는 각 과정을 계층으로 나눈 구조&lt;/b&gt;를 &lt;b&gt;네트워크 참조 모델&lt;/b&gt;이라 부른다.&lt;br /&gt;대표적인 참조 모델로는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;OSI 모델&lt;/b&gt;&lt;/span&gt;과 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;TCP/IP 모델&lt;/b&gt;&lt;/span&gt;이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 통신 과정을 계층으로 나누는 이유는 크게 두 가지이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 네트워크 구성과 설계가 용이하다.&amp;nbsp;&lt;br /&gt;2. 네트워크 문제 진단과 해결이 용이하다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;OSI 모델&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;국제 표준화 기구 (ISO)에서 만든 네트워크 참조 모델.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 물리 계층&lt;br /&gt;전기 신호를 받아들이는 가장 근원적인 통신이 이루어지는 물리 계층&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 데이터 링크 계층&lt;br /&gt;네트워크 내 주변 장치 간 정보를 올바르게 주고받기 위한 계층&lt;br /&gt;이더넷, LAN, MAC 주소 체계 등 &lt;b&gt;네트워크 내 송수신지 특정&lt;/b&gt;, 전송 과정에서 발생하는 문제를 해결하는 계층.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 네트워크 계층&lt;br /&gt;메시지를 수신지까지 전달하는 계층&lt;br /&gt;인터넷을 가능케하는 계층으로 &lt;b&gt;IP 주소를 통해 수신지 호스트와&lt;/b&gt; &lt;b&gt;네트워크를 식별하고 원하는 수신지에 도달하기 위한&lt;/b&gt; &lt;b&gt;최적의 경로를 결정&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 전송 계층&lt;br /&gt;신뢰성 있고 안정성 있는 전송을 해야할 때 필요한 계층&lt;br /&gt;&lt;b&gt;패킷이 정상적으로 보내졌는지, 중간에 유실된 정보는 없는지, 여러개를 보낼때 패킷의 순서가 뒤바뀐건 없는지 등 패킷의 흐름 제어, 전송 오류를 점검&lt;/b&gt;해 안정적인 전송이 이루어지도록 한다.&amp;nbsp;&lt;br /&gt;&lt;b&gt;포트를 통해&lt;/b&gt; 실행중인 응용 프로그램 식별이 이루어지기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 세션 계층&lt;br /&gt;세션을 관리하기 위한 계층. 일반적으로 통신을 주고받는 &lt;b&gt;호스트의 응용 프로그램 간 연결 상태를 의미하는 세션&lt;/b&gt;&lt;br /&gt;세션을 생성, 유지, 종료되었을때 끊어주는 역할을 담당.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 표현 계층&lt;br /&gt;번역가와 같은 역할을 하는 계층&lt;br /&gt;사람이 이해할 수 있는 언어인 문자를 컴퓨터가 이해할 수 있게 코드로 변환하거나, 압축, 암호화 같은 작업을 담당&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. 응용 계층&lt;br /&gt;실질적인 네트워크 서비스가 제공되는 계층&lt;br /&gt;&lt;b&gt;웹 브라우저에 웹 페이지를 제공하거나, 이메일을 전송&lt;/b&gt; 등 네트워크 서비스가 이루어짐&lt;br /&gt;실질적인 네트워크 서비스가 이루어지는 만큼 타 계층에 비해 속한 프로토콜이 많다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;TCP/IP 모델&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OSI가 이론중심 모델이라면 &lt;b&gt;TCP/IP는 구현 중심의 모델&lt;/b&gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;오늘날 네트워크 구현의 핵심&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 네트워크 액세스 계층&lt;br /&gt;OSI의 데이터 링크 계층과 유사(네트워크 내 주변 장치 간 정보를 올바르게 주고받기 위한 계층)&lt;br /&gt;TCP/IP에서는 최하위 계층인 물리 계층이 없기에 이를 확장하여 5 계층으로 기술하기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 인터넷 계층&lt;br /&gt;OSI의 네트워크 계층과 유사 (메시지를 수신지까지 전달하는 계층)&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 전송 계층&lt;br /&gt;OSI의 전송 계층과 유사 (신뢰성 있고 안정성 있는 전송을 해야할 때 필요한 계층)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 응용 계층&lt;br /&gt;OSI의 세션, 표현, 응용을 합친것 과 유사&lt;br /&gt;세션을 관리하기 위한 계층 + 번역가와 같은 역할을 하는 계층 + 실질적인 네트워크 서비스가 제공되는 계층&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;캡슐화와 역캡슐화&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;패킷은 송신 과정에서 캡슐화 수신 과정에서 역캡슐화&lt;/b&gt;가 일어난다.&lt;br /&gt;누군가 택배를 보낸다면 누군가는 택배를 뜯어봐야하는것과 비슷&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;캡슐화&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패킷은 헤더와 페이로드 떄로는 트레일러를 포함하여 구성된다.&lt;br /&gt;포로토콜은 목적과 특징에 따라 헤더의 내용이 달라 질 수 있다.&lt;br /&gt;&lt;br /&gt;어떤 정보를 &lt;b&gt;송신할때 각 계층에서는 상위 계층으로부터&lt;/b&gt; &lt;b&gt;내려받은 패킷을 페이로드&lt;/b&gt;로 삼아서 &lt;b&gt;프로토콜에 걸맞는 헤더&lt;/b&gt;( 혹은 트레일러)를 덧붙힌 후에 &lt;b&gt;하위 계층으로 전달&lt;/b&gt;한다.&lt;br /&gt;&lt;b&gt;송신 과정에서 헤더 및 트레일러를&lt;span style=&quot;color: #ee2323;&quot;&gt; 추가&lt;/span&gt;해 나가는 과정을 캡슐화&lt;/b&gt;라고 부른다 (&lt;b&gt;인캡슐레이션&lt;/b&gt;이라고도 부름)&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;역캡슐화&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;받는 입장을 생각해보면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 &lt;b&gt;메시지를 수신할때 캡슐화 과정에서 붙혔던 헤더(트레일러) 등을 각 계층에서 확인한 뒤에 &lt;span style=&quot;color: #ee2323;&quot;&gt;제거&lt;/span&gt;하는 과정&lt;/b&gt;을 말한다.&lt;br /&gt;&lt;b&gt;역캡슐화&lt;/b&gt; &lt;b&gt;디캡슐레이션&lt;/b&gt;이라고도 부른다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;PDU (protocol date unit)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 &lt;b&gt;계층에서 송수신되는 &lt;span style=&quot;color: #ee2323;&quot;&gt;메시지의 단위&lt;/span&gt; PDU&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 상위 계층에서 전달받은 데이터에 현재 계층의 프로토콜 헤더(및 트레일러) 를 추가하면 현재 계층의 PDU가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;응용 + 표현 + 세션 계층에서의 PDU 는 Data&lt;br /&gt;전송 계층 PDU = segment, datagram (세그먼튼, 데이터그램)&lt;br /&gt;네트워크 계층 PDU = 패킷&lt;br /&gt;데이터 링크 계층 PDU = 프레임&lt;br /&gt;물리 계층 PDU = 비트&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크 계층에서의 PDU인 패킷은 일반적인 &lt;b&gt;네트워크 상에서 송수신 되는 메시지의 단위가 아니다.&amp;nbsp;&lt;/b&gt;&lt;br /&gt;송수신 단위를 지칭하기 위해 사용된다. (이 책에서는 혼동방지를 위해 &lt;b&gt;IP 패킷&lt;/b&gt;이라고 부른다)&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;트래픽&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크 내의 정보량을 의미.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;처리율 (throughput)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단위 시간 당 네트워크를 통해 실제로 전송되는 정보량&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;대역폭&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신호 처리 영역에서는 주파수의 범위를 의미하기도 하지만&lt;br /&gt;네트워크에서는 &lt;b&gt;단위 시간 동안 &lt;/b&gt;통신 매체를 통해&lt;b&gt; 송수신할 수 있는 최대 정보량을 의미&lt;/b&gt;. bps, Mbps, Gbps 단위 를 사용&lt;br /&gt;대역폭이 크다 = 많은 정보를 송수신할 능력이 크다 = 도로가 넒어 많은 자동차가 오갈 수 있는 상황&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;패킷 손실&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;송수신되는 패킷이 손실되는 상황을 의미.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;02 물리 계층과 데이터 링크 계층&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;물리 계층&lt;/b&gt;과 &lt;b&gt;데이터 링크 계층&lt;/b&gt;은 서로 밀접하게 연관되어있다. 이 &lt;b&gt;두 계층은&lt;/b&gt; &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;이더넷&lt;/span&gt;이라는 공통된 기술이 사용&lt;/b&gt;되기 때문이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;02-1 이더넷&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현대 LAN 특히 &lt;b&gt;유선 LAN 환경에서 가장 대중적으로 사용된느 기술&lt;/b&gt;.&lt;br /&gt;예를들어 두 대의 컴퓨터가 있다면 이 컴퓨터끼리 &lt;b&gt;정보를 주고받으려면&lt;/b&gt; &lt;b&gt;가장 먼저 케이블&lt;/b&gt;과 같은&lt;b&gt; 통신 매체가 필요&lt;/b&gt;하다.&lt;br /&gt;다양한 &lt;b&gt;통신 매체의 규격&lt;/b&gt;들과 &lt;b&gt;송수신되는 프레임의 형태&lt;/b&gt;, &lt;b&gt;프레임을 주고 받는 방법&lt;/b&gt;등이 &lt;b&gt;정의된 네트워크 기술&lt;/b&gt;이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;이더넷 표준&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현대 유선 LAN 환경은 십중팔구 이더넷을 기반으로 구성된다.&lt;br /&gt;&lt;b&gt;물리 계층&lt;/b&gt;에서는 &lt;b&gt;이더넷 규격의 케이블&lt;/b&gt;을&lt;br /&gt;&lt;b&gt;데이터 링크 계층&lt;/b&gt;에서는 주고받는 &lt;b&gt;프레임은 이더넷 프레임 형식&lt;/b&gt;을 따른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이더넷은 &lt;b&gt;IBEE 802.3&lt;/b&gt; 이라는 이름으로 표준화되어있다.&lt;br /&gt;&lt;b&gt;서로 다른 컴퓨터&lt;/b&gt;가 &lt;b&gt;각기 다른 제조사&lt;/b&gt;의 &lt;b&gt;네트워크 장비&lt;/b&gt;를 사용하더라도 동일한 형식의 프레임을 주고받고 약속한 듯 통일도니 형태로 작동하는 것은 통신 매체를 비롯한 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;네트워크 장비들이 이더넷 표준을 준수&lt;/b&gt;&lt;/span&gt;하기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;핵심&lt;/b&gt;은 &lt;b&gt;이더넷 표준&lt;/b&gt;에 따라 &lt;b&gt;지원되는 네트워크 장비&lt;/b&gt;, &lt;b&gt;통신 매체의 종류&lt;/b&gt;와 &lt;b&gt;전송 속도&lt;/b&gt; 등이 달라 질 수 있다는 점이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;통신 매체 표기 형태&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전송 속도&amp;nbsp;&lt;br /&gt;100 -&amp;gt; 100Mbps&lt;br /&gt;2.5G -&amp;gt; 2.5Gbps&lt;br /&gt;100G -&amp;gt; 100Gbps&lt;br /&gt;&lt;br /&gt;Base&lt;br /&gt;대부분 이더넷 통신 매체는 BASE를 사용한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;통신 매체 종류&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C - 동축 케이블&lt;br /&gt;T - 트위스티드 페어 케이블&lt;br /&gt;S - 단파장 광섬유 케이블&lt;br /&gt;L - 장파장 광섬유 케이블&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;이더넷 프레임&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현대 유선 LAN 환경은 대부분 이더넷 기반&lt;br /&gt;호스트가 &lt;b&gt;데이터 링크 계층에서 주고 받는 프레임 형식&lt;/b&gt;도 정해져있다.&lt;br /&gt;즉, 이더넷 네트워크에서 주고받는 프레임은 &lt;b&gt;이더넷 프레임 형식&lt;/b&gt;으로 정해져 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이더넷 프레임은 상위 계층으로 부터 받아들인 정보를 캡슐화 하는 과정에서 만들어진다.&lt;br /&gt;수신자 입장에서는 역캡슐화 과정을 거친다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이더넷 프레임 &lt;span style=&quot;color: #ee2323;&quot;&gt;헤더&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;프리엠블, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;수신지 MAC 주소, 송신지 MAC 주소&lt;/b&gt;&lt;/span&gt;, 타입/길이 로 구성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이더넷 프레임 페이로드&lt;br /&gt;데이터로 구성된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이더넷 프레임 트레일러&lt;br /&gt;FCS로 구성된다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;프리엠블&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이더넷 프레임의 시작을 알리는 8바이트 크기 정보.&lt;br /&gt;송수신지 간의 동기화를 위해 사용되는 정보 (이를 통해 호스트는 이더넷 프레임이 오고 있구나를 알 수 있다.)&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;수신지, 송신지 MAC 주소&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;MAC 주소는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;데이터 링크 계층의 핵심&lt;/b&gt;&lt;/span&gt; 내용이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;물리적 주소라고도 불리는 MAC 주소는 네트워크 인터페이스마다 부여되는 주소로서&lt;br /&gt;LAN 내의 송, 수신지 정보를 특정할 수 있다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;보통 NIC (network interface comtroller) 장치가 네트워크 인터페이스 역할을 담당하는데 하나의 컴퓨터에 NIC가 여러개 일 수 있으며 이때는 MAC 주소가 여러개 존재할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MAC 주소의 &lt;b&gt;대표적인 &lt;span style=&quot;color: #ee2323;&quot;&gt;오해&lt;/span&gt; 중 하나&lt;/b&gt;가. &lt;b&gt;맥주소는 반드시 고유하고 변경이 불가능하다 라는 점&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;사실 맥 주소는 변경이 가능한 경우도 많으며 고유하지 않을 수 있다고 한다. 다만 동이란 네트워크 내에서 동작하는 기기의 MAC 주소가 우연히 같을 확률이 현저히 낮다. 따라서 &lt;b&gt;MAC 주소는 일반적으로는 고유하고 변경되지 않는 주소 라고 이해&lt;/b&gt;하는게 적절하다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;타입/길이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;길이 - 프레임의 크기(길이)를 나타낸다&lt;br /&gt;타입 - 이더넷 프레임이 어떤 정보를 캡슐화했는지 나타내는 정보 이더타입이라고도 부름.&lt;br /&gt;타입 - 프로토콜&lt;br /&gt;0800 - IPv4&lt;br /&gt;86DD - IPv6&lt;br /&gt;0806 - ARP 등&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;데이터&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상위 계층에서 전달받거나, 상위 계층으로 전달해야하는 내용.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;FCS&amp;nbsp; (frame check sequence)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;수신한&lt;/span&gt; 이더넷 프레임이 오류가 있는지 확인&lt;/b&gt;하는 필드&lt;br /&gt;이를 통해 &lt;b&gt;데이터 링크 계층에서 오류 검출&lt;/b&gt;이 이루어지기도 한다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;02-2 NIC와 케이블&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NIC는 &lt;b&gt;호스트와 통신 매체를 연결&lt;/b&gt;하고 &lt;b&gt;MAC 주소가 부여되는 네트워크 장비&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;케이블은 NIC에 연결되는 &lt;b&gt;물리 계층의 유선 통신 매체&lt;/b&gt;이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;NIC&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호스트와 유무선 통신 매체를 연결하고 이러한 변환을 담당하는 네트워크 장비.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흔히 컴퓨터 본체에서 유선 랜 케이블을 연결하는 통로가 있는데 이를 담당하는 일종의 회로 기판?이라고 이해하자.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;NIC의 역할&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;통신매체에 흐르는 신호를 호스트가 이해하는 프레임으로 변환하거나 반대로 호스트가 이해하는 프레임으로 통신 매체에 흐르는 신호를 변환하는 역할을 함.&lt;br /&gt;네트워크와 연결점을 담당한다는 점에서 네트워크 인터페이스 역할을 수행하기도함&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;중략.&lt;br /&gt;02-3 허브&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;통신 매체를 통해 송수신되는 메시지는 다른 호스트에 전달되는 과정에서 네트워크 장비를 거칠 수 있다.&lt;br /&gt;대표적인 네트워크 장비로는&amp;nbsp;&lt;br /&gt;물리 계층의 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;허브&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;데이터 링크 계층의&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; 스위치&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;주소 개념이 없는 물리 계층&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;물리 계층에는 &lt;span style=&quot;color: #ee2323;&quot;&gt;주소 개념이 없다&lt;/span&gt;.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;주소 개념은 &lt;span style=&quot;color: #ee2323;&quot;&gt;데이터 링크 계층에서 등장&lt;/span&gt;한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그렇기에 물리 계층에서는 송수신되는 정보에 대한 어떠한 조작(송수신 내용 변경)이나 판단을 하지 않는다!!&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;허브&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;물리 계층의 허브는 여러 대의 호스트를 연결하는 장치이다. (TV 뒤에 인터넷 모뎀을 생각하자)&lt;br /&gt;이더넷 네트워크의 허브는 이더넷 허브라고도 부른다.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;허브에는 각 커넥터를 연결 할 수 있는 지점이 여러개 있는데 이곳 하나하나를 &lt;b&gt;포트&lt;/b&gt;라고 부른다 (&lt;b&gt;추후 다른의미의 포트도 등장함&lt;/b&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;허브의 특징&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;1. 전달받은 신호는 다른 모든 포트에 그대로 다시 내보낸다.&lt;br /&gt;주소 개념이 없기 때문이다.&lt;br /&gt;그럼 이렇게 전달 받은 모든 호스트는 각 데이터 링크 계층에서 패킷의 MAC 주소를 확인하고 자신과 관련없는 주소는 폐기한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;2. 반이중 모드로 통신한다.&lt;br /&gt;&lt;b&gt;반이중&lt;/b&gt;이란 쉽게 말해 &lt;b&gt;동시에 송수신이 불가능한 통신 방식&lt;/b&gt;을 말한다.&lt;br /&gt;무전기에서 누군가 이야기를 하고 있다면 다른 사람은 말할 수 없는 것과 동일하다.&lt;br /&gt;반대로 &lt;b&gt;전이중&lt;/b&gt;이란 &lt;b&gt;송수신을 동시에 양방향으로 할 수 있는 통신&lt;/b&gt;을 말한다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;콜리전 도메인&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;반이중 통신을 지원하는 허브에서 &lt;b&gt;만약 동시에 다른 호스트들이 허브에 신호를 송신&lt;/b&gt;하면 &lt;b&gt;충돌(콜리전)&lt;/b&gt;이 발생한다.&lt;br /&gt;이렇게 충돌이 발생할 수 있는 영역을 콜리전 도메인이라 부르며, &lt;b&gt;허브에 연결된 모든 호스트는 같은 콜리전 도메인에 속한다&lt;/b&gt;.&lt;br /&gt;콜리전 도메인은 작으면 작을 수록 충돌 발생이 줄어든다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;CSMA/CD 프로토콜&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;허브에서 &lt;b&gt;충돌이 발생하는 근본적인 이유&lt;/b&gt;는 &lt;b&gt;반이중 통신&lt;/b&gt; 때문인데 이 &lt;b&gt;충돌문제를 해결한 프로토콜&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Carrier Sense Multiple Access With Colision Detection 약자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CS는 Carrier Sense 캐리어 감지!&lt;br /&gt;MA는 다중 접근&lt;br /&gt;CD는 충돌 검출을 의미한다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 해당 프로톨은&lt;br /&gt;1. 먼저 현재 전송이 가능한 상태인지 확인&lt;br /&gt;2. 다른 호스트가 전송 중이지 않을 때만 메시지 전송&lt;br /&gt;3. 다수의 호스트가 접근해 충돌이 발생하면 임의의 시간 만큼 대기 한 후 다시 전송.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;02-4 스위치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 링크 계층의 장비 스위치.&lt;br /&gt;스위치는 허브와 달리 MAC 주소를 학습할 수 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;스위치&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스위치는 전이중 모드&amp;nbsp; + MAC 주소를 학습할 수 있으며 콜리전 도메인을 포트별로 구분할 수 있습니다.&lt;br /&gt;그렇기에 CSMA/CD 프로토콜에서의 임의의 대기시간이 없어지면서 당연히 성능상 이점이 있다.&lt;br /&gt;&lt;b&gt;스위치는 오늘날까지도 이더넷 네트워크의 구성시 자주 사용됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;스위치 특징&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;가장 중요한 특징&lt;/b&gt;은 &lt;b&gt;MAC 주소를 학습&lt;/b&gt; 즉, &lt;b&gt;특정 포트와 연결된 호스트의 MAC 주소와의 관계&lt;/b&gt;를 &lt;b&gt;기억&lt;/b&gt;한다는 점.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;MAC 주소 간 연관 관계를 메모리에 표 형태로 기억&lt;/b&gt;하는데 이를 &lt;b&gt;MAC 주소 테이블&lt;/b&gt;이라 부른다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;MAC 주소 학습&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 플러딩&lt;br /&gt;2. 포워딩과 필터링&lt;br /&gt;3. 에이징&lt;br /&gt;단계를 거치며 MAC 주소 테이블을 채워 특정 포트에만 프레임을 보낼 수 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스위치의 주소 학습은 프레임의 송신지 MAC 주소를 바탕으로 이루어진다.&lt;br /&gt;처음에는 MAC 주소를 학습하지 않았기 때문에 마치 허브처럼 수신지 포트를 제외한 모든 포트로 프레임을 전송한다. 이 동작을 &lt;b&gt;플러딩.&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 상관없는 패킷을 수신한 호스트는 자체적으로 이를 폐기하게된다.&lt;br /&gt;자 이제 처음 호스트의 MAC 주소를 학습했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 호스트로 수신한다면 위 과정을 반복하며 MAC 주소 테이블을 채워나간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전달받은 프레임을 어디로 내보내고 어디로 내보내지 않을지를 결정하는 스위치의 기능을 &lt;b&gt;필터링&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프레임이 전송될 포트에 실제로 프레임을 내보내는 것을 &lt;b&gt;포워딩&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 MAC 주소 테이블에 특정 포트에서 일정 시간 동안 프레임을 전송받지 못했다면 해당 항목을 삭제하는 기능을 &lt;b&gt;에이징&lt;/b&gt;이라 한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;VLAN (virual LAN)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;한대의 스위치를&lt;/b&gt; 이용해 가상의 LAN을 만든느 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각해보자 허브와 마찬가지로 스위치도 결국 브로드캐스팅을 해야하는 경우가 존재한다. 이는 성능 저하로 이어진다.&lt;br /&gt;VLAN을 구성하여 하나의 스위치에서도 여러개의 LAN을 구성할 수 있다면??&lt;br /&gt;10개의 포트를 A B 5개씩으로 나눈다고 가정해보자.&lt;br /&gt;A라는 VLAN A 환경에서 수신된다면 이전에는 9개에 대해서 보냈지만, 이제는 A에서 4개만 보내면 되는 셈이 되어버리는것이다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 이렇게 나눈 &lt;b&gt;A VLAN에 속한 호스트가 B에 속한 호스트와 통신하고자&lt;/b&gt; 한다면 &lt;b&gt;데이터 링크 계층 장비가 아닌 네트워크 계층 이상의 장비가 필요&lt;/b&gt;하다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;포트 기반의 VLAN&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스위치의 포트를 기반으로 VLAN을 결정하는 방식&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;MAC 주소 기반의 VLAN&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MAC 주소를 기반으로 VLAN을 결정하는 방식&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[출처 : 혼공네트 (저자: 강민철)_한빛&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;미디어 ]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;1076&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8BSh4/btsMcQiAUCx/cuict8Xejcz1LqpjE4JxjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8BSh4/btsMcQiAUCx/cuict8Xejcz1LqpjE4JxjK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8BSh4/btsMcQiAUCx/cuict8Xejcz1LqpjE4JxjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8BSh4%2FbtsMcQiAUCx%2Fcuict8Xejcz1LqpjE4JxjK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;1076&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;1076&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발서적</category>
      <category>cs</category>
      <category>cs 네트워크</category>
      <category>네트워크</category>
      <category>혼공네트</category>
      <category>혼자 공부하는 네트워크</category>
      <author>codermun</author>
      <guid isPermaLink="true">https://codermun-log.tistory.com/619</guid>
      <comments>https://codermun-log.tistory.com/619#entry619comment</comments>
      <pubDate>Sun, 9 Feb 2025 09:47:49 +0900</pubDate>
    </item>
    <item>
      <title>[혼자 공부하는 컴퓨터구조 + 운영체제] 2회독 정리_3</title>
      <link>https://codermun-log.tistory.com/617</link>
      <description>&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;08. 입출력장치&lt;/h3&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;8-1 장치 컨트럴러와 장치 드라이버&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;장치 컨트롤러&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입출력 장치는 CPU, 메모리보다 다루기 더 까다롭다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 입출력장치에는 종류가 너무나도 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프린터, 카메라, 키보드, 헤드셋, 스피커 등등 다양한 입출력 장치와 정보를 주고 받는 방식을 규격화하기 어렵다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 일반적으로 CPU와 메모리의 데이터 전송률을 높지만, 입출력 장치의 데이터 전송률은 낮다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1초에 1000마디 하는 사람과 1초에 1마디 하는 사람은 제대로 대화하기 어렵다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이와 같은 이유로&lt;b&gt; 입출력 장치는 직접 컴퓨터에 연결하지 않고,&lt;/b&gt; &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;장치 컨트롤러라&lt;/span&gt;는 하드웨어를 통해 연결&lt;/b&gt;한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하드 디스크를 뒤집어보면 볼 수 있는 하드웨어이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;장치 컨트롤러의 역할&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CPU와 입출력 장치간의 통신 중개&lt;/li&gt;
&lt;li&gt;오류 검출&lt;/li&gt;
&lt;li&gt;데이터 버퍼링&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 중 &lt;b&gt;데이터 버퍼링&lt;/b&gt;은 &lt;b&gt;전송률이 높은 장치와 낮은 장치 사이에 주고받는 데이터를 &lt;span style=&quot;color: #ee2323;&quot;&gt;버퍼라는 임시 저장 공간&lt;/span&gt;에 저장하여 전송률을 비슷하게 맞추는 방법&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;장치 드라이버&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장치 컨트롤러의 동작을 감지하고 제어함으로써 장치 컨트롤러가 컴퓨터 내부와 정보를 주고 받을 수 있게 하는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;프로그램&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장치 컨트롤러가 &lt;b&gt;입출력 장치를 연결하기 위한 하드웨어적 통로&lt;/b&gt;라면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장치 드라이버는 &lt;b&gt;입출력 장치를 연결하기 위한 소프트웨어적 통로&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터가 연결된 장치 드라이버를 인식하고 실행할 수 있다면 어떤 회사에서 만들이전 제품이든 생김새가 어떻든 컴퓨터 내부와 정보를 주고 받을 수 있다.&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;8-2 다양한 입출력 방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장치 컨트롤러와 CPU가 정보를 주고 받는 방법에는 크게 3가지가 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램 입출력&lt;/li&gt;
&lt;li&gt;인터럽트 기반 입출력&lt;/li&gt;
&lt;li&gt;DMA 입출력&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 입출력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램 속 명령어로 입출력 장치를 제어하는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장치 컨트롤러 내부는 데이터 레지스터 상태 레지스터, 제어 레지스터 등이 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 CPU는 입출력 장치들의 주소를 어떻게 알까? 더 자세히는 장치 컨트롤러의 레지스터들은 이걸 어떻게 아는걸까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에는 크게 2가지 방식이 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모리 맵 입출력 - 메모리에 접근하기 위한 주소 공간과 입출력 장치에 접근하기 위한 주소 공간을 하나의 주소 공간으로 간주하는법&lt;/li&gt;
&lt;li&gt;고립형 입출력 - 메모리를 위한 주소 공간과 입출력 장치를 위한 주소 공간을 분리하는 방법&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;인터럽트 기반 입출력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입출력장치가 CPU에게 인터럽트 요청 신호를 보내면 CPU는 하던일을 잠시 멈추고 해당 인터럽트를 처리하는 프로그램인 인터럽트 서비스 루틴을 실행한 뒤 다시 하던일로 되돌아온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 장치 컨트롤러가 입출력 작업을 끝낸 뒤 CPU에게 인터럽트 요청 신호를 보내는 입출력을 인터럽트 기반 입출력 (I/O)라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 키보드, 스피커, 프린터 등 많은 입출력 장치에서 동시에 인터럽트가 발생하면 어떻게 처리하는 걸까???&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CPU는 인터럽트 간 우선순위를 고려하여 우선순위가 높은 인터럽트 순으로 처리를 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선순위를 반영하여 다중 인터럽트를 처리하는 방법에는 여러가지가 존재한다고 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 컴퓨터에서는 &lt;b&gt;프로그래머블 인터럽트 컨트롤러 (PIC)라는 하드웨어를 사용하여 인터럽트의 우선순위를 판별한 뒤 CPU에게 지금 처리해야할 인터럽트가 무엇인지 알려주는 장치&lt;/b&gt;를 사용하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;DMA 입출력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞선 2가지 방식의 공통점은 모두 CPU를 반드시 거친다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU를 거쳐야한다는 것은 그만큼 CPU 부담이 커진다는 것을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 &lt;b&gt;입출력장치와 메모리가 &lt;span style=&quot;color: #ee2323;&quot;&gt;CPU를 거치지 않고&lt;/span&gt; 상호작용할 수&lt;/b&gt; 있는 &lt;b&gt;DMA (Direct Memory Access) 입출력&lt;/b&gt;이 등장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;[출처 : 혼공컴운 (저자: 강민철)_한빛 미디어 ]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;904&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eyYZTZ/btsHtMGlkzN/au0ULwM7XXV4ivR89nkBt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eyYZTZ/btsHtMGlkzN/au0ULwM7XXV4ivR89nkBt0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eyYZTZ/btsHtMGlkzN/au0ULwM7XXV4ivR89nkBt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeyYZTZ%2FbtsHtMGlkzN%2Fau0ULwM7XXV4ivR89nkBt0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;308&quot; height=&quot;363&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;904&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>개발서적</category>
      <author>codermun</author>
      <guid isPermaLink="true">https://codermun-log.tistory.com/617</guid>
      <comments>https://codermun-log.tistory.com/617#entry617comment</comments>
      <pubDate>Sun, 19 May 2024 17:02:16 +0900</pubDate>
    </item>
    <item>
      <title>[혼자 공부하는 컴퓨터구조 + 운영체제] 2회독 정리_2</title>
      <link>https://codermun-log.tistory.com/616</link>
      <description>&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;05.  CPU 성능 향상 기법&lt;/h3&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;5-1&amp;nbsp; 빠른 CPU를 위한 설계 기법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;클럭 (Clock)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;컴퓨터의 모든 부품을 일사불란하게&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;움직 일 수 있게하는 시간 단위라고 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;클럭 신호가 빠르게 반복되면 CPU를 비롯한 컴퓨터 부품들을 그만큼 빠른 박자에 맞춰 움직인다. 클럭 속도가 높을 수록 CPU의 명령어 사이클은 더 빠르게 반복하고 동작한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;실제로 &lt;b&gt;클럭 속도가 높은 CPU가 일반적으로 성능&lt;/b&gt;이 좋다. 그래서 &lt;b&gt;클럭 속도는 CPU 속도 단위로 간주&lt;/b&gt;되기도 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클럭 속도는 Hz 단위로 측정한다. 1Hz 1초에 1번, 100Hz는 1초에 100번 반복됨을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 현대 CPU의 클럭 속도는 얼마일가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Base : 2.5GHz Max : 4.9GHz&lt;br /&gt;1초에 클럭이 기본적으로 25억 (2.5 x 10^9)번, 순간적으로 최대 49억(4.9 x 10^9)번 반복됨을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네이버에서 가장 먼저 검색되는 제품은 아래와 같다. (Intel CPU i7 14세대)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;152&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dtsYOj/btsHq2nHiYJ/XTsiVWYBZmOqQaM5CnWjXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dtsYOj/btsHq2nHiYJ/XTsiVWYBZmOqQaM5CnWjXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dtsYOj/btsHq2nHiYJ/XTsiVWYBZmOqQaM5CnWjXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdtsYOj%2FbtsHq2nHiYJ%2FXTsiVWYBZmOqQaM5CnWjXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;561&quot; height=&quot;112&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;152&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그렇다면 클럭 속도를 무지막지하게 높이면 CPU가 무조건 빨라질까? -&amp;gt; No&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;클럭 속도가 무작정 높아지면 발열 문제가 심각&lt;/b&gt;해진다. 클럭 속도를 높이면 분명 CPU를 빠르게 만들 수는 있다. &lt;b&gt;하지만 클럭 속도만으로는 CPU 성능을 올리느데 한계&lt;/b&gt;가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;코어와 멀티코어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;클럭 속도 이외에 CPU 성능을 높이는 방법&lt;/b&gt;은 &lt;b&gt;대표적으로 &lt;span style=&quot;color: #ee2323;&quot;&gt;CPU의 코어와 스레드 수&lt;/span&gt;를 늘리는 방법&lt;/b&gt;이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그렇다면 코어는 무엇인가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지의 &lt;b&gt;CPU는 명령어를 실행하는 부품으로 이해&lt;/b&gt;했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 &lt;b&gt;오늘날의 CPU&lt;/b&gt;는 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;CPU 내부&lt;/span&gt;에 &lt;span style=&quot;color: #ee2323;&quot;&gt;명령어를 실행하는 부품&lt;/span&gt;을 얼마든지 만들 수 있게 발전&lt;/b&gt;했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코어 (Core) : &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;명령어를 실행하는 부품&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU : 명령어를 실행하는 부품을 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;여러개 포함&lt;/span&gt;하는 부품으로 범위가 확장&lt;/b&gt;되었다. 즉, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;코어를 여러개 포함하는 부품.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 이미지를 참고하면 &lt;b&gt;오늘날의 CPU는 내부에 20개의 코어를 가지고 있다.&lt;/b&gt; 스레드는 아래에서 추가설명하겠다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;972&quot; data-origin-height=&quot;374&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgL08g/btsHqNRNJ3G/bDXw5QzCmfHVpFLVatj0B0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgL08g/btsHqNRNJ3G/bDXw5QzCmfHVpFLVatj0B0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgL08g/btsHqNRNJ3G/bDXw5QzCmfHVpFLVatj0B0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgL08g%2FbtsHqNRNJ3G%2FbDXw5QzCmfHVpFLVatj0B0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;574&quot; height=&quot;221&quot; data-origin-width=&quot;972&quot; data-origin-height=&quot;374&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이처럼 &lt;b&gt;코어를 여러개 포함하고 있는 CPU&lt;/b&gt;를 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;멀티코어 CPU&lt;/b&gt;&lt;/span&gt; or &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;멀티코어 프로세서&lt;/b&gt;&lt;/span&gt;라고 부른다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이는 CPU 내부에 명령어를 처리하는 일꾼이 20명 있는 것 과 동일하다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;가령 클럭 속도가 2.4GHz 단일코어 VS 클럭 속더가 1.9GHz인 &lt;b&gt;듀얼 코어를 비교하면 후자가 성능이 더 좋다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;CPU 안에 코어가 몇 개인가에 따라 싱글, 듀얼, 쿼드, 옥타, 데카코어 등으로 부른다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;그렇다면 코어를 100개까지 늘리면 CPU 성능이 100배로 빨라질까??? -&amp;gt; No&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;코어마다 &lt;span style=&quot;color: #ee2323;&quot;&gt;처리할 연산이 적절히 분배&lt;/span&gt;되지 안흐면 코어 수에 비례하여 연산 속도가 증가하지 않는다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또한&lt;b&gt; 작업량보다 코어 수가 지나치게 많아도 성능에는 크게 영향이 없다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;100인분 도시락을 1명의 요리사가 만드는것보다는 10명의 요리사가 만드는게 빠르다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하지만, 4인분의 도시락을 10명의 요리가사 만다는게 5명의 요리사가 만드는 것보다 특별히 더 빠르지 않는 것과 비슷하다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;중요한 것은 &lt;b&gt;코어마다 처리할 명령어를 &lt;span style=&quot;color: #ee2323;&quot;&gt;얼마나 적절하게 분배&lt;/span&gt;하느냐에 따라 연산 속도는 크게 달라진다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;스레드와 멀티스레드&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;많은 사람이 암기하듯 외우는 스레드는 &quot;실행 흐름의 단위&quot;이다.&amp;nbsp;&lt;br /&gt;&lt;b&gt;하지만 CPU에서 사용되는 스레드와 프로그래밍에서 사용되는 스레드는 의미가 다르다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;앞으로 스레드는 아래와 같이 기억하자.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CPU에서 사용되는&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; 하드웨어적 스레드&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;프로그램에서 사용되는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;소프트웨어적 스레드&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하드웨어적 스레드 (논리 프로세서)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하드웨어적 스레드를 &lt;b&gt;정의&lt;/b&gt;하면 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;하나의 코어가 동시에 처리하는 명령어 단위&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;지금까지 알고 있던 CPU는 1코어 1스레드 CPU였다. 즉, 코어가 하나이고, 한번에 하나씩 명령어를 실행하는 CPU라고 생각했다.&lt;br /&gt;(뒤에서도 설명하겠지만, &lt;span style=&quot;color: #ee2323;&quot;&gt;실행 흐름의 단위라고만 암기한다면&lt;/span&gt; 1코어 1스레드 CPU가 여러 스레드로 만들어진 프로그램을 실행할 수 있다는 말을 이해하기 어려워질 수 있다.)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;하지만,&amp;nbsp;&lt;span style=&quot;color: #000000;&quot;&gt;여러 스레드를 지원하는 &lt;span style=&quot;color: #ee2323;&quot;&gt;CPU는 하나의 코어로도 여러 개의 명령어를 동시에 실행&lt;/span&gt;할 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 8코어 16스레드는 하나의 코어당 2개의 스레드를 처리한다는 뜻이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 이미지의 20코어 28스레드는 명령어를 실행하는 부품이 20개 이고, 1번의 28개의 명령어를 처리할 수 있는 CPU를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 20코어 28스레드는 어떻게 설명이 가능한가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 CPU 제조사에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;비대칭적 스레드 분배&lt;/b&gt;&lt;/span&gt;를 통해 CPU를 제조했기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;일부 코어는 두 개의 스레드를 처리할 수 있고, 나머지 코어는 하나의 스레드만 처리할 수 있습니다. 예를 들어, 20코어 중 14개의 코어가 &lt;b&gt;하이퍼스레딩&lt;/b&gt;을 지원하고, 나머지 6개 코어는 단일 스레드만 처리할 수 있습니다. 이렇게 되면 14*2 + 6 = 28스레드가 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;여기서 &lt;b&gt;하이퍼스레딩이란 인텔의 멀티스레드 기술을 의미한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 &lt;b&gt;하나의 코어로 여러 명령어를 동시에 처리&lt;/b&gt;하는 CPU를 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;멀티스레드 CPU&lt;/b&gt;&lt;/span&gt; or &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;멀티스레드 프로세서&lt;/b&gt;&lt;/span&gt;라고 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;소프트웨어적 스레드&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;하나의 프로그램에서 독립적으로 실행되는 단위를 의미&lt;/b&gt;&lt;/span&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;프로그래밍 언어나 운영체제를 학습할때 접하는 스레드는 보통 소프트웨어적 스레드를 의미&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;대표적인 예시로 워드 프로세서 프로그램에서 입력을 받은 내용을 화면에 보여주는 기능, 맞춤법을 검사하는 기능, 입력한 내용을 수시로 저장하는 기능을 각각의 스레드로 만들면 동시에 실행 할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1322&quot; data-origin-height=&quot;614&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ybvfj/btsHpb0ZwIC/Z7bdztY2wNxXVkbY8eRyLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ybvfj/btsHpb0ZwIC/Z7bdztY2wNxXVkbY8eRyLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ybvfj/btsHpb0ZwIC/Z7bdztY2wNxXVkbY8eRyLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYbvfj%2FbtsHpb0ZwIC%2FZ7bdztY2wNxXVkbY8eRyLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;593&quot; height=&quot;275&quot; data-origin-width=&quot;1322&quot; data-origin-height=&quot;614&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;정리&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CPU에서 사용되는&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;하드웨어적 스레드&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;하나의 코어가 동시에 처리하는 명령어 단위.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;프로그램에서 사용되는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;소프트웨어적 스레드&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;하나의 프로그램에서 독립적으로 실행되는 단위.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;명령어를 실행할 수 있는 하드웨어 부품이 CPU 안에 2개 이상 들어있는 CPU &lt;span style=&quot;color: #ee2323;&quot;&gt;멀티코어 프로세서&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt; 하나의 코어로 여러개의 명령어를 동시에 실행할 수 있는 CPU&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;멀티스레드 프로세서&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;실행 흐름의 단위라고만 암기한다면&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;1코어 1스레드 CPU가 여러 스레드로 만들어진 프로그램을 실행할 수 있다는 말을 이해하기 어려워질 수 있다. 따라서 &lt;span style=&quot;color: #ee2323;&quot;&gt;하드웨어적 스레드와 소프트웨어적 스레드를 구분하여 기억&lt;/span&gt;하는 것이 좋다.&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;멀티스레드 프로세서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 코어로 명령어를 동시에 처리하는 CPU.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 가능케하는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;핵심 이유는 레지스터&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램 카운터가 2개이면 가져올 명령어 주소를 2개 저장할 수 있고, 스택 포인터가 2개이면 2개의 스택을 관리할 수 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 명령어를 실행하기 위해 레지스터 세트가 하나 필요하다고 가정하면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레지스터 세트가 2개면 2개의 명령어를 동시에 실행할 수 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하드웨어적 스레드를 이용하면 하나의 코어로 여러 명령어를 동시에 처리할 수 있다고 했다. 그러나&lt;b&gt; 메모리 입장&lt;/b&gt;에서 보면 하드웨어적 스레드는 마치 한번에 하나의 명령어를 처리하는 CPU나 다름없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 2코어 4스레드 CPU는 한번에 4개의 명령어를 처리할 수 있는데 프로그램 입장에서 봤을때는 한 번에 하나의 명령어를 처리하는 CPU가 4개 있는것 처럼 보인다는 것이다. 따라서 &lt;b&gt;하드웨어 스레드를 논리적 프로세서라고 부르기도 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5-2 명령어 병렬 처리 기법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빠른 CPU를 만들기 위해 클럭 속도, 멀티 코어, 멀티 스레드를 지원하는 CPU를 만드는 것도 중요하지만, &lt;b&gt;CPU가 놀지 않고 시간을 알뜰하게 쓰면서 작동하게 만드는 것도 중요&lt;/b&gt;하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;명령어를 동시에 처리하여 CPU를 한시도 쉬지 않고 작동시키는 방법을 &lt;span style=&quot;color: #ee2323;&quot;&gt;명령어 병렬 처리 기법&lt;/span&gt;이&lt;/b&gt;라 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어 병렬 처리 기법에는 대표적으로 아래 3가지 방법이 존재한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;명령어 파이프 라이닝&lt;/li&gt;
&lt;li&gt;슈퍼스칼라&lt;/li&gt;
&lt;li&gt;비순차적 명령어 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;명렁어 파이프 라이닝&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어를 처리하는 과정을 클럭 단위로 나누어 보면 일반적으로 아래와 같이 나눌 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;명령어 인출&lt;/li&gt;
&lt;li&gt;명령어 해석&lt;/li&gt;
&lt;li&gt;명령어 실행&lt;/li&gt;
&lt;li&gt;결과 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 &lt;b&gt;중요한점은 같은 단계가 겹치지만 않는다면 CPU&lt;/b&gt;는 &lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;각 단계를 동시에 실행할 수 있다&lt;/b&gt;&lt;/span&gt;는 것이다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU는 &lt;b&gt;명령어를 인출하는 동안&lt;/b&gt;에 다른 &lt;b&gt;명령어를 실행&lt;/b&gt;할 수 있고 한 &lt;b&gt;명령어가&lt;/b&gt; &lt;b&gt;실행되는 동안&lt;/b&gt;에 &lt;b&gt;연산 결과를 저장&lt;/b&gt;할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마치 &lt;b&gt;공장 생산라인과 같이 명령어들을 명령어 파이프라인에 넣고 동시에 처리하는 기법&lt;/b&gt;을 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;명령어 파이프라이닝&lt;/b&gt;&lt;/span&gt;이라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 높은 성능 가져다 주긴 하지만, 성능 향상에 시래하는 &lt;b&gt;파이프라인 위험이란 상황이 존재&lt;/b&gt;한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1470&quot; data-origin-height=&quot;936&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/N7Mc1/btsHqIQyiyP/6K0VIgbuShxC9Ize54Py70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/N7Mc1/btsHqIQyiyP/6K0VIgbuShxC9Ize54Py70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/N7Mc1/btsHqIQyiyP/6K0VIgbuShxC9Ize54Py70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FN7Mc1%2FbtsHqIQyiyP%2F6K0VIgbuShxC9Ize54Py70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;511&quot; height=&quot;325&quot; data-origin-width=&quot;1470&quot; data-origin-height=&quot;936&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이프라인 위험에는 크게 3가지가 존재한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 위험
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;명령어 간의 데이터 의존성에 의해 발생.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;제어 위험
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램 카운터의 갑작스러운 변화에 의해 발생.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;구조적 위험
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;명령어를 실행하는 과정에서 서로 다른 명령어가 동시에 ALU, 레지스트 등과 같은 CPU 부품을 사용하려고 할때 발생.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;슈퍼스칼라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CPU 내부에 여러 개의 명령어 파이프라인을 포함한 구조&lt;/b&gt;를 &lt;b&gt;슈퍼스칼라&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공장 생산 라인을 여러개 두는 것을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;슈퍼스칼라 구조로 명령어 처리가 가능한 CPU를 &lt;b&gt;슈퍼스칼라 CPU&lt;/b&gt; or &lt;b&gt;슈퍼스칼라 프로세서&lt;/b&gt;라고 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식을 차용한 CPU는 파이프라인 위험을 방지하기 위해 고도로 설계되어야 한다. 파이프라인이 늘어날 수록 파이프라인 위험이 증가하기 때문이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1472&quot; data-origin-height=&quot;1102&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brLnaV/btsHqrarDwF/o8Pp7xZxvo1Ay59lGqXMq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brLnaV/btsHqrarDwF/o8Pp7xZxvo1Ay59lGqXMq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brLnaV/btsHqrarDwF/o8Pp7xZxvo1Ay59lGqXMq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrLnaV%2FbtsHqrarDwF%2Fo8Pp7xZxvo1Ay59lGqXMq0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;486&quot; height=&quot;364&quot; data-origin-width=&quot;1472&quot; data-origin-height=&quot;1102&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;비순차적 명령어 처리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어 파이프라이닝, 슈프스칼라는 &lt;b&gt;모두 명령어의 순차적인 처리를 상정한 방법&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 이미지를 참고해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3번 명령어는 1번 2번 명령어에 대한 의존성이 있다. 즉 1 2번 명령어 실행이 끝날때까지 기다려야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 3번 명령어 와 같이 뒤의 명령어 순서를 바꾸어 실행해도 크게 문제될 것이 없는 명령어 실행을 뒤로 미룬다면?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 &lt;b&gt;명령어를 순차적으로 실행하지 않고 순서를 바꿔도 실행해도 무방한 명령어를 먼저 실행하여 명령어 파이프라인이 멈추는 것을 방지하는 기법&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;비순차적 명령어 처리&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1506&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vFR2u/btsHpKPjNJy/ze9tw4jJi3ITn5QFUR7NgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vFR2u/btsHpKPjNJy/ze9tw4jJi3ITn5QFUR7NgK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vFR2u/btsHpKPjNJy/ze9tw4jJi3ITn5QFUR7NgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvFR2u%2FbtsHpKPjNJy%2Fze9tw4jJi3ITn5QFUR7NgK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;511&quot; height=&quot;204&quot; data-origin-width=&quot;1506&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1484&quot; data-origin-height=&quot;660&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brfksO/btsHo9Ch7XD/nr2QkEJapXno2KAZk410t0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brfksO/btsHo9Ch7XD/nr2QkEJapXno2KAZk410t0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brfksO/btsHo9Ch7XD/nr2QkEJapXno2KAZk410t0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrfksO%2FbtsHo9Ch7XD%2Fnr2QkEJapXno2KAZk410t0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;467&quot; height=&quot;208&quot; data-origin-width=&quot;1484&quot; data-origin-height=&quot;660&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;5-3 CISC와 RISC (현대 CPU의 주요 설계 방식 CISC -&amp;gt; RISC)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명렁어 파이프라이닝과 슈퍼스칼라가 적용된 CPU는 명령어가 이 구조에 최적화 되어있어한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 이러한 &lt;b&gt;기법을 효과적으로 사용&lt;/b&gt;하려면 &lt;b&gt;CPU가 인출하고 실행하는 명령어가 파이프라이닝 하기 쉬어야 한다&lt;/b&gt;는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;명령어 집합&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU는 명령어를 실행한다. 하지만 모든 CPU가 이해하고 실행하는 명령어는 다 똑같이 생기지 않았다. 제소사 별로 규격 기능 만듦새가 다 다르기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CPU마다 명령어의 생김새 연산, 주소 지정 방식 등 차이&lt;/b&gt;가 있는데 &lt;b&gt;CPU가 이해할 수 있는 명령어들의 모음&lt;/b&gt;을 &lt;b&gt;명령어 집합&lt;/b&gt; or &lt;b&gt;명령어 집합 구조&lt;/b&gt; &lt;b&gt;ISA&lt;/b&gt;라고 부른다. 즉, &lt;b&gt;CPU마다 ISA가 다를 수 있다.&lt;/b&gt; (인텔 CPU 컴퓨터에서 만든 실행 파일을 아이폰에 옮기면 특별한 설정 없이 바로 실행할 수 없다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어를 읽기 편한 현태로 표현한 언어를 어셈블리어라고 했다. ISA가 다르다는건 CPU가 이해할 수 있는 명령어가 다르다는 뜻이고 명령어가 달라지면 어셈블리어도 달라진다. 다시 말해 같은 소스 코드로 만든 프로그램이라 할지라도 ISA가 다르면 CPU가 이해할 수 있는 명령어도 어셈블리어도 달라진다는 뜻이다. (&lt;b&gt;동일한 소스코드를 윈도우 환경으로 패키징하면 MAC OS에서 실행 시킬 수 없는 이유&lt;/b&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ISA는 CPU의 언어이자 하드웨어가 소프트웨어를 어떻게 이해할지에 대한 &lt;span style=&quot;color: #ee2323;&quot;&gt;약속&lt;/span&gt;&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;CISC (Complex Instruction Set Computer)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;복잡한 명령어 집합을 활용하는 컴퓨터&lt;/b&gt;를 의미한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어의 형태와 크기가 다양한 &lt;b&gt;가변 길이 명령어&lt;/b&gt;를 활용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리를 아끼며 개발하는 시기에 유행했으나, 명령어의 크기와 실행되기까지의 시간이 일정하지 않는다는 단점이있다. 따라서 효율적으로 파이프라인을 이용한 명령어를 처리할 수 없었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;명령어의 규격화가 어려워 파이프라이닝에 적합하지 않았다&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RISC (Reduced Instruction Set Computer)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;CISC의 단점을 보완한 상위 호환의 개념이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;CISC오 &lt;b&gt;달리 짧고 규격화된 명령어를 1클럭 내외로 실행되는 명령어를 지향&lt;/b&gt;한다는 의미를 가지고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;고정 길이 명령어&lt;/b&gt;를 활용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;명령어가 규격화 되어있고 하나의 명령어가 1클럭 내외로 실행된다. RISC는 &lt;b&gt;메모리 접근을 단순화, 최소화하는 대신 레지스터를 적극적으로 활용&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;CISC보다 레지스터 연산이 많고 범용 레지스터의 갯수가 많다. 다만 명령어가 적기 때문에 CISC보다 많은 명령으로 프로그램을 작동 시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;즉, RISC는 &lt;b&gt;짧고 규격화된 고정 길이 명령어 집합을 사용하여 파이프라이닝 하기 쉬운 이점&lt;/b&gt;이 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;06. 메모리와 캐시 메모리&lt;/h3&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;6-1  RAM의 특징과 종류&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;RAM&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;RAM에는 실행할 프로그램의 명령어와 데이터가 저장된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;RAM은 &lt;b&gt;전원을 끄면 명령어와 데이터가 모두 날아가버리는&lt;/b&gt; &lt;b&gt;휘발성 저장 장치&lt;/b&gt;이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;반대로 HDD SSD 같은 &lt;b&gt;보조기억장치&lt;/b&gt;가 &lt;b&gt;비휘발성 저장 장치&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CPU는 보조기억장치에 직접 접근하지 못한다.&lt;/b&gt; 일반적으로 &lt;b&gt;보조 기억 장치&lt;/b&gt;에는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;보관할 대상&lt;/b&gt;&lt;/span&gt;을 저장하고 &lt;b&gt;RAM&lt;/b&gt;에는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;실행할 대상을 저장&lt;/b&gt;&lt;/span&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RAM의 용량와 성능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RAM의 용량이 적다면 CPU가 실행하고자하는 프로그램을 보조기억장치에서 꺼내오는 작업이 필요하고, 이게 잦다면 당연히 성능이 느려질 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &lt;b&gt;일반적으로 RAM의 용량이 크면 많은 프로그램을 동시에 실행하는데 유리&lt;/b&gt;하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약, RAM의 용량이 무지막지하게 크다면? 프로그램 실행 속도도 그와 비례하여 빨라질까? -&amp;gt; No&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;용량이 커짐에 따라 실행속도가 빨라지긴 하지만, 필요 이상으로 커졌을땐 속도가 이에 비례하여 증가하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 대한 예시로 책에 빗대어 생각해볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보조기억장치가 책이 꽂혀있는 책장이라면, RAM은 책을 읽을 수 있는 책상과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책 100권 이상 올려놓을 수 있는 책상에서 책을 읽든, 1000권 이상 올려놓을 수 있는 책상에서 책을 읽든 간에 책장을 오고가는 시간에는 큰 차이가 없는 것과 비슷하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RAM의 종류&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RAM의 종류는 크게 아래 4가지이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DARM (Dynamic RAM)&lt;/li&gt;
&lt;li&gt;SRAM (Static RAM)&lt;/li&gt;
&lt;li&gt;SDRAM (Synchronous Dynamic RAM)&lt;/li&gt;
&lt;li&gt;DDR SDRAM (Double Data SDRAM)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;DRAM&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동적 램이란 의미로, 저장된 데이터가 동작으로 변하는(사라지는) RAM을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DRAM은 시간이 지나면 저장된 데이터가 점차 사라지는 RAM이다. 이에 &lt;b&gt;데이터 소멸을 막기 위해 일정 주기로 데이터를 재활성&lt;/b&gt;(다시 저장)해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 단점에도 불구하고 일반적인 메모리는 DRAM이다. &lt;b&gt;소비 전력이 상대적으로 낮고, 저렴하며 집적도가 높기 때문에 대용량으로 설계하기 용이하기 때문&lt;/b&gt;이다. (집적도 === 더 작고 뺵빽하게 만들 수 있다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;SRAM&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정적 램이란 의미로, 저장된 데이터가 변하지 않는 RAM을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 데이터 재활성화 단계가 필요하지 않으므로 &lt;b&gt;DRAM보다 속도가 더 빠르다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정적 램이라고 해도 전원이 공급되지 않으면 저장된 데이터가 날라간다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SRAM은 &lt;b&gt;집적도가 낮고, 소비전력도 크며, 가격이 더 비싸다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &lt;b&gt;대용량으로 만들어 질 필요는 없지만 속도가 빨라야하는 저장 장치&lt;/b&gt;, 가령 &lt;b&gt;캐시 메모리&lt;/b&gt; 등에 사용이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;SDRAM&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DRAM과 SRAM의 &lt;b&gt;합성어가&lt;span style=&quot;color: #ee2323;&quot;&gt; 아니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클럭 신호와 동기화된 &lt;b&gt;발전된 DRAM&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;클럭 신호와 동기화 되어있다는 의미&lt;/b&gt;는 &lt;b&gt;클럭 타이밍에 맞춰 CPU와 정보를 주고 받을 수 있음을 의미&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;DDR SDRAM&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;최근 가장 널리 사용되는 RAM&lt;/b&gt;으로 &lt;b&gt;대역폭을 넓혀 속도를 빠르게 만든 SDRAM&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;대역폭(Data Rate)&lt;/b&gt;&lt;/span&gt;란, &lt;b&gt;데이터를 주고 받는 길의 너비를 의미&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;흔히, 자동차 도로에 비유를 하는데, CPU와 한 클럭에 하나씩 정보를 주고받는 SDRAM과 비교했을때&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;한 클럭에 2개씩, 한 클럭에 4개씩... 16개씩 주고 받는 길이 확장된다고 이해하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;DDR2 RAM, DDR3 RAM, DDR4 RAM, DDR5 RAM... 등이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;6-2&amp;nbsp; 메모리의 주소 공간&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;물리 주소와 논리 주소&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CPU와 실행중인 프로그램은 현재 메모리&lt;/b&gt; 몇 번지에 무엇이 저장되어 있는지 다 알고 있을까? -&amp;gt; No&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;메모리에 저장된 정보는 시시각각 변하기 때문&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;같은 프로그램을 실행하다고 해도 적재되는 메모리주소는 달라 질 수 있으며, 실행되지 않는 프로그램은 언제든지 삭제될 수 있기 때문&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;CPU와 실행중인 프로그램이 이해하는 주소는 무엇&lt;/b&gt;&lt;/span&gt;일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물리 주소 - 정보가 &lt;b&gt;실제로 저장된 하드웨어상의 주소.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;논리 주소&lt;/b&gt;&lt;/span&gt; - &lt;b&gt;CPU와 실행 중인 프로그램이 사용하는 주소&lt;/b&gt;로 실행 중인 프로그램 각각에게 부여된 0번지부터 시작되는 주소를 의미.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리 일일이 모든 사람이 IP 번호를 외울 수 없어 사용하는 도메인 주소나 도로명주소를 사용하는 이유와 비슷하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국에는 CPU와 메모리가 상호작용하기 위해선 &lt;b&gt;논리 주소와 물리 주소 간의 &lt;span style=&quot;color: #ee2323;&quot;&gt;변환&lt;/span&gt;&lt;/b&gt;이 이루어져야 한다. 따로 국밥이 될 수 는 없으니까 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 변환은 CPU와 주소 버스 사이에 위치한 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;메모리 관리 장치&lt;/span&gt; (MMU, Memory Management Unit)이라는 하드웨어에 의해 수행&lt;/b&gt;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MMU는 &lt;b&gt;CPU가 발생시킨 논리 주소에 베이스 레지스터 값을 더해 논리 주소를 물리 주소로 변환&lt;/b&gt;하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;베이스 레지스터는 프로그램의 가장 작은 물리 주소, 즉 프록램의 첫 물리 주소를 저장하며&lt;br /&gt;논리 주소는 프로그램의 시작점으로부터 떨어진 거리를 의미하기도 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1516&quot; data-origin-height=&quot;684&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k6c5a/btsHuqJg5Oo/KzlfpXlxIECJKRo8LqQKRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k6c5a/btsHuqJg5Oo/KzlfpXlxIECJKRo8LqQKRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k6c5a/btsHuqJg5Oo/KzlfpXlxIECJKRo8LqQKRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk6c5a%2FbtsHuqJg5Oo%2FKzlfpXlxIECJKRo8LqQKRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;594&quot; height=&quot;268&quot; data-origin-width=&quot;1516&quot; data-origin-height=&quot;684&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;메모리 보호 기법&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아래 명령어와 같이 프로그램의 &lt;b&gt;논리 주소 영역을 벗어난 명령은 실행되어서는 안된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;메모장 명령어가 브라우저에 값을 저장하고 삭제하는 일은 일어나서는 안되는 명령이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1482&quot; data-origin-height=&quot;716&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s33NL/btsHtvSnUxu/AnFnsb2SmvhuoSrD0YkO7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s33NL/btsHtvSnUxu/AnFnsb2SmvhuoSrD0YkO7K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s33NL/btsHtvSnUxu/AnFnsb2SmvhuoSrD0YkO7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs33NL%2FbtsHtvSnUxu%2FAnFnsb2SmvhuoSrD0YkO7K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;605&quot; height=&quot;292&quot; data-origin-width=&quot;1482&quot; data-origin-height=&quot;716&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 명령를 보호하는 역할은 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;한계 레지스터&lt;/span&gt;가 담당&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU는 &lt;b&gt;메모리에 접근하기 전에 접근하고자하는 논리 주소가 한계 레지스터 보다 작은지를 &lt;span style=&quot;color: #ee2323;&quot;&gt;항상 검사&lt;/span&gt;&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 CPU가 한계 레지스터보다 높은 논리 주소에 접근하려고 하면&lt;b&gt; 인터럽트(트랩)을 발생시켜 실행을 중단&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 방식으로 실행 중인 프로그램의 독립적인 실행 공간을 확보하고 &lt;b&gt;하나의 프로그램이 다른 프로그램을 침범하지 못하게 보호&lt;/b&gt;할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1516&quot; data-origin-height=&quot;634&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7pSLB/btsHu7oQz5p/F9755fLecby8U3xxFV35qk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7pSLB/btsHu7oQz5p/F9755fLecby8U3xxFV35qk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7pSLB/btsHu7oQz5p/F9755fLecby8U3xxFV35qk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7pSLB%2FbtsHu7oQz5p%2FF9755fLecby8U3xxFV35qk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;633&quot; height=&quot;265&quot; data-origin-width=&quot;1516&quot; data-origin-height=&quot;634&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;6-3&amp;nbsp;  캐시 메모리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU는 프로그램을 실행하면서 메모리에 저장된 데이터를 빈번하게 사용한다. 하지만 CPU가 메모리에 접근하는 시간은 CPU의 연산속도보다 느리다. &lt;b&gt;(CPU 메모리 접근 시간 &amp;gt;&amp;gt; CPU 연산속도)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CPU의 연산속도가 아무리 빠르다해도 메모리에 접근하는 시간이 느리면 이점이 없다.&lt;/b&gt; 이를 &lt;b&gt;극복하기 위해 나온 저장 장치&lt;/b&gt;가 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;캐시 메모리&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;저장 장치 계층 구조&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 사용자들은 빠르고 동시에 용량이 큰 저장 장치를 원한다. 하지만 양립하기 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저장 장치는 일반적으로 아래 명제를 따른다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;CPU와 가까운 저장 장치는 빠르고, 멀리 있는 저장 장치는 느리다.&lt;/b&gt;&lt;br /&gt;&lt;b&gt;속도가 빠른 저장 장치는 저장 용량이 적고, 가격이 비싸다.&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저장 장치들을 &lt;b&gt;CPU에 얼마나 가까운가를 기준&lt;/b&gt;으로 아래 계층으로 나눌 수 있는데, 이를 &lt;b&gt;저장 장치 계층 구조&lt;/b&gt;라 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1444&quot; data-origin-height=&quot;564&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vwdl6/btsHtYGsGq4/t1gh7bSflWJEp8oqUDavmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vwdl6/btsHtYGsGq4/t1gh7bSflWJEp8oqUDavmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vwdl6/btsHtYGsGq4/t1gh7bSflWJEp8oqUDavmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fvwdl6%2FbtsHtYGsGq4%2Ft1gh7bSflWJEp8oqUDavmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;558&quot; height=&quot;218&quot; data-origin-width=&quot;1444&quot; data-origin-height=&quot;564&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;캐시 메모리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU가 메모리에 접근하느 속도는 레지스터에 접근하는 속도 보다 느리다. 그럼에도 CPU는 빈번하게 메모리에 접근해야만 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 배경으로 등장한 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;캐시 메모리&lt;/b&gt;&lt;/span&gt;는 &lt;b&gt;CPU와 메모리 사이에 위치&lt;/b&gt;하고, &lt;b&gt;레지스터 보다 용량이 크고 메모리보다 빠른&lt;/b&gt; &lt;b&gt;SRAM 기반 저장 장치&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU === 집, 메모리는 === 대형 마트, 캐시 메모리 === 편의점 으로 예시를 들 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;편의점에 물건이 있으면 집에서 가까운 곳에서도 물건을 구할 수 있는 것이고, 편의점에 없으면 이 보다 먼 대형마트에서 물건을 구하는 경우와 비슷하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 캐시 메모리들은 CPU와 가까운 순서대로 계층을 구성하는데, 가장 가까운 캐시 메모리는 L1, (level 1) L2, L3 캐시가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 L1, L2 캐시는 CPU 내부에 L3 캐시는 CPU(여기선 코어) 외부에 위치 해있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1532&quot; data-origin-height=&quot;430&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d6nebx/btsHu3UqsiL/CK7ru37On3RL0p3KAts6UK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d6nebx/btsHu3UqsiL/CK7ru37On3RL0p3KAts6UK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d6nebx/btsHu3UqsiL/CK7ru37On3RL0p3KAts6UK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd6nebx%2FbtsHu3UqsiL%2FCK7ru37On3RL0p3KAts6UK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;610&quot; height=&quot;171&quot; data-origin-width=&quot;1532&quot; data-origin-height=&quot;430&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;L1, L2 캐시는 각각의 코어 마다 고유한 캐시 메모리로 할당이 되고, L3는 여러 코어가 공유하는 형태로 사용이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 저장 장치 계층 구조를 확장하면 아래와 같이 표현할 수 도 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1430&quot; data-origin-height=&quot;792&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lGPCv/btsHubFEkpZ/bWKqmZy5DgTeIyCcK2qGK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lGPCv/btsHubFEkpZ/bWKqmZy5DgTeIyCcK2qGK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lGPCv/btsHubFEkpZ/bWKqmZy5DgTeIyCcK2qGK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlGPCv%2FbtsHubFEkpZ%2FbWKqmZy5DgTeIyCcK2qGK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;569&quot; height=&quot;315&quot; data-origin-width=&quot;1430&quot; data-origin-height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참조 지역성의 원리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시 메모리는 당연히! 메모리보다 용량이 작다. 그렇기에 메모리에 있는 모든 내용을 저장할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리가 보조 기억장치의 일부를 복사하여 저장하고 있는 것처럼&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시 메모리도 메모리의 일부를 복사하여 저장한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 캐시 메모리는 무엇을 저장할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보조 기억 장치는 &lt;b&gt;기억할 대상을 저장&lt;/b&gt;하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리는 &lt;b&gt;실행 중인 대상을 저장&lt;/b&gt;하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시 메모리는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;CPU가 사용할 법한 대상을 예측하여 저장&lt;/b&gt;&lt;/span&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 실제로 캐시 메모리에 저장된 데이터를 CPU가 활용하는 경우를 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;캐시 히트&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 반대의 경우를 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;캐시 미스&lt;/b&gt;&lt;/span&gt;라고 한다. 당연히, 캐시 미스가 많이 발생할 수록 성능은 떨어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시가 히트되는 비율을 캐시 적중률이라고 하며 아래와 같이 계산한다&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;캐시 히트 횟수 / (캐시 히트 횟수 + 캐시 미스 횟수)&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 &lt;b&gt;보통 사용하는 컴퓨터의 캐시 적중률은 85~ 95% 이상&lt;/b&gt;이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 캐시 메모리는 CPU가 사용할 법한 데이터를 어떻게 알 수 있을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시 메모리는 &lt;b&gt;한가지 원칙에 의해 메모리로부터 가져올 데이터를 결정한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;참조 지역성의 원리&lt;/span&gt; - CPU가 메모리에 접근할 때 주된 경향을 바탕으로 만들어진 원리&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;CPU는 최근에 접근했던 메모리 공간에 다시 접근하려는 경향이 있다(시간 지역성)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;CPU는 접근한 메모리 공간 근처를 접근하려는 경향이 있다 (공간 지역성)&lt;/b&gt;&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;07. 보조 기억 장치&lt;/h3&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;7-1 다양한 보조 기억 장치&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대표적인 보조 기억 장치로는 하드 디스크와 플래시 메모리가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;USB, SSD, SD 카드 간은 저장 장치를 플래시 메모리라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하드 디스크&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;자기적인 방식으로 데이터를 저장하는 보조 기억 장치&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;플래터, 스핀들, 헤드, 디스크 암으로 구성되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하드 디스크가 저장된 데이터에 접근하는 시간&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;탐색 시간&lt;/li&gt;
&lt;li&gt;회전 지연&lt;/li&gt;
&lt;li&gt;전송 시간&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글의 천재 엔지니어 중 한사람인 제프 딘은 과저 프로그래머가 꼭 알아야할 컴퓨터 시간들을 공개한 바가 있는데 아래는 일부를 발췌한 자료이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2011년 자료이며, 하드 디스크 성능이 많이 향상되었겠지만 생각보다 많은 시간이 걸린다는 것을 알 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1212&quot; data-origin-height=&quot;730&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCBl2S/btsHvt6ohC7/OC5BjzJW0yKnIjmruDBiN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCBl2S/btsHvt6ohC7/OC5BjzJW0yKnIjmruDBiN0/img.png&quot; data-alt=&quot;출처: https://velog.io/@mmodestaa/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Section-7.-%EB%B3%B4%EC%A1%B0%EA%B8%B0%EC%96%B5%EC%9E%A5%EC%B9%98&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCBl2S/btsHvt6ohC7/OC5BjzJW0yKnIjmruDBiN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCBl2S%2FbtsHvt6ohC7%2FOC5BjzJW0yKnIjmruDBiN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;579&quot; height=&quot;349&quot; data-origin-width=&quot;1212&quot; data-origin-height=&quot;730&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처: https://velog.io/@mmodestaa/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Section-7.-%EB%B3%B4%EC%A1%B0%EA%B8%B0%EC%96%B5%EC%9E%A5%EC%B9%98&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;플래시 메모리&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;전기적 데이터를 읽고 쓸 수 있는 반도체 기반의 저장 장치&lt;/b&gt;이다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;크게 NAND 플래시 메모리와 NOR 플래시 메모리가 존재한다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 중 대용량 저장장치로 사용되는 플래시 메모리는 NAND 플래시 메모리이다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;플래시 메모리는 셀 Cell 이라는 플래시 메모리에서 데이터를 저장하는 가장 단위가 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;셀이 모여 MB, GB TB 용량을 갖는 저장 장치가 되는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리에도 수명이 있는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플래시 메모리 뿐만 아니라 하드 디스크 또한 &lt;b&gt;수명이 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;한 셀에 일정 횟수 이상 데이터를 쓰고 지우면 그 셀은 더이상 데이터를 저장할 수 없어지기 때문&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;7-2 RAID의 정의와 종류&lt;/h4&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;1TB 하드 디스크 4개와 4TB 하드 디스크 1개를 사용하는게 더 나을까?&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결론적으로 1TB 하드 디스크 4개를 RAID로 구성하면 4TB 하드 디스크 1개의 성능과 안정성을 능가할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;RAID의 정의&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;구글, 아마존과 같은 글로벌 IT 기업의 서버를 관리한다고 생각해보자.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;엄청난 양의 데이터가 서버로 쏟아지고 개인 정보, 결제 정보 등 절대 잃어버리면 안되는 민감한 정보들도 쏟아지고 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;어떻게 이러한 정보를 안전하게 관리할 것인가?&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;이때 사용할 수 있는 방법 중 하나가 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;RAID&lt;/b&gt;&lt;/span&gt; (Redundant Array of Independent Disks)&lt;br /&gt;하드 디스크와 SSD를 사용하는 기술로 데이터의 안정성, 높은 성능을 위해 &lt;b&gt;여러개의 물리적인 보조기억장치를 마치 하나의 논리적 보조기억장치처럼 사용하는 기술이다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;RAID의 종류&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;RAID 구성 방법을 RAID 레벨이라 표현하는데, 관련 용어만 정리하고 RAID를 각각 어떻게 구성하는지는 책을 참고해보자.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;책에 있는 이미지와 어떠한 문제로 인해 탄생했는지 배경을 이해하면 이해하기 수월하다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;스트라이핑 (Striping)&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;데이터를 분산하여 저장함&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;저장된 데이터를 일고 쓰는 속도가 빨라진다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;패리티 비트 (Parity Bit)&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;오류를 복구하기 위한 정보&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;오류를 검출하는 패리티 비트&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;원래 패리티 비트는 오류 검출만 가능할 뿐 오류 복구는 불가능하다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;하지만 RAID에서는 패리티 값으로 오류 수정도 가능하다.구체적인 방법보다는 아래 2가지를 기억하자.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;RAID4 에서는 패리티 정보를 저장한 장치로서 나머지 장치들의 오류를 검출 복구한다.&lt;br /&gt;&lt;b&gt;패리티 비트는 본래 오류 검출용 정보지만, RAID에서는 오류 복구도 가능하다. ( 더 중요 )&lt;/b&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;[출처 : 혼공컴운 (저자: 강민철)_한빛 미디어 ]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;904&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6LEL9/btsHqNxvEYN/fYTzQCOXKw1f5cKJiDz1U1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6LEL9/btsHqNxvEYN/fYTzQCOXKw1f5cKJiDz1U1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6LEL9/btsHqNxvEYN/fYTzQCOXKw1f5cKJiDz1U1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6LEL9%2FbtsHqNxvEYN%2FfYTzQCOXKw1f5cKJiDz1U1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;308&quot; height=&quot;363&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;904&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>개발서적</category>
      <author>codermun</author>
      <guid isPermaLink="true">https://codermun-log.tistory.com/616</guid>
      <comments>https://codermun-log.tistory.com/616#entry616comment</comments>
      <pubDate>Wed, 15 May 2024 16:02:09 +0900</pubDate>
    </item>
    <item>
      <title>[혼자 공부하는 컴퓨터구조 + 운영체제] 2회독 정리</title>
      <link>https://codermun-log.tistory.com/615</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;01 . 컴퓨터 구조 시작하기&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1-1 실력 있는 개발자가 되기 위해 컴퓨터 구조를 알아야 하는 이유&amp;nbsp;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문제 해결의 실마리를 다양하게 찾을 수 있다. 단순 코드 개발뿐만이 아닌 다양한 문제를 스스로 해결 할 수 있다.&lt;/li&gt;
&lt;li&gt;성능, 용량, 비용을 결정 할 수 있게 된다. 단순 입출력을 넘어서 성능, 용량, 비용까지 고려하며 개발할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1-2 컴퓨터 구조의 큰 그림&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;컴퓨터 구조 지식은 크게 두 가지이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컴퓨터가 이해하는 정보&lt;/li&gt;
&lt;li&gt;컴퓨터의 네 가지 핵심 부품&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;컴퓨터가 이해하는 정보&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터는 0과 1로 표현된 정보만을 이해한다. 이 정보에는 크게 &lt;b&gt;데이터와 명령어&lt;/b&gt;가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터가 이해하는 숫자, 문자, 이미지 등 정적인 정보를 &lt;b&gt;데이터&lt;/b&gt;라 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 데이터를 움직이고 컴퓨터를 작동 시키는 정보를 &lt;b&gt;명령어&lt;/b&gt;라 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;명령어가 없으면 컴퓨터를 작동시킬 수 없기 때문에 명령어가 더 중요한 정보이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;숫자 1과 2는 데이터이며, 더하라, 1과 2를은 명령어이다. CPU에서 이와 같은 명령어를 읽고 실행하지 않는 한 우리는 3이라는 결과값을 볼 수 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;컴퓨터의 네 가지 핵심 부품&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중앙처리장치 (CPU : Central Processing Unit)&lt;/li&gt;
&lt;li&gt;주기억장치 (Main Memory)&lt;/li&gt;
&lt;li&gt;보조기억장치 (Secondary Storage)&lt;/li&gt;
&lt;li&gt;입출력장치 (I/O Device)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;CPU (Central Processing Unit)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;메모리에 저장된 명령어를 읽어 들이고, 읽어 들인 명령어를 해석하고 실행하는 부품.&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;CPU의 중요한 세 가지 구성요소는 아래와 같다.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;산술논리연산장치 (ALU : Arithmetic Logic Unit)&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;계산을 담당하는 부품으로 컴퓨터 내부의 대부분의 계산을 담당한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;레지스터 (Register)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CPU 내의 작은 임시 기억 장치로 프로그램을 실행하는 필요한 값들을 임시로 저장한다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;제어장치 (Control Unit)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;제어신호라는 전기신호를 내보내고 명령어를 해석하는 장치로 여기서의 제어신호랑 컴퓨터 부품을 관리하고 작동시키기 위한 일종의 전기 신호를 일컫는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;주기억장치 (메모리)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;현재 실행되는 프로그램의 명령어와 데이터를 저장하는 부품.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;프로그램이 실행되기 위해선 &lt;span style=&quot;color: #ee2323;&quot;&gt;반드시&lt;/span&gt; 메모리에 저장되어 있어야 한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 집주소를 찾아가듯이, CPU에서는 메모리에 접근하여 명령어를 읽어야하는데, &lt;br /&gt;저장된 값에 빠르고 효율적으로 접근하기 위해 &lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;주소라는 개념을 사용&lt;/span&gt;&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;메모리의 단점으로는 대표적으로 두 가지가 존재한다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가격이 비싸 저장 용량이 작다.&lt;/li&gt;
&lt;li&gt;전원이 꺼지면 저장된 내용을 잃는다. (휘발성)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;보조기억장치 (Secondary Storage)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;전원이 꺼져도 저장된 프로그램을 저장하는 부품이다.(비휘발성)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;메모리가 &lt;b&gt;현재 실행되는 프로그램&lt;/b&gt;을 저장한다면, 보조기억장치는 &lt;b&gt;보관할 프로그램&lt;/b&gt;을 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;HDD, SDD, USB, DVD, CD-ROM과같은 저장 장치를 보조기억장치라 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;입출력장치 (I/O Device)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마이크, 키보드, 스피커, 마우스처럼 컴퓨터 외부에 연결되어 컴퓨터 내부와 정보를 교환하는 장치.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;메인보드와 시스템 버스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위 네가지 핵심 부품은 모두 메인보드라는 판에 연결된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;메인보드를 마더보드라고도 부르며 이러한 부품들은 서로 정보를 주고 받을 수 있는데 &lt;b&gt;이러한 정보를 주고 받을 수 있는 통로&lt;/b&gt;를 &lt;b&gt;버스(bus)&lt;/b&gt;라고 부르며, 메인 보드 내의 &lt;b&gt;가장 중요한 버스로는 시스템 버스&lt;/b&gt;가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;시스템 버스는 아래 세 가지로 구성된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주소 버스 (Address Bus) - 주소를 주고 받는 통로&lt;/li&gt;
&lt;li&gt;데이터 버스 (Data Bus) - 명령어와 데이터를 주고 받는 통로&lt;/li&gt;
&lt;li&gt;제어 버스 (Control Bus) - 제어 신호를 주고 받는 통로&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;02. 데이터&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-1. 0과 1로 숫자를 표현하는 방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0과 1만을 이해하는 컴퓨터 7과 같은 숫자를 이해할 수 있는 이유는 이러한 값들을 모두 0과1로 표현 할 수 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;정보 단위&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터가 이해하는 가장 작은 정보 단위는 &lt;b&gt;비트(bit)&lt;/b&gt;다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;즉, 0과 1을 표현할 수 있는 가장 작은 정보 단위이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비트는 0과1 두 가지 상태만 표현할 수 있으며, 몇개의 정보를 표현할 수 있는지는 경우의수를 생각하면 쉽게 이해할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2비트는 2^2 4개의 정보를 표현할 수 있고 3비트는 2^3 8개의 정보를 표현할 수 있는 식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 비트로 프로그램은 이루어져있다. 그러나, 우리가 흔히 어떤 파일을 가르킬때 비트라는 표현보다는 &lt;b&gt;바이트&lt;/b&gt;라는 한 단계 큰 정보 단위를 주로 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바이트(Byte)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;여덟 개의 비트를 묶은&lt;/b&gt; 정보 단위.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 1 바이트 === 8비트와 같으므로 총 2^8 256개의 정보를 표현 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바이트보다 더 큰 단위로는 아래와 같은 것들이 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1 킬로바이트 (KB) === 1000 Byte&lt;/li&gt;
&lt;li&gt;1 메가바이트 (MB) === 1000 KB&lt;/li&gt;
&lt;li&gt;1 기가바이트 (GB) === 1000 MB&lt;/li&gt;
&lt;li&gt;1 테라바이트 (TB) === 1000 GB&lt;/li&gt;
&lt;li&gt;1 페타바이트 (PB) === 1000 TB ....&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;중요 정보 단위로 &quot;워드&quot; 라는 것도 존재한다.&lt;br /&gt;워드(Word)란 CPU가 한번에 처리할 수 있는 데이터 크기를 의미한다.&lt;br /&gt;만약 CPU가 한번에 16비트를 처리할 수 있다고 하면 1워드 === 16비트를 의미한다.&lt;br /&gt;&lt;br /&gt;현대 컴퓨ㅓ는 대부분 32비트 또는 64비트가 1워드인데 가령 intel CPU에서 보였던 x86 CPU는 32비트의 워드 CPU를 의미하며 x64 CPU는 64비트의 워드 CPU를 의미한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이진법&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그래서 7과 같은 숫자를 컴퓨터는 어떻게 이해할 수 있을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;수학에서 0과 1만으로 모든 숫자를 표현하는 방법을 이진법이라고 한다.&lt;br /&gt;기본적으로 이진법으로 컴퓨터에게 이해를 시킬 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이진법, 십진법, 십육진법 ... 등이 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;숫자 10을 이진수인지, 십진수인지를 컴퓨터는 어떻게 구분할까?&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이진수 끝에 아래첨자(2)를 붙히거나&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;192&quot; data-origin-height=&quot;58&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cyzMTt/btsHb41bEl3/D0qtRi3FhDDE1iKgVcLkq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cyzMTt/btsHb41bEl3/D0qtRi3FhDDE1iKgVcLkq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cyzMTt/btsHb41bEl3/D0qtRi3FhDDE1iKgVcLkq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcyzMTt%2FbtsHb41bEl3%2FD0qtRi3FhDDE1iKgVcLkq0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;86&quot; height=&quot;26&quot; data-origin-width=&quot;192&quot; data-origin-height=&quot;58&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이진수 앞에 0b를 붙힌다.&amp;nbsp; (0b1000 === 8)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이진수의 음수 표현&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;0과 1만으로 음수를 표현하는 방법 중 가장 널리 사용되는 방법은 &lt;b&gt;2의 보수를 구해 이 값을 음수로 간주하는 방법&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사전적 의미는 &quot;어떤 수를 그보다 큰 2^n에서 뺀 값&quot;을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(주입식으로는 &quot;모든 0과 1을 뒤집고 거이에 1을 더한 값&quot;으로 구할 수 있다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하지만 실제로 보수표현에는 한계가 있기에 컴퓨터 내부에서 &lt;b&gt;어떤 수가 양수인지 음수인지를 구분하기 위한 플래그(Flag)&lt;/b&gt;를 사용하여 컴퓨터는 어떠 수가 음수인지 양수인지를 정확히 인지 할 수 있다, 이후 레지스터를 다룰 때 또 등장한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;십육진법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이진수로 모든 숫자를 표현하다 보면 숫자의 길이가 너무 길어진다는 단점&lt;/b&gt;이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 이진법을 대신하여 십육진법도 자주 사용하는데 십육진법이 이진법을 대신해서 사용되는 &lt;b&gt;핵심 이유는 이진수를 십육진수로 십육진수를 이진수로 변환하기 쉽기 때문&lt;/b&gt;이다.&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-2. 0과 1로 문자를 표현하는 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;문자 집합과 인코딩&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;0과 1을 문자로 표현하는 방법에 대해 알기 전에 아래 세 가지 용어를 이해해보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문자집합 (Character Set)&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컴퓨터가 인식하고 표현할 수 있는 문자의 모음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;문자 인코딩 (C.. Encoding)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문자를 0과 1로 &lt;b&gt;컴퓨터가 이해할 수 있는 문자로&lt;/b&gt; 변환하는 과정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;문자 디코딩 (C.. Decoding)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;0과 1로 이루어진 문자 코드를 &lt;b&gt;사람이 이해할 수 있는 문자로&lt;/b&gt; 변환하는 과정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아스키 코드 (ASCII)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;128개의 고유한 수에 숫자를 일대일로 매핑한 초창기 문자 집합 중 하나이다. (아스키코드, UTF 등은 팀내에서 발표했던 자료를 추후 포스팅 하겠다)&lt;br /&gt;아스키 코드는 아메리칸 스탠다스 즉, 영어권 국가에서 한정하여 사용할 수 있는 문자 집합이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;결국, 한국을 포함한 영어권 외의 나라에서 자신들의 언어로 0과 1을 표현할 수 있는 고유한 문자 집합과 인코딩 방식이 필요해졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EUC-KR&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위와 같은 이유로 등장한 한글 문자 집합이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;한글은 다른 언어와 달리 두 가지 인코딩 방식이 존재한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;완성형 인코딩&lt;/li&gt;
&lt;li&gt;조합형 인코딩&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가 라는 문자를 1로 인코딩하는 방식을 완성형&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가 라는 문자를 &quot;ㄱ&quot;, &quot;ㅏ&quot; 등으로 나누어 초성, 중성, 종성에 해당하는 코드를 합하여 하나의 글자 코드로 만드는 인코딩 방식이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ECU-KR은 대표적인 완성형 인코딩 방식이다. 모두 결합된 한글 단어에 2바이트 킈의 코드를 부여한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하자면, ECU-KR은 한글을 2바이트 크기로 인코딩 할 수 있는 완성형 인코딩 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ECU-KR은 총 2,350개의 한글 단어를 표현할 수 있지만, 쀍, 쀓과 같은 글자는 표현할 수 없었다. 결국 모든 글자를 표현할 수 없었기에 MS에서 CP949라는 ECU-KR의 확장된 버전을 내놓았지만 이마저도 한글 전체를 표현하기에는 부족했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;유니코드와 UTF-8&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ECU-KR -&amp;gt; CP949 만으로는 모든 한글을 표현할 수 없는 한계가 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더욱이 언어별로 인코딩을 다르게해야하는 상황에서 다국어를 지원하는 프로그램은 지원하는 모든 나의 인코딩을 모두 알아야하는 번거로움이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 유니코드라는 문자 집합이 등장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;유니코드는 대부분의 나라의 문자, 특수문자, 화살표와 같은 이모티콘까지 코드로 표현할 수 있는 통일된 문자 집합으로 현대 문자를 표현할 때 가장 많이 사용되는 표준 문자 집합&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 유니코드는 여러 나라의 문자를 광범위하게 표현할 수 있는 통일된 문자 집합이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아스키코드, EUC-KR은 글자에 부여된 값을 그대로 인코딩 값으로 기준을 잡았는데,&amp;nbsp;&lt;br /&gt;유니코드는 위와 다르게 다양한 방법으로 인코딩을하는데 이러한 인코딩 방법으로 UTF-8, UTF-16, UTF-32등이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;즉, &lt;span style=&quot;color: #ee2323;&quot;&gt;UTF&lt;/span&gt;는 유니코드 문자에 부여된 값을 인코딩 하는 방식을 말한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UTF(Unicode Transformation Format) : 유니코드를 인코딩하는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이중 가장 대중적인 것 인코딩 방법은 UTF-8이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UTF-8은 통상 1~4바이트까지의 인코딩 결과를 만들어 내는데, 자세히 알고 싶다면 책을 읽어보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;아스키 코드로부터 시작해서 컴퓨터가 문자를 어떻게 0과 1로 이해하는지 플로우를 이해하는게 더 중요하다고 생각한다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;03. 명령어&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-1. 소스 코드와 명령어&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;컴퓨터는 명령어를 처리하는 기계&lt;/b&gt; 라고 표현할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어는 컴퓨터를 실직적으로 작동시키는 중요한 정보인데 C, Java와 같은 프로그래밍 언어로 만든 소스 코드는 무엇일까?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;컴퓨터는 이러한 프로그래밍 언어를 이해하고 있는걸까? -&amp;gt; No&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이해할 수 없다. 컴퓨터는 0과 1만을 이해할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 위와 같은 &lt;b&gt;모든 ~~~ 소스 코드는 컴퓨터 내부에서 명령어로 변환되는 과정을 거친다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;고급 언어와 저급 언어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자가 작성하는 프로그래밍 언어는 &lt;b&gt;사람이 이해하기 쉽게 만들어진 언어&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 언어를 &lt;b&gt;고급 언어라 부른다. &lt;/b&gt;반대로, &lt;b&gt;컴퓨터가 이해하고 실행할 수 있는 언어를 저급 언어라 부른다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;저급 언어는 명령어로 이루어져 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터가 이해하고 실행할 수 있는 언어는 오로지! 저급 언어 뿐이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 저급 언어에는 기계어와 어셈블리어가 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기계어 - 0과 1의 명령어 비트로 이루어진 언어&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1714975038084&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;8000 00b0 8100 2140 ........&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;어셈블리어 - 기계어를 읽기 편한 현태로 번역한 언어&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1714975090133&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], 1
....
ret&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그래서 왜 저급 언어를 알아햐 하나요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관찰할 일이 거의 없는 개발자도 있지만, 임베디드, 게임, 정보 보안 쪽 개발자는 이러한 어셈블리어를 매우 중요한 관찰의 대상으로 바라봐야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어셈블리어를 읽으면 컴퓨터가 프로그램을 어떤 과정으로 실행하는지, 즉 프로그램이 어떤 절차로 작동하는지를 가장 근본적인 단계에서부터 하나하나 추적하고 관찰할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개발자의 영역에 따라 저급 언어의 중요성은 달라질 수 있다. 그러나 고급 언어와 저급 언어의 차이를 이해하는 것은 개발 분야를 막론하고 매우 좋은 교양이기에 알아두는 것이 좋다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;컴파일 언어와 인터프리터 언어&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;개발자가 작성한 소스 코드는 결국 저급 언어로 변환된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이때 두 가지 방식으로 변환되는데 컴파일과 인터프리터 방식이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;컴파일 언어로 작성된 소스 코드는 컴파일러에 의해 저급 언어로 변환이 된다. 이 과정을 컴파일 이라 하고, 컴파일 결과로 저급 언어로 변환된 목적 코드가 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;인터프리터 언어로 작성 소스 코드는 인터프리터에 의해 저급 언어로 변환이 된다. 이때 인터프리터는 소스 코드를 한 줄 한줄 차례로 실행하면서 한 줄씩 저급 언어로 변환하여 실행한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;컴파일 언어와 인터프리터 언어, 칼로 자르듯이 구분될까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하나의 프로그래밍 언어가 반드시 둘 중 하나의 방식만으로 작동한다고 생각하는 것은 오개념이다. 컴파일이 가능한 언어라고해서 인터프리터가 불가능하거나, 인터프리터가 가능한 언어라고 해서 컴파일이 불가능한 것은 아니다.&lt;br /&gt;따라서, 칼로 자르듯 구분하기 보다는 &lt;b&gt;고급 언어가 저급 언어로 변환되는 대표적인 방법에는 컴파일 방식과 인터프리터 방식이 있다는 정도로 이해하자.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이를 이해하는데 더 도움이 되는 예시는 독일어를 모르는 친구에게 독일어로 쓰인 책을 설명해주는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;컴파일 언어로 독일어로 쓰인 책 전체를 한국어로 번역 책을 건네주는 방식이라면,&lt;br /&gt;인터프리터언어는 친구와 함께 한줄한줄 읽으면서 바로 번역해서 알려주는 방식과 같다.&lt;br /&gt;컴파일하는 과정을 거치고 안 거치고 등의 차이가 있지만, 한국어로 번역한 책을 건네주는 방식이 훨씬 빠르게 읽을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;목적 파일 vs 실행 파일&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;목적 코드로 이루어진 파일을 목적 파일.&lt;br /&gt;실행 코드로 이루어진 파일을 실행 파일이라고 부른다. 대표적으로 윈도우 .exe 확장자를 가진 파일이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;목적 파일과 실행 파일은 같은 의미일까? -&amp;gt; No&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;목적 코드가 실행 파일이 되기 위해서는 링킹 작업&lt;/b&gt;을 거처야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;A.c, B.c라는 두 개의 소스 코드를 작성했다고 가정해보자.&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;A.c 안에서는 &quot;OOO 더하기&quot;라는 기능이 구현되어있다.&lt;/li&gt;
&lt;li&gt;B.c 안에서는 A.c에 구현된 OOO 더하기 기능과 프로그래밍 언어가 기본으로 제공하는 화면 출력이라는 기능을 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이 들을 각각 컴파일하여 목적 코드를 생성하면 B.c는 저급 언어니까 바로 실행할 수 있을까? -&amp;gt; No&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;B.c에서는 존재하지 않는 OOO 더하기 기능을 어떻게 실행하는지 알지 못하기 때문이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 B.c를 실행하면 B.c에는 없는 외부 기능들, 즉, OOO 더하기 기능을 B.c와 연결짓는 작업이 필요한데 이러한 연결 작업을 링킹이라고 한다.&lt;br /&gt;이렇게&lt;b&gt; 링킹 작업까지 거치고 나면 비로소 하나의 실행 파일이 만들어진다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;03-2. 명령어의 구조&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;명령어는 연산 코드와 오퍼랜드로 구성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;연산 코드&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;명령어가 수행할 연산을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;연산 코드는 연산자라고도 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;연산 코드는 아래 가장 기본적인 연산 코드 유형 네 가지로 나눌 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 전송 : MOVE, STORE, LOAD, PUSH..&lt;/li&gt;
&lt;li&gt;산술/논리 연산 : ADD, DIVIDE, AND, OR, COMPARE ..&lt;/li&gt;
&lt;li&gt;제어 흐름 변경 : JUMP, HALT, CALL, RETURN ..&lt;/li&gt;
&lt;li&gt;입출력 제어 : READ, WRITE, TEST IO, START IO ...&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;오퍼랜드&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;연산에 사용될 데이터 또는 연산에 사용될 데이터가 지정된 위치를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;오퍼랜드는 피연산자라고도 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위의 어셈블리어의 예시를 가지고 와보자, 기계어 예시는 우리가 봐도 알아볼 수 없으므로&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아래와 같이 오퍼랜드가 하나도 없는 명령이 존재할 수 있는데 0-주소 명령어, 1-주소 명령어 ..., 3-주소 명령어 라고도 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1714977996195&quot; class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], 1
....
ret

// 연산 코드 | 오퍼랜드
push | rbp
mov | rbp, rsp
mov | DWORD PTR [rbp-4], 1
....
ret |&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;주소 지정 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어의 오퍼랜드 필드에는 메모리나 레지스터의 주소를 담는 경우가 많다. 따라서 &lt;b&gt;오퍼랜드 필드를 주소 필드&lt;/b&gt;라고 부르기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오퍼랜드 필드를 굳이 두지 않고, &amp;lt;연산 코드, 연산 코드에 사용될 데이터&amp;gt; 형식으로 명령어를 구성하지 않게 되면 명령어의 길이가 굉장히 길어질 수 있는 문제가 생길 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 오퍼랜드에 연산에 사용될 데이터를 직접적으로 담는 경우는 드물며, 연산 대상이 되는 데이터가 지정된 위치를 담는 경우가 대부분이며 이때 데이터가 지정된 위치를&lt;b&gt; 유효 주소&lt;/b&gt;라고 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오퍼랜드 필드에 데이터가 지정된 위치를 명시할때 연산에 사용할 데이터의 위치를 찾는 방법을 주소 지정 방식이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유효 주소를 찾는 방법과도 동일한 의미를 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현대 CPU에서는 다양한 주소 지정 방식을 사용한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;즉지 주소 지정 방식&lt;/li&gt;
&lt;li&gt;직접 주소 지정 방식&lt;/li&gt;
&lt;li&gt;간접 주소 지정 방식&lt;/li&gt;
&lt;li&gt;레지스터 주소 지정 방식&lt;/li&gt;
&lt;li&gt;레지스터 간접 주소 지정 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 접근 방식은 이후에 등장하게 될 용어인 외부 단편화 문제를 해결하는 방식과 크게 다르지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;주소 지정 방식은 연산에 사용할 데이터의 위치를 찾는 방법이라는 점과 데이터의 위치를 찾을때 효율적인 방법으로 찾기 위한 방식으로 여러가지 방식이 존재한다는 것 정도 이해하면 좋을 것 같다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;04. CPU의 작동 원리&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;04-1 ALU와 제어장치&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;CPU 구성 요소&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;내부 계산 담당 ALU (Arithmetic Logic Unit) 산술 논리 장치&lt;/li&gt;
&lt;li&gt;명령어를 읽어 들이고 해석하는 제어장치&lt;/li&gt;
&lt;li&gt;작은 임시 저장 장치인 레지스터&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ALU&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1514&quot; data-origin-height=&quot;760&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blh5iW/btsHqu543xF/skhyjcg6MDfQ9QSiHWfW90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blh5iW/btsHqu543xF/skhyjcg6MDfQ9QSiHWfW90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blh5iW/btsHqu543xF/skhyjcg6MDfQ9QSiHWfW90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fblh5iW%2FbtsHqu543xF%2Fskhyjcg6MDfQ9QSiHWfW90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;426&quot; height=&quot;214&quot; data-origin-width=&quot;1514&quot; data-origin-height=&quot;760&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1+2 라는 계산을 할때 1, 2는 피연산자, &quot;더하기&quot;라는 수행할 연산을 필요로 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;즉, 레지스터로 부터 피연산자를 받아들이고, 제어장치로부터 수행할 연산을 알려주는 제어 신호를 받아들인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ALU는 수행할 결과를 바로 메모리에 저장하지 않고 레지스터에 임시로 저장한다. &lt;b&gt;CPU가 메모리에 접근하는 속도보다 레지스터로 접근하는 속도가 매우 빠르다. CPU의 연산 결과가 매번 메모리에 바로 저장된다면 프로그램 실행 속도가 느려진다&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ALU는 수행 결과와 더불어 &lt;b&gt;플래그&lt;/b&gt;도 함께 내보낸다. (위에서 이진수를 보고 음수, 양수인지를 판단할때 플래그를 보고 판단한다고 하였는데, 이 플래그는 ALU가 추가적으로 보내는 상태 정보이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 밖에도, 제로, 캘리, 오버플로우, 인터럽트 그리고 슈퍼바이저 플래그 등 대표적인 플래그들이 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;제어장치&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1548&quot; data-origin-height=&quot;958&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckfDDj/btsHrrOizN7/6Kqed4e1WfF4FusEZqpYf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckfDDj/btsHrrOizN7/6Kqed4e1WfF4FusEZqpYf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckfDDj/btsHrrOizN7/6Kqed4e1WfF4FusEZqpYf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckfDDj%2FbtsHrrOizN7%2F6Kqed4e1WfF4FusEZqpYf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;584&quot; height=&quot;361&quot; data-origin-width=&quot;1548&quot; data-origin-height=&quot;958&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제어 신호를 내보내고, 명령어를 해석하는 부품. 제어 신호는 컴퓨터 부품들을 작동시키기 위한 일종의 전기 신호이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU의 구성 요소 중 가장 정교하게 설계된 부품이며, CPU를 제조하는 제조사 별로 구현 방식이나, 명령어를 해석하는 방식 등의 차이가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;제어 장치가 받아들이는 정보.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;제어 장치는 클럭 신호를 받아 들인다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;clock : 컴퓨터의 모든 부품을 일사불란하게 움직 일 수 있게하는 시간 단위.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;해석해야 할 명령어를 받아 들인다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CPU가 해석할 명령어는 명령어 레지스터에 저장된다. 제어 장치는 이 명령어 레지스터로부터 해석할 명령어를 받아 들이고 제어 신호를 발생시킨다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;플래그 레지스터의 플래그 값을 받아 들인다.&lt;/li&gt;
&lt;li&gt;시스텀 버스 중 제어 버스로 전달되는 제어 신호를 받아 들인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;제어 장치가 내보내는 정보&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제어 장치가 CPU 외부에 제어 신호를 전달한다 === 제어 버스로 제어 신호를 내보낸다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CPU 외부에 전달하는 제어 신호
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모리
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;get, set 등을 수행하고 싶을때 제어 신호를 내보낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;입출력장치 (보조기억장치 + 입출력장치)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;get, set 등을 수행하고 싶을때 제어 신호를 내보낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CPU 내부에 전달하는 제어 신호
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ALU
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;수행할 연산을 지시하기 위해 제어 신호를 내보낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;레지스터
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;레지스터간 데이터 이동, 레지스터에 저장된 명령어를 해석하기 위해 제어 신호를 내보낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;04-2 레지스터&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프로그램 속 명령어와 데이터는 실행 전후로&lt;span style=&quot;color: #ee2323;&quot;&gt; 반드시 레지스터에 저장&lt;/span&gt;된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU 제조사 별로 레지스터가 다양하지만 대표적으로 반드시 알아야 할 레지스터로는 아래 8가지가 있다고 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램 카운터 (명령어 포인터)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모리에서 읽어 들일 명령어 주소를 저장&lt;/li&gt;
&lt;li&gt;프로그램 카운터는 지속적으로 증가하며 계속해서 다음 명령어를 읽어 들일 준비를 한다. 이 과정이 반복되면서 CPU는 프로그램을 차례대로 실행해 나간다. 결국&lt;b&gt; CPU가 메모리 속 프로그램을 순차적으로 읽어 들이고 실행해 나갈 수 있는 이유는 프로그램 카운터가 꾸준히 증가하기 때문&lt;/b&gt;이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;명령어 레지스터
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모리에서 읽어 들인 명령어를 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;메모리 주소 레지스터
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CPU가 읽어 들이고자 하는 메모리 주소를 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;메모리 버퍼 레지스터 (메모리 데이터 레지스터)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모리와 주고 받을 값 (데이터, 명령어)을 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;플래그 레지스터
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;연산 결과 또는 CPU 상태에 대한 부가적인 정보를 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;범용 레지스터
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자유롭게 사용할 수 있는 레지스터&lt;/li&gt;
&lt;li&gt;데이터, 주소 등 모두 저장할 수 있으며, CPU 안에는 여러개의 범용 레지스터가 존재한다. 즉, 메모리 버퍼 레지스터, 메모리 주소 레지스터 등 다양한 역할을 수행할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;스택 포인터
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모리 주소 지정 방식 중 스택 주소 지정 방식에 사용되는 레지스터&lt;/li&gt;
&lt;li&gt;스택의 마지막으로 저장한 값의 위치를 저장하는 레지스터이다. 즉, 스택 포인터로 어디까지 데이터가 채워져 있는지에 대한 표시라고 이해하면 된다. 여기서 스택은 메모리 안에 존재하는 영역이며, 암묵적으로 약속된 영역이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;베이스 레지스터
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모리 주소 지정 방식 중 변위 주소 지정 방식에 사용되는 레지스터&lt;/li&gt;
&lt;li&gt;명령어는 연산 코드와 오퍼랜드로 이루어져있다고 했었다. (3장) 그리고 오퍼랜드 필드에는 메모리의 주소가 담기는 경우도 존재한다. &lt;b&gt;변위 주소 지정 방식은 이처럼 오퍼랜드 필드의 값과 베이스 레지스터의 값을 더하여 유효 주소를 얻어내는 주소 지정 방식이다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;베이스 레지스터 속 기준 주소로부터 얼마나 떨어져 있는 주소에 접근할 것인지를 연산하여 유효 주소를 얻어내는 방식으로 &lt;b&gt;베이스 레지스터는 기준 주소&lt;/b&gt;, &lt;b&gt;오퍼랜드는 기준 주소로 부터 떨어진 거리의 역할&lt;/b&gt;을 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;04-3 명령어 사이클과 인터럽트&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;명령어 사이클&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;CPU는 명령어들을 하나씩 실행하는데 이때 프로그램 속 각각의 명령어들은 일정한 주기가 반복되며 실행되는데 이 주기를 &lt;b&gt;명령어 사이클&lt;/b&gt;이라 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;메모리에 저장된 명령어를 하나 실행한다고 가정하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;메모리에 있는 명령어를 CPU로 가져온느 단계를 &lt;b&gt;인출 사이클&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;CPU로 가져온 명령어를 실행하는 단계, 제어 장치가 명령어 레지스터에 담긴 값을 해석하고 제어 신호를 발생시키는 단계를 &lt;b&gt;실행 사이클&lt;/b&gt;이라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;CPU로 명령어를 인출했다고 해도 바로 실행할 수 없는 경우가 존재하는데, 이는 실행 사이클 진입 전 메모리 접근이 한번 더 필요한 경우를 말하는데 이를 &lt;b&gt;간접 사이클&lt;/b&gt;이라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;CPU가 수행 중인 작업은 방해를 받아 잠시 중단 될 수 있는데, 이러한 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;신호를 인터럽트(Interrupt)&lt;/b&gt;&lt;/span&gt;라고 부른다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1494&quot; data-origin-height=&quot;628&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkVBIB/btsHpRASTkR/D3RipHwvKk4nxc5qXZiDK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkVBIB/btsHpRASTkR/D3RipHwvKk4nxc5qXZiDK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkVBIB/btsHpRASTkR/D3RipHwvKk4nxc5qXZiDK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkVBIB%2FbtsHpRASTkR%2FD3RipHwvKk4nxc5qXZiDK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;550&quot; height=&quot;231&quot; data-origin-width=&quot;1494&quot; data-origin-height=&quot;628&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;인터럽트&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;인터럽트는 크기 2가지 종류가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동기 인터럽트 (예외), 비동기 인터럽트(하드웨어 인터럽트)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;동기 인터럽트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그래밍 상의 오류와 같은 예외적인 상황을 마주쳤을때 발생하는 인터럽트. &lt;b&gt;예외(Exception)&lt;/b&gt;라고 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;비동기 인터럽트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주로 입출력장치에 의해 발생하는 인터럽트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU가 프린터에게 프린터를 작업을 수행하라고 명령하면 프린터는 프린터 작업을 마치고 CPU에게 완료 알림(인터럽트)를 보내며 CPU는 이러한 인터럽트가 발생하면 해당 작업을 먼저 수행한 후 이전 작업으로 돌아와 진행하고 있던 작업을 마저 수행하게 된다. 이때 이러한 인터럽트를 &lt;b&gt;비동기 인터럽트, 하드웨어 인터럽트라고 부르며 비동기 인터럽트는 마치 알림과 같은 역할을 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비동기 언터럽트는 CPU가 명령어를 효율적으로 처리하는 것과 관련이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU가 프린터에게 출력을 명령했다고 가정해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;입출력장치는 CPU보다 속도가 현저히 느리다. 따라서 CPU는 입출력 작업의 결과를 바로 받아볼수 없다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비동기 인터럽트를 사용하지 않는다면 CPU는 프린터 작업이 언제 끝날지 모르기 때문에 계속 완료 여부를 확인해야 할 것이고 CPU 사이클 낭비로 이어진다. &lt;b&gt;마치 전자레인지 앞에서 언제 조리가 끝날지 알 수 없어 하염없이 그 자리에서 기다리고 있는 것과 같다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 비동기 인터럽트를 이용하면 CPU는 주기적으로 완료 여부를 확인 할 필요가 없게된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;비동기 인터럽트의 처리 순서&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;입출력 장치는 CPU에 &lt;b&gt;인터럽트 요청 신호&lt;/b&gt;를 보낸다.&lt;/li&gt;
&lt;li&gt;CPU는 &lt;b&gt;실행 사이클이 끝나고 명령어를 인출하기 전&lt;/b&gt; &lt;b&gt;항상 인터럽트 여부&lt;/b&gt;를 확인한다.&lt;/li&gt;
&lt;li&gt;CPU가 인터럽트 요청을 확인하고 &lt;b&gt;인터럽트 플래그&lt;/b&gt;를 통해 &lt;b&gt;현재 인터럽트를 받아 들일 수 있는지 여부를 확인&lt;/b&gt;한다.&lt;/li&gt;
&lt;li&gt;인터럽트를 받아들일 수 있다면 CPU는 지금까지의 작업을 &lt;b&gt;스택 영역에 백업&lt;/b&gt;한다.&lt;/li&gt;
&lt;li&gt;CPU는&lt;b&gt; 인터럽트 백터를 참조&lt;/b&gt;하여 &lt;b&gt;인터럽트 서비스 루틴을 실행&lt;/b&gt;한다.&lt;/li&gt;
&lt;li&gt;인터럽트 서비스 루틴 실행이 끝나면 &lt;b&gt;백업해둔 작업을 복구하여 실행을 재개&lt;/b&gt;한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;인터럽트 요청 신호&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU의 정상저긴 흐름을 끊기 위해 인터럽트를 하기 전 CPU에 요청을 보내는 신호.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;인터럽트 플래그&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU가 인터럽트 요청을 수용하기 위해 플래그 레지스터에 있는 인터럽트 플래그가 활성화되어 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 인터럽트 플래그가 불가능으로 설정되어 있더라도 &lt;b&gt;무시할 수 없는 인터럽트 요청도 존재&lt;/b&gt;하는데 반드시 가장 먼저 처리해야하는 인터럽트가 있다. 대표적으로 정전, 하드웨어 고장과 같은 인터럽트가 이에 해당한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;인터럽트 서비스 루틴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;인터럽트가 발생하면 어떻게 행동할지 알려주는 인터럽트를 처리하기 위한 프로그램&lt;/b&gt;이다. 키보드에서 인터럽트 요청이 발생하면 어떻게 작동한다, 마우스에서 인터럽트 요청이 발생하면 어떻게 작동한다와 같이 &lt;b&gt;인터럽트가 발생하면 어떻게 행동해야 할지 알려주는 프로그램&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 &lt;b&gt;명령어와 데이터로&lt;/b&gt; 이루어진 프로그램이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CPU가 인터럽트를 처리한다는 말은 === 인터럽트 서비스 루틴을 실행하고 본래 수행하던 작업으로 돌아온다는 것을 의미한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 &lt;b&gt;인터럽트 서비스 루틴은 메모리에 저장&lt;/b&gt;이 되어있다. 그렇다면 CPU는 마우스, 키보드, 프린터와 같이 각긱 다른 인터럽트 서비스 루틴을 어떻게 구별하는 걸까??&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;인터럽트 백터&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;인터럽트 서비스 루틴을 식별하기 위한 정보&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU가 인터럽트 서비스 루틴을 &lt;b&gt;실행하려면 인터럽트 서비스 루틴의 시작 주소를 알아야하는데 이를 인터럽트 백터&lt;/b&gt;를 통해 알 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;[출처 : 혼공컴운 (저자: 강민철)_한빛 미디어 ]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;904&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IXtrr/btsHd7JpJdp/evfom4anzQKA2dqjICDaP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IXtrr/btsHd7JpJdp/evfom4anzQKA2dqjICDaP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IXtrr/btsHd7JpJdp/evfom4anzQKA2dqjICDaP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIXtrr%2FbtsHd7JpJdp%2Fevfom4anzQKA2dqjICDaP0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;308&quot; height=&quot;363&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;904&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>개발서적</category>
      <author>codermun</author>
      <guid isPermaLink="true">https://codermun-log.tistory.com/615</guid>
      <comments>https://codermun-log.tistory.com/615#entry615comment</comments>
      <pubDate>Mon, 6 May 2024 13:35:31 +0900</pubDate>
    </item>
    <item>
      <title>useState 인자로 함수 전달하기 (+useReducer)</title>
      <link>https://codermun-log.tistory.com/613</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;941&quot; data-origin-height=&quot;501&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEbitl/btrALVh9c6z/6jVKoKrYkkLhan3XsUANY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEbitl/btrALVh9c6z/6jVKoKrYkkLhan3XsUANY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEbitl/btrALVh9c6z/6jVKoKrYkkLhan3XsUANY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEbitl%2FbtrALVh9c6z%2F6jVKoKrYkkLhan3XsUANY0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;941&quot; height=&quot;501&quot; data-origin-width=&quot;941&quot; data-origin-height=&quot;501&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;useState&amp;nbsp;인자로&amp;nbsp;함수&amp;nbsp;전달하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이상하게도 지금까지 한 번도 useState에 인자로 함수를 전달하는 것을 생각하지 못하였다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러던 중 &lt;b&gt;리액트 성능 테스트&lt;/b&gt;를 하기 위해 많은 양의 데이터를 화면에 출력해야 하는 상황이 생겨 useState 인자로 많은 데이터를 생성하는 함수를 넣어보았다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;useState의 인자로 함수를 전달하는 경우 + 추가로 useReducer의 인자로 함수를 전달하는 경우를 정리해보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(해당 내용 출처 : 리액트를 다루는 기술 개정판/ 지은이: 김민준)&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;useState 인자로 함수를 전달하는 경우&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;useState 초기값으로 함수를 전달할 수 있는데 아래 2가지 경우에 따라 다르게 동작시킬 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1651149792213&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const testFuc = () =&amp;gt; {
	...
}

// #1
const [data, setData] = useState(testFuc())


// #2
const [data, setData] = useState(testFuc)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;#1의 경우&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 해당 컴포넌트가 리랜더링 될 때마다 함수가 호출됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;#2의 경우&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 함수의 형태로만 전달하면 Didmount와 같이 컴포넌트가 처음 랜더링 되는 시점에서만 함수가 호출됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나의 경우에는 해당 로직이 APP 컴포넌트에 위치해 있으며 처음 랜더링된 시점에서만 많은 양의 데이터가 필요하기에 #2와 같이 사용하였다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;useReducer 인자로 함수를 전달하는 경우&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이&amp;nbsp;&lt;b&gt;useReducer&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;초기값으로 함수를 전달하는 경우를 살펴보자. &lt;br /&gt;아래 2가지 방법이 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1651157226386&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const todoReducer = (todos, action) =&amp;gt; {
  switch (action.type) {
    case 'INSERT':
      return todos.concat(action.todo);
    case 'REMOVE':
      return todos.filter((todo) =&amp;gt; todo.id !== action.id);
    case 'TOGGLE':
      return todos.map((todo) =&amp;gt;
        todo.id === action.id ? { ...todo, checked: !todo.checked } : todo
      );
    default:
      return todos;
  }
};

// #1
const [todos, dispatch] = useReducer(todoReducer, createBulkTodos());

// #2
const [todos, dispatch] = useReducer(todoReducer, undefined, createBulkTodos);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#1의 경우&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 일반적인 방법으로 useReducer를 두번째 인자, 초기 값으로 전달하는 방법.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 보통 state 자체를 넣어주는 경우가 많긴 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;#2의 경우&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 보통 useReducer는 두번째 인자로 초기값을 전달한다, &lt;br /&gt;여기서는 두번째 인자로 undefined를 세번째 인자로 초기 값을 생성하는 함수를 전달하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실상 1, 2번 경우 모두 동일하게 동작하는 것으로 보인다. &lt;br /&gt;useState 예제와 달리 접근성?의 차이가 있지 않나라고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실상 useReducer의 두번째 인자로 초기 값을 전달하는 것으로 모두 알고 있기에 1번과 같이 전달하면 정확히 어떤 값을 전달하고 싶은지 애매모호해지지 않나라고 생각한다. &lt;b&gt;반면에 2번과 같이&lt;/b&gt; 초기값으로 확실한 &lt;b&gt;undefined&lt;/b&gt;를 명시하고 이후 state를 생성하는 함수를 전달하는 &lt;b&gt;방식을 취하는게 더 useReducer를 useReducer 답게 사용하는 방법&lt;/b&gt;이지 않을까 생각한다.&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt; (굉장히 주관적)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 useReducer에서는 세번째 인자로 state를 생성하는 함수를 받을 수 있으니 말이다!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 useState, useReducer 예제는 모두 같은 역할을 하지만 &lt;br /&gt;useReduer로 상태를 업데이트하면 해당 로직을 분리시킬 수 있고, &lt;br /&gt;굉장히 많은 상태를 다루는 경우 useState보다 useReducer를 사용하는게 개인적으로 편리했다고 생각한다.&lt;br /&gt;추가되는 값에 따라 계속 어떠한 상태를 추가하는 로직보다는 reducer 함수에 추가시킴으로써 확장성 측면에서도 굉장히 큰 이점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;수많은 데이터를 다뤄야할 경우 useReducer가 확실히 이점이 있다고 생각하지만 규모가 크지 않다면 굳이 &lt;br /&gt;useReducer를 사용하지 않아도 될 것 같다. 책에서는 성능은 2가지 모두 큰 차이가 없다고 하니 말이다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출처 및 참고&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;리액트를 다루는 기술 개정판 (지은이 김민준)&lt;/b&gt;&lt;/p&gt;</description>
      <category>React</category>
      <category>useReducer</category>
      <category>useReducer 인자로 함수 전달하기</category>
      <category>useReducer 초기 값 함수로 전달하기</category>
      <category>useState</category>
      <category>useState 인자로 함수 전달하기</category>
      <category>useState 초기 값 함수로 전달하기</category>
      <author>codermun</author>
      <guid isPermaLink="true">https://codermun-log.tistory.com/613</guid>
      <comments>https://codermun-log.tistory.com/613#entry613comment</comments>
      <pubDate>Thu, 28 Apr 2022 23:55:37 +0900</pubDate>
    </item>
    <item>
      <title>JAM Stack</title>
      <link>https://codermun-log.tistory.com/611</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beYvdM/btrzsPC5Llg/TRne6Nv0VGmztx7etEF9q1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beYvdM/btrzsPC5Llg/TRne6Nv0VGmztx7etEF9q1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beYvdM/btrzsPC5Llg/TRne6Nv0VGmztx7etEF9q1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeYvdM%2FbtrzsPC5Llg%2FTRne6Nv0VGmztx7etEF9q1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;936&quot; height=&quot;307&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;307&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;JAM Stack&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;JavaScript API MarkUp Stack&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;웹 서비스를 만드는 하나의 설계 방식, 프로그래밍 기법이라 할 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적인 프로그래밍 기법이고 매우 익숙하게 느낄 수 있다. 실제로는 이러한 개념을 모르고 현재까지 이와 비슷한 방식으로 개발을 해오고 있었을 수도 있다.&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(LAMP, MEAN Stack과 같은 개념을 떠올리면 된다.)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 나아가서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;JAM Stack은 정적 사이트 생성기를 사용한 서비스의 설계를 의미하기도 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 정적 사이트 생성기란 (SSG) Next, Hugo, Gastby 등을 의미한다. 아래에서 SSG에 대해서도 다뤄보자.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;JAM Stack 공식 문서에서는 아래와 같이 정의한다.&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;웹 애플리케이션에서 렌더링 할 화면을 Pre-render 하고 이를 CDN에서 제공(delivery)하여&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;b&gt;빠르고 안전한 앱으로 웹 서버를 관리하거나 실행할 필요가 없다.&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Jamstack is an architecture designed to make the web faster, more secure, and easier to scale.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;JAM Stack 은 더 빠르고, 안전하며, 스케일링하기 쉬운 웹을 만들기 위해 디자인된 아키텍처입니다.&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;688&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cEjnij/btrzo937KjV/BrSSxbtLnPlX2YRhmB2VG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cEjnij/btrzo937KjV/BrSSxbtLnPlX2YRhmB2VG0/img.png&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp;https://www.youtube.com/watch?v=CTtoHa1g8I4&amp;amp;amp;t=329s&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cEjnij/btrzo937KjV/BrSSxbtLnPlX2YRhmB2VG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcEjnij%2Fbtrzo937KjV%2FBrSSxbtLnPlX2YRhmB2VG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;449&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;688&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;amp;nbsp;https://www.youtube.com/watch?v=CTtoHa1g8I4&amp;amp;t=329s&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;여기서 핵심&lt;/span&gt;으로 JAM Stack은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;웹 애플리케이션의 마크업과 콘텐츠를 정적 페이지로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;미리 생성&lt;/b&gt;해놓는다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;pre-rendering&lt;/span&gt;&lt;/b&gt;라 하며 로그인, 결제 등은 외부 API로 분리하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;decoupling&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이라는 두 가지 개념이 중요&lt;/b&gt;하다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;Markup : SSG(Static Site Generator)나 Template Engine(Webpack 등)을 이용해서&lt;br /&gt;Markup을 미리 생성합니다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;JAM Stack에서 가장 핵심은 MarkUp이라고 할 수 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MarkUp을 만들 수 있는 방법은 여러 가지가 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;1.HTML을 직접 작성한다&lt;/b&gt;&lt;br /&gt;&lt;b&gt;2.Template Engine 와 같은 툴을 사용한다.&lt;/b&gt;&lt;br /&gt;&lt;b&gt;3. 정적 사이트 생성기(Static Site Generator, SSG)를 이용해서 Static HTML을 생성한다.&lt;/b&gt;&lt;br /&gt;&lt;b&gt;e.g) Gatsby, Next.js, Gridsome, Nuxt.js, Hugo, Jekyll 등&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 만들어진 Static HTML은 웹 서버의 리소스를 사용할 필요 없이 사용자에게 HTML만 전달해주면 된다. Static HTML은 CDN을 통해서 Cache 하고 배포해서 빠른 속도를 유지하고,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;따로 동적으로 HTML을 생성하지 않기 때문에 웹서버가 필요 없어서 서버 비용이 크지 않다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 모든 HTML을 Static HTML로 만들라는 뜻은 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 Markup을 정적으로 유지하게 되면, 최신 데이터를 유지하기 어렵기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 것은 최대한 HTML Build를 하여 CDN Cache 서버를 통해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;첫 의미 있는 페이지를 볼 수 있는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;속도&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;(&lt;span style=&quot;background-color: #f2f2f2; color: #292929;&quot;&gt;First meaningful paint&lt;/span&gt;)를 단축시킨다는 것에 주목할 필요가 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이렇게&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;JAM Stack&lt;/b&gt;은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;페이지를 사전에 미리 생성한다는 것을 기억&lt;/span&gt;해야 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;기존 웹들이 SSR이나, SPA 프레임워크, 라이브러리 등을 사용해서 페이지를 동적으로 생성한 것과 비교된다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 내용을 취합하여&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;JAM Stack&lt;/b&gt;을 다시 한번 표현해보자면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동적 요소 처리를 위한 JS, 재사용 가능한 API, 사전 생성된 페이지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이 3가지가 조합되어 서버 없이 배포 운영되는 모던 웹 개발 구조를 말한다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;688&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/x4TpN/btrzoPEMkyf/ej7hVngDW6hO9R7ZdMxcc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/x4TpN/btrzoPEMkyf/ej7hVngDW6hO9R7ZdMxcc0/img.png&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp;https://www.youtube.com/watch?v=CTtoHa1g8I4&amp;amp;amp;t=329s&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/x4TpN/btrzoPEMkyf/ej7hVngDW6hO9R7ZdMxcc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fx4TpN%2FbtrzoPEMkyf%2Fej7hVngDW6hO9R7ZdMxcc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;449&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;688&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;amp;nbsp;https://www.youtube.com/watch?v=CTtoHa1g8I4&amp;amp;t=329s&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;JavaScript, API 그리고 MarkUp&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이름에서도 보았듯 이전 LAMP, MEAN과는 달리&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;DB, 서버에 관련한 스펙은 보이지 않는다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB, 서버는 철저하게 API로 분리하여 정적인 사이트를 만드는데 최적화된 방법이라 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript와 MarkUp에 해당하는 HTML, CSS 정적 리소스들을 활용하여 웹 애플리케이션을 구성하는 스택이며, 이 정적 리소스들을 CDN에 배포하여 서버 관리를 최소화할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;코드를 빌드하여 정적 페이지를 사전에 생성하고 이를 CDN에 배포함으로써&lt;br /&gt;비용절감 + 사용자 경험까지 개선하는 것이 JAM Stack에서 권장하는 설계 구조이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;이러한 정적 페이지를 빌드해주고 CDN에 배포해주는 서비스가 Netlify, Vercel,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;AWS CloudFront이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;JAMStack으로 개발한다는 것의 구조&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;JAM Stack&lt;/b&gt;은 SSG를 사용하여 빌드한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SSG 빌드의 결과물로 정적인 페이지들이 산출&lt;/b&gt;되고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CDN&lt;/b&gt;을 통해 전송을 하고 별도 추상화된 함수나 서비스들을 사용해 API 요청을 하게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;666&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TLCNm/btrzprcqUSA/usIRUuYj1NKCcCD1FCylRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TLCNm/btrzprcqUSA/usIRUuYj1NKCcCD1FCylRK/img.png&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp;https://www.youtube.com/watch?v=CTtoHa1g8I4&amp;amp;amp;t=329s&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TLCNm/btrzprcqUSA/usIRUuYj1NKCcCD1FCylRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTLCNm%2FbtrzprcqUSA%2FusIRUuYj1NKCcCD1FCylRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;285&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;666&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;amp;nbsp;https://www.youtube.com/watch?v=CTtoHa1g8I4&amp;amp;t=329s&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;JAM Stack을 사용하는 이유&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;1. 높은 안정성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 정적 페이지를 미리 생성해놓기 때문에 동적으로 변경되는 부분이 적고, 서버나 DB 실행이 필요하지 않기 때문에 안정성이 높다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;2. 빠른 성능&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 콘텐츠들이 미리 정적 페이지로 생성이 돼있기 때문에 빠르게 랜더링이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CDN에 정적 페이지를 배포하기 때문에 빠르게 전송하고 CDN의 캐싱 기능도 활용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;3. 확장성 및 낮은 비용&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 전 세계 어디든 CDN을 통해 손쉽게 확장하고 정적 HTML 호스팅 비용은 매우 저렴하거나 공짜인 서비스도 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;4. 쉬운 자동화&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 빌드 산출물이 정적 페이지이기 때문에 배포 과정이 편리하고 정적 자산을 호스팅 서비스에 제공만 하면 되기 때문에 자동화가 매우 쉽다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;JAM Stack의 한계&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;1. 빌드 속도&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 콘텐츠가 매우 많은 경우 생성해야 하는 페이지도 많아지고 결국 빌드 시간이 오래 걸리는 문제가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;2. 실시간 변경 콘텐츠&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 실시간 단위로 콘텐츠를 변경해야만 하는 경우 반영에 시간이 걸린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;JAM Stack&lt;/b&gt;은 콘텐츠 변경사항을 반영하기 위해 빌드를 수행해야 하는데 빌드 속도가 느릴 경우 변경 사항을 즉각적으로 반영할 수 없다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;해결책 1&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 별도 CMS나 API 서비스를 활용해서 위 문제를 해결을 할 수는 있으나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 근본적으로 빌드 성능 개선에 관련한 문제를 해결하는 해결방법이 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;해결책 2&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 위 문제를 해결하기 위해 Gastby, Next 같은 경우 점진적 Build라는 방법으로 이를 해결하기 위해 노력하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 매번 전체 콘텐츠를 대상으로 다시 빌드해서 페이지를 생성하는 방법이 아닌&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 변경된 부분만 빌드해서 해당 페이지만 다시 생성하는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이로 인해 빌드 속도를 20분에서 -&amp;gt; 1분 -&amp;gt; 10초 이하로 줄일 수 있었다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이러한 점진적 Build라는 방법이 얼마만큼 발전하는지에 따라 웹의 미래를 선도할 가능성이 있다고 한다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;정적 사이트 생성기 (Static Site Generator, SSG)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드 산출물로써 정적 페이지를 만들어내는 것이 특징이다. SSG 별로 개발에 사용하는 언어가 다르다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1250&quot; data-origin-height=&quot;552&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OlaJq/btrzpsI6Buw/gKlpwpemdqO4lRkvGCsCc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OlaJq/btrzpsI6Buw/gKlpwpemdqO4lRkvGCsCc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OlaJq/btrzpsI6Buw/gKlpwpemdqO4lRkvGCsCc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOlaJq%2FbtrzpsI6Buw%2FgKlpwpemdqO4lRkvGCsCc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;221&quot; data-origin-width=&quot;1250&quot; data-origin-height=&quot;552&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;JAM Stack이 등장하게 된 배경 알아보기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뭐든지 그게 왜 등장했는지를 알면 이해가 훨씬 빠르다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하게 웹 역사를 짚어보고 왜 등장하게 되었는지 따라가 보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Static Sites&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;초기 웹은 전부 Static Sites, 정적 사이트였다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;577&quot; data-origin-height=&quot;375&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6faxN/btrzoPSkLcR/N202Ho7OkESf2YbaNB25Z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6faxN/btrzoPSkLcR/N202Ho7OkESf2YbaNB25Z0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6faxN/btrzoPSkLcR/N202Ho7OkESf2YbaNB25Z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6faxN%2FbtrzoPSkLcR%2FN202Ho7OkESf2YbaNB25Z0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;260&quot; data-origin-width=&quot;577&quot; data-origin-height=&quot;375&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 URL을 입력하면 클라이언트는 서버 측에 어떤 HTML이 필요한지 요청을 보내면 서버에서는 이미 만들어져 있는 정적 HTML 파일을 내려주며 동작하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 페이지를 보기 위해선 또 HTML 파일을 받아야 했고, 특정 일부분만 업데이트되는 것이 아닌 full page reqeuest로 전체 페이지를 다시 받아오는 방식이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;iframe&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDyqQ1/btrzpsbj7DW/C19GvxFTplne56UzlvbYi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDyqQ1/btrzpsbj7DW/C19GvxFTplne56UzlvbYi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDyqQ1/btrzpsbj7DW/C19GvxFTplne56UzlvbYi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDyqQ1%2Fbtrzpsbj7DW%2FC19GvxFTplne56UzlvbYi1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;249&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;문서 내에서 또 다른 문서를 담을 수 있는 iframe 태그가 도입&lt;/b&gt;이 되었고 이후 페이지 내에서 부분적으로 문서를 받아와서 업데이트할 수가 있게 된다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;XMLHttpRequest&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529;&quot;&gt;Microsoft&lt;/span&gt;에서 만든 http 프로토콜을 사용하여 서버에 자원을 요청하기 위해 사용되는 자바스크립트 객체이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTML 문서 전체가 아닌, JSON 형식으로 서버에서 필요한 데이터만 받아와는 요청을 보낼 수 있게 되었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;539&quot; data-origin-height=&quot;325&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zSfIv/btrzqzOwShT/9keCYgJ5HFKP2dxytTZWE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zSfIv/btrzqzOwShT/9keCYgJ5HFKP2dxytTZWE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zSfIv/btrzqzOwShT/9keCYgJ5HFKP2dxytTZWE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzSfIv%2FbtrzqzOwShT%2F9keCYgJ5HFKP2dxytTZWE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;241&quot; data-origin-width=&quot;539&quot; data-origin-height=&quot;325&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;AJAX (2005 ~)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-token-index=&quot;0&quot; data-reactroot=&quot;&quot;&gt;&lt;b&gt;Asynchronous JavaScript And XML&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;약자로 XML과 같은 방식이 공식적으로 AJAX라는 이름을 갖게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;자바스크립트를 사용하여 클라이언트와 서버 간에 데이터를 주고받는 비동기 HTTP 통신 기술&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 이는 fetch, axios 등의 부모가 되는 개념이라 할 수 있다. (실제로 동일하지는 않다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;SPA (Single Page Application)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AJAX를 통해 필요한 데이터를 서버에서 비동기로 받아 올 수 있게 되었으며 페이지의 일부만 동적으로 업데이트할 수 있게 됨으로 써 SPA라는 개념이 등장하게 되고, 대세로 자리 잡게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SPA는 하나의 큰 애플리케이션의 모든 페이지를 하나의 페이지 내에서 동적으로 구성하는 방법이며,&lt;br /&gt;CSR 방식을 채택하여 사용자에게 화면을 출력해주게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;CSR (Client Side Rendering)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CSR 이전에는 서버에서 동적으로 HTML을 생성할 수 있었다. 하지만 그 방법만으로는 HTML 조작에 한계가 있었고 JS와 브라우저 성능이 발전하면서 Vue, React, Angluar와 같이 DOM을 조작하기 쉽게 도와주는 프레임워크, 라이브러리의 등장으로 CSR이라는 개념이 등장하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;SSR (Server Side Rendering)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CSR의 페이지 초기 랜더링 속도, SEO 최적화 문제 등으로 등장하게 된 개념이며, 이전 Static Sites로 부터 영감을 받아 등장하게 되었다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실상 이전부터 있었던 방식으로 CSR의 문제점으로 인해 다시 돌고 돌아 등장하게 된 개념이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(CSR, SSR은 이 포스팅에서는 따로 설명하지 않는다.)&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;그래서 JAM Stack이 등장하게 된 배경이 무엇이냐?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 위 내용은 지금부터 정리하게 될 내용을 이해하기 위한 발판이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 영상을 한번 정독하고 본다면 더 이해하기 쉬울 것이라 확신한다. (&lt;a href=&quot;https://www.youtube.com/watch?v=CTtoHa1g8I4&quot;&gt;NHN Cloud Youtube)&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;처음 전통적인 웹 구조는 아래와 같았다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;142&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIyfBq/btrzpbARe0g/h8axWAjk0UK8GRF50sSZ01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIyfBq/btrzpbARe0g/h8axWAjk0UK8GRF50sSZ01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIyfBq/btrzpbARe0g/h8axWAjk0UK8GRF50sSZ01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIyfBq%2FbtrzpbARe0g%2Fh8axWAjk0UK8GRF50sSZ01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;83&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;142&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB, CMS (Contents Management System, 워드프레스와 같은 툴) 사용하여 애플리케이션에 필요한 데이터를 조회하거나 저장하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;App Server에서는 다양한 비즈니스 로직을 처리하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Web Server에서는 처리한 데이터를 사용하여 HTML 페이지를 만들거나, 이미지, 폰트 등의 클라이언트에 필요한 정적 자원들을 브라우저에 전달하는 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 구조는 각 계층 간 의존성이 높기 때문에 별도의 서버 운용에 들어가는 비용이 크다는 단점이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Serverless 웹&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 단점을 개선하기 위해 Serverless라는 개념이 등장하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;서버 시스템을 가상의 클라우드 환경에 두고 운용하는 구조이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이로 인해 서버 유지보수 비용 및 인프라 비용을 절감할 수 있었고&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;필요한 API, 비즈니스 로직 개발에만 집중할 수 있는 환경이 만들어졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이에 대한 확장으로 AWS lambda, Netlify, Firebase 등 함수 단위의 서비스가 등장하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Serverless 웹 구조&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1209&quot; data-origin-height=&quot;230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xxOoX/btrzoN74stb/voXBMFVdQakchaH3T6PAV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xxOoX/btrzoN74stb/voXBMFVdQakchaH3T6PAV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xxOoX/btrzoN74stb/voXBMFVdQakchaH3T6PAV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxxOoX%2FbtrzoN74stb%2FvoXBMFVdQakchaH3T6PAV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;95&quot; data-origin-width=&quot;1209&quot; data-origin-height=&quot;230&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저에서 데이터를 요청하면 DB에 접근하여 데이터를 가져와 화면을 출력해주는 것은 동일하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 부분은!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB 서비스 API를 사용한다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 웹 개발 시 DB, API 구조에 대해서는 전혀 신경 쓰지 않고 원하는 데이터를 DB 서버에 저장하고 필요에 따라 조회하면서 사용하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;Serverless&lt;/span&gt;란, 서버가 없다는 개념이 아닌, 서버 구성, 관리에 대해 신경 쓰지 않아도 된다는 개념이다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;JAM Stack은 Serverless에서 파생된 개념이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터넷이 계속 발전하면서 만들어지는 웹 개발의 아키텍처, 프로그래밍 설계의 변화에서 있어 가장 최신 버전? 의 패러다임이 아닐까 생각한다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;LAMP, MEAN 처럼 말이다.&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;LAMP (리눅스, 아파치, MySQL, PHP)&amp;nbsp; -&amp;gt; MEAN Stack (MongoDB, Express.JS, Angular or React, NodeJS)&lt;/b&gt;&lt;b&gt;-&amp;gt;&amp;nbsp;JAM Stack&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재까지 CSR + SSR 서로의 단점을 보완하는 방법으로&lt;br /&gt;이를 접목시킨 Next.JS, Nuxt.JS 등 프레임워크들이 인기를 끌고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;JAM Stack은 Next.JS와는 다르다,&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;b&gt;결국 웹 사이트를 어떻게 구성할 것인지에 대한 관점이다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;돌고 돌아 그래서 JAM Stack 이 등장하게 된 배경&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기존 웹 사이트들은 서버, DB 등에 매우 크게&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;의존&lt;/span&gt;했었기 때문이라고 정리할 수 있을 것 같다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;JAM Stack이라는 하나의 아키텍쳐?가 고안되면서 이러한&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;의존도가 크게 떨어졌고, 이는 비용 감소, 안정성, 확장성 측면에서 매우 큰 이점&lt;/span&gt;을 챙길 수 있었다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이러한 의존 관계를 벗어나 더 나은 성능, 안정성, 낮은 비용 그리고 높은 확장성을 갖는 웹 사이트를&lt;/b&gt;&lt;br /&gt;&lt;b&gt;개발할 수 있게 되었다고 이해할 수 있을 것 같다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;마무리&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나에게 있어 생각보다 어려운 주제였다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수많은 자료들을 토대로 어느 정도만 이해가 되었을 뿐 완벽하지는 않다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;아래 박성룡&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;님 Medium 아티클&lt;/span&gt;을 보면 JAM Stack을 가장 쉽게 따라 하는 방법에 대한 서술이 기록&lt;/b&gt;되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이를 실제로 내가 개발해 보면서 포스팅을 수정하려고 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CDN에서 배포가 왜 빠른지가 궁금하다면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://codermun-log.tistory.com/610&quot;&gt;이전 포스팅&lt;/a&gt;을 참고하면 이해하기 수월할 거라 생각한다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 제가 보기 위해서 포스팅을 남깁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어려운 주제를 스마트하게 다루지 못한 것 같아 글을 계속 다듬어야 할 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;언제나 잘못된 부분이 있다면 피드백 남겨주시면 더 견고한 지식이 될 것 같습니다!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출처 및 참고&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;a href=&quot;https://pks2974.medium.com/jam-stack-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC%ED%95%98%EA%B8%B0-17dd5c34edf7&quot;&gt;Medium_박성룡님_Blog&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=CTtoHa1g8I4&quot;&gt;NHN Cloud Youtube&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=5ILR9Vd_Vos&quot;&gt;얄팍한 코딩사전 Youtube&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;a href=&quot;https://jamstack.wtf/&quot;&gt;WTF is Jamstack?&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.freecodecamp.org/news/an-introduction-to-the-jamstack-the-architecture-of-the-modern-web-c4a0d128d9ca/&quot;&gt;freeCodeCamp_Blog&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jamstack.org/&quot;&gt;jamstack.org&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jbee.io/web/jam-stack/&quot;&gt;jbee.io&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@kysung95/SSR-vs-CSR-%EB%8B%B9%EC%8B%A0%EC%9D%98-%EC%84%A0%ED%83%9D%EC%9D%80-feat.-ssg&quot;&gt;velog_yongseong님_BLog&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://azderica.github.io/00-web-jamstack/&quot;&gt;azderica.github&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.netlify.com/jamstack/&quot;&gt;netlify&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;​&lt;/p&gt;</description>
      <category>개발</category>
      <category>JAM Stack</category>
      <category>JAM Stack 이란?</category>
      <category>JAM Stack이 등장하게 된 배경</category>
      <category>JAM Stack이 등장하게 된 이유</category>
      <category>잼스택</category>
      <category>잼스택이란?</category>
      <author>codermun</author>
      <guid isPermaLink="true">https://codermun-log.tistory.com/611</guid>
      <comments>https://codermun-log.tistory.com/611#entry611comment</comments>
      <pubDate>Fri, 15 Apr 2022 01:00:16 +0900</pubDate>
    </item>
    <item>
      <title>CDN 이해하기</title>
      <link>https://codermun-log.tistory.com/610</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;JAM Stack에 대해 알아보기 전에 CDN에 대한 이해가 선행되어야 했다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 포스팅에서 JAM Stack에 대해 정리하기 위해 CDN을 따로 포스팅한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 포스팅과 이후 업로드할 JAM Stack을 함께 본다면 JAM Stack에 대해 조금은 더 잘 이해하게 되지 않을까 생각된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;틀린 부분이 있다면 마구마구 지적해주신다면 감사할 것 같다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;CDN (&lt;b&gt;&amp;nbsp;Content Delivery Network )&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CDN은 Content Delivery Network의 약자로서&lt;br /&gt;지리적인 제약 없이 전 세계 사용자에게 빠르고 안전하게 콘텐츠 전송을 할 수 있고, 콘텐츠 전송에 특화된 기술을 말한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CDN은 요청을 분산시킨다에 초점이 맞추면 이해하기 어렵지 않다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 유투브, 페이스북과 같은 서비스들에 서버가 단 1개라면??&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물리적인 거리에 있어서도 영향을 받을 것이고, 수많은 요청을 서버가 감당하게 되면서 말 그래도 서버에 부하가 걸리게 된다. 즉 네트워크의 트래픽이 증가한다는 것인데,&amp;nbsp; &lt;b&gt;이때 이러한 수많은 요청을 분산시키는 기술이 CDN이다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1388&quot; data-origin-height=&quot;668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V9oaO/btry7SaYqV6/p6gbjbv4lTNlAMAjmT7mVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V9oaO/btry7SaYqV6/p6gbjbv4lTNlAMAjmT7mVK/img.png&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp;https://hongku.tistory.com/320&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V9oaO/btry7SaYqV6/p6gbjbv4lTNlAMAjmT7mVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV9oaO%2Fbtry7SaYqV6%2Fp6gbjbv4lTNlAMAjmT7mVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1388&quot; height=&quot;668&quot; data-origin-width=&quot;1388&quot; data-origin-height=&quot;668&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;amp;nbsp;https://hongku.tistory.com/320&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Origin 서버로부터 여러 개의 Edge 서버를 두는데 &lt;br /&gt;Edge 서버는 Origin 서버로부터의 콘텐츠를 캐싱을 통해 동기화를 해 Cache 서버라고 부르기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결국 이러한 여러개의 서버들이 기존&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Origin&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;서버의 트래픽을 분산해서 처리하게 된다. &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 사용자는 자신에게 가장 빠르게 응답을 전달해줄 수 있는&lt;span&gt;&amp;nbsp;&lt;/span&gt;Edge&lt;span&gt;&amp;nbsp;&lt;/span&gt;서버로 요청을 보내게 되고 &lt;br /&gt;그&lt;span&gt;&amp;nbsp;&lt;/span&gt;Edge&lt;span&gt;&amp;nbsp;&lt;/span&gt;서버는&lt;span&gt;&amp;nbsp;&lt;/span&gt;Origin&lt;span&gt;&amp;nbsp;&lt;/span&gt;서버의 콘텐츠를 캐싱하고 있다고 했다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;캐싱에도 2가지 방식이 있다.&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 정적 캐싱&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 어떠한 콘텐츠를 사용자가 요청을 보내기 전에 미리 Edge 서버에서 컨텐츠를 캐싱하는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 주로 용량이 큰 콘텐츠들은 정적 캐싱을 통해 이미 콘텐츠를 가지고 있는 경우가 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 동적 캐싱&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사용자가 요청을 보내면 해당 콘텐츠가 Edge 서버에 있는지 확인하고 없으면 그때 해당 콘텐츠를 받아오는 캐싱 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Edge 서버에 콘텐츠가 있으면 Cache Hit , 없으면 Cache Miss 라고 부르며, 결국 Cache Miss의 경우 해당 콘텐츠를 받아온다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;위에 정적 캐싱과 동적 캐싱은 정적 콘텐츠와 동적 컨텐츠와는 완전히 다른 의미이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정적 컨텐츠&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- HTML, CSS, JS, Image 파일과 같이 내용이 고정되어 있는 것들을 정적 콘텐츠라고 부르며&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;동적 컨텐츠&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 어떠한 최신 정보를 불러오는&amp;nbsp; API 요청의 결과와 같이 어떠한 요청으로 결과 값이 달라질 수 있는 변할 수 있는 데이터, 값 등을 동적 콘텐츠라 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CDN 업체에 따라 정적 콘텐츠만 캐싱하거나, 동적 컨텐츠를 바이트 단위로 분석해서 바뀐 부분만 다시 캐싱하는 등 서비스를 제공하는 업체별로 동적 컨텐츠 전달 속도를 높이며 제공하는 업체들도 있다고 한다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;추가로 TTL을 상황과 용도에 맞게 설정하여 관리한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;TTL (Time To Live) : 데이터가 캐시에 얼마만큼 남아 있을지 지정하는 값을 말함.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;사용자가 콘텐츠를 받아오는 방법&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Cache Hit&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사용자와 가장 가깝고 빠른 요청과 응답이 가능한 Edge 서버로 요청을 보내고 Cache Hit일 경우 컨텐츠를 사용자에게 전송한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1476&quot; data-origin-height=&quot;712&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oIjdr/btrzadlRBYJ/tcCJpXJ6agxWLHvC549IHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oIjdr/btrzadlRBYJ/tcCJpXJ6agxWLHvC549IHK/img.png&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp;https://hongku.tistory.com/320&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oIjdr/btrzadlRBYJ/tcCJpXJ6agxWLHvC549IHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoIjdr%2FbtrzadlRBYJ%2FtcCJpXJ6agxWLHvC549IHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;241&quot; data-origin-width=&quot;1476&quot; data-origin-height=&quot;712&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;amp;nbsp;https://hongku.tistory.com/320&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Cache Miss&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사용자가 원하는 콘텐츠가 없는 경우, Edge 서버는 Origin 서버로 요청을 보내 콘텐츠를 받아오고 해당 컨텐츠를 캐싱하고 사용자에게 전송한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1476&quot; data-origin-height=&quot;712&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mSt9E/btry9ogR7U7/7uifNpI7nyx9NcxXSksJkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mSt9E/btry9ogR7U7/7uifNpI7nyx9NcxXSksJkk/img.png&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp;https://hongku.tistory.com/320&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mSt9E/btry9ogR7U7/7uifNpI7nyx9NcxXSksJkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmSt9E%2Fbtry9ogR7U7%2F7uifNpI7nyx9NcxXSksJkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;241&quot; data-origin-width=&quot;1476&quot; data-origin-height=&quot;712&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;amp;nbsp;https://hongku.tistory.com/320&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CDN은 웹페이지, 이미지, 동영상 등 서버에서 사용자에게로 전송하는 역할을 한다. &lt;br /&gt;&lt;/b&gt;&lt;b&gt;이러한 전송에 대한 개념은 클라이언트와 서버 간 데이터 통신과 같은 말이다. &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;즉 CDN이라는 개념이 없어도 서버에서 사용자로 콘텐츠를 전송할 수 있다. 당연한 얘기다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하지만 CDN을 사용함으로써 챙길 수 있는 강력한 이점들이 많기 때문에 CDN을 사용한다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;CDN을 사용하는 이유 (장점)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 서버 호스팅 비용 감소&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Origin 서버로 많은 요청이 들어오지 않기 때문에 대역폭 비용을 크게 아낄 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 즉 서버를 운용하는 비용보다 CDN을 사용하고 운영하는 비용이 훨씬 저렴하다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 여기서 대역폭이란? : 주어진 시간 안에 데이터를 얼마나 많이 실어서 보낼 수 있는가를 나타내는 지표이다.&lt;br /&gt;(보통 고속도로 2차선, 4차선 8차선 개념으로 이해한다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 웹 사이트 로딩 속도 개선&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 요청과 응답은 실제로 서버와 사용자의 물리적인 주소, 거리 와도 연관이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사용자에게 가장 빠르고, 물리적으로 가까운 주소의 CDN 서버로 요청을 보낼 수 있게 되기 때문에 로딩 속도 개선에 이점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;- 이 장점은 SEO에서도 강점이 있을 수 있는데, 구글은 2010년에 웹 사이트 속도가 검색 엔진 순위에 영향을 줄 것이라고 발표했다고 한다. 참고 주소를 방문하면 굉장히 디테일한 장단점을 확인할 수 있다. (&lt;a href=&quot;https://ohjongsung.io/2017/07/31/content-delivery-network%EC%9D%98-%EC%9E%A5%EC%A0%90%EA%B3%BC-%EB%8B%A8%EC%A0%90&quot;&gt;참고&lt;/a&gt;)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 서버의 안정성 향상&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Origin 서버의 부하가 줄어들음으로 인해 과부하로 인한 예기치 못한 에러의 위험성이 줄어들고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CDN Edga 서버 중 하나에 문제가 생기면 다른 Edge 서버로 연결되기 때문에 안정적인 서비스를 제공할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 보안성 향상&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 대표적으로, 한 번에 많은 요청으로 서버의 과부하를 일으키는 DDos 공격에 대한 보안성 향상에 이점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CDN 서비스를 제공하는 업체들은 이러한 공격에 대해 정상 요청과 비정상 요청을 구분하거나, 집중된 요청을 수많은 Edge 서버로 분산시키는 등의 방법으로 보안성을 높인다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;그렇다면 CDN의 단점은?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 특정 국가나 지역만을 타깃으로 하는 웹 서비스를 운영한다면 CDN 서비스를 활용할 필요가 없다. 이 경우 CDN을 이용하면 오히려 불필요한 연결 지점이 늘어나 웹 사이트의 성능 저하를 불러올 수 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CDN을 위한 Cache Server들이 많이 보유되지 않거나 성능이 안정적이지 않다면 최악의 경우 SPOF(단일 장애점) 문제(즉 한 군데가 중단되면 전체 시스템이 중단되어버리는 현상)가 발생할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 단점 또한 구체적으로 확인할 수 있는 블로그를 참고하면 좋을 것 같다. (&lt;a href=&quot;https://ohjongsung.io/2017/07/31/content-delivery-network%EC%9D%98-%EC%9E%A5%EC%A0%90%EA%B3%BC-%EB%8B%A8%EC%A0%90&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;참고&lt;/a&gt;)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;출처 및 참고&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://libertegrace.tistory.com/entry/Network-CDNContents-Delivery-Network-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://libertegrace.tistory.com/entry/Network-CDNContents-Delivery-Network-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ohjongsung.io/2017/07/31/content-delivery-network%EC%9D%98-%EC%9E%A5%EC%A0%90%EA%B3%BC-%EB%8B%A8%EC%A0%90&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ohjongsung.io/2017/07/31/content-delivery-network%EC%9D%98-%EC%9E%A5%EC%A0%90%EA%B3%BC-%EB%8B%A8%EC%A0%90&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://goddaehee.tistory.com/173&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://goddaehee.tistory.com/173&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://hongku.tistory.com/320&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://hongku.tistory.com/320&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=_kcoeK0ITkQ&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;얄팍한 코딩사전 Youtube&lt;/a&gt;&lt;/p&gt;</description>
      <category>네트워크</category>
      <category>CDN</category>
      <category>CDN 이해하기</category>
      <category>cdn이란</category>
      <category>CDN이란?</category>
      <author>codermun</author>
      <guid isPermaLink="true">https://codermun-log.tistory.com/610</guid>
      <comments>https://codermun-log.tistory.com/610#entry610comment</comments>
      <pubDate>Tue, 12 Apr 2022 18:42:53 +0900</pubDate>
    </item>
    <item>
      <title>[TS] fetch API return type</title>
      <link>https://codermun-log.tistory.com/608</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;타입스크립트로 개발을 해오면서 매개변수는 어떤 타입을 받아야하고, 함수는 입력에 따른 출력으로 어떤 타입을 리턴해야하는지 명시하여 코드의 안정성을 높히며 사용을 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅은 컴포넌트 내에서는 당연하게 생각하였던 부분들이 API 로직을 사용하는 부분에서는 별도로 return type을 명시하지 않았던 지난 날을 반성하며 잊어 먹지 않기 위해 포스팅하려 한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;922&quot; data-origin-height=&quot;808&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWEWGp/btryQ00hzt6/iYmtQAwGxnXUnEqbEXqB8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWEWGp/btryQ00hzt6/iYmtQAwGxnXUnEqbEXqB8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWEWGp/btryQ00hzt6/iYmtQAwGxnXUnEqbEXqB8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWEWGp%2FbtryQ00hzt6%2FiYmtQAwGxnXUnEqbEXqB8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;438&quot; data-origin-width=&quot;922&quot; data-origin-height=&quot;808&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;간단하게 어떤 value 값을 받아 http 요청을 보내고 이에 대한 응답을 받는 async/await을 사용한&lt;br /&gt;fetch api 기본 로직이다.&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1649408825832&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const testAPI = async (value: string) =&amp;gt; {
  try {
    const res = await fetch(
      `blabalURL...key=${value}`,
    );

    if (res.ok) {
      return await res.json();
    }

    throw new Error('API Error');
  } catch (e: unknown) {
    alert(e);
  }
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;fetch의 경우 디폴트 값은 'GET' 방식으로 옵션을 따로 설정하지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 언급했던 바와 같이 어떠한 입력으로 발생하는 출력 결과, 즉 return 값에 대한 타입을 정의해주며 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 항상 보면 API 로직에서는 return 값을 정의하지 않고 사용을 해왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 놓쳤던 부분을 상기하고, 이제부터라도 더 꼼꼼하게 타입스크리브를 사용해보려 한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 로직에서 return 값을 정의해주는 방법은 크게 2가지가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 함수의 리턴 타입 추론&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1649409308524&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const testAPI = async (value: string): Promise&amp;lt;ITestInterface&amp;gt; =&amp;gt; {
  try {
    const res = await fetch(
      `blabalURL...key=${value}`,
    );

    if (res.ok) {
      return await res.json();
    }

    throw new Error('API Error');
  } catch (e: unknown) {
    alert(e);
  }
};&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. as 다운 캐스팅&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 캐스팅이란?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;형변환을 뜻하는 용어로 업캐스팅과 다운캐스팅이라는 개념이 있다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;업캐스팅 - 자식 클래스가 부모 클래스의 타입으로 캐스팅되는 경우&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;다운캐스팅 - 부모 클래스가 자식 클래스의 타입으로 캐스팅 되는 경우가 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;보통 명시적으로 타입을 선언해주는 경우!! (return, 지금이 그렇다)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;as 키워드를 사용하여 타입을 강제하지 않는다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기에 아래 방법보다는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;위의 함수의 리턴 타입을 명시적으로 정의해주 방법이 더 좋은 방법이라고 생각한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1649409458053&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const testAPI = async (value: string) =&amp;gt; {
  try {
    const res = await fetch(
      `blabalURL...key=${value}`,
    );

    if (res.ok) {
      return (await res.json() as Promise&amp;lt;ITestInterface&amp;gt;);
    }

    throw new Error('API Error');
  } catch (e: unknown) {
    alert(e);
  }
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>TypeScript</category>
      <author>codermun</author>
      <guid isPermaLink="true">https://codermun-log.tistory.com/608</guid>
      <comments>https://codermun-log.tistory.com/608#entry608comment</comments>
      <pubDate>Fri, 8 Apr 2022 18:31:19 +0900</pubDate>
    </item>
    <item>
      <title>브라우저 랜더링</title>
      <link>https://codermun-log.tistory.com/607</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이전 DOM에 관해 글을 남긴 적이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;면접을 보게 되면서 무언가 깔끔하고 장황하지 않게 정리한 점과 몰랐던 부분에 대해 기록으로 남겨보자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알고 있는데, 듣기 쉽고 알아듣기 쉽도록 말하는 것도 능력이지 않을까 싶다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;브라우저 랜더링 정리&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;브라우저는 HTML, CSS, JS, 이미지, 폰트 파일 등 랜더링에 필요한 리소스를 서버에 요청하고 응답을 받는다.&lt;/li&gt;
&lt;li&gt;브라우저의 랜더링 엔진인 서버로 부터 응답받은 HTML, CSS를 파싱 하여 DOM과 CSSOM 트리를 생성하고 이 둘을 결합해 랜더 트리를 생성한다.&lt;/li&gt;
&lt;li&gt;브라우저의 자바스크립트 엔진은 서버로 부터 응답받은 JS를 파싱 하여 AST(&lt;span style=&quot;background-color: #ffffff; color: #3d3d3d;&quot;&gt;Abstract Syntax Tree)를 생성하고 바잍트 코드로 변환하여 이를 실행한다. 이때 js가 DOM API를 통해 DOM or CSSOM 트리를 변경한다면 변경된 DOM CSSOM은 다시 랜더 트리로 결합된다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;이렇게 랜더트리를 기반으로 HTML 요소의 레이아웃(위치, 크기)등을 계산하고 브라우저는 HTML 요소를 그린다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1394&quot; data-origin-height=&quot;790&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PSJj9/btrtajscU4x/OtpbdHobGPOgcySdvH2kE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PSJj9/btrtajscU4x/OtpbdHobGPOgcySdvH2kE1/img.png&quot; data-alt=&quot;https://poiemaweb.com/js-browser&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PSJj9/btrtajscU4x/OtpbdHobGPOgcySdvH2kE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPSJj9%2FbtrtajscU4x%2FOtpbdHobGPOgcySdvH2kE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1394&quot; height=&quot;790&quot; data-origin-width=&quot;1394&quot; data-origin-height=&quot;790&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://poiemaweb.com/js-browser&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 랜더링 엔진은 각 브라우저 별로 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크롬 - 블링크 / 사파리 = 웹킷 / 파이어폭스 = 개코&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;796&quot; data-origin-height=&quot;174&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BxcrT/btrtejE73gP/7kS2YkdVChCV6P2QyfUOqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BxcrT/btrtejE73gP/7kS2YkdVChCV6P2QyfUOqK/img.png&quot; data-alt=&quot;https://d2.naver.com/helloworld/59361&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BxcrT/btrtejE73gP/7kS2YkdVChCV6P2QyfUOqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBxcrT%2FbtrtejE73gP%2F7kS2YkdVChCV6P2QyfUOqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;796&quot; height=&quot;174&quot; data-origin-width=&quot;796&quot; data-origin-height=&quot;174&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://d2.naver.com/helloworld/59361&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;그럼 여기서 면접 질문을 추가로 알아보자.&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 받은 면접 질문은 브라우저가 js 즉, scirpt 태그를 만나면 어떻게 되는가? 였다&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;브라우저의 랜더링 엔진은 자바스크립트를 파싱 할 수 없기 때문에 자바스크립트 엔진으로 권한을 위임하게 되는데 이때 DOM 생성 프로세스를 중지하는 블로킹이 발생된다.&lt;/li&gt;
&lt;li&gt;이후 자바스크립트 엔진의 파싱이 완료가 되면 중단되었던 시점으로 돌아가 다시 DOM을 생성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지는 나름 좋은 답변이라고 생각했는데, 그다음 질문에서 당황하였다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그럼 CSS link, style 태그를 만났을때도 블로킹이 발생하나요?&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;s&gt;나의 대답은 No 였다. 여기에서 딱 마무리되었다.&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;이 질문을 마지막으로 2차 면접을 진행하였는데, 아무리 생각해도 잘 못 말한 것 같았다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;정답을 먼저 말하자면 Yes 이다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 link, style이 블로킹이 발생하지 않았을 거라 생각했던 이유&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;브라우저의 랜더링 엔진이 html, css 파서를 모두 가지고 있으니 별도로 엔진에 위임을 할 필요가 없다고 생각했고 그렇기에 블로킹이 발생하지 않을 거라 생각했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2차 면접을 앞두고 생각해보니 아무리 생각해도 잘못 대답한 것 같았다.&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;css를 통해서는 CSSOM 트리를 생성하는데, 그럼 DOM 생성 프로세스가 잠시 중단돼야 하지 않았을까?&lt;/li&gt;
&lt;li&gt;그렇다, 답변을 제대로 하지 못했다. 이것이 내가 이 글을 포스팅하는 이유이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 브라우저의 랜더링 엔진은 HTML 문서를 한 줄 한줄 순차적으로 파싱 하다가 CSS를 로드하는 link style 태그를 만나면 DOM 생성 프로세스를 중지하고, CSSOM 생성하는 프로세스가 진행된다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 생성된 DOM, CSSOM 트리를 통해 랜더 트리를 만들고 화면에 그리게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;결론, link, style 태그를 만나면 DOM 생성 프로세스가 &lt;span style=&quot;color: #ee2323;&quot;&gt;중단&lt;/span&gt;된다. &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;즉, &lt;span style=&quot;color: #ee2323;&quot;&gt;CSS, JS는 브라우저 랜더링의 블로킹 요소로 작용&lt;/span&gt;한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 추가사항 &lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;defet는 아는데 async는 무엇일까??&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 대한 질문을 받지는 않았지만, css 블로킹을 보며 알게 된 내용을 기록으로 남긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;역시 무언가가 왜 생겨났는지 역사를 살펴보면 다 이유가 있다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;먼저, async / defer 속성은 왜 나오게 된 걸까?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 자바스크립트에 의한 블로킹 현상을 해결하기 위해 &lt;b&gt;HTML5부터&lt;/b&gt; async defer 속성이 추가되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;async와 defer의 공통점&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 속성 모두 HTML 파싱과 자바스크립트 파일 로드를 비동기적으로 동시에 진행하게 만들어 준다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;async 와 defer 의 차이점&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트 실행 시점의 차이가 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;async&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트 파싱과 실행이 파일이 로드된 직후 바로 진행이 되기 때문에 이때 HTML 파싱이 중단된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 비동기적으로 동시에 진행이 가능하지만, 완료된 순서로 실행되기 때문에 실행 순서를 보장할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 async를 사용해도 DOM 생성 프로세스가 중단될 가능성이 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;136&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bG1nFT/btrteiGd1aD/NW81sZ4TjUmDEyIJkmlcmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bG1nFT/btrteiGd1aD/NW81sZ4TjUmDEyIJkmlcmK/img.png&quot; data-alt=&quot;https://devcecy.com/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%A0%8C%EB%8D%94%EB%A7%81-%EB%90%A0%EA%B9%8C/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bG1nFT/btrteiGd1aD/NW81sZ4TjUmDEyIJkmlcmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbG1nFT%2FbtrteiGd1aD%2FNW81sZ4TjUmDEyIJkmlcmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;786&quot; height=&quot;136&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;136&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://devcecy.com/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%A0%8C%EB%8D%94%EB%A7%81-%EB%90%A0%EA%B9%8C/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;defer&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트 파일을 비동기적으로 동시에 로드를 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 async와 다르게 HTML 파싱이 완료된 직후, 즉 DOM을 생성한 이후에 자바스크립트를 파싱 하고 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DOM 생성 프로세스 진행 중 자바스크립트에서 DOM API를 통해 DOM을 조작하면 예기치 못한 에러를 발생시킬 수 있는데 결국 이러한 문제를 방지하는 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;왜 async는 보지를 못했는데, defet는 알고 있는지 이유도 해결해 보았다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;799&quot; data-origin-height=&quot;172&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JVzk2/btrtk1Kfil0/RSAohXA2TxU8AkCAZfHdqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JVzk2/btrtk1Kfil0/RSAohXA2TxU8AkCAZfHdqk/img.png&quot; data-alt=&quot;https://devcecy.com/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%A0%8C%EB%8D%94%EB%A7%81-%EB%90%A0%EA%B9%8C/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JVzk2/btrtk1Kfil0/RSAohXA2TxU8AkCAZfHdqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJVzk2%2Fbtrtk1Kfil0%2FRSAohXA2TxU8AkCAZfHdqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;799&quot; height=&quot;172&quot; data-origin-width=&quot;799&quot; data-origin-height=&quot;172&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://devcecy.com/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%A0%8C%EB%8D%94%EB%A7%81-%EB%90%A0%EA%B9%8C/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;랜더링 참고자료&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1: &lt;a href=&quot;https://devcecy.com/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%A0%8C%EB%8D%94%EB%A7%81-%EB%90%A0%EA%B9%8C/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://devcecy.com/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%A0%8C%EB%8D%94%EB%A7%81-%EB%90%A0%EA%B9%8C/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1644828981630&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;브라우저는 어떻게 렌더링 될까? - devCecy : 뎁쎄씨&quot; data-og-description=&quot;오늘은 클라이언트가 서버로부터 응답받은 데이터를 어떻게 브라우저에 렌더링하는지 그 과정에 대해 알아보겠습니다.&quot; data-og-host=&quot;devcecy.com&quot; data-og-source-url=&quot;https://devcecy.com/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%A0%8C%EB%8D%94%EB%A7%81-%EB%90%A0%EA%B9%8C/&quot; data-og-url=&quot;https://devcecy.com/브라우저는-어떻게-렌더링-될까/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/QROZ3/hyNpjdhHPn/N95URgkZa6cogmFCqF5n1K/img.png?width=2028&amp;amp;height=1202&amp;amp;face=0_0_2028_1202,https://scrap.kakaocdn.net/dn/NOZxU/hyNpkceop1/SSkKODfhbkp8BZ3dbAVz8K/img.png?width=1024&amp;amp;height=825&amp;amp;face=0_0_1024_825,https://scrap.kakaocdn.net/dn/dUy67p/hyNpn05hfQ/CaNCerimhyHVXtqyq82ZHk/img.png?width=1024&amp;amp;height=578&amp;amp;face=0_0_1024_578&quot;&gt;&lt;a href=&quot;https://devcecy.com/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%A0%8C%EB%8D%94%EB%A7%81-%EB%90%A0%EA%B9%8C/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://devcecy.com/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%A0%8C%EB%8D%94%EB%A7%81-%EB%90%A0%EA%B9%8C/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/QROZ3/hyNpjdhHPn/N95URgkZa6cogmFCqF5n1K/img.png?width=2028&amp;amp;height=1202&amp;amp;face=0_0_2028_1202,https://scrap.kakaocdn.net/dn/NOZxU/hyNpkceop1/SSkKODfhbkp8BZ3dbAVz8K/img.png?width=1024&amp;amp;height=825&amp;amp;face=0_0_1024_825,https://scrap.kakaocdn.net/dn/dUy67p/hyNpn05hfQ/CaNCerimhyHVXtqyq82ZHk/img.png?width=1024&amp;amp;height=578&amp;amp;face=0_0_1024_578');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;브라우저는 어떻게 렌더링 될까? - devCecy : 뎁쎄씨&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;오늘은 클라이언트가 서버로부터 응답받은 데이터를 어떻게 브라우저에 렌더링하는지 그 과정에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;devcecy.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2: &lt;a href=&quot;https://coffeeandcakeandnewjeong.tistory.com/34&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://coffeeandcakeandnewjeong.tistory.com/34&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1644830008964&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[프론트엔드] 성능 최적화 정리&quot; data-og-description=&quot;목차 0. 개요 1. 브라우저 동작 원리 2. 성능 최적화 2.1 페이지 로드 최적화 2.2 페이지 렌더링 최적화 3. 성능 측정 기준 3.1 브라우저 내부 이벤트 기준 3.2 사용자 기준 성능 지표 3.3 사용자 기준 성&quot; data-og-host=&quot;coffeeandcakeandnewjeong.tistory.com&quot; data-og-source-url=&quot;https://coffeeandcakeandnewjeong.tistory.com/34&quot; data-og-url=&quot;https://coffeeandcakeandnewjeong.tistory.com/34&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bFM3TV/hyNphNu9CZ/OyJVKFjtRBhDNG7YKIiHMK/img.png?width=280&amp;amp;height=280&amp;amp;face=0_0_280_280,https://scrap.kakaocdn.net/dn/gj5Df/hyNpolyspo/n3lWPRyEEmgiyDXbWbeUL0/img.png?width=280&amp;amp;height=280&amp;amp;face=0_0_280_280,https://scrap.kakaocdn.net/dn/bMeRyG/hyNpmH0mbL/n7PxZFPhAYgv6EEiB8JHKK/img.jpg?width=1920&amp;amp;height=943&amp;amp;face=0_0_1920_943&quot;&gt;&lt;a href=&quot;https://coffeeandcakeandnewjeong.tistory.com/34&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://coffeeandcakeandnewjeong.tistory.com/34&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bFM3TV/hyNphNu9CZ/OyJVKFjtRBhDNG7YKIiHMK/img.png?width=280&amp;amp;height=280&amp;amp;face=0_0_280_280,https://scrap.kakaocdn.net/dn/gj5Df/hyNpolyspo/n3lWPRyEEmgiyDXbWbeUL0/img.png?width=280&amp;amp;height=280&amp;amp;face=0_0_280_280,https://scrap.kakaocdn.net/dn/bMeRyG/hyNpmH0mbL/n7PxZFPhAYgv6EEiB8JHKK/img.jpg?width=1920&amp;amp;height=943&amp;amp;face=0_0_1920_943');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[프론트엔드] 성능 최적화 정리&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;목차 0. 개요 1. 브라우저 동작 원리 2. 성능 최적화 2.1 페이지 로드 최적화 2.2 페이지 렌더링 최적화 3. 성능 측정 기준 3.1 브라우저 내부 이벤트 기준 3.2 사용자 기준 성능 지표 3.3 사용자 기준 성&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;coffeeandcakeandnewjeong.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3: &lt;span style=&quot;color: #777777;&quot;&gt;&lt;a href=&quot;https://poiemaweb.com/js-browser&quot;&gt;https://poiemaweb.com/js-browser&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4: &lt;span style=&quot;color: #777777;&quot;&gt;&lt;a href=&quot;https://d2.naver.com/helloworld/59361&quot;&gt;https://d2.naver.com/helloworld/59361&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>HTML</category>
      <category>async와 defer</category>
      <category>개발자 면접 준비</category>
      <category>브라우저 css 블로킹</category>
      <category>브라우저 랜더링</category>
      <category>브라우저 블로킹 요소</category>
      <category>프론트엔드 면접 준비</category>
      <author>codermun</author>
      <guid isPermaLink="true">https://codermun-log.tistory.com/607</guid>
      <comments>https://codermun-log.tistory.com/607#entry607comment</comments>
      <pubDate>Mon, 14 Feb 2022 18:10:48 +0900</pubDate>
    </item>
    <item>
      <title>TypeScript + Webpack + Babel 을 사용하는 이유</title>
      <link>https://codermun-log.tistory.com/605</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프런트엔드 개발을 하면 자연스럽게 따라오는 것들이 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;TypeScript, Webpack, Babel &lt;/b&gt;&lt;b&gt;이전 프로그래머스 교육을 받으며 사용했던 것들이다. (이것 말고도 많겠지만...)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그런 느낌이 있다 개발을 하다 보면 이래서 이걸 사용하는구나?라고 느낄 때가 있지만 누군가 물어본다면 속 시원하게 대답할 수 없을 것 같은 느낌적인 느낌 말이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;다른 사람에게 설명을 하지 못하면 진짜 내 지식이 아니지 않을까 생각한다. &lt;/b&gt;&lt;b&gt;이 기회에 왜 이것들을 사용해야 하는지에 대한 이유를 나름 정리해보려 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;혹시라도 잘못된 내용이 있다면 가감 없이 피드백 해주시면&amp;nbsp;감사하겠습니다.&lt;/b&gt;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignCenter&quot; data-emoticon-type=&quot;friends2&quot; data-emoticon-name=&quot;050&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends2/large/050.png&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends2/large/050.png&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;844&quot; data-origin-height=&quot;396&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DMlbs/btrrVm21YDj/dKcJs2kScWskSZgGFkq4tK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DMlbs/btrrVm21YDj/dKcJs2kScWskSZgGFkq4tK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DMlbs/btrrVm21YDj/dKcJs2kScWskSZgGFkq4tK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDMlbs%2FbtrrVm21YDj%2FdKcJs2kScWskSZgGFkq4tK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;396&quot; data-origin-width=&quot;844&quot; data-origin-height=&quot;396&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;왜 TypeScript를 사용하는가?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;JavaScript는 동적 타입의 인터프리터 언어이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동적 타입이라는 의미는 number, string과 같은 자료형의 타입을&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소스 코드를 빌드하는 컴파일 환경이 아닌, 실행하는 런타임 환경에서 결정한다는 의미이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 편하고 빠르게 개발할 수 있는 장점이 있으나, 예기치 못한 에러를 발생하는 원인으로 작용하기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여담이지만, 이 때문에 JAVA, C, C++과 같은 정적 타입의 언어와 달리 JavaScript, Python과 같은 동적 타입의 언어를 싫어하는 개발자도 있다고 알고 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;본론으로 그래서 왜 TypeScript를 사용하는 걸까?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;TypeScript를 간단하게 설명하자면 타입이 적용된 JavaScript이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #4d5156;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;타입 스크립트 컴파일러&lt;span style=&quot;background-color: #ffffff; color: #4d5156;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;또는 바벨(Babel)을 통해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;자바스크립트&lt;span style=&quot;background-color: #ffffff; color: #4d5156;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;코드&lt;/span&gt;로&lt;span style=&quot;background-color: #ffffff; color: #4d5156;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;변환하는 과정이 필요한 것이 특징이다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;1. 타입이 존재&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입이 존재함으로써 &lt;b&gt;코드의 안전성이 높아&lt;/b&gt;지고, 실제로 코드를 테스트하기 이전 단계&lt;b&gt;(컴파일 환경)&lt;/b&gt;에서 에러를 캐치할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 타입을 통해 특정 로직이 어떤 역할을 수행하는지 등 &lt;b&gt;가독성이 높아지는 효과도 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;2. JavaScript 100% 호환&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 말한 바와 같이 TypeScript는 타입이 적용된 JavaScript이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 이전 JavaScript로 작성된 프로젝트를 TypeScript로 점진적 리팩토링에 있어 매우 큰 강점을 갖는다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;844&quot; data-origin-height=&quot;248&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lSXAh/btrrQ8rm0tf/pQ0BRsCuDuli3D8nF7qEWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lSXAh/btrrQ8rm0tf/pQ0BRsCuDuli3D8nF7qEWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lSXAh/btrrQ8rm0tf/pQ0BRsCuDuli3D8nF7qEWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlSXAh%2FbtrrQ8rm0tf%2FpQ0BRsCuDuli3D8nF7qEWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;88&quot; data-origin-width=&quot;844&quot; data-origin-height=&quot;248&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;왜 Webpack을 사용하는가?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;1. 빠른 로딩 속도와 높은 성능&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹사이트 진입 시 브라우저는 서버로부터 해당 애플리케이션의 자원(HTML, CSS, JS, Image)등을 다운로드한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 자바스크립트 번들러인 웹팩을 사용하여 여러 개의 자원을 하나의 이상의 파일로 병합시켜준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 서버로부터 받아야 하는 자원이 줄어드는 효과가 있어, 네트워크의 부하를 줄일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;즉, 네트워크 요청 자체가 줄어든다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 초기 진입 시 모든 리소스를 한 번에 다운로드하는 SPA의 단점을 보완하기 위해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필요한 리소스는 그때그때 받아오자는 원리로 Lazy-loading과 code splitting 기능을 함께 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;2. 웹 개발 작업 자동화 도구 (web task manager)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹에서 가장 많이 하는 것 vscode 같이 편집기에서 코드 수정하고 저장하고 웹에서 확인 및 새로고침 하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;html,css,js 압축, 이미지 압축, scss-&amp;gt;css 전처리 변환 와 같은 작업들을  웹팩이 자동으로 관리해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;3. 파일 단위의 자바스크립트 모듈 관리의 필요성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;먼저, 해당 이유를 이해하기 위해선 웹팩의 등장 배경을 알아보는 것이 좋다. (가장 좋은 참고 자료- Inkyo 님의 블로그(&lt;a href=&quot;https://ingg.dev/webpack/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;))&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ES6 이후부터 자바스크립트에서 표준 모듈 시스템을 제안하였고 이것이 export/import 방식이 등장하였다. 그러나 모든 모든 브라우저에서 ES6 방식의 모듈 시스템을 지원하지는 않았다. 따라서 개발자들은 &lt;b&gt;브라우저와 버전에 상관없이 편리한 모듈 시스템을 사용하기를&amp;nbsp;원했고&lt;/b&gt; 이러한 배경에 의해 등장하게 된 툴이 웹팩이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;854&quot; data-origin-height=&quot;354&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bb2W7Q/btrrPGWF93z/QSCEO7Jon9wXDABiEF5BAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bb2W7Q/btrrPGWF93z/QSCEO7Jon9wXDABiEF5BAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bb2W7Q/btrrPGWF93z/QSCEO7Jon9wXDABiEF5BAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbb2W7Q%2FbtrrPGWF93z%2FQSCEO7Jon9wXDABiEF5BAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;124&quot; data-origin-width=&quot;854&quot; data-origin-height=&quot;354&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;왜 Babel을 사용하는가?&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Babel은&amp;nbsp;&lt;b&gt;JavaScript&lt;/b&gt; 컴파일러이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력도 &lt;b&gt;JavaScript&lt;/b&gt;, 출력도 &lt;b&gt;JavaScript이다&lt;/b&gt;. (이 때문에 소스 대 소드 컴파일러 -&amp;gt; 트랜스파일러라고 불리기도 한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Babel은 TypeScript와 JSX 또한 지원한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(JSX는 리액트(페이스북)에서 만든 HTML과 비슷하지만 동일하지 않은 언어로 이를 변환하는 과정 없이는 브라우저가 JSX를 인식할 수 없기 때문에 &lt;span style=&quot;color: #006dd7;&quot;&gt;Babel의 JSX 지원은 React와&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt; Babel을 함께 사용하는 이유&lt;/span&gt;이기도 하다.)&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;여기서 컴파일러와 트랜스파일러를 한번 정리해보고 넘어가자.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;Compile&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;한 언어로 작성된 소스 코드를 다른 언어로 변환하는 것을&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;의미&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;Transplie&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;한 언어로 작성된 소스 코드를 비슷한 수준의 추상화를 가진 다른 언어로 변환&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;하는 것을 말한다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;그럼 Babel은 트랜스파일러라고 불러야 하지 않을까? 하지만 공식문서에서 Babel은 컴파일러라고 말한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;정확하게 말하자면 Babel은 트랜스파일러이자 컴파일러라고 한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;컴파일은 작성된 코드를 컴퓨터의 저수준 실행 파일(일반적으로 기계어 코드)로 바꾸는 포괄적인 용어이며, &lt;/b&gt;&lt;br /&gt;&lt;b&gt;트랜스파일은 때때로 소스-투-소스 컴파일러라고도 하므로 트랜스파일러가 컴파일러의 한 유형 이기 때문에 babel이 컴파일러라고 주장할 수 있다고 한다.&lt;br /&gt;&lt;a href=&quot;https://stackoverflow.com/questions/43968748/is-babel-a-compiler-or-transpiler/&quot;&gt;https://stackoverflow.com/questions/43968748/is-babel-a-compiler-or-transpiler/&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://dev.to/kealanparr/compiling-vs-transpiling-3h9i/&quot;&gt;https://dev.to/kealanparr/compiling-vs-transpiling-3h9i/&lt;/a&gt;&lt;br /&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;모든 언어가 그렇듯 언어 기술은 발전한다. JavaScript 또한 계속 발전해왔다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 중 Babel을 잘 이해하는데 도움이 되는 것이라 한다면 &lt;br /&gt;&lt;b&gt;ES5 -&amp;gt; ES6(&lt;b&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f8f9fa; color: #212529;&quot;&gt;ECMAScript2015&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;)&lt;/b&gt;으로 넘어가는 시점을 들여다보면 좋을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ES6 이전까지는 변수 선언으로 var 키워드를 사용했었다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ES6가 등장하면서 let, const 키워드가 var를 대체하기 시작했다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;대체된 배경을 잠시 짚어보고 넘어가자면&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. var는 중복 선언이 가능했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. var는 블록 레벨 스코프를 지원하지 않고, 함수 레벨 스코프만 지원했다. (전역 변수 오염 문제)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. var 키워드는 생략이 가능했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 호이스팅과 함께 초기화가 된다. ( 선언 및 할당하기 전 식별자에 접근이 가능했다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ES6 이후 let과 const가 등장하면서 var는 사용되면 안 되는 키워드로 전락하게 된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;let과 const는&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 중복 선언이 불가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 블록 레벨 스코프를 지원한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 키워드 생략이 불가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 호이 스팅은 그대로 일어나지만 바로 초기화가 이루어지지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;let, const를 통해 생성된 식별자가 TDZ에 안에 들어가게 됨으로써 식별자가 초기화되지 않은 상태에서 접근할 경우 에러가 발생된다.&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;TDZ(Temporal Dead Zone)&lt;br /&gt;스코프의 시작 지점부터 초기화 시작 지점까지의 구간을 &amp;lsquo;일시적 사각지대(Temporal Dead Zone; TDZ)&amp;rsquo;라고 부른다.&lt;br /&gt;출처 및 참고 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://velog.io/@mgm-dev/let-const-%EA%B7%B8%EB%A6%AC%EA%B3%A0-TDZ&quot;&gt;링크&lt;/a&gt;&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;본론으로 다시 가서! 그래서 Babel을 왜 사용할까?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;1. 크로스 브라우징.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;babel은 JavaScript 컴파일러라고 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;즉, JavaScript (ES6) -&amp;gt; JavaScript(ES5)로 변환해준다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript는 기본적으로 브라우저 내에서만 실행할 수 있고, 브라우저 환경에서만 사용할 수 있는 언어였다. 물론, Node.JS가 등장하기 전까지의 말이지만 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 JavaScript가 발전함에 따라 자연스럽게 브라우저 또한 발전했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 아직도 갤럭시 노트2를 사용하는 사람이 있는 것처럼 모든 사람들이 최신의 브라우저를 사용하는 것은 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결국 브라우저 하위 호환성을 생각하여 ES6로 코드를 작성하여도 구형 브라우저가 이를 인식할 수 있도록 ES5로 변환하는 과정이 필요했다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;또한, 각 브라우저마다 JavaScript 엔진이 다르며 (크롬, 사파리, 파이어폭스...) Babel 모든 브라우저에서 동작하도록 호환성을 지켜준다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;2. 폴리필(polyfill)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Babel을 사용한다고 해서 최신 함수를 사용할 수 있는 것은 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Babel은 &quot;변환&quot;만 해주기 때문이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;즉 , 브라우저 엔진이 구현하지 않는 새로운 함수라면 이를 브라우저에서 실행할 수 없다는 의미이며, 이에 대한 방안이 폴리필이다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;폴리필은 &lt;span style=&quot;background-color: #ffffff;&quot;&gt;개발자가 특정 기능이 지원되지 않는 브라우저를 위해 사용할 수 있는 코드 조각이나 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;플러그인을 의미한다.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;폴리필은 프로그램이 처음에 시작될 때 현재 브라우저에서 지원하지 않는 함수를 검사해서 각 object의 prototype에 붙여주는 역할을 한다. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #555555;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #505050;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #292929;&quot;&gt;babel은 컴파일-타임에 실행되고 babel-polyfill은 런-타임에 실행된다고 한다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://typescript-kr.github.io/pages/tutorials/typescript-in-5-minutes.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;타입스크립트 핸드북&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://webpack.kr/concepts/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;웹팩 공식문서&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://babeljs.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;바벨 공식문서&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.samsungsds.com/kr/insights/TypeScript.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;타입스크립트 참고링크1&lt;/b&gt;&lt;/a&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1643270682990&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;활용도가 높아지는 웹 프론트엔드 언어, 타입스크립트(TypeScript)&quot; data-og-description=&quot;활용도가 높아지는 웹 프론트엔드 언어, 타입스크립트(TypeScript)&quot; data-og-host=&quot;www.samsungsds.com&quot; data-og-source-url=&quot;https://www.samsungsds.com/kr/insights/TypeScript.html&quot; data-og-url=&quot;https://www.samsungsds.com/kr/insights/TypeScript.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fRGz4/hyNey1rIY2/anXmIcCoqB1cDY54hZQU2k/img.jpg?width=900&amp;amp;height=600&amp;amp;face=0_0_900_600&quot;&gt;&lt;a href=&quot;https://www.samsungsds.com/kr/insights/TypeScript.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.samsungsds.com/kr/insights/TypeScript.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fRGz4/hyNey1rIY2/anXmIcCoqB1cDY54hZQU2k/img.jpg?width=900&amp;amp;height=600&amp;amp;face=0_0_900_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;활용도가 높아지는 웹 프론트엔드 언어, 타입스크립트(TypeScript)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;활용도가 높아지는 웹 프론트엔드 언어, 타입스크립트(TypeScript)&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.samsungsds.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ingg.dev/webpack/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;웹팩 참고 링크1 Inkyo 님의 블로그&lt;/b&gt;&lt;/a&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1643263626378&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;[JS] Webpack을 쓰는 이유&quot; data-og-description=&quot;Webpack은 여러개 파일을 하나의 파일로 합쳐주는 모듈 번들러(Module bundler)이다. Webpack을 쓰는 이유는 무엇일까? 표준화된 모듈화 기법이 등장한 것은 ES2015부터인데, Webpack&amp;hellip;&quot; data-og-host=&quot;ingg.dev&quot; data-og-source-url=&quot;https://ingg.dev/webpack/&quot; data-og-url=&quot;https://ingg.dev/webpack/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://ingg.dev/webpack/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ingg.dev/webpack/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[JS] Webpack을 쓰는 이유&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Webpack은 여러개 파일을 하나의 파일로 합쳐주는 모듈 번들러(Module bundler)이다. Webpack을 쓰는 이유는 무엇일까? 표준화된 모듈화 기법이 등장한 것은 ES2015부터인데, Webpack&amp;hellip;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ingg.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://codermun-log.tistory.com/436&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;나의 글&lt;/b&gt;&lt;/a&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1643263663137&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;webpack 이란 무엇인가?&quot; data-og-description=&quot;웹사이트를 구성할때 .js .css .images 파일등 수 많은 들이 모여 웹사이트를 구성하게 된다. 따라서 웹사이트에 접속했을때 굉장히 많은 파일이 다운로드될 수 있는데 이것에 비례하여 서버의 자원&quot; data-og-host=&quot;codermun-log.tistory.com&quot; data-og-source-url=&quot;https://codermun-log.tistory.com/436&quot; data-og-url=&quot;https://codermun-log.tistory.com/436&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/hcGrm/hyNeMSSvsE/xSZZUemJCahtSZIyb7Nxv0/img.png?width=800&amp;amp;height=426&amp;amp;face=0_0_800_426,https://scrap.kakaocdn.net/dn/lrR9B/hyNdn8fO29/OC9vNGwebulro4rxnQzgDK/img.png?width=800&amp;amp;height=426&amp;amp;face=0_0_800_426,https://scrap.kakaocdn.net/dn/cNfphr/hyNeFe8PGT/L2wLkcZNIV8695akc2VLEk/img.png?width=1705&amp;amp;height=910&amp;amp;face=0_0_1705_910&quot;&gt;&lt;a href=&quot;https://codermun-log.tistory.com/436&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://codermun-log.tistory.com/436&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/hcGrm/hyNeMSSvsE/xSZZUemJCahtSZIyb7Nxv0/img.png?width=800&amp;amp;height=426&amp;amp;face=0_0_800_426,https://scrap.kakaocdn.net/dn/lrR9B/hyNdn8fO29/OC9vNGwebulro4rxnQzgDK/img.png?width=800&amp;amp;height=426&amp;amp;face=0_0_800_426,https://scrap.kakaocdn.net/dn/cNfphr/hyNeFe8PGT/L2wLkcZNIV8695akc2VLEk/img.png?width=1705&amp;amp;height=910&amp;amp;face=0_0_1705_910');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;webpack 이란 무엇인가?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;웹사이트를 구성할때 .js .css .images 파일등 수 많은 들이 모여 웹사이트를 구성하게 된다. 따라서 웹사이트에 접속했을때 굉장히 많은 파일이 다운로드될 수 있는데 이것에 비례하여 서버의 자원&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codermun-log.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ljs0705.medium.com/babel-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-a1d0e6bd021a&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;바벨 참고링크1&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1643270561104&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Babel 이해하기&quot; data-og-description=&quot;react로 개발을 하고 있다면 거의 대부분 babel도 함께 사용하고 있을 것이다. create-react-app에도 기본으로 들어있고 기타 react 관련된 튜토리얼을 따라 하다 보면 자연스럽게 babel을 설치하게 된다. &quot; data-og-host=&quot;ljs0705.medium.com&quot; data-og-source-url=&quot;https://ljs0705.medium.com/babel-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-a1d0e6bd021a&quot; data-og-url=&quot;https://ljs0705.medium.com/babel-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-a1d0e6bd021a&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://ljs0705.medium.com/babel-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-a1d0e6bd021a&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ljs0705.medium.com/babel-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-a1d0e6bd021a&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Babel 이해하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;react로 개발을 하고 있다면 거의 대부분 babel도 함께 사용하고 있을 것이다. create-react-app에도 기본으로 들어있고 기타 react 관련된 튜토리얼을 따라 하다 보면 자연스럽게 babel을 설치하게 된다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ljs0705.medium.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://bravenamme.github.io/2020/02/12/what-is-babel/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;바벨 참고링크2&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1643270617424&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;babel 이란 무엇인가?&quot; data-og-description=&quot;들어가며 최근에 react 프로젝트와 typescript 프로젝트를 거치면서 webpack 을 자주 써보고 세팅해보게 되었습니다. 처음에는 동작의 원리보다 요즘 잘나가는 프론트엔드 개발 환경 만들기라는 목표&quot; data-og-host=&quot;bravenamme.github.io&quot; data-og-source-url=&quot;https://bravenamme.github.io/2020/02/12/what-is-babel/&quot; data-og-url=&quot;https://bravenamme.github.io/2020/02/12/what-is-babel/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/2M99L/hyNdrCTKjp/mkSinB2bl01dOL7OGOZg10/img.jpg?width=1200&amp;amp;height=900&amp;amp;face=0_0_1200_900&quot;&gt;&lt;a href=&quot;https://bravenamme.github.io/2020/02/12/what-is-babel/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://bravenamme.github.io/2020/02/12/what-is-babel/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/2M99L/hyNdrCTKjp/mkSinB2bl01dOL7OGOZg10/img.jpg?width=1200&amp;amp;height=900&amp;amp;face=0_0_1200_900');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;babel 이란 무엇인가?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;들어가며 최근에 react 프로젝트와 typescript 프로젝트를 거치면서 webpack 을 자주 써보고 세팅해보게 되었습니다. 처음에는 동작의 원리보다 요즘 잘나가는 프론트엔드 개발 환경 만들기라는 목표&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;bravenamme.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Javascript</category>
      <category>babel을 사용하는 이유</category>
      <category>typescript를 사용하는 이유</category>
      <category>webpack을 사용하는 이유</category>
      <category>바벨을 사용하는 이유</category>
      <category>웹팩을 사용하는 이유</category>
      <category>타입스크립트를 사용하는 이유</category>
      <author>codermun</author>
      <guid isPermaLink="true">https://codermun-log.tistory.com/605</guid>
      <comments>https://codermun-log.tistory.com/605#entry605comment</comments>
      <pubDate>Thu, 27 Jan 2022 14:49:40 +0900</pubDate>
    </item>
  </channel>
</rss>