<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>dev_owon</title>
        <link>https://velog.io/</link>
        <description>공부한 내용들을 정리하는 저장소입니다.</description>
        <lastBuildDate>Fri, 15 Sep 2023 11:53:37 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>dev_owon</title>
            <url>https://velog.velcdn.com/images/dev_dowon/profile/0ad0548c-d119-4149-8133-8a1f64b01f8b/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. dev_owon. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/dev_dowon" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[네트워크 기초 이론 10편(완)]]></title>
            <link>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-%EC%9D%B4%EB%A1%A0-10%ED%8E%B8%EC%99%84</link>
            <guid>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-%EC%9D%B4%EB%A1%A0-10%ED%8E%B8%EC%99%84</guid>
            <pubDate>Fri, 15 Sep 2023 11:53:37 GMT</pubDate>
            <description><![CDATA[<h3 id="mtu와-packet-단편화">MTU와 Packet 단편화</h3>
<p>IP 헤더의 구조는 아래의 그림과 같다. 
<img src="https://velog.velcdn.com/images/dev_dowon/post/02268bb2-ad9a-47e5-9007-70c25f61cba3/image.png" alt=""></p>
<p>단편화의 내용은 Identification + IP Flags + Fragment Offset에 들어가있다.
MTU는 1500byte가 제공된다. MSS: MTU - 20(IP 헤더) - 20(TCP 헤더) ~= 1460bytes
단편화가 발생하는 환경을 아래와같이 시나리오 가정을 해본다. 
<img src="https://velog.velcdn.com/images/dev_dowon/post/cd85505c-f09c-4516-b5b9-56e2e882a50c/image.png" alt=""></p>
<p>그림을 보면 라우터 2번에 MTU가 1400인걸 알 수 있다. PC1번과 서버는 MTU가 1500인데 중간에 끼어있는 라우터의 MTU가 1400밖에 안된다면 라우터 1번과 2번 사이에서 단편화가 발생한다. 1500의 MTU를 한번에 다 담지 못하기에, 패킷을 일정 부분을 잘라서 두개의 패킷을 만들어준다. 두개의 패킷은 IP헤더에 있는  Identification값이 같다. 여기서 Offset값이 다를 수는 있다. 나중에 Offset값을 참조해서 쪼개진 패킷을 다시 조합할 수도 있다.
분할된 패킷을 어디선가 재조립을 해야되는데, 이는 선택에 따라 다를 수 있다. 기본적으로 단편화가 된 데이터를 수신한 쪽에서 재조합을 하게 되어있다, 위의 예제에서선 서버가 된다. 하지만 과도한 단편화는 서버에 과부하를 줄 수 있기에 좋은 현상은 아니다.
요즘은 사실상 기술의 발전에 의해 단편화 현상이 많이 줄어들었다. 그래서 가끔 일어나는 단편화는 VPN(IPSec) 떄문에 발생한다고 본다. 
단편화가 안나게끔 MTU를 조절해서 패킷을 보내면 단편화를 피할 수도 있다고 한다. bps /pps라는 개념이 있다. bps는 데이터의 량에 대해서 설명하는 단위고, PPS는 Packet의 개수, 즉 단편화를 줄여야 PPS가 떨어지고, 데이터 처리 성능이 올라간다. 단편화를 피하기 위해 패킷을 보내는 PC단에서 패킷의 MTU를 낮추는 방법을 하향평준화라 부른다.</p>
<h3 id="packet--segment--header-payload">packet / segment / header/ payload</h3>
<p>Packet는 데이터 덩어리다. 패킷은 두 부분으로 나뉘는데, 각각 header와 payload다. 여기서 header는 IP header다. Payload 부분을 보게되면, 내부에 TCP 헤더가 있고 Data가 있다. 
<img src="https://velog.velcdn.com/images/dev_dowon/post/1b0c66b6-fef7-45ee-bebf-fa1ec77baf9a/image.png" alt=""></p>
<p>IP Payload 내부에 TCP와 Data가 있지만 보통 패킷의 헤더라 함은 IP 헤더 + TCP 헤더를 뜻한다. 그럼 Data는 1460을 가져가고 IP / TCP 헤더에서 각각 20씩 가져간다. Data 부분을 Segment라고 본다. IP 패킷을 뜯어보면 안에 TCP헤더를 포함한 데이터가 있다.
프로세스에서 RWX를 특정 형식(프로토콜)에 따라 동작을 하는데, 인터넷 통신을 하며 데이터 송수신을 할 때 소켓은 파일형식 (Stream)이다. Stream을 패킷의 크기(MTU)에 맞게 잘르고 4계층으로 내려가면 TCP계층에서 TCP 헤더를 붙여 TCP헤더 + Data가 된다. 이를 Segment라고 부르고 그 밑으로 IP 계층으로 내려가면 IP헤더를 붙여 IP 패킷이 된다. NIC 계층으로 내려가면, Ethenet 헤더를 장착시키고 Frame 단위로 재구성 된다. L2관점에서 봤을 때 Payload는 Frame에서 Ethenet헤더 부분을 제외한 내용이다. Payload는 관점에 따라 상대적으로 바뀌는 개념이다. 
TCP가 아니라 UDP라면, 헤더 부분이 Outer부분에 IP/TCP가 아닌 IP/UDP가 있고, UDP일 떈 Payload대신 Datagram이라고 부르기도 한다. </p>
<h3 id="tcp-장애유형-5가지">TCP 장애유형 5가지</h3>
<p>TCP라는 프로토콜은 생각보다 복잡하다. 장애대응의 대원칙은 무조건 장애의 확인 순서는  아래에서 위로다. 인터넷이 안된다면 무조건 물리적인 연결부터 확인하는게 원칙이라는 뜻이다. 
Ethenet 수준의 Loss
엔드포인트 끝단에서 네트워크 구간 전체에서 어떤 일이 일어나는지 모르기에 loss 가 일어날 수 있는 이유가 여러가지 있다. 
TCP 수준에서 DupACK </p>
<p>TCP 수준에서 Retransmission
위의 두 장애 유형은 보내는 쪽에서 Segment하나를 보내고 wait 상태가 되는데, 이때 받는 속도와 보내는 속도가 안맞을 때 발생한다. 이 두가지 유형은 네트워크 지연도 의심해야하고, 커널측에서 문제가 생길 수도 있다. 송수신 쪽의 세팅이(타이머) 안맞아서 그런 경우도 있다.
2,3 문제는 혼잡상태라고 본다. 이를 해결하기 위해 타이머를 조절하여 송수신 속도를 양측 다 떨어뜨린다. 
Zero Window
수신측 버퍼가 꽉차는 현상이기에, 주로 어플리케이션을 확인해봐야한다. 방화벽 등 문제일 수도 있다.
소켓 통신 Reset
소켓이 엔드포인트 프로세스에서 비정상상태로 날라갔을 때 Reset을 비정상적으로 보내는 현상이다. 해킹시도가 있거나 시퀀스가 안맞을 때도 reset이 된다고 한다. 
MSA(multi segment analysis): 구간마다 선을 연결(out ot path)하여 데이터가 사라지는지 체크하여 장애대응을 도와주는 도구.</p>
<h3 id="서브넷팅">서브넷팅</h3>
<p>서브넷을 왜 사용하는지에 대해 알아본다. 192.168.0.10(Cclass)이라는 주소가 있다면, 앞의 세 블록은 Network ID가 되고, 뒤의 10 부분이 Host 번호가 된다. 2진수 기준 0으로 꽉찬 수 또는 1로 꽉찬수는 각각 사용되지 않는 값 또는 Broadcast로서 동작하기에, 하나의 블록에 254개의 주소가 존재할 수 있다. 
리소스 낭비를 막기위해 Network ID 부분을 오른쪽으로 확장시킨다. 한칸만 오른쪽으로 확장해도 254개 주소에서 126개 주소로 경우의 수가 줄어든다. 하지만 표기법은 바꾸지 않는다. 그리고 broadcast address는 127(1로 가득참)이 된다. host 할당 가능범위는 항상 0으로 가득찬 번호~ 1로 가득찬 번호 사이다.
서브넷을 나눌수록 두개의 주소가 낭비된다. 0으로 가득찬 것과 1로 가득찬 주소는 항상 뺴야하기에, 주소가 2개가 준다. 그래서 쪼개기 전보다 더 많은 자원을 아낄 수 있기에 적절한 서브넷 쪼개기는 필요하다.</p>
<p>LAN공간에서 네트워크 분할을 해준다. 한 네트워크에서 Broadcast가 많이 일어날 수록 효율이 떨어진다(ARP이슈). 그래서 네트워크를 분할해준다. ISP입장에선 앞서 말했듯이 네트워크가 낭비되지 않도록 적절한 공간을 할당해준다. 
네트워크가 왜 두개로 더 쪼갤 수 있냐면, 네트워크 아이디를 오른쪽으로 한칸 확장하게되면 한 자리수를 더 사용할 수 있기에 경우의 가지 수가 2배가 된다. 그렇기에 네트워크 분할을 할때마다 두개의 네트워크로 쪼개진다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[네트워크 기초 이론 9편]]></title>
            <link>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-%EC%9D%B4%EB%A1%A0-9%ED%8E%B8</link>
            <guid>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-%EC%9D%B4%EB%A1%A0-9%ED%8E%B8</guid>
            <pubDate>Thu, 14 Sep 2023 12:08:51 GMT</pubDate>
            <description><![CDATA[<h3 id="전세계-인터넷을-중단시키는-방법">전세계 인터넷을 중단시키는 방법</h3>
<p>인터넷은 라우터와 DNS로 이뤄진 분산형 DB다. 계층적으로 존재하기 때문에 전세계적으로 분산 되어있는 Root DNS 13대를 종료하면 전세계의 인터넷을 중단시킬 수 있다.
IP주소에 이름을 지정해준 것을 도메인 네임이라고 한다. 네이버를 검색창에 입력하면 아래와 같은 과정이 일어난다:</p>
<pre><code>1. 컴퓨터 내부에 있는 DNS cache를 검색한다.
2. hosts File을 검색한다.
3. 공유기에서 포워딩을 시도한다. 
4. 인터넷 통신사별로 자사 Cache  DNS를 확인한다. 
5. 마지막으로 DNS를 확인한다. 
6. 만약 해당 DNS에 도메인 주소가 없다면 RootDNS에게 요청을 한다.
7. RootDNS가 해당 DNS에게 도메인 주소와 관련된 DNS목록을 반환한다.
8. 해당 DNS는 목록에서 가장 가까운 DNS를 접속하여 도메인이 있는 서버주소를 get한다.
9. 서버에 해당 도메인 네임의 주소가 있는지 체크하고 있다면 IP주소를 가져온다.
10. 요청을 보낼 때 마다 응답과 함께 유효기간(expiration)을 받아온다. 이는 해당 주소를 Cache처리할 때 사용하게 된다.</code></pre><p>nslookup - [ip address] 를 입력하면 자신이 원하는 IP주소의 출처를 확인할 수 있다.</p>
<p>만약 컴퓨터가 악성코드에 전염된다면, cache 또한 poisoning 될 수 있어서, 원래 접속하던 DNS가 다른 서버 주소에 접근하게 될 수도 있다. </p>
<h3 id="tcpip-통신과-mac주소의-변화">TCP/IP 통신과 MAC주소의 변화</h3>
<p>인터넷은 기본적으로 패킷 스위치 네트워크다. 이는 L3구간이다. 한칸 내려가서 L2로 가게된다면 Packet은 Frame으로 변환된다. 최초 패킷이 생성됐을 때 패킷을 감싸고 있는 Frame이 있는데 그 위에 이더넷 Header가 탑재가 되는데 header의 S-&gt;D(시작점에서 도착지) 정보를 잘 확인해야한다. L2구간을 지나면 Frame의 이더넷 header가 떨어지고 새로운 목적지가 담긴 이더넷 header를 삽입한다. 
사실상 IP 수준(L3계층)에서는 목적지에 대한 생각을 하지 않는다, L2로 넘어왔을 때 Mac address를 기준으로 이더넷 header를 통해 목적지에 전달된다는 뜻이다. 
Mac address가 unique하지만 인터넷의 IP 주소를 Mac address를 기준으로 할 수 없다. 체계 자체가 다르고, L2에서만 사용하기에 IP 주소를 대체할 수는 없다.</p>
<h3 id="l2스위치와-arp작동-원리">L2스위치와 ARP작동 원리</h3>
<p>ARP는 IP주소로 MAC주소를 알아내는 프로토콜이다. L2구간은 MAC이 중요하다. 스위치 허브엔 포트마다 MAC을 저장하고, 전원을 키면 학습모드로 들어가게 된다. 포트 하나에 Port MAC address를 여러개 저장할 수 있으며 이를 용량 단위로 하드웨어 성능을 설명한다. 스위치가 계층적으로 이뤄져있고, 포트가 up-link가 된다면 MAC address 가 여러개로 인식될 수도 있다. 랜선을 갈아 끼우면 (포트가 교체됐을 때) 따로 학습을 시키거나 다른 방식으로 대응을 해줘야한다. 
특정 PC의 전원을 껐다 키면 자신에게 게이트웨이로 설정되어있던 192.168.0.1 의 MAC 주소를 못찾을 때 네트워크 전체에 Broadcast로 192.168.0.1의 위치를 찾는다. 이때 Query를 보내는데, reply가 올땐 unicast로 날아온다. 받은 Reply를 ARP Cache를 한다. 
Broadcast가 닿는 곳을 LAN이라고 볼 수도 있다고 한다. </p>
<h3 id="길-잃은-packet의-소멸과-ttl">길 잃은 Packet의 소멸과 TTL</h3>
<p>PC가 서버로 TCP 연결 요청을 할 때 TTL이라는 값이 헤더에 들어가게된다. 이는 Time To Live는, 라우터와 라우터 간격을 넘어갈 때 마다 Hop을 넘어간다고 하는데 이때 마다 TTL을 하나씩 감소시킨다. TTL은 8bit(2^8) 경우의 가지수가 있다. TTL이 0이 되면 Packet은 소멸하게 된다. 라우팅 설정이 잘못 됐을 때, 패킷이 루프에 빠질 수 있는데, 루프에 빠지면 연관 컴퓨터는 CPU에 과부하가 생겨 문제가 될 수 있다. 특정 라우터에 도착했는데, TTL이 0일 때 ICMP를 이용해 도착지에 응답을 보내준다. 해당 응답은 패킷이 버려졌다는 걸 의미하는데, 보안적인 문제 때문에 응답을 보내지 않을 수도 있다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[네트워크 기초 이론 8편]]></title>
            <link>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-8%ED%8E%B8</link>
            <guid>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-8%ED%8E%B8</guid>
            <pubDate>Tue, 12 Sep 2023 12:03:42 GMT</pubDate>
            <description><![CDATA[<h3 id="tcp-연결이라는-착각에-대해">TCP 연결이라는 착각에 대해</h3>
<p>TCP헤더에 Sequence Number가 바로 packet의 고유 segment 번호다. 시퀀스 번호는 32bit 기준으로 약 4GB(용량으로 환산)정도의 경우의 수가 있다. </p>
<p>ACK넘버 또한 TCP헤더에 기재되어있는 것을 볼 수 있다.
연결지향이라는 관점에 대해서 알아 볼 필요가 있다. 연결이라는 것은 보안적인 측면을 고려해야한다. 사실상 TCP 연결은 착각이다. 
TCP 연결은 3-way handshake가 이루어진다. 이때 단위는 segment다. 3 way-handshake는 사실상 seg번호 + MSS + 혼잡제어 정책에 대한 정보를 교환하는 행위다. 하지만 이런 방식은 보안 정책이 없어서 보안사고가 날 수 있다. </p>
<h3 id="lan-케이블을-뽑았을-때-tcp-연결">LAN 케이블을 뽑았을 때 TCP 연결</h3>
<p>TCP 레이어에선 연결이라는 표현을 쓰지만, 1계층으로 내려가면 Link-up이라는 표현을 사용한다. TCP연결이 성립됐다에는 Virtual Circuit의 연결이 성공했다는 것을 전제에 둔다. 
서버에서 큰 파일을 다운로드 받는 동안, 빠르게 NIC에 연결되어있는 LAN 케이블을 뽑게 된다. 하지만 LAN 케이블을 뽑은 시간이 일정 시간보다 크게된다면, 끊어지는 것을 볼 수 있다.
TCP연결은 가상환경의 논리적으로 유지되고있는 연결이기에 무선 환경에서 기지국을 갈아타도 핸드폰은 TCP연결이 유지될 수 있다. 
이러한 특성이 파일을 다운로드 받을 때는 장점이 될 수 있지만, 실시간 게임과 같은 네트워크 환경에선 TCP연결이 끊어지는 시점이 훨씬 빠를 수 밖에 없다. 
결론적으로 LAN 케이블을 뽑았을 때 TCP의 연결은 일정시간 유지된다. 그리고 연결 지속 시간은 설정에 따라 달라진다. 게임의 아이템 복사 버그도 TCP연결의 지속 현상에 의해 나타난 버그현상이다.</p>
<h3 id="unicast-broadcast-multicast">Unicast, Broadcast, Multicast</h3>
<p>네트워크에서 cast 방식은 총 세가지가 있다. NAT는 network address translation이 있고 라우터는 게이트웨이로서 존재하게 된다. 라우터를 기준으로 네트워크는 내부와 외부로 나눌 수 있다. 같은 네트워크를 공유하는 PC간의 연결을 Unicast라고 부른다. 
호스트번호가 2진수 기준으로 전부 1로 되어있는 곳을 Broadcast로 부른다. Broadcast는 MAC주소가 48(FFFFFFFFFFFF)가 된다. 즉 192.168.0.255으로 무언가 연결을 하면, 같은 네트워크를 공유하고 있는 모든 연결단에 Broadcast를 해준다. Broadcast는 리소스를 많이 차지하기에 네트워크의 성능을 저하시키는 주범이 된다. 시그널을 넘겨준다면, 모든 네트워크 segment에 해당 내용을 전송하게 된다.
Multicast는 특정 Group에 등록된 곳에만 신호를 보내게 된다. 사실상 L2 수준에서 봤을 땐 Broadcast처리가 된다. 
SDN(소프트웨어 정의 네트워킹) 에서 가장 중요한 내용이 바로 Multicast와 Broadcast를 컨트롤 하는 일이다. 이는 클라우드와 밀접한 관계가 있다고 한다. </p>
<h3 id="ip주소의-종류와-특징">IP주소의 종류와 특징</h3>
<p>IP주소는 Global IP / Private IP / Lookback / Broadcast 로 나뉘어진다. v4 기준으로 8bit를 네번 사용할 수 있기에 32bit(2^32) 경우의 가지수가 있다.</p>
<p>Global IP -&gt; Internet(Public, Global) ~= Router + DNS
여기서 라우터는 라우팅을 하는데, 글로벌 IP에 대해서만 Routing을 해줘서 사설 IP에 대해서는 라우팅하지 않는다.</p>
<p>Private IP -&gt; 사설 인터넷. 규모가 글로벌 인터넷보단 작지만 구조는 비슷하다.
Global IP는 보통 같은 IP를 갖고있지 않지만, Private IP는 클래스에 따라서 Private IP가 정해져 있다.
그중 C클래스의 주는 우리가 익숙한 192.168.x.x를 갖고 있다. 즉 Private IP는 공유기에 많이 쓰게 된다. 공유기 IP는 Global IP를 각 PC에 공유해주는 것이다.</p>
<p>Loopback -&gt; 127.0.0.1 -&gt; Host 자신을 의미한다. 이는 사실상 localhost의 주소와 같다. 출발지와 도착지가 모두 같을 때 Loopback을 사용한다. 패킷을 만든다 해도 자신의 가상메모리 상에서 전달하게된다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[네트워크 기초 이론 7편]]></title>
            <link>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-7%ED%8E%B8</link>
            <guid>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-7%ED%8E%B8</guid>
            <pubDate>Mon, 11 Sep 2023 12:17:20 GMT</pubDate>
            <description><![CDATA[<h3 id="tcp-송수신-원리">TCP 송/수신 원리</h3>
<p>PC와 서버가 TCP/IP 연결을 하고, File download하는 상황을 예시로 든다. 
Server:
서버에선 서버 프로그램이 실행되고 Socket이 열려있어 클라이언트와 통신을 할 것 이다. 소켓은 기본적으로 파일이기에 프로세스가 동적으로 메모리 할당을 해준다. 기본적으로 프로세스가 파일에 할 수 있는 조작은 RWX가 있다. (소켓이니 X는 생략) 
소켓이 읽으면 Receive며 쓴다는 Send다. 즉 프로세스가 소켓에 대해 I/O를 실행한다고 생각하면 좋다(Stream). 
HDD에 파일이 들어가 있다고 생각해보자, 그럼 파일 시스템이 드라이버에 접근을 해서 HDD에 데이터를 읽고 쓰는 행위를 반복할 수 있다. HDD에서 데이터를 읽어올 땐 한번에 가져오는 것이 아닌 매우 작은 단위로 쪼개서 적재해온다.
TCP와 소켓이 맞닿는 지점에선 데이터의 분해가 일어난다. 그럼 쪼개온 데이터는 분해지점으로 넘어와 Copy되어 적재한다. 이런 과정을 Buffered I/O라고 한다. TCP에서 IP쪽으로 데이터(buffer)가 넘어가는데 이때 Segment 단위로 한번 더 쪼개준다. 그럼 하나의 Segment를 Packet처리해 한번 더 포장해준다. 그리고 포장된 Packet들을 Frame에 적재하여 데이터 전송을 해준다. 중요한건, Frame에 담긴 Packet은 한번에 엔드포인트에서 엔드포인트로 이동하지 않고, 여러번 Frame을 갈아타면서 전송이 된다.</p>
<p>Client:
도착지 엔드포인트 쪽에 도달하면 다시 클라이언트 단의 소켓을 통해 한번 더 File I/O Buffer를 하게 된다. Frame이 클라이언트 측에 도달하면 decapsulation이 일어나면서 사라지게 되고, TCP단에 바로 Segment로 분해가된다. Segment를 잘 수신되었다면, 다음 Segment 번호를 ACK 해준다. 
서버측에서는 다음 Segment ACK를 Wait하기 때문에 속도지연 발생이 일어난다. 
수신측의 TCP Buffer 사이즈를 윈도우 사이즈라고한다. 이때 window는 운영체제와 관련이 없는 별개의 용어다. ACK에는 window size가 적재되어있는데, 이 사이즈에 따라서 서버측에서 전송할지 말지를 판단한다. window size가 MSS보다 클때만 보내주고, 만약 작다면 클라이언트 측에 window size가 적절크기 이상이 될 때 까지 wait를 하게된다. 그렇기에 데이터 전송 속도는 클라이언트 측의 Read 속도와 밀접한 관계가 있다. 클라이언트의 Read 속도가 서버 전송 속도보다 느리다면 window size가 작다는 이유로 데이터 전송이 지연된다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[네트워크 기초 이론 6편]]></title>
            <link>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-%EC%9D%B4%EB%A1%A0-6%ED%8E%B8</link>
            <guid>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-%EC%9D%B4%EB%A1%A0-6%ED%8E%B8</guid>
            <pubDate>Mon, 11 Sep 2023 11:13:27 GMT</pubDate>
            <description><![CDATA[<h3 id="application-proxy">(Application) Proxy</h3>
<p>라우터와 스위치들은 구조가 Inline / Inline이지만 Out of path로 구현한 것, 그리고 Proxy로 부르는 형식이 있다. 
PC가 인터넷에 연동이 되어있다고 가정을 했을 때, naver에 접속을 한다면, HTTPS와 TCP/IP로 통신을 했을 것이다. 이때 통신을 위해 Socket이 사용된다. 만약 PC와 인터넷 사이에 PC2가 프록시로 설정됐다면, PC는 PC2에 연결이 되고, PC2가 인터넷에 연결이 된다. Proxy의 사전적 정의는 대리자이기에, 네트워크에서의 역할 또한 대리로(한번 거쳐서) 통신을 할 수 있도록 도와준다. 
Proxy의 역할은 Inbound로 들어온 데이터를 Socket#1로 받았을 때, Proxy는 Socket#2에게 똑같은 내용을 전달하여 Outbound되도록 도와준다. 이는 “우회하다”와 흡사한 개념이다.
특정 프로그램이 프록시 역할을 한다라고 한다면, 이를 Usermode Application Proxy라고 부른다. </p>
<pre><code>외울 것
Usermode Application Proxy -&gt; Socket Stream -&gt; Inline + Out of path -&gt; Packet</code></pre><h3 id="proxy의-활용-1-우회">Proxy의 활용 #1: 우회</h3>
<p>프록시 설정을 한다면, PC단에서 특정 주소에 접근을 했을 때 직선적으로 접속하는 것이 아닌, TCP연결이 프록시를 먼저 접속한다음 두번째 TCP를 통해 해당 사이트에 접속하게 된다. 만약 프록시의 주소가 다른 나라가 된다면, 접속한 사이트에선 다른나라에서 HTTP요청을 했다고 인식한다. 이는 VPN으로 우회하는 방식의 기본적인 작동원리와 흡사하다.
프록시를 사용한다면, 프록시에서 모든 통신을 감청할 수 있다. 프록시 서버를 운영하는 측에선 모든 데이터를 읽을 수 있기에 보안적으로 고려를 해야할 수준이 많다. 
VPN은 네트워크 수준에서 많이 쓰고, Proxy는 웹 수준에서 많이 쓴다고 한다.</p>
<h3 id="proxy의-활용-2-분석">Proxy의 활용 #2: 분석</h3>
<p>Web을 사용할 때 HTTP요청을 하게되면 인터넷상에서 모든 요청이 노출되기 마련이다. 이를 보호하기 위해 HTTPS를 이용해 보안처리를 해준다. Wireshark는 필터처럼 TCP/IP와 Driver사이에 위치한다. 하지만 필터링을 해주진 않고 Sensor로서 분석만 한다. 웹 요청을 처리할 때 소켓을 통해 TCP/IP -&gt; Wireshark로 넘어오게 되는데, 이때 https로 암호화처리를 했다면, Wireshark에서 암호화된 HTTP요청을 분석하기엔 애매한 부분이 많다. Packet에선 이미 암호화되어있기에 분석이 힘들어져서, Socket 단계에서 Stream에 Proxy를 설정해주면 된다. 
로컬 수준에서 Proxy설정을 해준다면, Socket에서 Stream이 Proxy의 소켓으로 전해지는데, 이때는 데이터는 암호화가 안되어있는 평문이다. 이를 이용해 데이터의 분석을 편하게 할 수 있다. Fiddler와 같은 프로그램을 이용하면 소켓통신 분석을 해볼 수 있다. </p>
<h3 id="proxy의-활용-3-감시와-보호">Proxy의 활용 #3: 감시와 보호</h3>
<p>모든 PC들은 Proxy설정을 하고 있다는 가정을 하고, 동일한 Proxy 서버를 이용한다. 모든 PC들은 HTTPS통신을 했을 때 프록시서버를 거쳐 서버에 연결이 될 수 있다. 모든 HTTPS요청은 프록시서버를 통과하기 때문에, 악성코드의 유입을 차단해줄 수 있다. 또 다른 예시로, 유저가 특정 사이트에 접속했는지에 대해 감시를 할 수도 있다. 감시와 보호기능을 구현할 수 있기에 Proxy를 어떻게 운용하는지에 따라서 유용한 도구들을 만들 수 있다. 구조를 역으로 이용하면 Proxy로 인터넷 접근 보호에 대한 기능도 구현 할 수 있다.</p>
<h3 id="proxy의-활용-4-reverse">Proxy의 활용 #4:: Reverse</h3>
<p>Proxy를 거쳐야 특정 사이트에 접근할 수 있도록 할 수 있다. 이는 접근제어를 할 수 있으며, 동시에 감시를 할 수도 있다. 프록시에서 해커의 공격인지 아닌지를 서버를 위해 확인하는 경우를 WAF(web application firewall)라고 부른다. 통제하는 단위는 소켓 스트림 단위로(L7 HTTP) 치리한다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[네트워크 기초 이론 5편]]></title>
            <link>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-%EC%9D%B4%EB%A1%A0-5%ED%8E%B8</link>
            <guid>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-%EC%9D%B4%EB%A1%A0-5%ED%8E%B8</guid>
            <pubDate>Mon, 11 Sep 2023 11:12:26 GMT</pubDate>
            <description><![CDATA[<h3 id="wireshark의-작동-구조와-원리">Wireshark의 작동 구조와 원리</h3>
<p>크롬이 작동 중이라면 http통신(L7)를 하면 TCP/IP(L4)을 기반으로 수행한다. Socket-&gt;Stream, TCP-&gt; Segment, IP-&gt;Packet, NIC-&gt;Frame이라고 연관지어 생각하면 좋다.
IP과 Driver사이에 Filter가 존재한다. 통과시켜준다면 Bypass라고 하고 통과되지 않았다면 Drop이라고 한다. 만약 통과에 대한 기능이 없는 단순히 감시를하는 용도로 IP와 Driver사이에 존재한다면, 이를 Sensor라고 한다. Sensor는 항상 Bypass를 하는 대신 데이터를 수집한다. Sensor로 구성된 프로그램은 Npcap이 있다. Sensor가 수집하고 있는 내용을 Wireshark가 청취하고 디코딩을 해준다. 그래서 Wireshark는 Analyzer 라고 설명하지만, 정보수집에 목적에 있어서 Sniffer라는 표현도 있다. 
참고로 트래픽이 네트워크 쪽으로 나가게 된다면 Outbound라 하고 반대로 들어온다면 Inbound라고 한다. </p>
<h3 id="router의-내부구조와-inline">Router의 내부구조와 Inline</h3>
<p>라우터는 L3스위치의 일종이다. L3 스위치는 패킷을 들고 스위칭한다. 보통 하나의 라우터에 연결된 인터페이스는 두 개가 있다. NIC-&gt; 네트워크 인터페이스 카드가 두 장이 있다는 뜻이다. 내부로 들어오는 것과 외부로 나가는 NIC 각각 하나씩 총 두개가 필요하다.
인라인 구조는 패킷이 1번 NIC를 통해 OSI 7계층을 uplink하고 다시 NIC에 downlink를 타고 외부로 빠져나간다. 이 과정에서 리소스가 많이 발생하기 때문에 하드웨어 수준에서 처리를 하는 것이 가장 좋으며 이를 가속했다라고 표현한다.
패킷 단위 데이터를 단순 전송하는 경우 라우터가 내부로 들어온 패킷을 외부로 내보낼 수도 있지만 다른 라우터로 보낼 수도 있다. 이 경우에는 IP주소 수준에서 Read를 통해 패킷을 내부로 읽은 뒤 Write를 통해 NIC를 선택해야한다. Read만 한다면 패킷이 Drop된다.
적정한 주소가 없어서 Drop되는 경우와 두번째, 패킷이 외부로부터 내부로 들어오는 경우에 Drop되는 경우가 있다.
인라인 장비들은 항상 결정을 내려서 Bypass 또는 Drop 처리를 해야한다. 단지 라우팅에 관련된 것만 한다면 라우터가 되는 것이고, 보안적인 이유로 사용한다면 방화벽이 된다. 라우터와 방화벽은 같은 L3 스위치의 일종이며 같은 내부구조를 가지고 있다.</p>
<h3 id="inline-구조와-out-of-path-구조">Inline 구조와 Out of path 구조</h3>
<p>네트워크의 장치에 대해 논할 때 inline의 방식으로 설치하는지 아니면 Out of path 구조인지에 대해서 고민해봐야한다. 
게이트웨이에서는 라우터에게 1번 끝자리를 주는 경우가 많다. 라우터를 기준으로 내부/외부망을 나눈다. 여기서 라우터는 Inline의 구조를 갖고있다. Inline구조를 갖고있기에 Bypass를 할지 Drop처리를 할지 결정할 수 있다. 
Distribution switch는 통과하는 패킷을 특정 포트로 Copy를 해주는데 이를 Port Mirroring라고 부른다. 보통은 리소스를 많이 차지하기 때문에 네트워크 측면에서 많이 사용하려 하지는 않는다.  Port Mirroring은 Out of path구조로 설치됐는데, Sensor(Read Only)가 내부에 있다. 
스위치에서 전송되는 데이터를 Copy(미러링)한 이유가 만약 장애가 있는지 확인하기위함이라면 장애대응 Sensor가 되며, 해킹인지 아닌지 식별하는에 대한 탐지체계라면 DPI -&gt; NIDS가 된다. 
Tab Switch는 Copy전용 스위치다. 패킷이 하나만 지나가도 포트의 갯수만큼 Copy하여 전송한다. 이때 전송한 복사본이 Sensor에 어떤 기능에 사용될지는 설계자 마음이다.
정리를 하자면 Inline으로 인스톨 되면 Bypass/Drop이 다 되고, Out of path로 하면, sensor를 이용하며 Read only의 특성을 갖고있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[네트워크 기초 이론 4편]]></title>
            <link>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-%EC%9D%B4%EB%A1%A0-4%ED%8E%B8</link>
            <guid>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-%EC%9D%B4%EB%A1%A0-4%ED%8E%B8</guid>
            <pubDate>Mon, 04 Sep 2023 09:34:33 GMT</pubDate>
            <description><![CDATA[<h3 id="lan-과-wan">LAN 과 WAN</h3>
<p>LAN은 Local, WAN은 Wide다. Logical은 가상환경을 떠오르면 된다, 인터넷은 사실상 logical network, 다른 말로 해석하자면 virtual net이다. 인터넷을 WAN으로 보기 때문에, WAN의 Wide는 지역의 크기로 나누는 것 타당하지 않을 수 있다. 
LAN은 사실상 1<del>2계층에 있고, 3</del>4계층에 WAN이 있다라고 기억해도 좋다. Ethernet의 식별자는 MAC주소(48bit)인데, MAC주소로 식별하는 네트워크가 LAN이다. 반면 IP주소는 인터넷의 중요한 식별자다. 
IP주소와 MAC주소중에 특수한 주소가 있다, 이를 방송주소(broadcast address)라고 부르는데, 이 또한 LAN으로 취급할 수 있다.</p>
<h3 id="패킷의-생성-원리">패킷의 생성 원리</h3>
<p>프로그램에 프로세스가 존재한다면 커널영역에 TCP/IP가 있고 H/W영역에 NIC가 있어 Internet에 접근 할 수 있는데, 소켓이라는 파일의 일종(TCP를 추상화한 파일)이 존재하고, 프로그램의 프로세스가 인터넷에 RW, I/O를 할 수 있도록(Stream) 도와준다.
Stream의 데이터는 매우 길 수 있기에 이를 Segment단위로 쪼개주는데, Segment를 캡슐화하여 Packet이 되며, 패킷을 한번더 캡슐화하면 Frame이 된다. 
소켓에서 data send를 실행하면 스트림 데이터를 알아서 쪼개준다. 패킷의 최대크기 MTU는 보통 1500의 길이를 갖고있는데, 이때 패킷의 구조엔 Header와 Payload로 분리할 수 있다. 
Header에는 IP/TCP에 대한 데이터를 각각 20bytes씩 들고있으니, Payload의 최대크기는 1500에서 20바이트를 뺀 1460bytes(MSS) 크기가 된다. 
보안문제 때문에 패킷을 들여다 볼 수도 있는데 이를 DPI라고 부른다. 만약 웹 서비스에서 데이터를 2000bytes 크기로 send한다면 최소 2개의 packet이 필요하다. </p>
<h3 id="l2-스위치">L2 스위치</h3>
<p>물리적 주소는 MAC 주소다. 네트워크는 switch의 집합체라고 생각할 수 있다. L2 Access라는 스위치에 여러개의 PC(NIC)간 통신을 할 수 있도록 만들어준다. L2 Access들 끼리 연결할 수 있도록 도와주는 스위치가 바로 L2 Distribution 스위치다. 이용주체의 엔드를 Endpoint로 취급하는데, Endpoint와 제일 먼저 접근되는 스위치가 L2 Access고, 일반적으로 스위치를 위한 스위치가 L2 Distribution이다. L2 Distribution에서 계속 외부로 접근하면 Router(L3)가 나오고 그 후엔 Internet에 접근할 수 있다. 
L2 Access -&gt; L2 Distribution와 같이 계층 상향으로 이동하는 연결하는 라인을 uplink로 부른다. link-up/down이라는 개념도 있는데 이는 uplink와 다른 뜻이다. Link-up은 연결이 완성됐을 때 녹색불을 뜨면서 Link-up됐다고 표현할 때 쓰는 용어다.
공유기가 16개의 포트단자를 갖고있을 때 이때 uplink용 포트 하나를 제외하면 총 15개의 컴퓨터에 연결할 수 있다. </p>
<h3 id="ip-헤더-형식과-의미-요약">IP 헤더 형식과 의미 요약</h3>
<p><img src="https://velog.velcdn.com/images/dev_dowon/post/1c11838d-1b0e-4803-b90b-89d2903033b5/image.png" alt="">
ToS-&gt; Type of Service  대역폭 품질 관리할 때 사용이 된다.
Identification은 단편화와 관련되어있다. 
TTL: Type of Line, 인터넷은 라우터의 집합체인데, Packet을 유통하는데 라우터를 하나씩 지날 때 마다 TTL이 하나씩 감소하는데, TTL은 라우터를 너무 많이 거치면 0이 된다. 0이 된다면, 0이 된 라우터에서 해당 데이터를 버린다. 
Protocol은 4계층의 헤더가 뭔지 확인한다. 해당 값을 확인해서 뒤의 데이터를 값으로 처리할 지 TCP/UDP 헤더가 또 나오는지 확인 할 수 있다. 
Source address은 출발지 IP 주소, Destination address는 도착지 IP 주소다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[네트워크 기초 이론 3편]]></title>
            <link>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-%EC%9D%B4%EB%A1%A0-3%ED%8E%B8</link>
            <guid>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-%EC%9D%B4%EB%A1%A0-3%ED%8E%B8</guid>
            <pubDate>Sat, 02 Sep 2023 11:49:21 GMT</pubDate>
            <description><![CDATA[<h3 id="웹-서비스">웹 서비스</h3>
<p>티모시 버너스리님이 웹 서비스의 기반을 만들어줬다. 프로그램은 세가지 요소로 이루어진다. 자료구조(문서 포함), UI 그리고 제어 세가지로 분류를 해줬는데, 이는 유지보수의 편의성을 위해서 쪼개둔 것이다. 초기 웹 서비스와 같은 경우 웹클라이언트(브라우저)가 인터넷에 연결이 되어있다면, 웹 서버에 연결이 된다. HTTP 1.1기준으로 TCP/IP연결이 되어있다 가정을 하고 웹 서비스가 실행된다. 이때 HTTP의 가장중요한 특징은 바로 Stateless다 . TCP/IP 연결은 상태와 관련이 되는데, HTTP의 stateless 특징 떄문에 설계적으로 문제가 생긴다.
URL에 특정 주소를 입력했을 때(DNS생략) http 통신을 통해 request를 주면 http의 response가 온다, 이때 가장 자주쓰이는 request method가 get인데, 이는 특정 리소스를 get 요청한다는 것을 의미한다. 웹 서버에 get 요청을 하면 해당 리소스(html 문서)를 response로 반환해준다. 
받아온 리소스(HTML)은 구문분석(Parsing)을 실시하고 자료구조를 생성하는데, 이때 해당 자료구조를 DOM이라고 부른다. DOM을 갖고 렌더링 엔진이 화면을 보여주면 get 요청이 마무리된다. </p>
<h3 id="웹-서비스-3대-요소">웹 서비스 3대 요소</h3>
<p>자료구조에 해당되게 HTML이라고 한다면, UI부분을 담당하는 부분이 CSS3다. response의 데이터 순서는 HTML, CSS, 이미지 파일이 도착한다. 그렇기에 렌더링을 할 때 이미지 파일 렌더링이 늦어질 수 있어서, onload나 동적 import를 신경써줘야한다. 
Post 요청을 하면 request를 보낼 때 특정 데이터를 웹 서버에 보내주고, 백 서버에서 처리를 해준다. 그리고 다시 response를 반환해주니 데이터는 양방향 상호작용이 가능케 된다.
하지만 양방향 상호작용에는 문맥이 발생하는데 상태는 전이성이 있다. 그에 반에 http 는 stateless이기에 이를 해결하기 위해 Database라는 시스템을 도입하기 시작했다. 문맥을 기억하기위해 Database을 사용해 연산 처리와 데이터 자료를 분리할 수 있게된다. 
브러우저단에 따로 또 연산을 할 수 있는 엔진을 넣어주려 하는데, 이때 사용되는 언어가 Mocha -&gt; Live -&gt; Javascript가 된다. 그리고 클라이언트 측에서의 state 저장도 가능한데, 이를 Cookie라고 부른다. (쿠키의 특징으로는 속성 범위 기간이 있다)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[네트워크 기초 이론 2편]]></title>
            <link>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-%EC%9D%B4%EB%A1%A0-2%ED%8E%B8</link>
            <guid>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-%EC%9D%B4%EB%A1%A0-2%ED%8E%B8</guid>
            <pubDate>Thu, 31 Aug 2023 12:29:31 GMT</pubDate>
            <description><![CDATA[<h3 id="port-번호---process-식별자">Port 번호 - Process 식별자</h3>
<p>본질은 파일이지만 프로토콜을 추상화했기에 소켓으로 정의를 한다. TCP 소켓인 경우 소켓에 attach되는 내용 중 하나가 Port 번호이다. 포트번호는 16bit(대부분)인데, 이는 0~65535가지의 경우의 수가 있다. 이때 0과 65535는 사용 할 수 없다.
인터넷에 접속할 땐 소켓을 열어주는데, 이때 소켓의 포트번호 하나에 브라우저 하나를 담당한다. 즉 엣지와 크롬을 사용할 땐 두개의 포트번호가 열리게 된다. </p>
<p>데이터의 흐름을 간단하게 설명하자면:</p>
<pre><code>데이터 패킷 -&gt; NIC -&gt; Driver -&gt; TCP/IP -&gt; Process / Edge / etc
이때 프로세스로 갈지 다른 곳으로 갈지는 포트번호에 따라 목적지가 결정된다.</code></pre><p>Port번호는 Socket에 binding 된다는 걸 명심하자.</p>
<h3 id="switch와-switching">Switch와 Switching</h3>
<p>Switch는 선택이라는 개념으로 시작할 수 있다. 데이터를 최종 목적지 까지 효율적으로 최단거리로 갈 수 있는지 고려하는 건 네트워크에서 매우 중요한 일이다. 인터넷은 기본적으로 라우터의 집합체(L3)인데, 인터넷에서 출발한 데이터는 라우팅 테이블을 통해 데이터 패킷은 적절한 Switching(라우터)을 하여 최종 목적지로 도달 할 수 있다. </p>
<h3 id="네트워크-데이터-단위-정리">네트워크 데이터 단위 정리</h3>
<p>Socket은 프로토콜을 추상화 한 파일을 뜻 하는데, 파일의 I/O은 기본적으로 시작점만 있으며, 데이터를 Write할 때 마다 지속적으로 용량이 커진다. Socket또한 File이기에, 이러한 특징을 갖고 있는데, 이 개념을 Stream이라고 부른다. Stream의 특징은 시작점을 알지만 종료지점은 정해져있지 않다는 것 이다. 하지만 데이터가 IP 단위를 넘어서게 된다면, 한번에 데이터를 전송하기 어려울 수 있다. 이 때 등장한 개념이 바로 segment다. IP단위에서 다루는 단위가 바로 Packet이고, NIC단위에선 Frame이다. </p>
<pre><code>Stream -&gt; Segment화 -&gt; Segment -&gt; Packet -&gt; Encapsulation -&gt; Frame</code></pre><p>패킷의 최대크기(MTU 1500bytes)에 따라서 Segment의 최대크기(MSS)가 정해진다. </p>
<h3 id="네트워크-인터페이스-선택-원리와-기준">네트워크 인터페이스 선택 원리와 기준</h3>
<p>통신을 하고 싶다면 Socket에 IP가 바인딩 되어야한다, 만약 무선,유선을 동시에 사용한다면 어떤 네트워크를 이용해 통신을 할지에 대한 결정권(인터페이스 선택) 을 고려해볼 필요가 있다.
인터페이스의 선택은 Switching과정이라 볼 수 있다. 일반적으로 매트릭 값이 가장 낮은 순위를 근거로 인터페이스 선택이 결정된다. 이때 매트릭 값은 비용이라고 생각하면 쉽다.</p>
<h3 id="웹-서비스-구조">웹 서비스 구조</h3>
<p>웹 서비스의 초석은 무선(Text)와 링크의 확장구조다. 문서(HTML)를 인터넷에 연결하고 HTTP를 통해 문서를 전달하는 행위를 실행하는 주체가 바로 웹 서비스 본체다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[네트워크 기초 이론 1편]]></title>
            <link>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-%EC%9D%B4%EB%A1%A0-1%ED%8E%B8</link>
            <guid>https://velog.io/@dev_dowon/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-%EC%9D%B4%EB%A1%A0-1%ED%8E%B8</guid>
            <pubDate>Thu, 31 Aug 2023 12:23:47 GMT</pubDate>
            <description><![CDATA[<p>네트워크 이론 시리즈는 널널한 개발자님의 강의 &lt;네트워크 기초 이론&gt;를 수강하고 배운 내용과 생각을 정리한 내용으로 구성되어있습니다. 아래의 링크에서 강의 원본을 보실 수 있습니다.
<a href="https://youtube.com/playlist?list=PLXvgR_grOs1BFH-TuqFsfHqbh-gpMbFoy&amp;si=pCOZhfCTt88FF0Rm">https://youtube.com/playlist?list=PLXvgR_grOs1BFH-TuqFsfHqbh-gpMbFoy&amp;si=pCOZhfCTt88FF0Rm</a></p>
<h3 id="네트워크-이론">네트워크 이론</h3>
<p>OSI 7Layer는 구체적인 실체가 아닌 이상적인 개념이다. 이상적인 개념이기에, 너무 완벽하게 이해하려 할 필요는 없다고 한다. DoD(미국 국방부) 기준으로 네트워크 레이어를 구분 지을 수도 있다. 
OSI 7Layer인지 DoD 기준 구분인지에 초점을 두는 것 보단, 어떻게 프로세스에서 동작할건지에 대한 “구현”에 중점을 두고 공부하는 것이 훨씬 이득라고 한다. </p>
<p><img src="https://velog.velcdn.com/images/dev_dowon/post/d78f95e2-8455-43eb-be4c-664c8bb3dd27/image.png" alt=""></p>
<p>유저모드 애플리케이션을 파일의 형태로 추상화하게 되는데, 이때 TCP/IP통신과 관련된 추상화 요소라면 이를 Socket이라고 부른다. HTTP는 L7계층에 속해 있다.
각 계층별로 식별자가 있는데, 엑세스 수준의 식별자는 MAC이며 네트워크 수준에선 IP주소, TCP수준에선 포트번호가 있다.</p>
<h3 id="mac-ip-port가-식별하는-것">MAC, IP, Port가 식별하는 것</h3>
<p>MAC -&gt; Network Interface Card에 대한 식별자, 보통은 LAN카드에 연동되어있다. 자주 변경될 수 없는 식별자다.
IP주소 -&gt; Host 에 대한 식별자: 인터넷에 연결된 컴퓨터를 식별한다. 컴퓨터는 여러개의  IP주소를 갖고있다. 
반대로 Port같은 경우엔 레이어층에 따라서 식별하는 것이 다른데, H/W 측에선 공유기의 인터페이스 번호를 식별하고, 커널 단에선 서비스를 식별하고, 유저 단에선 프로세스를 식별한다고 한다. </p>
<h3 id="host-switch-network의-관계">Host, Switch, Network의 관계</h3>
<p>컴퓨터가 네트워크에 연결되어있다면 Host라고 부른다. Host는 Network 자체인 경우가 있고 Network 이용 주체인 경우가 있다. 
<img src="https://velog.velcdn.com/images/dev_dowon/post/5614da51-fefb-4375-8678-f8615a149758/image.png" alt=""></p>
<p>네트워크 자체인 경우 Switch로 본다. Switch의 역할은 Switching을 해주는 것인데, F/W(방화벽)과 IPS도 엄밀히 말하자면 Switch다, 이는 보안 스위칭이라고 부른다. 
Network 이용주체는 End-Point(엔드포인트)가 된다. 대표적으로 Router가 있다. Router같은 경우엔 경로를 찾기위해 사용되는 경로 스위칭이다.
Network 중 가장 대표적인 예는 Internet이 있다. 여기서 인터넷이란 라우터와 DNS의 집합체라고 기억하면 좋다. 
레이어가 높아질 수록 비용이 비싸진다는 내용도 언급이 되었다. </p>
<pre><code>Net 이용주체 (End-Point) -&gt;  Peer / Server / Client
Net 자체(Switch) -&gt; Router  -&gt; L3의 IP를 스위칭 한다 -&gt; Router</code></pre><h3 id="ip주소와-net-mask">IP주소와 Net-mask</h3>
<p>IP주소(Internet Protocol)는 Host에 대한 식별자다. IP주소는 IPv4와 IPv6로 나누어져있는데, 이 둘의 차이는 주소길이의 차이이다. IPv4는 32bit(2의 32승 약 43억)의 길이를 갖고있으며, IPv6은 128bit을 갖고있다. IPv4 기준으로 IP주소는 Net ID, Host ID로 구성되어있는데, 이 둘의 총 합을 32bit다. Net ID의 길이을 나타내는 것이 NetMask다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[운영체제 이론 8편(완)]]></title>
            <link>https://velog.io/@dev_dowon/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9D%B4%EB%A1%A0-8%ED%8E%B8%EC%99%84</link>
            <guid>https://velog.io/@dev_dowon/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9D%B4%EB%A1%A0-8%ED%8E%B8%EC%99%84</guid>
            <pubDate>Mon, 28 Aug 2023 12:21:35 GMT</pubDate>
            <description><![CDATA[<h3 id="메모리-접근-권한">메모리 접근 권한</h3>
<p><img src="https://velog.velcdn.com/images/dev_dowon/post/60267eef-11cd-4cfa-ab95-897405b76077/image.png" alt=""></p>
<p>가상메모리 공간은 특별한 이유가 없다면, 32bit 크기의 저장할 수 있는 메모리 크기를 갖게된다. 이때 VMS는 4GB다. 유저와 커널은 각각 2GB씩 할당 받게 된다. 위의 그림에서 나오는 프로세스(VMS)는 유저(2GB)를 뜻한다. </p>
<pre><code>데이터:
  *Stack
  *Heap
  *정적:
    Read / Write
    Read</code></pre><p>데이터 영역에서 특별한 이유가 없다면 RW기능만 된다. 코드영역은 RX(Read/Execute) 가 된다. 정적영역에서 읽고 쓰기가RW) 다 되는 영역은 전역변수다. 정적 영역 중 읽기만 되는 부분 영역은 코드 영역에 섞여 들어간다. 
<img src="https://velog.velcdn.com/images/dev_dowon/post/799280fc-287f-42ba-a993-6a65cfe73941/image.png" alt=""></p>
<p>프로그램 코드로 코드 / 데이터와 같은 각종 영역에 RWX에 대한 권한을 변경할 수 있다. 메모리를 다룰 때 DEP라는 개념을 잘 이해해야한다.</p>
<pre><code>DEP(Data Execution Prevention)는 바이러스 및 기타 보안 위협으로 인한 컴퓨터 손상을 방지하는 데 도움이 되는 보안 기능이다. 
DEP는 프로그램이 시스템 메모리를 안전하게 사용하는지 모니터링함으로써 컴퓨터를 보호할 수 있다. DEP가 컴퓨터에서 메모리를 잘못 사용하는 프로그램을 탐지할 경우 프로그램을 닫고 사용자에게 알려준다.</code></pre><p>페이지 테이블에는 권한 비트가 존재하여, 가상메모리가 실제 메모리에 접근 하기 전에 실행 
내용을 체크해서 page fault를 일으킬 수 있다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[운영체제 이론 7편]]></title>
            <link>https://velog.io/@dev_dowon/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9D%B4%EB%A1%A0-7%ED%8E%B8</link>
            <guid>https://velog.io/@dev_dowon/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9D%B4%EB%A1%A0-7%ED%8E%B8</guid>
            <pubDate>Fri, 25 Aug 2023 11:57:22 GMT</pubDate>
            <description><![CDATA[<h3 id="가상메모리">가상메모리</h3>
<p>가상메모리체계는 시스템 프로그래밍을 다루는 내용에서 멀티 스레딩 / 프로세스 와 함께 매우 중요한 내용이라고 한다. 메모리는 1차 메모리(RAM)와 2차 메모리(HDD/SDD)가 있는데, 메모리의 크기가 서로 다르기 떄문에 소프트웨어가 메모리의 규격에 따라 버전별로 설정해줘야하는 문제가 있었다. 이런 장치에(메모리) 대한 의존성을 가상메모리가 없에 줄 뿐 아니라 관리적 의미에서 추상성을 제공하여 접근제어(보안)을 가능케 한다. 
가상메모리는 32/64bit에 따라 상수단위가 결정된다. 강의에선 32비트를 기준으로 가상메모리에 대한 개념을 설명한다. 32비트를 기준으로 했을 때 VMS라는 가상메모리 공간이 있다면, 이를 반으로 공간을 분할하여 User영역과 Kernel영역으로 나눈다, 이때 User의 0번대 주소 부근은 OS가 차지하도록 설계되어있다. </p>
<p>가상시스템에서 메모리 메니저는 RAM+Swap영역을 관리한다. 프로세스가 사용하는 가상주소공간을 실제 물리메모리로 전환하는데,  이를 동적 주소 변환이라고 한다. 여기서 동적은 Runtime내에서 실행된다는 뜻이다. 가변분할 방식으로 프로세스의 공간을 할당해준다 해도, VMS와 같은 방식으로 주소공간을 분배하도록 한다. 
물리메모리에는 절대주소가 부여되어있는데, 가상메모리 상의 주소가 같다고 해도 물리 메모리 상에서도 같은 주소를 가르키는건 절대 아니다. 여기서 매핑 테이블이라는 중요한 개념이 나오는데, 이는 프로세스(VMS)가 실제 물리적인 메모리 주소를(세그먼트)에 매핑해주는 중요한 기능을 한다. 매핑 테이블은 보통 배열일 가능성이 매우 높다. 운영체제가 매핑 테이블을 관리하면 좋은 점이 있는데, 프로세스가 잘 작동하다가 오작동 때문에 갑작스럽게 terminate가 된 경우 운영체제의 메모리 매니저가 신속히 물리적 공간을 회수해서 자원적 낭비를 없애 줄 수 있다. 메모리의 회수는 RAM의 성능을 온전히 사용할 수 있도록 보장해준다, 그리고 그 것을 매니저 메모리가 가능하도록 만들어준다.</p>
<h3 id="가상메모리-페이징-기법의-구현">가상메모리 페이징 기법의 구현</h3>
<p>가상메모리의 페이징 기법은 매우 중요한 내용이다. C언어의 포인터라는 개념을 잘 이해하려면 기본적으로 컴퓨터의 구조에 대한 이해도와 VMS(가상메모리공간)에 대한 개념을 어느정도 숙지해야한다. VMS(32bit기준)은 4GB의 용량이 있는 배열이다. 즉 해당 배열 내부에 Stack / Heap과 같은 요소들이 선형적으로 배치되어있다. Page는 윈도우 체계를 기준으로 4kb정도 차지를 한다. 
<img src="https://velog.velcdn.com/images/dev_dowon/post/75b30b4f-0b9a-4072-b60d-8e0a17d10b4f/image.png" alt=""></p>
<p>여기서 프레임과 페이지는 모두 메모리를 일정한 크기의 공간으로 나누어 관리하는 단위이다. 프레임은 물리 메모리를 일정한 크기로 나눈 블록이며, 페이지는 가상 메모리를 일정한 크기로 나눈블록이다. 보통 프레임과 페이지의 크기를 같은 사이즈로 맞추며, 페이지가 하나의 프레임을 할당 받으면 물리 메모리에 위치할 수 있게 된다. 페이징 기법은 사실상 주소공간을 페이지 단위로 나누고 실제 메모리 공간은 페이지 크기와 같은 프레임으로 나누어 사용된다.
<img src="https://velog.velcdn.com/images/dev_dowon/post/d133d0fc-dffb-4ba2-a5c6-83008f4b4c79/image.png" alt=""></p>
<p>가상주소 VA = &lt;P,D&gt; 라는 간단한 관계가 있는데, 여기서 P는 페이지 호수, D는 distance(offset)을 상징한다. 페이지 테이블은 상대적인 프로세스의 주소를 물리적인 절대 주소에 매칭할 수 있도록 도와준다.
운영체제의 스와퍼는 물리 메모리에 동작하고 있는 모든 프로세스를 로드하지 않는다. 그리고 프로세스의 모든 페이지를 물리 메모리에 로드하지 않기 떄문에 프로그램의 페이지가 물리 메모리에 부재하는 경우 페이지 폴트 현상이 일어날 수 있다. 
운영체제가 페이지 테이블을 이용해 요구 페이징 수행을 하는 과정은 아래와 같다:</p>
<pre><code>1. CPU는 물리 메모리을 확인하여 페이지가 없으면 trap을 발생하여 운영체제에 알린다.
2. 운영체제는 CPU의 동작을 잠시 멈춘다.
3. 운영체제는 페이지 테이블을 확인하여 가상 메모리에 페이지가 존재하는지 확인하고, 없으면 프로세스를 중단한다.
4. 페이지 폴트이면, 현재 물리 메모리에 비어있는 프레임(Free Frame)이 있는지 찾는다.
5. 비어있는 프레임에 해당 페이지를 로드하고, 페이지 테이블을 최신화 한다.
6. 중단되었던 CPU를 다시 시작한다.</code></pre><p>물리 메모리에 비어있는 프레임이 없으면 희생 프레임을 골라서 이를 가상 메모리에 저장 후 필요한 페이지를 물리 메모리에 불러온다, 이 때 페이지 교체 알고리즘이 사용하게 된다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[운영체제 이론 6편]]></title>
            <link>https://velog.io/@dev_dowon/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9D%B4%EB%A1%A0-6%ED%8E%B8</link>
            <guid>https://velog.io/@dev_dowon/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9D%B4%EB%A1%A0-6%ED%8E%B8</guid>
            <pubDate>Thu, 24 Aug 2023 14:28:15 GMT</pubDate>
            <description><![CDATA[<h3 id="교착상태">교착상태</h3>
<p>교착상태는 다음 흐름으로 진행이 안되는 흐름이 죽어있는 상태를 말한다. 교착상태가 걸리는 이유는 임계구간 과정 중 자원을 wait하게되는데, 외부의 어떠한 프로세스에서 해당 자원을 선점하고 있다면 상호 wait하는 루프가 만들어지고, 이때부터 교착상태가 형성된다. 어떤 영역이든 의존관계에서 순환구조가 나온다면, 그건 매우 위험한 구조다. 
사실상 교착상태가 쉽게 일어나지 않는다. 한 프로세스 내에서 두개의 스레드가 교착상태에 빠지지 않을지 제 3의 스레드를 이용해 상태감시를 해주면 된다. 교착상태의 대응방식으로 하나의 스레드를 terminate하고 재실행해주는 방식도 있다. 스레드 뿐 아니라, OS의 단위에서도 똑같은 과정이 일어난다. 여러개의 프로세스가 동시 동작하는데, 특정 프로세스가 특정 자원을 차지하고 suspense 상태로 전환이 됐다면, 운영체제에서 이를 감지해서 강제적으로 해당 프로세스를 종료하고, 강제회수한 자원을 필요한 프로세스에게 전달한다. 사실상 프로세스의 메모리는 가상화를 해두기 때문에, 프로세스의 terminate는 가상화 메모리로 적용되어 있는 부분을 날리는 형식으로 실행하면 된다.</p>
<h3 id="메모리-관리">메모리 관리</h3>
<p>메모리에는 1차메모리(RAM)과 2차메모리(SDD,HDD)가 있다. 메모리의 주소는 일련번호라고 생각하면 된다. 32비트 체계는 2^32 의 주소 메모리를 통제할 수 있다. 그래서 RAM을 8기가를 장착을 해도, 최대 4기가 밖에 운용할 수 없는 현상이 일어날 수 있다. CPU의 연산속도가 빠르지만, 그렇다고 모든 작업이 대기상태가 없거나 대기상태가 너무 길어서도 좋지는 않다. 결국엔 속도 또한 자원의 일부이기에, Cache 예측과 같은 특성을 이용해, CPU가 꾸준히 일을 할 수 있도록 하는 것이 중요하다. 
메모리 관리자가 메모리 사용의 배치 작업을 수행해준다. RAM이라는 공간은 한정되어있지만 그 위에서 작동해야되는 프로세스가 여러개 존재한다면, 배치정책을 이용해야한다. 프로세스의 상태를 감시하면서, 사용되지 않는 데이터는 HDD로 저장소를 옮기는 식으로 배치정책을 실시한다. 페이지 단위 메모리로 통제하게 되어있고, 페이지는 보통 4KB로 이뤄져있다. </p>
<h3 id="절대주소와-상대주소">절대주소와 상대주소</h3>
<p>메모리의 주소를 얘기할 때는 두 가지 형식이 있다. 운영체제를 포함해서 주소를 가르키면 절대주소, 유저의 위치를 기준으로 재설정 한 후 주소를 가르키면 상대주소다. 절대주소와 상대주소는 가상메모리를 이해하기위해 알아야하는 기본적인 개념이다. 프로세스의 메모리를 회수하고 새로운 프로세스의 메모리 공간을 동적할당하는 과정에서, 프로세스 매니저가 메모리 할당에 대한 고민을 해결해준다. </p>
<h3 id="메모리-오버레이와-스왑">메모리 오버레이와 스왑</h3>
<p>프로그램의 메모리 크기가 실제 메모리 크기보다 클 때 메모리를 쪼개서 운용하는 방식을 메모리 오버레이라고 한다. 옛날에 RAM의 크기가 작았을 때 자주사용된 개념이다. HDD에 스왑영역을 설정하고, RAM의 영역과 더하여 실제 컴퓨터가 사용하는 메모리 공간이라고 이해할 수 있는데, 이런 방식은 가상메모리 운용과 밀접한 관계가 있다. Swap In/Out이라는 용어는 Page In/Out이라는 용어와 비슷한 개념인데, RAM과 HDD사이에서 일어나는 메모리 전환 과정을 표시한다. 
최대 절전모드로 들어가면, RAM메모리에 있는 모든 정보를 HDD에 전환시켜준다, 그럼 모든 작업 상태를 저장할 수 있고, 다시 전원을 켰을 때 HDD -&gt; RAM 과정을 거쳐 상태를 복구한다. SSD가 HDD보다 좋은 성능을 내는 이유는, Swap out에 대해서 속도를 몇배 올릴 수 있어서, CPU를 교체하지 않아도, I/O 지연을 줄여줘서, 컴퓨터 성능이 향상되는 현상을 경험할 수 있었다. 그래서 CPU대신 SSD로 컴퓨터 메모리 장치를 교체하여 성능향상을 하던 시절이 있었다고 한다.</p>
<h3 id="물리-메모리-분할-방식">(물리) 메모리 분할 방식</h3>
<p>가상메모리 보다는 중요하지 않을 수도 있지만, 물리적으로 어떻게 메모리 분할이 진행되는지 알아보도록 한다. 프로그램에서 물리 메모리를 사용하는 경우는 S/W(기계어)를 잘라서 CPU연산이 진행될 때다. 프로그램이 동시에 여러개가 작동할 때 프로세스화되어 진행이 되는데, 프로세스를 각각에 연속되는 공간으로 메모리 할당을 해줄 때, 가변 분할 방식과 고정 분할 방식이 있다. 가변 분할 방식을 사용할 땐 빈 공간(Fragment)가 발생한다. 물리적인 메모리 분할은 위의 두가지 방식을 섞어서 사용한다. 관리측면에선 고정 분할 방식이 훨씬 쉽다. 
<img src="https://velog.velcdn.com/images/dev_dowon/post/7cfd5c71-e0f1-429f-b022-17e28b64efc0/image.png" alt=""></p>
<p>가변분할을 사용하게 되면, 빈공간이 많이 생겨 조각모음을 진행해야되는 단점이 있다. 이를 외부 단편화라고 표현한다. 조각모음을 하는 행위 자체는 빈 공간을 창출해 메모리를 추가적으로 확보할 수 있지만, 이 또한 CPU 자원을 잡아먹기 때문에, 무조건 좋다고 할 수는 없다. SSD는 HDD와 다르게 어느 섹터를 접근하든 같은 속도로 접근하기에 조각모음을 하지 않는 편이다. (해둬서  나쁘진 않다)
다음 글 부턴 가상메모리에 대해서 정리하도록 한다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[운영체제 이론 5편]]></title>
            <link>https://velog.io/@dev_dowon/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9D%B4%EB%A1%A0-5%ED%8E%B8</link>
            <guid>https://velog.io/@dev_dowon/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9D%B4%EB%A1%A0-5%ED%8E%B8</guid>
            <pubDate>Thu, 17 Aug 2023 10:43:53 GMT</pubDate>
            <description><![CDATA[<h3 id="cpu-스케줄링">CPU 스케줄링</h3>
<p>운영체제는 백그라운드에서 실행되는 특별한 프로그램이라고 생각할 수 있다. 운영체제의 목적은 프로세스간 원활하게 동작할 수 있도록 지원해주는 것이다. 프로그램이 실행되면 스레드가 CPU 자원을 선점하게 되어있다. 그렇다면 OS에서 스레드의 작업 분배를 해주기 위해 스케줄링을 한다. 스레드에 대한 스케줄링은 저수준 스케줄링에 해당하게 된다.
<img src="https://velog.velcdn.com/images/dev_dowon/post/41979355-21ce-4a1a-8d83-cc9262a95a44/image.png" alt=""></p>
<p>중간 수준 스케줄링은 작업 스케줄링이라고도 하는데 여기서 작업은 Job의 단위로 볼 수 있다. Job이란 여러개의 스레드를 하나로 묶은 작업단위다. 
고수준 스케줄링은 전체적인 시스템의 부하 상태를 스케줄링한다. 어플리케이션 또는 운영체제와 같은 큰 단위를 기준으로 스케줄링한다고 생각하면 된다. 선점형(Preemtive)/비선점형(Non-Preemtive) 스케줄링이라는 용어를 잘 익혀보자. OS가 CPU를 뺏어서 사용하는 방식을 선점형 스케줄링이라고 한다. 비선점은 정반대 상황이다, 하나의 프로세스가 CPU를 점유하면 다른 프로세스는 CPU를 뻇을 수 없다. 보통은 선점형으로 사용이 되고, 특수한 상황에서만 비선점형으로 스케줄링을 실행한다.
프로세스 / 스레드 별로 우선순위를 정할 수 있는데, 보통은 5단계로 분류된다. 재밌는 점은, 리액트의 스케줄러 작업 우선순위도 5단계로 나뉜다는 것이다. 순위가 높은 프로세스로는 미디어 관련 작업이 있고(GUI), 순위가 낮은 프로세스로는 백그라운드 프로그램이 있다(압축해제). 느린 I/O를 사용할 땐 주의해야하는데, wait와 같은 방식으로 CPU를 오랫동안 선점을 하고있어서, 성능에 차질이 일어날 수 있다. 그래서 비동기 처리를 잘 해야한다. 
서버는 대표적인 I/O가 기본적으로 많은 작업 프로세스다. 대기하는 시간이 많기에, 백그라운드로 진행되는 경우가 일반적이다.
<img src="https://velog.velcdn.com/images/dev_dowon/post/68c4e4d6-9a66-405b-9509-cf214d755aea/image.png" alt=""></p>
<p>IOCP -&gt; Kernel I/O이기에, 우선순위가 가장 높은 프로세스로 처리가되어, 유저입장의 모든 I/O의 빠른성능을 보장해준다. </p>
<h3 id="process-간-통신">Process 간 통신</h3>
<p>IPC(inter process communication)은 운영체제에서 매우 중요한 내용이고, 면접에서도 잘 나오는 문제다. 프로세스는 독립적인 메모리 공간이 주어진다. 경계가 있다는 건 다른 프로세스의 접근에 대해 차단할 수 있다는 것이다. 접근 차단은 OS가 보장해주는데, 이는 외부에서 특정 프로세스의 메모리 내역을 변경하는 상황을 방지해준다. 만일 OS를 뚫어서 특정 공간에 대해 접근할 수 있다면, 그건 고급 해킹영역이다.
메모리는 RAM+File(2차)의 형태로 사용이 되는데, File은 Stream과 밀접한 관계가 있다. FIle은 보통 HDD에 저장되어있는데, Head부분의 메모리  size가 0이다. 그 위에 write를 하면,  메모리 공간이 증가한다. 그에 반면에 Memory형식은 OS가 매우 엄격하게 메모리 크기 할당을 관리하게된다. 
IPC가 네트워크 단위로 확장하게 된다면 그걸 소켓과 같은 방식이라고 생각하면 된다. RPC(Remote Processer Call)이라는 기술은 HTTP3 덕분에 최근들어 다시 급상하고 있다.
전역변수 또한 RAM 메모리를 사용한다는 것이라 Shared Memory 영역에 들어가있다. 두 프로세스가 어떠한 값에 대한 데이터를 특정 주소값을 참조하는 식으로 들고있는 상황에서, 두 주소값이 서로 일치할 때 Shared Memory라고 부른다. 
프로세스A가 Shared 메모리에 값을 변동하고(RW) wait하고 있는 프로세스 B에게 Signal을 보내면 프로세스 B가 다시한번 주소 값을 따라 RW을 시도한다. 
<img src="https://velog.velcdn.com/images/dev_dowon/post/43dd736e-c032-42c3-b737-f92a42664027/image.png" alt=""></p>
<p>이때 프로세스와 Shared Memory의 메모리 공간은 고정되어있다. 이는 File과 반대되는 방식이다.
정리를 해보자면, IPC를 하는 방법은 아래와 같다:</p>
<pre><code>Memory
Pipe (File)
Socket
RPC
Registry (윈도우 한정)</code></pre><h3 id="공유-자원과-임계구역">공유 자원과 임계구역</h3>
<p>여러개의 스레드가 동시에 하나의 프로세스 자원에 접근하는 것 처럼, 여러개를 동시에 실행 할 땐 경쟁조건을 고려해야한다. 코드 한 구문이 CPU의 관점에선 1개의 명령이 아닐 수 있다. 한줄 연산에서도 여러가지 연산이 포함되어 있기에, 한 구문에 한개의 명령을 보장받을 수 있는가가 원자성에 대한 내용이다. 
동시적 접근에 의해 발생할 수 있는 문제(동시성)에 대해 원자성을 부여하여, 동시에 발생할 수 없는 문제로 전환하여 오류를 사전 차단할 수 있다. 
코드를 실행 할 때 만약 하나의 스레드가 구문을 실행하는 도중에 다른 스레드의 연산에 의해 연산과정 사용되는 변수 값이 변동 된다면, 해당 코드는 정상적인 실행을 보장받을 수 없다. 이런 현상을 방지하기 위해 우리는 Lock이라는 방식으로 연산과정의 원자성을 보장해준다.
임계구간은 최소화를 무조건해줘야한다. 사실상 임계구간을 최대한 없에는 것이 제일 좋다, 아니면 락이 걸릴 위험이 있다. </p>
<h3 id="임계구역-해결-방법">임계구역 해결 방법</h3>
<p>여러개의 스레드의 임계구역 문제를 해결해주기 위해서 전역변수를 사용할 수 있다. 기능구현을 할 땐 UI/Service/Data Structure로 나뉠 수 있는데, 이 때 공통적으로 사용하는 전역변수에 대해서 임계구역문제가 생길 수 있다. 네트워크의 연결은 비동기적이며 불안정하다. 
어떤 기능을 조작할 때 추가하는 것보다 삭제하는 조작이 자료구조보다 약 3배 정도 복잡하게 진행된다고 한다. 특히 서버에서 DB의 삭제를 실시한다면, 클라이언트 단에서 값을 조회하다가 오류를발생 할 수 있다. 그렇기에 조회 / 검색이라는 기능을 사용할 때 동시에 추가 또는 삭제의 조작을 하지 않도록 임계구역을 설정해줘야한다. while 문으로 Lock에 대한 기능을 구현한걸 SpinLock이라고 부른다, CPU점유율이 높기에, 운영체제에서 제공하는 SpinLock은 어느정도 성능 최적화가 되어있어 CPU점유율 100%까지 가진 않는다.
결론적으로 스레드 또는 프로세스의 동기화를 이루기 위해선 Queue를 사용해야한다. Queue를 이용해서 동기성 문제를 해결할 수 있기에, 동기화 문제에는 꼭 Queue가 나올 수 밖에 없다. </p>
<blockquote>
<p>브라우저의 렌더링 엔진을 생각해보면, render queue, callback queue 등 많은 종류의 queue를 만나볼 수 있는데, 이 또한 동기성 문제를 해결하기 위해 만들어 진 자료구조라는 것을 알 수 있다. </p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[운영체제 이론 4편]]></title>
            <link>https://velog.io/@dev_dowon/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9D%B4%EB%A1%A0-4%ED%8E%B8</link>
            <guid>https://velog.io/@dev_dowon/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9D%B4%EB%A1%A0-4%ED%8E%B8</guid>
            <pubDate>Mon, 14 Aug 2023 10:36:19 GMT</pubDate>
            <description><![CDATA[<h3 id="프로세스-생성과-복사">프로세스 생성과 복사</h3>
<p>운영 체제에서 가상메모리와 프로세스가 매우 중요하다. OS가 접근제어를 할때, File이나 자원에 대해서 처리를 하려면 프로세스라는 단위를 통해 권한을 취한다. 
프로세스에게 가상메모리가 주어진다. 스레드는 안에서 자유롭게 활동할 수 있다. OS에서 새로운 프로세스를 생성했을 때, 독립적인 가상메모리 공간을 가져야한다. 그래서 프로세스 마다 OS가 할당을 해줘야한다. 
프로세스의 생성과 복사는 가상메모리를 어떻게 운용하는지와 밀접한 관계가 있다. Win32API / UNIX는 운영체제가 달라서 프로세스를 생성하는 방식 또한 차이가 있다. 
프로세스 생성 시 메모리를 복사한다. 이 과정에서 코드를(text) 복사하며 PCB가 생성되는데 이 과정에서 이비 VMS(Heap/Stack/Data)가 만들어진다.
프로세스의 생성은 많은 시간과 자원을 할당해야하기에, UNIX에는 fork() / exec() 두 방식이 있다. fork()방식은 기존의 부모 프로세스를 그대로 복사해온다. 그리고 text부분과 레지서트와 상태정보만 리셋시켜주면 새로운 프로세스로서 사용할 수 있다. exec()은 새로운 프로세스를 만들지 않고, 기존의 프로세스를 그대로 이용하고 기존 코드를 새로운 코드로 갱신해준다. exec()을 사용할 수 있다면 exec을 사용하는 것 을 권장한다.</p>
<h3 id="멀티스레딩과-동기화-기본">멀티스레딩과 동기화 기본</h3>
<p>프로세스를 여러개 사용하면 멀티태스킹 이라고 부른다. 멀티로 프로세스를 사용한다면 동기화 이슈가 일어난다. race condition이 이러한 병목현상이 발생할 때 고려해야된다. 
CPU의 자원을 선점하는 것은 Thread다(사용하는 역할). CPU의 코어를 몇개까지 할당하는지는 운영체제가 프로세스를 통해 수행한다. 그래서 스레드는 프로세스의 권한 또는 리소스 할당에 제한을 받는다. 
Stack은 스레드 마다 갖고있는 영역이다. Stack의 메모리는 특별한 설정을 안해주면 1MB정도로 충분한 공간을 갖고있다. TCB 단위로 스레드 연산이 실행되는데, 이 연산은 CPU core에서 실행되는데, 이 코어 내부에 레지스터가 있다. 코어의 레지스터의 상태를 변경하는 행위를 Context Switching(문맥교환)이라고 한다. 문맥교환은 프로세스와 똑같이 상태가 있다. </p>
<h3 id="멀티스레드의-특징">멀티스레드의 특징</h3>
<p>프로세스는 적어도 한개의 스레드를 가지고 있다. 그래서 프로세스가 슬립한다는 건 스레드가 슬립한다 라고 생각하는게 좀 더 현실성이 있다. GUI 또는 내부의 처리가 있을 수 있는데, 이를 보통 각각 여러개의 스레드로 분리한다. 그렇다면 개별적인 흐름이 존재할 수 있는데, 그렇기에 동기화 이슈가 매우 중요하다. 
멀티스레드를 사용하면 어떤 CPU코어위에서 연산을 진행할지 모르기에, 우연이라는 개념이 나올 수 밖에 없다. 그래서 sleep을 이용하면 우연을 줄일 수 있는데, 얼만큼 대기 상태를 유지해야될지도 명확히 알 수 없다. 멀티스레드의 동기화를 잘 하기위해선 상태를 잘 관리해줘야 한다. (sleep(0)을 이용해서 대기열의 뒤로 이동시키는 테크니션도 있다.)</p>
<h3 id="강의코드내용">강의코드내용</h3>
<p>코드에서 초반엔 sleep을 최소화 하면서 우연의 발생 확률을 낮추는 작업을 보여줬다. .set event와 같은 방식으로, 하나의 스레드 흐름이 끝났을 때 그 다음 작업을 linked하는 방식으로 동기화를 처리해줄 수 있지 않을까 싶다. 하지만 sleep을 이용하면 우연을 일으킬 확률이 높기때문에, 얼마나 잘 다룰 수 있냐에 따라 프로세스를 사용하는 역량을 파악할 수 있다. 리액트로 치면 렌더를 위한 상태관리 역량과 일맥상통하는 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[운영체제 이론 3편]]></title>
            <link>https://velog.io/@dev_dowon/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9D%B4%EB%A1%A0-3%ED%8E%B8</link>
            <guid>https://velog.io/@dev_dowon/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9D%B4%EB%A1%A0-3%ED%8E%B8</guid>
            <pubDate>Tue, 08 Aug 2023 08:48:00 GMT</pubDate>
            <description><![CDATA[<h3 id="예측하고-움직이는-cpu의-단점">예측하고 움직이는 CPU의 단점</h3>
<p>CPU가 미리 자료를 ‘예측’ 한다는 것은, 시키지 않은 일을  한다는 것이다. 하지만 CPU가 예측해서 발생한 ‘심각한’ 보안 문제가 있는데, 그걸 CPU 게이트 문제라고 부른다.
 특정 저장소에 접근 요청을 하면, 접근 권한이 없다고 반환이 되는데, 문제는 해당 저장소에 접근하고 읽은 다음에 접근권한이 없다고 반환한다는 것이다. 읽은 데이터는 CPU의 케싱이 되어있다. 이를 특정 연산을 통해 원하는 값을 간접적으로 취할 수 있다.</p>
<h3 id="가상화-환경에서-해킹">가상화 환경에서 해킹</h3>
<p>비정상적인 연산으로 케싱내용을 탈취할 수 있다. 악성 유저가 무작위로 RAM을 읽는 행위를 한다면, 다른 유저의 작업 정보를 케싱해뒀던 영역을 악성유저의 케싱 영역과 겹쳐지는 기적(?)이 일어날 수 있어서, 필요한 정보를 해킹을 할 수 있다. 
간단한 예시로 AWS를 쓰고있다면, 악성 유저는 같은 하드에 등록되어있는 다른 유저의 인증서 정보를 CPU게이트 원리를 이용해 탈취할 수 있다는 것이다. </p>
<h3 id="프로세스와-스레드">프로세스와 스레드</h3>
<p>컴퓨터의 자원은 CPU,RAM,HDD을 통해 사용하는 경우가 많다. RAM+HDD는 Virtual Memory 형식으로 적용한다. 윈도우 기준으로는 자원을 스레드에게 준다. (곰 책에선 프로세스에게 나눠준다고 설명된다) 
가상메모리는 프로세스에 전달되고, 이를 관리하기 위해서 OS에서 PCB라는 개념이 있다.
CPU를 주로쓰는건 스레드고 버추얼 메모리를 사용하는 건 프로세스라고 생각하면 좋다.
CPU는 연산의 주체이다. 컴퓨터에 실행되는 프로세스는 몇천개 이상은 된다. 하지만 CPU의 코어 갯수는 한정적이기 때문에 병목현상이 일어나기 일수다. 그래서 비동기적으로 처리를 하는게 기본이다. 프로세스의 요청을 모두 처리하기위해 CPU 코어에 시분할사용을 적용한다. </p>
<h3 id="pcb-란">PCB 란?</h3>
<p><img src="https://velog.velcdn.com/images/dev_dowon/post/4e032c41-a5c3-4858-8e07-0e363a9fe0f3/image.png" alt=""></p>
<p>PCB는 프로세스 컨트롤 블록의 약자다. 이름에서도 알 수 있듯이 프로세스를 제어하기 위한 모든 정보가 다 들어있다. 이는 리액트의 파이버가 비슷한 구조를 띄고 있다는 것을 알 수 있다. 리액트 훅 파이버 내부를 까보면 next라는 속성이 있는데, 이는 다음 훅을 호출 하기위해 연결점을 제공하며, 전체적으로 훅들은 Linked List 구조를 띄고있다. </p>
<pre><code>PID(process id값) 보통 32bit 양의 정수로 들어가있다.
Stack: 정적 영역(static) R -&gt; 문자열 “hello”  / RW(읽기 쓰기) -&gt; 전역변수
Heap -&gt; 동적 데이터 malloc 으로 주소를 할당받을 수 있다.
Code (text section 기계어) -&gt; 실행중인 코드의 주소도 PCB에 들어간다.</code></pre><p>프로그램이 메모리에 올라와 프로세스가 되는 과정:</p>
<p>프로그램이 HDD에 저장되어 있다면(설치됨), 이를 RAM 메모리에 올리고 Instance화를 한다. 운영체제가 프로그램을 읽어서, 메모리에 적재를 하고 PCB생성을 한다. 가상메모리도 할당을 한 다음 하나씩 정보를 떼와서 연산을 시작한다. 이때 프로그램이라고 부르지 않고 프로세스라고 부른다. 프로세스는 프로그램의 실행 형태라고 생각하면 된다.</p>
<h3 id="프로세스의-상태는-전이한다">프로세스의 상태는 전이한다</h3>
<p><img src="https://velog.velcdn.com/images/dev_dowon/post/36ca347a-09b1-4834-9ca9-6a604a110444/image.png" alt=""></p>
<p>대기상태가 추가되면서 프로세스의 상태관리가 매우 복잡해진다. 입출력 요청을 때렸을 때 Response를 받을 때 까지 대기를 한다면, 블록킹 I/O다. 비동기 요청은 요청자의 상태가 매우 중요하다. 요청자가 요청을 하고 대기상태로 빠진다면 블록킹, 반대 상황이라면 논 블록킹 요청이다. 
운영체제가 프로세스를 관리할때 상태를 관리한다고 하는데, 디스패치라는 개념이 많이 등장 할 예정이다. 디스패치의 주체는 OS이고, 디스패치의 대상을 선정하는 행위를 디스패치라고 한다. 
대기 큐에서 프로세스 상태가 Ready일때 운영체제에서 dispatch를 하는데, 이때 코어가 8개면 8개를 꺼내서 dispatch를 해준다. dispatch가 끝나면 자원할당 과정이 시작된다.</p>
<blockquote>
<p>리액트에서도 마찬가지로 스케줄러에서 파이버들 중 리렌더에 해당되는 컴포넌트 / 훅 들을 탐색하는 작업을 갖는다. 리액트의 dispatch 동작 구조는 운영체제의 프로세스 관리 운용 방식과 매우 흡사하다는 것을 다시한번 체감했다.</p>
</blockquote>
<h3 id="프로세스-상태휴식-보류와-문맥교환">프로세스 상태(휴식, 보류)와 문맥교환</h3>
<p><img src="https://velog.velcdn.com/images/dev_dowon/post/f567f348-55d6-4579-8667-8b26bbdd7124/image.png" alt=""></p>
<p>Process의 상태에는 Sleep과 Suspend라는 중요한 상태가 더 있다.  </p>
<p>suspend 상태는 외부요인으로 인해 의도치 않게 띈 상태다. sleep은 자발적으로 전환된 상태다. Ready된 스레드들을 모아둔 Queue에서 각자 스레드에서 sleep / suspend 로 인해 큐에서 잠깐 빠지게 된다. 상태가 전이된 스레드는 대기열에서 이탈하게 되는데, sleep으로 1ms 대기열에서 이탈한다면, 1ms이 지나고 이탈 상태에서 대기열로 재진입을 시도한다. 재진입을 하는 과정에서 추가된 시간을 소모하기에 1ms보다 더 많은 시간을 쉬게된다. 
<img src="https://velog.velcdn.com/images/dev_dowon/post/573d1529-3300-4771-9414-408da9dd376e/image.png" alt=""></p>
<p> suspend도 sleep과 마찬가지로 이탈한 다음 재진입하는 추가적인 시간이 걸린다. 
CPU의 코어는 한정적이기에, 한번에 모든 일을 처리하기 위해서 비동기적으로 context를 진행한다. 이러한 흐름을 제어하는 행위를 문맥교환(context switch)이라고 부른다. </p>
<p>CPU가 연산을 하는 과정엔 프로세스의 상태변화가 일어나는데, 상태는 Register에 담겨진다. 
상태가 장시간 변동되지 않는 프로세스는 운영체제에서 swap처리를 한다. RAM-&gt;HDD로 옮기거나, 연산을 하지 않을 문제가 있는 프로세스같은 경우엔 dump처리를 하는 경우도있는데, 이럴 때 suspend 상태로 전이될 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[운영체제 이론 2편]]></title>
            <link>https://velog.io/@dev_dowon/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9D%B4%EB%A1%A0-2%ED%8E%B8</link>
            <guid>https://velog.io/@dev_dowon/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9D%B4%EB%A1%A0-2%ED%8E%B8</guid>
            <pubDate>Fri, 04 Aug 2023 11:07:21 GMT</pubDate>
            <description><![CDATA[<h3 id="컴퓨터는-3층-구조를-갖고-있다">컴퓨터는 3층 구조를 갖고 있다.</h3>
<p>하드웨어 (물리적) 소프트웨어 (로지컬/버추얼)
OS는 다른말로 플랫폼이라고 한다. 운영체제는 어플리케이션을 서포트하고, 하드웨어를 관리하고 제어한다. 
한 컴퓨터에서 여러개의 프로세스를 실행하려면 운영체제가 잘 케어해줘야한다.
운영체제를 잘 이해하려면 하드웨어를 기본적으로 이해해야한다. Interrupt는 하드웨어끼리 I/O가 생길 때 마다 발생하는 이벤트인데, 이런 흐름들을 컨트롤하는 것이 바로 운영체제다.</p>
<p>print(‘hello world’) 라는 명령어를 실행하면, 실행 프로세스에서 API요청을 호출하여 커널로 명령이 특정 인터페이스를 거쳐 진입하게 된다. 커널에 진입한 뒤 명령어는 새로운 형식으로 전환이 되는데 이 전환된 결과물을 System Call이라고 부른다. System Call은 Device Driver를 통해 특정 하드웨어를 구동할 수 있다. Device Driver내부에서 Interrupt를 요청한다(IRQ는 고유번호를 갖는다.). </p>
<pre><code>print(‘hello world’) 실행 
-&gt; 프로세스가 API 요청 
-&gt; 커널로 진입하며 명령어는 System Call로 전환 
-&gt; System Call에서 Device Driver로 명령 
-&gt; Deviece Driver 내부에 IRQ 발생
-&gt; 스케줄링에 따라 하드웨어에 접근(모니터) 
-&gt; 실행이 끝났다고 다시 위로 함수 값 반환</code></pre><h3 id="인터럽트는-매우-중요하다">인터럽트는 매우 중요하다</h3>
<p>인터럽트는 현재 진행 중이던 작업을 중단시키는 개념을 이해할 수 있다. 소프트웨어 관점에선 시스템이 원활하게 동작하기 위해 인터럽트에 우선순위를 설정해야 한다. 물론 스프트웨어의 기능적인 관점 외에도 인터럽트라는 개념을 사용할 수 있다. 
인터럽트의 종류는 주로 외부 인터럽트, 내부 인터럽트, 소프트웨어 인터럽트로 분류할 수 있다. </p>
<p>외부 인터럽트:</p>
<blockquote>
<p> 보통 물리적으로 전원이나 CPU에 기능적 문제가 생겨 이상을 일으키는 인터럽트가 있고, 외부 신호로 인한 인터럽트, 그리고 I/O 인터럽트가 있다.</p>
</blockquote>
<p>RAM &lt;-&gt; CPU로 동작하는게 기본이었지만, 요즘은 메모리를 관리하는 입출력 관리자를 통해 간접적으로 I/O인터럽트를 관리한다.</p>
<p>내부 인터럽트:</p>
<blockquote>
<p>잘못된 명령이나 데이터를 이용할 때 Trap이라는 인터럽트가 있다. 프로그램 검사 인터럽트로서 Division by zero, overflow/underflow/ Exception 등이 있다.</p>
</blockquote>
<p>인터럽트의 동작순서는 아래와 같다:</p>
<pre><code>인터럽트 요청 
-&gt; 프로그램 중단 (현재 실행중인 Micro operation까지 수행) 
-&gt; 현재의 프로그램 보존(Process Control Block),PC(program counter)등 
-&gt; ISR 실행 
-&gt; 상태복구 
-&gt; 중단된 프로그램 실행 재개.</code></pre><p>인터럽트의 우선순위:</p>
<blockquote>
<p>전원 이상 &gt; 기계 착오 &gt; 외부 신호 &gt; 입출력(I/O) &gt; 명령어 잘못 &gt; 프로그램 검사 &gt; SVC</p>
</blockquote>
<p><strong>DirectX</strong>에 대한 얘기가 잠깐 나왔는데, 예전엔 유저와 커널사이에 GDI엔진이라는 그래픽 처리 요소가 있었는데, 유저단에서 게임을 실행하면 GDI API를 호출해서 Device Driver와 상호작용하기위해 너무 많은 단계를 거쳐야했다. 성능저하를 피하기위해 만든 것이 바로 DirectX인데, 그래픽 엔진 부분에 있어서  I/O 성능을 극단적으로 끌어올릴 수 있었다.</p>
<h3 id="dmadirect-memory-access">DMA(direct memory access)</h3>
<p>고성능과 밀접한 연관이 있는 개념이다. 메모리는 CPU의 cache메모리와 RAM의 메모리가 있는데, DMA에는 RAM의 메모리만 생각하면 된다. I/O 관리자는 보통 메인보드에 위치하는데 CPU의 작업실행을 보조해준다. 
 네트워크 인터페이스 카드에서 자주 나오는 내용이다. DMA는 복잡한 메모리 복사 과정을 생략하고 직접적으로 메모리를 관리할 수 있도록 도와준다. 발신의 과정을 기술해봤다:</p>
<pre><code>발신 : 네트워크 데이터 -&gt; Socket send (I/O Buffer) -&gt; Segment -&gt; NIC -&gt; 네트워크(수신쪽)</code></pre><p>수신의 과정은 아래와 같다.</p>
<pre><code>수신 : Process에서 데이터를 Receive를 하기위해 RAM메모리를 확보하고 대기를 탄다 
-&gt; NIC가 DMA를 지원한다면 OS가 Lock을 걸어서 NIC에서 받은 메모리를 프로세스가 
확보해둔 메모리로 바로 보내준다. </code></pre><p><strong>VM</strong>(가상환경)은 이를 더 큰 범주로 적용해서 속도를 극대화 할 수 있다. 두 유저간의 네트워크 교류가 사실상 같은 VM에서 동작하기 때문에, 굳이 클래식한 방식 처럼  각종 Interrupt를 거치지 않아도 된다. </p>
<h3 id="cpu는-연산할-내용을-예측하여-실행한다">CPU는 연산할 내용을 예측하여 실행한다.</h3>
<p> 연상장치에서 가장 중요한건 속도다, 물리적인 한계를 돌파하기 위해 코어의 수를 올리고 있다. 코어와 램의 속도차이는 대략 50배 정도 되는데, 이를 해결하려고 도입한게 중간 역할을 해주는 케시 메모리다. </p>
<p>케시메모리에는 명령과 데이터가 들어가있다. 필요한 데이터 공간을 미리 예측해서 선언하고, 추후에 사용할 수 있도록 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[운영체제 이론 1편]]></title>
            <link>https://velog.io/@dev_dowon/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9D%B4%EB%A1%A0-1%ED%8E%B8</link>
            <guid>https://velog.io/@dev_dowon/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9D%B4%EB%A1%A0-1%ED%8E%B8</guid>
            <pubDate>Tue, 01 Aug 2023 11:21:54 GMT</pubDate>
            <description><![CDATA[<h3 id="관리자-권한을-탈취하는-법">관리자 권한을 탈취하는 법</h3>
<p>해커가 암호없이 관리자 권한을 얻는 방법은 원격코드를 실행하는 것이다. 이는 운영체제(OS)와 관련된 내용이다. 해당 강의 목록에선 OS에 관한 내용을 다뤄준다.</p>
<p>키보드와 마우스로 프로세스를 통제해서 컴퓨터를 조작할 수 있도록 도와준다. OS가 국가라면 시스템 프로세스는 공무원이라고 비유할 수 있다. 시스템 프로세스는 관리자(root) 권한을 갖게된다. </p>
<p>윈도우 로그인 화면은 사실상 프로세스에 권한을 주입하는 과정이라고 생각할 수 있다. 프로세스 인증 방식은 웹의 로그인 세션과 같은 구조를 갖고있다. 
윈도우 로그인을 완려하면 Process Shell이 열려 권한을 부여해준다(DI). Process Shell을 통해 명령어로 새로운 프로세스를 작동한다면 권한을 상속시켜준다. </p>
<pre><code>Login Process -&gt; Process Shell -&gt; Program Process 순서로 권한이 상속된다.</code></pre><p>시스템 프로세스가 관리자 권한을 갖고있을 때, 해당 프로세스에 특정 정보를 주입시켜주면서 프로세스 오작동을 일으킨다. 결과적으로 Process Shell을 실행하도록 만들어 관리자 권한이 해커에게 넘어가게된다. </p>
<p>OS수준에서 Shell의 오작동을 방지하는 기술을 Secure OS라고 한다. 
어벤져스의 윈터솔저가 암호코드를 들으면 명령모드로 변환되는 것이 원격코드를 주입시켜 관리자권한을 탈취하는 방식과 흡사하다고 한다.</p>
<h3 id="sleep함수와-우연-그리고-cpu로-랜덤뽑기">Sleep함수와 우연 그리고 CPU로 랜덤뽑기</h3>
<p>Thread: 실행의 단위. Cpu 코어가 여러개 있을 때 연산의 개수를 스레드라고 할 수 있다.
하나의 프로세스에는 여러개의 스레드가 존재할 수 있다. 스레드에는 상태라는 개념이 따라다닌다. 작동 중인 경우 스레드는 Running이라는 상태를 갖게되고, 잠깐 멈춰야 할 땐 Suspend 상태에 처하게된다. </p>
<p>Sleep() 함수에는 ms단위의 시간을 매개변수로 넣어준다. Sleep함수가 실행된다면 Cpu의 스케줄러에게 요청을 하여, 상태전환과 관련된 목록에서 Sleep함수를 요청한 특정 스레드를 제외시켜준다. </p>
<blockquote>
<p>이는 리액트의 스케줄러가 Cpu의 스케줄러를 따라했다고 생각하면 될 것 같다. 그럼 스레드의 상태(state)는 리액트의 상태 관리와 흡사한 상태라고 이해할 수 있다.</p>
</blockquote>
<p>Sleep이 실행되는 동안 스케줄러에서 제외가 되는거지 스레드가 완전 멈추는 것은 아니라는 걸 명심하자. 또 한가지 주의할 점은, 1ms의 시간동안 Sleep을 했다는 가정하에, 1ms를 스케줄러에서 제외하는 것이기 때문에, 실제로 걸리는 시간은 1ms보다 크다. 그렇기에 부정확한 결과를 반환하는 함수라 위험성(우연)이라는 특징을 내재하고있다.</p>
<p>이러한 우연의 특징을 교묘하게 이용한 기능이 랜덤뽑기 기능이라 볼 수 있다. Cpu가 동작하는 시간은 Cpu의 상태에 따라 다르기에, 랜덤시드만 던져주면 사람이 느끼기에 랜덤한 숫자를 던져주기 때문이다. 하지만 이 세상에 있는 모든 랜덤은 pseudo random (수도랜덤)에 속한다. 완벽한 랜덤은 없다는 사실만 알아두도록 하자.</p>
<h3 id="운영체제-공룡책">운영체제 공룡책</h3>
<p>영상에서 책을 추천해줬는데, OS + system programming이 책에 포함되어 있다고 한다.</p>
<p><a href="https://www.academia.edu/42880365/Operating_System_Concepts_10th_Edition">https://www.academia.edu/42880365/Operating_System_Concepts_10th_Edition</a>
여기서 원본 PDF를 다운받을 수 있으니, 꼭 참고하자.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Javascript 선언자 var, let, const 에 대한 연구일지]]></title>
            <link>https://velog.io/@dev_dowon/JS-%EC%84%A0%EC%96%B8%EC%9E%90-%EC%97%B0%EA%B5%AC</link>
            <guid>https://velog.io/@dev_dowon/JS-%EC%84%A0%EC%96%B8%EC%9E%90-%EC%97%B0%EA%B5%AC</guid>
            <pubDate>Tue, 04 Oct 2022 04:21:25 GMT</pubDate>
            <description><![CDATA[<h2 id="해결할-점--궁금한-점">해결할 점 / 궁금한 점</h2>
<h4 id="q1-javascript에서-var--const--let-각-예약자의-선언-및-할당-방식">Q1. Javascript에서 var / const / let 각 예약자의 선언 및 할당 방식</h4>
<h4 id="q2-선언자를-작성하지-않는-변수는-var--const--let-중-어느-것인가">Q2. 선언자를 작성하지 않는 변수는 var / const / let 중 어느 것인가?</h4>
<h4 id="q3-변수가-어떤-선언자를-사용했는지-알아내는-방법-내장함수">Q3. 변수가 어떤 선언자를 사용했는지 알아내는 방법? 내장함수?</h4>
<h2 id="var-에-대한-탐구">var 에 대한 탐구</h2>
<p>javascript를 조금이라도 접한 사람들은 var의 악명을 익히 들었으리라 믿는다.var라는 친구는
호이스팅이나 스코프 문제 등으로, 자유분방하다 못해 사람들에게 혼란을 안겨주곤 했다.</p>
<p>ES6에 let과 const의 도입이 되어 var는 서서히 도태되가는 상황이지만,아직도 적지않은 
개발자들이 var를 이용하고있다.</p>
<p>const / let 은 갖고있지 않는 var의 특성을 코드로 표현해보도록 하자.</p>
<h3 id="var---연구-1--선-접근-후-선언">var - 연구 #1 : 선 접근 후 선언</h3>
<pre><code class="language-javascript">  console.log(&#39;var 예약어:&#39;, variable_var);
  var variable_var = &#39;할당 받은 값&#39;;
  console.log(&#39;var 예약어:&#39;, variable_var);</code></pre>
<p>실행결과는 다음과 같다:</p>
<pre><code>var 예약어: undefined ---&gt; (선언 / 미할당)
var 예약어: 할당 받은 값  ---&gt;(선언 / 할당)</code></pre><p>코드를 보면 알 수 있듯이, variable_var 변수가 나오기도 전에 출력을 할 수 있고, <strong>오류</strong>가 뜨지 않는다.
이는 호이스팅 현상때문이다. 위의 코드는 아래와 동일하다:</p>
<pre><code class="language-javascript">  var variable_var;
  console.log(&#39;var 예약어:&#39;, variable_var);
  variable_var = &#39;할당 받은 값&#39;;
  console.log(&#39;var 예약어:&#39;, variable_var);</code></pre>
<p>이는 javascript의 엔진이 소스코드를 위에서 밑으로 실행하기에 앞서 모든 선언문을 우선적으로 찾아내 실행하기 때문이다. 변수선언의 위치와 상관없이 제일 위로 끌어올려서 (비유적으로) 실행되는 특징을 호이스팅이라고 한다.</p>
<p>var 뿐만아니라, let, const, function, function*, class 키워드를 사용해 선언한 모든 식별자는 호이스팅이 된다.</p>
<h3 id="var---연구-2--중복할당-및-재선언">var - 연구 #2 : 중복할당 및 재선언</h3>
<p>이론적으로는 호이스팅이 이해가 되겠지만, 실제로 이렇게 작성하면 어떻게 될까? 라는 궁금증을 해소하기 위해 이 자리를 마련한거다. 하나 둘씩 시도해보도록 하자.</p>
<pre><code class="language-javascript">var variable_var;
console.log(&#39;var 선언 미할당:&#39;, variable_var);
variable_var = &#39;할당 받은 값&#39;;
console.log(&#39;var 할당:&#39;, variable_var);

variable_var = &#39;self&#39;;
var variable_var = variable_var;
console.log(&#39;var 자신을 할당하면?&#39;, variable_var);</code></pre>
<p>실행 결과는 다음과 같다:</p>
<pre><code>var 선언 미할당: undefined
var 할당: 할당 받은 값
var 자신을 할당하면? self</code></pre><p>위의 코드를 수학문제 풀듯이 살짝만 변형을 줘보자:</p>
<pre><code class="language-javascript">var variable_var;
console.log(&#39;var 선언 미할당:&#39;, variable_var);
variable_var = &#39;할당 받은 값&#39;;
console.log(&#39;var 할당:&#39;, variable_var);

variable_var = &#39;self&#39;;
variable_var = variable_var;
console.log(&#39;var 자신을 할당하면?&#39;, variable_var);</code></pre>
<p>전혀 문제가 있어보이진 않는다. 호이스팅의 특징대로 선언을 제일 위로 올리고, 변수의 할당은 
순서대로 진행되다보니 문법상 문제가 될 부분은 없다.</p>
<h3 id="var---내용정리">var - 내용정리</h3>
<blockquote>
<p>var는 변수의 초기값을 할당하지 않고 선언을 할 수 있으며, 초기값 할당전에 var 변수를 출력하면 오류가 뜨지 않으며 ( 문법적으로 허용한다는 의미 ) undefined으로 변수의 값이 표시가 된다.( 즉 초기 값 할당 전 default 값이 undefined )  </p>
</blockquote>
<h2 id="const-에-대한-탐구">const 에 대한 탐구</h2>
<h3 id="const---연구-1--선-접근-후-선언">const - 연구 #1 : 선 접근 후 선언</h3>
<p>const 예약어로 선언한 변수에 대해서 다음과 같이 코드를 작성해보았다:</p>
<pre><code class="language-javascript">try {
  console.log(&#39;const 예약어&#39;, variable_const + &#39; (선언 미할당)&#39;);
  const variable_const = &#39;할당 받은 값&#39;;
  console.log(&#39;const 예약어&#39;, variable_const + &#39; (할당)&#39;);
} catch (error) {
  console.error(error);
}</code></pre>
<p>에러처리를 위해서 <strong>try-catch</strong>문으로 이쁘게 감싸주었다. 
실행 결과는 다음과 같다: </p>
<pre><code class="language-javascript">ReferenceError: Cannot access &#39;variable_const&#39; before initialization
    ...</code></pre>
<p><strong>ReferenceError</strong>가 뜨는 것을 알 수 가 있다. 할당이 되지 않은 const 변수에 
접근 할 수 없다고 알려주고 있다. 오류가 뜨는 부분은 확연히 var와는 다른 반응이다.</p>
<h3 id="const---연구-2--선언---미할당">const - 연구 #2 : 선언 - 미할당</h3>
<p>대조를 하기 위해서, 똑같이 try-catch로 감싸 선언은 하되 초기값을 할당하지 않은 
const 변수를 출력하는 코드를 작성해보았다.</p>
<pre><code class="language-javascript">try {
  const variable_const2;
  console.log(&#39;const 예약어&#39;,variable_const2);
}catch (error){
  console.error(error);
}</code></pre>
<p>실행을 하면 error catch를 하기도 전에 이러한 에러가 뜬다: </p>
<pre><code class="language-javascript">SyntaxError: Missing initializer in const declaration
    ...</code></pre>
<p>아까와는 다르게 <strong>ReferenceError</strong>가 아닌 <strong>SyntaxError</strong>가 뜨는 것을 발견 할 수 있다. 
에러는 const 변수를 선언하는 과정에서 할당 값을 못찾았다는 걸 알려주는데 이를 
직관적으로 해석하자면 다음과 같다:</p>
<blockquote>
<p>문법오류!: const 변수는 선언함과 동시에 초기값을 할당하지 않으면 안돼!</p>
</blockquote>
<h3 id="const---연구-번외편">const - 연구 #번외편</h3>
<p>나는 이것저것 시도를 해보면서 더욱 흥미로운 것을 발견했다. 
선언을 하지 않은 undefined 인자를 console.log에 출력하면, 실행결과는 다음과 같이 나오는데:</p>
<pre><code class="language-javascript">console.log(&#39;unknown&#39;, unknown);

// 실행결과:
ReferenceError: unknown is not defined
    ...</code></pre>
<p>이는 첫번째 시도처럼 ReferenceError 인 것을 알 수 가 있다. 
ReferenceError와 SyntaxError는 분명 접근하는 방향이 다를 것 이다. 
그럼 Javascript는 도대체 어떤 방식으로 선언과 할당을 인식하고 조작하는 걸까?</p>
<h3 id="const---내용정리">const - 내용정리</h3>
<p>일단 위의 세가지 시도를 통해 나는 다음과 같은 결과를 도출해냈다 : </p>
<blockquote>
<pre><code>(1) const는 var와 마찬가지로 호이스팅이 되지만, undefined와 같은 default 할당 값이 없다.
(2) 만일 const로 변수를 선언하기 전에 접근을 한다면 (1)로 인해 Reference Error가 뜬다. 
   즉 const 변수의 선언은 확인됐지만 참조를 할 수 없다. </code></pre><p>   (3) const는 문법 상 무조건 선언과 할당을 동시에 이뤄져야한다. 그렇지 않으면 Syntax Error가 발생한다. </p>
</blockquote>
<h2 id="let-에-대한-탐구">let 에 대한 탐구</h2>
<p>let의 특징은, var 처럼 변수 값의 재할당이 가능하며, const 처럼 재선언이 안된다는 점이다. 
let을 하면서 const / var 와 중복되는 부분이 적지 않아서, 대조실험만 간단하게 하고, 메인연구를 
진행하도록 하겠다.</p>
<h3 id="let---연구-1--선언-및-할당">let - 연구 #1 : 선언 및 할당</h3>
<p>일단 선언과 할당에 대해 간단하게 알아보자:</p>
<pre><code class="language-javascript">let variable_let;
console.log(&#39;let 선언 미할당:&#39;, variable_let);
variable_let = &#39;할당 받은 값&#39;;
console.log(&#39;let 할당:&#39;, variable_let);
</code></pre>
<p>결과는 아래와 같다:</p>
<pre><code>let 선언 미할당: undefined
let 할당: 할당 받은 값</code></pre><p>이 결과는 let은 var와 같이 선언을 할때 default 값으로 undefined를 넘겨준다는 사실을 알수가 있다.</p>
<h3 id="let---연구-2--선접근-미할당">let - 연구 #2 : 선접근 미할당</h3>
<p>그렇다면 만일 선언을 하기 전에 let 변수에 접근을 하게 된다면 어떻게 될까?</p>
<pre><code class="language-javascript">console.log(&#39;let 미선언 미할당:&#39;, variable_let);
let variable_let;
variable_let = &#39;할당 받은 값&#39;;
console.log(&#39;let 할당:&#39;, variable_let);</code></pre>
<p>대답은 실행결과에서 알 수 있다:</p>
<pre><code class="language-javascript">ReferenceError: Cannot access &#39;variable_let&#39; before initialization
...</code></pre>
<p>이 부분이 let가 var와 다른 부분이다. let은 선언과 동시에 default값으로 undefined 값을 부여 받지만,
var 처럼 선언 및 default값의 할당이 호이스팅 되는 것이 아니라는 말이다.
이 부분이 이해가 안된다면, 아래에서 진행될 var-const-let 문제해결편에서 더 상세하게 설명될 예정이다.</p>
<h2 id="var-const-let-문제해결편">var, const, let 문제해결편</h2>
<h3 id="q1-javascript에서-var--const--let-각-예약자의-선언-및-할당-방식-1">Q1. Javascript에서 var / const / let 각 예약자의 선언 및 할당 방식</h3>
<p>먼저 아래와 같이 코드를 작성하여, 각 선언자의 선언 및 할당 방식을 연구해보자:</p>
<pre><code class="language-javascript">try {
  console.log(&#39;var:&#39;, variable_var);
} catch (error) {
  console.log(error);
}

try {
  console.log(&#39;const:&#39;, variable_const);
} catch (error) {
  console.log(error);
}

try {
  console.log(&#39;let:&#39;, variable_let);
} catch (error) {
  console.log(error);
}

var variable_var;
const variable_const = &#39;const 오류방지&#39;;
let variable_let;
console.log(&#39;var:&#39;, variable_var);
console.log(&#39;const:&#39;, variable_const);
console.log(&#39;let:&#39;, variable_let);
</code></pre>
<p>실행결과 : </p>
<pre><code>var: undefined
ReferenceError: Cannot access &#39;variable_const&#39; before initialization
...
ReferenceError: Cannot access &#39;variable_let&#39; before initialization
...

var: undefined
const: const 오류방지
let: undefined
</code></pre><p>하나만 더 시도해보자, 내용은 var가 중복할당을 할 수 있다고 하는데, 그럼 var 와 const / let 사이의 재선언
결과는 어떻게 될까? 이해하기 쉽게 코드를 보자:</p>
<p>var 의 재할당 / 재선언 예시:</p>
<pre><code class="language-javascript">var variable_var = &#39;value&#39;;
console.log(variable_var);
variable_var = &#39;value2 재할당&#39;;
console.log(variable_var);
var variable_var = &#39;value3 재선언&#39;;
console.log(variable_var);

실행결과 :
value
value2
value3
</code></pre>
<p>var, const, let 의 재선언:</p>
<pre><code class="language-javascript">var variable_var = &#39;var&#39;;
console.log(variable_var);
const variable_var = &#39;const&#39;;
console.log(variable_var);
let variable_var = &#39;let&#39;;

실행결과 :
SyntaxError: Identifier &#39;variable_var&#39; has already been declared
...
</code></pre>
<p>var, const, let 의 재선언 ver2:</p>
<pre><code class="language-javascript">const variable_var = &#39;const&#39;;
console.log(variable_var);
var variable_var = &#39;var&#39;;
console.log(variable_var);

실행결과 :
SyntaxError: Identifier &#39;variable_var&#39; has already been declared
...
</code></pre>
<p>결과는 모두 문법 오류를 발생시켰다. ( Systax Error )
분명 var / const / let 모두 선언의 호이스팅이 이루어진다는 건 알 수 가 있다. 그래야 var 의 값을 접근할 때 const 또는 let 이 같은 이름으로 선언을 했는지 오류체크를 할 수 있기 때문이다.  </p>
<h3 id="q1-대답">Q1. 대답</h3>
<p>이 실험으로 우리는 첫번째 질문에 명확한 대답을 할 수 있다:</p>
<blockquote>
<p>Q1. Javascript에서 var / const / let 각 예약자의 선언 및 할당 방식?
A1.
    (1) var / const / let 모두 선언은 호이스팅이 되어 javascript engine이 인식할 수 있다.
    (2) var / let은 초기값 없이 선언을 하면 default 값으로 defined 값이 할당되지만, var 과는 
    다르게 let은 선언전에 접근을 할 수 없다. ( 초기값을 부여받지 못했다고 Reference Error 발생 ) 
    (3) const는 무조건 문법상 선언과 할당을 동시에 진행해야한다. 하지만 선언의 호이스팅은 존재한다. </p>
</blockquote>
<h3 id="q2-선언자를-작성하지-않는-변수는-var--const--let-중-어느-것인가-1">Q2. 선언자를 작성하지 않는 변수는 var / const / let 중 어느 것인가?</h3>
<p> 사실 var / const / let 을 생각하면서 제일 궁금했던 부분이었다. 
 그 궁금증을 해결해줄 코드를 아래와 같이 작성해보았다:</p>
<pre><code class="language-javascript">try {
  variable;
  console.log(variable);
} catch (error) {
  console.log(error);
}

실행결과 :
ReferenceError: variable is not defined
     ...</code></pre>
<p>어쩌면 당연해 보이는 결과일지도 모르겠지만, 이 결과는 문제를 해결해줄 핵심내용이다.</p>
<p>보다 정확한 추론을 위해 코드를 몇개 더 작성해보자:</p>
<pre><code class="language-javascript">console.log(variable);
variable = &#39;value&#39;;

실행결과 :
ReferenceError: variable is not defined
...</code></pre>
<p>일단 선언자가 없는 변수는 var 형식으로 선언되는게 아니란걸 알 수 있다.</p>
<pre><code class="language-javascript">variable = &#39;value&#39;;
console.log(variable);
variable = &#39;value2&#39;;
console.log(variable);

실행결과:
value
value2</code></pre>
<p>선언자 없이 선언된 변수는 let의 형식을 띄고 있다는 것을 알 수 가 있다.</p>
<h3 id="q2-대답">Q2. 대답</h3>
<p>두번째 질문에 대한 결론은 아래와 같다:</p>
<blockquote>
<p>Q2. 선언자를 작성하지 않는 변수는 var / const / let 중 어느 것인가?
A2. 선언자를 작성하지 않은 변수는 let으로 선언하는 것과 같다.</p>
</blockquote>
<p>   이 결론은 ES5 / ES6의 차이에서 알 수 있는데, 애초에 ES5에선 선언자 없이 변수를 선언 할 수 없었다. </p>
<h3 id="q3-변수가-어떤-선언자를-사용했는지-알아내는-방법-내장함수-1">Q3. 변수가 어떤 선언자를 사용했는지 알아내는 방법? 내장함수?</h3>
<p>일단 결론부터 말하자면, 어떤 선언자를 사용했는지 알아내는 방법은 있지만, 따로 판별하는 내장함수는 없으며, 관련된 함수 또한 만들 수 없다. (할 수 있다면 어떻게 했는지 알려주세요...)</p>
<p>어떤 선언자를 사용했는지 알아내는 방법은 간단하다. 각 선언자의 특성을 파악하면, 이 문제는 해결된다.
재할당을 할 수 있다면 일단 const는 제외한다. 그리고 변수의 스코프를 확인하면 선언자를 확인할 수 있다. 
만일 블록범위의 스코프를 갖고 있다면 그 변수는 let으로 선언되었을 것 이다.</p>
<p>따로 선언자를 구분짓는 내장함수를 만들 수 없는 이유도 위와 같다. 변수를 함수의 인자로 넘기게 되면,
var / const / let 선언자 구분 없이 참조값만 넘겨주기 때문이다. 
간단하게 설명하자면:</p>
<pre><code class="language-javascript">const Test = (value) =&gt; {
  console.log(value);
  value = &#39;new value&#39;;  // == (let value = &#39;new value&#39;)
  // 외부 변수에 새값을 할당하지 않는다. 이때 인자의 참조값은 어디로 갔을까..?
  console.log(value);
};
var variable_var = &#39;var value&#39;;
let variable_let = &#39;let value&#39;;
const variable_const = &#39;const value&#39;;

console.log(&#39;var 변수를 넘겼을때: &#39;);
Test(variable_var);
console.log(&#39;let 변수를 넘겼을때: &#39;);
Test(variable_let);
console.log(&#39;const 변수를 넘겼을때: &#39;);
Test(variable_const);
</code></pre>
<p>Test 함수는 외부에 있는 변수를 인자로 받아와서 출력을하고, 함수 내부에서 받아온 변수를 재할당하고 다시 출력하는 기능을 갖고있다.</p>
<p>실행결과:</p>
<pre><code>var 변수를 넘겼을때: 
var
new value
let 변수를 넘겼을때: 
let
new value
const 변수를 넘겼을때: 
const
new value</code></pre><p>결과에서 볼 수 있듯이 선언자의 종류와 상관없이, 함수로 받아오는 인자는 변수의 주소값이 아닌 참조값만
가져오기 때문에, 실질적으로 외부에서 들어온 변수에 대해 선언자 판별이 불가능하다.</p>
<h3 id="q3-대답">Q3. 대답</h3>
<blockquote>
<p>Q3. 변수가 어떤 선언자를 사용했는지 알아내는 방법? 내장함수?
A3. 변수가 어떤 선언자를 사용했는지는 직접 선언자의 특징을 가지고 디버깅해보면 된다.
하지만 javascript의 특징상 직접적으로 주소값이나 메모리할당을 조작할 수 없기에 선언자를 
판별할 수 있는 함수를 만드는데는 어려움이 있다.</p>
</blockquote>
<h2 id="여담">여담</h2>
<p>자료조사와 실제 코드조작을 통해 한가지 추론을 세워본다:</p>
<blockquote>
<p>const / let 로 선언된 변수는 var 변수를 prototype형식으로 상속받은 새로운 객체일 것이다.</p>
</blockquote>
<p>근거의 뒷받침으로 세가지 선언자는 모두 호이스팅이 적용되며, 모두 선언된 초기 상태가
javascript엔진의 컴파일 시작점의 같은선상에 위치해 Syntax Error / Reference Error 체크가 진행된다.</p>
<p>const / let은 var 변수에 몇가지 속성을 더 부여한 객체라고 생각이 든다. 
직접 소스코드를 볼 수 없어서, 추측일 뿐이고, 그리 중요한 내용이 아니라고 생각할 수 있지만,
언젠간 나의 추론의 진위여부를 확인 할 수 있는 기회가 왔으면 좋겠다. </p>
<p>실제로 var, const, let 선언자가 어떤 형식으로 작성이 되었는지 궁금해서 소스코드를 검색해봤다.
리액트의 오픈소스처럼 실제 소스코드를 보진 못했지만, V8엔진에서 c++로 작성한 javascript엔진에 대해서 많은 자료들을 보고 많은 수확이 있었다.
<a href="https://v8.dev/">https://v8.dev/</a>
<img src="https://velog.velcdn.com/images/dev_dowon/post/3937e16f-4a59-4afc-8464-9736224d4d54/image.png" alt="V8 홈페이지">
특히 ECMAScript 규격을 소개하는 사이트에 들어가서 실제로 javascript가 어떤 형식으로interface가 구성되어있고, 어떤 메카니즘으로 시스템이 돌아가는지 자세하게 나와있어서 깊은 공부를 하는데 도움이 됐다.
<img src="https://velog.velcdn.com/images/dev_dowon/post/1ab8b7da-d79b-438c-a574-98e9476c8745/image.png" alt="ECMAScript"><img src="https://velog.velcdn.com/images/dev_dowon/post/5060e0fd-b981-4c44-86ea-a01e0d90fe26/image.PNG" alt="ECMAScript"></p>
<p><a href="https://tc39.es/ecma262/multipage/#sec-intro">https://tc39.es/ecma262/multipage/#sec-intro</a></p>
<p>궁금한게 있으면 공식문서를 참조하면서 이론공부를 하고, 부족한 실기경험은 직접 코딩을 하면서 알아가는 방식이 제일 확실한 방법인 것 같다.</p>
]]></description>
        </item>
    </channel>
</rss>